diff options
-rw-r--r-- | src/soc/intel/cannonlake/memmap.c | 167 |
1 files changed, 119 insertions, 48 deletions
diff --git a/src/soc/intel/cannonlake/memmap.c b/src/soc/intel/cannonlake/memmap.c index 0259cda7d6..e5117ad81d 100644 --- a/src/soc/intel/cannonlake/memmap.c +++ b/src/soc/intel/cannonlake/memmap.c @@ -104,6 +104,115 @@ static bool is_ptt_enable(void) 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 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 (IS_ENABLED(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 = dev->chip_info; + + /* Get PRMRR size */ + reserve_mem_base -= get_prmrr_size(reserve_mem_base, config); + + /* Get Tracehub size */ + reserve_mem_base -= get_imr_size(); + + /* 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: * @@ -136,64 +245,25 @@ static bool is_ptt_enable(void) * 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(void) +static uintptr_t calculate_dram_base(size_t *reserved_mem_size) { - const struct soc_intel_cannonlake_config *config; - const struct device *dev; uintptr_t dram_base; - uintptr_t prmrr_base; - size_t prmrr_size; - size_t imr_size; + const struct device *dev; dev = dev_find_slot(0, PCI_DEVFN(SA_DEV_SLOT_IGD, 0)); if (!dev) - die("ERROR - device not found!"); + die("ERROR - IGD device not found!"); /* 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 -= sa_get_tseg_size(); - - /* Get DPR size */ - if (IS_ENABLED(CONFIG_SA_ENABLE_DPR)) - dram_base -= sa_get_dpr_size(); - - config = dev->chip_info; - prmrr_size = config->PrmrrSize; + /* Get Intel Traditional Memory Range Size */ + dram_base -= calculate_traditional_mem_size(dram_base, dev); - 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; - } else if (config->enable_c6dram && prmrr_size == 0) { - /* Allocate PRMRR memory for C6DRAM */ - dram_base -= 1*MiB; - } - - /* ME stolen memory */ - imr_size = MCHBAR32(IMRLIMIT) - MCHBAR32(IMRBASE); - if (imr_size > 0) - dram_base -= imr_size; + /* Get Intel Reserved Memory Range Size */ + *reserved_mem_size = calculate_reserved_mem_size(dram_base, dev); - if (is_ptt_enable()) - dram_base -= 4*KiB; /* Allocate 4KB for PTT if enable */ + dram_base -= *reserved_mem_size; return dram_base; } @@ -201,8 +271,9 @@ static uintptr_t calculate_dram_base(void) void cbmem_top_init(void) { uintptr_t top; + size_t chipset_mem_size; - top = calculate_dram_base(); + top = calculate_dram_base(&chipset_mem_size); write32(top_of_ram_register(), top); } |