From a62684b7a236578ac55fe941c5eb07e2ccb08a7d Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Tue, 5 Nov 2024 19:38:26 +0530 Subject: soc/intel/common: Add RAMTOP size in ramtop_table This patch adds a new field, `size`, to the `ramtop_table` structure to store the size of the RAMTOP region. The RAMTOP size is calculated as the difference between the cbmem top and the FSP reserved memory base address, aligned up to the nearest 4MB boundary. This change allows for more accurate tracking of the RAMTOP region and improves compatibility with different memory configurations. Previously, the RAMTOP size was always assumed to be 16MB. This could lead to boot hangs on systems with different memory configurations, where the actual RAMTOP size exceeded 16MB. By dynamically calculating and storing the RAMTOP size, this patch ensures that the correct memory range is used for intermediate caching, preventing boot hangs and improving boot speed. The `update_ramtop()` function is updated to write the calculated RAMTOP size to CMOS along with the RAMTOP address. The `early_ramtop_enable_cache_range()` function is also updated to use the RAMTOP size from CMOS to set the correct MTRR range. BUG=b:373290479 TEST=Built and booted successfully on various platforms. Verified that the RAMTOP size is correctly calculated and stored in CMOS Change-Id: I16d610c5791895b59da57d543c54da6621617912 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/85003 Reviewed-by: Kapil Porwal Reviewed-by: V Sowmya Tested-by: build bot (Jenkins) Reviewed-by: Dinesh Gehlot --- src/soc/intel/common/basecode/ramtop/ramtop.c | 70 ++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 7 deletions(-) (limited to 'src/soc/intel/common') 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 #include #include +#include #include #include #include /* 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); } -- cgit v1.2.3