From fba86624da0b301559eaaf04b86363783db51019 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Go=C5=82a=C5=9B?= Date: Mon, 6 Oct 2025 18:43:12 +0200 Subject: [PATCH 1/9] ifdtool: Add set top swap size PCH strap subcommand MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Top-Block Swap mode of Intel PCH allows to swap the boot block with another location placed directly below it by redirecting the memory accesses. The range of the addresses to be redirected is configured using the Top Swap Block Size (or BOOT_BLOCK_SIZE) PCH strap using 3 bits to encode one of 8 sizes: 64 KB, 128 KB, 256 KB, 512 KB, 1 MB, 2 MB, 4 MB or 8 MB. The source and target ranges depend on the configured size, eg: - 64 KB - FFFF_0000h - FFFF_FFFFh -> FFFE_0000h - FFFE_FFFFh - 128 KB - FFFE_0000h - FFFF_FFFFh -> FFFC_0000h - FFFD_FFFFh - 8 MB - FF80_0000h - FFFF_FFFFh -> FF00_0000h - FF7F_FFFFh Only supporting Alder Lake-P and Alder Lake-N for now. Needed for the bootblock redundancy feature suggested at https://mail.coreboot.org/archives/list/coreboot@coreboot.org/thread/C6JN2PB7K7D67EG7OIKB6BBERZU5YV35/ TEST=check using xxd, MFIT tool, ensure VP6670 boots Test details: xxd: ./util/ifdtool/ifdtool -p adl -T 0x10000 vp66xx_fd.bin && \ xxd vp66xx_fd.bin > vp66xx.hex && \ xxd vp66xx_fd.bin.new > vp66xx_fd.new.hex && \ diff -au vp66xx_fd.hex vp66xx_fd.new.hex File vp66xx_fd.bin is 4096 bytes Writing new image to vp66xx_fd.bin.new Change-Id: I7f2ae67808e8ac0aaa2a9ad5e091c2b358d4a5ab --- vp66xx_fd.hex 2025-10-08 12:03:09.527193533 +0200 +++ vp66xx_fd.new.hex 2025-10-08 12:05:08.717108142 +0200 @@ -18,7 +18,7 @@ 00000110: 7f78 0700 0000 0000 1800 0000 0000 1f00 .x.............. 00000120: 0808 1170 0000 0000 0000 7f06 80f8 8107 ...p............ 00000130: 0000 0000 0f00 0000 2222 2222 2202 2222 ........"""""."" -00000140: 0000 0000 0000 0000 0000 ff00 6000 80c8 ............`... +00000140: 0000 0000 0000 0000 0000 ff00 0000 80c8 ................ 00000150: 4586 0036 0000 0000 0002 5800 0000 4000 E..6......X...@. 00000160: 0018 0000 0000 0000 0000 0000 0000 0000 ................ 00000170: 0000 0000 0000 0000 54b3 04a0 3000 0140 ........T...0..@ mfittool: ./mfit --gui -decompose protectli_vp66xx_v0.9.2.rom In the UI: Flash Settings > BIOS Configuration > Top Swap Block Size shows the value changing to the expected one, ie. -T 0x10000 results in 64kB -T 0x20000 results in 128kB -T 0x400000 results in 4MB etc. Change-Id: I50e9d4160ee4b60e83567bcd33c9d80d428cf2bb Signed-off-by: Filip Gołaś Reviewed-on: https://review.coreboot.org/c/coreboot/+/89438 Reviewed-by: Sergii Dmytruk Tested-by: build bot (Jenkins) --- 3rdparty/dasharo-blobs | 2 +- util/ifdtool/ifdtool.c | 83 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 78 insertions(+), 7 deletions(-) diff --git a/3rdparty/dasharo-blobs b/3rdparty/dasharo-blobs index 8dce760434d..f786573d2c0 160000 --- a/3rdparty/dasharo-blobs +++ b/3rdparty/dasharo-blobs @@ -1 +1 @@ -Subproject commit 8dce760434d3cf3c6acfc7c2f07028d37365aa79 +Subproject commit f786573d2c04dfd3a9698ced69610052909ab448 diff --git a/util/ifdtool/ifdtool.c b/util/ifdtool/ifdtool.c index cf726feacae..d44acae7a23 100644 --- a/util/ifdtool/ifdtool.c +++ b/util/ifdtool/ifdtool.c @@ -2389,6 +2389,16 @@ static void new_layout(const char *filename, char *image, int size, free(new_image); } +static uint32_t uint_log2(uint32_t n) +{ + int log = -1; + while (n) { + n >>= 1; + ++log; + } + return log; +} + static void print_version(void) { printf("ifdtool v%s -- ", IFDTOOL_VERSION); @@ -2447,6 +2457,9 @@ static void print_usage(const char *name) " wbg - Wellsburg\n" " -S | --setpchstrap Write a PCH strap\n" " -V | --newvalue The new value to write into PCH strap specified by -S\n" + " -T | --topswapsize Set the Top Swap Block Size PCH strap value\n" + " Possible values: 0x10000, 0x20000, 0x40000, 0x80000,\n" + " 0x100000, 0x200000, 0x400000, 0x800000\n" " -v | --version: print the version\n" " -h | --help: print this help\n\n" " is one of Descriptor, BIOS, ME, GbE, Platform Data, Secondary BIOS, " @@ -2462,9 +2475,9 @@ int main(int argc, char *argv[]) int mode_layout = 0, mode_newlayout = 0, mode_density = 0, mode_setstrap = 0; int mode_read = 0, mode_altmedisable = 0, altmedisable = 0, mode_fmap_template = 0; int mode_gpr0_disable = 0, mode_gpr0_enable = 0, mode_gpr0_status = 0; - char *region_type_string = NULL, *region_fname = NULL; - const char *layout_fname = NULL; - char *new_filename = NULL; + int mode_settopswapsize = 0; + char *region_type_string = NULL, *region_fname = NULL, *layout_fname = NULL; + char *new_filename = NULL, *top_swap_size_arg = NULL; int region_type = -1, inputfreq = 0; unsigned int value = 0; unsigned int pchstrap = 0; @@ -2496,10 +2509,11 @@ int main(int argc, char *argv[]) {"validate", 0, NULL, 't'}, {"setpchstrap", 1, NULL, 'S'}, {"newvalue", 1, NULL, 'V'}, + {"topswapsize", 1, NULL, 'T'}, {0, 0, 0, 0} }; - while ((opt = getopt_long(argc, argv, "S:V:df:F:D:C:M:xi:n:O:s:p:elrugEcvth?", + while ((opt = getopt_long(argc, argv, "S:V:df:F:D:C:M:xi:n:O:s:p:T:elrugEcvth?", long_options, &option_index)) != EOF) { switch (opt) { case 'd': @@ -2750,6 +2764,10 @@ int main(int argc, char *argv[]) case 't': mode_validate = 1; break; + case 'T': + mode_settopswapsize = 1; + top_swap_size_arg = optarg; + break; case 'v': print_version(); exit(EXIT_SUCCESS); @@ -2767,7 +2785,7 @@ int main(int argc, char *argv[]) } if ((mode_dump + mode_layout + mode_fmap_template + mode_extract + mode_inject + - mode_setstrap + mode_newlayout + (mode_spifreq | mode_em100 | + mode_setstrap + mode_settopswapsize + mode_newlayout + (mode_spifreq | mode_em100 | mode_unlocked | mode_locked) + mode_altmedisable + mode_validate + (mode_gpr0_disable | mode_gpr0_enable) + mode_gpr0_status) > 1) { fprintf(stderr, "You may not specify more than one mode.\n\n"); @@ -2776,7 +2794,7 @@ int main(int argc, char *argv[]) } if ((mode_dump + mode_layout + mode_fmap_template + mode_extract + mode_inject + - mode_setstrap + mode_newlayout + mode_spifreq + mode_em100 + + mode_setstrap + mode_settopswapsize + mode_newlayout + mode_spifreq + mode_em100 + mode_locked + mode_unlocked + mode_density + mode_altmedisable + mode_validate + (mode_gpr0_disable | mode_gpr0_enable) + mode_gpr0_status) == 0) { fprintf(stderr, "You need to specify a mode.\n\n"); @@ -2884,6 +2902,59 @@ int main(int argc, char *argv[]) if (mode_gpr0_status) is_gpr0_protected(image, size); + if (mode_settopswapsize) { + if (platform == -1) { + fprintf(stderr, "Error: No platform specified.\n"); + exit(EXIT_FAILURE); + } + struct fpsba *fpsba = find_fpsba(image, size); + uint32_t top_swap_size_offset = 0; + switch (platform) { + case PLATFORM_ADL: + // fixed bits for ADL-P / ADL-N + if (fpsba->pchstrp[0xd0 / 4] == 0x00000300) { + // fixed bits for ADL-P + if (((fpsba->pchstrp[0x7c / 4] >> 1) & 0xff) == 0x18) { + printf("Detected ADL-P flash descriptor\n"); + pchstrap = 0x4C / 4; + top_swap_size_offset = 4; + // fixed bits for ADL-N + } else if (((fpsba->pchstrp[0x7c / 4] >> 1) & 0xff) == 0x51) { + printf("Detected ADL-N flash descriptor\n"); + pchstrap = 0x4C / 4; + top_swap_size_offset = 4; + } + } + break; + default: + break; + } + if (pchstrap == 0) { + fprintf(stderr, "Setting top swap size not supported on selected platform.\n"); + exit(EXIT_FAILURE); + } + + uint32_t top_swap_size = strtoul(top_swap_size_arg, NULL, 0); + if (top_swap_size < 0x10000 || !IS_POWER_OF_2(top_swap_size) || top_swap_size > 0x800000) { + fprintf(stderr, + "Unsupported top swap size: %s\n" + "Supported top swap sizes:\n" + "\t0x10000, 0x20000, 0x40000, 0x80000, 0x100000,\n" + "\t0x200000, 0x400000, 0x800000\n", + top_swap_size_arg); + exit(EXIT_FAILURE); + } + // convert to 0x00-0x07 + top_swap_size = uint_log2(top_swap_size / 0x10000); + const struct fdbar *fdb = find_fd(image, size); + value = fpsba->pchstrp[pchstrap]; + value &= ~(0x7 << top_swap_size_offset); + value |= (top_swap_size << top_swap_size_offset); + + set_pchstrap(fpsba, fdb, pchstrap, value); + write_image(new_filename, image, size); + } + if (mode_setstrap) { struct fpsba *fpsba = find_fpsba(image, size); const struct fdbar *fdb = find_fd(image, size); From 43466715123848126168825d487dde5448d25aee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Lewi=C5=84ski?= Date: Thu, 16 Oct 2025 11:13:07 +0200 Subject: [PATCH 2/9] ifittool: allow adding files from a separate region MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allows ifittool to add FIT entries for files that are located in a different FMAP region than the FIT table. The region from where to source the file can be specified with -R. If not given it defaults to using the value of the mandatory -r, for full backwards compatibility. Example: Tested with a custom binary with the bootblock and corresponding FIT table in a separate region, and the microcode still in the COREBOOT region: λ ./ifittool -f test_ts.rom -a -n cpu_microcode_blob.bin -t 1 \ -r BOOTBLOCK \ -R COREBOOT \ -s 4 Change-Id: I7e49247f280ec118e09cf173795d7602a4c0d7f6 Signed-off-by: Filip Lewiński Reviewed-on: https://review.coreboot.org/c/coreboot/+/89608 Reviewed-by: Sergii Dmytruk Tested-by: build bot (Jenkins) --- util/cbfstool/fit.c | 6 +++--- util/cbfstool/fit.h | 2 +- util/cbfstool/ifittool.c | 46 +++++++++++++++++++++++++++++++++------- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/util/cbfstool/fit.c b/util/cbfstool/fit.c index d4e48f19462..2c625a37e7b 100644 --- a/util/cbfstool/fit.c +++ b/util/cbfstool/fit.c @@ -491,7 +491,7 @@ static void update_fit_key_manifest_entry(struct fit_table *fit, /* Special case for ucode CBFS file, as it might contain more than one ucode */ int fit_add_microcode_file(struct fit_table *fit, - struct cbfs_image *image, + struct cbfs_image *file_source_image, const char *blob_name, fit_offset_converter_t offset_helper, const size_t max_fit_entries) @@ -507,7 +507,7 @@ int fit_add_microcode_file(struct fit_table *fit, return 1; } - if (parse_microcode_blob(image, blob_name, &mcus_found, mcus, + if (parse_microcode_blob(file_source_image, blob_name, &mcus_found, mcus, max_fit_entries)) { free(mcus); return 1; @@ -515,7 +515,7 @@ int fit_add_microcode_file(struct fit_table *fit, for (i = 0; i < mcus_found; i++) { if (fit_add_entry(fit, - offset_to_ptr(offset_helper, &image->buffer, + offset_to_ptr(offset_helper, &file_source_image->buffer, mcus[i].offset), 0, FIT_TYPE_MICROCODE, diff --git a/util/cbfstool/fit.h b/util/cbfstool/fit.h index 6d7681f7109..9df546ffa59 100644 --- a/util/cbfstool/fit.h +++ b/util/cbfstool/fit.h @@ -54,7 +54,7 @@ int fit_delete_entry(struct fit_table *fit, const size_t idx); int fit_add_microcode_file(struct fit_table *fit, - struct cbfs_image *image, + struct cbfs_image *file_source_image, const char *blob_name, fit_offset_converter_t offset_helper, const size_t max_fit_entries); diff --git a/util/cbfstool/ifittool.c b/util/cbfstool/ifittool.c index d0d9431804b..d289ef746aa 100644 --- a/util/cbfstool/ifittool.c +++ b/util/cbfstool/ifittool.c @@ -15,10 +15,11 @@ /* Global variables */ partitioned_file_t *image_file; -static const char *optstring = "H:j:f:r:d:t:n:s:cAaDvhF?"; +static const char *optstring = "H:j:f:r:R:d:t:n:s:cAaDvhF?"; static struct option long_options[] = { {"file", required_argument, 0, 'f' }, {"region", required_argument, 0, 'r' }, + {"file-region", required_argument, 0, 'R' }, {"add-cbfs-entry", no_argument, 0, 'a' }, {"add-region", no_argument, 0, 'A' }, {"del-entry", required_argument, 0, 'd' }, @@ -54,10 +55,12 @@ static void usage(const char *name) "\t\t-D|--dump : Dump FIT table (at end of operation)\n" "\t\t-c|--clear-table : Remove all existing entries (do not update)\n" "\t\t-j|--topswap-size : Use second FIT table if non zero\n" + "\t\t-R|--file-region : The FMAP region of the added file,\n" + "\t\t : defaults to the value of -r\n" "\tREQUIRED ARGUMENTS:\n" "\t\t-f|--file name : The file containing the CBFS\n" "\t\t-s|--max-table-size : The number of possible FIT entries in table\n" - "\t\t-r|--region : The FMAP region to operate on\n" + "\t\t-r|--region : The FMAP region of the FIT table\n" , name); } @@ -139,6 +142,7 @@ int main(int argc, char *argv[]) const char *input_file = NULL; const char *name = NULL; const char *region_name = NULL; + const char *file_region_name = NULL; enum fit_operation op = NO_OP; bool dump = false, clear_table = false; size_t max_table_size = 0; @@ -228,6 +232,9 @@ int main(int argc, char *argv[]) case 'r': region_name = optarg; break; + case 'R': + file_region_name = optarg; + break; case 's': max_table_size = atoi(optarg); break; @@ -282,7 +289,9 @@ int main(int argc, char *argv[]) op != NO_OP || clear_table); struct buffer image_region; + struct buffer file_image_region; + // Open the FIT table's region if (!partitioned_file_read_region(&image_region, image_file, region_name)) { partitioned_file_close(image_file); @@ -290,16 +299,37 @@ int main(int argc, char *argv[]) return 1; } + // If the added file region is not specified, default to the FIT table's one. + if (!file_region_name) { + file_image_region = image_region; + } else { + // Open the -n file-to-add region + if (!partitioned_file_read_region(&file_image_region, image_file, + file_region_name)) { + partitioned_file_close(image_file); + ERROR("The image will be left unmodified.\n"); + return 1; + } + } + struct buffer bootblock; // The bootblock is part of the CBFS on x86 buffer_clone(&bootblock, &image_region); + // Open the FIT table's CBFS struct cbfs_image image; if (cbfs_image_from_buffer(&image, &image_region, headeroffset)) { partitioned_file_close(image_file); return 1; } + // Open the -n file-to-add CBFS + struct cbfs_image file_source_image; + if (cbfs_image_from_buffer(&file_source_image, &file_image_region, HEADER_OFFSET_UNKNOWN)) { + partitioned_file_close(image_file); + return 1; + } + struct fit_table *fit = NULL; if (op != SET_FIT_PTR_OP) { fit = fit_get_table(&bootblock, convert_to_from_top_aligned, topswap_size); @@ -339,8 +369,8 @@ int main(int argc, char *argv[]) case ADD_CBFS_OP: { if (fit_type == FIT_TYPE_MICROCODE) { - if (fit_add_microcode_file(fit, &image, name, - convert_to_from_top_aligned, + if (fit_add_microcode_file(fit, &file_source_image, name, + convert_to_from_absolute_top_aligned, max_table_size)) { return 1; } @@ -348,7 +378,7 @@ int main(int argc, char *argv[]) uint32_t offset, len; struct cbfs_file *cbfs_file; - cbfs_file = cbfs_get_entry(&image, name); + cbfs_file = cbfs_get_entry(&file_source_image, name); if (!cbfs_file) { partitioned_file_close(image_file); ERROR("%s not found in CBFS.\n", name); @@ -356,9 +386,9 @@ int main(int argc, char *argv[]) } len = be32toh(cbfs_file->len); - offset = offset_to_ptr(convert_to_from_top_aligned, - &image.buffer, - cbfs_get_entry_addr(&image, cbfs_file) + + offset = offset_to_ptr(convert_to_from_absolute_top_aligned, + &file_source_image.buffer, + cbfs_get_entry_addr(&file_source_image, cbfs_file) + be32toh(cbfs_file->offset)); From ed0baa7b416509d38c2e4435c7ea8a7774132e7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Go=C5=82a=C5=9B?= Date: Thu, 9 Oct 2025 12:34:45 +0200 Subject: [PATCH 3/9] intel soc,southbridge: Add Kconfig to set TSBS in IFD during build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To modify the Top Swap Block Size in the FD (if provided and CONFIG_HAVE_IFD_BIN=y), set the following Kconfig variables: - CONFIG_INTEL_HAS_TOP_SWAP - CONFIG_INTEL_ADD_TOP_SWAP_BOOTBLOCK - CONFIG_INTEL_TOP_SWAP_BOOTBLOCK_SIZE - CONFIG_INTEL_IFD_SET_TOP_SWAP_BOOTBLOCK_SIZE Needed for the bootblock redundancy feature suggested at https://mail.coreboot.org/archives/list/coreboot@coreboot.org/thread/C6JN2PB7K7D67EG7OIKB6BBERZU5YV35/ TEST=build VP66xx with custom Kconfig, check if TSBS is modified in FD Change-Id: I94d3d3e2511a7e56392a9e34f845ae91602ce7f1 Signed-off-by: Filip Gołaś Reviewed-on: https://review.coreboot.org/c/coreboot/+/89493 Reviewed-by: Sergii Dmytruk Tested-by: build bot (Jenkins) --- src/soc/intel/common/Kconfig.common | 14 +++++++++++++- src/southbridge/intel/common/firmware/Makefile.mk | 14 ++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/soc/intel/common/Kconfig.common b/src/soc/intel/common/Kconfig.common index 7ce93d45937..f961a4938c9 100644 --- a/src/soc/intel/common/Kconfig.common +++ b/src/soc/intel/common/Kconfig.common @@ -23,7 +23,19 @@ config INTEL_TOP_SWAP_BOOTBLOCK_SIZE default 0x10000 help Set this config to a supported topswap size. - Valid sizes: 0x10000 0x20000 0x40000 0x80000 0x100000 + Valid sizes: 0x10000/0x20000/0x40000/0x80000/0x100000/ + 0x200000/0x400000/0x800000. The maximum size + varies depending on the platform. + +config INTEL_IFD_SET_TOP_SWAP_BOOTBLOCK_SIZE + bool "Replace the TSBS value with INTEL_TOP_SWAP_BOOTBLOCK_SIZE" + default n + depends on HAVE_IFD_BIN + help + Set to use ifdtool to replace the Top Swap Block Size + PCH strap value in the Intel Firmware Descriptor + with INTEL_TOP_SWAP_BOOTBLOCK_SIZE + config INTEL_TOP_SWAP_FIT_ENTRY_FMAP_REG string diff --git a/src/southbridge/intel/common/firmware/Makefile.mk b/src/southbridge/intel/common/firmware/Makefile.mk index a7431902c45..ba5447f341c 100644 --- a/src/southbridge/intel/common/firmware/Makefile.mk +++ b/src/southbridge/intel/common/firmware/Makefile.mk @@ -49,9 +49,22 @@ ifeq ($(CONFIG_HAVE_EC_BIN),y) add_intel_firmware: $(call strip_quotes,$(CONFIG_EC_BIN_PATH)) endif add_intel_firmware: $(obj)/coreboot.pre $(IFDTOOL) +ifeq ($(INTEL_IFD_SET_TOP_SWAP_BOOTBLOCK_SIZE),y) + printf " IFDTOOL Modifying top swap PCH strap in IFD\n" + printf " $(IFDTOOL_USE_CHIPSET)" + $(objutil)/ifdtool/ifdtool \ + $(IFDTOOL_USE_CHIPSET) \ + -T $(CONFIG_INTEL_TOP_SWAP_BOOTBLOCK_SIZE) \ + -O $(obj)/ifd_custom_tsbs \ + $(IFD_BIN_PATH) + printf " DD Adding Intel Firmware Descriptor\n" + dd if=$(obj)/ifd_custom_tsbs\ + of=$(obj)/coreboot.pre conv=notrunc >/dev/null 2>&1 +else printf " DD Adding Intel Firmware Descriptor\n" dd if=$(IFD_BIN_PATH) \ of=$(obj)/coreboot.pre conv=notrunc >/dev/null 2>&1 + ifeq ($(CONFIG_IFDTOOL_DISABLE_ME),y) printf " IFDTOOL set AltMeDisable/HAP bit\n" $(objutil)/ifdtool/ifdtool \ @@ -59,6 +72,7 @@ ifeq ($(CONFIG_IFDTOOL_DISABLE_ME),y) --altmedisable 1 \ -O $(obj)/coreboot.pre \ $(obj)/coreboot.pre + endif ifeq ($(CONFIG_VALIDATE_INTEL_DESCRIPTOR),y) printf " IFDTOOL validate IFD against FMAP\n" From a60aa77f836d3e646bb1d282f31cc50b7b256d0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Lewi=C5=84ski?= Date: Fri, 17 Oct 2025 16:00:46 +0200 Subject: [PATCH 4/9] Makefile.mk: separate bootblocks into BOOTBLOCK and TOPSWAP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add Kconfig INTEL_TOP_SWAP_SEPARATE_REGIONS. When enabled, place the regular bootblock in BOOTBLOCK and the Top Swap bootblock in TOPSWAP to simplify A B updates. This lays groundwork for redundancy where one bootblock remains a read only golden copy and the other is replaceable. No swap control logic is added in this change. The option depends on INTEL_ADD_TOP_SWAP_BOOTBLOCK and defaults to n so existing builds are unchanged. A custom .fmd is required with BOOTBLOCK and TOPSWAP added at the end of the image. Background and update flow are described here: Link: https://mail.coreboot.org/archives/list/coreboot@coreboot.org/thread/C6JN2PB7K7D67EG7OIKB6BBERZU5Y V35/ TEST=Build and run Protectli VP6650 (ADL-P), boots successfully with correct microcode Change-Id: I489406dd8d08ad85bb46324d3d009acb49b6c52a Signed-off-by: Filip Lewiński Reviewed-on: https://review.coreboot.org/c/coreboot/+/89570 Tested-by: build bot (Jenkins) Reviewed-by: Sergii Dmytruk --- Makefile.mk | 29 +++++++++++++++++++++++++++-- src/cpu/intel/fit/Makefile.mk | 16 +++++++++++----- src/soc/intel/common/Kconfig.common | 9 +++++++++ 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/Makefile.mk b/Makefile.mk index 10f707b9d1d..e8ffd70bd4d 100644 --- a/Makefile.mk +++ b/Makefile.mk @@ -1289,8 +1289,22 @@ $(obj)/fmap.fmap: $(obj)/fmap.fmd $(FMAPTOOL) $(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) +BB_FIT_REGION = COREBOOT +TS_FIT_REGION = COREBOOT +else +BB_FIT_REGION = BOOTBLOCK +TS_FIT_REGION = TOPSWAP +bootblock_add_params = -f $(objcbfs)/bootblock.bin \ + -n bootblock -t bootblock \ + -b -$(call file-size,$(objcbfs)/bootblock.bin) \ + $(TXTIBB) $(cbfs-autogen-attributes) $(TS_OPTIONS) $(CBFSTOOL_ADD_CMD_OPTIONS) +endif ifneq ($(CONFIG_ARCH_X86),y) add_bootblock = $(CBFSTOOL) $(1) write -u -r BOOTBLOCK -f $(2) @@ -1304,7 +1318,9 @@ ifneq ($(CONFIG_UPDATE_IMAGE),y) $(obj)/coreboot.pre: $$(prebuilt-files) $(CBFSTOOL) $(obj)/fmap.fmap $(obj)/fmap.desc $(objcbfs)/bootblock.bin $(CBFSTOOL) $@.tmp create -M $(obj)/fmap.fmap -r $(shell cat $(obj)/fmap.desc) printf " BOOTBLOCK\n" +ifneq ($(CONFIG_INTEL_TOP_SWAP_SEPARATE_REGIONS),y) $(call add_bootblock,$@.tmp,$(objcbfs)/bootblock.bin) +endif # ifneq ($(CONFIG_INTEL_TOP_SWAP_SEPARATE_REGIONS),y) $(prebuild-files) true mv $@.tmp $@ else # ifneq ($(CONFIG_UPDATE_IMAGE),y) @@ -1334,6 +1350,15 @@ add_intermediate = \ $(1): $(obj)/coreboot.pre $(2) | $(INTERMEDIATE) \ $(eval INTERMEDIATE+=$(1)) $(eval PHONY+=$(1)) +ifeq ($(CONFIG_INTEL_TOP_SWAP_SEPARATE_REGIONS),y) +$(call add_intermediate, prep_bb_regions, $(CBFSTOOL)) + @printf " PREP place bootblocks in BOOTBLOCK and TOPSWAP\n" + @printf " BOOTBLOCK\n" + $(CBFSTOOL) $< add -r $(BB_FIT_REGION) $(bootblock_add_params) + @printf " TOPSWAP\n" + $(CBFSTOOL) $< add -r $(TS_FIT_REGION) $(bootblock_add_params) +endif + $(obj)/coreboot.rom: $(obj)/coreboot.pre $(CBFSTOOL) $(IFITTOOL) $$(INTERMEDIATE) @printf " CBFS $(subst $(obj)/,,$(@))\n" # The full ROM may be larger than the CBFS part, so create an empty @@ -1342,11 +1367,11 @@ $(obj)/coreboot.rom: $(obj)/coreboot.pre $(CBFSTOOL) $(IFITTOOL) $$(INTERMEDIATE dd if=$(obj)/coreboot.pre of=$@.tmp bs=8192 conv=notrunc 2> /dev/null ifeq ($(CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE),y) # Print final FIT table - $(IFITTOOL) -f $@.tmp -D -r COREBOOT + $(IFITTOOL) -f $@.tmp -D -r $(BB_FIT_REGION) # Print final TS BOOTBLOCK FIT table ifeq ($(CONFIG_INTEL_ADD_TOP_SWAP_BOOTBLOCK),y) @printf " TOP SWAP FIT table\n" - $(IFITTOOL) -f $@.tmp -D $(TS_OPTIONS) -r COREBOOT + $(IFITTOOL) -f $@.tmp -D $(TS_OPTIONS) -r $(TS_FIT_REGION) endif # CONFIG_INTEL_ADD_TOP_SWAP_BOOTBLOCK endif # CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE mv $@.tmp $@ diff --git a/src/cpu/intel/fit/Makefile.mk b/src/cpu/intel/fit/Makefile.mk index 0661984f155..5c2ed7379f2 100644 --- a/src/cpu/intel/fit/Makefile.mk +++ b/src/cpu/intel/fit/Makefile.mk @@ -17,9 +17,14 @@ ifneq ($(CONFIG_INTEL_FIT_LOC),) intel_fit-COREBOOT-position := $(CONFIG_INTEL_FIT_LOC) endif +ifeq ($(CONFIG_INTEL_TOP_SWAP_SEPARATE_REGIONS),y) +regions-for-file-intel_fit = BOOTBLOCK +regions-for-file-intel_fit_ts = TOPSWAP +endif + $(call add_intermediate, set_fit_ptr, $(IFITTOOL)) @printf " UPDATE-FIT set FIT pointer to table\n" - $(IFITTOOL) -f $< -F -n intel_fit -r COREBOOT -c + $(IFITTOOL) -f $< -F -n intel_fit -r $(BB_FIT_REGION) -c FIT_ENTRY=$(call strip_quotes, $(CONFIG_INTEL_TOP_SWAP_FIT_ENTRY_FMAP_REG)) @@ -28,22 +33,23 @@ ifneq ($(CONFIG_UPDATE_IMAGE),y) # never update the bootblock ifneq ($(CONFIG_CPU_MICROCODE_CBFS_NONE)$(CONFIG_CPU_INTEL_MICROCODE_CBFS_SPLIT_BINS),y) $(call add_intermediate, add_mcu_fit, set_fit_ptr $(IFITTOOL)) + @printf "$(call regions-for-file,$(cpu_microcode_blob.bin))" @printf " UPDATE-FIT Microcode\n" - $(IFITTOOL) -f $< -a -n cpu_microcode_blob.bin -t 1 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) -r COREBOOT + $(IFITTOOL) -f $< -a -n cpu_microcode_blob.bin -t 1 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) -r $(BB_FIT_REGION) -R COREBOOT # Second FIT in TOP_SWAP bootblock ifeq ($(CONFIG_INTEL_ADD_TOP_SWAP_BOOTBLOCK),y) $(call add_intermediate, set_ts_fit_ptr, $(IFITTOOL)) @printf " UPDATE-FIT Top Swap: set FIT pointer to table\n" - $(IFITTOOL) -f $< -F -n intel_fit_ts -r COREBOOT $(TS_OPTIONS) + $(IFITTOOL) -f $< -F -n intel_fit_ts -r $(TS_FIT_REGION) $(TS_OPTIONS) $(call add_intermediate, add_ts_mcu_fit, set_ts_fit_ptr $(IFITTOOL)) @printf " UPDATE-FIT Top Swap: Microcode\n" ifneq ($(FIT_ENTRY),) - $(IFITTOOL) -f $< -A -n $(FIT_ENTRY) -t 1 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) $(TS_OPTIONS) -r COREBOOT + $(IFITTOOL) -f $< -A -n $(FIT_ENTRY) -t 1 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) $(TS_OPTIONS) -r $(TS_FIT_REGION) endif # FIT_ENTRY - $(IFITTOOL) -f $< -a -n cpu_microcode_blob.bin -t 1 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) $(TS_OPTIONS) -r COREBOOT + $(IFITTOOL) -f $< -a -n cpu_microcode_blob.bin -t 1 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) $(TS_OPTIONS) -r $(TS_FIT_REGION) -R COREBOOT cbfs-files-y += intel_fit_ts intel_fit_ts-file := fit_table.c:struct diff --git a/src/soc/intel/common/Kconfig.common b/src/soc/intel/common/Kconfig.common index f961a4938c9..cb26881506a 100644 --- a/src/soc/intel/common/Kconfig.common +++ b/src/soc/intel/common/Kconfig.common @@ -48,6 +48,15 @@ config INTEL_TOP_SWAP_FIT_ENTRY_FMAP_REG onto ifittool (-A -n option). ifittool will not parse the region for MCU entries, and only locate the region and insert its address into FIT. +config INTEL_TOP_SWAP_SEPARATE_REGIONS + bool "Place the regular and Top Swap bootblocks in separate fmap regions" + depends on INTEL_ADD_TOP_SWAP_BOOTBLOCK && BOOTBLOCK_IN_CBFS + default n + help + Place the bootblocks in BOOTBLOCK and TOPSWAP regions for easy access, to + facilitate firmware updates using the Top Swap as Slot A/Slot B redundancy. + Requires a custom .fmd with the regions added at the end. + endif config SOC_INTEL_COMMON From 9677c49091b8506f1b85fb6fbbca4835ad50a105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Lewi=C5=84ski?= Date: Tue, 18 Nov 2025 15:56:45 +0100 Subject: [PATCH 5/9] src/southbridge/intel/common/firmware/Makefile.mk: fix after cherrypick MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Iad2722b474b0919d60731dbe2df6e9b571927c30 Signed-off-by: Filip Lewiński --- src/southbridge/intel/common/firmware/Makefile.mk | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/southbridge/intel/common/firmware/Makefile.mk b/src/southbridge/intel/common/firmware/Makefile.mk index ba5447f341c..10b1c4c906b 100644 --- a/src/southbridge/intel/common/firmware/Makefile.mk +++ b/src/southbridge/intel/common/firmware/Makefile.mk @@ -64,7 +64,7 @@ else printf " DD Adding Intel Firmware Descriptor\n" dd if=$(IFD_BIN_PATH) \ of=$(obj)/coreboot.pre conv=notrunc >/dev/null 2>&1 - +endif ifeq ($(CONFIG_IFDTOOL_DISABLE_ME),y) printf " IFDTOOL set AltMeDisable/HAP bit\n" $(objutil)/ifdtool/ifdtool \ @@ -72,7 +72,6 @@ ifeq ($(CONFIG_IFDTOOL_DISABLE_ME),y) --altmedisable 1 \ -O $(obj)/coreboot.pre \ $(obj)/coreboot.pre - endif ifeq ($(CONFIG_VALIDATE_INTEL_DESCRIPTOR),y) printf " IFDTOOL validate IFD against FMAP\n" From 73e37583bc215b1281edcb0dd1635516cdfc8777 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 6/9] 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 --- 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 e9a691c37bf..7ef78b6884f 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 @@ -34,4 +35,7 @@ void bootblock_soc_init(void) if (CONFIG(INTEL_CBNT_LOGGING)) intel_cbnt_log_registers(); + + 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 cb26881506a..7037dd76af9 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 0f09d7e0fb7..ca53996c6b5 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 5a5de912bba..fd8dc887551 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 From 1618304d93a322bcfe07075952e949ba6b3d191b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Lewi=C5=84ski?= Date: Fri, 21 Nov 2025 12:19:48 +0100 Subject: [PATCH 7/9] soc/intel/common/block/rtc/rtc.c: Top Swap: add Slot B selection mechanism MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- Makefile.mk | 14 ++++++++------ src/include/fmap.h | 4 ++++ src/lib/cbfs.c | 16 ++++++++++++++-- src/soc/intel/common/block/rtc/rtc.c | 17 +++++++++++++++++ 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/Makefile.mk b/Makefile.mk index e8ffd70bd4d..c320f68d2b2 100644 --- a/Makefile.mk +++ b/Makefile.mk @@ -996,6 +996,14 @@ extract_nth=$(subst *,$(spc),$(patsubst -%-,%,$(word $(1), $(subst |,- -,-$(2)-) # multiple CBFSes in fmap regions, override it. 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) cbfs-autogen-attributes=-g endif @@ -1288,12 +1296,6 @@ $(obj)/fmap.fmap: $(obj)/fmap.fmd $(FMAPTOOL) echo " FMAP $(FMAPTOOL) -h $(obj)/fmap_config.h $< $@" $(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) BB_FIT_REGION = COREBOOT TS_FIT_REGION = COREBOOT diff --git a/src/include/fmap.h b/src/include/fmap.h index 761e742f560..b21701e87ae 100644 --- a/src/include/fmap.h +++ b/src/include/fmap.h @@ -8,6 +8,10 @@ #include #include +/* Return the name of the boot region. Falls back to COREBOOT, if not overriden + * by any multi-slot mechanism (e.g Intel Top Swap, vboot). */ +const char *cbfs_fmap_region_hint(const char *default_region); + /* 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 * 0 on success, < 0 on error. */ diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c index df34594a53c..d501e782c3b 100644 --- a/src/lib/cbfs.c +++ b/src/lib/cbfs.c @@ -31,6 +31,11 @@ struct mem_pool cbfs_cache = MEM_POOL_INIT(_cbfs_cache, REGION_SIZE(cbfs_cache), CONFIG_CBFS_CACHE_ALIGN); #endif +__weak const char *cbfs_fmap_region_hint(const char *default_region) +{ + return default_region; +} + static void switch_to_postram_cache(int unused) { 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) { + printk(BIOS_DEBUG, "Starting cbfs_boot_device\n"); static struct cbfs_boot_device ro; /* 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)) return &ro; - if (fmap_locate_area_as_rdev("COREBOOT", &ro.rdev)) - die("Cannot locate primary CBFS"); + /* Falls back to the default COREBOOT region if no overriding mechanisms are in + place (e.g. Intel Top Swap). */ + const char *region = cbfs_fmap_region_hint("COREBOOT"); + + 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) { enum cb_err err = cbfs_init_boot_device(&ro, metadata_hash_get()); diff --git a/src/soc/intel/common/block/rtc/rtc.c b/src/soc/intel/common/block/rtc/rtc.c index fd8dc887551..718aab41987 100644 --- a/src/soc/intel/common/block/rtc/rtc.c +++ b/src/soc/intel/common/block/rtc/rtc.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include #include @@ -69,4 +70,20 @@ void sync_rtc_buc_top_swap(void) board_reset(); } } + +/* + * Select the FMAP region to continue booting from, depending on the state of + * Top Swap + */ +const char *cbfs_fmap_region_hint(const char *default_region) +{ + if (!CONFIG(INTEL_TOP_SWAP_OPTION_CONTROL)) + return default_region; + + if (get_rtc_buc_top_swap_status()) + return "COREBOOT_TS"; + else + return "COREBOOT"; +} + #endif From 27b95fe1d706d5c184a2d6ff80f15f85e35edb7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Go=C5=82a=C5=9B?= Date: Thu, 9 Oct 2025 12:34:45 +0200 Subject: [PATCH 8/9] intel soc,southbridge: Add Kconfig to set TSBS in IFD during build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To modify the Top Swap Block Size in the FD (if provided and CONFIG_HAVE_IFD_BIN=y), set the following Kconfig variables: - CONFIG_INTEL_HAS_TOP_SWAP - CONFIG_INTEL_ADD_TOP_SWAP_BOOTBLOCK - CONFIG_INTEL_TOP_SWAP_BOOTBLOCK_SIZE - CONFIG_INTEL_IFD_SET_TOP_SWAP_BOOTBLOCK_SIZE Needed for the bootblock redundancy feature suggested at https://mail.coreboot.org/archives/list/coreboot@coreboot.org/thread/C6JN2PB7K7D67EG7OIKB6BBERZU5YV35/ TEST=build VP66xx with custom Kconfig, check if TSBS is modified in FD Change-Id: I94d3d3e2511a7e56392a9e34f845ae91602ce7f1 Signed-off-by: Filip Gołaś Reviewed-on: https://review.coreboot.org/c/coreboot/+/89493 Reviewed-by: Sergii Dmytruk Tested-by: build bot (Jenkins) --- 3rdparty/dasharo-blobs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty/dasharo-blobs b/3rdparty/dasharo-blobs index f786573d2c0..b1e4c3ad236 160000 --- a/3rdparty/dasharo-blobs +++ b/3rdparty/dasharo-blobs @@ -1 +1 @@ -Subproject commit f786573d2c04dfd3a9698ced69610052909ab448 +Subproject commit b1e4c3ad2363ee36dfef76acf640a8d48a0237bf From 9e8b8dda400e1cf6c7bea22d99e4e562cfdf5276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Lewi=C5=84ski?= Date: Thu, 13 Nov 2025 09:58:24 +0100 Subject: [PATCH 9/9] downstream-specific config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ib183a1f72ee8585b2c4ad4376344de33ff54cbb9 Signed-off-by: Filip Lewiński --- build.sh | 2 +- configs/config.protectli_vp66xx_cmos_edk2 | 62 +++++++++++++++++++ configs/config.protectli_vp66xx_cmos_seabios | 24 +++++++ src/mainboard/protectli/vault_adl_p/Kconfig | 10 ++- .../protectli/vault_adl_p/cmos.default | 6 ++ .../protectli/vault_adl_p/cmos.layout | 47 ++++++++++++++ .../protectli/vault_adl_p/top_swap.fmd | 40 ++++++++++++ 7 files changed, 189 insertions(+), 2 deletions(-) create mode 100644 configs/config.protectli_vp66xx_cmos_edk2 create mode 100644 configs/config.protectli_vp66xx_cmos_seabios create mode 100644 src/mainboard/protectli/vault_adl_p/cmos.default create mode 100644 src/mainboard/protectli/vault_adl_p/cmos.layout create mode 100644 src/mainboard/protectli/vault_adl_p/top_swap.fmd diff --git a/build.sh b/build.sh index 3493287b7a2..73fbb402c8e 100755 --- a/build.sh +++ b/build.sh @@ -359,7 +359,7 @@ case "$CMD" in build_msi ddr5 "Z790-P DDR5 " ;; "vp66xx" | "VP66XX") - BOARD="vp66xx" + BOARD="vp66xx_cmos_edk2" build_protectli_vault ;; "vp46xx" | "VP46XX") diff --git a/configs/config.protectli_vp66xx_cmos_edk2 b/configs/config.protectli_vp66xx_cmos_edk2 new file mode 100644 index 00000000000..4f25318fe3a --- /dev/null +++ b/configs/config.protectli_vp66xx_cmos_edk2 @@ -0,0 +1,62 @@ +CONFIG_LOCALVERSION="v0.9.3-rc1" +CONFIG_USE_OPTION_TABLE=y +CONFIG_VENDOR_PROTECTLI=y +CONFIG_PCIEXP_L1_SUB_STATE=y +CONFIG_PCIEXP_CLK_PM=y +CONFIG_IFD_BIN_PATH="3rdparty/dasharo-blobs/$(MAINBOARDDIR)/descriptor.bin" +CONFIG_ME_BIN_PATH="3rdparty/dasharo-blobs/$(MAINBOARDDIR)/me.bin" +CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x100000 +CONFIG_HAVE_IFD_BIN=y +CONFIG_BOARD_PROTECTLI_VP66XX=y +CONFIG_POWER_STATE_OFF_AFTER_FAILURE=y +CONFIG_HAVE_ME_BIN=y +CONFIG_ME_REGION_ALLOW_CPU_READ_ACCESS=y +CONFIG_PCIEXP_LANE_ERR_STAT_CLEAR=y +CONFIG_DRIVERS_EFI_VARIABLE_STORE=y +CONFIG_DRIVERS_EFI_FW_INFO=y +CONFIG_DRIVERS_GENERIC_CBFS_SERIAL=y +CONFIG_DRIVERS_GENERIC_CBFS_UUID=y +CONFIG_TPM2=y +# CONFIG_CONSOLE_USE_ANSI_ESCAPES is not set +CONFIG_POST_DEVICE_LPC=y +CONFIG_PAYLOAD_EDK2=y +CONFIG_EDK2_SERIAL_SUPPORT=y +CONFIG_DASHARO=y +CONFIG_EDK2_DASHARO_SERIAL_REDIRECTION_DEFAULT_ENABLE=y +# CONFIG_EDK2_SECURE_BOOT_DEFAULT_ENABLE is not set +CONFIG_EDK2_HAVE_2ND_UART=y +CONFIG_EDK2_DASHARO_SERIAL_REDIRECTION2_DEFAULT_ENABLE=y +CONFIG_EDK2_DASHARO_CPU_CONFIG=y +CONFIG_EDK2_CORE_DISABLE_OPTION=y +CONFIG_EDK2_HYPERTHREADING_OPTION=y +CONFIG_EDK2_BOOT_MENU_KEY=0x0015 +CONFIG_EDK2_SETUP_MENU_KEY=0x0008 +CONFIG_EDK2_DISABLE_OPTION_ROMS=y +CONFIG_EDK2_CREATE_PREINSTALLED_BOOT_OPTIONS=y +CONFIG_EDK2_SETUP_PASSWORD=y +CONFIG_EDK2_DASHARO_SYSTEM_FEATURES=y +CONFIG_EDK2_DASHARO_SECURITY_OPTIONS=y +CONFIG_EDK2_DASHARO_USB_CONFIG=y +CONFIG_EDK2_DASHARO_POWER_CONFIG=y +CONFIG_EDK2_FAN_CURVE_OPTION=y +CONFIG_EDK2_FAN_OFF_CURVE_OPTION=y +CONFIG_EDK2_CPU_THROTTLING_THRESHOLD_OPTION=y +CONFIG_EDK2_DASHARO_NETWORK_BOOT_DEFAULT_ENABLE=y +CONFIG_EDK2_USE_EDK2_PLATFORMS=y +CONFIG_EDK2_PLATFORMS_REPOSITORY="https://github.com/Dasharo/edk2-platforms" +CONFIG_EDK2_PLATFORMS_TAG_OR_REV="1002a59639f111a2f8178b77d1f5fde0ea8d976f" +CONFIG_EDK2_CBMEM_LOGGING=y +CONFIG_EDK2_FOLLOW_BGRT_SPEC=y +# CONFIG_EDK2_PRIORITIZE_INTERNAL is not set +# CONFIG_EDK2_PS2_SUPPORT is not set +CONFIG_EDK2_SERIAL_SUPPORT=y +CONFIG_BUILD_IPXE=y +CONFIG_IPXE_ADD_SCRIPT=y +CONFIG_IPXE_SCRIPT="3rdparty/dasharo-blobs/dasharo/protectli.ipxe" +CONFIG_IPXE_CUSTOM_BUILD_ID="0123456789" +CONFIG_EDK2_ENABLE_IPXE=y +CONFIG_EDK2_IPXE_OPTION_NAME="Network Boot and Utilities" +CONFIG_DEFAULT_CONSOLE_LOGLEVEL_0=y +# CONFIG_CONSOLE_USE_LOGLEVEL_PREFIX is not set +# CONFIG_CONSOLE_USE_ANSI_ESCAPES is not set +CONFIG_POST_DEVICE_LPC=y diff --git a/configs/config.protectli_vp66xx_cmos_seabios b/configs/config.protectli_vp66xx_cmos_seabios new file mode 100644 index 00000000000..948f34fd8c4 --- /dev/null +++ b/configs/config.protectli_vp66xx_cmos_seabios @@ -0,0 +1,24 @@ +CONFIG_LOCALVERSION="v0.9.3-rc1" +CONFIG_VENDOR_PROTECTLI=y +CONFIG_BOARD_PROTECTLI_VP66XX=y +CONFIG_PCIEXP_L1_SUB_STATE=y +CONFIG_PCIEXP_CLK_PM=y +CONFIG_IFD_BIN_PATH="3rdparty/dasharo-blobs/$(MAINBOARDDIR)/descriptor.bin" +CONFIG_ME_BIN_PATH="3rdparty/dasharo-blobs/$(MAINBOARDDIR)/me.bin" +CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x100000 +CONFIG_HAVE_IFD_BIN=y +CONFIG_POWER_STATE_OFF_AFTER_FAILURE=y +CONFIG_HAVE_ME_BIN=y +CONFIG_ME_REGION_ALLOW_CPU_READ_ACCESS=y +CONFIG_PCIEXP_LANE_ERR_STAT_CLEAR=y +CONFIG_DRIVERS_GENERIC_CBFS_SERIAL=y +CONFIG_DRIVERS_GENERIC_CBFS_UUID=y +CONFIG_TPM2=y +CONFIG_BOOTMEDIA_LOCK_CONTROLLER=y +CONFIG_BOOTMEDIA_SMM_BWP=y +# CONFIG_CONSOLE_USE_ANSI_ESCAPES is not set +CONFIG_POST_DEVICE_LPC=y +# CONFIG_OPTION_BACKEND_NONE is not set +CONFIG_HAVE_OPTION_TABLE=y +CONFIG_HAVE_CMOS_DEFAULT=y +CONFIG_USE_OPTION_TABLE=y diff --git a/src/mainboard/protectli/vault_adl_p/Kconfig b/src/mainboard/protectli/vault_adl_p/Kconfig index aa8da560753..815ab48eb89 100644 --- a/src/mainboard/protectli/vault_adl_p/Kconfig +++ b/src/mainboard/protectli/vault_adl_p/Kconfig @@ -16,6 +16,13 @@ config BOARD_SPECIFIC_OPTIONS select INTEL_GMA_HAVE_VBT select MEMORY_MAPPED_TPM select USE_DDR5 + select HAVE_OPTION_TABLE + select HAVE_CMOS_DEFAULT + select USE_OPTION_TABLE + select INTEL_HAS_TOP_SWAP + select INTEL_ADD_TOP_SWAP_BOOTBLOCK + select INTEL_TOP_SWAP_SEPARATE_REGIONS + select INTEL_TOP_SWAP_OPTION_CONTROL config MAINBOARD_DIR default "protectli/vault_adl_p" @@ -67,7 +74,8 @@ config SOC_INTEL_CSE_SEND_EOP_EARLY default n config FMDFILE - default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwa.fmd" if VBOOT && VBOOT_SLOTS_RW_A + default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwa.fmd" if VBOOT + default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/top_swap.fmd" if INTEL_HAS_TOP_SWAP config BEEP_ON_BOOT bool "Beep on successful boot" diff --git a/src/mainboard/protectli/vault_adl_p/cmos.default b/src/mainboard/protectli/vault_adl_p/cmos.default new file mode 100644 index 00000000000..ee8f645e365 --- /dev/null +++ b/src/mainboard/protectli/vault_adl_p/cmos.default @@ -0,0 +1,6 @@ +## SPDX-License-Identifier: GPL-2.0-only + +boot_option=Fallback +debug_level=Debug +me_state=Disable +attempt_slot_b=Disable diff --git a/src/mainboard/protectli/vault_adl_p/cmos.layout b/src/mainboard/protectli/vault_adl_p/cmos.layout new file mode 100644 index 00000000000..d5b0813cd18 --- /dev/null +++ b/src/mainboard/protectli/vault_adl_p/cmos.layout @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: GPL-2.0-only + +entries + +0 384 r 0 reserved_memory + +# RTC_BOOT_BYTE (coreboot hardcoded) +384 1 e 4 boot_option +388 4 h 0 reboot_counter + +# RTC_CLK_ALTCENTURY +400 8 r 0 century + +412 4 e 6 debug_level +416 1 e 2 me_state +417 3 h 0 me_state_counter +420 1 e 7 attempt_slot_b + +# CMOS_VSTART_ramtop +800 80 r 0 ramtop + +984 16 h 0 check_sum + +enumerations + +2 0 Enable +2 1 Disable + +4 0 Fallback +4 1 Normal + +6 0 Emergency +6 1 Alert +6 2 Critical +6 3 Error +6 4 Warning +6 5 Notice +6 6 Info +6 7 Debug +6 8 Spew + +7 0 Disable +7 1 Enable + +checksums + +checksum 408 799 984 diff --git a/src/mainboard/protectli/vault_adl_p/top_swap.fmd b/src/mainboard/protectli/vault_adl_p/top_swap.fmd new file mode 100644 index 00000000000..703d63701b3 --- /dev/null +++ b/src/mainboard/protectli/vault_adl_p/top_swap.fmd @@ -0,0 +1,40 @@ +FLASH 16M { + SI_ALL@0x0 { + SI_DESC 4K + SI_ME 0x4c0000 + SI_DEVICEEXT2 0xbf000 + } + SI_BIOS@0x580000 0xa80000 { + SMMSTORE(PRESERVE) 256K + + RW_MISC 320K { + UNIFIED_MRC_CACHE(PRESERVE) { + RECOVERY_MRC_CACHE 128K + RW_MRC_CACHE 128K + } + RW_VPD(PRESERVE) 8K + RW_NVRAM(PRESERVE) 24K + } + + BOOTSPLASH(CBFS) 512K + + RW_SECTION_A { + VBLOCK_A 64K + COREBOOT_TS(CBFS) + RW_FWID_A 0x100 + } + + WP_RO 4M { + RO_VPD(PRESERVE) 16K + RO_SECTION { + FMAP 2K + RO_FRID 0x100 + RO_FRID_PAD 0x700 + GBB 12K + COREBOOT(CBFS) + } + } + TOPSWAP(CBFS) 512K + BOOTBLOCK(CBFS) 512K + } +}