summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2014-03-20 15:24:03 -0500
committerMarc Jones <marc.jones@se-eng.com>2014-11-15 00:40:15 +0100
commit84437989991ac29e0957625f6333c4b857a4ad45 (patch)
tree216af1c49dff3b1b5504d4ac9734fdd6bc491227
parente742dda985ac428b85d8e90d384ac134c0808af6 (diff)
vboot: allow non-relocatable ramstage loading
The vboot implementation previously assumed that ramstage would be a relocatable module. Allow for ramstage not being a relocatable module. BUG=chrome-os-partner:27094 BRANCH=None TEST=Built nyan with vboot. Original-Change-Id: Id3544533740d77e2db6be3960bef0c129173bacc Original-Signed-off-by: Aaron Durbin <adurbin@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/190923 Original-Reviewed-by: Gabe Black <gabeblack@chromium.org> (cherry picked from commit 756ee3a6987097c65588c8784ee9653fd6e735e4) Signed-off-by: Marc Jones <marc.jones@se-eng.com> Change-Id: I813b07e1bec75640ad4066aca749ba8dccec31d4 Reviewed-on: http://review.coreboot.org/7220 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
-rw-r--r--src/vendorcode/google/chromeos/Kconfig1
-rw-r--r--src/vendorcode/google/chromeos/vboot_loader.c57
2 files changed, 58 insertions, 0 deletions
diff --git a/src/vendorcode/google/chromeos/Kconfig b/src/vendorcode/google/chromeos/Kconfig
index a1a9d9acd2..81567582c1 100644
--- a/src/vendorcode/google/chromeos/Kconfig
+++ b/src/vendorcode/google/chromeos/Kconfig
@@ -80,6 +80,7 @@ config FLASHMAP_OFFSET
config VBOOT_VERIFY_FIRMWARE
bool "Verify firmware with vboot."
default n
+ select RELOCATABLE_MODULES
help
Enabling VBOOT_VERIFY_FIRMWARE will use vboot to verify the ramstage
and boot loader.
diff --git a/src/vendorcode/google/chromeos/vboot_loader.c b/src/vendorcode/google/chromeos/vboot_loader.c
index 2f786adb64..cfdc5af7df 100644
--- a/src/vendorcode/google/chromeos/vboot_loader.c
+++ b/src/vendorcode/google/chromeos/vboot_loader.c
@@ -141,6 +141,7 @@ static void vboot_invoke_wrapper(struct vboot_handoff *vboot_handoff)
vboot_run_stub(&context);
}
+#if CONFIG_RELOCATABLE_RAMSTAGE
static void *vboot_load_ramstage(uint32_t cbmem_id, const char *name,
const struct cbmem_entry **cbmem_entry)
{
@@ -204,6 +205,62 @@ static void *vboot_load_ramstage(uint32_t cbmem_id, const char *name,
return rmod_load.entry;
}
+#else /* CONFIG_RELOCATABLE_RAMSTAGE */
+static void vboot_load_ramstage(struct vboot_handoff *vboot_handoff,
+ struct romstage_handoff *handoff)
+{
+ struct cbfs_stage *stage;
+ const struct firmware_component *fwc;
+
+ if (CONFIG_VBOOT_RAMSTAGE_INDEX >= MAX_PARSED_FW_COMPONENTS) {
+ printk(BIOS_ERR, "Invalid ramstage index: %d\n",
+ CONFIG_VBOOT_RAMSTAGE_INDEX);
+ return;
+ }
+
+ /* Check for invalid address. */
+ fwc = &vboot_handoff->components[CONFIG_VBOOT_RAMSTAGE_INDEX];
+ if (fwc->address == 0) {
+ printk(BIOS_DEBUG, "RW ramstage image address invalid.\n");
+ return;
+ }
+
+ printk(BIOS_DEBUG, "RW ramstage image at 0x%08x, 0x%08x bytes.\n",
+ fwc->address, fwc->size);
+
+ stage = vboot_get_region(fwc->address, fwc->size);
+
+ if (stage == NULL) {
+ printk(BIOS_DEBUG, "Unable to get RW ramstage region.\n");
+ return;
+ }
+
+ timestamp_add_now(TS_START_COPYRAM);
+
+ /* Stages rely the below clearing so that the bss is initialized. */
+ memset((void *) (uintptr_t) stage->load, 0, stage->memlen);
+
+ if (cbfs_decompress(stage->compression,
+ ((unsigned char *) stage) +
+ sizeof(struct cbfs_stage),
+ (void *) (uintptr_t) stage->load,
+ stage->len))
+ return;
+
+ timestamp_add_now(TS_END_COPYRAM);
+
+#if CONFIG_ARCH_X86
+ __asm__ volatile (
+ "movl $0, %%ebp\n"
+ "jmp *%%edi\n"
+ :: "D"(stage->entry)
+ );
+#elif CONFIG_ARCH_ARM
+ stage_exit((void *)(uintptr_t)stage->entry);
+#endif
+}
+#endif /* CONFIG_RELOCATABLE_RAMSTAGE */
+
const struct ramstage_loader_ops vboot_ramstage_loader = {
.name = "VBOOT",