summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/intel/common/basecode/ramtop/ramtop.c70
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);
}