soc/intel/common/block/rtc/rtc.c: Top Swap: add Slot B selection mechanism
If the Top Swap mechanism is enabled, after running the bootblock from the TOP_SWAP region, boot from an updatable COREBOOT_TS FMAP region. Having flashed the TOP_SWAP bootblock and COREBOOT_TS, this allows the user to boot a newer version of the firmware with the ability to revert to the previous known-good version by performing a CMOS reset. Requires having a read-write COREBOOT_TS region in the FMAP file. This is part of an ongoing implementation of a redundancy feature proposed on the mailing list: https://mail.coreboot.org/archives/list/coreboot@coreboot.org/thread/C6JN2PB7K7D67EG7OIKB6BBERZU5YV35/ TEST=Boot Protectli VP6650, setting the attempt_slot_b flag to different values, observing the "Booting from COREBOOT/COREBOOT_TS region" prints correspondingly. Change-Id: Ieadc9bfbe940cbec79eb84f16a5d622bfbb82ede Signed-off-by: Filip Lewiński <filip.lewinski@3mdeb.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/90147 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
This commit is contained in:
parent
a65b874472
commit
4068ba39f8
5 changed files with 42 additions and 8 deletions
14
Makefile.mk
14
Makefile.mk
|
|
@ -979,6 +979,14 @@ extract_nth=$(subst *,$(spc),$(patsubst -%-,%,$(word $(1), $(subst |,- -,-$(2)-)
|
||||||
# multiple CBFSes in fmap regions, override it.
|
# multiple CBFSes in fmap regions, override it.
|
||||||
regions-for-file ?= $(if $(value regions-for-file-$(1)), $(regions-for-file-$(1)), COREBOOT)
|
regions-for-file ?= $(if $(value regions-for-file-$(1)), $(regions-for-file-$(1)), COREBOOT)
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_INTEL_ADD_TOP_SWAP_BOOTBLOCK),y)
|
||||||
|
ifneq ($(CONFIG_INTEL_TOP_SWAP_SEPARATE_REGIONS),y)
|
||||||
|
TS_OPTIONS := -j $(CONFIG_INTEL_TOP_SWAP_BOOTBLOCK_SIZE)
|
||||||
|
else
|
||||||
|
regions-for-file = $(if $(value regions-for-file-$(1)), $(regions-for-file-$(1)), COREBOOT,COREBOOT_TS)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_CBFS_AUTOGEN_ATTRIBUTES),y)
|
ifeq ($(CONFIG_CBFS_AUTOGEN_ATTRIBUTES),y)
|
||||||
cbfs-autogen-attributes=-g
|
cbfs-autogen-attributes=-g
|
||||||
endif
|
endif
|
||||||
|
|
@ -1260,12 +1268,6 @@ $(obj)/fmap.fmap: $(obj)/fmap.fmd $(FMAPTOOL)
|
||||||
echo " FMAP $(FMAPTOOL) -h $(obj)/fmap_config.h $< $@"
|
echo " FMAP $(FMAPTOOL) -h $(obj)/fmap_config.h $< $@"
|
||||||
$(FMAPTOOL) -h $(obj)/fmap_config.h -R $(obj)/fmap.desc $< $@
|
$(FMAPTOOL) -h $(obj)/fmap_config.h -R $(obj)/fmap.desc $< $@
|
||||||
|
|
||||||
ifeq ($(CONFIG_INTEL_ADD_TOP_SWAP_BOOTBLOCK),y)
|
|
||||||
ifneq ($(CONFIG_INTEL_TOP_SWAP_SEPARATE_REGIONS),y)
|
|
||||||
TS_OPTIONS := -j $(CONFIG_INTEL_TOP_SWAP_BOOTBLOCK_SIZE)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(CONFIG_INTEL_TOP_SWAP_SEPARATE_REGIONS),y)
|
ifneq ($(CONFIG_INTEL_TOP_SWAP_SEPARATE_REGIONS),y)
|
||||||
BB_FIT_REGION = COREBOOT
|
BB_FIT_REGION = COREBOOT
|
||||||
TS_FIT_REGION = COREBOOT
|
TS_FIT_REGION = COREBOOT
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,9 @@ pbp.bin-type := raw
|
||||||
$(call add_intermediate, add_pbp_fit, set_fit_ptr $(IFITTOOL))
|
$(call add_intermediate, add_pbp_fit, set_fit_ptr $(IFITTOOL))
|
||||||
@printf " UPDATE-FIT Platform Boot Policy binary\n"
|
@printf " UPDATE-FIT Platform Boot Policy binary\n"
|
||||||
$(IFITTOOL) -f $< -a -n pbp.bin -t 4 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) -r COREBOOT
|
$(IFITTOOL) -f $< -a -n pbp.bin -t 4 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) -r COREBOOT
|
||||||
|
ifeq ($(CONFIG_INTEL_TOP_SWAP_SEPARATE_REGIONS),y)
|
||||||
|
$(IFITTOOL) -f $< -a -n pbp.bin -t 4 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) -r COREBOOT_TS
|
||||||
|
endif
|
||||||
|
|
||||||
endif # CONFIG_HAVE_PBP_BIN
|
endif # CONFIG_HAVE_PBP_BIN
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,10 @@
|
||||||
#error "FMAP must always start flash address 0"
|
#error "FMAP must always start flash address 0"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Return the name of the boot region. Falls back to COREBOOT, if not overridden
|
||||||
|
* by any multi-slot mechanism (e.g Intel Top Swap, vboot). */
|
||||||
|
const char *cbfs_fmap_region_hint(void);
|
||||||
|
|
||||||
/* Locate the named area in the fmap and fill in a region device representing
|
/* Locate the named area in the fmap and fill in a region device representing
|
||||||
* that area. The region is a sub-region of the readonly boot media. Return
|
* that area. The region is a sub-region of the readonly boot media. Return
|
||||||
* 0 on success, < 0 on error. */
|
* 0 on success, < 0 on error. */
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,11 @@ struct mem_pool cbfs_cache =
|
||||||
MEM_POOL_INIT(_cbfs_cache, REGION_SIZE(cbfs_cache), CONFIG_CBFS_CACHE_ALIGN);
|
MEM_POOL_INIT(_cbfs_cache, REGION_SIZE(cbfs_cache), CONFIG_CBFS_CACHE_ALIGN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
__weak const char *cbfs_fmap_region_hint(void)
|
||||||
|
{
|
||||||
|
return "COREBOOT";
|
||||||
|
}
|
||||||
|
|
||||||
static void switch_to_postram_cache(int unused)
|
static void switch_to_postram_cache(int unused)
|
||||||
{
|
{
|
||||||
if (_preram_cbfs_cache != _postram_cbfs_cache)
|
if (_preram_cbfs_cache != _postram_cbfs_cache)
|
||||||
|
|
@ -670,6 +675,7 @@ enum cb_err cbfs_init_boot_device(const struct cbfs_boot_device *cbd,
|
||||||
|
|
||||||
const struct cbfs_boot_device *cbfs_get_boot_device(bool force_ro)
|
const struct cbfs_boot_device *cbfs_get_boot_device(bool force_ro)
|
||||||
{
|
{
|
||||||
|
printk(BIOS_DEBUG, "Starting cbfs_boot_device\n");
|
||||||
static struct cbfs_boot_device ro;
|
static struct cbfs_boot_device ro;
|
||||||
|
|
||||||
/* Ensure we always init RO mcache, even if the first file is from the RW CBFS.
|
/* Ensure we always init RO mcache, even if the first file is from the RW CBFS.
|
||||||
|
|
@ -693,8 +699,14 @@ const struct cbfs_boot_device *cbfs_get_boot_device(bool force_ro)
|
||||||
if (region_device_sz(&ro.rdev))
|
if (region_device_sz(&ro.rdev))
|
||||||
return &ro;
|
return &ro;
|
||||||
|
|
||||||
if (fmap_locate_area_as_rdev("COREBOOT", &ro.rdev))
|
/* Falls back to the default COREBOOT region if no overriding mechanisms are in
|
||||||
die("Cannot locate primary CBFS");
|
place (e.g. Intel Top Swap). */
|
||||||
|
const char *region = cbfs_fmap_region_hint();
|
||||||
|
|
||||||
|
if (fmap_locate_area_as_rdev(region, &ro.rdev))
|
||||||
|
die("Cannot locate %s CBFS", region);
|
||||||
|
|
||||||
|
printk(BIOS_INFO, "Booting from %s region\n", region);
|
||||||
|
|
||||||
if (ENV_INITIAL_STAGE) {
|
if (ENV_INITIAL_STAGE) {
|
||||||
enum cb_err err = cbfs_init_boot_device(&ro, metadata_hash_get());
|
enum cb_err err = cbfs_init_boot_device(&ro, metadata_hash_get());
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
|
||||||
|
#include <fmap.h>
|
||||||
#include <intelblocks/pcr.h>
|
#include <intelblocks/pcr.h>
|
||||||
#include <intelblocks/rtc.h>
|
#include <intelblocks/rtc.h>
|
||||||
#include <option.h>
|
#include <option.h>
|
||||||
|
|
@ -69,4 +70,16 @@ void sync_rtc_buc_top_swap(void)
|
||||||
board_reset();
|
board_reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Select the FMAP region to continue booting from, depending on the state of
|
||||||
|
* Top Swap
|
||||||
|
*/
|
||||||
|
const char *cbfs_fmap_region_hint(void)
|
||||||
|
{
|
||||||
|
if (CONFIG(INTEL_TOP_SWAP_OPTION_CONTROL) && get_rtc_buc_top_swap_status())
|
||||||
|
return "COREBOOT_TS";
|
||||||
|
else
|
||||||
|
return "COREBOOT";
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue