1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #define __SIMPLE_DEVICE__
5 #include <device/pci_ops.h>
6 #include <intelblocks/systemagent_server.h>
8 static uint32_t pci_moving_config32(pci_devfn_t dev
, unsigned int reg
)
10 uint32_t value
, ones
, zeroes
;
12 value
= pci_read_config32(dev
, reg
);
14 pci_write_config32(dev
, reg
, 0xffffffff);
15 ones
= pci_read_config32(dev
, reg
);
17 pci_write_config32(dev
, reg
, 0x00000000);
18 zeroes
= pci_read_config32(dev
, reg
);
20 pci_write_config32(dev
, reg
, value
);
25 uint64_t sa_server_read_map_entry(pci_devfn_t dev
,
26 const struct sa_server_mem_map_descriptor
*entry
)
29 uint32_t alignment
= entry
->alignment
;
31 if (entry
->is_64_bit
) {
32 value
= pci_s_read_config32(dev
, entry
->reg_offset
+ 4);
36 value
|= pci_s_read_config32(dev
, entry
->reg_offset
);
39 * Probe the alignment if not provided, promising the lower bits are read only, otherwise
40 * SoC should give a initial value.
43 alignment
= ~pci_moving_config32(dev
, entry
->reg_offset
) + 1;
46 * If register stores the limit address, where lower bits are read as 0s but treated as 1s,
47 * restore the lower bits and align it up.
50 value
= ALIGN_UP(value
+ alignment
- 1, alignment
);
52 value
= ALIGN_DOWN(value
, alignment
);