From 51e99de558c9926f90cd211e3f5651f41392a2d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Lewi=C5=84ski?= Date: Fri, 21 Nov 2025 12:18:58 +0100 Subject: [PATCH] soc/intel/common/block/rtc/rtc.c: control Top Swap via CMOS option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Toggle the RTC BUC control bit for Top Swap bootblock selection based on the "attempt_slot_b" flag CMOS option, allowing to select which of the BOOTBLOCK or TOP_SWAP regions to boot from. This means that after an update, the CMOS option can be set to boot from the newer TOP_SWAP bootblock. In case of failure, CMOS can be cleared to revert to the known-good base BOOTBLOCK. This is part of ongoing implementation of a redundancy feature proposed on the mailing list: https://mail.coreboot.org/archives/list/coreboot@coreboot.org/thread/C6JN2PB7K7D67EG7OIKB6BBERZU5YV35/ Switching between identical bootblocks doesn't impact further boot flow, i.e. selecting which FMAP region to load consecutive stages from. That is to be enabled in following patches. So far tested and enabled for the Alder Lake SoC. TEST=Boot VP6650, setting the attempt_slot_b flag to different values, observing that it resets/continues booting correctly. Change-Id: Ib183a1f72ee8585b2c4ad4376344de33ff54cbb9 Signed-off-by: Filip LewiƄski Reviewed-on: https://review.coreboot.org/c/coreboot/+/90042 Tested-by: build bot (Jenkins) Reviewed-by: Sergii Dmytruk --- src/soc/intel/alderlake/bootblock/bootblock.c | 4 ++++ src/soc/intel/common/Kconfig.common | 9 +++++++++ .../common/block/include/intelblocks/rtc.h | 7 +++++++ src/soc/intel/common/block/rtc/rtc.c | 18 +++++++++++++++++- 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/soc/intel/alderlake/bootblock/bootblock.c b/src/soc/intel/alderlake/bootblock/bootblock.c index b8086a42ab..df39c9db52 100644 --- a/src/soc/intel/alderlake/bootblock/bootblock.c +++ b/src/soc/intel/alderlake/bootblock/bootblock.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -30,4 +31,7 @@ void bootblock_soc_init(void) /* Programming TCO_BASE_ADDRESS and TCO Timer Halt */ tco_configure(); + + if (CONFIG(INTEL_TOP_SWAP_OPTION_CONTROL)) + sync_rtc_buc_top_swap(); } diff --git a/src/soc/intel/common/Kconfig.common b/src/soc/intel/common/Kconfig.common index be05c65315..964a564303 100644 --- a/src/soc/intel/common/Kconfig.common +++ b/src/soc/intel/common/Kconfig.common @@ -57,6 +57,15 @@ config INTEL_TOP_SWAP_SEPARATE_REGIONS facilitate firmware updates using the Top Swap as Slot A/Slot B redundancy. Requires a custom .fmd with the regions added at the end. +config INTEL_TOP_SWAP_OPTION_CONTROL + bool "Toggle the Top Swap functionality using a CMOS option" + depends on INTEL_TOP_SWAP_SEPARATE_REGIONS && USE_OPTION_TABLE && SOC_INTEL_ALDERLAKE + default n + help + Switch between the Top Swap bootblocks using the "attempt_slot_b" CMOS + option. Note that the option must be present in the board's cmos.layout. + file. + endif config SOC_INTEL_COMMON diff --git a/src/soc/intel/common/block/include/intelblocks/rtc.h b/src/soc/intel/common/block/include/intelblocks/rtc.h index 0f09d7e0fb..ca53996c6b 100644 --- a/src/soc/intel/common/block/include/intelblocks/rtc.h +++ b/src/soc/intel/common/block/include/intelblocks/rtc.h @@ -3,6 +3,8 @@ #ifndef SOC_INTEL_COMMON_BLOCK_RTC_H #define SOC_INTEL_COMMON_BLOCK_RTC_H +#define TOP_SWAP_ENABLE_CMOS_OPTION "attempt_slot_b" + /* Top swap feature enable/disable config */ enum ts_config { TS_DISABLE, @@ -32,6 +34,11 @@ void configure_rtc_buc_top_swap(enum ts_config ts_state); */ enum ts_config get_rtc_buc_top_swap_status(void); +/* + * Set/unset the top swap bit based on TOP_SWAP_ENABLE_CMOS_OPTION state + */ +void sync_rtc_buc_top_swap(void); + /* Set RTC Configuration BILD bit. */ void rtc_conf_set_bios_interface_lockdown(void); #endif /* SOC_INTEL_COMMON_BLOCK_RTC_H */ diff --git a/src/soc/intel/common/block/rtc/rtc.c b/src/soc/intel/common/block/rtc/rtc.c index 5a5de912bb..fd8dc88755 100644 --- a/src/soc/intel/common/block/rtc/rtc.c +++ b/src/soc/intel/common/block/rtc/rtc.c @@ -2,8 +2,10 @@ #include #include -#include +#include #include +#include +#include /* RTC PCR configuration */ #define PCR_RTC_CONF 0x3400 @@ -53,4 +55,18 @@ enum ts_config get_rtc_buc_top_swap_status(void) else return TS_DISABLE; } + +void sync_rtc_buc_top_swap(void) +{ + uint8_t cmos_slotb_option, topswap_control_bit; + cmos_slotb_option = get_uint_option(TOP_SWAP_ENABLE_CMOS_OPTION, 0); + topswap_control_bit = get_rtc_buc_top_swap_status(); + printk(BIOS_INFO, "Top Swap: CMOS option state: %d\n", cmos_slotb_option); + printk(BIOS_INFO, "Top Swap: RTC BUC control bit: %d\n", topswap_control_bit); + if (cmos_slotb_option != topswap_control_bit) { + configure_rtc_buc_top_swap(cmos_slotb_option); + printk(BIOS_INFO, "Top Swap: RTC BUC control bit set to: %d, platform reset is necessary\n", get_rtc_buc_top_swap_status()); + board_reset(); + } +} #endif