[coreboot-gerrit] New patch to review for coreboot: b49243f rmodule: consolidate rmodule stage loading

Aaron Durbin (adurbin@google.com) gerrit at coreboot.org
Tue Jan 28 03:55:35 CET 2014


Aaron Durbin (adurbin at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4897

-gerrit

commit b49243fe93cd7120e7ddff4298b5f714c2f59ca1
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Thu Oct 24 10:14:06 2013 -0500

    rmodule: consolidate rmodule stage loading
    
    There are 3 places rmodule stages are loaded in the
    existing code: cbfs and 2 in vboot_wrapper. Much of the
    code is the same except for a few different cbmem entry
    ids. Instead provide a common implementation in the
    rmodule library itself.
    
    A structure named rmod_stage_load is introduced to manage
    the inputs and outputs from the new API.
    
    BUG=chrome-os-partner:22866
    BRANCH=None
    TEST=Built and booted successfully.
    
    Change-Id: I146055005557e04164e95de4aae8a2bde8713131
    Signed-off-by: Aaron Durbin <adurbin at chromium.org>
    Reviewed-on: https://chromium-review.googlesource.com/174425
    Reviewed-by: Duncan Laurie <dlaurie at chromium.org>
---
 src/include/rmodule.h                         | 20 ++++++
 src/lib/cbfs.c                                | 50 +++-----------
 src/lib/rmodule.c                             | 61 +++++++++++++++++
 src/vendorcode/google/chromeos/vboot_loader.c | 95 +++++----------------------
 4 files changed, 108 insertions(+), 118 deletions(-)

diff --git a/src/include/rmodule.h b/src/include/rmodule.h
index 247711a..da12ec8 100644
--- a/src/include/rmodule.h
+++ b/src/include/rmodule.h
@@ -79,6 +79,26 @@ int rmodule_calc_region(unsigned int region_alignment, size_t rmodule_size,
 	__attribute__ ((section (".module_header"))) = \
 	RMODULE_HEADER(entry_, type_)
 
+/* Support for loading rmodule stages. This API is only available wwhen
+ * using dynamic cbmem because it uses the dynamic cbmem API to obtain
+ * the backing store region for the stage. */
+#if CONFIG_DYNAMIC_CBMEM
+struct cbfs_stage;
+struct cbmem_entry;
+
+struct rmod_stage_load {
+	/* Inputs */
+	uint32_t cbmem_id;
+	const char *name;
+	/* Outputs */
+	const struct cbmem_entry *cbmem_entry;
+	void *entry;
+};
+
+/* Both of the following functions return 0 on success, -1 on error. */
+int rmodule_stage_load(struct rmod_stage_load *rsl, struct cbfs_stage *stage);
+int rmodule_stage_load_from_cbfs(struct rmod_stage_load *rsl);
+#endif
 
 /* Private data structures below should not be used directly. */
 
diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c
index 396fe33..9fe1757 100644
--- a/src/lib/cbfs.c
+++ b/src/lib/cbfs.c
@@ -130,51 +130,19 @@ void *cbfs_load_optionrom(struct cbfs_media *media, uint16_t vendor,
 static void *load_stage_from_cbfs(struct cbfs_media *media, const char *name,
                                   struct romstage_handoff *handoff)
 {
-	struct cbfs_stage *stage;
-	struct rmodule ramstage;
-	void *entry_point;
-	size_t region_size;
-	char *ramstage_region;
-	int rmodule_offset;
-	int load_offset;
-	const struct cbmem_entry *ramstage_entry;
-
-	stage = (struct cbfs_stage *)
-	  cbfs_get_file_content(media, name, CBFS_TYPE_STAGE, NULL);
+	struct rmod_stage_load rmod_ram = {
+		.cbmem_id = CBMEM_ID_RAMSTAGE,
+		.name = name,
+	};
 
-	if (stage == NULL)
-		return (void *) -1;
-
-	rmodule_offset =
-		rmodule_calc_region(DYN_CBMEM_ALIGN_SIZE,
-	                            stage->memlen, &region_size, &load_offset);
-
-	ramstage_entry = cbmem_entry_add(CBMEM_ID_RAMSTAGE, region_size);
-
-	if (ramstage_entry == NULL)
+	if (rmodule_stage_load_from_cbfs(&rmod_ram)) {
+		printk(BIOS_DEBUG, "Could not load ramstage.\n");
 		return (void *) -1;
+	}
 
-	ramstage_region = cbmem_entry_start(ramstage_entry);
-
-	LOG("Decompressing stage %s @ 0x%p (%d bytes)\n",
-	    name, &ramstage_region[rmodule_offset], stage->memlen);
-
-	if (!cbfs_decompress(stage->compression, &stage[1],
-	                     &ramstage_region[rmodule_offset], stage->len))
-		return (void *) -1;
-
-	if (rmodule_parse(&ramstage_region[rmodule_offset], &ramstage))
-		return (void *) -1;
-
-	/* The ramstage is responsible for clearing its own bss. */
-	if (rmodule_load(&ramstage_region[load_offset], &ramstage))
-		return (void *) -1;
-
-	entry_point = rmodule_entry(&ramstage);
-
-	cache_loaded_ramstage(handoff, ramstage_entry, entry_point);
+	cache_loaded_ramstage(handoff, rmod_ram.cbmem_entry, rmod_ram.entry);
 
-	return entry_point;
+	return rmod_ram.entry;
 }
 
 void * cbfs_load_stage(struct cbfs_media *media, const char *name)
diff --git a/src/lib/rmodule.c b/src/lib/rmodule.c
index 462c7d7..a78afea 100644
--- a/src/lib/rmodule.c
+++ b/src/lib/rmodule.c
@@ -300,3 +300,64 @@ int rmodule_calc_region(unsigned int region_alignment, size_t rmodule_size,
 
 	return region_alignment - sizeof(struct rmodule_header);
 }
+
+#if CONFIG_DYNAMIC_CBMEM
+#include <cbmem.h>
+#include <cbfs_core.h>
+
+int rmodule_stage_load(struct rmod_stage_load *rsl, struct cbfs_stage *stage)
+{
+	struct rmodule rmod_stage;
+	size_t region_size;
+	char *stage_region;
+	int rmodule_offset;
+	int load_offset;
+	const struct cbmem_entry *cbmem_entry;
+
+	if (stage == NULL || rsl->name == NULL)
+		return -1;
+
+	rmodule_offset =
+		rmodule_calc_region(DYN_CBMEM_ALIGN_SIZE,
+		                    stage->memlen, &region_size, &load_offset);
+
+	cbmem_entry = cbmem_entry_add(rsl->cbmem_id, region_size);
+
+	if (cbmem_entry == NULL)
+		return -1;
+
+	stage_region = cbmem_entry_start(cbmem_entry);
+
+	printk(BIOS_INFO, "Decompressing stage %s @ 0x%p (%d bytes)\n",
+	       rsl->name, &stage_region[rmodule_offset], stage->memlen);
+
+	if (!cbfs_decompress(stage->compression, &stage[1],
+	                    &stage_region[rmodule_offset], stage->len))
+		return -1;
+
+	if (rmodule_parse(&stage_region[rmodule_offset], &rmod_stage))
+		return -1;
+
+	if (rmodule_load(&stage_region[load_offset], &rmod_stage))
+		return -1;
+
+	rsl->cbmem_entry = cbmem_entry;
+	rsl->entry = rmodule_entry(&rmod_stage);
+
+	return 0;
+}
+
+int rmodule_stage_load_from_cbfs(struct rmod_stage_load *rsl)
+{
+	struct cbfs_stage *stage;
+
+	stage =cbfs_get_file_content(CBFS_DEFAULT_MEDIA,
+	                              rsl->name, CBFS_TYPE_STAGE, NULL);
+
+	if (stage == NULL)
+		return -1;
+
+	return rmodule_stage_load(rsl, stage);
+}
+
+#endif /* DYNAMIC_CBMEM */
diff --git a/src/vendorcode/google/chromeos/vboot_loader.c b/src/vendorcode/google/chromeos/vboot_loader.c
index 91f6237..6eff99c 100644
--- a/src/vendorcode/google/chromeos/vboot_loader.c
+++ b/src/vendorcode/google/chromeos/vboot_loader.c
@@ -37,59 +37,26 @@
 
 static void vboot_run_stub(struct vboot_context *context)
 {
-	const struct cbmem_entry *vboot_entry;
-	struct rmodule vbootstub;
-	struct cbfs_stage *stage;
-	size_t region_size;
-	int rmodule_offset;
-	int load_offset;
-	char *vboot_region;
+	struct rmod_stage_load rmod_stage = {
+		.cbmem_id = 0xffffffff,
+		.name = CONFIG_CBFS_PREFIX "/vboot",
+	};
 	void (*entry)(struct vboot_context *context);
 
-	stage = cbfs_get_file_content(CBFS_DEFAULT_MEDIA,
-	                              CONFIG_CBFS_PREFIX "/vboot",
-	                              CBFS_TYPE_STAGE, NULL);
-
-	if (stage == NULL)
-		return;
-
-	rmodule_offset =
-		rmodule_calc_region(DYN_CBMEM_ALIGN_SIZE,
-	                            stage->memlen, &region_size, &load_offset);
-
-	vboot_entry = cbmem_entry_add(0xffffffff, region_size);
-
-	if (vboot_entry == NULL) {
-		printk(BIOS_DEBUG, "Couldn't get region for vboot stub.\n");
-		return;
-	}
-
-	vboot_region = cbmem_entry_start(vboot_entry);
-
-	if (!cbfs_decompress(stage->compression, &stage[1],
-	                     &vboot_region[rmodule_offset], stage->len)) {
-		printk(BIOS_DEBUG, "Couldn't decompress vboot stub.\n");
+	if (rmodule_stage_load_from_cbfs(&rmod_stage)) {
+		printk(BIOS_DEBUG, "Could not load vboot stub.\n");
 		goto out;
 	}
 
-	if (rmodule_parse(&vboot_region[rmodule_offset], &vbootstub)) {
-		printk(BIOS_DEBUG, "Couldn't parse vboot stub rmodule.\n");
-		goto out;
-	}
-
-	if (rmodule_load(&vboot_region[load_offset], &vbootstub)) {
-		printk(BIOS_DEBUG, "Couldn't load vboot stub.\n");
-		goto out;
-	}
-
-	entry = rmodule_entry(&vbootstub);
+	entry = rmod_stage.entry;
 
 	/* Call stub. */
 	entry(context);
 
 out:
 	/* Tear down the region no longer needed. */
-	cbmem_entry_remove(vboot_entry);
+	if (rmod_stage.cbmem_entry != NULL)
+		cbmem_entry_remove(rmod_stage.cbmem_entry);
 }
 
 /* Helper routines for the vboot stub. */
@@ -175,14 +142,11 @@ static void vboot_load_ramstage(struct vboot_handoff *vboot_handoff,
                                 struct romstage_handoff *handoff)
 {
 	struct cbfs_stage *stage;
-	struct rmodule ramstage;
-	void *entry_point;
-	size_t region_size;
-	char *ramstage_region;
-	int rmodule_offset;
-	int load_offset;
-	const struct cbmem_entry *ramstage_entry;
 	const struct firmware_component *fwc;
+	struct rmod_stage_load rmod_load = {
+		.cbmem_id = CBMEM_ID_RAMSTAGE,
+		.name = CONFIG_CBFS_PREFIX "/coreboot_ram",
+	};
 
 	if (CONFIG_VBOOT_RAMSTAGE_INDEX >= MAX_PARSED_FW_COMPONENTS) {
 		printk(BIOS_ERR, "Invalid ramstage index: %d\n",
@@ -202,45 +166,22 @@ static void vboot_load_ramstage(struct vboot_handoff *vboot_handoff,
 
 	stage = (void *)fwc->address;
 
-	rmodule_offset =
-		rmodule_calc_region(DYN_CBMEM_ALIGN_SIZE,
-	                            stage->memlen, &region_size, &load_offset);
-
-	ramstage_entry = cbmem_entry_add(CBMEM_ID_RAMSTAGE, region_size);
+	timestamp_add_now(TS_START_COPYRAM);
 
-	if (ramstage_entry == NULL) {
+	if (rmodule_stage_load(&rmod_load, stage)) {
 		vboot_handoff->selected_firmware = VB_SELECT_FIRMWARE_READONLY;
-		printk(BIOS_DEBUG, "Could not add ramstage region.\n");
+		printk(BIOS_DEBUG, "Could not load ramstage region.\n");
 		return;
 	}
 
-	timestamp_add_now(TS_START_COPYRAM);
-
-	ramstage_region = cbmem_entry_start(ramstage_entry);
-
-	printk(BIOS_DEBUG, "Decompressing ramstage @ 0x%p (%d bytes)\n",
-	       &ramstage_region[rmodule_offset], stage->memlen);
-
-	if (!cbfs_decompress(stage->compression, &stage[1],
-	                     &ramstage_region[rmodule_offset], stage->len))
-		return;
-
-	if (rmodule_parse(&ramstage_region[rmodule_offset], &ramstage))
-		return;
-
-	if (rmodule_load(&ramstage_region[load_offset], &ramstage))
-		return;
-
-	entry_point = rmodule_entry(&ramstage);
-
-	cache_loaded_ramstage(handoff, ramstage_entry, entry_point);
+	cache_loaded_ramstage(handoff, rmod_load.cbmem_entry, rmod_load.entry);
 
 	timestamp_add_now(TS_END_COPYRAM);
 
 	__asm__ volatile (
 		"movl $0, %%ebp\n"
 		"jmp  *%%edi\n"
-		:: "D"(entry_point)
+		:: "D"(rmod_load.entry)
 	);
 }
 



More information about the coreboot-gerrit mailing list