Subrata Banik has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/85003?usp=email )
Change subject: soc/intel/common: Add RAMTOP size in ramtop_table ......................................................................
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.
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 subratabanik@google.com --- M src/soc/intel/common/basecode/ramtop/ramtop.c 1 file changed, 58 insertions(+), 4 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/03/85003/1
diff --git a/src/soc/intel/common/basecode/ramtop/ramtop.c b/src/soc/intel/common/basecode/ramtop/ramtop.c index 9cef9b1..59490b8 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 @@ 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 @@ 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 @@ /* 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%lx) into CMOS\n", + ramtop.addr, ramtop.size); }
uint32_t get_ramtop_addr(void) @@ -114,6 +157,16 @@ 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 @@ 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 @@ -145,5 +199,5 @@ 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); }