From f5fe3590af9a67f9fd3adaee85168d3cac0d84d0 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Tue, 22 Aug 2017 17:58:02 +0530 Subject: soc/intel/skylake: Usable dram top calculation based on HW registers This patch ensures that entire system memory calculation is done based on host bridge registers. BRANCH=none BUG=b:63974384 TEST=Build and boot eve and poppy successfully with below configurations 1. Booting to OS with no UPD change 2. Enable ProbelessTrace UPD and boot to OS. 3. Enable PRMRR with size 1MB and boot to OS. 4. Enable PRMRR with size 32MB and boot to OS. 5. Enable PRMRR with size 2MB and unable to boot to OS due to unsupported PRMRR size. Change-Id: I9966cc4f2caa70b9880056193d5a5631493c3f3d Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/21150 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin --- src/soc/intel/skylake/include/soc/iomap.h | 10 ++- src/soc/intel/skylake/memmap.c | 102 +++++++++++++++++++++++------- 2 files changed, 87 insertions(+), 25 deletions(-) (limited to 'src/soc/intel/skylake') diff --git a/src/soc/intel/skylake/include/soc/iomap.h b/src/soc/intel/skylake/include/soc/iomap.h index ff4e4b0396..de9ef97744 100644 --- a/src/soc/intel/skylake/include/soc/iomap.h +++ b/src/soc/intel/skylake/include/soc/iomap.h @@ -17,6 +17,8 @@ #ifndef _SOC_IOMAP_H_ #define _SOC_IOMAP_H_ +#include + /* * Memory-mapped I/O registers. */ @@ -60,7 +62,13 @@ #define HECI1_BASE_ADDRESS 0xfed1a000 /* CPU Trace reserved memory size */ -#define TRACE_MEMORY_SIZE 0x8000000 /* 128MiB */ +#define GDXC_MOT_MEMORY_SIZE (96*MiB) +#define GDXC_IOT_MEMORY_SIZE (32*MiB) +#define PSMI_BUFFER_AREA_SIZE (64*MiB) + +/* PTT registers */ +#define PTT_TXT_BASE_ADDRESS 0xfed30800 +#define PTT_PRESENT 0x00070000 /* * I/O port address space 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 #include #include +#include #include #include +#include #include #include #include @@ -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) -- cgit v1.2.3