From 30a011417fb227d8e1e78a6a47abd9ea332c00c7 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Wed, 22 Mar 2023 00:35:42 +0530 Subject: =?UTF-8?q?soc/intel:=20Rename=20IA=20common=20code=20module=20fro?= =?UTF-8?q?m=C2=A0`TOM`=20to=20`RAMTOP`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch renames all references of `top_of_ram` (TOM) in IA common `basecode` module (for example: functions, variables, Kconfig, Makefile and comments) with `ramtop` aka top_of_ram to make it more meaningful and to avoid conflicts with Intel SA chipset TOM registers. BUG=Able to build and boot google/rex with the same ~49ms savings in place. Change-Id: Icfe6300a8e4c5761064537fb256cfecbe2afb2d8 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/73881 Reviewed-by: Angel Pons Tested-by: build bot (Jenkins) --- src/soc/intel/common/basecode/ramtop/Kconfig | 15 +++ src/soc/intel/common/basecode/ramtop/Makefile.inc | 2 + src/soc/intel/common/basecode/ramtop/ramtop.c | 127 ++++++++++++++++++++++ 3 files changed, 144 insertions(+) create mode 100644 src/soc/intel/common/basecode/ramtop/Kconfig create mode 100644 src/soc/intel/common/basecode/ramtop/Makefile.inc create mode 100644 src/soc/intel/common/basecode/ramtop/ramtop.c (limited to 'src/soc/intel/common/basecode/ramtop') diff --git a/src/soc/intel/common/basecode/ramtop/Kconfig b/src/soc/intel/common/basecode/ramtop/Kconfig new file mode 100644 index 0000000000..2b600e7464 --- /dev/null +++ b/src/soc/intel/common/basecode/ramtop/Kconfig @@ -0,0 +1,15 @@ +config SOC_INTEL_COMMON_BASECODE_RAMTOP + bool + default n + help + Driver code to store the top_of_ram (RAMTOP) address into + non-volatile space (CMOS) during the first boot and use + it across all consecutive boot. + + Purpose of this driver code is to cache the RAMTOP (with a + fixed size) for all consecutive boots even before calling + into the FSP. Otherwise, this range remains un-cached until postcar + boot stage updates the MTRR programming. FSP-M and late romstage + uses this uncached RAMTOP range for various purposes and having the + ability to cache this range beforehand would help to optimize the boot + time (more than 50ms). diff --git a/src/soc/intel/common/basecode/ramtop/Makefile.inc b/src/soc/intel/common/basecode/ramtop/Makefile.inc new file mode 100644 index 0000000000..4585173b91 --- /dev/null +++ b/src/soc/intel/common/basecode/ramtop/Makefile.inc @@ -0,0 +1,2 @@ +## SPDX-License-Identifier: GPL-2.0-only +romstage-$(CONFIG_SOC_INTEL_COMMON_BASECODE_RAMTOP) += ramtop.c diff --git a/src/soc/intel/common/basecode/ramtop/ramtop.c b/src/soc/intel/common/basecode/ramtop/ramtop.c new file mode 100644 index 0000000000..89e84d9891 --- /dev/null +++ b/src/soc/intel/common/basecode/ramtop/ramtop.c @@ -0,0 +1,127 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include +#include +#include + +/* We need a region in CMOS to store the RAMTOP address */ + +#define RAMTOP_SIGNATURE 0x52544F50 /* 'RTOP' */ + +#define RAMTOP_CMOS_OFFSET 0x64 + +/* + * Address of the ramtop_cmos_offset byte in CMOS. Should be reserved + * in mainboards' cmos.layout and not covered by checksum. + */ + +#if CONFIG(USE_OPTION_TABLE) +#include "option_table.h" +#if CMOS_VSTART_ramtop_cmos_offset != RAMTOP_CMOS_OFFSET * 8 +#error "CMOS start for RAMTOP_CMOS is not correct, check your cmos.layout" +#endif +#if CMOS_VLEN_ramtop_cmos_offset != 12 +#error "CMOS length for RAMTOP_CMOS bytes are not correct, check your cmos.layout" +#endif +#endif + +struct ramtop_table { + uint32_t signature; + uint32_t addr; + uint16_t checksum; +} __packed; + +/* Read and validate ramtop_table structure from CMOS */ +static int ramtop_cmos_read(struct ramtop_table *ramtop) +{ + u8 i, *p; + u16 csum; + + for (p = (u8 *)ramtop, i = 0; i < sizeof(*ramtop); i++, p++) + *p = cmos_read(RAMTOP_CMOS_OFFSET + i); + + /* Verify signature */ + if (ramtop->signature != RAMTOP_SIGNATURE) { + printk(BIOS_DEBUG, "ramtop_table invalid signature\n"); + return -1; + } + + /* Verify checksum over signature and counter only */ + csum = compute_ip_checksum(ramtop, offsetof(struct ramtop_table, checksum)); + + if (csum != ramtop->checksum) { + printk(BIOS_DEBUG, "ramtop_table checksum mismatch\n"); + return -1; + } + + return 0; +} + +/* Write ramtop_table structure to CMOS */ +static void ramtop_cmos_write(struct ramtop_table *ramtop) +{ + u8 i, *p; + + /* Checksum over signature and counter only */ + ramtop->checksum = compute_ip_checksum( + ramtop, offsetof(struct ramtop_table, checksum)); + + for (p = (u8 *)ramtop, i = 0; i < sizeof(*ramtop); i++, p++) + cmos_write(*p, RAMTOP_CMOS_OFFSET + i); +} + +/* Update the RAMTOP if required based on the input top_of_ram address */ +void update_ramtop(uint32_t addr) +{ + struct ramtop_table ramtop; + + /* Read and update ramtop (if required) */ + if (ramtop_cmos_read(&ramtop) < 0) { + /* Structure invalid, re-initialize */ + ramtop.signature = RAMTOP_SIGNATURE; + ramtop.addr = 0; + } + + /* Update ramtop if required */ + if (ramtop.addr == addr) + return; + + ramtop.addr = addr; + + /* 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); +} + +static uint32_t get_ramtop_addr(void) +{ + struct ramtop_table ramtop; + + if (ramtop_cmos_read(&ramtop) < 0) + return 0; + + return ramtop.addr; +} + +/* Early caching of top_of_ram region */ +void early_ramtop_enable_cache_range(void) +{ + uint32_t ramtop = get_ramtop_addr(); + if (!ramtop) + return; + + int mtrr = get_free_var_mtrr(); + if (mtrr == -1) { + printk(BIOS_WARNING, "ramtop_table update failure due to no free MTRR available!\n"); + return; + } + /* + * 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. + */ + set_var_mtrr(mtrr, ramtop - 16 * MiB, 16 * MiB, MTRR_TYPE_WRBACK); +} -- cgit v1.2.3