diff options
author | Daisuke Nojiri <dnojiri@chromium.org> | 2016-05-04 14:55:57 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-05-07 03:32:47 -0700 |
commit | 85dbb3442011e6d5b69da54c46f11d59c9172784 (patch) | |
tree | a722d6a20b82ee22eec8b1ce295f116d281404a8 /firmware/bdb | |
parent | 8917b808ce4b4cda9b8e52c7ff8bb04e7836479b (diff) | |
download | vboot-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.h | 4 | ||||
-rw-r--r-- | firmware/bdb/bdb_api.h | 68 | ||||
-rw-r--r-- | firmware/bdb/misc.c | 124 | ||||
-rw-r--r-- | firmware/bdb/stub.c | 24 |
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; +} |