mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-24 18:25:10 +00:00
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>
125 lines
3.0 KiB
C
125 lines
3.0 KiB
C
/* 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();
|
|
}
|