[coreboot-gerrit] New patch to review for coreboot: arch/x86: Add ability to place bootloader and payload in seperate FMAP regions

Timothy Pearson (tpearson@raptorengineering.com) gerrit at coreboot.org
Sat Aug 20 23:47:28 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 9d9d8ee13934794f1674fdcaa64333a4b6699cd2
Author: Timothy Pearson <tpearson at raptorengineering.com>
Date:   Sat Aug 20 16:44:42 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                   | 23 +++++++++++++++++++++++
 payloads/external/Makefile.inc |  5 +++++
 src/Kconfig                    | 29 +++++++++++++++++++++++++++++
 src/arch/x86/mmap_boot.c       |  5 ++++-
 src/arch/x86/walkcbfs.S        | 10 ++++++++++
 src/include/cbfs.h             |  5 +++--
 src/lib/cbfs.c                 | 11 +++++++----
 src/lib/coreboot_table.c       |  3 ++-
 src/lib/prog_loaders.c         | 10 +++++++++-
 9 files changed, 92 insertions(+), 9 deletions(-)

diff --git a/Makefile.inc b/Makefile.inc
index ff77747..eaaf881 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
@@ -761,6 +775,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 +786,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 +803,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..92478d5 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -35,6 +35,35 @@ 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_BOOTBLOCK_REGION
+	string "FMAP region to place bootblock"
+	default "COREBOOT"
+	help
+	  Select the FMAP region into which the bootblock will be placed.
+	  It's "COREBOOT" by default, "BOOTBLOCK" is a common alternative.
+
+config FMAP_BOOTBLOCK_COREBOOT_OFFSET
+	hex "Start of CBFS in COREBOOT FMAP region"
+	default 0
+	help
+	  The absolute offset in bytes of the start of the coreboot CBFS
+	  FMAP region.  The bootblock uses this as the CBFS start location.
+	  This must match the offset defined in your ,fmap, and should
+	  be zero if the bootblock is contained in the same CBFS as the
+	  rest of coreboot.
+
+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..249178d 100644
--- a/src/arch/x86/mmap_boot.c
+++ b/src/arch/x86/mmap_boot.c
@@ -2,6 +2,7 @@
  * This file is part of the coreboot project.
  *
  * Copyright 2015 Google Inc.
+ * Copyright 2016 Raptor Engineering, LLC
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,7 +30,8 @@ const struct region_device *boot_device_ro(void)
 	return &boot_dev.rdev;
 }
 
-static int cbfs_master_header_props(struct cbfs_props *props)
+#if CONFIG_FMAP_BOOTBLOCK_COREBOOT_OFFSET == 0
+static int cbfs_master_header_props(struct cbfs_props *props, uint32_t *)
 {
 	struct cbfs_header header;
 	int32_t offset;
@@ -69,3 +71,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..18bdd12 100644
--- a/src/arch/x86/walkcbfs.S
+++ b/src/arch/x86/walkcbfs.S
@@ -31,6 +31,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 - CONFIG_FMAP_BOOTBLOCK_COREBOOT_OFFSET))
+
 .section .text
 .global walkcbfs_asm
 
@@ -43,14 +46,21 @@
 walkcbfs_asm:
 	cld
 
+#if CONFIG_FMAP_BOOTBLOCK_COREBOOT_OFFSET != 0
+	mov $FMAP_COREBOOT_CBFS_HEADER_ABSOLUTE_ADDRESS, %eax
+	add $4152, %eax	/* skip fmap definition and 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 CONFIG_FMAP_BOOTBLOCK_COREBOOT_OFFSET == 0
 	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..9b7ce38 100644
--- a/src/include/cbfs.h
+++ b/src/include/cbfs.h
@@ -2,6 +2,7 @@
  * This file is part of the coreboot project.
  *
  * Copyright 2015 Google Inc.
+ * Copyright 2016 Raptor Engineering, LLC
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -61,7 +62,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 +75,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..d6a68e0 100644
--- a/src/lib/cbfs.c
+++ b/src/lib/cbfs.c
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2011 secunet Security Networks AG
  * Copyright 2015 Google Inc.
+ * Copyright 2016 Raptor Engineering, LLC
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -41,7 +42,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 +219,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 +232,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 +278,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 +292,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..a4e3c12 100644
--- a/src/lib/coreboot_table.c
+++ b/src/lib/coreboot_table.c
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2003-2004 Eric Biederman
  * Copyright (C) 2005-2010 coresystems GmbH
+ * Copyright 2016 Raptor Engineering, LLC
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -269,7 +270,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..b7da29e 100644
--- a/src/lib/prog_loaders.c
+++ b/src/lib/prog_loaders.c
@@ -2,6 +2,7 @@
  * This file is part of the coreboot project.
  *
  * Copyright 2015 Google Inc.
+ * Copyright 2016 Raptor Engineering, LLC
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -39,7 +40,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