diff options
-rw-r--r-- | src/soc/intel/common/basecode/ramtop/ramtop.c | 70 |
1 files changed, 63 insertions, 7 deletions
diff --git a/src/soc/intel/common/basecode/ramtop/ramtop.c b/src/soc/intel/common/basecode/ramtop/ramtop.c index 9cef9b1358..0ef531acb0 100644 --- a/src/soc/intel/common/basecode/ramtop/ramtop.c +++ b/src/soc/intel/common/basecode/ramtop/ramtop.c @@ -4,13 +4,14 @@ #include <console/console.h> #include <cpu/cpu.h> #include <cpu/x86/mtrr.h> +#include <fsp/util.h> #include <intelbasecode/ramtop.h> #include <pc80/mc146818rtc.h> #include <stdint.h> /* We need a region in CMOS to store the RAMTOP address */ -#define RAMTOP_SIGNATURE 0x52544F50 /* 'RTOP' */ +#define RAMTOP_SIGNATURE 0x504F5452 /* 'RTOP' */ /* * Address of the ramtop byte in CMOS. Should be reserved @@ -39,6 +40,7 @@ struct ramtop_table { uint32_t signature; uint32_t addr; + size_t size; uint16_t checksum; } __packed; @@ -57,6 +59,12 @@ static int ramtop_cmos_read(struct ramtop_table *ramtop) return -1; } + /* Verify RAMTOP size */ + if (ramtop->size == 0) { + printk(BIOS_DEBUG, "ramtop_table holds invalid size\n"); + return -1; + } + /* Verify checksum over signature and counter only */ csum = ipchksum(ramtop, offsetof(struct ramtop_table, checksum)); @@ -80,6 +88,36 @@ static void ramtop_cmos_write(struct ramtop_table *ramtop) cmos_write(*p, (CMOS_VSTART_ramtop / 8) + i); } +/* + * RAMTOP range: + * + * This defines the memory range covered by RAMTOP, which extends from + * cbmem_top down to FSP TOLUM. This range includes essential components: + * + * +---------------------------+ TOLUM / top_of_ram / cbmem_top + * | CBMEM Root | + * +---------------------------+ + * | FSP Reserved Memory | + * +---------------------------+ + * | various CBMEM entries | + * +---------------------------+ top_of_stack (8 byte aligned) + * | stack (CBMEM entry) | + * +---------------------------+ FSP TOLUM + * | | + * +---------------------------+ 0 +*/ +static size_t calculate_ramtop_size(uint32_t addr) +{ + struct range_entry fsp_mem; + uint32_t fsp_reserve_base; + fsp_find_reserved_memory(&fsp_mem); + + fsp_reserve_base = range_entry_base(&fsp_mem); + size_t ramtop_size = ALIGN_UP(addr - fsp_reserve_base, 4 * MiB); + + return ramtop_size; +} + /* Update the RAMTOP if required based on the input top_of_ram address */ void update_ramtop(uint32_t addr) { @@ -90,18 +128,23 @@ void update_ramtop(uint32_t addr) /* Structure invalid, re-initialize */ ramtop.signature = RAMTOP_SIGNATURE; ramtop.addr = 0; + ramtop.size = 0; } + size_t size = calculate_ramtop_size(addr); + /* Update ramtop if required */ - if (ramtop.addr == addr) + if ((ramtop.addr == addr) && (ramtop.size == size)) return; ramtop.addr = addr; + ramtop.size = size; /* Write the new top_of_ram address to CMOS */ ramtop_cmos_write(&ramtop); - printk(BIOS_DEBUG, "Updated the RAMTOP address into CMOS 0x%x\n", ramtop.addr); + printk(BIOS_DEBUG, "Updated the RAMTOP address (0x%x) with size (0x%zx) into CMOS\n", + ramtop.addr, ramtop.size); } uint32_t get_ramtop_addr(void) @@ -114,6 +157,16 @@ uint32_t get_ramtop_addr(void) return ramtop.addr; } +static uint32_t get_ramtop_size(void) +{ + struct ramtop_table ramtop; + + if (ramtop_cmos_read(&ramtop) < 0) + return 0; + + return ramtop.size; +} + /* Early caching of top_of_ram region */ void early_ramtop_enable_cache_range(void) { @@ -127,6 +180,7 @@ void early_ramtop_enable_cache_range(void) return; } + size_t ramtop_size = get_ramtop_size(); /* * Background: Some SoCs have a critical bug inside the NEM logic which is responsible * for mapping cached memory to physical memory during tear down and @@ -139,11 +193,13 @@ void early_ramtop_enable_cache_range(void) */ unsigned int mtrr_type = MTRR_TYPE_WRCOMB; /* - * We need to make sure late romstage (including FSP-M post mem) will be run - * cached. Caching 16MB below ramtop is a safe to cover late romstage. - */ + * Late romstage (including FSP-M post-memory initialization) needs to be + * executed from cache for performance reasons. This requires caching + * `ramtop_size`, which encompasses both FSP reserved memory and the CBMEM + * range, to guarantee sufficient cache coverage for late romstage. + */ if (is_cache_sets_power_of_two()) mtrr_type = MTRR_TYPE_WRBACK; - set_var_mtrr(mtrr, ramtop - 16 * MiB, 16 * MiB, mtrr_type); + set_var_mtrr(mtrr, ramtop - ramtop_size, ramtop_size, mtrr_type); } |