diff options
Diffstat (limited to 'src/soc/intel/skylake/memmap.c')
-rw-r--r-- | src/soc/intel/skylake/memmap.c | 102 |
1 files changed, 78 insertions, 24 deletions
diff --git a/src/soc/intel/skylake/memmap.c b/src/soc/intel/skylake/memmap.c index 43faabb011..d5d372484c 100644 --- a/src/soc/intel/skylake/memmap.c +++ b/src/soc/intel/skylake/memmap.c @@ -17,8 +17,10 @@ #include <arch/io.h> #include <cbmem.h> #include <chip.h> +#include <console/console.h> #include <device/device.h> #include <device/pci.h> +#include <intelblocks/systemagent.h> #include <soc/msr.h> #include <soc/pci_devs.h> #include <soc/smm.h> @@ -106,6 +108,15 @@ int smm_subregion(int sub, void **start, size_t *size) return 0; } +static bool is_ptt_enable(void) +{ + if ((read32((void *)PTT_TXT_BASE_ADDRESS) & PTT_PRESENT) == + PTT_PRESENT) + return true; + + return false; +} + /* * Host Memory Map: * @@ -125,6 +136,8 @@ int smm_subregion(int sub, void **start, size_t *size) * | PRM (C6DRAM/SGX) | * +--------------------------+ PRMRR * | Trace Memory | + * +--------------------------+ Probless Trace + * | PTT | * +--------------------------+ top_of_ram * | Reserved - FSP/CBMEM | * +--------------------------+ TOLUM @@ -136,41 +149,82 @@ int smm_subregion(int sub, void **start, size_t *size) * 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. */ - -static u32 top_of_32bit_ram(void) +static u32 calculate_dram_base(void) { - msr_t prmrr_base; - u32 top_of_ram; - const struct device *dev; const struct soc_intel_skylake_config *config; + const struct device *dev; + uint32_t dram_base; + uint32_t prmrr_base; + size_t prmrr_size; + + dev = dev_find_slot(0, PCI_DEVFN(SA_DEV_SLOT_IGD, 0)); + + /* Read TOLUD from Host Bridge offset */ + dram_base = sa_get_tolud_base(); + + if (dev->enabled) { + /* Read BDSM from Host Bridge */ + dram_base -= sa_get_dsm_size(); + + /* Read BGSM from Host Bridge */ + dram_base -= sa_get_gsm_size(); + } + /* Get TSEG size */ + dram_base -= smm_region_size(); + + /* Get DPR size */ + if (IS_ENABLED(CONFIG_SA_ENABLE_DPR)) + dram_base -= sa_get_dpr_size(); + + dev = dev_find_slot(0, PCI_DEVFN(SA_DEV_SLOT_ROOT, 0)); + config = dev->chip_info; + prmrr_size = config->PrmrrSize; + if (prmrr_size > 0) { + /* + * PRMRR Sizes that are > 1MB and < 32MB are + * not supported and will fail out. + */ + if ((prmrr_size > 1*MiB) && (prmrr_size < 32*MiB)) + die("PRMRR Sizes that are > 1MB and < 32MB are not" + "supported!\n"); + + prmrr_base = dram_base - prmrr_size; + if (prmrr_size >= 32*MiB) + prmrr_base = ALIGN_DOWN(prmrr_base, 128*MiB); + dram_base = prmrr_base; + } + + if (config->ProbelessTrace) { + /* GDXC MOT */ + dram_base -= GDXC_MOT_MEMORY_SIZE; + /* Round down to natual boundary accroding to PSMI size */ + dram_base = ALIGN_DOWN(dram_base, PSMI_BUFFER_AREA_SIZE); + /* GDXC IOT */ + dram_base -= GDXC_IOT_MEMORY_SIZE; + /* PSMI buffer area */ + dram_base -= PSMI_BUFFER_AREA_SIZE; + } + + if (is_ptt_enable()) + dram_base -= 4*KiB; /* Allocate 4KB for PTT if enable */ + + return dram_base; +} + +/* Get usable system memory start address */ +static u32 top_of_32bit_ram(void) +{ /* * 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. */ - top_of_ram = smm_region_start(); - if (top_of_ram == 0) + 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); - if (prmrr_base.lo) - top_of_ram = prmrr_base.lo; - - if (config->ProbelessTrace) - top_of_ram -= TRACE_MEMORY_SIZE; - - return top_of_ram; + return calculate_dram_base(); } void *cbmem_top(void) |