Aaron Durbin (adurbin(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11744
-gerrit
commit 37830e40023dd0db030526015a4c482f66ca206f
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Tue Sep 29 17:56:59 2015 -0500
vboot: provide a unified flow for separate verstage
The vboot verification in a stage proper is unified
replacing duplicate code in the tegra SoC code. The
original verstage.c file is renamed to reflect its
real purpose. The support for a single verstage flow
is added to the vboot2 directory proper.
BUG=chrome-os-partner:44827
BRANCH=None
TEST=Built glados.
Change-Id: I14593e1fc69a1654fa27b512eb4b612395b94ce5
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/mainboard/google/foster/Makefile.inc | 1 -
src/mainboard/google/foster/verstage.c | 29 --
src/soc/nvidia/tegra132/include/soc/verstage.h | 2 +-
src/soc/nvidia/tegra132/verstage.c | 48 ---
src/soc/nvidia/tegra210/include/soc/verstage.h | 2 +-
src/soc/nvidia/tegra210/verstage.c | 45 ---
src/vendorcode/google/chromeos/vboot2/Makefile.inc | 3 +-
src/vendorcode/google/chromeos/vboot2/misc.h | 1 -
.../google/chromeos/vboot2/vboot_logic.c | 352 +++++++++++++++++++++
src/vendorcode/google/chromeos/vboot2/verstage.c | 339 ++------------------
src/vendorcode/google/chromeos/vboot_common.h | 6 +
11 files changed, 380 insertions(+), 448 deletions(-)
diff --git a/src/mainboard/google/foster/Makefile.inc b/src/mainboard/google/foster/Makefile.inc
index 7b2329e..51208c7 100644
--- a/src/mainboard/google/foster/Makefile.inc
+++ b/src/mainboard/google/foster/Makefile.inc
@@ -32,7 +32,6 @@ bootblock-y += bootblock.c
bootblock-y += pmic.c
bootblock-y += reset.c
-verstage-y += verstage.c
verstage-y += chromeos.c
verstage-y += reset.c
diff --git a/src/mainboard/google/foster/verstage.c b/src/mainboard/google/foster/verstage.c
deleted file mode 100644
index d5bcd44..0000000
--- a/src/mainboard/google/foster/verstage.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2014 Google Inc.
- * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-#include <soc/addressmap.h>
-#include <soc/funitcfg.h>
-#include <soc/padconfig.h>
-#include <soc/verstage.h>
-#include <soc/nvidia/tegra/i2c.h>
-
-void verstage_mainboard_init(void)
-{
-}
diff --git a/src/soc/nvidia/tegra132/include/soc/verstage.h b/src/soc/nvidia/tegra132/include/soc/verstage.h
index df6a386..d54a111 100644
--- a/src/soc/nvidia/tegra132/include/soc/verstage.h
+++ b/src/soc/nvidia/tegra132/include/soc/verstage.h
@@ -20,6 +20,6 @@
#ifndef __SOC_NVIDIA_TEGRA132_SOC_VERSTAGE_H__
#define __SOC_NVIDIA_TEGRA132_SOC_VERSTAGE_H__
-void verstage_mainboard_init(void);
+#include <vendorcode/google/chromeos/chromeos.h>
#endif /* __SOC_NVIDIA_TEGRA132_SOC_VERSTAGE_H__ */
diff --git a/src/soc/nvidia/tegra132/verstage.c b/src/soc/nvidia/tegra132/verstage.c
deleted file mode 100644
index d6eba9a..0000000
--- a/src/soc/nvidia/tegra132/verstage.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2014 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-#include <arch/cache.h>
-#include <arch/exception.h>
-#include <arch/hlt.h>
-#include <arch/stages.h>
-#include <console/console.h>
-#include <soc/verstage.h>
-#include <program_loading.h>
-#include <timestamp.h>
-
-void __attribute__((weak)) verstage_mainboard_init(void)
-{
- /* Default empty implementation. */
-}
-
-static void verstage(void)
-{
- console_init();
- timestamp_add_now(TS_START_VBOOT);
- exception_init();
- verstage_mainboard_init();
-
- run_romstage();
-}
-
-void main(void)
-{
- verstage();
- hlt();
-}
diff --git a/src/soc/nvidia/tegra210/include/soc/verstage.h b/src/soc/nvidia/tegra210/include/soc/verstage.h
index 6c37218..d6564c9 100644
--- a/src/soc/nvidia/tegra210/include/soc/verstage.h
+++ b/src/soc/nvidia/tegra210/include/soc/verstage.h
@@ -20,6 +20,6 @@
#ifndef __SOC_NVIDIA_TEGRA210_SOC_VERSTAGE_H__
#define __SOC_NVIDIA_TEGRA210_SOC_VERSTAGE_H__
-void verstage_mainboard_init(void);
+#include <vendorcode/google/chromeos/chromeos.h>
#endif /* __SOC_NVIDIA_TEGRA210_SOC_VERSTAGE_H__ */
diff --git a/src/soc/nvidia/tegra210/verstage.c b/src/soc/nvidia/tegra210/verstage.c
deleted file mode 100644
index 6a4df29..0000000
--- a/src/soc/nvidia/tegra210/verstage.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2014 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-#include <arch/cache.h>
-#include <arch/exception.h>
-#include <arch/hlt.h>
-#include <soc/verstage.h>
-#include <console/console.h>
-#include <program_loading.h>
-
-void __attribute__((weak)) verstage_mainboard_init(void)
-{
- /* Default empty implementation. */
-}
-
-static void verstage(void)
-{
- console_init();
- exception_init();
- verstage_mainboard_init();
-
- run_romstage();
-}
-
-void main(void)
-{
- verstage();
- hlt();
-}
diff --git a/src/vendorcode/google/chromeos/vboot2/Makefile.inc b/src/vendorcode/google/chromeos/vboot2/Makefile.inc
index 21613ba..c2ee868 100644
--- a/src/vendorcode/google/chromeos/vboot2/Makefile.inc
+++ b/src/vendorcode/google/chromeos/vboot2/Makefile.inc
@@ -31,8 +31,9 @@ romstage-y += ../vboot_common.c
ramstage-y += ../vboot_common.c
bootblock-y += common.c
-libverstage-y += verstage.c
+libverstage-y += vboot_logic.c
verstage-y += common.c
+verstage-y += verstage.c
ifeq (${CONFIG_VBOOT2_MOCK_SECDATA},y)
libverstage-y += secdata_mock.c
else
diff --git a/src/vendorcode/google/chromeos/vboot2/misc.h b/src/vendorcode/google/chromeos/vboot2/misc.h
index d4f9f48..305d0da 100644
--- a/src/vendorcode/google/chromeos/vboot2/misc.h
+++ b/src/vendorcode/google/chromeos/vboot2/misc.h
@@ -23,7 +23,6 @@
#include "../vboot_common.h"
void vboot_fill_handoff(void);
-void verstage_main(void);
void *vboot_load_stage(int stage_index,
struct region *fw_main,
struct vboot_components *fw_info);
diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_logic.c b/src/vendorcode/google/chromeos/vboot2/vboot_logic.c
new file mode 100644
index 0000000..76355ec
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/vboot_logic.c
@@ -0,0 +1,352 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.
+ */
+
+#include <antirollback.h>
+#include <arch/exception.h>
+#include <assert.h>
+#include <console/console.h>
+#include <console/vtxprintf.h>
+#include <delay.h>
+#include <string.h>
+#include <timestamp.h>
+#include <vb2_api.h>
+
+#include "../chromeos.h"
+#include "misc.h"
+
+#define TODO_BLOCK_SIZE 1024
+
+static int is_slot_a(struct vb2_context *ctx)
+{
+ return !(ctx->flags & VB2_CONTEXT_FW_SLOT_B);
+}
+
+/* exports */
+
+void vb2ex_printf(const char *func, const char *fmt, ...)
+{
+ va_list args;
+
+ printk(BIOS_INFO, "VB2:%s() ", func);
+ va_start(args, fmt);
+ do_printk_va_list(BIOS_INFO, fmt, args);
+ va_end(args);
+
+ return;
+}
+
+int vb2ex_tpm_clear_owner(struct vb2_context *ctx)
+{
+ uint32_t rv;
+ printk(BIOS_INFO, "Clearing TPM owner\n");
+ rv = tpm_clear_and_reenable();
+ if (rv)
+ return VB2_ERROR_EX_TPM_CLEAR_OWNER;
+ return VB2_SUCCESS;
+}
+
+int vb2ex_read_resource(struct vb2_context *ctx,
+ enum vb2_resource_index index,
+ uint32_t offset,
+ void *buf,
+ uint32_t size)
+{
+ struct region_device rdev;
+ const char *name;
+
+ switch (index) {
+ case VB2_RES_GBB:
+ name = "GBB";
+ break;
+ case VB2_RES_FW_VBLOCK:
+ if (is_slot_a(ctx))
+ name = "VBLOCK_A";
+ else
+ name = "VBLOCK_B";
+ break;
+ default:
+ return VB2_ERROR_EX_READ_RESOURCE_INDEX;
+ }
+
+ if (vboot_named_region_device(name, &rdev))
+ return VB2_ERROR_EX_READ_RESOURCE_SIZE;
+
+ if (rdev_readat(&rdev, buf, offset, size) != size)
+ return VB2_ERROR_EX_READ_RESOURCE_SIZE;
+
+ return VB2_SUCCESS;
+}
+
+/* No-op stubs that can be overridden by SoCs with hardware crypto support. */
+__attribute__((weak))
+int vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
+ uint32_t data_size)
+{
+ return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
+}
+
+__attribute__((weak))
+int vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size)
+{
+ BUG(); /* Should never get called if init() returned an error. */
+ return VB2_ERROR_UNKNOWN;
+}
+
+__attribute__((weak))
+int vb2ex_hwcrypto_digest_finalize(uint8_t *digest, uint32_t digest_size)
+{
+ BUG(); /* Should never get called if init() returned an error. */
+ return VB2_ERROR_UNKNOWN;
+}
+
+static int hash_body(struct vb2_context *ctx, struct region_device *fw_main)
+{
+ uint64_t load_ts;
+ uint32_t expected_size;
+ uint8_t block[TODO_BLOCK_SIZE];
+ size_t block_size = sizeof(block);
+ size_t offset;
+ int rv;
+
+ /*
+ * Since loading the firmware and calculating its hash is intertwined,
+ * we use this little trick to measure them separately and pretend it
+ * was first loaded and then hashed in one piece with the timestamps.
+ * (This split won't make sense with memory-mapped media like on x86.)
+ */
+ load_ts = timestamp_get();
+ timestamp_add(TS_START_HASH_BODY, load_ts);
+
+ expected_size = region_device_sz(fw_main);
+ offset = 0;
+
+ /* Start the body hash */
+ rv = vb2api_init_hash(ctx, VB2_HASH_TAG_FW_BODY, &expected_size);
+ if (rv)
+ return rv;
+
+ /* Extend over the body */
+ while (expected_size) {
+ uint64_t temp_ts;
+ if (block_size > expected_size)
+ block_size = expected_size;
+
+ temp_ts = timestamp_get();
+ if (rdev_readat(fw_main, block, offset, block_size) < 0)
+ return VB2_ERROR_UNKNOWN;
+ load_ts += timestamp_get() - temp_ts;
+
+ rv = vb2api_extend_hash(ctx, block, block_size);
+ if (rv)
+ return rv;
+
+ expected_size -= block_size;
+ offset += block_size;
+ }
+
+ timestamp_add(TS_DONE_LOADING, load_ts);
+ timestamp_add_now(TS_DONE_HASHING);
+
+ /* Check the result (with RSA signature verification) */
+ rv = vb2api_check_hash(ctx);
+ if (rv)
+ return rv;
+
+ timestamp_add_now(TS_END_HASH_BODY);
+
+ return VB2_SUCCESS;
+}
+
+static int locate_firmware(struct vb2_context *ctx,
+ struct region_device *fw_main)
+{
+ const char *name;
+
+ if (is_slot_a(ctx))
+ name = "FW_MAIN_A";
+ else
+ name = "FW_MAIN_B";
+
+ return vboot_named_region_device(name, fw_main);
+}
+
+/**
+ * Save non-volatile and/or secure data if needed.
+ */
+static void save_if_needed(struct vb2_context *ctx)
+{
+ if (ctx->flags & VB2_CONTEXT_NVDATA_CHANGED) {
+ printk(BIOS_INFO, "Saving nvdata\n");
+ save_vbnv(ctx->nvdata);
+ ctx->flags &= ~VB2_CONTEXT_NVDATA_CHANGED;
+ }
+ if (ctx->flags & VB2_CONTEXT_SECDATA_CHANGED) {
+ printk(BIOS_INFO, "Saving secdata\n");
+ antirollback_write_space_firmware(ctx);
+ ctx->flags &= ~VB2_CONTEXT_SECDATA_CHANGED;
+ }
+}
+
+static uint32_t extend_pcrs(struct vb2_context *ctx)
+{
+ return tpm_extend_pcr(ctx, 0, BOOT_MODE_PCR) ||
+ tpm_extend_pcr(ctx, 1, HWID_DIGEST_PCR);
+}
+
+static void init_vb2_working_data(void)
+{
+ struct vb2_working_data *wd;
+ size_t work_size;
+
+ work_size = vb2_working_data_size();
+ wd = vboot_get_working_data();
+ memset(wd, 0, work_size);
+ /*
+ * vboot prefers 16-byte alignment. This takes away 16 bytes
+ * from the VBOOT2_WORK region, but the vboot devs said that's okay.
+ */
+ wd->buffer_offset = ALIGN_UP(sizeof(*wd), 16);
+ wd->buffer_size = work_size - wd->buffer_offset;
+}
+
+/**
+ * Verify and select the firmware in the RW image
+ *
+ * TODO: Avoid loading a stage twice (once in hash_body & again in load_stage).
+ * when per-stage verification is ready.
+ */
+void verstage_main(void)
+{
+ struct vb2_context ctx;
+ struct region_device fw_main;
+ struct vb2_working_data *wd;
+ int rv;
+ init_vb2_working_data();
+ wd = vboot_get_working_data();
+ timestamp_add_now(TS_START_VBOOT);
+
+ /* Set up context and work buffer */
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.workbuf = vboot_get_work_buffer(wd);
+ ctx.workbuf_size = wd->buffer_size;
+
+ /* Read nvdata from a non-volatile storage */
+ read_vbnv(ctx.nvdata);
+
+ /* Read secdata from TPM. Initialize TPM if secdata not found. We don't
+ * check the return value here because vb2api_fw_phase1 will catch
+ * invalid secdata and tell us what to do (=reboot). */
+ timestamp_add_now(TS_START_TPMINIT);
+ antirollback_read_space_firmware(&ctx);
+ timestamp_add_now(TS_END_TPMINIT);
+
+ if (!IS_ENABLED(CONFIG_VIRTUAL_DEV_SWITCH) &&
+ get_developer_mode_switch())
+ ctx.flags |= VB2_CONTEXT_FORCE_DEVELOPER_MODE;
+
+ if (get_recovery_mode_switch()) {
+ clear_recovery_mode_switch();
+ ctx.flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
+ if (IS_ENABLED(CONFIG_VBOOT_DISABLE_DEV_ON_RECOVERY))
+ ctx.flags |= VB2_DISABLE_DEVELOPER_MODE;
+ }
+
+ if (IS_ENABLED(CONFIG_WIPEOUT_SUPPORTED) && get_wipeout_mode_switch())
+ ctx.flags |= VB2_CONTEXT_FORCE_WIPEOUT_MODE;
+
+ if (IS_ENABLED(CONFIG_LID_SWITCH) && !get_lid_switch())
+ ctx.flags |= VB2_CONTEXT_NOFAIL_BOOT;
+
+ /* Do early init (set up secdata and NVRAM, load GBB) */
+ printk(BIOS_INFO, "Phase 1\n");
+ rv = vb2api_fw_phase1(&ctx);
+
+ if (rv) {
+ /*
+ * If vb2api_fw_phase1 fails, check for return value.
+ * If it is set to VB2_ERROR_API_PHASE1_RECOVERY, then continue
+ * into recovery mode.
+ * For any other error code, save context if needed and reboot.
+ */
+ if (rv == VB2_ERROR_API_PHASE1_RECOVERY) {
+ printk(BIOS_INFO, "Recovery requested (%x)\n", rv);
+ save_if_needed(&ctx);
+ extend_pcrs(&ctx); /* ignore failures */
+ timestamp_add_now(TS_END_VBOOT);
+ return;
+ }
+
+ printk(BIOS_INFO, "Reboot reqested (%x)\n", rv);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ /* Determine which firmware slot to boot (based on NVRAM) */
+ printk(BIOS_INFO, "Phase 2\n");
+ rv = vb2api_fw_phase2(&ctx);
+ if (rv) {
+ printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ /* Try that slot (verify its keyblock and preamble) */
+ printk(BIOS_INFO, "Phase 3\n");
+ timestamp_add_now(TS_START_VERIFY_SLOT);
+ rv = vb2api_fw_phase3(&ctx);
+ timestamp_add_now(TS_END_VERIFY_SLOT);
+ if (rv) {
+ printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ printk(BIOS_INFO, "Phase 4\n");
+ rv = locate_firmware(&ctx, &fw_main);
+ if (rv)
+ die("Failed to read FMAP to locate firmware");
+
+ rv = hash_body(&ctx, &fw_main);
+ save_if_needed(&ctx);
+ if (rv) {
+ printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
+ vboot_reboot();
+ }
+
+ rv = extend_pcrs(&ctx);
+ if (rv) {
+ printk(BIOS_WARNING, "Failed to extend TPM PCRs (%#x)\n", rv);
+ vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_U_ERROR, rv);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ /* Lock TPM */
+ rv = antirollback_lock_space_firmware();
+ if (rv) {
+ printk(BIOS_INFO, "Failed to lock TPM (%x)\n", rv);
+ vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_L_ERROR, 0);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ printk(BIOS_INFO, "Slot %c is selected\n", is_slot_a(&ctx) ? 'A' : 'B');
+ vb2_set_selected_region(wd, &fw_main);
+ timestamp_add_now(TS_END_VBOOT);
+}
diff --git a/src/vendorcode/google/chromeos/vboot2/verstage.c b/src/vendorcode/google/chromeos/vboot2/verstage.c
index 7803d39..3938ebf 100644
--- a/src/vendorcode/google/chromeos/vboot2/verstage.c
+++ b/src/vendorcode/google/chromeos/vboot2/verstage.c
@@ -1,7 +1,7 @@
/*
* This file is part of the coreboot project.
*
- * Copyright 2014 Google Inc.
+ * Copyright 2015 Google Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -9,7 +9,7 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
@@ -17,333 +17,30 @@
* Foundation, Inc.
*/
-#include <antirollback.h>
#include <arch/exception.h>
-#include <assert.h>
+#include <arch/hlt.h>
#include <console/console.h>
-#include <console/vtxprintf.h>
-#include <delay.h>
-#include <string.h>
-#include <timestamp.h>
-#include <vb2_api.h>
+#include <program_loading.h>
+#include "../vboot_common.h"
-#include "../chromeos.h"
-#include "misc.h"
-
-#define TODO_BLOCK_SIZE 1024
-
-static int is_slot_a(struct vb2_context *ctx)
-{
- return !(ctx->flags & VB2_CONTEXT_FW_SLOT_B);
-}
-
-/* exports */
-
-void vb2ex_printf(const char *func, const char *fmt, ...)
+void __attribute__((weak)) verstage_mainboard_init(void)
{
- va_list args;
-
- printk(BIOS_INFO, "VB2:%s() ", func);
- va_start(args, fmt);
- do_printk_va_list(BIOS_INFO, fmt, args);
- va_end(args);
-
- return;
-}
-
-int vb2ex_tpm_clear_owner(struct vb2_context *ctx)
-{
- uint32_t rv;
- printk(BIOS_INFO, "Clearing TPM owner\n");
- rv = tpm_clear_and_reenable();
- if (rv)
- return VB2_ERROR_EX_TPM_CLEAR_OWNER;
- return VB2_SUCCESS;
+ /* Default empty implementation. */
}
-int vb2ex_read_resource(struct vb2_context *ctx,
- enum vb2_resource_index index,
- uint32_t offset,
- void *buf,
- uint32_t size)
+void verstage(void)
{
- struct region_device rdev;
- const char *name;
-
- switch (index) {
- case VB2_RES_GBB:
- name = "GBB";
- break;
- case VB2_RES_FW_VBLOCK:
- if (is_slot_a(ctx))
- name = "VBLOCK_A";
- else
- name = "VBLOCK_B";
- break;
- default:
- return VB2_ERROR_EX_READ_RESOURCE_INDEX;
- }
-
- if (vboot_named_region_device(name, &rdev))
- return VB2_ERROR_EX_READ_RESOURCE_SIZE;
-
- if (rdev_readat(&rdev, buf, offset, size) != size)
- return VB2_ERROR_EX_READ_RESOURCE_SIZE;
-
- return VB2_SUCCESS;
-}
-
-/* No-op stubs that can be overridden by SoCs with hardware crypto support. */
-__attribute__((weak))
-int vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
- uint32_t data_size)
-{
- return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
-}
-
-__attribute__((weak))
-int vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size)
-{
- BUG(); /* Should never get called if init() returned an error. */
- return VB2_ERROR_UNKNOWN;
-}
-
-__attribute__((weak))
-int vb2ex_hwcrypto_digest_finalize(uint8_t *digest, uint32_t digest_size)
-{
- BUG(); /* Should never get called if init() returned an error. */
- return VB2_ERROR_UNKNOWN;
-}
-
-static int hash_body(struct vb2_context *ctx, struct region_device *fw_main)
-{
- uint64_t load_ts;
- uint32_t expected_size;
- uint8_t block[TODO_BLOCK_SIZE];
- size_t block_size = sizeof(block);
- size_t offset;
- int rv;
-
- /*
- * Since loading the firmware and calculating its hash is intertwined,
- * we use this little trick to measure them separately and pretend it
- * was first loaded and then hashed in one piece with the timestamps.
- * (This split won't make sense with memory-mapped media like on x86.)
- */
- load_ts = timestamp_get();
- timestamp_add(TS_START_HASH_BODY, load_ts);
-
- expected_size = region_device_sz(fw_main);
- offset = 0;
-
- /* Start the body hash */
- rv = vb2api_init_hash(ctx, VB2_HASH_TAG_FW_BODY, &expected_size);
- if (rv)
- return rv;
-
- /* Extend over the body */
- while (expected_size) {
- uint64_t temp_ts;
- if (block_size > expected_size)
- block_size = expected_size;
-
- temp_ts = timestamp_get();
- if (rdev_readat(fw_main, block, offset, block_size) < 0)
- return VB2_ERROR_UNKNOWN;
- load_ts += timestamp_get() - temp_ts;
-
- rv = vb2api_extend_hash(ctx, block, block_size);
- if (rv)
- return rv;
-
- expected_size -= block_size;
- offset += block_size;
- }
-
- timestamp_add(TS_DONE_LOADING, load_ts);
- timestamp_add_now(TS_DONE_HASHING);
-
- /* Check the result (with RSA signature verification) */
- rv = vb2api_check_hash(ctx);
- if (rv)
- return rv;
-
- timestamp_add_now(TS_END_HASH_BODY);
-
- return VB2_SUCCESS;
-}
-
-static int locate_firmware(struct vb2_context *ctx,
- struct region_device *fw_main)
-{
- const char *name;
-
- if (is_slot_a(ctx))
- name = "FW_MAIN_A";
- else
- name = "FW_MAIN_B";
-
- return vboot_named_region_device(name, fw_main);
-}
-
-/**
- * Save non-volatile and/or secure data if needed.
- */
-static void save_if_needed(struct vb2_context *ctx)
-{
- if (ctx->flags & VB2_CONTEXT_NVDATA_CHANGED) {
- printk(BIOS_INFO, "Saving nvdata\n");
- save_vbnv(ctx->nvdata);
- ctx->flags &= ~VB2_CONTEXT_NVDATA_CHANGED;
- }
- if (ctx->flags & VB2_CONTEXT_SECDATA_CHANGED) {
- printk(BIOS_INFO, "Saving secdata\n");
- antirollback_write_space_firmware(ctx);
- ctx->flags &= ~VB2_CONTEXT_SECDATA_CHANGED;
- }
-}
-
-static uint32_t extend_pcrs(struct vb2_context *ctx)
-{
- return tpm_extend_pcr(ctx, 0, BOOT_MODE_PCR) ||
- tpm_extend_pcr(ctx, 1, HWID_DIGEST_PCR);
-}
-
-static void init_vb2_working_data(void)
-{
- struct vb2_working_data *wd;
- size_t work_size;
-
- work_size = vb2_working_data_size();
- wd = vboot_get_working_data();
- memset(wd, 0, work_size);
- /*
- * vboot prefers 16-byte alignment. This takes away 16 bytes
- * from the VBOOT2_WORK region, but the vboot devs said that's okay.
- */
- wd->buffer_offset = ALIGN_UP(sizeof(*wd), 16);
- wd->buffer_size = work_size - wd->buffer_offset;
-}
-
-/**
- * Verify and select the firmware in the RW image
- *
- * TODO: Avoid loading a stage twice (once in hash_body & again in load_stage).
- * when per-stage verification is ready.
- */
-void verstage_main(void)
-{
- struct vb2_context ctx;
- struct region_device fw_main;
- struct vb2_working_data *wd;
- int rv;
- init_vb2_working_data();
- wd = vboot_get_working_data();
- timestamp_add_now(TS_START_VBOOT);
-
- /* Set up context and work buffer */
- memset(&ctx, 0, sizeof(ctx));
- ctx.workbuf = vboot_get_work_buffer(wd);
- ctx.workbuf_size = wd->buffer_size;
-
- /* Read nvdata from a non-volatile storage */
- read_vbnv(ctx.nvdata);
-
- /* Read secdata from TPM. Initialize TPM if secdata not found. We don't
- * check the return value here because vb2api_fw_phase1 will catch
- * invalid secdata and tell us what to do (=reboot). */
- timestamp_add_now(TS_START_TPMINIT);
- antirollback_read_space_firmware(&ctx);
- timestamp_add_now(TS_END_TPMINIT);
-
- if (!IS_ENABLED(CONFIG_VIRTUAL_DEV_SWITCH) &&
- get_developer_mode_switch())
- ctx.flags |= VB2_CONTEXT_FORCE_DEVELOPER_MODE;
-
- if (get_recovery_mode_switch()) {
- clear_recovery_mode_switch();
- ctx.flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
- if (IS_ENABLED(CONFIG_VBOOT_DISABLE_DEV_ON_RECOVERY))
- ctx.flags |= VB2_DISABLE_DEVELOPER_MODE;
- }
-
- if (IS_ENABLED(CONFIG_WIPEOUT_SUPPORTED) && get_wipeout_mode_switch())
- ctx.flags |= VB2_CONTEXT_FORCE_WIPEOUT_MODE;
-
- if (IS_ENABLED(CONFIG_LID_SWITCH) && !get_lid_switch())
- ctx.flags |= VB2_CONTEXT_NOFAIL_BOOT;
-
- /* Do early init (set up secdata and NVRAM, load GBB) */
- printk(BIOS_INFO, "Phase 1\n");
- rv = vb2api_fw_phase1(&ctx);
- if (rv) {
- printk(BIOS_INFO, "Recovery requested (%x)\n", rv);
- /* If we need recovery mode, leave firmware selection now */
- save_if_needed(&ctx);
- extend_pcrs(&ctx); /* ignore failures */
- timestamp_add_now(TS_END_VBOOT);
- return;
- }
-
- /* Determine which firmware slot to boot (based on NVRAM) */
- printk(BIOS_INFO, "Phase 2\n");
- rv = vb2api_fw_phase2(&ctx);
- if (rv) {
- printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
- save_if_needed(&ctx);
- vboot_reboot();
- }
-
- /* Try that slot (verify its keyblock and preamble) */
- printk(BIOS_INFO, "Phase 3\n");
- timestamp_add_now(TS_START_VERIFY_SLOT);
- rv = vb2api_fw_phase3(&ctx);
- timestamp_add_now(TS_END_VERIFY_SLOT);
- if (rv) {
- printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
- save_if_needed(&ctx);
- vboot_reboot();
- }
-
- printk(BIOS_INFO, "Phase 4\n");
- rv = locate_firmware(&ctx, &fw_main);
- if (rv)
- die("Failed to read FMAP to locate firmware");
-
- rv = hash_body(&ctx, &fw_main);
- save_if_needed(&ctx);
- if (rv) {
- printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
- vboot_reboot();
- }
-
- rv = extend_pcrs(&ctx);
- if (rv) {
- printk(BIOS_WARNING, "Failed to extend TPM PCRs (%#x)\n", rv);
- vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_U_ERROR, rv);
- save_if_needed(&ctx);
- vboot_reboot();
- }
+ console_init();
+ exception_init();
+ verstage_mainboard_init();
- /* Lock TPM */
- rv = antirollback_lock_space_firmware();
- if (rv) {
- printk(BIOS_INFO, "Failed to lock TPM (%x)\n", rv);
- vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_L_ERROR, 0);
- save_if_needed(&ctx);
- vboot_reboot();
+ if (IS_ENABLED(CONFIG_RETURN_FROM_VERSTAGE)) {
+ verstage_main();
+ } else {
+ run_romstage();
+ hlt();
}
-
- printk(BIOS_INFO, "Slot %c is selected\n", is_slot_a(&ctx) ? 'A' : 'B');
- vb2_set_selected_region(wd, &fw_main);
- timestamp_add_now(TS_END_VBOOT);
}
-#if IS_ENABLED(CONFIG_RETURN_FROM_VERSTAGE)
-void main(void)
-{
- console_init();
- exception_init();
- verstage_main();
-}
-#endif
+/* This is for boards that rely on main() for an entry point of a stage. */
+void main(void) __attribute__((alias ("verstage_chain_load")));
diff --git a/src/vendorcode/google/chromeos/vboot_common.h b/src/vendorcode/google/chromeos/vboot_common.h
index f4d5e11..3a9c89b 100644
--- a/src/vendorcode/google/chromeos/vboot_common.h
+++ b/src/vendorcode/google/chromeos/vboot_common.h
@@ -48,4 +48,10 @@ int vboot_enable_developer(void);
void vboot_reboot(void);
+/* Main logic for verified boot. verstage() is the stage entry point
+ * while the verstage_main() is just the core logic. */
+void verstage_main(void);
+void verstage_mainboard_init(void);
+void verstage(void);
+
#endif /* VBOOT_COMMON_H */
Aaron Durbin (adurbin(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11744
-gerrit
commit 23de41a14c53a8f86b7f70f26a195a4ec128e8c9
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Tue Sep 29 17:56:59 2015 -0500
vboot: provide a unified flow for separate verstage
The vboot verification in a stage proper is unified
replacing duplicate code in the tegra SoC code. The
original verstage.c file is renamed to reflect its
real purpose. The support for a single verstage flow
is added to the vboot2 directory proper.
BUG=chrome-os-partner:44827
BRANCH=None
TEST=Built glados.
Change-Id: I14593e1fc69a1654fa27b512eb4b612395b94ce5
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/mainboard/google/foster/Makefile.inc | 1 -
src/mainboard/google/foster/verstage.c | 29 --
src/soc/nvidia/tegra132/include/soc/verstage.h | 2 +-
src/soc/nvidia/tegra132/verstage.c | 48 ---
src/soc/nvidia/tegra210/include/soc/verstage.h | 2 +-
src/soc/nvidia/tegra210/verstage.c | 45 ---
src/vendorcode/google/chromeos/vboot2/Makefile.inc | 3 +-
src/vendorcode/google/chromeos/vboot2/misc.h | 1 -
.../google/chromeos/vboot2/vboot_logic.c | 352 +++++++++++++++++++++
src/vendorcode/google/chromeos/vboot2/verstage.c | 339 ++------------------
src/vendorcode/google/chromeos/vboot_common.h | 6 +
11 files changed, 380 insertions(+), 448 deletions(-)
diff --git a/src/mainboard/google/foster/Makefile.inc b/src/mainboard/google/foster/Makefile.inc
index 7b2329e..51208c7 100644
--- a/src/mainboard/google/foster/Makefile.inc
+++ b/src/mainboard/google/foster/Makefile.inc
@@ -32,7 +32,6 @@ bootblock-y += bootblock.c
bootblock-y += pmic.c
bootblock-y += reset.c
-verstage-y += verstage.c
verstage-y += chromeos.c
verstage-y += reset.c
diff --git a/src/mainboard/google/foster/verstage.c b/src/mainboard/google/foster/verstage.c
deleted file mode 100644
index d5bcd44..0000000
--- a/src/mainboard/google/foster/verstage.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2014 Google Inc.
- * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-#include <soc/addressmap.h>
-#include <soc/funitcfg.h>
-#include <soc/padconfig.h>
-#include <soc/verstage.h>
-#include <soc/nvidia/tegra/i2c.h>
-
-void verstage_mainboard_init(void)
-{
-}
diff --git a/src/soc/nvidia/tegra132/include/soc/verstage.h b/src/soc/nvidia/tegra132/include/soc/verstage.h
index df6a386..d54a111 100644
--- a/src/soc/nvidia/tegra132/include/soc/verstage.h
+++ b/src/soc/nvidia/tegra132/include/soc/verstage.h
@@ -20,6 +20,6 @@
#ifndef __SOC_NVIDIA_TEGRA132_SOC_VERSTAGE_H__
#define __SOC_NVIDIA_TEGRA132_SOC_VERSTAGE_H__
-void verstage_mainboard_init(void);
+#include <vendorcode/google/chromeos/chromeos.h>
#endif /* __SOC_NVIDIA_TEGRA132_SOC_VERSTAGE_H__ */
diff --git a/src/soc/nvidia/tegra132/verstage.c b/src/soc/nvidia/tegra132/verstage.c
deleted file mode 100644
index d6eba9a..0000000
--- a/src/soc/nvidia/tegra132/verstage.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2014 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-#include <arch/cache.h>
-#include <arch/exception.h>
-#include <arch/hlt.h>
-#include <arch/stages.h>
-#include <console/console.h>
-#include <soc/verstage.h>
-#include <program_loading.h>
-#include <timestamp.h>
-
-void __attribute__((weak)) verstage_mainboard_init(void)
-{
- /* Default empty implementation. */
-}
-
-static void verstage(void)
-{
- console_init();
- timestamp_add_now(TS_START_VBOOT);
- exception_init();
- verstage_mainboard_init();
-
- run_romstage();
-}
-
-void main(void)
-{
- verstage();
- hlt();
-}
diff --git a/src/soc/nvidia/tegra210/include/soc/verstage.h b/src/soc/nvidia/tegra210/include/soc/verstage.h
index 6c37218..d6564c9 100644
--- a/src/soc/nvidia/tegra210/include/soc/verstage.h
+++ b/src/soc/nvidia/tegra210/include/soc/verstage.h
@@ -20,6 +20,6 @@
#ifndef __SOC_NVIDIA_TEGRA210_SOC_VERSTAGE_H__
#define __SOC_NVIDIA_TEGRA210_SOC_VERSTAGE_H__
-void verstage_mainboard_init(void);
+#include <vendorcode/google/chromeos/chromeos.h>
#endif /* __SOC_NVIDIA_TEGRA210_SOC_VERSTAGE_H__ */
diff --git a/src/soc/nvidia/tegra210/verstage.c b/src/soc/nvidia/tegra210/verstage.c
deleted file mode 100644
index 6a4df29..0000000
--- a/src/soc/nvidia/tegra210/verstage.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2014 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-#include <arch/cache.h>
-#include <arch/exception.h>
-#include <arch/hlt.h>
-#include <soc/verstage.h>
-#include <console/console.h>
-#include <program_loading.h>
-
-void __attribute__((weak)) verstage_mainboard_init(void)
-{
- /* Default empty implementation. */
-}
-
-static void verstage(void)
-{
- console_init();
- exception_init();
- verstage_mainboard_init();
-
- run_romstage();
-}
-
-void main(void)
-{
- verstage();
- hlt();
-}
diff --git a/src/vendorcode/google/chromeos/vboot2/Makefile.inc b/src/vendorcode/google/chromeos/vboot2/Makefile.inc
index 21613ba..c2ee868 100644
--- a/src/vendorcode/google/chromeos/vboot2/Makefile.inc
+++ b/src/vendorcode/google/chromeos/vboot2/Makefile.inc
@@ -31,8 +31,9 @@ romstage-y += ../vboot_common.c
ramstage-y += ../vboot_common.c
bootblock-y += common.c
-libverstage-y += verstage.c
+libverstage-y += vboot_logic.c
verstage-y += common.c
+verstage-y += verstage.c
ifeq (${CONFIG_VBOOT2_MOCK_SECDATA},y)
libverstage-y += secdata_mock.c
else
diff --git a/src/vendorcode/google/chromeos/vboot2/misc.h b/src/vendorcode/google/chromeos/vboot2/misc.h
index d4f9f48..305d0da 100644
--- a/src/vendorcode/google/chromeos/vboot2/misc.h
+++ b/src/vendorcode/google/chromeos/vboot2/misc.h
@@ -23,7 +23,6 @@
#include "../vboot_common.h"
void vboot_fill_handoff(void);
-void verstage_main(void);
void *vboot_load_stage(int stage_index,
struct region *fw_main,
struct vboot_components *fw_info);
diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_logic.c b/src/vendorcode/google/chromeos/vboot2/vboot_logic.c
new file mode 100644
index 0000000..76355ec
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/vboot_logic.c
@@ -0,0 +1,352 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.
+ */
+
+#include <antirollback.h>
+#include <arch/exception.h>
+#include <assert.h>
+#include <console/console.h>
+#include <console/vtxprintf.h>
+#include <delay.h>
+#include <string.h>
+#include <timestamp.h>
+#include <vb2_api.h>
+
+#include "../chromeos.h"
+#include "misc.h"
+
+#define TODO_BLOCK_SIZE 1024
+
+static int is_slot_a(struct vb2_context *ctx)
+{
+ return !(ctx->flags & VB2_CONTEXT_FW_SLOT_B);
+}
+
+/* exports */
+
+void vb2ex_printf(const char *func, const char *fmt, ...)
+{
+ va_list args;
+
+ printk(BIOS_INFO, "VB2:%s() ", func);
+ va_start(args, fmt);
+ do_printk_va_list(BIOS_INFO, fmt, args);
+ va_end(args);
+
+ return;
+}
+
+int vb2ex_tpm_clear_owner(struct vb2_context *ctx)
+{
+ uint32_t rv;
+ printk(BIOS_INFO, "Clearing TPM owner\n");
+ rv = tpm_clear_and_reenable();
+ if (rv)
+ return VB2_ERROR_EX_TPM_CLEAR_OWNER;
+ return VB2_SUCCESS;
+}
+
+int vb2ex_read_resource(struct vb2_context *ctx,
+ enum vb2_resource_index index,
+ uint32_t offset,
+ void *buf,
+ uint32_t size)
+{
+ struct region_device rdev;
+ const char *name;
+
+ switch (index) {
+ case VB2_RES_GBB:
+ name = "GBB";
+ break;
+ case VB2_RES_FW_VBLOCK:
+ if (is_slot_a(ctx))
+ name = "VBLOCK_A";
+ else
+ name = "VBLOCK_B";
+ break;
+ default:
+ return VB2_ERROR_EX_READ_RESOURCE_INDEX;
+ }
+
+ if (vboot_named_region_device(name, &rdev))
+ return VB2_ERROR_EX_READ_RESOURCE_SIZE;
+
+ if (rdev_readat(&rdev, buf, offset, size) != size)
+ return VB2_ERROR_EX_READ_RESOURCE_SIZE;
+
+ return VB2_SUCCESS;
+}
+
+/* No-op stubs that can be overridden by SoCs with hardware crypto support. */
+__attribute__((weak))
+int vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
+ uint32_t data_size)
+{
+ return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
+}
+
+__attribute__((weak))
+int vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size)
+{
+ BUG(); /* Should never get called if init() returned an error. */
+ return VB2_ERROR_UNKNOWN;
+}
+
+__attribute__((weak))
+int vb2ex_hwcrypto_digest_finalize(uint8_t *digest, uint32_t digest_size)
+{
+ BUG(); /* Should never get called if init() returned an error. */
+ return VB2_ERROR_UNKNOWN;
+}
+
+static int hash_body(struct vb2_context *ctx, struct region_device *fw_main)
+{
+ uint64_t load_ts;
+ uint32_t expected_size;
+ uint8_t block[TODO_BLOCK_SIZE];
+ size_t block_size = sizeof(block);
+ size_t offset;
+ int rv;
+
+ /*
+ * Since loading the firmware and calculating its hash is intertwined,
+ * we use this little trick to measure them separately and pretend it
+ * was first loaded and then hashed in one piece with the timestamps.
+ * (This split won't make sense with memory-mapped media like on x86.)
+ */
+ load_ts = timestamp_get();
+ timestamp_add(TS_START_HASH_BODY, load_ts);
+
+ expected_size = region_device_sz(fw_main);
+ offset = 0;
+
+ /* Start the body hash */
+ rv = vb2api_init_hash(ctx, VB2_HASH_TAG_FW_BODY, &expected_size);
+ if (rv)
+ return rv;
+
+ /* Extend over the body */
+ while (expected_size) {
+ uint64_t temp_ts;
+ if (block_size > expected_size)
+ block_size = expected_size;
+
+ temp_ts = timestamp_get();
+ if (rdev_readat(fw_main, block, offset, block_size) < 0)
+ return VB2_ERROR_UNKNOWN;
+ load_ts += timestamp_get() - temp_ts;
+
+ rv = vb2api_extend_hash(ctx, block, block_size);
+ if (rv)
+ return rv;
+
+ expected_size -= block_size;
+ offset += block_size;
+ }
+
+ timestamp_add(TS_DONE_LOADING, load_ts);
+ timestamp_add_now(TS_DONE_HASHING);
+
+ /* Check the result (with RSA signature verification) */
+ rv = vb2api_check_hash(ctx);
+ if (rv)
+ return rv;
+
+ timestamp_add_now(TS_END_HASH_BODY);
+
+ return VB2_SUCCESS;
+}
+
+static int locate_firmware(struct vb2_context *ctx,
+ struct region_device *fw_main)
+{
+ const char *name;
+
+ if (is_slot_a(ctx))
+ name = "FW_MAIN_A";
+ else
+ name = "FW_MAIN_B";
+
+ return vboot_named_region_device(name, fw_main);
+}
+
+/**
+ * Save non-volatile and/or secure data if needed.
+ */
+static void save_if_needed(struct vb2_context *ctx)
+{
+ if (ctx->flags & VB2_CONTEXT_NVDATA_CHANGED) {
+ printk(BIOS_INFO, "Saving nvdata\n");
+ save_vbnv(ctx->nvdata);
+ ctx->flags &= ~VB2_CONTEXT_NVDATA_CHANGED;
+ }
+ if (ctx->flags & VB2_CONTEXT_SECDATA_CHANGED) {
+ printk(BIOS_INFO, "Saving secdata\n");
+ antirollback_write_space_firmware(ctx);
+ ctx->flags &= ~VB2_CONTEXT_SECDATA_CHANGED;
+ }
+}
+
+static uint32_t extend_pcrs(struct vb2_context *ctx)
+{
+ return tpm_extend_pcr(ctx, 0, BOOT_MODE_PCR) ||
+ tpm_extend_pcr(ctx, 1, HWID_DIGEST_PCR);
+}
+
+static void init_vb2_working_data(void)
+{
+ struct vb2_working_data *wd;
+ size_t work_size;
+
+ work_size = vb2_working_data_size();
+ wd = vboot_get_working_data();
+ memset(wd, 0, work_size);
+ /*
+ * vboot prefers 16-byte alignment. This takes away 16 bytes
+ * from the VBOOT2_WORK region, but the vboot devs said that's okay.
+ */
+ wd->buffer_offset = ALIGN_UP(sizeof(*wd), 16);
+ wd->buffer_size = work_size - wd->buffer_offset;
+}
+
+/**
+ * Verify and select the firmware in the RW image
+ *
+ * TODO: Avoid loading a stage twice (once in hash_body & again in load_stage).
+ * when per-stage verification is ready.
+ */
+void verstage_main(void)
+{
+ struct vb2_context ctx;
+ struct region_device fw_main;
+ struct vb2_working_data *wd;
+ int rv;
+ init_vb2_working_data();
+ wd = vboot_get_working_data();
+ timestamp_add_now(TS_START_VBOOT);
+
+ /* Set up context and work buffer */
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.workbuf = vboot_get_work_buffer(wd);
+ ctx.workbuf_size = wd->buffer_size;
+
+ /* Read nvdata from a non-volatile storage */
+ read_vbnv(ctx.nvdata);
+
+ /* Read secdata from TPM. Initialize TPM if secdata not found. We don't
+ * check the return value here because vb2api_fw_phase1 will catch
+ * invalid secdata and tell us what to do (=reboot). */
+ timestamp_add_now(TS_START_TPMINIT);
+ antirollback_read_space_firmware(&ctx);
+ timestamp_add_now(TS_END_TPMINIT);
+
+ if (!IS_ENABLED(CONFIG_VIRTUAL_DEV_SWITCH) &&
+ get_developer_mode_switch())
+ ctx.flags |= VB2_CONTEXT_FORCE_DEVELOPER_MODE;
+
+ if (get_recovery_mode_switch()) {
+ clear_recovery_mode_switch();
+ ctx.flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
+ if (IS_ENABLED(CONFIG_VBOOT_DISABLE_DEV_ON_RECOVERY))
+ ctx.flags |= VB2_DISABLE_DEVELOPER_MODE;
+ }
+
+ if (IS_ENABLED(CONFIG_WIPEOUT_SUPPORTED) && get_wipeout_mode_switch())
+ ctx.flags |= VB2_CONTEXT_FORCE_WIPEOUT_MODE;
+
+ if (IS_ENABLED(CONFIG_LID_SWITCH) && !get_lid_switch())
+ ctx.flags |= VB2_CONTEXT_NOFAIL_BOOT;
+
+ /* Do early init (set up secdata and NVRAM, load GBB) */
+ printk(BIOS_INFO, "Phase 1\n");
+ rv = vb2api_fw_phase1(&ctx);
+
+ if (rv) {
+ /*
+ * If vb2api_fw_phase1 fails, check for return value.
+ * If it is set to VB2_ERROR_API_PHASE1_RECOVERY, then continue
+ * into recovery mode.
+ * For any other error code, save context if needed and reboot.
+ */
+ if (rv == VB2_ERROR_API_PHASE1_RECOVERY) {
+ printk(BIOS_INFO, "Recovery requested (%x)\n", rv);
+ save_if_needed(&ctx);
+ extend_pcrs(&ctx); /* ignore failures */
+ timestamp_add_now(TS_END_VBOOT);
+ return;
+ }
+
+ printk(BIOS_INFO, "Reboot reqested (%x)\n", rv);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ /* Determine which firmware slot to boot (based on NVRAM) */
+ printk(BIOS_INFO, "Phase 2\n");
+ rv = vb2api_fw_phase2(&ctx);
+ if (rv) {
+ printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ /* Try that slot (verify its keyblock and preamble) */
+ printk(BIOS_INFO, "Phase 3\n");
+ timestamp_add_now(TS_START_VERIFY_SLOT);
+ rv = vb2api_fw_phase3(&ctx);
+ timestamp_add_now(TS_END_VERIFY_SLOT);
+ if (rv) {
+ printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ printk(BIOS_INFO, "Phase 4\n");
+ rv = locate_firmware(&ctx, &fw_main);
+ if (rv)
+ die("Failed to read FMAP to locate firmware");
+
+ rv = hash_body(&ctx, &fw_main);
+ save_if_needed(&ctx);
+ if (rv) {
+ printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
+ vboot_reboot();
+ }
+
+ rv = extend_pcrs(&ctx);
+ if (rv) {
+ printk(BIOS_WARNING, "Failed to extend TPM PCRs (%#x)\n", rv);
+ vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_U_ERROR, rv);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ /* Lock TPM */
+ rv = antirollback_lock_space_firmware();
+ if (rv) {
+ printk(BIOS_INFO, "Failed to lock TPM (%x)\n", rv);
+ vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_L_ERROR, 0);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ printk(BIOS_INFO, "Slot %c is selected\n", is_slot_a(&ctx) ? 'A' : 'B');
+ vb2_set_selected_region(wd, &fw_main);
+ timestamp_add_now(TS_END_VBOOT);
+}
diff --git a/src/vendorcode/google/chromeos/vboot2/verstage.c b/src/vendorcode/google/chromeos/vboot2/verstage.c
index 7803d39..d0b75f9 100644
--- a/src/vendorcode/google/chromeos/vboot2/verstage.c
+++ b/src/vendorcode/google/chromeos/vboot2/verstage.c
@@ -1,7 +1,7 @@
/*
* This file is part of the coreboot project.
*
- * Copyright 2014 Google Inc.
+ * Copyright 2015 Google Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -9,7 +9,7 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
@@ -17,333 +17,30 @@
* Foundation, Inc.
*/
-#include <antirollback.h>
#include <arch/exception.h>
-#include <assert.h>
+#include <arch/hlt.h>
#include <console/console.h>
-#include <console/vtxprintf.h>
-#include <delay.h>
-#include <string.h>
-#include <timestamp.h>
-#include <vb2_api.h>
+#include <program_loading.h>
+#include "../vboot_common.h"
-#include "../chromeos.h"
-#include "misc.h"
-
-#define TODO_BLOCK_SIZE 1024
-
-static int is_slot_a(struct vb2_context *ctx)
-{
- return !(ctx->flags & VB2_CONTEXT_FW_SLOT_B);
-}
-
-/* exports */
-
-void vb2ex_printf(const char *func, const char *fmt, ...)
+void __attribute__((weak)) verstage_mainboard_init(void)
{
- va_list args;
-
- printk(BIOS_INFO, "VB2:%s() ", func);
- va_start(args, fmt);
- do_printk_va_list(BIOS_INFO, fmt, args);
- va_end(args);
-
- return;
-}
-
-int vb2ex_tpm_clear_owner(struct vb2_context *ctx)
-{
- uint32_t rv;
- printk(BIOS_INFO, "Clearing TPM owner\n");
- rv = tpm_clear_and_reenable();
- if (rv)
- return VB2_ERROR_EX_TPM_CLEAR_OWNER;
- return VB2_SUCCESS;
+ /* Default empty implementation. */
}
-int vb2ex_read_resource(struct vb2_context *ctx,
- enum vb2_resource_index index,
- uint32_t offset,
- void *buf,
- uint32_t size)
+void verstage(void)
{
- struct region_device rdev;
- const char *name;
-
- switch (index) {
- case VB2_RES_GBB:
- name = "GBB";
- break;
- case VB2_RES_FW_VBLOCK:
- if (is_slot_a(ctx))
- name = "VBLOCK_A";
- else
- name = "VBLOCK_B";
- break;
- default:
- return VB2_ERROR_EX_READ_RESOURCE_INDEX;
- }
-
- if (vboot_named_region_device(name, &rdev))
- return VB2_ERROR_EX_READ_RESOURCE_SIZE;
-
- if (rdev_readat(&rdev, buf, offset, size) != size)
- return VB2_ERROR_EX_READ_RESOURCE_SIZE;
-
- return VB2_SUCCESS;
-}
-
-/* No-op stubs that can be overridden by SoCs with hardware crypto support. */
-__attribute__((weak))
-int vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
- uint32_t data_size)
-{
- return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
-}
-
-__attribute__((weak))
-int vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size)
-{
- BUG(); /* Should never get called if init() returned an error. */
- return VB2_ERROR_UNKNOWN;
-}
-
-__attribute__((weak))
-int vb2ex_hwcrypto_digest_finalize(uint8_t *digest, uint32_t digest_size)
-{
- BUG(); /* Should never get called if init() returned an error. */
- return VB2_ERROR_UNKNOWN;
-}
-
-static int hash_body(struct vb2_context *ctx, struct region_device *fw_main)
-{
- uint64_t load_ts;
- uint32_t expected_size;
- uint8_t block[TODO_BLOCK_SIZE];
- size_t block_size = sizeof(block);
- size_t offset;
- int rv;
-
- /*
- * Since loading the firmware and calculating its hash is intertwined,
- * we use this little trick to measure them separately and pretend it
- * was first loaded and then hashed in one piece with the timestamps.
- * (This split won't make sense with memory-mapped media like on x86.)
- */
- load_ts = timestamp_get();
- timestamp_add(TS_START_HASH_BODY, load_ts);
-
- expected_size = region_device_sz(fw_main);
- offset = 0;
-
- /* Start the body hash */
- rv = vb2api_init_hash(ctx, VB2_HASH_TAG_FW_BODY, &expected_size);
- if (rv)
- return rv;
-
- /* Extend over the body */
- while (expected_size) {
- uint64_t temp_ts;
- if (block_size > expected_size)
- block_size = expected_size;
-
- temp_ts = timestamp_get();
- if (rdev_readat(fw_main, block, offset, block_size) < 0)
- return VB2_ERROR_UNKNOWN;
- load_ts += timestamp_get() - temp_ts;
-
- rv = vb2api_extend_hash(ctx, block, block_size);
- if (rv)
- return rv;
-
- expected_size -= block_size;
- offset += block_size;
- }
-
- timestamp_add(TS_DONE_LOADING, load_ts);
- timestamp_add_now(TS_DONE_HASHING);
-
- /* Check the result (with RSA signature verification) */
- rv = vb2api_check_hash(ctx);
- if (rv)
- return rv;
-
- timestamp_add_now(TS_END_HASH_BODY);
-
- return VB2_SUCCESS;
-}
-
-static int locate_firmware(struct vb2_context *ctx,
- struct region_device *fw_main)
-{
- const char *name;
-
- if (is_slot_a(ctx))
- name = "FW_MAIN_A";
- else
- name = "FW_MAIN_B";
-
- return vboot_named_region_device(name, fw_main);
-}
-
-/**
- * Save non-volatile and/or secure data if needed.
- */
-static void save_if_needed(struct vb2_context *ctx)
-{
- if (ctx->flags & VB2_CONTEXT_NVDATA_CHANGED) {
- printk(BIOS_INFO, "Saving nvdata\n");
- save_vbnv(ctx->nvdata);
- ctx->flags &= ~VB2_CONTEXT_NVDATA_CHANGED;
- }
- if (ctx->flags & VB2_CONTEXT_SECDATA_CHANGED) {
- printk(BIOS_INFO, "Saving secdata\n");
- antirollback_write_space_firmware(ctx);
- ctx->flags &= ~VB2_CONTEXT_SECDATA_CHANGED;
- }
-}
-
-static uint32_t extend_pcrs(struct vb2_context *ctx)
-{
- return tpm_extend_pcr(ctx, 0, BOOT_MODE_PCR) ||
- tpm_extend_pcr(ctx, 1, HWID_DIGEST_PCR);
-}
-
-static void init_vb2_working_data(void)
-{
- struct vb2_working_data *wd;
- size_t work_size;
-
- work_size = vb2_working_data_size();
- wd = vboot_get_working_data();
- memset(wd, 0, work_size);
- /*
- * vboot prefers 16-byte alignment. This takes away 16 bytes
- * from the VBOOT2_WORK region, but the vboot devs said that's okay.
- */
- wd->buffer_offset = ALIGN_UP(sizeof(*wd), 16);
- wd->buffer_size = work_size - wd->buffer_offset;
-}
-
-/**
- * Verify and select the firmware in the RW image
- *
- * TODO: Avoid loading a stage twice (once in hash_body & again in load_stage).
- * when per-stage verification is ready.
- */
-void verstage_main(void)
-{
- struct vb2_context ctx;
- struct region_device fw_main;
- struct vb2_working_data *wd;
- int rv;
- init_vb2_working_data();
- wd = vboot_get_working_data();
- timestamp_add_now(TS_START_VBOOT);
-
- /* Set up context and work buffer */
- memset(&ctx, 0, sizeof(ctx));
- ctx.workbuf = vboot_get_work_buffer(wd);
- ctx.workbuf_size = wd->buffer_size;
-
- /* Read nvdata from a non-volatile storage */
- read_vbnv(ctx.nvdata);
-
- /* Read secdata from TPM. Initialize TPM if secdata not found. We don't
- * check the return value here because vb2api_fw_phase1 will catch
- * invalid secdata and tell us what to do (=reboot). */
- timestamp_add_now(TS_START_TPMINIT);
- antirollback_read_space_firmware(&ctx);
- timestamp_add_now(TS_END_TPMINIT);
-
- if (!IS_ENABLED(CONFIG_VIRTUAL_DEV_SWITCH) &&
- get_developer_mode_switch())
- ctx.flags |= VB2_CONTEXT_FORCE_DEVELOPER_MODE;
-
- if (get_recovery_mode_switch()) {
- clear_recovery_mode_switch();
- ctx.flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
- if (IS_ENABLED(CONFIG_VBOOT_DISABLE_DEV_ON_RECOVERY))
- ctx.flags |= VB2_DISABLE_DEVELOPER_MODE;
- }
-
- if (IS_ENABLED(CONFIG_WIPEOUT_SUPPORTED) && get_wipeout_mode_switch())
- ctx.flags |= VB2_CONTEXT_FORCE_WIPEOUT_MODE;
-
- if (IS_ENABLED(CONFIG_LID_SWITCH) && !get_lid_switch())
- ctx.flags |= VB2_CONTEXT_NOFAIL_BOOT;
-
- /* Do early init (set up secdata and NVRAM, load GBB) */
- printk(BIOS_INFO, "Phase 1\n");
- rv = vb2api_fw_phase1(&ctx);
- if (rv) {
- printk(BIOS_INFO, "Recovery requested (%x)\n", rv);
- /* If we need recovery mode, leave firmware selection now */
- save_if_needed(&ctx);
- extend_pcrs(&ctx); /* ignore failures */
- timestamp_add_now(TS_END_VBOOT);
- return;
- }
-
- /* Determine which firmware slot to boot (based on NVRAM) */
- printk(BIOS_INFO, "Phase 2\n");
- rv = vb2api_fw_phase2(&ctx);
- if (rv) {
- printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
- save_if_needed(&ctx);
- vboot_reboot();
- }
-
- /* Try that slot (verify its keyblock and preamble) */
- printk(BIOS_INFO, "Phase 3\n");
- timestamp_add_now(TS_START_VERIFY_SLOT);
- rv = vb2api_fw_phase3(&ctx);
- timestamp_add_now(TS_END_VERIFY_SLOT);
- if (rv) {
- printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
- save_if_needed(&ctx);
- vboot_reboot();
- }
-
- printk(BIOS_INFO, "Phase 4\n");
- rv = locate_firmware(&ctx, &fw_main);
- if (rv)
- die("Failed to read FMAP to locate firmware");
-
- rv = hash_body(&ctx, &fw_main);
- save_if_needed(&ctx);
- if (rv) {
- printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
- vboot_reboot();
- }
-
- rv = extend_pcrs(&ctx);
- if (rv) {
- printk(BIOS_WARNING, "Failed to extend TPM PCRs (%#x)\n", rv);
- vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_U_ERROR, rv);
- save_if_needed(&ctx);
- vboot_reboot();
- }
+ console_init();
+ exception_init();
+ verstage_mainboard_init();
- /* Lock TPM */
- rv = antirollback_lock_space_firmware();
- if (rv) {
- printk(BIOS_INFO, "Failed to lock TPM (%x)\n", rv);
- vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_L_ERROR, 0);
- save_if_needed(&ctx);
- vboot_reboot();
+ if (IS_ENABLED(CONFIG_RETURN_FROM_VERSTAGE)) {
+ verstage_main();
+ } else {
+ run_romstage();
+ hlt();
}
-
- printk(BIOS_INFO, "Slot %c is selected\n", is_slot_a(&ctx) ? 'A' : 'B');
- vb2_set_selected_region(wd, &fw_main);
- timestamp_add_now(TS_END_VBOOT);
}
-#if IS_ENABLED(CONFIG_RETURN_FROM_VERSTAGE)
-void main(void)
-{
- console_init();
- exception_init();
- verstage_main();
-}
-#endif
+/* This is for boards that rely on main() for an entry point of a stage. */
+void main(void) __attribute__((alias ("verstage_chain_load")))
diff --git a/src/vendorcode/google/chromeos/vboot_common.h b/src/vendorcode/google/chromeos/vboot_common.h
index f4d5e11..3a9c89b 100644
--- a/src/vendorcode/google/chromeos/vboot_common.h
+++ b/src/vendorcode/google/chromeos/vboot_common.h
@@ -48,4 +48,10 @@ int vboot_enable_developer(void);
void vboot_reboot(void);
+/* Main logic for verified boot. verstage() is the stage entry point
+ * while the verstage_main() is just the core logic. */
+void verstage_main(void);
+void verstage_mainboard_init(void);
+void verstage(void);
+
#endif /* VBOOT_COMMON_H */
Aaron Durbin (adurbin(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11744
-gerrit
commit 6ad3c15c861b956e6fac8b1d36a67191be8b7563
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Tue Sep 29 17:56:59 2015 -0500
vboot: provide a unified flow for separate verstage
The vboot verification in a stage proper is unified
replacing duplicate code in the tegra SoC code. The
original verstage.c file is renamed to reflect its
real purpose. The support for a single verstage flow
is added to the vboot2 directory proper.
BUG=chrome-os-partner:44827
BRANCH=None
TEST=Built glados.
Change-Id: I14593e1fc69a1654fa27b512eb4b612395b94ce5
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/mainboard/google/foster/Makefile.inc | 1 -
src/mainboard/google/foster/verstage.c | 29 --
src/soc/nvidia/tegra132/include/soc/verstage.h | 2 +-
src/soc/nvidia/tegra132/verstage.c | 48 ---
src/soc/nvidia/tegra210/include/soc/verstage.h | 2 +-
src/soc/nvidia/tegra210/verstage.c | 45 ---
src/vendorcode/google/chromeos/vboot2/Makefile.inc | 3 +-
src/vendorcode/google/chromeos/vboot2/misc.h | 1 -
.../google/chromeos/vboot2/vboot_logic.c | 352 +++++++++++++++++++++
src/vendorcode/google/chromeos/vboot2/verstage.c | 338 +-------------------
src/vendorcode/google/chromeos/vboot_common.h | 6 +
11 files changed, 379 insertions(+), 448 deletions(-)
diff --git a/src/mainboard/google/foster/Makefile.inc b/src/mainboard/google/foster/Makefile.inc
index 7b2329e..51208c7 100644
--- a/src/mainboard/google/foster/Makefile.inc
+++ b/src/mainboard/google/foster/Makefile.inc
@@ -32,7 +32,6 @@ bootblock-y += bootblock.c
bootblock-y += pmic.c
bootblock-y += reset.c
-verstage-y += verstage.c
verstage-y += chromeos.c
verstage-y += reset.c
diff --git a/src/mainboard/google/foster/verstage.c b/src/mainboard/google/foster/verstage.c
deleted file mode 100644
index d5bcd44..0000000
--- a/src/mainboard/google/foster/verstage.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2014 Google Inc.
- * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-#include <soc/addressmap.h>
-#include <soc/funitcfg.h>
-#include <soc/padconfig.h>
-#include <soc/verstage.h>
-#include <soc/nvidia/tegra/i2c.h>
-
-void verstage_mainboard_init(void)
-{
-}
diff --git a/src/soc/nvidia/tegra132/include/soc/verstage.h b/src/soc/nvidia/tegra132/include/soc/verstage.h
index df6a386..d54a111 100644
--- a/src/soc/nvidia/tegra132/include/soc/verstage.h
+++ b/src/soc/nvidia/tegra132/include/soc/verstage.h
@@ -20,6 +20,6 @@
#ifndef __SOC_NVIDIA_TEGRA132_SOC_VERSTAGE_H__
#define __SOC_NVIDIA_TEGRA132_SOC_VERSTAGE_H__
-void verstage_mainboard_init(void);
+#include <vendorcode/google/chromeos/chromeos.h>
#endif /* __SOC_NVIDIA_TEGRA132_SOC_VERSTAGE_H__ */
diff --git a/src/soc/nvidia/tegra132/verstage.c b/src/soc/nvidia/tegra132/verstage.c
deleted file mode 100644
index d6eba9a..0000000
--- a/src/soc/nvidia/tegra132/verstage.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2014 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-#include <arch/cache.h>
-#include <arch/exception.h>
-#include <arch/hlt.h>
-#include <arch/stages.h>
-#include <console/console.h>
-#include <soc/verstage.h>
-#include <program_loading.h>
-#include <timestamp.h>
-
-void __attribute__((weak)) verstage_mainboard_init(void)
-{
- /* Default empty implementation. */
-}
-
-static void verstage(void)
-{
- console_init();
- timestamp_add_now(TS_START_VBOOT);
- exception_init();
- verstage_mainboard_init();
-
- run_romstage();
-}
-
-void main(void)
-{
- verstage();
- hlt();
-}
diff --git a/src/soc/nvidia/tegra210/include/soc/verstage.h b/src/soc/nvidia/tegra210/include/soc/verstage.h
index 6c37218..d6564c9 100644
--- a/src/soc/nvidia/tegra210/include/soc/verstage.h
+++ b/src/soc/nvidia/tegra210/include/soc/verstage.h
@@ -20,6 +20,6 @@
#ifndef __SOC_NVIDIA_TEGRA210_SOC_VERSTAGE_H__
#define __SOC_NVIDIA_TEGRA210_SOC_VERSTAGE_H__
-void verstage_mainboard_init(void);
+#include <vendorcode/google/chromeos/chromeos.h>
#endif /* __SOC_NVIDIA_TEGRA210_SOC_VERSTAGE_H__ */
diff --git a/src/soc/nvidia/tegra210/verstage.c b/src/soc/nvidia/tegra210/verstage.c
deleted file mode 100644
index 6a4df29..0000000
--- a/src/soc/nvidia/tegra210/verstage.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2014 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-#include <arch/cache.h>
-#include <arch/exception.h>
-#include <arch/hlt.h>
-#include <soc/verstage.h>
-#include <console/console.h>
-#include <program_loading.h>
-
-void __attribute__((weak)) verstage_mainboard_init(void)
-{
- /* Default empty implementation. */
-}
-
-static void verstage(void)
-{
- console_init();
- exception_init();
- verstage_mainboard_init();
-
- run_romstage();
-}
-
-void main(void)
-{
- verstage();
- hlt();
-}
diff --git a/src/vendorcode/google/chromeos/vboot2/Makefile.inc b/src/vendorcode/google/chromeos/vboot2/Makefile.inc
index 21613ba..c2ee868 100644
--- a/src/vendorcode/google/chromeos/vboot2/Makefile.inc
+++ b/src/vendorcode/google/chromeos/vboot2/Makefile.inc
@@ -31,8 +31,9 @@ romstage-y += ../vboot_common.c
ramstage-y += ../vboot_common.c
bootblock-y += common.c
-libverstage-y += verstage.c
+libverstage-y += vboot_logic.c
verstage-y += common.c
+verstage-y += verstage.c
ifeq (${CONFIG_VBOOT2_MOCK_SECDATA},y)
libverstage-y += secdata_mock.c
else
diff --git a/src/vendorcode/google/chromeos/vboot2/misc.h b/src/vendorcode/google/chromeos/vboot2/misc.h
index d4f9f48..305d0da 100644
--- a/src/vendorcode/google/chromeos/vboot2/misc.h
+++ b/src/vendorcode/google/chromeos/vboot2/misc.h
@@ -23,7 +23,6 @@
#include "../vboot_common.h"
void vboot_fill_handoff(void);
-void verstage_main(void);
void *vboot_load_stage(int stage_index,
struct region *fw_main,
struct vboot_components *fw_info);
diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_logic.c b/src/vendorcode/google/chromeos/vboot2/vboot_logic.c
new file mode 100644
index 0000000..76355ec
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/vboot_logic.c
@@ -0,0 +1,352 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.
+ */
+
+#include <antirollback.h>
+#include <arch/exception.h>
+#include <assert.h>
+#include <console/console.h>
+#include <console/vtxprintf.h>
+#include <delay.h>
+#include <string.h>
+#include <timestamp.h>
+#include <vb2_api.h>
+
+#include "../chromeos.h"
+#include "misc.h"
+
+#define TODO_BLOCK_SIZE 1024
+
+static int is_slot_a(struct vb2_context *ctx)
+{
+ return !(ctx->flags & VB2_CONTEXT_FW_SLOT_B);
+}
+
+/* exports */
+
+void vb2ex_printf(const char *func, const char *fmt, ...)
+{
+ va_list args;
+
+ printk(BIOS_INFO, "VB2:%s() ", func);
+ va_start(args, fmt);
+ do_printk_va_list(BIOS_INFO, fmt, args);
+ va_end(args);
+
+ return;
+}
+
+int vb2ex_tpm_clear_owner(struct vb2_context *ctx)
+{
+ uint32_t rv;
+ printk(BIOS_INFO, "Clearing TPM owner\n");
+ rv = tpm_clear_and_reenable();
+ if (rv)
+ return VB2_ERROR_EX_TPM_CLEAR_OWNER;
+ return VB2_SUCCESS;
+}
+
+int vb2ex_read_resource(struct vb2_context *ctx,
+ enum vb2_resource_index index,
+ uint32_t offset,
+ void *buf,
+ uint32_t size)
+{
+ struct region_device rdev;
+ const char *name;
+
+ switch (index) {
+ case VB2_RES_GBB:
+ name = "GBB";
+ break;
+ case VB2_RES_FW_VBLOCK:
+ if (is_slot_a(ctx))
+ name = "VBLOCK_A";
+ else
+ name = "VBLOCK_B";
+ break;
+ default:
+ return VB2_ERROR_EX_READ_RESOURCE_INDEX;
+ }
+
+ if (vboot_named_region_device(name, &rdev))
+ return VB2_ERROR_EX_READ_RESOURCE_SIZE;
+
+ if (rdev_readat(&rdev, buf, offset, size) != size)
+ return VB2_ERROR_EX_READ_RESOURCE_SIZE;
+
+ return VB2_SUCCESS;
+}
+
+/* No-op stubs that can be overridden by SoCs with hardware crypto support. */
+__attribute__((weak))
+int vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
+ uint32_t data_size)
+{
+ return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
+}
+
+__attribute__((weak))
+int vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size)
+{
+ BUG(); /* Should never get called if init() returned an error. */
+ return VB2_ERROR_UNKNOWN;
+}
+
+__attribute__((weak))
+int vb2ex_hwcrypto_digest_finalize(uint8_t *digest, uint32_t digest_size)
+{
+ BUG(); /* Should never get called if init() returned an error. */
+ return VB2_ERROR_UNKNOWN;
+}
+
+static int hash_body(struct vb2_context *ctx, struct region_device *fw_main)
+{
+ uint64_t load_ts;
+ uint32_t expected_size;
+ uint8_t block[TODO_BLOCK_SIZE];
+ size_t block_size = sizeof(block);
+ size_t offset;
+ int rv;
+
+ /*
+ * Since loading the firmware and calculating its hash is intertwined,
+ * we use this little trick to measure them separately and pretend it
+ * was first loaded and then hashed in one piece with the timestamps.
+ * (This split won't make sense with memory-mapped media like on x86.)
+ */
+ load_ts = timestamp_get();
+ timestamp_add(TS_START_HASH_BODY, load_ts);
+
+ expected_size = region_device_sz(fw_main);
+ offset = 0;
+
+ /* Start the body hash */
+ rv = vb2api_init_hash(ctx, VB2_HASH_TAG_FW_BODY, &expected_size);
+ if (rv)
+ return rv;
+
+ /* Extend over the body */
+ while (expected_size) {
+ uint64_t temp_ts;
+ if (block_size > expected_size)
+ block_size = expected_size;
+
+ temp_ts = timestamp_get();
+ if (rdev_readat(fw_main, block, offset, block_size) < 0)
+ return VB2_ERROR_UNKNOWN;
+ load_ts += timestamp_get() - temp_ts;
+
+ rv = vb2api_extend_hash(ctx, block, block_size);
+ if (rv)
+ return rv;
+
+ expected_size -= block_size;
+ offset += block_size;
+ }
+
+ timestamp_add(TS_DONE_LOADING, load_ts);
+ timestamp_add_now(TS_DONE_HASHING);
+
+ /* Check the result (with RSA signature verification) */
+ rv = vb2api_check_hash(ctx);
+ if (rv)
+ return rv;
+
+ timestamp_add_now(TS_END_HASH_BODY);
+
+ return VB2_SUCCESS;
+}
+
+static int locate_firmware(struct vb2_context *ctx,
+ struct region_device *fw_main)
+{
+ const char *name;
+
+ if (is_slot_a(ctx))
+ name = "FW_MAIN_A";
+ else
+ name = "FW_MAIN_B";
+
+ return vboot_named_region_device(name, fw_main);
+}
+
+/**
+ * Save non-volatile and/or secure data if needed.
+ */
+static void save_if_needed(struct vb2_context *ctx)
+{
+ if (ctx->flags & VB2_CONTEXT_NVDATA_CHANGED) {
+ printk(BIOS_INFO, "Saving nvdata\n");
+ save_vbnv(ctx->nvdata);
+ ctx->flags &= ~VB2_CONTEXT_NVDATA_CHANGED;
+ }
+ if (ctx->flags & VB2_CONTEXT_SECDATA_CHANGED) {
+ printk(BIOS_INFO, "Saving secdata\n");
+ antirollback_write_space_firmware(ctx);
+ ctx->flags &= ~VB2_CONTEXT_SECDATA_CHANGED;
+ }
+}
+
+static uint32_t extend_pcrs(struct vb2_context *ctx)
+{
+ return tpm_extend_pcr(ctx, 0, BOOT_MODE_PCR) ||
+ tpm_extend_pcr(ctx, 1, HWID_DIGEST_PCR);
+}
+
+static void init_vb2_working_data(void)
+{
+ struct vb2_working_data *wd;
+ size_t work_size;
+
+ work_size = vb2_working_data_size();
+ wd = vboot_get_working_data();
+ memset(wd, 0, work_size);
+ /*
+ * vboot prefers 16-byte alignment. This takes away 16 bytes
+ * from the VBOOT2_WORK region, but the vboot devs said that's okay.
+ */
+ wd->buffer_offset = ALIGN_UP(sizeof(*wd), 16);
+ wd->buffer_size = work_size - wd->buffer_offset;
+}
+
+/**
+ * Verify and select the firmware in the RW image
+ *
+ * TODO: Avoid loading a stage twice (once in hash_body & again in load_stage).
+ * when per-stage verification is ready.
+ */
+void verstage_main(void)
+{
+ struct vb2_context ctx;
+ struct region_device fw_main;
+ struct vb2_working_data *wd;
+ int rv;
+ init_vb2_working_data();
+ wd = vboot_get_working_data();
+ timestamp_add_now(TS_START_VBOOT);
+
+ /* Set up context and work buffer */
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.workbuf = vboot_get_work_buffer(wd);
+ ctx.workbuf_size = wd->buffer_size;
+
+ /* Read nvdata from a non-volatile storage */
+ read_vbnv(ctx.nvdata);
+
+ /* Read secdata from TPM. Initialize TPM if secdata not found. We don't
+ * check the return value here because vb2api_fw_phase1 will catch
+ * invalid secdata and tell us what to do (=reboot). */
+ timestamp_add_now(TS_START_TPMINIT);
+ antirollback_read_space_firmware(&ctx);
+ timestamp_add_now(TS_END_TPMINIT);
+
+ if (!IS_ENABLED(CONFIG_VIRTUAL_DEV_SWITCH) &&
+ get_developer_mode_switch())
+ ctx.flags |= VB2_CONTEXT_FORCE_DEVELOPER_MODE;
+
+ if (get_recovery_mode_switch()) {
+ clear_recovery_mode_switch();
+ ctx.flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
+ if (IS_ENABLED(CONFIG_VBOOT_DISABLE_DEV_ON_RECOVERY))
+ ctx.flags |= VB2_DISABLE_DEVELOPER_MODE;
+ }
+
+ if (IS_ENABLED(CONFIG_WIPEOUT_SUPPORTED) && get_wipeout_mode_switch())
+ ctx.flags |= VB2_CONTEXT_FORCE_WIPEOUT_MODE;
+
+ if (IS_ENABLED(CONFIG_LID_SWITCH) && !get_lid_switch())
+ ctx.flags |= VB2_CONTEXT_NOFAIL_BOOT;
+
+ /* Do early init (set up secdata and NVRAM, load GBB) */
+ printk(BIOS_INFO, "Phase 1\n");
+ rv = vb2api_fw_phase1(&ctx);
+
+ if (rv) {
+ /*
+ * If vb2api_fw_phase1 fails, check for return value.
+ * If it is set to VB2_ERROR_API_PHASE1_RECOVERY, then continue
+ * into recovery mode.
+ * For any other error code, save context if needed and reboot.
+ */
+ if (rv == VB2_ERROR_API_PHASE1_RECOVERY) {
+ printk(BIOS_INFO, "Recovery requested (%x)\n", rv);
+ save_if_needed(&ctx);
+ extend_pcrs(&ctx); /* ignore failures */
+ timestamp_add_now(TS_END_VBOOT);
+ return;
+ }
+
+ printk(BIOS_INFO, "Reboot reqested (%x)\n", rv);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ /* Determine which firmware slot to boot (based on NVRAM) */
+ printk(BIOS_INFO, "Phase 2\n");
+ rv = vb2api_fw_phase2(&ctx);
+ if (rv) {
+ printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ /* Try that slot (verify its keyblock and preamble) */
+ printk(BIOS_INFO, "Phase 3\n");
+ timestamp_add_now(TS_START_VERIFY_SLOT);
+ rv = vb2api_fw_phase3(&ctx);
+ timestamp_add_now(TS_END_VERIFY_SLOT);
+ if (rv) {
+ printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ printk(BIOS_INFO, "Phase 4\n");
+ rv = locate_firmware(&ctx, &fw_main);
+ if (rv)
+ die("Failed to read FMAP to locate firmware");
+
+ rv = hash_body(&ctx, &fw_main);
+ save_if_needed(&ctx);
+ if (rv) {
+ printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
+ vboot_reboot();
+ }
+
+ rv = extend_pcrs(&ctx);
+ if (rv) {
+ printk(BIOS_WARNING, "Failed to extend TPM PCRs (%#x)\n", rv);
+ vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_U_ERROR, rv);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ /* Lock TPM */
+ rv = antirollback_lock_space_firmware();
+ if (rv) {
+ printk(BIOS_INFO, "Failed to lock TPM (%x)\n", rv);
+ vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_L_ERROR, 0);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ printk(BIOS_INFO, "Slot %c is selected\n", is_slot_a(&ctx) ? 'A' : 'B');
+ vb2_set_selected_region(wd, &fw_main);
+ timestamp_add_now(TS_END_VBOOT);
+}
diff --git a/src/vendorcode/google/chromeos/vboot2/verstage.c b/src/vendorcode/google/chromeos/vboot2/verstage.c
index 7803d39..0d78668 100644
--- a/src/vendorcode/google/chromeos/vboot2/verstage.c
+++ b/src/vendorcode/google/chromeos/vboot2/verstage.c
@@ -1,7 +1,7 @@
/*
* This file is part of the coreboot project.
*
- * Copyright 2014 Google Inc.
+ * Copyright 2015 Google Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -9,7 +9,7 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
@@ -17,333 +17,29 @@
* Foundation, Inc.
*/
-#include <antirollback.h>
#include <arch/exception.h>
-#include <assert.h>
+#include <arch/hlt.h>
#include <console/console.h>
-#include <console/vtxprintf.h>
-#include <delay.h>
-#include <string.h>
-#include <timestamp.h>
-#include <vb2_api.h>
+#include <program_loading.h>
-#include "../chromeos.h"
-#include "misc.h"
-
-#define TODO_BLOCK_SIZE 1024
-
-static int is_slot_a(struct vb2_context *ctx)
-{
- return !(ctx->flags & VB2_CONTEXT_FW_SLOT_B);
-}
-
-/* exports */
-
-void vb2ex_printf(const char *func, const char *fmt, ...)
+void __attribute__((weak)) verstage_mainboard_init(void)
{
- va_list args;
-
- printk(BIOS_INFO, "VB2:%s() ", func);
- va_start(args, fmt);
- do_printk_va_list(BIOS_INFO, fmt, args);
- va_end(args);
-
- return;
-}
-
-int vb2ex_tpm_clear_owner(struct vb2_context *ctx)
-{
- uint32_t rv;
- printk(BIOS_INFO, "Clearing TPM owner\n");
- rv = tpm_clear_and_reenable();
- if (rv)
- return VB2_ERROR_EX_TPM_CLEAR_OWNER;
- return VB2_SUCCESS;
+ /* Default empty implementation. */
}
-int vb2ex_read_resource(struct vb2_context *ctx,
- enum vb2_resource_index index,
- uint32_t offset,
- void *buf,
- uint32_t size)
+void verstage(void)
{
- struct region_device rdev;
- const char *name;
-
- switch (index) {
- case VB2_RES_GBB:
- name = "GBB";
- break;
- case VB2_RES_FW_VBLOCK:
- if (is_slot_a(ctx))
- name = "VBLOCK_A";
- else
- name = "VBLOCK_B";
- break;
- default:
- return VB2_ERROR_EX_READ_RESOURCE_INDEX;
- }
-
- if (vboot_named_region_device(name, &rdev))
- return VB2_ERROR_EX_READ_RESOURCE_SIZE;
-
- if (rdev_readat(&rdev, buf, offset, size) != size)
- return VB2_ERROR_EX_READ_RESOURCE_SIZE;
-
- return VB2_SUCCESS;
-}
-
-/* No-op stubs that can be overridden by SoCs with hardware crypto support. */
-__attribute__((weak))
-int vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
- uint32_t data_size)
-{
- return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
-}
-
-__attribute__((weak))
-int vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size)
-{
- BUG(); /* Should never get called if init() returned an error. */
- return VB2_ERROR_UNKNOWN;
-}
-
-__attribute__((weak))
-int vb2ex_hwcrypto_digest_finalize(uint8_t *digest, uint32_t digest_size)
-{
- BUG(); /* Should never get called if init() returned an error. */
- return VB2_ERROR_UNKNOWN;
-}
-
-static int hash_body(struct vb2_context *ctx, struct region_device *fw_main)
-{
- uint64_t load_ts;
- uint32_t expected_size;
- uint8_t block[TODO_BLOCK_SIZE];
- size_t block_size = sizeof(block);
- size_t offset;
- int rv;
-
- /*
- * Since loading the firmware and calculating its hash is intertwined,
- * we use this little trick to measure them separately and pretend it
- * was first loaded and then hashed in one piece with the timestamps.
- * (This split won't make sense with memory-mapped media like on x86.)
- */
- load_ts = timestamp_get();
- timestamp_add(TS_START_HASH_BODY, load_ts);
-
- expected_size = region_device_sz(fw_main);
- offset = 0;
-
- /* Start the body hash */
- rv = vb2api_init_hash(ctx, VB2_HASH_TAG_FW_BODY, &expected_size);
- if (rv)
- return rv;
-
- /* Extend over the body */
- while (expected_size) {
- uint64_t temp_ts;
- if (block_size > expected_size)
- block_size = expected_size;
-
- temp_ts = timestamp_get();
- if (rdev_readat(fw_main, block, offset, block_size) < 0)
- return VB2_ERROR_UNKNOWN;
- load_ts += timestamp_get() - temp_ts;
-
- rv = vb2api_extend_hash(ctx, block, block_size);
- if (rv)
- return rv;
-
- expected_size -= block_size;
- offset += block_size;
- }
-
- timestamp_add(TS_DONE_LOADING, load_ts);
- timestamp_add_now(TS_DONE_HASHING);
-
- /* Check the result (with RSA signature verification) */
- rv = vb2api_check_hash(ctx);
- if (rv)
- return rv;
-
- timestamp_add_now(TS_END_HASH_BODY);
-
- return VB2_SUCCESS;
-}
-
-static int locate_firmware(struct vb2_context *ctx,
- struct region_device *fw_main)
-{
- const char *name;
-
- if (is_slot_a(ctx))
- name = "FW_MAIN_A";
- else
- name = "FW_MAIN_B";
-
- return vboot_named_region_device(name, fw_main);
-}
-
-/**
- * Save non-volatile and/or secure data if needed.
- */
-static void save_if_needed(struct vb2_context *ctx)
-{
- if (ctx->flags & VB2_CONTEXT_NVDATA_CHANGED) {
- printk(BIOS_INFO, "Saving nvdata\n");
- save_vbnv(ctx->nvdata);
- ctx->flags &= ~VB2_CONTEXT_NVDATA_CHANGED;
- }
- if (ctx->flags & VB2_CONTEXT_SECDATA_CHANGED) {
- printk(BIOS_INFO, "Saving secdata\n");
- antirollback_write_space_firmware(ctx);
- ctx->flags &= ~VB2_CONTEXT_SECDATA_CHANGED;
- }
-}
-
-static uint32_t extend_pcrs(struct vb2_context *ctx)
-{
- return tpm_extend_pcr(ctx, 0, BOOT_MODE_PCR) ||
- tpm_extend_pcr(ctx, 1, HWID_DIGEST_PCR);
-}
-
-static void init_vb2_working_data(void)
-{
- struct vb2_working_data *wd;
- size_t work_size;
-
- work_size = vb2_working_data_size();
- wd = vboot_get_working_data();
- memset(wd, 0, work_size);
- /*
- * vboot prefers 16-byte alignment. This takes away 16 bytes
- * from the VBOOT2_WORK region, but the vboot devs said that's okay.
- */
- wd->buffer_offset = ALIGN_UP(sizeof(*wd), 16);
- wd->buffer_size = work_size - wd->buffer_offset;
-}
-
-/**
- * Verify and select the firmware in the RW image
- *
- * TODO: Avoid loading a stage twice (once in hash_body & again in load_stage).
- * when per-stage verification is ready.
- */
-void verstage_main(void)
-{
- struct vb2_context ctx;
- struct region_device fw_main;
- struct vb2_working_data *wd;
- int rv;
- init_vb2_working_data();
- wd = vboot_get_working_data();
- timestamp_add_now(TS_START_VBOOT);
-
- /* Set up context and work buffer */
- memset(&ctx, 0, sizeof(ctx));
- ctx.workbuf = vboot_get_work_buffer(wd);
- ctx.workbuf_size = wd->buffer_size;
-
- /* Read nvdata from a non-volatile storage */
- read_vbnv(ctx.nvdata);
-
- /* Read secdata from TPM. Initialize TPM if secdata not found. We don't
- * check the return value here because vb2api_fw_phase1 will catch
- * invalid secdata and tell us what to do (=reboot). */
- timestamp_add_now(TS_START_TPMINIT);
- antirollback_read_space_firmware(&ctx);
- timestamp_add_now(TS_END_TPMINIT);
-
- if (!IS_ENABLED(CONFIG_VIRTUAL_DEV_SWITCH) &&
- get_developer_mode_switch())
- ctx.flags |= VB2_CONTEXT_FORCE_DEVELOPER_MODE;
-
- if (get_recovery_mode_switch()) {
- clear_recovery_mode_switch();
- ctx.flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
- if (IS_ENABLED(CONFIG_VBOOT_DISABLE_DEV_ON_RECOVERY))
- ctx.flags |= VB2_DISABLE_DEVELOPER_MODE;
- }
-
- if (IS_ENABLED(CONFIG_WIPEOUT_SUPPORTED) && get_wipeout_mode_switch())
- ctx.flags |= VB2_CONTEXT_FORCE_WIPEOUT_MODE;
-
- if (IS_ENABLED(CONFIG_LID_SWITCH) && !get_lid_switch())
- ctx.flags |= VB2_CONTEXT_NOFAIL_BOOT;
-
- /* Do early init (set up secdata and NVRAM, load GBB) */
- printk(BIOS_INFO, "Phase 1\n");
- rv = vb2api_fw_phase1(&ctx);
- if (rv) {
- printk(BIOS_INFO, "Recovery requested (%x)\n", rv);
- /* If we need recovery mode, leave firmware selection now */
- save_if_needed(&ctx);
- extend_pcrs(&ctx); /* ignore failures */
- timestamp_add_now(TS_END_VBOOT);
- return;
- }
-
- /* Determine which firmware slot to boot (based on NVRAM) */
- printk(BIOS_INFO, "Phase 2\n");
- rv = vb2api_fw_phase2(&ctx);
- if (rv) {
- printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
- save_if_needed(&ctx);
- vboot_reboot();
- }
-
- /* Try that slot (verify its keyblock and preamble) */
- printk(BIOS_INFO, "Phase 3\n");
- timestamp_add_now(TS_START_VERIFY_SLOT);
- rv = vb2api_fw_phase3(&ctx);
- timestamp_add_now(TS_END_VERIFY_SLOT);
- if (rv) {
- printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
- save_if_needed(&ctx);
- vboot_reboot();
- }
-
- printk(BIOS_INFO, "Phase 4\n");
- rv = locate_firmware(&ctx, &fw_main);
- if (rv)
- die("Failed to read FMAP to locate firmware");
-
- rv = hash_body(&ctx, &fw_main);
- save_if_needed(&ctx);
- if (rv) {
- printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
- vboot_reboot();
- }
-
- rv = extend_pcrs(&ctx);
- if (rv) {
- printk(BIOS_WARNING, "Failed to extend TPM PCRs (%#x)\n", rv);
- vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_U_ERROR, rv);
- save_if_needed(&ctx);
- vboot_reboot();
- }
+ console_init();
+ exception_init();
+ verstage_mainboard_init();
- /* Lock TPM */
- rv = antirollback_lock_space_firmware();
- if (rv) {
- printk(BIOS_INFO, "Failed to lock TPM (%x)\n", rv);
- vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_L_ERROR, 0);
- save_if_needed(&ctx);
- vboot_reboot();
+ if (IS_ENABLED(CONFIG_RETURN_FROM_VERSTAGE)) {
+ verstage_main();
+ } else {
+ run_romstage();
+ hlt();
}
-
- printk(BIOS_INFO, "Slot %c is selected\n", is_slot_a(&ctx) ? 'A' : 'B');
- vb2_set_selected_region(wd, &fw_main);
- timestamp_add_now(TS_END_VBOOT);
}
-#if IS_ENABLED(CONFIG_RETURN_FROM_VERSTAGE)
-void main(void)
-{
- console_init();
- exception_init();
- verstage_main();
-}
-#endif
+/* This is for boards that rely on main() for an entry point of a stage. */
+void main(void) __attribute__((alias ("verstage_chain_load")))
diff --git a/src/vendorcode/google/chromeos/vboot_common.h b/src/vendorcode/google/chromeos/vboot_common.h
index f4d5e11..3a9c89b 100644
--- a/src/vendorcode/google/chromeos/vboot_common.h
+++ b/src/vendorcode/google/chromeos/vboot_common.h
@@ -48,4 +48,10 @@ int vboot_enable_developer(void);
void vboot_reboot(void);
+/* Main logic for verified boot. verstage() is the stage entry point
+ * while the verstage_main() is just the core logic. */
+void verstage_main(void);
+void verstage_mainboard_init(void);
+void verstage(void);
+
#endif /* VBOOT_COMMON_H */
Aaron Durbin (adurbin(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11744
-gerrit
commit 6d975f7d4939d61f7dcd46ad42a70360f4b66275
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Tue Sep 29 17:56:59 2015 -0500
vboot: provide a unified flow for separate verstage
The vboot verification in a stage proper is unified
replacing duplicate code in the tegra SoC code. The
original verstage.c file is renamed to reflect its
real purpose. The support for a single verstage flow
is added to the vboot2 directory proper.
BUG=chrome-os-partner:44827
BRANCH=None
TEST=Built glados.
Change-Id: I14593e1fc69a1654fa27b512eb4b612395b94ce5
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/mainboard/google/foster/Makefile.inc | 1 -
src/mainboard/google/foster/verstage.c | 29 --
src/soc/nvidia/tegra132/include/soc/verstage.h | 2 +-
src/soc/nvidia/tegra132/verstage.c | 48 ---
src/soc/nvidia/tegra210/include/soc/verstage.h | 2 +-
src/soc/nvidia/tegra210/verstage.c | 45 ---
src/vendorcode/google/chromeos/vboot2/Makefile.inc | 3 +-
src/vendorcode/google/chromeos/vboot2/misc.h | 2 +
.../google/chromeos/vboot2/vboot_logic.c | 352 +++++++++++++++++++++
src/vendorcode/google/chromeos/vboot2/verstage.c | 338 +-------------------
10 files changed, 375 insertions(+), 447 deletions(-)
diff --git a/src/mainboard/google/foster/Makefile.inc b/src/mainboard/google/foster/Makefile.inc
index 7b2329e..51208c7 100644
--- a/src/mainboard/google/foster/Makefile.inc
+++ b/src/mainboard/google/foster/Makefile.inc
@@ -32,7 +32,6 @@ bootblock-y += bootblock.c
bootblock-y += pmic.c
bootblock-y += reset.c
-verstage-y += verstage.c
verstage-y += chromeos.c
verstage-y += reset.c
diff --git a/src/mainboard/google/foster/verstage.c b/src/mainboard/google/foster/verstage.c
deleted file mode 100644
index d5bcd44..0000000
--- a/src/mainboard/google/foster/verstage.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2014 Google Inc.
- * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-#include <soc/addressmap.h>
-#include <soc/funitcfg.h>
-#include <soc/padconfig.h>
-#include <soc/verstage.h>
-#include <soc/nvidia/tegra/i2c.h>
-
-void verstage_mainboard_init(void)
-{
-}
diff --git a/src/soc/nvidia/tegra132/include/soc/verstage.h b/src/soc/nvidia/tegra132/include/soc/verstage.h
index df6a386..d54a111 100644
--- a/src/soc/nvidia/tegra132/include/soc/verstage.h
+++ b/src/soc/nvidia/tegra132/include/soc/verstage.h
@@ -20,6 +20,6 @@
#ifndef __SOC_NVIDIA_TEGRA132_SOC_VERSTAGE_H__
#define __SOC_NVIDIA_TEGRA132_SOC_VERSTAGE_H__
-void verstage_mainboard_init(void);
+#include <vendorcode/google/chromeos/chromeos.h>
#endif /* __SOC_NVIDIA_TEGRA132_SOC_VERSTAGE_H__ */
diff --git a/src/soc/nvidia/tegra132/verstage.c b/src/soc/nvidia/tegra132/verstage.c
deleted file mode 100644
index d6eba9a..0000000
--- a/src/soc/nvidia/tegra132/verstage.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2014 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-#include <arch/cache.h>
-#include <arch/exception.h>
-#include <arch/hlt.h>
-#include <arch/stages.h>
-#include <console/console.h>
-#include <soc/verstage.h>
-#include <program_loading.h>
-#include <timestamp.h>
-
-void __attribute__((weak)) verstage_mainboard_init(void)
-{
- /* Default empty implementation. */
-}
-
-static void verstage(void)
-{
- console_init();
- timestamp_add_now(TS_START_VBOOT);
- exception_init();
- verstage_mainboard_init();
-
- run_romstage();
-}
-
-void main(void)
-{
- verstage();
- hlt();
-}
diff --git a/src/soc/nvidia/tegra210/include/soc/verstage.h b/src/soc/nvidia/tegra210/include/soc/verstage.h
index 6c37218..d6564c9 100644
--- a/src/soc/nvidia/tegra210/include/soc/verstage.h
+++ b/src/soc/nvidia/tegra210/include/soc/verstage.h
@@ -20,6 +20,6 @@
#ifndef __SOC_NVIDIA_TEGRA210_SOC_VERSTAGE_H__
#define __SOC_NVIDIA_TEGRA210_SOC_VERSTAGE_H__
-void verstage_mainboard_init(void);
+#include <vendorcode/google/chromeos/chromeos.h>
#endif /* __SOC_NVIDIA_TEGRA210_SOC_VERSTAGE_H__ */
diff --git a/src/soc/nvidia/tegra210/verstage.c b/src/soc/nvidia/tegra210/verstage.c
deleted file mode 100644
index 6a4df29..0000000
--- a/src/soc/nvidia/tegra210/verstage.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2014 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-#include <arch/cache.h>
-#include <arch/exception.h>
-#include <arch/hlt.h>
-#include <soc/verstage.h>
-#include <console/console.h>
-#include <program_loading.h>
-
-void __attribute__((weak)) verstage_mainboard_init(void)
-{
- /* Default empty implementation. */
-}
-
-static void verstage(void)
-{
- console_init();
- exception_init();
- verstage_mainboard_init();
-
- run_romstage();
-}
-
-void main(void)
-{
- verstage();
- hlt();
-}
diff --git a/src/vendorcode/google/chromeos/vboot2/Makefile.inc b/src/vendorcode/google/chromeos/vboot2/Makefile.inc
index 21613ba..c2ee868 100644
--- a/src/vendorcode/google/chromeos/vboot2/Makefile.inc
+++ b/src/vendorcode/google/chromeos/vboot2/Makefile.inc
@@ -31,8 +31,9 @@ romstage-y += ../vboot_common.c
ramstage-y += ../vboot_common.c
bootblock-y += common.c
-libverstage-y += verstage.c
+libverstage-y += vboot_logic.c
verstage-y += common.c
+verstage-y += verstage.c
ifeq (${CONFIG_VBOOT2_MOCK_SECDATA},y)
libverstage-y += secdata_mock.c
else
diff --git a/src/vendorcode/google/chromeos/vboot2/misc.h b/src/vendorcode/google/chromeos/vboot2/misc.h
index d4f9f48..f6f8d7d1a5 100644
--- a/src/vendorcode/google/chromeos/vboot2/misc.h
+++ b/src/vendorcode/google/chromeos/vboot2/misc.h
@@ -24,6 +24,8 @@
void vboot_fill_handoff(void);
void verstage_main(void);
+void verstage_mainboard_init(void);
+void verstage(void);
void *vboot_load_stage(int stage_index,
struct region *fw_main,
struct vboot_components *fw_info);
diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_logic.c b/src/vendorcode/google/chromeos/vboot2/vboot_logic.c
new file mode 100644
index 0000000..76355ec
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vboot2/vboot_logic.c
@@ -0,0 +1,352 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.
+ */
+
+#include <antirollback.h>
+#include <arch/exception.h>
+#include <assert.h>
+#include <console/console.h>
+#include <console/vtxprintf.h>
+#include <delay.h>
+#include <string.h>
+#include <timestamp.h>
+#include <vb2_api.h>
+
+#include "../chromeos.h"
+#include "misc.h"
+
+#define TODO_BLOCK_SIZE 1024
+
+static int is_slot_a(struct vb2_context *ctx)
+{
+ return !(ctx->flags & VB2_CONTEXT_FW_SLOT_B);
+}
+
+/* exports */
+
+void vb2ex_printf(const char *func, const char *fmt, ...)
+{
+ va_list args;
+
+ printk(BIOS_INFO, "VB2:%s() ", func);
+ va_start(args, fmt);
+ do_printk_va_list(BIOS_INFO, fmt, args);
+ va_end(args);
+
+ return;
+}
+
+int vb2ex_tpm_clear_owner(struct vb2_context *ctx)
+{
+ uint32_t rv;
+ printk(BIOS_INFO, "Clearing TPM owner\n");
+ rv = tpm_clear_and_reenable();
+ if (rv)
+ return VB2_ERROR_EX_TPM_CLEAR_OWNER;
+ return VB2_SUCCESS;
+}
+
+int vb2ex_read_resource(struct vb2_context *ctx,
+ enum vb2_resource_index index,
+ uint32_t offset,
+ void *buf,
+ uint32_t size)
+{
+ struct region_device rdev;
+ const char *name;
+
+ switch (index) {
+ case VB2_RES_GBB:
+ name = "GBB";
+ break;
+ case VB2_RES_FW_VBLOCK:
+ if (is_slot_a(ctx))
+ name = "VBLOCK_A";
+ else
+ name = "VBLOCK_B";
+ break;
+ default:
+ return VB2_ERROR_EX_READ_RESOURCE_INDEX;
+ }
+
+ if (vboot_named_region_device(name, &rdev))
+ return VB2_ERROR_EX_READ_RESOURCE_SIZE;
+
+ if (rdev_readat(&rdev, buf, offset, size) != size)
+ return VB2_ERROR_EX_READ_RESOURCE_SIZE;
+
+ return VB2_SUCCESS;
+}
+
+/* No-op stubs that can be overridden by SoCs with hardware crypto support. */
+__attribute__((weak))
+int vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
+ uint32_t data_size)
+{
+ return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
+}
+
+__attribute__((weak))
+int vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size)
+{
+ BUG(); /* Should never get called if init() returned an error. */
+ return VB2_ERROR_UNKNOWN;
+}
+
+__attribute__((weak))
+int vb2ex_hwcrypto_digest_finalize(uint8_t *digest, uint32_t digest_size)
+{
+ BUG(); /* Should never get called if init() returned an error. */
+ return VB2_ERROR_UNKNOWN;
+}
+
+static int hash_body(struct vb2_context *ctx, struct region_device *fw_main)
+{
+ uint64_t load_ts;
+ uint32_t expected_size;
+ uint8_t block[TODO_BLOCK_SIZE];
+ size_t block_size = sizeof(block);
+ size_t offset;
+ int rv;
+
+ /*
+ * Since loading the firmware and calculating its hash is intertwined,
+ * we use this little trick to measure them separately and pretend it
+ * was first loaded and then hashed in one piece with the timestamps.
+ * (This split won't make sense with memory-mapped media like on x86.)
+ */
+ load_ts = timestamp_get();
+ timestamp_add(TS_START_HASH_BODY, load_ts);
+
+ expected_size = region_device_sz(fw_main);
+ offset = 0;
+
+ /* Start the body hash */
+ rv = vb2api_init_hash(ctx, VB2_HASH_TAG_FW_BODY, &expected_size);
+ if (rv)
+ return rv;
+
+ /* Extend over the body */
+ while (expected_size) {
+ uint64_t temp_ts;
+ if (block_size > expected_size)
+ block_size = expected_size;
+
+ temp_ts = timestamp_get();
+ if (rdev_readat(fw_main, block, offset, block_size) < 0)
+ return VB2_ERROR_UNKNOWN;
+ load_ts += timestamp_get() - temp_ts;
+
+ rv = vb2api_extend_hash(ctx, block, block_size);
+ if (rv)
+ return rv;
+
+ expected_size -= block_size;
+ offset += block_size;
+ }
+
+ timestamp_add(TS_DONE_LOADING, load_ts);
+ timestamp_add_now(TS_DONE_HASHING);
+
+ /* Check the result (with RSA signature verification) */
+ rv = vb2api_check_hash(ctx);
+ if (rv)
+ return rv;
+
+ timestamp_add_now(TS_END_HASH_BODY);
+
+ return VB2_SUCCESS;
+}
+
+static int locate_firmware(struct vb2_context *ctx,
+ struct region_device *fw_main)
+{
+ const char *name;
+
+ if (is_slot_a(ctx))
+ name = "FW_MAIN_A";
+ else
+ name = "FW_MAIN_B";
+
+ return vboot_named_region_device(name, fw_main);
+}
+
+/**
+ * Save non-volatile and/or secure data if needed.
+ */
+static void save_if_needed(struct vb2_context *ctx)
+{
+ if (ctx->flags & VB2_CONTEXT_NVDATA_CHANGED) {
+ printk(BIOS_INFO, "Saving nvdata\n");
+ save_vbnv(ctx->nvdata);
+ ctx->flags &= ~VB2_CONTEXT_NVDATA_CHANGED;
+ }
+ if (ctx->flags & VB2_CONTEXT_SECDATA_CHANGED) {
+ printk(BIOS_INFO, "Saving secdata\n");
+ antirollback_write_space_firmware(ctx);
+ ctx->flags &= ~VB2_CONTEXT_SECDATA_CHANGED;
+ }
+}
+
+static uint32_t extend_pcrs(struct vb2_context *ctx)
+{
+ return tpm_extend_pcr(ctx, 0, BOOT_MODE_PCR) ||
+ tpm_extend_pcr(ctx, 1, HWID_DIGEST_PCR);
+}
+
+static void init_vb2_working_data(void)
+{
+ struct vb2_working_data *wd;
+ size_t work_size;
+
+ work_size = vb2_working_data_size();
+ wd = vboot_get_working_data();
+ memset(wd, 0, work_size);
+ /*
+ * vboot prefers 16-byte alignment. This takes away 16 bytes
+ * from the VBOOT2_WORK region, but the vboot devs said that's okay.
+ */
+ wd->buffer_offset = ALIGN_UP(sizeof(*wd), 16);
+ wd->buffer_size = work_size - wd->buffer_offset;
+}
+
+/**
+ * Verify and select the firmware in the RW image
+ *
+ * TODO: Avoid loading a stage twice (once in hash_body & again in load_stage).
+ * when per-stage verification is ready.
+ */
+void verstage_main(void)
+{
+ struct vb2_context ctx;
+ struct region_device fw_main;
+ struct vb2_working_data *wd;
+ int rv;
+ init_vb2_working_data();
+ wd = vboot_get_working_data();
+ timestamp_add_now(TS_START_VBOOT);
+
+ /* Set up context and work buffer */
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.workbuf = vboot_get_work_buffer(wd);
+ ctx.workbuf_size = wd->buffer_size;
+
+ /* Read nvdata from a non-volatile storage */
+ read_vbnv(ctx.nvdata);
+
+ /* Read secdata from TPM. Initialize TPM if secdata not found. We don't
+ * check the return value here because vb2api_fw_phase1 will catch
+ * invalid secdata and tell us what to do (=reboot). */
+ timestamp_add_now(TS_START_TPMINIT);
+ antirollback_read_space_firmware(&ctx);
+ timestamp_add_now(TS_END_TPMINIT);
+
+ if (!IS_ENABLED(CONFIG_VIRTUAL_DEV_SWITCH) &&
+ get_developer_mode_switch())
+ ctx.flags |= VB2_CONTEXT_FORCE_DEVELOPER_MODE;
+
+ if (get_recovery_mode_switch()) {
+ clear_recovery_mode_switch();
+ ctx.flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
+ if (IS_ENABLED(CONFIG_VBOOT_DISABLE_DEV_ON_RECOVERY))
+ ctx.flags |= VB2_DISABLE_DEVELOPER_MODE;
+ }
+
+ if (IS_ENABLED(CONFIG_WIPEOUT_SUPPORTED) && get_wipeout_mode_switch())
+ ctx.flags |= VB2_CONTEXT_FORCE_WIPEOUT_MODE;
+
+ if (IS_ENABLED(CONFIG_LID_SWITCH) && !get_lid_switch())
+ ctx.flags |= VB2_CONTEXT_NOFAIL_BOOT;
+
+ /* Do early init (set up secdata and NVRAM, load GBB) */
+ printk(BIOS_INFO, "Phase 1\n");
+ rv = vb2api_fw_phase1(&ctx);
+
+ if (rv) {
+ /*
+ * If vb2api_fw_phase1 fails, check for return value.
+ * If it is set to VB2_ERROR_API_PHASE1_RECOVERY, then continue
+ * into recovery mode.
+ * For any other error code, save context if needed and reboot.
+ */
+ if (rv == VB2_ERROR_API_PHASE1_RECOVERY) {
+ printk(BIOS_INFO, "Recovery requested (%x)\n", rv);
+ save_if_needed(&ctx);
+ extend_pcrs(&ctx); /* ignore failures */
+ timestamp_add_now(TS_END_VBOOT);
+ return;
+ }
+
+ printk(BIOS_INFO, "Reboot reqested (%x)\n", rv);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ /* Determine which firmware slot to boot (based on NVRAM) */
+ printk(BIOS_INFO, "Phase 2\n");
+ rv = vb2api_fw_phase2(&ctx);
+ if (rv) {
+ printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ /* Try that slot (verify its keyblock and preamble) */
+ printk(BIOS_INFO, "Phase 3\n");
+ timestamp_add_now(TS_START_VERIFY_SLOT);
+ rv = vb2api_fw_phase3(&ctx);
+ timestamp_add_now(TS_END_VERIFY_SLOT);
+ if (rv) {
+ printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ printk(BIOS_INFO, "Phase 4\n");
+ rv = locate_firmware(&ctx, &fw_main);
+ if (rv)
+ die("Failed to read FMAP to locate firmware");
+
+ rv = hash_body(&ctx, &fw_main);
+ save_if_needed(&ctx);
+ if (rv) {
+ printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
+ vboot_reboot();
+ }
+
+ rv = extend_pcrs(&ctx);
+ if (rv) {
+ printk(BIOS_WARNING, "Failed to extend TPM PCRs (%#x)\n", rv);
+ vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_U_ERROR, rv);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ /* Lock TPM */
+ rv = antirollback_lock_space_firmware();
+ if (rv) {
+ printk(BIOS_INFO, "Failed to lock TPM (%x)\n", rv);
+ vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_L_ERROR, 0);
+ save_if_needed(&ctx);
+ vboot_reboot();
+ }
+
+ printk(BIOS_INFO, "Slot %c is selected\n", is_slot_a(&ctx) ? 'A' : 'B');
+ vb2_set_selected_region(wd, &fw_main);
+ timestamp_add_now(TS_END_VBOOT);
+}
diff --git a/src/vendorcode/google/chromeos/vboot2/verstage.c b/src/vendorcode/google/chromeos/vboot2/verstage.c
index 7803d39..a421c95 100644
--- a/src/vendorcode/google/chromeos/vboot2/verstage.c
+++ b/src/vendorcode/google/chromeos/vboot2/verstage.c
@@ -1,7 +1,7 @@
/*
* This file is part of the coreboot project.
*
- * Copyright 2014 Google Inc.
+ * Copyright 2015 Google Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -9,7 +9,7 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
@@ -17,333 +17,29 @@
* Foundation, Inc.
*/
-#include <antirollback.h>
#include <arch/exception.h>
-#include <assert.h>
+#include <arch/hlt.h>
#include <console/console.h>
-#include <console/vtxprintf.h>
-#include <delay.h>
-#include <string.h>
-#include <timestamp.h>
-#include <vb2_api.h>
+#include <program_loading.h>
-#include "../chromeos.h"
-#include "misc.h"
-
-#define TODO_BLOCK_SIZE 1024
-
-static int is_slot_a(struct vb2_context *ctx)
-{
- return !(ctx->flags & VB2_CONTEXT_FW_SLOT_B);
-}
-
-/* exports */
-
-void vb2ex_printf(const char *func, const char *fmt, ...)
+void __attribute__((weak)) verstage_mainboard_init(void)
{
- va_list args;
-
- printk(BIOS_INFO, "VB2:%s() ", func);
- va_start(args, fmt);
- do_printk_va_list(BIOS_INFO, fmt, args);
- va_end(args);
-
- return;
-}
-
-int vb2ex_tpm_clear_owner(struct vb2_context *ctx)
-{
- uint32_t rv;
- printk(BIOS_INFO, "Clearing TPM owner\n");
- rv = tpm_clear_and_reenable();
- if (rv)
- return VB2_ERROR_EX_TPM_CLEAR_OWNER;
- return VB2_SUCCESS;
+ /* Default empty implementation. */
}
-int vb2ex_read_resource(struct vb2_context *ctx,
- enum vb2_resource_index index,
- uint32_t offset,
- void *buf,
- uint32_t size)
+void verstage_chain_load(void)
{
- struct region_device rdev;
- const char *name;
-
- switch (index) {
- case VB2_RES_GBB:
- name = "GBB";
- break;
- case VB2_RES_FW_VBLOCK:
- if (is_slot_a(ctx))
- name = "VBLOCK_A";
- else
- name = "VBLOCK_B";
- break;
- default:
- return VB2_ERROR_EX_READ_RESOURCE_INDEX;
- }
-
- if (vboot_named_region_device(name, &rdev))
- return VB2_ERROR_EX_READ_RESOURCE_SIZE;
-
- if (rdev_readat(&rdev, buf, offset, size) != size)
- return VB2_ERROR_EX_READ_RESOURCE_SIZE;
-
- return VB2_SUCCESS;
-}
-
-/* No-op stubs that can be overridden by SoCs with hardware crypto support. */
-__attribute__((weak))
-int vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
- uint32_t data_size)
-{
- return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
-}
-
-__attribute__((weak))
-int vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size)
-{
- BUG(); /* Should never get called if init() returned an error. */
- return VB2_ERROR_UNKNOWN;
-}
-
-__attribute__((weak))
-int vb2ex_hwcrypto_digest_finalize(uint8_t *digest, uint32_t digest_size)
-{
- BUG(); /* Should never get called if init() returned an error. */
- return VB2_ERROR_UNKNOWN;
-}
-
-static int hash_body(struct vb2_context *ctx, struct region_device *fw_main)
-{
- uint64_t load_ts;
- uint32_t expected_size;
- uint8_t block[TODO_BLOCK_SIZE];
- size_t block_size = sizeof(block);
- size_t offset;
- int rv;
-
- /*
- * Since loading the firmware and calculating its hash is intertwined,
- * we use this little trick to measure them separately and pretend it
- * was first loaded and then hashed in one piece with the timestamps.
- * (This split won't make sense with memory-mapped media like on x86.)
- */
- load_ts = timestamp_get();
- timestamp_add(TS_START_HASH_BODY, load_ts);
-
- expected_size = region_device_sz(fw_main);
- offset = 0;
-
- /* Start the body hash */
- rv = vb2api_init_hash(ctx, VB2_HASH_TAG_FW_BODY, &expected_size);
- if (rv)
- return rv;
-
- /* Extend over the body */
- while (expected_size) {
- uint64_t temp_ts;
- if (block_size > expected_size)
- block_size = expected_size;
-
- temp_ts = timestamp_get();
- if (rdev_readat(fw_main, block, offset, block_size) < 0)
- return VB2_ERROR_UNKNOWN;
- load_ts += timestamp_get() - temp_ts;
-
- rv = vb2api_extend_hash(ctx, block, block_size);
- if (rv)
- return rv;
-
- expected_size -= block_size;
- offset += block_size;
- }
-
- timestamp_add(TS_DONE_LOADING, load_ts);
- timestamp_add_now(TS_DONE_HASHING);
-
- /* Check the result (with RSA signature verification) */
- rv = vb2api_check_hash(ctx);
- if (rv)
- return rv;
-
- timestamp_add_now(TS_END_HASH_BODY);
-
- return VB2_SUCCESS;
-}
-
-static int locate_firmware(struct vb2_context *ctx,
- struct region_device *fw_main)
-{
- const char *name;
-
- if (is_slot_a(ctx))
- name = "FW_MAIN_A";
- else
- name = "FW_MAIN_B";
-
- return vboot_named_region_device(name, fw_main);
-}
-
-/**
- * Save non-volatile and/or secure data if needed.
- */
-static void save_if_needed(struct vb2_context *ctx)
-{
- if (ctx->flags & VB2_CONTEXT_NVDATA_CHANGED) {
- printk(BIOS_INFO, "Saving nvdata\n");
- save_vbnv(ctx->nvdata);
- ctx->flags &= ~VB2_CONTEXT_NVDATA_CHANGED;
- }
- if (ctx->flags & VB2_CONTEXT_SECDATA_CHANGED) {
- printk(BIOS_INFO, "Saving secdata\n");
- antirollback_write_space_firmware(ctx);
- ctx->flags &= ~VB2_CONTEXT_SECDATA_CHANGED;
- }
-}
-
-static uint32_t extend_pcrs(struct vb2_context *ctx)
-{
- return tpm_extend_pcr(ctx, 0, BOOT_MODE_PCR) ||
- tpm_extend_pcr(ctx, 1, HWID_DIGEST_PCR);
-}
-
-static void init_vb2_working_data(void)
-{
- struct vb2_working_data *wd;
- size_t work_size;
-
- work_size = vb2_working_data_size();
- wd = vboot_get_working_data();
- memset(wd, 0, work_size);
- /*
- * vboot prefers 16-byte alignment. This takes away 16 bytes
- * from the VBOOT2_WORK region, but the vboot devs said that's okay.
- */
- wd->buffer_offset = ALIGN_UP(sizeof(*wd), 16);
- wd->buffer_size = work_size - wd->buffer_offset;
-}
-
-/**
- * Verify and select the firmware in the RW image
- *
- * TODO: Avoid loading a stage twice (once in hash_body & again in load_stage).
- * when per-stage verification is ready.
- */
-void verstage_main(void)
-{
- struct vb2_context ctx;
- struct region_device fw_main;
- struct vb2_working_data *wd;
- int rv;
- init_vb2_working_data();
- wd = vboot_get_working_data();
- timestamp_add_now(TS_START_VBOOT);
-
- /* Set up context and work buffer */
- memset(&ctx, 0, sizeof(ctx));
- ctx.workbuf = vboot_get_work_buffer(wd);
- ctx.workbuf_size = wd->buffer_size;
-
- /* Read nvdata from a non-volatile storage */
- read_vbnv(ctx.nvdata);
-
- /* Read secdata from TPM. Initialize TPM if secdata not found. We don't
- * check the return value here because vb2api_fw_phase1 will catch
- * invalid secdata and tell us what to do (=reboot). */
- timestamp_add_now(TS_START_TPMINIT);
- antirollback_read_space_firmware(&ctx);
- timestamp_add_now(TS_END_TPMINIT);
-
- if (!IS_ENABLED(CONFIG_VIRTUAL_DEV_SWITCH) &&
- get_developer_mode_switch())
- ctx.flags |= VB2_CONTEXT_FORCE_DEVELOPER_MODE;
-
- if (get_recovery_mode_switch()) {
- clear_recovery_mode_switch();
- ctx.flags |= VB2_CONTEXT_FORCE_RECOVERY_MODE;
- if (IS_ENABLED(CONFIG_VBOOT_DISABLE_DEV_ON_RECOVERY))
- ctx.flags |= VB2_DISABLE_DEVELOPER_MODE;
- }
-
- if (IS_ENABLED(CONFIG_WIPEOUT_SUPPORTED) && get_wipeout_mode_switch())
- ctx.flags |= VB2_CONTEXT_FORCE_WIPEOUT_MODE;
-
- if (IS_ENABLED(CONFIG_LID_SWITCH) && !get_lid_switch())
- ctx.flags |= VB2_CONTEXT_NOFAIL_BOOT;
-
- /* Do early init (set up secdata and NVRAM, load GBB) */
- printk(BIOS_INFO, "Phase 1\n");
- rv = vb2api_fw_phase1(&ctx);
- if (rv) {
- printk(BIOS_INFO, "Recovery requested (%x)\n", rv);
- /* If we need recovery mode, leave firmware selection now */
- save_if_needed(&ctx);
- extend_pcrs(&ctx); /* ignore failures */
- timestamp_add_now(TS_END_VBOOT);
- return;
- }
-
- /* Determine which firmware slot to boot (based on NVRAM) */
- printk(BIOS_INFO, "Phase 2\n");
- rv = vb2api_fw_phase2(&ctx);
- if (rv) {
- printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
- save_if_needed(&ctx);
- vboot_reboot();
- }
-
- /* Try that slot (verify its keyblock and preamble) */
- printk(BIOS_INFO, "Phase 3\n");
- timestamp_add_now(TS_START_VERIFY_SLOT);
- rv = vb2api_fw_phase3(&ctx);
- timestamp_add_now(TS_END_VERIFY_SLOT);
- if (rv) {
- printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
- save_if_needed(&ctx);
- vboot_reboot();
- }
-
- printk(BIOS_INFO, "Phase 4\n");
- rv = locate_firmware(&ctx, &fw_main);
- if (rv)
- die("Failed to read FMAP to locate firmware");
-
- rv = hash_body(&ctx, &fw_main);
- save_if_needed(&ctx);
- if (rv) {
- printk(BIOS_INFO, "Reboot requested (%x)\n", rv);
- vboot_reboot();
- }
-
- rv = extend_pcrs(&ctx);
- if (rv) {
- printk(BIOS_WARNING, "Failed to extend TPM PCRs (%#x)\n", rv);
- vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_U_ERROR, rv);
- save_if_needed(&ctx);
- vboot_reboot();
- }
+ console_init();
+ exception_init();
+ verstage_mainboard_init();
- /* Lock TPM */
- rv = antirollback_lock_space_firmware();
- if (rv) {
- printk(BIOS_INFO, "Failed to lock TPM (%x)\n", rv);
- vb2api_fail(&ctx, VB2_RECOVERY_RO_TPM_L_ERROR, 0);
- save_if_needed(&ctx);
- vboot_reboot();
+ if (IS_ENABLED(CONFIG_RETURN_FROM_VERSTAGE)) {
+ verstage_main();
+ } else {
+ run_romstage();
+ hlt();
}
-
- printk(BIOS_INFO, "Slot %c is selected\n", is_slot_a(&ctx) ? 'A' : 'B');
- vb2_set_selected_region(wd, &fw_main);
- timestamp_add_now(TS_END_VBOOT);
}
-#if IS_ENABLED(CONFIG_RETURN_FROM_VERSTAGE)
-void main(void)
-{
- console_init();
- exception_init();
- verstage_main();
-}
-#endif
+/* This is for boards that rely on main() for an entry point of a stage. */
+void main(void) __attribute__((alias ("verstage_chain_load")))
Aaron Durbin (adurbin(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11739
-gerrit
commit 19f8af68692e7915f7b595a2bcae95273a881f01
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Tue Sep 29 14:54:25 2015 -0500
x86: provide common macro for linking early stages
In order to support verstage on x86 one needs to link verstage
like romstage since it needs all the cache-as-ram goodies. Therefore,
provide a macro that one can invoke that provides the necessary
recipes for linking that particular stage in such an environment.
BUG=chrome-os-partner:44827
BRANCH=None
TEST=Built and booted glados.
Change-Id: I12f4872df09fff6715829de68fc374e230350c2e
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/arch/x86/Makefile.inc | 49 ++++++++++++++++++++++++-------------------
src/arch/x86/assembly_entry.S | 37 ++++++++++++++++++++++++++++++++
src/arch/x86/romstage.S | 37 --------------------------------
3 files changed, 65 insertions(+), 58 deletions(-)
diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc
index 1779099..f16edcd 100644
--- a/src/arch/x86/Makefile.inc
+++ b/src/arch/x86/Makefile.inc
@@ -115,27 +115,44 @@ endif
endif # CONFIG_ARCH_BOOTBLOCK_X86_32 / CONFIG_ARCH_BOOTBLOCK_X86_64
###############################################################################
-# romstage
+# common support for early assembly includes
###############################################################################
-ifeq ($(CONFIG_ARCH_ROMSTAGE_X86_32)$(CONFIG_ARCH_ROMSTAGE_X86_64),y)
-
-romstage-y += memlayout.ld
-
# Chipset specific assembly stubs in the romstage program flow. Certain
# boards have more than one assembly stub so collect those and put them
# into a single generated file.
crt0s = $(cpu_incs-y)
-$(objgenerated)/romstage.inc: $$(crt0s)
+$(objgenerated)/assembly.inc: $$(crt0s)
@printf " GEN $(subst $(obj)/,,$(@))\n"
printf '$(foreach crt0,$(crt0s),#include "$(crt0)"\n)' > $@
+define early_x86_stage
+# $1 stage name
+# $2 oformat
+$(1)-y += memlayout.ld
# Add the assembly file that pulls in the rest of the dependencies in
-# the right order. Make sure the auto generated romstage.inc is a proper
+# the right order. Make sure the auto generated assembly.inc is a proper
# dependency.
-romstage-y += romstage.S
-$(obj)/arch/x86/romstage.romstage.o: $(objgenerated)/romstage.inc
+$(1)-y += assembly_entry.S
+$$(obj)/arch/x86/assembly_entry.$(1).o: $(objgenerated)/assembly.inc
+
+$$(objcbfs)/$(1).debug: $$$$($(1)-libs) $$$$($(1)-objs)
+ @printf " LINK $$(subst $$(obj)/,,$$(@))\n"
+ $$(LD_$(1)) $$(LDFLAGS_$(1)) -o $$@ -L$$(obj) $$(COMPILER_RT_FLAGS_$(1)) --whole-archive --start-group $$(filter-out %.ld,$$($(1)-objs)) $$($(1)-libs) --no-whole-archive $$(COMPILER_RT_$(1)) --end-group -T $$(obj)/arch/x86/memlayout.$(1).ld --oformat $(2)
+ LANG=C LC_ALL= $$(OBJCOPY_$(1)) --only-section .illegal_globals $$(@) $$(objcbfs)/$(1)_null.offenders 2>&1 | \
+ grep -v "Empty loadable segment detected" && \
+ $$(NM_$(1)) $$(objcbfs)/$(1)_null.offenders | grep -q ""; if [ $$$$? -eq 0 ]; then \
+ echo "Forbidden global variables in "$(1)":"; \
+ $$(NM_$(1)) $$(objcbfs)/$(1)_null.offenders; false; \
+ else true; fi
+endef
+
+###############################################################################
+# romstage
+###############################################################################
+
+ifeq ($(CONFIG_ARCH_ROMSTAGE_X86_32)$(CONFIG_ARCH_ROMSTAGE_X86_64),y)
ifneq ($(CONFIG_ROMCC),y)
@@ -180,21 +197,11 @@ endif
romstage-libs ?=
ifeq ($(CONFIG_ARCH_ROMSTAGE_X86_32),y)
-romstage-oformat=elf32-i386
+$(eval $(call early_x86_stage,romstage,elf32-i386))
else
-romstage-oformat=elf64-x86-64
+$(eval $(call early_x86_stage,romstage,elf64-x86-64))
endif
-$(objcbfs)/romstage.debug: $$(romstage-objs) $$(romstage-libs)
- @printf " LINK $(subst $(obj)/,,$(@))\n"
- $(LD_romstage) $(LDFLAGS_romstage) -o $@ -L$(obj) $(COMPILER_RT_FLAGS_romstage) --whole-archive --start-group $(filter-out %.ld,$(romstage-objs)) $(romstage-libs) --no-whole-archive $(COMPILER_RT_romstage) --end-group -T $(obj)/arch/x86/memlayout.romstage.ld --oformat $(romstage-oformat)
- LANG=C LC_ALL= $(OBJCOPY_romstage) --only-section .illegal_globals $(@) $(objcbfs)/romstage_null.offenders 2>&1 | \
- grep -v "Empty loadable segment detected" && \
- if [ -n "`$(NM_romstage) $(objcbfs)/romstage_null.offenders 2>/dev/null`" ]; then \
- echo "Forbidden global variables in romstage:"; \
- $(NM_romstage) $(objcbfs)/romstage_null.offenders; false; \
- else true; fi
-
# Compiling crt0 with -g seems to trigger https://sourceware.org/bugzilla/show_bug.cgi?id=6428
romstage-S-ccopts += -I. -g0
diff --git a/src/arch/x86/assembly_entry.S b/src/arch/x86/assembly_entry.S
new file mode 100644
index 0000000..c23d177
--- /dev/null
+++ b/src/arch/x86/assembly_entry.S
@@ -0,0 +1,37 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.
+ */
+
+/* This file assembles the start of the romstage program by the order of the
+ * includes. Thus, it's extremely important that one pays very careful
+ * attention to the order of the includes. */
+
+#include <arch/x86/prologue.inc>
+#include <cpu/x86/32bit/entry32.inc>
+#include <cpu/x86/fpu_enable.inc>
+#if IS_ENABLED(CONFIG_SSE)
+#include <cpu/x86/sse_enable.inc>
+#endif
+
+/*
+ * The assembly.inc is generated based on the requirements of the mainboard.
+ * For example, for ROMCC boards the MAINBOARDDIR/romstage.c would be
+ * processed by ROMCC and added. In non-ROMCC boards the chipsets'
+ * cache-as-ram setup files would be here.
+ */
+#include <generated/assembly.inc>
diff --git a/src/arch/x86/romstage.S b/src/arch/x86/romstage.S
deleted file mode 100644
index b19b954..0000000
--- a/src/arch/x86/romstage.S
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2015 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-/* This file assembles the start of the romstage program by the order of the
- * includes. Thus, it's extremely important that one pays very careful
- * attention to the order of the includes. */
-
-#include <arch/x86/prologue.inc>
-#include <cpu/x86/32bit/entry32.inc>
-#include <cpu/x86/fpu_enable.inc>
-#if IS_ENABLED(CONFIG_SSE)
-#include <cpu/x86/sse_enable.inc>
-#endif
-
-/*
- * The romstage.inc is generated based on the requirements of the mainboard.
- * For example, for ROMCC boards the MAINBOARDDIR/romstage.c would be
- * processed by ROMCC and added. In non-ROMCC boards the chipsets'
- * cache-as-ram setup files would be here.
- */
-#include <generated/romstage.inc>
Aaron Durbin (adurbin(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11740
-gerrit
commit 5d05f04a589e4a32067edb251cd20f1535607798
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Thu Sep 24 12:18:07 2015 -0500
x86: prepare cache-as-ram to allow multiple stages
In order to do a verification of romstage on x86 one needs to
run verstage which verifies romstage (and the memory init code).
However, x86 doesn't have SRAM like every other modern SoC so
managing the cache-as-ram region is especially critical.
First move all of the "shared" objects to the beginning of
the .car.data section. This change then ensures that each stage
using car.ld to link has the same consistent view of the addresses
of these fixed-sized objects in cache-as-ram. The CAR_GLOBALs can
be unique per stage. However, these variables are expected to have
a value of zero at the start of each stage. In order to allow a
stage to provide those semantics outside of the initial cache-as-arm
setup routine add _car_global_start and _car_global_end symbols.
Those symbols can be used to clear the CAR_GLOBALs for that stage.
Note that the timestamp region can't be moved out similarly to the
pre-ram cbmem console because the object storage of the timestamp
cache is used *after* cache-as-ram is torn down to indicate if the
cache should be used or not. Therefore, that timestamp needs to
migrated to ram. A logic change in src/lib/timestamp.c could
alleviate this requirement, but that task wasn't tackled in this
patch.
BUG=chrome-os-partner:44827
BRANCH=None
TEST=Built and booted glados.
Change-Id: I15e9f6b0c632ee5a2369da0709535d6cb0d94f61
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/arch/x86/car.ld | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/src/arch/x86/car.ld b/src/arch/x86/car.ld
index c30c802..5da9dcf 100644
--- a/src/arch/x86/car.ld
+++ b/src/arch/x86/car.ld
@@ -22,15 +22,29 @@
/* This file is included inside a SECTIONS block */
. = CONFIG_DCACHE_RAM_BASE;
.car.data . (NOLOAD) : {
+ /* The pre-ram cbmem console as well as the timestamp region are fixed
+ * in size. Therefore place them at the beginning .car.data section
+ * so that multiple stages (romstage and verstage) have a consistent
+ * link address of these shared objects. */
+ PRERAM_CBMEM_CONSOLE(., (CONFIG_LATE_CBMEM_INIT ? 0 : 0xc00))
_car_data_start = .;
+ /* The timestamp implementation relies on this storage to be around
+ * after migration. One of the fields indicates not to use it as the
+ * backing store once cbmem comes online. Therefore, this data needs
+ * to reside in the migrated area (between _car_data_start and
+ * _car_data_end). */
#if IS_ENABLED(CONFIG_HAS_PRECBMEM_TIMESTAMP_REGION)
TIMESTAMP(., 0x100)
#endif
+ /* _car_global_start and _car_global_end provide symbols to per-stage
+ * variables that are not shared like the timestamp and the pre-ram
+ * cbmem console. This is useful for clearing this area on a per-stage
+ * basis when more than one stage uses cache-as-ram for CAR_GLOBALs. */
+ _car_global_start = .;
*(.car.global_data);
. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
+ _car_global_end = .;
_car_data_end = .;
-
- PRERAM_CBMEM_CONSOLE(., (CONFIG_LATE_CBMEM_INIT ? 0 : 0xc00))
}
/* Global variables are not allowed in romstage
@@ -48,4 +62,4 @@
*(.sbss.*)
}
-_bogus = ASSERT((CONFIG_DCACHE_RAM_SIZE == 0) || (SIZEOF(.car.data) + 0xc00 <= CONFIG_DCACHE_RAM_SIZE), "Cache as RAM area is too full");
+_bogus = ASSERT((CONFIG_DCACHE_RAM_SIZE == 0) || (SIZEOF(.car.data) <= CONFIG_DCACHE_RAM_SIZE), "Cache as RAM area is too full");
Alexandru Gagniuc (mr.nuke.me(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11607
-gerrit
commit a669c130714df138a1194464d52107b1104f4539
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Wed Sep 9 22:38:06 2015 -0700
cpu: microcode: Use microcode stored in binary format
Using a copiler to compile something that's already a binary is pretty
stupid. Now that Stefan converted most microcode in blobs to a plain
binary, use the binary version.
Change-Id: Iecf1f0cdf7bbeb7a61f46a0cd984ba341af787ce
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
---
src/cpu/Makefile.inc | 23 ++++++-------
src/cpu/amd/model_10xxx/Makefile.inc | 2 +-
src/cpu/amd/model_10xxx/microcode_blob.c | 3 --
src/cpu/amd/model_fxx/Makefile.inc | 2 +-
src/cpu/intel/ep80579/Makefile.inc | 2 --
src/cpu/intel/ep80579/microcode_blob.c | 8 -----
src/cpu/intel/fsp_model_206ax/Kconfig | 5 ---
src/cpu/intel/fsp_model_206ax/Makefile.inc | 9 ++---
src/cpu/intel/fsp_model_206ax/microcode_blob.c | 22 -------------
src/cpu/intel/fsp_model_206ax/microcode_blob.h | 33 -------------------
src/cpu/intel/fsp_model_206ax/microcode_size.h | 7 ----
src/cpu/intel/fsp_model_406dx/Kconfig | 4 ---
src/cpu/intel/fsp_model_406dx/Makefile.inc | 10 ++----
src/cpu/intel/fsp_model_406dx/microcode_blob.c | 29 -----------------
src/cpu/intel/fsp_model_406dx/microcode_size.h | 7 ----
src/cpu/intel/haswell/Makefile.inc | 5 +--
src/cpu/intel/haswell/microcode_blob.c | 30 -----------------
src/cpu/intel/model_1067x/Makefile.inc | 2 +-
src/cpu/intel/model_1067x/microcode_blob.c | 3 --
src/cpu/intel/model_106cx/Makefile.inc | 2 +-
src/cpu/intel/model_106cx/microcode_blob.c | 3 --
src/cpu/intel/model_2065x/Makefile.inc | 2 +-
src/cpu/intel/model_2065x/microcode_blob.c | 22 -------------
src/cpu/intel/model_206ax/Makefile.inc | 3 +-
src/cpu/intel/model_206ax/microcode_blob.c | 23 -------------
src/cpu/intel/model_65x/Makefile.inc | 2 +-
src/cpu/intel/model_65x/microcode_blob.c | 3 --
src/cpu/intel/model_67x/Makefile.inc | 2 +-
src/cpu/intel/model_67x/microcode_blob.c | 3 --
src/cpu/intel/model_68x/Makefile.inc | 2 +-
src/cpu/intel/model_68x/microcode_blob.c | 3 --
src/cpu/intel/model_69x/Makefile.inc | 2 +-
src/cpu/intel/model_69x/microcode_blob.c | 3 --
src/cpu/intel/model_6bx/Makefile.inc | 2 +-
src/cpu/intel/model_6bx/microcode_blob.c | 3 --
src/cpu/intel/model_6dx/Makefile.inc | 2 +-
src/cpu/intel/model_6dx/microcode_blob.c | 3 --
src/cpu/intel/model_6ex/Makefile.inc | 2 +-
src/cpu/intel/model_6ex/microcode_blob.c | 3 --
src/cpu/intel/model_6fx/Makefile.inc | 2 +-
src/cpu/intel/model_6fx/microcode_blob.c | 3 --
src/cpu/intel/model_6xx/Makefile.inc | 2 +-
src/cpu/intel/model_6xx/microcode_blob.c | 3 --
src/cpu/intel/model_f0x/Makefile.inc | 2 +-
src/cpu/intel/model_f0x/microcode_blob.c | 4 ---
src/cpu/intel/model_f1x/Makefile.inc | 2 +-
src/cpu/intel/model_f1x/microcode_blob.c | 4 ---
src/cpu/intel/model_f2x/Makefile.inc | 2 +-
src/cpu/intel/model_f2x/microcode_blob.c | 4 ---
src/cpu/intel/model_f3x/Makefile.inc | 2 +-
src/cpu/intel/model_f3x/microcode_blob.c | 3 --
src/cpu/intel/model_f4x/Makefile.inc | 2 +-
src/cpu/intel/model_f4x/microcode_blob.c | 3 --
src/cpu/via/nano/Makefile.inc | 4 +--
src/soc/intel/baytrail/Makefile.inc | 3 +-
src/soc/intel/baytrail/microcode/Makefile.inc | 1 -
src/soc/intel/baytrail/microcode/microcode_blob.c | 3 --
src/soc/intel/braswell/Makefile.inc | 3 +-
src/soc/intel/braswell/microcode/Makefile.inc | 2 --
src/soc/intel/braswell/microcode/microcode_blob.c | 22 -------------
src/soc/intel/broadwell/Makefile.inc | 3 +-
src/soc/intel/broadwell/microcode/Makefile.inc | 1 -
src/soc/intel/broadwell/microcode/microcode_blob.c | 22 -------------
src/soc/intel/fsp_baytrail/Makefile.inc | 3 +-
src/soc/intel/fsp_baytrail/microcode/Makefile.inc | 26 ---------------
.../intel/fsp_baytrail/microcode/microcode_blob.c | 38 ----------------------
.../intel/fsp_baytrail/microcode/microcode_size.h | 6 ----
src/soc/intel/skylake/Makefile.inc | 3 +-
src/soc/intel/skylake/microcode/Makefile.inc | 2 --
src/soc/intel/skylake/microcode/microcode_blob.c | 24 --------------
70 files changed, 50 insertions(+), 450 deletions(-)
diff --git a/src/cpu/Makefile.inc b/src/cpu/Makefile.inc
index 3ea42e5..92024f3 100644
--- a/src/cpu/Makefile.inc
+++ b/src/cpu/Makefile.inc
@@ -28,20 +28,17 @@ cpu_ucode_cbfs_file = $(obj)/cpu_microcode_blob.bin
cbfs_include_ucode = y
endif
-# In case we have more than one "source" (cough) files containing microcode, we
-# link them together in one large blob, so that we get all the microcode updates
-# in one file. This makes it easier for objcopy in the final step.
-# The --entry=0 is just here to suppress the LD warning. It does not affect the
-# final microcode file.
-$(obj)/cpu_microcode_blob.o: $$(cpu_microcode-objs)
- @printf " LD $(subst $(obj)/,,$(@))\n"
- $(LD_cpu_microcode) -static --entry=0 $+ -o $@
-
-# We have a lot of useless data in the large blob, and we are only interested in
-# the data section, so we only copy that part to the final microcode file
-$(obj)/cpu_microcode_blob.bin: $(obj)/cpu_microcode_blob.o
+# We just mash all microcode binaries together into one binary to rule them all.
+# This approach assumes that the microcode binaries are properly padded, and
+# their headers specify the correct size. This works fairly well on isolatied
+# updates, such as Intel and some AMD microcode, but won't work very well if the
+# updates are wrapped in a container, like AMD's microcode update container. If
+# there is only one microcode binary (i.e. one container), then we don't have
+# this issue, and this rule will continue to work.
+$(obj)/cpu_microcode_blob.bin: $$(cpu_microcode_bins)
@printf " MICROCODE $(subst $(obj)/,,$(@))\n"
- $(OBJCOPY_cpu_microcode) -j .data -O binary $< $@
+ @echo $(cpu_microcode_bins)
+ cat $+ > $@
cbfs-files-$(cbfs_include_ucode) += cpu_microcode_blob.bin
cpu_microcode_blob.bin-file := $(cpu_ucode_cbfs_file)
diff --git a/src/cpu/amd/model_10xxx/Makefile.inc b/src/cpu/amd/model_10xxx/Makefile.inc
index c17e66c..122e474 100644
--- a/src/cpu/amd/model_10xxx/Makefile.inc
+++ b/src/cpu/amd/model_10xxx/Makefile.inc
@@ -8,4 +8,4 @@ ramstage-y += ram_calc.c
ramstage-y += monotonic_timer.c
ramstage-$(CONFIG_HAVE_ACPI_TABLES) += powernow_acpi.c
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
+cpu_microcode_bins += 3rdparty/blobs/cpu/amd/model_10xxx/microcode.bin
diff --git a/src/cpu/amd/model_10xxx/microcode_blob.c b/src/cpu/amd/model_10xxx/microcode_blob.c
deleted file mode 100644
index a51b993..0000000
--- a/src/cpu/amd/model_10xxx/microcode_blob.c
+++ /dev/null
@@ -1,3 +0,0 @@
-unsigned char microcode[] __attribute__ ((aligned(16))) = {
-#include "../../../../3rdparty/blobs/cpu/amd/model_10xxx/microcode.h"
-};
diff --git a/src/cpu/amd/model_fxx/Makefile.inc b/src/cpu/amd/model_fxx/Makefile.inc
index 19a6255..4d8153a 100644
--- a/src/cpu/amd/model_fxx/Makefile.inc
+++ b/src/cpu/amd/model_fxx/Makefile.inc
@@ -6,4 +6,4 @@ ramstage-y += model_fxx_update_microcode.c
ramstage-y += processor_name.c
ramstage-$(CONFIG_HAVE_ACPI_TABLES) += powernow_acpi.c
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
+cpu_microcode_bins += 3rdparty/blobs/cpu/amd/model_fxx/microcode.bin
diff --git a/src/cpu/intel/ep80579/Makefile.inc b/src/cpu/intel/ep80579/Makefile.inc
index b213c08..1af9188 100644
--- a/src/cpu/intel/ep80579/Makefile.inc
+++ b/src/cpu/intel/ep80579/Makefile.inc
@@ -6,5 +6,3 @@ subdirs-y += ../../x86/lapic
subdirs-y += ../../x86/cache
subdirs-y += ../../x86/smm
subdirs-y += ../microcode
-
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
diff --git a/src/cpu/intel/ep80579/microcode_blob.c b/src/cpu/intel/ep80579/microcode_blob.c
deleted file mode 100644
index 689f59e..0000000
--- a/src/cpu/intel/ep80579/microcode_blob.c
+++ /dev/null
@@ -1,8 +0,0 @@
-/*
- * We support updating microcode from CBFS, but do not have any microcode
- * updates for this CPU. This will generate a useless cpu_microcode_blob.bin in
- * CBFS, but this file can be later replaced without needing to recompile the
- * coreboot.rom image.
- */
-unsigned microcode_updates_ep80579[] = {
-};
diff --git a/src/cpu/intel/fsp_model_206ax/Kconfig b/src/cpu/intel/fsp_model_206ax/Kconfig
index 3280f77..606000e 100644
--- a/src/cpu/intel/fsp_model_206ax/Kconfig
+++ b/src/cpu/intel/fsp_model_206ax/Kconfig
@@ -59,9 +59,4 @@ config CPU_MICROCODE_CBFS_LOC
depends on SUPPORT_CPU_UCODE_IN_CBFS
default 0xfff70000
-config MICROCODE_INCLUDE_PATH
- string "Location of the intel microcode patches"
- default "../intel/cpu/ivybridge/microcode" if CPU_INTEL_FSP_MODEL_306AX
- default "../intel/cpu/sandybridge/microcode" if CPU_INTEL_FSP_MODEL_206AX
-
endif
diff --git a/src/cpu/intel/fsp_model_206ax/Makefile.inc b/src/cpu/intel/fsp_model_206ax/Makefile.inc
index 83039bc..d2d61ef 100644
--- a/src/cpu/intel/fsp_model_206ax/Makefile.inc
+++ b/src/cpu/intel/fsp_model_206ax/Makefile.inc
@@ -6,11 +6,6 @@ ramstage-y += acpi.c
smm-$(CONFIG_HAVE_SMI_HANDLER) += finalize.c
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
CPPFLAGS_romstage += -I$(src)/cpu/intel/fsp_model_206ax
-
-ifneq ($(CONFIG_MICROCODE_INCLUDE_PATH),)
-ifneq ($(wildcard $(shell readlink -f "$(top)/$(CONFIG_MICROCODE_INCLUDE_PATH)")),)
-CPPFLAGS_common += -I$(CONFIG_MICROCODE_INCLUDE_PATH)
-endif
-endif
+cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_206ax/microcode.bin
+cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_306ax/microcode.bin
diff --git a/src/cpu/intel/fsp_model_206ax/microcode_blob.c b/src/cpu/intel/fsp_model_206ax/microcode_blob.c
deleted file mode 100644
index 15e33a2..0000000
--- a/src/cpu/intel/fsp_model_206ax/microcode_blob.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2012 The ChromiumOS Authors. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-unsigned microcode[] = {
-#include "microcode_blob.h"
-};
diff --git a/src/cpu/intel/fsp_model_206ax/microcode_blob.h b/src/cpu/intel/fsp_model_206ax/microcode_blob.h
deleted file mode 100644
index 01393ac..0000000
--- a/src/cpu/intel/fsp_model_206ax/microcode_blob.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2011 Google Inc.
- * Copyright (C) 2013 Sage Electronic Engineering, LLC.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-#if IS_ENABLED(CONFIG_CPU_INTEL_FSP_MODEL_206AX)
- /* Size is 0x2800 - Update in microcode_size.h when any included file changes*/
- #include <microcode-m12206a7_00000029.h>
-#endif
-
-#if IS_ENABLED(CONFIG_CPU_INTEL_FSP_MODEL_306AX)
- /* Size is 0xC000 - Update in microcode_size.h when any included file changes*/
- #include <microcode-m12306a2_00000008.h>
- #include <microcode-m12306a4_00000007.h>
- #include <microcode-m12306a5_00000007.h>
- #include <microcode-m12306a8_00000010.h>
- #include <microcode-m12306a9_00000019.h>
-#endif
diff --git a/src/cpu/intel/fsp_model_206ax/microcode_size.h b/src/cpu/intel/fsp_model_206ax/microcode_size.h
deleted file mode 100644
index 0b0364c..0000000
--- a/src/cpu/intel/fsp_model_206ax/microcode_size.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/* Maximum size of the area that the FSP will search for the correct microcode */
-
-#if IS_ENABLED(CONFIG_CPU_INTEL_FSP_MODEL_306AX)
- #define MICROCODE_REGION_LENGTH 0xC000
-#elif IS_ENABLED(CONFIG_CPU_INTEL_FSP_MODEL_206AX)
- #define MICROCODE_REGION_LENGTH 0x2800
-#endif
diff --git a/src/cpu/intel/fsp_model_406dx/Kconfig b/src/cpu/intel/fsp_model_406dx/Kconfig
index 8251f5d..1630409 100644
--- a/src/cpu/intel/fsp_model_406dx/Kconfig
+++ b/src/cpu/intel/fsp_model_406dx/Kconfig
@@ -62,8 +62,4 @@ config CPU_MICROCODE_CBFS_LOC
depends on SUPPORT_CPU_UCODE_IN_CBFS
default 0xfff60040
-config MICROCODE_INCLUDE_PATH
- string "Location of the intel microcode patches"
- default "../intel/cpu/rangeley/microcode"
-
endif #CPU_INTEL_FSP_MODEL_406DX
diff --git a/src/cpu/intel/fsp_model_406dx/Makefile.inc b/src/cpu/intel/fsp_model_406dx/Makefile.inc
index 744ed42..f28e531 100644
--- a/src/cpu/intel/fsp_model_406dx/Makefile.inc
+++ b/src/cpu/intel/fsp_model_406dx/Makefile.inc
@@ -22,11 +22,7 @@ subdirs-y += ../../x86/name
ramstage-y += acpi.c
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
CPPFLAGS_romstage += -I$(src)/cpu/intel/fsp_model_406dx
-
-ifneq ($(CONFIG_MICROCODE_INCLUDE_PATH),)
-ifneq ($(wildcard $(shell readlink -f "$(top)/$(CONFIG_MICROCODE_INCLUDE_PATH)")),)
-CPPFLAGS_common += -I$(CONFIG_MICROCODE_INCLUDE_PATH)
-endif
-endif
+# We don't have microcode for this CPU
+# Use CONFIG_CPU_MICROCODE_CBFS_EXTERNAL with a binary microcode file
+# cpu_microcode_bins += ???
diff --git a/src/cpu/intel/fsp_model_406dx/microcode_blob.c b/src/cpu/intel/fsp_model_406dx/microcode_blob.c
deleted file mode 100644
index f178f82..0000000
--- a/src/cpu/intel/fsp_model_406dx/microcode_blob.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2012 The ChromiumOS Authors. All rights reserved.
- * Copyright (C) 2014 Sage Electronic Engineering, LLC
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-unsigned microcode[] = {
-#if IS_ENABLED(CONFIG_FSP_MODEL_406DX_A1)
- /* Size is 0x14400 - update in microcode_size.h when the file changes */
- #include <microcode-m01406d000e.h>
-#elif IS_ENABLED(CONFIG_FSP_MODEL_406DX_B0)
- /* Size is 0x14800 - update in microcode_size.h when the file changes */
- #include <microcode-m01406d811d.h>
-#endif
-};
diff --git a/src/cpu/intel/fsp_model_406dx/microcode_size.h b/src/cpu/intel/fsp_model_406dx/microcode_size.h
deleted file mode 100644
index b638ae5..0000000
--- a/src/cpu/intel/fsp_model_406dx/microcode_size.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/* Maximum size of the area that the FSP will search for the correct microcode */
-
-#if IS_ENABLED(CONFIG_FSP_MODEL_406DX_A1)
- #define MICROCODE_REGION_LENGTH 0x14400
-#elif IS_ENABLED(CONFIG_FSP_MODEL_406DX_B0)
- #define MICROCODE_REGION_LENGTH 0x14800
-#endif
diff --git a/src/cpu/intel/haswell/Makefile.inc b/src/cpu/intel/haswell/Makefile.inc
index a4a9c34..d54a25c 100644
--- a/src/cpu/intel/haswell/Makefile.inc
+++ b/src/cpu/intel/haswell/Makefile.inc
@@ -10,8 +10,6 @@ ramstage-y += monotonic_timer.c
romstage-$(CONFIG_CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM) += stage_cache.c
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
-
smm-$(CONFIG_HAVE_SMI_HANDLER) += finalize.c
smm-$(CONFIG_HAVE_SMI_HANDLER) += tsc_freq.c
smm-y += monotonic_timer.c
@@ -25,3 +23,6 @@ subdirs-y += ../../x86/cache
subdirs-y += ../../x86/smm
subdirs-y += ../microcode
subdirs-y += ../turbo
+
+cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_306cx/microcode.bin
+cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_4065x/microcode.bin
diff --git a/src/cpu/intel/haswell/microcode_blob.c b/src/cpu/intel/haswell/microcode_blob.c
deleted file mode 100644
index 67ab1cd..0000000
--- a/src/cpu/intel/haswell/microcode_blob.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2011 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-unsigned microcode[] = {
- /*
- * FIXME: Can we just include both microcodes regardless, or is there
- * a very good reason why we only use one at a time?
- */
- #if CONFIG_INTEL_LYNXPOINT_LP
- #include "../../../../3rdparty/blobs/cpu/intel/model_4065x/microcode.h"
- #else
- #include "../../../../3rdparty/blobs/cpu/intel/model_306cx/microcode.h"
- #endif
-};
diff --git a/src/cpu/intel/model_1067x/Makefile.inc b/src/cpu/intel/model_1067x/Makefile.inc
index ccfeb7f..3e0af86 100644
--- a/src/cpu/intel/model_1067x/Makefile.inc
+++ b/src/cpu/intel/model_1067x/Makefile.inc
@@ -1,4 +1,4 @@
ramstage-y += model_1067x_init.c
subdirs-y += ../../x86/name
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
+cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_1067x/microcode.bin
diff --git a/src/cpu/intel/model_1067x/microcode_blob.c b/src/cpu/intel/model_1067x/microcode_blob.c
deleted file mode 100644
index 88e95db..0000000
--- a/src/cpu/intel/model_1067x/microcode_blob.c
+++ /dev/null
@@ -1,3 +0,0 @@
-unsigned microcode_updates_1067ax[] = {
- #include "../../../../3rdparty/blobs/cpu/intel/model_1067x/microcode.h"
-};
diff --git a/src/cpu/intel/model_106cx/Makefile.inc b/src/cpu/intel/model_106cx/Makefile.inc
index 8aa5a5e..25631e5 100644
--- a/src/cpu/intel/model_106cx/Makefile.inc
+++ b/src/cpu/intel/model_106cx/Makefile.inc
@@ -2,4 +2,4 @@ ramstage-y += model_106cx_init.c
subdirs-y += ../../x86/name
cpu_incs-y += $(src)/cpu/intel/car/cache_as_ram_ht.inc
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
+cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_106cx/microcode.bin
diff --git a/src/cpu/intel/model_106cx/microcode_blob.c b/src/cpu/intel/model_106cx/microcode_blob.c
deleted file mode 100644
index 5a0257a..0000000
--- a/src/cpu/intel/model_106cx/microcode_blob.c
+++ /dev/null
@@ -1,3 +0,0 @@
-unsigned microcode_updates_106cx[] = {
- #include "../../../../3rdparty/blobs/cpu/intel/model_106cx/microcode.h"
-};
diff --git a/src/cpu/intel/model_2065x/Makefile.inc b/src/cpu/intel/model_2065x/Makefile.inc
index 1b5d2ba..a13f5df 100644
--- a/src/cpu/intel/model_2065x/Makefile.inc
+++ b/src/cpu/intel/model_2065x/Makefile.inc
@@ -17,6 +17,6 @@ ramstage-y += acpi.c
smm-$(CONFIG_HAVE_SMI_HANDLER) += finalize.c
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
+cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_2065x/microcode.bin
cpu_incs-y += $(src)/cpu/intel/model_2065x/cache_as_ram.inc
diff --git a/src/cpu/intel/model_2065x/microcode_blob.c b/src/cpu/intel/model_2065x/microcode_blob.c
deleted file mode 100644
index c32b8f3..0000000
--- a/src/cpu/intel/model_2065x/microcode_blob.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2012 The ChromiumOS Authors. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-unsigned microcode[] = {
- #include "../../../../3rdparty/blobs/cpu/intel/model_2065x/microcode.h"
-};
diff --git a/src/cpu/intel/model_206ax/Makefile.inc b/src/cpu/intel/model_206ax/Makefile.inc
index 6f12756..6042991 100644
--- a/src/cpu/intel/model_206ax/Makefile.inc
+++ b/src/cpu/intel/model_206ax/Makefile.inc
@@ -6,6 +6,7 @@ ramstage-y += acpi.c
smm-$(CONFIG_HAVE_SMI_HANDLER) += finalize.c
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
+cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_206ax/microcode.bin
+cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_306ax/microcode.bin
cpu_incs-y += $(src)/cpu/intel/model_206ax/cache_as_ram.inc
diff --git a/src/cpu/intel/model_206ax/microcode_blob.c b/src/cpu/intel/model_206ax/microcode_blob.c
deleted file mode 100644
index cde01e0..0000000
--- a/src/cpu/intel/model_206ax/microcode_blob.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2012 The ChromiumOS Authors. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-unsigned microcode[] = {
- #include "../../../../3rdparty/blobs/cpu/intel/model_206ax/microcode.h"
- #include "../../../../3rdparty/blobs/cpu/intel/model_306ax/microcode.h"
-};
diff --git a/src/cpu/intel/model_65x/Makefile.inc b/src/cpu/intel/model_65x/Makefile.inc
index d40c413..98697c7 100644
--- a/src/cpu/intel/model_65x/Makefile.inc
+++ b/src/cpu/intel/model_65x/Makefile.inc
@@ -20,4 +20,4 @@
ramstage-y += model_65x_init.c
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
+cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_65x/microcode.bin
diff --git a/src/cpu/intel/model_65x/microcode_blob.c b/src/cpu/intel/model_65x/microcode_blob.c
deleted file mode 100644
index 8511708..0000000
--- a/src/cpu/intel/model_65x/microcode_blob.c
+++ /dev/null
@@ -1,3 +0,0 @@
-unsigned microcode_updates_65x[] = {
- #include "../../../../3rdparty/blobs/cpu/intel/model_65x/microcode.h"
-};
diff --git a/src/cpu/intel/model_67x/Makefile.inc b/src/cpu/intel/model_67x/Makefile.inc
index e42e566..6a748fa 100644
--- a/src/cpu/intel/model_67x/Makefile.inc
+++ b/src/cpu/intel/model_67x/Makefile.inc
@@ -20,4 +20,4 @@
ramstage-y += model_67x_init.c
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
+cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_67x/microcode.bin
diff --git a/src/cpu/intel/model_67x/microcode_blob.c b/src/cpu/intel/model_67x/microcode_blob.c
deleted file mode 100644
index 672dee3..0000000
--- a/src/cpu/intel/model_67x/microcode_blob.c
+++ /dev/null
@@ -1,3 +0,0 @@
-unsigned microcode_updates_67x[] = {
- #include "../../../../3rdparty/blobs/cpu/intel/model_67x/microcode.h"
-};
diff --git a/src/cpu/intel/model_68x/Makefile.inc b/src/cpu/intel/model_68x/Makefile.inc
index b0a5823..e7390ba 100644
--- a/src/cpu/intel/model_68x/Makefile.inc
+++ b/src/cpu/intel/model_68x/Makefile.inc
@@ -21,4 +21,4 @@
ramstage-y += model_68x_init.c
subdirs-y += ../../x86/name
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
+cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_68x/microcode.bin
diff --git a/src/cpu/intel/model_68x/microcode_blob.c b/src/cpu/intel/model_68x/microcode_blob.c
deleted file mode 100644
index db32f34..0000000
--- a/src/cpu/intel/model_68x/microcode_blob.c
+++ /dev/null
@@ -1,3 +0,0 @@
-unsigned microcode_updates_68x[] = {
- #include "../../../../3rdparty/blobs/cpu/intel/model_68x/microcode.h"
-};
diff --git a/src/cpu/intel/model_69x/Makefile.inc b/src/cpu/intel/model_69x/Makefile.inc
index e9d90ca..7bf028c 100644
--- a/src/cpu/intel/model_69x/Makefile.inc
+++ b/src/cpu/intel/model_69x/Makefile.inc
@@ -1,3 +1,3 @@
ramstage-y += model_69x_init.c
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
+cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_69x/microcode.bin
diff --git a/src/cpu/intel/model_69x/microcode_blob.c b/src/cpu/intel/model_69x/microcode_blob.c
deleted file mode 100644
index 04bc717..0000000
--- a/src/cpu/intel/model_69x/microcode_blob.c
+++ /dev/null
@@ -1,3 +0,0 @@
-unsigned microcode_updates_69x[] = {
- #include "../../../../3rdparty/blobs/cpu/intel/model_69x/microcode.h"
-};
diff --git a/src/cpu/intel/model_6bx/Makefile.inc b/src/cpu/intel/model_6bx/Makefile.inc
index 5f1f894..81e64e3 100644
--- a/src/cpu/intel/model_6bx/Makefile.inc
+++ b/src/cpu/intel/model_6bx/Makefile.inc
@@ -1,4 +1,4 @@
ramstage-y += model_6bx_init.c
subdirs-y += ../../x86/name
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
+cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_6bx/microcode.bin
diff --git a/src/cpu/intel/model_6bx/microcode_blob.c b/src/cpu/intel/model_6bx/microcode_blob.c
deleted file mode 100644
index dbfab5d..0000000
--- a/src/cpu/intel/model_6bx/microcode_blob.c
+++ /dev/null
@@ -1,3 +0,0 @@
-unsigned microcode_updates_6bx[] = {
- #include "../../../../3rdparty/blobs/cpu/intel/model_6bx/microcode.h"
-};
diff --git a/src/cpu/intel/model_6dx/Makefile.inc b/src/cpu/intel/model_6dx/Makefile.inc
index 4731de3..92985ea 100644
--- a/src/cpu/intel/model_6dx/Makefile.inc
+++ b/src/cpu/intel/model_6dx/Makefile.inc
@@ -1,3 +1,3 @@
ramstage-y += model_6dx_init.c
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
+cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_6dx/microcode.bin
diff --git a/src/cpu/intel/model_6dx/microcode_blob.c b/src/cpu/intel/model_6dx/microcode_blob.c
deleted file mode 100644
index 50e15cc..0000000
--- a/src/cpu/intel/model_6dx/microcode_blob.c
+++ /dev/null
@@ -1,3 +0,0 @@
-unsigned microcode_updates_6dx[] = {
- #include "../../../../3rdparty/blobs/cpu/intel/model_6dx/microcode.h"
-};
diff --git a/src/cpu/intel/model_6ex/Makefile.inc b/src/cpu/intel/model_6ex/Makefile.inc
index 6d94302..69d5c1b 100644
--- a/src/cpu/intel/model_6ex/Makefile.inc
+++ b/src/cpu/intel/model_6ex/Makefile.inc
@@ -1,4 +1,4 @@
ramstage-y += model_6ex_init.c
subdirs-y += ../../x86/name
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
+cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_6ex/microcode.bin
diff --git a/src/cpu/intel/model_6ex/microcode_blob.c b/src/cpu/intel/model_6ex/microcode_blob.c
deleted file mode 100644
index 2c749a7..0000000
--- a/src/cpu/intel/model_6ex/microcode_blob.c
+++ /dev/null
@@ -1,3 +0,0 @@
-unsigned microcode_updates_6ex[] = {
- #include "../../../../3rdparty/blobs/cpu/intel/model_6ex/microcode.h"
-};
diff --git a/src/cpu/intel/model_6fx/Makefile.inc b/src/cpu/intel/model_6fx/Makefile.inc
index 6a1bb51..ba31c7e 100644
--- a/src/cpu/intel/model_6fx/Makefile.inc
+++ b/src/cpu/intel/model_6fx/Makefile.inc
@@ -1,4 +1,4 @@
ramstage-y += model_6fx_init.c
subdirs-y += ../../x86/name
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
+cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_6fx/microcode.bin
diff --git a/src/cpu/intel/model_6fx/microcode_blob.c b/src/cpu/intel/model_6fx/microcode_blob.c
deleted file mode 100644
index 8044e51..0000000
--- a/src/cpu/intel/model_6fx/microcode_blob.c
+++ /dev/null
@@ -1,3 +0,0 @@
-unsigned microcode_updates_6fx[] = {
- #include "../../../../3rdparty/blobs/cpu/intel/model_6fx/microcode.h"
-};
diff --git a/src/cpu/intel/model_6xx/Makefile.inc b/src/cpu/intel/model_6xx/Makefile.inc
index 0c41cf2..1ac799e 100644
--- a/src/cpu/intel/model_6xx/Makefile.inc
+++ b/src/cpu/intel/model_6xx/Makefile.inc
@@ -1,3 +1,3 @@
ramstage-y += model_6xx_init.c
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
+cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_6xx/microcode.bin
diff --git a/src/cpu/intel/model_6xx/microcode_blob.c b/src/cpu/intel/model_6xx/microcode_blob.c
deleted file mode 100644
index 463faf0..0000000
--- a/src/cpu/intel/model_6xx/microcode_blob.c
+++ /dev/null
@@ -1,3 +0,0 @@
-unsigned microcode_updates_6xx[] = {
- #include "../../../../3rdparty/blobs/cpu/intel/model_6xx/microcode.h"
-};
diff --git a/src/cpu/intel/model_f0x/Makefile.inc b/src/cpu/intel/model_f0x/Makefile.inc
index 6c16419..158ac21 100644
--- a/src/cpu/intel/model_f0x/Makefile.inc
+++ b/src/cpu/intel/model_f0x/Makefile.inc
@@ -1,3 +1,3 @@
ramstage-y += model_f0x_init.c
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
+cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_f0x/microcode.bin
diff --git a/src/cpu/intel/model_f0x/microcode_blob.c b/src/cpu/intel/model_f0x/microcode_blob.c
deleted file mode 100644
index 7cef6d1..0000000
--- a/src/cpu/intel/model_f0x/microcode_blob.c
+++ /dev/null
@@ -1,4 +0,0 @@
-/* 256KB cache */
-unsigned microcode_updates_f0x[] = {
- #include "../../../../3rdparty/blobs/cpu/intel/model_f0x/microcode.h"
-};
diff --git a/src/cpu/intel/model_f1x/Makefile.inc b/src/cpu/intel/model_f1x/Makefile.inc
index c706234..81bc161 100644
--- a/src/cpu/intel/model_f1x/Makefile.inc
+++ b/src/cpu/intel/model_f1x/Makefile.inc
@@ -1,3 +1,3 @@
ramstage-y += model_f1x_init.c
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
+cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_f1x/microcode.bin
diff --git a/src/cpu/intel/model_f1x/microcode_blob.c b/src/cpu/intel/model_f1x/microcode_blob.c
deleted file mode 100644
index a9b25d7..0000000
--- a/src/cpu/intel/model_f1x/microcode_blob.c
+++ /dev/null
@@ -1,4 +0,0 @@
-/* 256KB cache */
-unsigned microcode_updates_f1x[] = {
- #include "../../../../3rdparty/blobs/cpu/intel/model_f1x/microcode.h"
-};
diff --git a/src/cpu/intel/model_f2x/Makefile.inc b/src/cpu/intel/model_f2x/Makefile.inc
index 3360611..589e49e 100644
--- a/src/cpu/intel/model_f2x/Makefile.inc
+++ b/src/cpu/intel/model_f2x/Makefile.inc
@@ -1,3 +1,3 @@
ramstage-y += model_f2x_init.c
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
+cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_f2x/microcode.bin
diff --git a/src/cpu/intel/model_f2x/microcode_blob.c b/src/cpu/intel/model_f2x/microcode_blob.c
deleted file mode 100644
index 3815f06..0000000
--- a/src/cpu/intel/model_f2x/microcode_blob.c
+++ /dev/null
@@ -1,4 +0,0 @@
-/* 512KB cache */
-unsigned microcode_updates_f2x[] = {
- #include "../../../../3rdparty/blobs/cpu/intel/model_f2x/microcode.h"
-};
diff --git a/src/cpu/intel/model_f3x/Makefile.inc b/src/cpu/intel/model_f3x/Makefile.inc
index ebd47cf..b73a25d 100644
--- a/src/cpu/intel/model_f3x/Makefile.inc
+++ b/src/cpu/intel/model_f3x/Makefile.inc
@@ -1,3 +1,3 @@
ramstage-y += model_f3x_init.c
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
+cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_f3x/microcode.bin
diff --git a/src/cpu/intel/model_f3x/microcode_blob.c b/src/cpu/intel/model_f3x/microcode_blob.c
deleted file mode 100644
index fb46747..0000000
--- a/src/cpu/intel/model_f3x/microcode_blob.c
+++ /dev/null
@@ -1,3 +0,0 @@
-unsigned microcode_updates_f3x[] = {
- #include "../../../../3rdparty/blobs/cpu/intel/model_f3x/microcode.h"
-};
diff --git a/src/cpu/intel/model_f4x/Makefile.inc b/src/cpu/intel/model_f4x/Makefile.inc
index 6ade9f3..9aeb107 100644
--- a/src/cpu/intel/model_f4x/Makefile.inc
+++ b/src/cpu/intel/model_f4x/Makefile.inc
@@ -1,3 +1,3 @@
ramstage-y += model_f4x_init.c
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
+cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_f4x/microcode.bin
diff --git a/src/cpu/intel/model_f4x/microcode_blob.c b/src/cpu/intel/model_f4x/microcode_blob.c
deleted file mode 100644
index b061dcc..0000000
--- a/src/cpu/intel/model_f4x/microcode_blob.c
+++ /dev/null
@@ -1,3 +0,0 @@
-unsigned microcode_updates_f4x[] = {
- #include "../../../../3rdparty/blobs/cpu/intel/model_f4x/microcode.h"
-};
diff --git a/src/cpu/via/nano/Makefile.inc b/src/cpu/via/nano/Makefile.inc
index d3df3fb..dcbdcc9 100644
--- a/src/cpu/via/nano/Makefile.inc
+++ b/src/cpu/via/nano/Makefile.inc
@@ -26,8 +26,6 @@ subdirs-y += ../../x86/smm
ramstage-y += nano_init.c
ramstage-y += update_ucode.c
-# This microcode is included as a separate CBFS file. It is never linked in to
-# the rest of coreboot.
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
+cpu_microcode_bins += 3rdparty/blobs/cpu/via/nano/microcode.bin
cpu_incs-y += $(src)/cpu/via/car/cache_as_ram.inc
diff --git a/src/soc/intel/baytrail/Makefile.inc b/src/soc/intel/baytrail/Makefile.inc
index 085a45e..edc77af 100644
--- a/src/soc/intel/baytrail/Makefile.inc
+++ b/src/soc/intel/baytrail/Makefile.inc
@@ -1,6 +1,5 @@
ifeq ($(CONFIG_SOC_INTEL_BAYTRAIL),y)
-subdirs-y += microcode
subdirs-y += romstage
subdirs-y += ../../../cpu/x86/lapic
subdirs-y += ../../../cpu/x86/mtrr
@@ -53,6 +52,8 @@ ramstage-y += hda.c
# Remove as ramstage gets fleshed out
ramstage-y += placeholders.c
+cpu_microcode_bins += 3rdparty/blobs/soc/intel/baytrail/microcode.bin
+
CPPFLAGS_common += -Isrc/soc/intel/baytrail/include
# If an MRC file is an ELF file determine the entry address and first loadable
diff --git a/src/soc/intel/baytrail/microcode/Makefile.inc b/src/soc/intel/baytrail/microcode/Makefile.inc
deleted file mode 100644
index 09bd454..0000000
--- a/src/soc/intel/baytrail/microcode/Makefile.inc
+++ /dev/null
@@ -1 +0,0 @@
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
diff --git a/src/soc/intel/baytrail/microcode/microcode_blob.c b/src/soc/intel/baytrail/microcode/microcode_blob.c
deleted file mode 100644
index a69990f..0000000
--- a/src/soc/intel/baytrail/microcode/microcode_blob.c
+++ /dev/null
@@ -1,3 +0,0 @@
-unsigned microcode[] = {
-#include "../../../../../3rdparty/blobs/soc/intel/baytrail/microcode_blob.h"
-};
diff --git a/src/soc/intel/braswell/Makefile.inc b/src/soc/intel/braswell/Makefile.inc
index e5ac640..426f359 100644
--- a/src/soc/intel/braswell/Makefile.inc
+++ b/src/soc/intel/braswell/Makefile.inc
@@ -1,6 +1,5 @@
ifeq ($(CONFIG_SOC_INTEL_BRASWELL),y)
-subdirs-y += microcode
subdirs-y += romstage
subdirs-y += ../../../cpu/x86/lapic
subdirs-y += ../../../cpu/x86/mtrr
@@ -51,6 +50,8 @@ smm-y += smihandler.c
smm-y += spi.c
smm-y += tsc_freq.c
+# cpu_microcode_bins += ???
+
CPPFLAGS_common += -I$(src)/soc/intel/braswell/
CPPFLAGS_common += -I$(src)/soc/intel/braswell/include
diff --git a/src/soc/intel/braswell/microcode/Makefile.inc b/src/soc/intel/braswell/microcode/Makefile.inc
deleted file mode 100644
index 3497328..0000000
--- a/src/soc/intel/braswell/microcode/Makefile.inc
+++ /dev/null
@@ -1,2 +0,0 @@
-# Add CPU uCode source to list of files to build.
-cpu_microcode-y += microcode_blob.c
diff --git a/src/soc/intel/braswell/microcode/microcode_blob.c b/src/soc/intel/braswell/microcode/microcode_blob.c
deleted file mode 100644
index e0aeaff..0000000
--- a/src/soc/intel/braswell/microcode/microcode_blob.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2015 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-unsigned microcode[] = {
-#include <microcode/microcode_blob.h>
-};
diff --git a/src/soc/intel/broadwell/Makefile.inc b/src/soc/intel/broadwell/Makefile.inc
index fdd064d..a9004ac 100644
--- a/src/soc/intel/broadwell/Makefile.inc
+++ b/src/soc/intel/broadwell/Makefile.inc
@@ -1,6 +1,5 @@
ifeq ($(CONFIG_SOC_INTEL_BROADWELL),y)
-subdirs-y += microcode
subdirs-y += romstage
subdirs-y += ../../../cpu/x86/lapic
subdirs-y += ../../../cpu/x86/mtrr
@@ -73,6 +72,8 @@ romstage-y += usbdebug.c
smm-y += usbdebug.c
endif
+cpu_microcode_bins += 3rdparty/blobs/soc/intel/broadwell/microcode.bin
+
CPPFLAGS_common += -Isrc/soc/intel/broadwell/include
# If an MRC file is an ELF file determine the entry address and first loadable
diff --git a/src/soc/intel/broadwell/microcode/Makefile.inc b/src/soc/intel/broadwell/microcode/Makefile.inc
deleted file mode 100644
index bf9e345..0000000
--- a/src/soc/intel/broadwell/microcode/Makefile.inc
+++ /dev/null
@@ -1 +0,0 @@
-cpu_microcode-y += microcode_blob.c
diff --git a/src/soc/intel/broadwell/microcode/microcode_blob.c b/src/soc/intel/broadwell/microcode/microcode_blob.c
deleted file mode 100644
index 412fedc..0000000
--- a/src/soc/intel/broadwell/microcode/microcode_blob.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2014 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-unsigned microcode[] = {
-#include "../../../../../3rdparty/blobs/soc/intel/broadwell/microcode_blob.h"
-};
diff --git a/src/soc/intel/fsp_baytrail/Makefile.inc b/src/soc/intel/fsp_baytrail/Makefile.inc
index 39a253f..7370830 100644
--- a/src/soc/intel/fsp_baytrail/Makefile.inc
+++ b/src/soc/intel/fsp_baytrail/Makefile.inc
@@ -20,7 +20,6 @@
ifeq ($(CONFIG_SOC_INTEL_FSP_BAYTRAIL),y)
-subdirs-y += microcode
subdirs-y += romstage
subdirs-y += ../../../cpu/x86/lapic
subdirs-y += ../../../cpu/x86/mtrr
@@ -59,6 +58,8 @@ ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smm.c
ramstage-y += placeholders.c
ramstage-y += i2c.c
+cpu_microcode_bins += 3rdparty/blobs/soc/intel/baytrail/microcode.bin
+
CPPFLAGS_common += -I$(src)/soc/intel/fsp_baytrail/
CPPFLAGS_common += -I$(src)/soc/intel/fsp_baytrail/fsp
diff --git a/src/soc/intel/fsp_baytrail/microcode/Makefile.inc b/src/soc/intel/fsp_baytrail/microcode/Makefile.inc
deleted file mode 100644
index 506291d..0000000
--- a/src/soc/intel/fsp_baytrail/microcode/Makefile.inc
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# This file is part of the coreboot project.
-#
-# Copyright (C) 2014 Sage Electronic Engineering, LLC.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc.
-#
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
-CPPFLAGS_romstage += -I$(src)/soc/intel/fsp_baytrail/microcode
-
-ifneq ($(CONFIG_MICROCODE_INCLUDE_PATH),)
-ifneq ($(wildcard $(shell readlink -f "$(top)/$(CONFIG_MICROCODE_INCLUDE_PATH)")),)
-CPPFLAGS_common += -I$(CONFIG_MICROCODE_INCLUDE_PATH)
-endif
-endif
diff --git a/src/soc/intel/fsp_baytrail/microcode/microcode_blob.c b/src/soc/intel/fsp_baytrail/microcode/microcode_blob.c
deleted file mode 100644
index 822c91b..0000000
--- a/src/soc/intel/fsp_baytrail/microcode/microcode_blob.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-unsigned microcode[] = {
-
- /*
- * The problem is that these microcode files are not in the tree. They come
- * with FSP, so let the user deal with the include paths when HAVE_FSP_BIN
- * is enabled.
- */
-#if IS_ENABLED(CONFIG_HAVE_FSP_BIN)
-#if !IS_ENABLED(CONFIG_SOC_INTEL_FSP_BAYTRAIL_MD)
- /* Region size is 0x30000 - update in microcode_size.h if it gets larger. */
- #include "M0230672228.h" // M0230672: Bay Trail "Super SKU" B0/B1
- #include "M0130673322.h" // M0130673: Bay Trail I B2 / B3
- #include "M0130679901.h" // M0130679: Bay Trail I D0
-#else
- /* Region size is 0x10000 - update in microcode_size.h if it gets larger. */
- #include "M0C30678829.h" // M0C30678: Bay Trail M D Stepping
-#endif /* CONFIG_SOC_INTEL_FSP_BAYTRAIL_MD */
-#endif /* CONFIG_HAVE_FSP_BIN */
-};
diff --git a/src/soc/intel/fsp_baytrail/microcode/microcode_size.h b/src/soc/intel/fsp_baytrail/microcode/microcode_size.h
deleted file mode 100644
index 2af2201..0000000
--- a/src/soc/intel/fsp_baytrail/microcode/microcode_size.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/* Maximum size of the area that the FSP will search for the correct microcode */
-#if !IS_ENABLED(CONFIG_SOC_INTEL_FSP_BAYTRAIL_MD)
- #define MICROCODE_REGION_LENGTH 0x30000
-#else
- #define MICROCODE_REGION_LENGTH 0x10000
-#endif
diff --git a/src/soc/intel/skylake/Makefile.inc b/src/soc/intel/skylake/Makefile.inc
index d6bc839..b80767b 100644
--- a/src/soc/intel/skylake/Makefile.inc
+++ b/src/soc/intel/skylake/Makefile.inc
@@ -1,6 +1,5 @@
ifeq ($(CONFIG_SOC_INTEL_SKYLAKE),y)
-subdirs-y += microcode
subdirs-y += romstage
subdirs-y += ../../../cpu/intel/microcode
subdirs-y += ../../../cpu/intel/turbo
@@ -61,6 +60,8 @@ smm-$(CONFIG_SPI_FLASH_SMM) += flash_controller.c
smm-y += tsc_freq.c
smm-$(CONFIG_UART_DEBUG) += uart_debug.c
+# cpu_microcode_bins += ???
+
CPPFLAGS_common += -I$(src)/soc/intel/skylake
CPPFLAGS_common += -I$(src)/soc/intel/skylake/include
diff --git a/src/soc/intel/skylake/microcode/Makefile.inc b/src/soc/intel/skylake/microcode/Makefile.inc
deleted file mode 100644
index ba308f6..0000000
--- a/src/soc/intel/skylake/microcode/Makefile.inc
+++ /dev/null
@@ -1,2 +0,0 @@
-# Add CPU uCode source to list of files to build.
-cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
diff --git a/src/soc/intel/skylake/microcode/microcode_blob.c b/src/soc/intel/skylake/microcode/microcode_blob.c
deleted file mode 100644
index 48c1aa2..0000000
--- a/src/soc/intel/skylake/microcode/microcode_blob.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2014 Google Inc.
- * Copyright (C) 2015 Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-unsigned int microcode[] = {
-#include <microcode/microcode_blob.h>
-};
-
WANG Siyuan (wangsiyuanbuaa(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11737
-gerrit
commit 4e4ec380acc318f65d21dea776ccd42c4536df1a
Author: WANG Siyuan <wangsiyuanbuaa(a)gmail.com>
Date: Tue Sep 29 11:12:03 2015 +0800
AMD Bettong: add README
This is the initial version of README.
AMD provides stable Bettong code in github. Add the link and bug fixed
list to README.
Change-Id: Ie8b761096fd1850afb9363ebb761aa4992b47643
Signed-off-by: WANG Siyuan <wangsiyuanbuaa(a)gmail.com>
Signed-off-by: WANG Siyuan <SiYuan.Wang(a)amd.com>
---
src/mainboard/amd/bettong/README | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/src/mainboard/amd/bettong/README b/src/mainboard/amd/bettong/README
new file mode 100644
index 0000000..d834af4
--- /dev/null
+++ b/src/mainboard/amd/bettong/README
@@ -0,0 +1,25 @@
+coreboot is changing all the time and the patches are reabsed when pushed to
+community, so it is a little difficult to provide stable Bettong code.
+From now on, AMD provides source code which is validated by QA team.
+The code is pushed to github https://github.com/BTDC/coreboot
+The version is identified by a tag. All the changes will be pushed to coreboot
+community.
+
+=====
+Version: TCMEF1F0 Release Date: 09/29/2015
+
+Changes from last version:
+1. Fix external graphics issue.
+2. Add board ID support.
+3. Support DDR4.
+4. Support SD 2.0.
+5. Fix Windows 7 S4 issue.
+6. Add GPIO, I2C and UART support.
+7. Fix the interrupt routine.
+8. Restruct PCI interrupt table (C00/C01).
+9. Fix DSDT issue.
+10. Fix the PCIe lane map.
+11. Lower the TOM to give more MMIO space.
+12. Add USB device.
+13. Set the USB3 port as unremoveable.
+14. Update AGESA to CarrizoPI 1.1.0.1.
WANG Siyuan (wangsiyuanbuaa(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11737
-gerrit
commit a000c294cd06c17ad8945ee7064e17de9d76f32d
Author: WANG Siyuan <wangsiyuanbuaa(a)gmail.com>
Date: Tue Sep 29 11:12:03 2015 +0800
AMD Bettong: add README
AMD provide stable Bettong code in github.
Change-Id: Ie8b761096fd1850afb9363ebb761aa4992b47643
Signed-off-by: WANG Siyuan <wangsiyuanbuaa(a)gmail.com>
Signed-off-by: WANG Siyuan <SiYuan.Wang(a)amd.com>
---
src/mainboard/amd/bettong/README | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/src/mainboard/amd/bettong/README b/src/mainboard/amd/bettong/README
new file mode 100644
index 0000000..b13c985
--- /dev/null
+++ b/src/mainboard/amd/bettong/README
@@ -0,0 +1,24 @@
+coreboot is changing all the time and the patches are reabsed when pushed to
+community, so it is a little difficult to provide stable Bettong code.
+From now on, AMD provides source code which is validated by QA team.
+The code is pushed to github https://github.com/BTDC/coreboot
+The version is identified by a tag. All the changes will be pushed to coreboot
+community.
+
+=====
+Version: TCMEF1F0:
+Changes from last version:
+1. Fix external graphics issue.
+2. Add board ID support.
+3. Support DDR4.
+4. Support SD 2.0.
+5. Fix Windows 7 S4 issue.
+6. Add GPIO, I2C and UART support.
+7. Fix the interrupt routine.
+8. Restruct PCI interrupt table (C00/C01).
+9. Fix DSDT issue.
+10. Fix the PCIe lane map.
+11. Lower the TOM to give more MMIO space.
+12. Add USB device.
+13. Set the USB3 port as unremoveable.
+14. Update AGESA to CarrizoPI 1.1.0.1.