diff options
author | Subrata Banik <subratabanik@google.com> | 2024-11-05 19:38:26 +0530 |
---|---|---|
committer | Subrata Banik <subratabanik@google.com> | 2024-11-11 11:41:20 +0000 |
commit | a62684b7a236578ac55fe941c5eb07e2ccb08a7d (patch) | |
tree | 9f236b65a184d699396e7530275977732ec84580 /src/soc | |
parent | 86d0642cfeb5750b9356f12ad7d134d002e52bbe (diff) |
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 <subratabanik@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/85003
Reviewed-by: Kapil Porwal <kapilporwal@google.com>
Reviewed-by: V Sowmya <v.sowmya@intel.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Dinesh Gehlot <digehlot@google.com>
Diffstat (limited to 'src/soc')
-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); } |