soc/intel/common/block/rtc/rtc.c: control Top Swap via CMOS option
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 <filip.lewinski@3mdeb.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/90042 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
This commit is contained in:
parent
56be23114e
commit
51e99de558
4 changed files with 37 additions and 1 deletions
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <bootblock_common.h>
|
||||
#include <intelblocks/fast_spi.h>
|
||||
#include <intelblocks/rtc.h>
|
||||
#include <intelblocks/systemagent.h>
|
||||
#include <intelblocks/tco.h>
|
||||
#include <intelblocks/uart.h>
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
|
||||
#include <intelblocks/pcr.h>
|
||||
#include <intelblocks/rtc.h>
|
||||
#include <soc/pcr_ids.h>
|
||||
#include <option.h>
|
||||
#include <pc80/mc146818rtc.h>
|
||||
#include <reset.h>
|
||||
#include <soc/pcr_ids.h>
|
||||
|
||||
/* 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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue