summaryrefslogtreecommitdiff
path: root/src/soc/intel/xeon_sp
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/intel/xeon_sp')
-rw-r--r--src/soc/intel/xeon_sp/uncore.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/src/soc/intel/xeon_sp/uncore.c b/src/soc/intel/xeon_sp/uncore.c
index 1a60b60e25..d4cf4bcc29 100644
--- a/src/soc/intel/xeon_sp/uncore.c
+++ b/src/soc/intel/xeon_sp/uncore.c
@@ -146,6 +146,8 @@ static void configure_dpr(struct device *dev)
* | Tseg (relocatable) | N x 8MB (0x70000000 - 0x77ffffff, 0x20000)
* +--------------------------+
* | DPR |
+ * +--------------------------+ 1M aligned DPR base
+ * | Unused memory |
* +--------------------------+ cbmem_top
* | Reserved - CBMEM | (0x6fffe000 - 0x6fffffff, 0x2000)
* +--------------------------+
@@ -168,7 +170,9 @@ static void mc_add_dram_resources(struct device *dev, int *res_count)
{
const struct resource *res;
uint64_t mc_values[NUM_MAP_ENTRIES];
+ uint64_t top_of_ram;
int index = *res_count;
+ struct range_entry fsp_mem;
/* Only add dram resources once. */
if (dev->bus->secondary != 0)
@@ -182,24 +186,41 @@ static void mc_add_dram_resources(struct device *dev, int *res_count)
res = ram_from_to(dev, index++, 0, 0xa0000);
LOG_RESOURCE("legacy_ram", dev, res);
- /* 1MB -> top_of_ram i.e., cbmem_top */
- res = ram_from_to(dev, index++, 1 * MiB, (uintptr_t)cbmem_top());
+ /* 1MB -> top_of_ram */
+ fsp_find_reserved_memory(&fsp_mem);
+ top_of_ram = range_entry_base(&fsp_mem) - 1;
+ res = ram_from_to(dev, index++, 1 * MiB, top_of_ram);
LOG_RESOURCE("low_ram", dev, res);
- /* Mark TSEG/SMM region as reserved */
- res = reserved_ram_from_to(dev, index++, mc_values[TSEG_BASE_REG],
- mc_values[TSEG_LIMIT_REG] + 1);
- LOG_RESOURCE("mmio_tseg", dev, res);
+ /* top_of_ram -> cbmem_top */
+ res = ram_from_to(dev, index++, top_of_ram, (uintptr_t)cbmem_top());
+ LOG_RESOURCE("cbmem_ram", dev, res);
/* Reserve and set up DPR */
configure_dpr(dev);
union dpr_register dpr = { .raw = pci_read_config32(dev, VTD_LTDPR) };
if (dpr.size) {
+ /*
+ * cbmem_top -> DPR base:
+ * DPR has a 1M granularity so it's possible if cbmem_top is not 1M
+ * aligned that some memory does not get marked as assigned.
+ */
+ res = reserved_ram_from_to(dev, index++, (uintptr_t)cbmem_top(),
+ (dpr.top - dpr.size) * MiB);
+ LOG_RESOURCE("unused_dram", dev, res);
+
+ /* DPR base -> DPR top */
res = reserved_ram_from_to(dev, index++, (dpr.top - dpr.size) * MiB,
dpr.top * MiB);
LOG_RESOURCE("dpr", dev, res);
+
}
+ /* Mark TSEG/SMM region as reserved */
+ res = reserved_ram_from_to(dev, index++, mc_values[TSEG_BASE_REG],
+ mc_values[TSEG_LIMIT_REG] + 1);
+ LOG_RESOURCE("mmio_tseg", dev, res);
+
/* Mark region between TSEG - TOLM (eg. MESEG) as reserved */
res = reserved_ram_from_to(dev, index++, mc_values[TSEG_LIMIT_REG] + 1,
mc_values[TOLM_REG]);