diff options
Diffstat (limited to 'src/soc/intel/skylake/memmap.c')
-rw-r--r-- | src/soc/intel/skylake/memmap.c | 86 |
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(); } |