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.

Change-Id: Id3544533740d77e2db6be3960bef0c129173bacc
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/190923
Reviewed-by: Gabe Black <gabeblack@chromium.org>
This commit is contained in:
Aaron Durbin 2014-03-20 15:24:03 -05:00 committed by chrome-internal-fetch
commit 756ee3a698
3 changed files with 59 additions and 1 deletions

View file

@ -145,7 +145,8 @@ $(obj)/lib/uart8250.smm.o : $(OPTION_TABLE_H)
ifeq ($(CONFIG_RELOCATABLE_MODULES),y)
ramstage-y += rmodule.c
romstage-$(CONFIG_RELOCATABLE_RAMSTAGE) += rmodule.c
# Include rmodule.c in romstage if vboot verification is selected.
romstage-$(CONFIG_VBOOT_VERIFY_FIRMWARE) += rmodule.c
RMODULE_LDSCRIPT := $(src)/lib/rmodule.ld

View file

@ -77,6 +77,7 @@ config VBOOT_VERIFY_FIRMWARE
bool "Verify firmware with vboot."
default n
depends on CHROMEOS
select RELOCATABLE_MODULES
help
Enabling VBOOT_VERIFY_FIRMWARE will use vboot to verify the ramstage
and boot loader.

View file

@ -143,6 +143,7 @@ static void vboot_invoke_wrapper(struct vboot_handoff *vboot_handoff)
vboot_run_stub(&context);
}
#if CONFIG_RELOCATABLE_RAMSTAGE
static void vboot_load_ramstage(struct vboot_handoff *vboot_handoff,
struct romstage_handoff *handoff)
{
@ -193,6 +194,61 @@ static void vboot_load_ramstage(struct vboot_handoff *vboot_handoff,
stage_exit(rmod_load.entry);
#endif
}
#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 */
void vboot_verify_firmware(struct romstage_handoff *handoff)
{