Michael Niewöhner has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/36136 )
Change subject: soc/intel: skl,cnl,icl: rely on TOLUM and reserved memory returned by FSP ......................................................................
soc/intel: skl,cnl,icl: rely on TOLUM and reserved memory returned by FSP
Instead of doing our own calculations, rely on the TOLUM and reserved memory size returned by FSP. This (hopefully) saves us from making mistakes in calculations of offsets and aligments.
Further this makes it easier to implement e.g. SGX PRMRR size selection via Kconfig as we do not have to know anything and do not have to make any assumptions about aligning but simply pass (valid) values to FSP.
Change-Id: If66a00d1320917bc68afb32c19db0e24c6732812 Signed-off-by: Michael Niewöhner foss@mniewoehner.de --- M src/soc/intel/cannonlake/memmap.c M src/soc/intel/icelake/memmap.c M src/soc/intel/skylake/include/soc/ebda.h M src/soc/intel/skylake/memmap.c 4 files changed, 43 insertions(+), 533 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/36/36136/1
diff --git a/src/soc/intel/cannonlake/memmap.c b/src/soc/intel/cannonlake/memmap.c index f3286cc..b2fcad0 100644 --- a/src/soc/intel/cannonlake/memmap.c +++ b/src/soc/intel/cannonlake/memmap.c @@ -28,8 +28,7 @@ #include <soc/pci_devs.h> #include <soc/systemagent.h> #include <stdlib.h> - -#include "chip.h" +#include <fsp/util.h>
void smm_region(uintptr_t *start, size_t *size) { @@ -37,161 +36,6 @@ *size = sa_get_tseg_size(); }
-/* Calculate ME Stolen size */ -static size_t get_imr_size(void) -{ - size_t imr_size; - - /* ME stolen memory */ - imr_size = MCHBAR32(IMRLIMIT) - MCHBAR32(IMRBASE); - - return imr_size; -} - -/* Calculate PRMRR size based on user input PRMRR size and alignment */ -static size_t get_prmrr_size(uintptr_t dram_base, - const struct soc_intel_cannonlake_config *config) -{ - uintptr_t prmrr_base = dram_base; - size_t prmrr_size; - - prmrr_size = config->PrmrrSize; - - /* Allocate PRMRR memory for C6DRAM */ - if (!prmrr_size) { - if (config->enable_c6dram) - prmrr_size = 1*MiB; - else - return 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 -= prmrr_size; - if (prmrr_size >= 32*MiB) - prmrr_base = ALIGN_DOWN(prmrr_base, 128*MiB); - else - prmrr_base = ALIGN_DOWN(prmrr_base, 16*MiB); - /* PRMRR Area Size */ - prmrr_size = dram_base - prmrr_base; - - return prmrr_size; -} - -/* Calculate Intel Traditional Memory size based on GSM, DSM, TSEG and DPR. */ -static size_t calculate_traditional_mem_size(uintptr_t dram_base, - const struct device *dev) -{ - uintptr_t traditional_mem_base = dram_base; - size_t traditional_mem_size; - - if (dev->enabled) { - /* Read BDSM from Host Bridge */ - traditional_mem_base -= sa_get_dsm_size(); - - /* Read BGSM from Host Bridge */ - traditional_mem_base -= sa_get_gsm_size(); - } - /* Get TSEG size */ - traditional_mem_base -= sa_get_tseg_size(); - - /* Get DPR size */ - if (CONFIG(SA_ENABLE_DPR)) - traditional_mem_base -= sa_get_dpr_size(); - - /* Traditional Area Size */ - traditional_mem_size = dram_base - traditional_mem_base; - - return traditional_mem_size; -} - -/* - * Calculate Intel Reserved Memory size based on - * PRMRR size, Me stolen memory and PTT selection. - */ -static size_t calculate_reserved_mem_size(uintptr_t dram_base, - const struct device *dev) -{ - uintptr_t reserve_mem_base = dram_base; - size_t reserve_mem_size; - const struct soc_intel_cannonlake_config *config; - - config = config_of(dev); - - /* Get PRMRR size */ - reserve_mem_base -= get_prmrr_size(reserve_mem_base, config); - - /* Get Tracehub size */ - reserve_mem_base -= get_imr_size(); - - /* Traditional Area Size */ - reserve_mem_size = dram_base - reserve_mem_base; - - return reserve_mem_size; -} - -/* - * 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 - * | ME Stolen Memory | - * +--------------------------+ ME Stolen - * | PTT | - * +--------------------------+ 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. - */ -static uintptr_t calculate_dram_base(size_t *reserved_mem_size) -{ - uintptr_t dram_base; - const struct device *dev; - - dev = pcidev_on_root(SA_DEV_SLOT_IGD, 0); - if (!dev) - die_with_post_code(POST_HW_INIT_FAILURE, - "ERROR - IGD device not found!"); - - /* Read TOLUD from Host Bridge offset */ - dram_base = sa_get_tolud_base(); - - /* Get Intel Traditional Memory Range Size */ - dram_base -= calculate_traditional_mem_size(dram_base, dev); - - /* Get Intel Reserved Memory Range Size */ - *reserved_mem_size = calculate_reserved_mem_size(dram_base, dev); - - dram_base -= *reserved_mem_size; - - return dram_base; -} - /* * SoC implementation * @@ -210,10 +54,19 @@ /* Fill up memory layout information */ void fill_soc_memmap_ebda(struct ebda_config *cfg) { - size_t chipset_mem_size; + struct range_entry fsp_mem; + struct range_entry tolum;
- cfg->tolum_base = calculate_dram_base(&chipset_mem_size); - cfg->reserved_mem_size = chipset_mem_size; + /* Lookup the FSP_BOOTLOADER_TOLUM_HOB */ + if (fsp_find_bootloader_tolum(&tolum)) + die("9.3: FSP_BOOTLOADER_TOLUM_HOB missing!\n"); + + /* Locate the FSP reserved memory area */ + if (fsp_find_reserved_memory(&fsp_mem)) + die("9.1: FSP_RESERVED_MEMORY_RESOURCE_HOB missing!\n"); + + cfg->tolum_end = range_entry_end(&tolum); + cfg->reserved_mem_size = range_entry_size(&fsp_mem); }
void cbmem_top_init(void) @@ -253,15 +106,6 @@ { struct ebda_config ebda_cfg;
- /* - * 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 (sa_get_tseg_base() == 0) - return NULL; - retrieve_ebda_object(&ebda_cfg);
return (void *)(uintptr_t)ebda_cfg.tolum_base; diff --git a/src/soc/intel/icelake/memmap.c b/src/soc/intel/icelake/memmap.c index 20c4e6f..9df1065 100644 --- a/src/soc/intel/icelake/memmap.c +++ b/src/soc/intel/icelake/memmap.c @@ -28,6 +28,7 @@ #include <soc/soc_chip.h> #include <soc/systemagent.h> #include <stdlib.h> +#include <fsp/util.h>
void smm_region(uintptr_t *start, size_t *size) { @@ -35,161 +36,6 @@ *size = sa_get_tseg_size(); }
-/* Calculate ME Stolen size */ -static size_t get_imr_size(void) -{ - size_t imr_size; - - /* ME stolen memory */ - imr_size = MCHBAR32(IMRLIMIT) - MCHBAR32(IMRBASE); - - return imr_size; -} - -/* Calculate PRMRR size based on user input PRMRR size and alignment */ -static size_t get_prmrr_size(uintptr_t dram_base, - const struct soc_intel_icelake_config *config) -{ - uintptr_t prmrr_base = dram_base; - size_t prmrr_size; - - prmrr_size = config->PrmrrSize; - - /* Allocate PRMRR memory for C6DRAM */ - if (!prmrr_size) { - if (config->enable_c6dram) - prmrr_size = 1*MiB; - else - return 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 -= prmrr_size; - if (prmrr_size >= 32*MiB) - prmrr_base = ALIGN_DOWN(prmrr_base, 128*MiB); - else - prmrr_base = ALIGN_DOWN(prmrr_base, 16*MiB); - /* PRMRR Area Size */ - prmrr_size = dram_base - prmrr_base; - - return prmrr_size; -} - -/* Calculate Intel Traditional Memory size based on GSM, DSM, TSEG and DPR. */ -static size_t calculate_traditional_mem_size(uintptr_t dram_base, - const struct device *dev) -{ - uintptr_t traditional_mem_base = dram_base; - size_t traditional_mem_size; - - if (dev->enabled) { - /* Read BDSM from Host Bridge */ - traditional_mem_base -= sa_get_dsm_size(); - - /* Read BGSM from Host Bridge */ - traditional_mem_base -= sa_get_gsm_size(); - } - /* Get TSEG size */ - traditional_mem_base -= sa_get_tseg_size(); - - /* Get DPR size */ - if (CONFIG(SA_ENABLE_DPR)) - traditional_mem_base -= sa_get_dpr_size(); - - /* Traditional Area Size */ - traditional_mem_size = dram_base - traditional_mem_base; - - return traditional_mem_size; -} - -/* - * Calculate Intel Reserved Memory size based on - * PRMRR size, Me stolen memory and PTT selection. - */ -static size_t calculate_reserved_mem_size(uintptr_t dram_base, - const struct device *dev) -{ - uintptr_t reserve_mem_base = dram_base; - size_t reserve_mem_size; - const struct soc_intel_icelake_config *config; - - config = config_of(dev); - - /* Get PRMRR size */ - reserve_mem_base -= get_prmrr_size(reserve_mem_base, config); - - /* Get Tracehub size */ - reserve_mem_base -= get_imr_size(); - - /* Traditional Area Size */ - reserve_mem_size = dram_base - reserve_mem_base; - - return reserve_mem_size; -} - -/* - * 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 - * | ME Stolen Memory | - * +--------------------------+ ME Stolen - * | PTT | - * +--------------------------+ 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. - */ -static uintptr_t calculate_dram_base(size_t *reserved_mem_size) -{ - uintptr_t dram_base; - const struct device *dev; - - dev = pcidev_on_root(SA_DEV_SLOT_IGD, 0); - if (!dev) - die_with_post_code(POST_HW_INIT_FAILURE, - "ERROR - IGD device not found!"); - - /* Read TOLUD from Host Bridge offset */ - dram_base = sa_get_tolud_base(); - - /* Get Intel Traditional Memory Range Size */ - dram_base -= calculate_traditional_mem_size(dram_base, dev); - - /* Get Intel Reserved Memory Range Size */ - *reserved_mem_size = calculate_reserved_mem_size(dram_base, dev); - - dram_base -= *reserved_mem_size; - - return dram_base; -} - /* * SoC implementation * @@ -208,10 +54,19 @@ /* Fill up memory layout information */ void fill_soc_memmap_ebda(struct ebda_config *cfg) { - size_t chipset_mem_size; + struct range_entry fsp_mem; + struct range_entry tolum;
- cfg->tolum_base = calculate_dram_base(&chipset_mem_size); - cfg->reserved_mem_size = chipset_mem_size; + /* Lookup the FSP_BOOTLOADER_TOLUM_HOB */ + if (fsp_find_bootloader_tolum(&tolum)) + die("9.3: FSP_BOOTLOADER_TOLUM_HOB missing!\n"); + + /* Locate the FSP reserved memory area */ + if (fsp_find_reserved_memory(&fsp_mem)) + die("9.1: FSP_RESERVED_MEMORY_RESOURCE_HOB missing!\n"); + + cfg->tolum_end = range_entry_end(&tolum); + cfg->reserved_mem_size = range_entry_size(&fsp_mem); }
void cbmem_top_init(void) @@ -251,18 +106,9 @@ { struct ebda_config ebda_cfg;
- /* - * 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 (sa_get_tseg_base() == 0) - return NULL; - retrieve_ebda_object(&ebda_cfg);
- return (void *)(uintptr_t)ebda_cfg.tolum_base; + return (void *)(uintptr_t)ebda_cfg.tolum_end; }
void fill_postcar_frame(struct postcar_frame *pcf) diff --git a/src/soc/intel/skylake/include/soc/ebda.h b/src/soc/intel/skylake/include/soc/ebda.h index ad62394..d588c18 100644 --- a/src/soc/intel/skylake/include/soc/ebda.h +++ b/src/soc/intel/skylake/include/soc/ebda.h @@ -20,8 +20,8 @@
struct ebda_config { uint32_t signature; /* 0x00 - EBDA signature */ - uint32_t tolum_base; /* 0x04 - coreboot memory start */ - uint32_t reserved_mem_size; /* 0x08 - chipset reserved memory size */ + uint32_t tolum_end; /* 0x04 - coreboot memory start */ + uint32_t reserved_mem_size; /* 0x0C - chipset reserved memory size */ };
#endif diff --git a/src/soc/intel/skylake/memmap.c b/src/soc/intel/skylake/memmap.c index 29f2517..5c4cc3a 100644 --- a/src/soc/intel/skylake/memmap.c +++ b/src/soc/intel/skylake/memmap.c @@ -29,8 +29,7 @@ #include <soc/pci_devs.h> #include <soc/systemagent.h> #include <stdlib.h> - -#include "chip.h" +#include <fsp/util.h>
void smm_region(uintptr_t *start, size_t *size) { @@ -38,185 +37,6 @@ *size = sa_get_tseg_size(); }
-static bool is_ptt_enable(void) -{ - if ((read32((void *)PTT_TXT_BASE_ADDRESS) & PTT_PRESENT) == - PTT_PRESENT) - return true; - - return false; -} - -/* Calculate PTT size */ -static size_t get_ptt_size(void) -{ - /* Allocate 4KB for PTT if enabled */ - return is_ptt_enable() ? 4*KiB : 0; -} - -/* Calculate Trace Hub size */ -static size_t get_tracehub_size(uintptr_t dram_base, - const struct soc_intel_skylake_config *config) -{ - uintptr_t tracehub_base = dram_base; - size_t tracehub_size = 0; - - if (!config->ProbelessTrace) - return 0; - - /* GDXC MOT */ - tracehub_base -= GDXC_MOT_MEMORY_SIZE; - /* Round down to natural boundary according to PSMI size */ - tracehub_base = ALIGN_DOWN(tracehub_base, PSMI_BUFFER_AREA_SIZE); - /* GDXC IOT */ - tracehub_base -= GDXC_IOT_MEMORY_SIZE; - /* PSMI buffer area */ - tracehub_base -= PSMI_BUFFER_AREA_SIZE; - - /* Tracehub Area Size */ - tracehub_size = dram_base - tracehub_base; - - return tracehub_size; -} - -/* Calculate PRMRR size based on user input PRMRR size and alignment */ -static size_t get_prmrr_size(uintptr_t dram_base, - const struct soc_intel_skylake_config *config) -{ - uintptr_t prmrr_base = dram_base; - size_t prmrr_size; - - if (CONFIG(PLATFORM_USES_FSP1_1)) - prmrr_size = 1*MiB; - else - prmrr_size = config->PrmrrSize; - - if (!prmrr_size) - return 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 -= prmrr_size; - if (prmrr_size >= 32*MiB) - prmrr_base = ALIGN_DOWN(prmrr_base, 128*MiB); - - /* PRMRR Area Size */ - prmrr_size = dram_base - prmrr_base; - - return prmrr_size; -} - -/* Calculate Intel Traditional Memory size based on GSM, DSM, TSEG and DPR. */ -static size_t calculate_traditional_mem_size(uintptr_t dram_base) -{ - const struct device *igd_dev = pcidev_path_on_root(SA_DEVFN_IGD); - uintptr_t traditional_mem_base = dram_base; - size_t traditional_mem_size; - - if (igd_dev && igd_dev->enabled) { - /* Read BDSM from Host Bridge */ - traditional_mem_base -= sa_get_dsm_size(); - - /* Read BGSM from Host Bridge */ - traditional_mem_base -= sa_get_gsm_size(); - } - /* Get TSEG size */ - traditional_mem_base -= sa_get_tseg_size(); - - /* Get DPR size */ - if (CONFIG(SA_ENABLE_DPR)) - traditional_mem_base -= sa_get_dpr_size(); - - /* Traditional Area Size */ - traditional_mem_size = dram_base - traditional_mem_base; - - return traditional_mem_size; -} - -/* - * Calculate Intel Reserved Memory size based on - * PRMRR size, Trace Hub config and PTT selection. - */ -static size_t calculate_reserved_mem_size(uintptr_t dram_base) -{ - const struct device *dev = pcidev_path_on_root(SA_DEVFN_ROOT); - uintptr_t reserve_mem_base = dram_base; - size_t reserve_mem_size; - const struct soc_intel_skylake_config *config; - - config = config_of(dev); - - /* Get PRMRR size */ - reserve_mem_base -= get_prmrr_size(reserve_mem_base, config); - - /* Get Tracehub size */ - reserve_mem_base -= get_tracehub_size(reserve_mem_base, config); - - /* Get PTT size */ - reserve_mem_base -= get_ptt_size(); - - /* Traditional Area Size */ - reserve_mem_size = dram_base - reserve_mem_base; - - return reserve_mem_size; -} - -/* - * 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 | - * +--------------------------+ Probless Trace - * | PTT | - * +--------------------------+ 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. - */ -static uintptr_t calculate_dram_base(size_t *reserved_mem_size) -{ - uintptr_t dram_base; - - /* Read TOLUD from Host Bridge offset */ - dram_base = sa_get_tolud_base(); - - /* Get Intel Traditional Memory Range Size */ - dram_base -= calculate_traditional_mem_size(dram_base); - - /* Get Intel Reserved Memory Range Size */ - *reserved_mem_size = calculate_reserved_mem_size(dram_base); - - dram_base -= *reserved_mem_size; - - return dram_base; -} - /* * SoC implementation * @@ -235,10 +55,19 @@ /* Fill up memory layout information */ void fill_soc_memmap_ebda(struct ebda_config *cfg) { - size_t chipset_mem_size; + struct range_entry fsp_mem; + struct range_entry tolum;
- cfg->tolum_base = calculate_dram_base(&chipset_mem_size); - cfg->reserved_mem_size = chipset_mem_size; + /* Lookup the FSP_BOOTLOADER_TOLUM_HOB */ + if (fsp_find_bootloader_tolum(&tolum)) + die("9.3: FSP_BOOTLOADER_TOLUM_HOB missing!\n"); + + /* Locate the FSP reserved memory area */ + if (fsp_find_reserved_memory(&fsp_mem)) + die("9.1: FSP_RESERVED_MEMORY_RESOURCE_HOB missing!\n"); + + cfg->tolum_end = range_entry_end(&tolum); + cfg->reserved_mem_size = range_entry_size(&fsp_mem); }
void cbmem_top_init(void) @@ -278,18 +107,9 @@ { struct ebda_config ebda_cfg;
- /* - * 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 (sa_get_tseg_base() == 0) - return NULL; - retrieve_ebda_object(&ebda_cfg);
- return (void *)(uintptr_t)ebda_cfg.tolum_base; + return (void *)(uintptr_t)ebda_cfg.tolum_end; }
#if CONFIG(PLATFORM_USES_FSP2_0)