Patrick Rudolph has uploaded this change for review.

View Change

[RFC]lib/coreboot_tables: Introduce BOOT_MEDIA_PARAMS2

BOOT_MEDIA_PARAMS2 exposes the boot media MMIO address if it's
memory mapped in addition to various regions inside the bootmedia.

That information can be used by payloads to:
* Support VBOOT on SeaBIOS, as it otherwise uses the RO CBFS only
* Support Intel Apollolake and platforms that don't map the end of
the BIOS region to the end of the address space
* Support fwupd and flashrom finding the FMAP in memory

Change-Id: Ia0b1ac927b8782cc99cd7f34d8bf5c4ef60b5570
Signed-off-by: Patrick Rudolph <siro@das-labor.org>
---
M src/commonlib/include/commonlib/coreboot_tables.h
M src/lib/coreboot_table.c
2 files changed, 118 insertions(+), 0 deletions(-)

git pull ssh://review.coreboot.org:29418/coreboot refs/changes/07/33107/1
diff --git a/src/commonlib/include/commonlib/coreboot_tables.h b/src/commonlib/include/commonlib/coreboot_tables.h
index 198ad27..a854e44 100644
--- a/src/commonlib/include/commonlib/coreboot_tables.h
+++ b/src/commonlib/include/commonlib/coreboot_tables.h
@@ -392,6 +392,81 @@
struct mac_address mac_addrs[0];
};

+/**
+ * coreboot boot media params2
+ *
+ * The coreboot 'boot media params2' contain information about the
+ * bootmedia layout, allowing a payload to read the boot media
+ * without the need to parse (platform specific) layout files.
+ *
+ * It extends 'boot media params' by MMIO addresses and a second CBFS
+ * pointer.
+ *
+ * If the boot media is memory mapped, as it's usually done on x86 platforms,
+ * the FMAP and CBFS can be easily accessed by any software without the need
+ * for platform specific drivers.
+ *
+ * If the boot media is not memory mapped, the `mmap_mmio_address` is set
+ * to ~0ULL. In that case the software must use platform specific drivers
+ * to access the boot media (like flashrom or Linux's MTD).
+ *
+ * The memory mapped area is `mmap_size` bytes in size, starting `mmap_offset`
+ * bytes from `mmap_mmio_address`.
+ * The memory mapped area might be smaller than `boot_media_size` bytes,
+ * which gives the total size in bytes as seen by an external programmer.
+ *
+ * Software utilizing the coreboot boot media params2 shall check if the
+ * region to be access falls completely within the memory mapped region,
+ * before trying to access them.
+ * In addition it should not assume that the whole boot media is memory mapped.
+ *
+ * Example on Intel Apollolake:
+ *
+ * physical memory boot media
+ * +-----------+
+ * | |
+ * | |
+ * +-----------+ MMAP MMIO address +-----------------+ --------
+ * | ~UNAVAIL~ | | | IFD | | | | |
+ * | | MMAP offset | | | | | |
+ * | | | | | | | | |
+ * +-----------+ --- <<< +-----------------+ | | | |
+ * | BIOS REG | | | BIOS | | | | |
+ * | | | | | | | | |
+ * | | | |+---------------+| --+-+-+-+CBFS offset
+ * | | | || CBFS Active || | | |
+ * | | MMAP size |+---------------+| --+-+-+FMAP offset
+ * | | | || FMAP || | |
+ * | | | |+---------------+| --+-+CBFS legacy offset
+ * | | | || COREBOOT(CBFS)|| |
+ * +-----------+ --- <<< |+---------------+| |
+ * | TXE SRAM | || BIOS UNUSABLE || |
+ * | | |+---------------+| |
+ * +-----------+ +-----------------+ |
+ * |DEVICE EXTENSION | |
+ * | | |
+ * +-----------------+ -+Boot media size
+ */
+
+#define LB_TAG_BOOT_MEDIA_PARAMS2 0x0036
+struct lb_boot_media_params2 {
+ uint32_t tag;
+ uint32_t size;
+ /* offsets are relative to start of boot media */
+ uint64_t fmap_offset;
+ uint64_t cbfs_offset;
+ uint64_t cbfs_legacy_offset;
+ uint64_t mmap_offset;
+ /* Size is in bytes */
+ uint64_t cbfs_size;
+ uint64_t fmap_size;
+ uint64_t boot_media_size;
+ uint64_t cbfs_legacy_size;
+ uint64_t mmap_size;
+ /* MMIO address of MMAPed boot media, ~0ULL if not MMAPed.*/
+ uint64_t mmap_mmio_address;
+};
+
#define LB_TAG_SERIALNO 0x002a
#define MAX_SERIALNO_LENGTH 32

diff --git a/src/lib/coreboot_table.c b/src/lib/coreboot_table.c
index 6e44f5d..c5807fd 100644
--- a/src/lib/coreboot_table.c
+++ b/src/lib/coreboot_table.c
@@ -261,8 +261,10 @@
static void lb_boot_media_params(struct lb_header *header)
{
struct lb_boot_media_params *bmp;
+ struct lb_boot_media_params2 *bmp2;
struct cbfs_props props;
const struct region_device *boot_dev;
+ struct region ar;
struct region_device fmrd;

boot_device_init();
@@ -285,6 +287,47 @@
bmp->fmap_offset = ~(uint64_t)0;
if (find_fmap_directory(&fmrd) == 0)
bmp->fmap_offset = region_device_offset(&fmrd);
+
+ /* LB_TAG_BOOT_MEDIA_PARAMS2 exposes additional parameters:
+ * - MMAPed boot media address
+ * - legacy CBFS position (RO partition in case of VBOOT)
+ */
+ bmp2 = (struct lb_boot_media_params2 *)lb_new_record(header);
+ bmp2->tag = LB_TAG_BOOT_MEDIA_PARAMS2;
+ bmp2->size = sizeof(*bmp2);
+
+ bmp2->cbfs_offset = bmp->cbfs_offset;
+ bmp2->cbfs_size = bmp->cbfs_size;
+ bmp2->boot_media_size = bmp->boot_media_size;
+ bmp2->fmap_offset = bmp->fmap_offset;
+
+ if (find_fmap_directory(&fmrd) == 0)
+ bmp2->fmap_size = region_device_size(&fmrd);
+
+ if (fmap_locate_area("COREBOOT", &ar)) {
+ printk(BIOS_INFO, "Can't find 'COREBOOT' area in FMAP\n");
+ bmp2->cbfs_legacy_offset = ~(uint64_t)0;
+ bmp2->cbfs_legacy_size = 0;
+ } else {
+ bmp2->cbfs_legacy_offset = ar.offset;
+ bmp2->cbfs_legacy_size = ar.size;
+ }
+
+ if (CONFIG(COMMON_CBFS_SPI_WRAPPER)) {
+ /* rdev_mmap will return a pointer to _postram_cbfs_cache */
+ bmp2->mmap_offset = ~(uint64_t)0;
+ bmp2->mmap_size = 0;
+ bmp2->mmap_mmio_address = ~(uint64_t)0;
+ } else {
+ /* FIXME: Introduce API to set correct values here */
+ bmp2->mmap_offset = 0;
+ bmp2->mmap_size = bmp2->boot_media_size;
+ /* Get address to MMAP boot media */
+ uintptr_t off = (uintptr_t)rdev_mmap(boot_dev, 0,
+ bmp2->mmap_size);
+ bmp2->mmap_mmio_address = off;
+ rdev_munmap(boot_dev, (void *)off);
+ }
}

static void lb_ram_code(struct lb_header *header)

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

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Ia0b1ac927b8782cc99cd7f34d8bf5c4ef60b5570
Gerrit-Change-Number: 33107
Gerrit-PatchSet: 1
Gerrit-Owner: Patrick Rudolph <siro@das-labor.org>
Gerrit-MessageType: newchange