[coreboot-gerrit] Patch set updated for coreboot: arch/x86: Add ability to place bootloader and payload in seperate FMAP regions

Timothy Pearson (tpearson@raptorengineering.com) gerrit at coreboot.org
Sun Aug 21 00:33:45 CEST 2016


Timothy Pearson (tpearson at raptorengineering.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16275

-gerrit

commit 3c51f18ce94e6e8196a59bad47c7e9ccb2fc544f
Author: Timothy Pearson <tpearson at raptorengineering.com>
Date:   Sat Aug 20 17:33:18 2016 -0500

    arch/x86: Add ability to place bootloader and payload in seperate FMAP regions
    
    Add KConfig menu options and glue code to allow placement of bootblock and
    payload files outside of the primary COREBOOT FMAP region.  Note that on
    x86 systems the bootblock FMAP region must be placed at the top of Flash
    ROM due to the location of the x86 reset vector.
    
    Test: Booted QEMU virtual machine with bootblock and Linux payload in
          separate FMAP regions from the main COREBOOT FMAP region.
    
    Change-Id: Ib7abc9a6b78c2092cfb222a25f4763d4bb3c9f8c
    Signed-off-by: Timothy Pearson <tpearson at raptorengineering.com>
---
 Makefile.inc                   | 24 ++++++++++++++++++++++++
 payloads/external/Makefile.inc |  5 +++++
 src/Kconfig                    | 27 +++++++++++++++++++++++++++
 src/arch/x86/mmap_boot.c       |  4 +++-
 src/arch/x86/walkcbfs.S        | 12 ++++++++++++
 src/include/cbfs.h             |  4 ++--
 src/lib/cbfs.c                 | 10 ++++++----
 src/lib/coreboot_table.c       |  2 +-
 src/lib/prog_loaders.c         |  9 ++++++++-
 9 files changed, 88 insertions(+), 9 deletions(-)

diff --git a/Makefile.inc b/Makefile.inc
index ff77747..fbc8f51 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -20,6 +20,8 @@ GIT:=$(shell [ -e "$(top)/.git" ] && command -v git)
 CONFIG_CBFS_PREFIX:=$(call strip_quotes,$(CONFIG_CBFS_PREFIX))
 CONFIG_FMDFILE:=$(call strip_quotes,$(CONFIG_FMDFILE))
 CONFIG_DEVICETREE:=$(call strip_quotes, $(CONFIG_DEVICETREE))
+CONFIG_FMAP_BOOTBLOCK_REGION:=$(call strip_quotes, $(CONFIG_FMAP_BOOTBLOCK_REGION))
+CONFIG_FMAP_PAYLOAD_REGION:=$(call strip_quotes, $(CONFIG_FMAP_PAYLOAD_REGION))
 
 #######################################################################
 # misleadingly named, this is the coreboot version
@@ -45,6 +47,18 @@ export MAINBOARDDIR
 ## These typically have suffixes .debug .elf .bin and .map
 export objcbfs := $(obj)/cbfs/$(CONFIG_CBFS_PREFIX)
 
+ifeq ($(CONFIG_FMAP_BOOTBLOCK_REGION),)
+export cbfs_bootblock_region := COREBOOT
+else
+export cbfs_bootblock_region := $(CONFIG_FMAP_BOOTBLOCK_REGION)
+endif
+
+ifeq ($(CONFIG_FMAP_PAYLOAD_REGION),)
+export cbfs_payload_region := COREBOOT
+else
+export cbfs_payload_region := $(CONFIG_FMAP_PAYLOAD_REGION)
+endif
+
 ## Based on the active configuration, Makefile conditionally collects
 ## the required assembly includes and saves them in a file.
 ## Such files that do not have a clear one-to-one relation to a source
@@ -197,6 +211,7 @@ romstage-c-deps:=$$(OPTION_TABLE_H)
 libverstage-c-deps:=$$(OPTION_TABLE_H)
 verstage-c-deps:=$$(OPTION_TABLE_H)
 bootblock-c-deps:=$$(OPTION_TABLE_H)
+bootblock-c-deps += $(obj)/fmap_config.h
 
 # Add handler to copy linker scripts
 define generic-objs_ld_template_gen
@@ -761,6 +776,8 @@ $(obj)/fmap.desc: $(obj)/fmap.fmap
 $(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 $< $@
+	@echo "#define FMAP_CBFS_PAYLOAD_BASE ___FMAP__$(cbfs_payload_region)_BASE" >> $(obj)/fmap_config.h
+	@echo "#define FMAP_CBFS_PAYLOAD_SIZE ___FMAP__$(cbfs_payload_region)_SIZE" >> $(obj)/fmap_config.h
 
 ifneq ($(CONFIG_UPDATE_IMAGE),y)
 $(obj)/coreboot.pre: $(objcbfs)/bootblock.bin $$(prebuilt-files) $(CBFSTOOL) $$(cpu_ucode_cbfs_file) $(obj)/fmap.fmap $(obj)/fmap.desc
@@ -770,6 +787,7 @@ ifeq ($(CONFIG_ARCH_X86),y)
 		-f $(objcbfs)/bootblock.bin \
 		-n bootblock \
 		-t bootblock \
+		-r $(cbfs_bootblock_region) \
 		-b -$(call file-size,$(objcbfs)/bootblock.bin) $(cbfs-autogen-attributes)
 else # ifeq ($(CONFIG_ARCH_X86),y)
 	$(CBFSTOOL) $@.tmp write -u \
@@ -786,6 +804,12 @@ else # ifeq ($(CONFIG_ARCH_X86),y)
 	rm -f $@.tmp.2
 endif # ifeq ($(CONFIG_ARCH_X86),y)
 	$(CBFSTOOL) $@.tmp add-master-header
+ifneq ($(CONFIG_FMAP_BOOTBLOCK_REGION),COREBOOT)
+	$(CBFSTOOL) $@.tmp add-master-header -r $(cbfs_bootblock_region)
+endif # ifneq ($(CONFIG_FMAP_BOOTBLOCK_REGION),COREBOOT)
+ifneq ($(CONFIG_FMAP_PAYLOAD_REGION),COREBOOT)
+	$(CBFSTOOL) $@.tmp add-master-header -r $(cbfs_payload_region)
+endif # ifneq ($(CONFIG_FMAP_PAYLOAD_REGION),COREBOOT)
 	$(prebuild-files) true
 	mv $@.tmp $@
 else # ifneq ($(CONFIG_UPDATE_IMAGE),y)
diff --git a/payloads/external/Makefile.inc b/payloads/external/Makefile.inc
index 98ed4d2..31ee597 100644
--- a/payloads/external/Makefile.inc
+++ b/payloads/external/Makefile.inc
@@ -179,3 +179,8 @@ payloads/external/iPXE/ipxe/ipxe.rom ipxe: $(DOTCONFIG)
 	IPXE_UART=$(IPXE_UART) \
 	CONFIG_TTYS0_BAUD=$(CONFIG_TTYS0_BAUD) \
 	MFLAGS= MAKEFLAGS=
+
+regions-for-file = $(subst $(spc),$(comma),$(sort \
+	$(if $(filter \
+		%payload \
+		,$(1)),$(cbfs_payload_region),COREBOOT)))
\ No newline at end of file
diff --git a/src/Kconfig b/src/Kconfig
index 7db491f..13f0163 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -35,6 +35,33 @@ config CBFS_PREFIX
 	  Select the prefix to all files put into the image. It's "fallback"
 	  by default, "normal" is a common alternative.
 
+menu "FMAP Region Setup"
+	depends on ARCH_X86
+
+config FMAP_SEPARATE_BOOTBLOCK_REGION
+	bool "Store bootblock in separate FMAP region"
+	default n
+	depends on ARCH_X86
+	help
+	 Store the bootblock in a separate FMAP region.
+
+config FMAP_BOOTBLOCK_REGION
+	string "FMAP region to place bootblock"
+	default "COREBOOT"
+	depends on FMAP_SEPARATE_BOOTBLOCK_REGION
+	help
+	  Select the FMAP region into which the bootblock will be placed.
+	  It's "COREBOOT" by default, "BOOTBLOCK" is a common alternative.
+
+config FMAP_PAYLOAD_REGION
+	string "FMAP region to place payload"
+	default "COREBOOT"
+	help
+	  Select the FMAP region into which the payload will be placed.
+	  It's "COREBOOT" by default, "FW_MAIN_A" is a common alternative.
+
+endmenu
+
 choice
 	prompt "Compiler to use"
 	default COMPILER_GCC
diff --git a/src/arch/x86/mmap_boot.c b/src/arch/x86/mmap_boot.c
index 35a7544..d616836 100644
--- a/src/arch/x86/mmap_boot.c
+++ b/src/arch/x86/mmap_boot.c
@@ -29,7 +29,8 @@ const struct region_device *boot_device_ro(void)
 	return &boot_dev.rdev;
 }
 
-static int cbfs_master_header_props(struct cbfs_props *props)
+#if !IS_ENABLED(CONFIG_FMAP_SEPARATE_BOOTBLOCK_REGION)
+static int cbfs_master_header_props(struct cbfs_props *props, uint32_t *type)
 {
 	struct cbfs_header header;
 	int32_t offset;
@@ -69,3 +70,4 @@ const struct cbfs_locator cbfs_master_header_locator = {
 	.name = "Master Header Locator",
 	.locate = cbfs_master_header_props,
 };
+#endif
diff --git a/src/arch/x86/walkcbfs.S b/src/arch/x86/walkcbfs.S
index bd71f19..9ca7650 100644
--- a/src/arch/x86/walkcbfs.S
+++ b/src/arch/x86/walkcbfs.S
@@ -11,6 +11,8 @@
  * GNU General Public License for more details.
  */
 
+#include "fmap_config.h"
+
 #define CBFS_HEADER_PTR 0xfffffffc
 
 #define CBFS_HEADER_MAGIC 0
@@ -31,6 +33,9 @@
 
 #define CBFS_FILE_STRUCTSIZE (CBFS_FILE_OFFSET + 4)
 
+#define CBFS_X86_ROM_LOCATION_TOM 0x100000000
+#define FMAP_COREBOOT_CBFS_HEADER_ABSOLUTE_ADDRESS (CBFS_X86_ROM_LOCATION_TOM - (CONFIG_CBFS_SIZE - ___FMAP__COREBOOT_BASE))
+
 .section .text
 .global walkcbfs_asm
 
@@ -43,14 +48,21 @@
 walkcbfs_asm:
 	cld
 
+#if IS_ENABLED(CONFIG_FMAP_SEPARATE_BOOTBLOCK_REGION)
+	mov $FMAP_COREBOOT_CBFS_HEADER_ABSOLUTE_ADDRESS, %eax
+	add $56, %eax	/* skip irreleveant CBFS header data */
+#else
 	mov CBFS_HEADER_PTR, %eax
+#endif
 	mov CBFS_HEADER_ROMSIZE(%eax), %ecx
 	bswap %ecx
 	mov $0, %ebx
 	sub %ecx, %ebx	/* ROM base address in ebx */
 	mov CBFS_HEADER_OFFSET(%eax), %ecx
 	bswap %ecx
+#if !IS_ENABLED(CONFIG_FMAP_SEPARATE_BOOTBLOCK_REGION)
 	add %ecx, %ebx	/* address where we start looking for LARCHIVEs */
+#endif
 
 	/* determine filename length */
 	mov $0, %eax
diff --git a/src/include/cbfs.h b/src/include/cbfs.h
index 6d9dd42..b297b28 100644
--- a/src/include/cbfs.h
+++ b/src/include/cbfs.h
@@ -61,7 +61,7 @@ struct cbfs_props {
 };
 
 /* Return < 0 on error otherwise props are filled out accordingly. */
-int cbfs_boot_region_properties(struct cbfs_props *props);
+int cbfs_boot_region_properties(struct cbfs_props *props, uint32_t *type);
 
 /* Allow external logic to take action prior to locating a program
  * (stage or payload). */
@@ -74,7 +74,7 @@ struct cbfs_locator {
 	const char *name;
 	void (*prepare)(void);
 	/* Returns 0 on successful fill of cbfs properties. */
-	int (*locate)(struct cbfs_props *props);
+	int (*locate)(struct cbfs_props *props, uint32_t *type);
 };
 
 #endif
diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c
index 7318c87..8ee7ed0 100644
--- a/src/lib/cbfs.c
+++ b/src/lib/cbfs.c
@@ -41,7 +41,7 @@ int cbfs_boot_locate(struct cbfsf *fh, const char *name, uint32_t *type)
 	const struct region_device *boot_dev;
 	struct cbfs_props props;
 
-	if (cbfs_boot_region_properties(&props))
+	if (cbfs_boot_region_properties(&props, type))
 		return -1;
 
 	/* All boot CBFS operations are performed using the RO devie. */
@@ -218,7 +218,7 @@ out:
 }
 
 /* This only supports the "COREBOOT" fmap region. */
-static int cbfs_master_header_props(struct cbfs_props *props)
+static int cbfs_master_header_props(struct cbfs_props *props, uint32_t *type)
 {
 	struct cbfs_header header;
 	const struct region_device *bdev;
@@ -231,6 +231,8 @@ static int cbfs_master_header_props(struct cbfs_props *props)
 		return -1;
 
 	size_t fmap_top = ___FMAP__COREBOOT_BASE + ___FMAP__COREBOOT_SIZE;
+	if (type && (*type == CBFS_TYPE_PAYLOAD))
+		fmap_top = FMAP_CBFS_PAYLOAD_BASE + FMAP_CBFS_PAYLOAD_SIZE;
 
 	/* Find location of header using signed 32-bit offset from
 	 * end of CBFS region. */
@@ -275,7 +277,7 @@ static const struct cbfs_locator *locators[] = {
 	&cbfs_master_header_locator,
 };
 
-int cbfs_boot_region_properties(struct cbfs_props *props)
+int cbfs_boot_region_properties(struct cbfs_props *props, uint32_t *type)
 {
 	int i;
 
@@ -289,7 +291,7 @@ int cbfs_boot_region_properties(struct cbfs_props *props)
 		if (ops->locate == NULL)
 			continue;
 
-		if (ops->locate(props))
+		if (ops->locate(props, type))
 			continue;
 
 		LOG("'%s' located CBFS at [%zx:%zx)\n",
diff --git a/src/lib/coreboot_table.c b/src/lib/coreboot_table.c
index f8da658..401eee1 100644
--- a/src/lib/coreboot_table.c
+++ b/src/lib/coreboot_table.c
@@ -269,7 +269,7 @@ static void lb_boot_media_params(struct lb_header *header)
 
 	boot_device_init();
 
-	if (cbfs_boot_region_properties(&props))
+	if (cbfs_boot_region_properties(&props, NULL))
 		return;
 
 	boot_dev = boot_device_ro();
diff --git a/src/lib/prog_loaders.c b/src/lib/prog_loaders.c
index ecbc679..2c73710 100644
--- a/src/lib/prog_loaders.c
+++ b/src/lib/prog_loaders.c
@@ -39,7 +39,14 @@ int prog_locate(struct prog *prog)
 
 	cbfs_prepare_program_locate();
 
-	if (cbfs_boot_locate(&file, prog_name(prog), NULL))
+	uint32_t type = 0;
+	uint32_t *type_ptr = NULL;
+	if (prog_type(prog) == PROG_PAYLOAD)
+		type = CBFS_TYPE_PAYLOAD;
+	if (type != 0)
+		type_ptr = &type;
+
+	if (cbfs_boot_locate(&file, prog_name(prog), type_ptr))
 		return -1;
 
 	cbfs_file_data(prog_rdev(prog), &file);



More information about the coreboot-gerrit mailing list