diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc index c0481f1292..d23b96116c 100644 --- a/src/lib/Makefile.inc +++ b/src/lib/Makefile.inc @@ -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 diff --git a/src/vendorcode/google/chromeos/Kconfig b/src/vendorcode/google/chromeos/Kconfig index d14f168e8f..f2076b3ad7 100644 --- a/src/vendorcode/google/chromeos/Kconfig +++ b/src/vendorcode/google/chromeos/Kconfig @@ -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. diff --git a/src/vendorcode/google/chromeos/vboot_loader.c b/src/vendorcode/google/chromeos/vboot_loader.c index 6e7367b4b5..bd9619f972 100644 --- a/src/vendorcode/google/chromeos/vboot_loader.c +++ b/src/vendorcode/google/chromeos/vboot_loader.c @@ -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) {