summaryrefslogtreecommitdiff
path: root/firmware/bdb
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2016-05-04 14:55:57 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-05-07 03:32:47 -0700
commit85dbb3442011e6d5b69da54c46f11d59c9172784 (patch)
treea722d6a20b82ee22eec8b1ce295f116d281404a8 /firmware/bdb
parent8917b808ce4b4cda9b8e52c7ff8bb04e7836479b (diff)
downloadvboot-85dbb3442011e6d5b69da54c46f11d59c9172784.tar.gz
bdb: Add vba_bdb_init
vba_bdb_init initializes the vboot context and decides what to do next based on the vboot register content. Possible actions are: 1. proceed to verify the current slot 2. reset to try the other slot 3. reset to recovery mode bdb_sprw_test demonstrates these actions. BUG=chrome-os-partner:51907 BRANCH=tot TEST=make runtests Change-Id: If72cdd575d09b9162a871f088064ca853b7fd74d Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/342604 Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'firmware/bdb')
-rw-r--r--firmware/bdb/bdb.h4
-rw-r--r--firmware/bdb/bdb_api.h68
-rw-r--r--firmware/bdb/misc.c124
-rw-r--r--firmware/bdb/stub.c24
4 files changed, 220 insertions, 0 deletions
diff --git a/firmware/bdb/bdb.h b/firmware/bdb/bdb.h
index 91834913..30ecc17c 100644
--- a/firmware/bdb/bdb.h
+++ b/firmware/bdb/bdb.h
@@ -68,6 +68,10 @@ enum bdb_return_code {
/* Other errors in bdb_verify() */
BDB_ERROR_DIGEST, /* Error calculating digest */
BDB_ERROR_VERIFY_SIG, /* Error verifying signature */
+
+ /* Errors in vba_bdb_init */
+ BDB_ERROR_TRY_OTHER_SLOT,
+ BDB_ERROR_RECOVERY_REQUEST,
};
/*****************************************************************************/
diff --git a/firmware/bdb/bdb_api.h b/firmware/bdb/bdb_api.h
new file mode 100644
index 00000000..53823fae
--- /dev/null
+++ b/firmware/bdb/bdb_api.h
@@ -0,0 +1,68 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef VBOOT_REFERENCE_FIRMWARE_BDB_BDB_API_H
+#define VBOOT_REFERENCE_FIRMWARE_BDB_BDB_API_H
+
+#include <stdint.h>
+#include "vboot_register.h"
+
+struct vba_context {
+ /* Indicate which slot is being tried: 0 - primary, 1 - secondary */
+ uint8_t slot;
+};
+
+/**
+ * Initialize vboot process
+ *
+ * @param ctx
+ * @return enum bdb_return_code
+ */
+int vba_bdb_init(struct vba_context *ctx);
+
+/**
+ * Finalize vboot process
+ *
+ * @param ctx
+ * @return enum bdb_return_code
+ */
+int vba_bdb_finalize(struct vba_context *ctx);
+
+/**
+ * Log failed boot attempt and reset the chip
+ *
+ * @param ctx
+ */
+void vba_bdb_fail(struct vba_context *ctx);
+
+/**
+ * Get vboot register value
+ *
+ * Implemented by each chip
+ *
+ * @param type Type of register to get
+ * @return Register value
+ */
+uint32_t vbe_get_vboot_register(enum vboot_register type);
+
+/**
+ * Set vboot register value
+ *
+ * Implemented by each chip
+ *
+ * @param type Type of register to set
+ * @param val Value to set
+ */
+void vbe_set_vboot_register(enum vboot_register type, uint32_t val);
+
+/**
+ * Reset the SoC
+ *
+ * Implemented by each chip. This is different from reboot (a.k.a. board reset,
+ * cold reset).
+ */
+void vbe_reset(void);
+
+#endif
diff --git a/firmware/bdb/misc.c b/firmware/bdb/misc.c
new file mode 100644
index 00000000..fd3e0c9b
--- /dev/null
+++ b/firmware/bdb/misc.c
@@ -0,0 +1,124 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <stdint.h>
+#include "bdb.h"
+#include "bdb_api.h"
+#include "vboot_register.h"
+
+static int did_current_slot_fail(struct vba_context *ctx)
+{
+ uint32_t val = vbe_get_vboot_register(VBOOT_REGISTER_PERSIST);
+
+ if (ctx->slot)
+ return val & VBOOT_REGISTER_FAILED_RW_SECONDARY;
+ else
+ return val & VBOOT_REGISTER_FAILED_RW_PRIMARY;
+}
+
+static int did_other_slot_fail(struct vba_context *ctx)
+{
+ uint32_t val = vbe_get_vboot_register(VBOOT_REGISTER_PERSIST);
+
+ if (ctx->slot)
+ return val & VBOOT_REGISTER_FAILED_RW_PRIMARY;
+ else
+ return val & VBOOT_REGISTER_FAILED_RW_SECONDARY;
+}
+
+static void set_try_other_slot(struct vba_context *ctx)
+{
+ uint32_t val = vbe_get_vboot_register(VBOOT_REGISTER_PERSIST);
+
+ if (ctx->slot)
+ val &= ~VBOOT_REGISTER_TRY_SECONDARY_BDB;
+ else
+ val |= VBOOT_REGISTER_TRY_SECONDARY_BDB;
+
+ vbe_set_vboot_register(VBOOT_REGISTER_PERSIST, val);
+}
+
+static void set_recovery_request(struct vba_context *ctx)
+{
+ uint32_t val = vbe_get_vboot_register(VBOOT_REGISTER_PERSIST);
+
+ val |= VBOOT_REGISTER_RECOVERY_REQUEST;
+
+ vbe_set_vboot_register(VBOOT_REGISTER_PERSIST, val);
+}
+
+static void get_current_slot(struct vba_context *ctx)
+{
+ /* Assume SP-RO selects slot this way */
+ ctx->slot = (vbe_get_vboot_register(VBOOT_REGISTER_PERSIST)
+ & VBOOT_REGISTER_TRY_SECONDARY_BDB) ? 1 : 0;
+}
+
+static void set_current_slot_failed(struct vba_context *ctx)
+{
+ uint32_t val = vbe_get_vboot_register(VBOOT_REGISTER_PERSIST);
+
+ if (ctx->slot)
+ val |= VBOOT_REGISTER_FAILED_RW_SECONDARY;
+ else
+ val |= VBOOT_REGISTER_FAILED_RW_PRIMARY;
+
+ vbe_set_vboot_register(VBOOT_REGISTER_PERSIST, val);
+}
+
+static void unset_current_slot_failed(struct vba_context *ctx)
+{
+ uint32_t val = vbe_get_vboot_register(VBOOT_REGISTER_PERSIST);
+
+ if (ctx->slot)
+ val &= ~VBOOT_REGISTER_FAILED_RW_SECONDARY;
+ else
+ val &= ~VBOOT_REGISTER_FAILED_RW_PRIMARY;
+
+ vbe_set_vboot_register(VBOOT_REGISTER_PERSIST, val);
+}
+
+int vba_bdb_init(struct vba_context *ctx)
+{
+ /* Get current slot */
+ get_current_slot(ctx);
+
+ /* Check current slot failed or not at the last boot */
+ if (!did_current_slot_fail(ctx)) {
+ /* If not, we try this slot. Prepare for any accidents */
+ set_current_slot_failed(ctx);
+ return BDB_SUCCESS;
+ }
+
+ /* Check other slot failed or not at the previous boot */
+ if (!did_other_slot_fail(ctx)) {
+ /* If not, we try the other slot after reboot. */
+ set_try_other_slot(ctx);
+ return BDB_ERROR_TRY_OTHER_SLOT;
+ } else {
+ /* Otherwise, both slots are bad. Reboot to recovery */
+ set_recovery_request(ctx);
+ return BDB_ERROR_RECOVERY_REQUEST;
+ }
+}
+
+int vba_bdb_finalize(struct vba_context *ctx)
+{
+ /* Mark the current slot good */
+ unset_current_slot_failed(ctx);
+
+ /* Disable NVM bus */
+
+ return BDB_SUCCESS;
+}
+
+void vba_bdb_fail(struct vba_context *ctx)
+{
+ /* We can do some logging here if we want */
+
+ /* Unconditionally reboot. FailedRW flag is already set.
+ * At the next boot, bdb_init will decide what to do. */
+ vbe_reset();
+}
diff --git a/firmware/bdb/stub.c b/firmware/bdb/stub.c
new file mode 100644
index 00000000..87efbc33
--- /dev/null
+++ b/firmware/bdb/stub.c
@@ -0,0 +1,24 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "bdb_api.h"
+
+__attribute__((weak))
+uint32_t vbe_get_vboot_register(enum vboot_register type)
+{
+ return 0;
+}
+
+__attribute__((weak))
+void vbe_set_vboot_register(enum vboot_register type, uint32_t val)
+{
+ return;
+}
+
+__attribute__((weak))
+void vbe_reset(void)
+{
+ return;
+}