aboutsummaryrefslogtreecommitdiff
path: root/src/vendorcode/google/chromeos/vboot_handoff.c
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2014-09-04 09:55:34 -0700
committerAaron Durbin <adurbin@google.com>2015-03-24 14:48:04 +0100
commitefddcfbb52cd328ad2eb86d88cd306ac30294109 (patch)
tree0cf0e5aff39826797f48a3f040be9d50ce3cdb73 /src/vendorcode/google/chromeos/vboot_handoff.c
parent1b05d887d702fcf5ac704d2ee5257122a180694c (diff)
vboot2: separate verstage from bootblock
With CONFIG_RETURN_FROM_VERSTAGE false, the verstage loads the romstage over the bootblock, then exits to the romstage. this is necessary for some SOC (e.g. tegra124) which runs the bootblock on a different architecture. With CONFIG_RETURN_FROM_VERSTAGE true, the verstage returns to the bootblock. Then, the bootblock loads the romstage over the verstage and exits to the romstage. this is probably necessary for some SOC (e.g. rockchip) which does not have SRAM big enough to fit the verstage and the romstage at the same time. BUG=none TEST=Built Blaze with USE=+/-vboot2. Ran faft on Blaze. BRANCH=none Original-Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Original-Change-Id: I673945c5e21afc800d523fbb25d49fdc83693544 Original-Reviewed-on: https://chromium-review.googlesource.com/212365 Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org> Note: This purposefully is probably broken in vendorcode/google/chromeos as I'm just trying to set a base for dropping more patches in. The vboot paths will have to change from how they are currently constructed. (cherry picked from commit 4fa17395113d86445660091413ecb005485f8014) Signed-off-by: Aaron Durbin <adurbin@chromium.org> Change-Id: I9117434ce99695f9b7021a06196d864f180df5c9 Reviewed-on: http://review.coreboot.org/8881 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/vendorcode/google/chromeos/vboot_handoff.c')
-rw-r--r--src/vendorcode/google/chromeos/vboot_handoff.c77
1 files changed, 53 insertions, 24 deletions
diff --git a/src/vendorcode/google/chromeos/vboot_handoff.c b/src/vendorcode/google/chromeos/vboot_handoff.c
index 3b276aac95..ae3096aee2 100644
--- a/src/vendorcode/google/chromeos/vboot_handoff.c
+++ b/src/vendorcode/google/chromeos/vboot_handoff.c
@@ -19,6 +19,8 @@
#include <2recovery_reasons.h>
#include <2struct.h>
+#include <arch/stages.h>
+#include <assert.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
@@ -33,13 +35,33 @@
#include "vboot_handoff.h"
#include <vboot_struct.h>
+static void *load_ramstage(struct vboot_handoff *vboot_handoff,
+ struct vboot_region *fw_main)
+{
+ struct vboot_components *fw_info;
+ int i;
+
+ fw_info = vboot_locate_components(fw_main);
+ if (fw_info == NULL)
+ die("failed to locate firmware components\n");
+
+ /* these offset & size are used to load a rw boot loader */
+ for (i = 0; i < fw_info->num_components; i++) {
+ vboot_handoff->components[i].address =
+ fw_main->offset_addr + fw_info->entries[i].offset;
+ vboot_handoff->components[i].size = fw_info->entries[i].size;
+ }
+
+ return vboot_load_stage(CONFIG_VBOOT_RAMSTAGE_INDEX, fw_main, fw_info);
+}
+
/**
* Sets vboot_handoff based on the information in vb2_shared_data
*
* TODO: Read wp switch to set VBSD_BOOT_FIRMWARE_WP_ENABLED
*/
static void fill_vboot_handoff(struct vboot_handoff *vboot_handoff,
- struct vb2_shared_data *vb2_sd)
+ struct vb2_shared_data *vb2_sd)
{
VbSharedDataHeader *vb_sd =
(VbSharedDataHeader *)vboot_handoff->shared_data;
@@ -49,7 +71,6 @@ static void fill_vboot_handoff(struct vboot_handoff *vboot_handoff,
vboot_handoff->selected_firmware = vb2_sd->fw_slot;
- /* TODO: fw_slot is never 0xff while firmware_index can. */
vb_sd->firmware_index = vb2_sd->fw_slot;
vb_sd->magic = VB_SHARED_DATA_MAGIC;
@@ -61,7 +82,7 @@ static void fill_vboot_handoff(struct vboot_handoff *vboot_handoff,
if (vb2_sd->recovery_reason) {
vb_sd->firmware_index = 0xFF;
if (vb2_sd->recovery_reason == VB2_RECOVERY_RO_MANUAL)
- vb_sd->flags |= VBSD_BOOT_REC_SWITCH_ON;
+ vb_sd->flags |= VBSD_BOOT_REC_SWITCH_ON;
*oflags |= VB_INIT_OUT_ENABLE_RECOVERY;
*oflags |= VB_INIT_OUT_CLEAR_RAM;
*oflags |= VB_INIT_OUT_ENABLE_DISPLAY;
@@ -75,6 +96,7 @@ static void fill_vboot_handoff(struct vboot_handoff *vboot_handoff,
vb_sd->flags |= VBSD_BOOT_DEV_SWITCH_ON;
vb_sd->flags |= VBSD_LF_DEV_SWITCH_ON;
}
+ /* TODO: Set these in depthcharge */
if (CONFIG_VIRTUAL_DEV_SWITCH)
vb_sd->flags |= VBSD_HONOR_VIRT_DEV_SWITCH;
if (CONFIG_EC_SOFTWARE_SYNC) {
@@ -92,51 +114,58 @@ static void fill_vboot_handoff(struct vboot_handoff *vboot_handoff,
if (vb2_sd->workbuf_preamble_size) {
struct vb2_fw_preamble *fp;
uintptr_t dst, src;
- printk(BIOS_ERR, "Copying FW preamble\n");
+ printk(BIOS_INFO, "Copying FW preamble\n");
fp = (struct vb2_fw_preamble *)( (uintptr_t)vb2_sd +
vb2_sd->workbuf_preamble_offset);
- src = (uintptr_t)&fp->kernel_subkey + fp->kernel_subkey.key_offset;
+ src = (uintptr_t)&fp->kernel_subkey +
+ fp->kernel_subkey.key_offset;
dst = (uintptr_t)vb_sd + sizeof(VbSharedDataHeader);
- memcpy((void *)dst, (void *)src, fp->kernel_subkey.key_size);
- vb_sd->data_used += fp->kernel_subkey.key_size;
+ assert(dst + fp->kernel_subkey.key_size <=
+ (uintptr_t)vboot_handoff + sizeof(*vboot_handoff));
+ memcpy((void *)dst, (void *)src,
+ fp->kernel_subkey.key_size);
+ vb_sd->data_used += fp->kernel_subkey.key_size;
vb_sd->kernel_subkey.key_offset =
dst - (uintptr_t)&vb_sd->kernel_subkey;
vb_sd->kernel_subkey.key_size = fp->kernel_subkey.key_size;
vb_sd->kernel_subkey.algorithm = fp->kernel_subkey.algorithm;
- vb_sd->kernel_subkey.key_version = fp->kernel_subkey.key_version;
+ vb_sd->kernel_subkey.key_version =
+ fp->kernel_subkey.key_version;
}
vb_sd->recovery_reason = vb2_sd->recovery_reason;
}
/**
- * Create vboot handoff struct
- *
- * struct vboot_handoff {
- * VbInitParams init_params;
- * uint32_t selected_firmware;
- * struct firmware_component components[MAX_PARSED_FW_COMPONENTS];
- * char shared_data[VB_SHARED_DATA_MIN_SIZE];
- * } __attribute__((packed));
+ * Load ramstage and return the entry point
*/
-void vboot_create_handoff(void *vboot_workbuf)
+void *vboot_load_ramstage(void)
{
struct vboot_handoff *vh;
struct vb2_shared_data *sd;
+ struct vb2_working_data *wd = vboot_get_working_data();
- sd = (struct vb2_shared_data *)vboot_workbuf;
+ sd = (struct vb2_shared_data *)wd->buffer;
sd->workbuf_hash_offset = 0;
sd->workbuf_hash_size = 0;
- printk(BIOS_INFO, "Creating vboot_handoff structure\n");
+ printk(BIOS_INFO, "creating vboot_handoff structure\n");
vh = cbmem_add(CBMEM_ID_VBOOT_HANDOFF, sizeof(*vh));
-
- if (vh == NULL) {
- printk(BIOS_ERR, "Could not add vboot_handoff structure\n");
- return;
- }
+ if (vh == NULL)
+ /* we don't need to failover gracefully here because this
+ * shouldn't happen with the image that has passed QA. */
+ die("failed to allocate vboot_handoff structure\n");
memset(vh, 0, sizeof(*vh));
+ /* needed until we finish transtion to vboot2 for kernel verification */
fill_vboot_handoff(vh, sd);
+
+ if (vboot_is_readonly_path(wd))
+ /* we're on recovery path. continue to ro-ramstage. */
+ return NULL;
+
+ printk(BIOS_INFO,
+ "loading ramstage from Slot %c\n", sd->fw_slot ? 'B' : 'A');
+ return load_ramstage(vh, &wd->selected_region);
}