Simon Glass has uploaded this change for review.

View Change

Support CCB in a CBFS file

Enhance the CCB to allow it to be in a CBFS file, instead of embedded in
the bootblock. This is fairly straightforward, with just a little more
logic in the CCB implementation and cbfstool.

The CBFS file is not added by the build, so configuration must be
updated afterwards using cbfstool, otherwise a default CCB (all zeroes)
is used.

Note that with this option the CCB init happens later in bootblock, so
that the first part of the bootblock console output cannot be controlled
by CCB. This is because we want to avoid accessing FMAP/CBFS when the
console is off, in case something goes wrong.

BUG=b:172341184, b:262546009, b:249105972
BRANCH=none
TEST=see next CL

Change-Id: Id67e472afa67909065f1b1e45e5a8c2f112af367
Signed-off-by: Simon Glass <sjg@chromium.org>
---
M Documentation/technotes/ccb.md
M src/Kconfig
M src/include/program_loading.h
M src/lib/bootblock.c
M src/lib/ccb.c
M util/cbfstool/cbfstool.c
6 files changed, 91 insertions(+), 2 deletions(-)

git pull ssh://review.coreboot.org:29418/coreboot refs/changes/92/83292/1
diff --git a/Documentation/technotes/ccb.md b/Documentation/technotes/ccb.md
index f913cca..bdb9b18 100644
--- a/Documentation/technotes/ccb.md
+++ b/Documentation/technotes/ccb.md
@@ -77,9 +77,14 @@
and into CBMEM. Thus it can be used by the following stages which don't have
access to the cache.

-## Future extensions
+Some boards use a signed bootblock which cannot easily be modified after
+building, since it requires resigning parts of the image. To address this, the
+CCB can be stored in CBFS instead, accessed from the romstage. This means it is
+unable to affect the operation of bootblock, of course. This is controlled by
+the CCB_CBFS option. This applies mostly to AMD, since Intel platforms, do not
+have a signed bootblock.

-CCB could be stored in a CBFS file.
+## Future extensions

CCB could be stored in an FMAP region.

diff --git a/src/Kconfig b/src/Kconfig
index 6ce95a1..bee8363 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -604,6 +604,18 @@

See Documentation/util/cbfstool/ccb.md for more information.

+config CCB_CBFS
+ bool "Read coreboot control block from CBFS"
+ depends on CCB
+ help
+ Enable this to read the CCB (coreboot control block) from a file in
+ CBFS. The file is read after CBFS is inited in bootblock.
+
+ The CCB provides a few simple settings for coreboot which can be
+ changed using the 'cbfstool set-ccb' command.
+
+ See Documentation/util/cbfstool/ccb.md for more information.
+
endchoice

menu "Software Bill Of Materials (SBOM)"
diff --git a/src/include/program_loading.h b/src/include/program_loading.h
index e53cb7c..dad6b41 100644
--- a/src/include/program_loading.h
+++ b/src/include/program_loading.h
@@ -25,6 +25,7 @@
PROG_BL32,
PROG_POSTCAR,
PROG_OPENSBI,
+ PROG_CCB,
};

/*
diff --git a/src/lib/bootblock.c b/src/lib/bootblock.c
index de95e61..454e538 100644
--- a/src/lib/bootblock.c
+++ b/src/lib/bootblock.c
@@ -51,6 +51,7 @@
if (CONFIG(CMOS_POST))
cmos_post_init();

+ /* if CCB is available without any setup, init it now */
if (ENV_HOLDS_CCB)
ccb_init();

@@ -59,6 +60,14 @@
exception_init();
}

+ /* late init of CCB for when CCB is in CBFS */
+ if (!ENV_HOLDS_CCB) {
+ ccb_init();
+
+ /* check if the console should be silent */
+ console_check_silent();
+ }
+
bootblock_soc_init();
bootblock_mainboard_init();

diff --git a/src/lib/ccb.c b/src/lib/ccb.c
index b50a7f9..c45ea04 100644
--- a/src/lib/ccb.c
+++ b/src/lib/ccb.c
@@ -77,6 +77,20 @@
ccb = cbmem_find(CBMEM_ID_CCB);
if (!ccb) /* This should not happen */
printk(BIOS_ERR, "CCB: Not found in CBMEM\n");
+ } else if (CONFIG(CCB_CBFS)) {
+ struct prog ccb_file = PROG_INIT(PROG_CCB, "ccb");
+ struct region_device rdev;
+ union cbfs_mdata mdata;
+
+ if (_cbfs_boot_lookup(prog_name(&ccb_file), true, &mdata, &rdev)) {
+ printk(BIOS_DEBUG, "CCB: No file in CBFS\n");
+ return NULL;
+ }
+ if (region_device_sz(&rdev) != sizeof(struct ccb)) {
+ printk(BIOS_ERR, "CCB: Incorrect file size in CBFS\n");
+ return NULL;
+ }
+ ccb = rdev_mmap_full(&rdev);
} else {
/* we cannot get here */
BUG();
diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c
index 07fc057..987f71e 100644
--- a/util/cbfstool/cbfstool.c
+++ b/util/cbfstool/cbfstool.c
@@ -715,6 +715,54 @@
}
}

+ INFO("CCB not in bootblock\n");
+
+ struct cbfs_image image;
+ struct cbfs_file *ccb_file;
+ const char *filename = "ccb";
+ struct buffer ccb_buf;
+
+ if (cbfs_image_from_buffer(&image, param.image_region, param.headeroffset))
+ return 1;
+
+ ccb_file = cbfs_get_entry(&image, filename);
+ if (!ccb_file) {
+ struct cbfs_file *header;
+ struct ccb *ccb;
+ int ret;
+
+ INFO("CCB not in CBFS: creating\n");
+
+ if (buffer_create(&ccb_buf, sizeof(struct ccb), filename))
+ return 1;
+
+ header = cbfs_create_file_header(CBFS_TYPE_RAW, ccb_buf.size,
+ filename);
+
+ ccb = buffer_get(&ccb_buf);
+ memset(ccb, '\0', sizeof(struct ccb));
+ ccb->magic = CCB_MAGIC;
+
+ ret = cbfs_add_entry(&image, &ccb_buf, 0, header, 0);
+ free(header);
+ buffer_delete(&ccb_buf);
+ if (ret) {
+ ERROR("Failed to add '%s' into ROM image.\n", filename);
+ return 1;
+ }
+ ccb_file = cbfs_get_entry(&image, filename);
+ }
+
+ if (!ccb_file) {
+ ERROR("Cannot get file\n");
+ return 1;
+ }
+
+ /* Locate the CCB */
+ *ccbp = (void *)ccb_file + be32toh(ccb_file->offset);
+
+ return 0;
+
no_bootblock:
ERROR("CCB not in ROM image?!?\n");
return 1;

To view, visit change 83292. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: newchange
Gerrit-Project: coreboot
Gerrit-Branch: main
Gerrit-Change-Id: Id67e472afa67909065f1b1e45e5a8c2f112af367
Gerrit-Change-Number: 83292
Gerrit-PatchSet: 1
Gerrit-Owner: Simon Glass <sjg@chromium.org>