summaryrefslogtreecommitdiff
path: root/src/soc/intel/skylake/memmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/intel/skylake/memmap.c')
-rw-r--r--src/soc/intel/skylake/memmap.c86
1 files changed, 71 insertions, 15 deletions
diff --git a/src/soc/intel/skylake/memmap.c b/src/soc/intel/skylake/memmap.c
index 494b259455..0dc46a9c8c 100644
--- a/src/soc/intel/skylake/memmap.c
+++ b/src/soc/intel/skylake/memmap.c
@@ -20,7 +20,11 @@
#include <arch/io.h>
#include <cbmem.h>
+#include <chip.h>
+#include <console/console.h>
+#include <device/device.h>
#include <device/pci.h>
+#include <soc/msr.h>
#include <soc/pci_devs.h>
#include <soc/romstage.h>
#include <soc/smm.h>
@@ -108,6 +112,71 @@ int smm_subregion(int sub, void **start, size_t *size)
return 0;
}
+/*
+ * Host Memory Map:
+ *
+ * +--------------------------+ TOUUD
+ * | |
+ * +--------------------------+ 4GiB
+ * | PCI Address Space |
+ * +--------------------------+ TOLUD (also maps into MC address space)
+ * | iGD |
+ * +--------------------------+ BDSM
+ * | GTT |
+ * +--------------------------+ BGSM
+ * | TSEG |
+ * +--------------------------+ TSEGMB
+ * | DMA Protected Region |
+ * +--------------------------+ DPR
+ * | PRM (C6DRAM/SGX) |
+ * +--------------------------+ PRMRR
+ * | Trace Memory |
+ * +--------------------------+ top_of_ram
+ * | Reserved - FSP/CBMEM |
+ * +--------------------------+ TOLUM
+ * | Usage DRAM |
+ * +--------------------------+ 0
+ *
+ * Some of the base registers above can be equal making the size of those
+ * regions 0. The reason is because the memory controller internally subtracts
+ * the base registers from each other to determine sizes of the regions. In
+ * other words, the memory map is in a fixed order no matter what.
+ */
+
+u32 top_of_32bit_ram(void)
+{
+ msr_t prmrr_base;
+ u32 top_of_ram;
+ const struct device *dev;
+ const struct soc_intel_skylake_config *config;
+
+ /*
+ * Check if Tseg has been initialized, we will use this as a flag
+ * to check if the MRC is done, and only then continue to read the
+ * PRMMR_BASE MSR. The system hangs if PRMRR_BASE MSR is read before
+ * PRMRR_MASK MSR lock bit is set.
+ */
+ if (smm_region_start() == 0)
+ return 0;
+
+ dev = dev_find_slot(0, PCI_DEVFN(SA_DEV_SLOT_ROOT, 0));
+ config = dev->chip_info;
+
+ /*
+ * On Skylake, cbmem_top is offset down from PRMRR_BASE by reserved
+ * memory (128MiB) for CPU trace if enabled, then reserved memory (4KB)
+ * for PTT if enabled. PTT is in fact not used on Skylake platforms.
+ * Refer to Fsp Integration Guide for the memory mapping layout.
+ */
+ prmrr_base = rdmsr(UNCORE_PRMRR_PHYS_BASE_MSR);
+ top_of_ram = prmrr_base.lo;
+
+ if (config->ProbelessTrace)
+ top_of_ram -= TRACE_MEMORY_SIZE;
+
+ return top_of_ram;
+}
+
void *cbmem_top(void)
{
/*
@@ -117,7 +186,7 @@ void *cbmem_top(void)
* | (TSEG) |
* +-------------------------+ SMM base (aligned)
* | |
- * | Chipset Reserved Memory | Length: Multiple of CONFIG_TSEG_SIZE
+ * | Chipset Reserved Memory |
* | |
* +-------------------------+ top_of_ram (aligned)
* | |
@@ -137,19 +206,6 @@ void *cbmem_top(void)
* | |
* +-------------------------+
*/
-
- uintptr_t top_of_ram = smm_region_start();
-
- /*
- * Subtract DMA Protected Range size if enabled and align to a multiple
- * of TSEG size.
- */
- u32 dpr = pci_read_config32(SA_DEV_ROOT, DPR);
- if (dpr & DPR_EPM) {
- top_of_ram -= (dpr & DPR_SIZE_MASK) << 16;
- top_of_ram = ALIGN_DOWN(top_of_ram, mmap_region_granluarity());
- }
-
- return (void *)top_of_ram;
+ return (void *)top_of_32bit_ram();
}