mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-05 22:41:44 +00:00
Remove signature-based vboot support
Superseded by EC software sync (hash-based). Sig-based vboot was correctly implemented, but ended up being too slow to be useful given the limited processing power of the EC chips, and we also couldn't come up with a manageable way to handle A/B autoupdate of signed EC firmware. This change and an associated vboot_reference change shrinks the EC binary by ~2KB. BUG=chrome-os-partner:11232 TEST=build link,snow; boot link and check that 'hash' command still works. Change-Id: I3f03ae2d0a4030977826980d6ec5613181e154c2 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/29496 Reviewed-by: Bill Richardson <wfrichar@chromium.org>
This commit is contained in:
@@ -16,8 +16,6 @@
|
||||
/* Optional features */
|
||||
#define CONFIG_CONSOLE_CMDHELP
|
||||
#define CONFIG_SYSTEM_UNLOCKED /* Allow dangerous commands */
|
||||
#define CONFIG_VBOOT
|
||||
/* FIXME: This got broken. #define CONFIG_VBOOT_SIG */
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
/* compute RW firmware hash at startup */
|
||||
#define CONFIG_VBOOT
|
||||
#define CONFIG_VBOOT_HASH
|
||||
|
||||
/* Allow dangerous commands all the time, since we don't have a write protect
|
||||
* switch. */
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#define CONFIG_TMP006
|
||||
#define CONFIG_USB_CHARGE
|
||||
#define CONFIG_VBOOT
|
||||
#define CONFIG_VBOOT_HASH
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
/* compute RW firmware hash at startup */
|
||||
#define CONFIG_VBOOT
|
||||
#define CONFIG_VBOOT_HASH
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
|
||||
@@ -59,36 +59,11 @@
|
||||
#define CONFIG_SECTION_RW_OFF (CONFIG_SECTION_RO_OFF \
|
||||
+ CONFIG_SECTION_RO_SIZE)
|
||||
|
||||
#ifdef CONFIG_VBOOT_SIG
|
||||
/*
|
||||
* The top of each section will hold the vboot stuff, since the firmware vector
|
||||
* table has to go at the start. The root key will fit in 2K, but the vblocks
|
||||
* need 4K.
|
||||
*/
|
||||
#define CONFIG_VBOOT_ROOTKEY_SIZE 0x800
|
||||
#define CONFIG_VBLOCK_SIZE 0x1000
|
||||
|
||||
/* RO: firmware (+ FMAP), root keys */
|
||||
#define CONFIG_FW_RO_OFF CONFIG_SECTION_RO_OFF
|
||||
#define CONFIG_FW_RO_SIZE (CONFIG_SECTION_RO_SIZE \
|
||||
- CONFIG_VBOOT_ROOTKEY_SIZE)
|
||||
#define CONFIG_VBOOT_ROOTKEY_OFF (CONFIG_FW_RO_OFF + CONFIG_FW_RO_SIZE)
|
||||
|
||||
/* RW: firmware, vblock */
|
||||
#define CONFIG_FW_RW_OFF CONFIG_SECTION_RW_OFF
|
||||
#define CONFIG_FW_RW_SIZE (CONFIG_SECTION_RW_SIZE \
|
||||
- CONFIG_VBLOCK_SIZE)
|
||||
#define CONFIG_VBLOCK_RW_OFF (CONFIG_FW_RW_OFF + CONFIG_FW_RW_SIZE)
|
||||
|
||||
#else /* CONFIG_VBOOT_SIG */
|
||||
|
||||
#define CONFIG_FW_RO_OFF CONFIG_SECTION_RO_OFF
|
||||
#define CONFIG_FW_RO_SIZE CONFIG_SECTION_RO_SIZE
|
||||
#define CONFIG_FW_RW_OFF CONFIG_SECTION_RW_OFF
|
||||
#define CONFIG_FW_RW_SIZE CONFIG_SECTION_RW_SIZE
|
||||
|
||||
#endif /* CONFIG_VBOOT_SIG */
|
||||
|
||||
/****************************************************************************/
|
||||
/* Customize the build */
|
||||
|
||||
|
||||
@@ -239,11 +239,6 @@ void keyboard_scan_clear_boot_key(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
int keyboard_scan_recovery_pressed(void)
|
||||
{
|
||||
return boot_key_value == BOOT_KEY_ESC ? 1 : 0;
|
||||
}
|
||||
|
||||
int keyboard_scan_init(void)
|
||||
{
|
||||
/* Configure GPIO */
|
||||
@@ -279,7 +274,7 @@ int keyboard_scan_init(void)
|
||||
}
|
||||
|
||||
/* Trigger event if recovery key was pressed */
|
||||
if (keyboard_scan_recovery_pressed())
|
||||
if (boot_key_value == BOOT_KEY_ESC)
|
||||
host_set_single_event(EC_HOST_EVENT_KEYBOARD_RECOVERY);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,28 +40,15 @@ VBOOT_DEVKEYS?=/usr/share/vboot/devkeys
|
||||
CFLAGS_$(CONFIG_VBOOT)+= -DCHROMEOS_ENVIRONMENT -DCHROMEOS_EC
|
||||
# CFLAGS_$(CONFIG_VBOOT)+= -DVBOOT_DEBUG
|
||||
|
||||
common-$(CONFIG_VBOOT)+=vboot.o vboot_stub.o
|
||||
common-$(CONFIG_VBOOT_HASH)+=vboot_hash.o
|
||||
common-$(CONFIG_VBOOT_SIG)+=vboot_sig.o
|
||||
common-$(CONFIG_VBOOT)+=vboot_stub.o vboot_hash.o
|
||||
|
||||
includes-$(CONFIG_VBOOT)+= \
|
||||
$(VBOOT_SOURCE)/include \
|
||||
$(VBOOT_SOURCE)/lib/include \
|
||||
$(VBOOT_SOURCE)/lib/cryptolib/include
|
||||
|
||||
dirs-$(CONFIG_VBOOT)+= \
|
||||
vboot/lib vboot/lib/cryptolib
|
||||
dirs-$(CONFIG_VBOOT)+=vboot/lib vboot/lib/cryptolib
|
||||
|
||||
vboot-$(CONFIG_VBOOT)+= \
|
||||
lib/cryptolib/padding.o \
|
||||
lib/cryptolib/sha_utility.o \
|
||||
lib/cryptolib/sha256.o
|
||||
|
||||
vboot-$(CONFIG_VBOOT_SIG)+= \
|
||||
lib/vboot_common.o \
|
||||
lib/utility.o \
|
||||
lib/cryptolib/rsa_utility.o \
|
||||
lib/cryptolib/rsa.o \
|
||||
lib/stateful_util.o
|
||||
|
||||
sign-$(CONFIG_VBOOT_SIG)+=sign_image
|
||||
|
||||
@@ -45,11 +45,7 @@ typedef struct _FmapAreaHeader {
|
||||
uint16_t area_flags;
|
||||
} __packed FmapAreaHeader;
|
||||
|
||||
#ifdef CONFIG_VBOOT_SIG
|
||||
#define NUM_EC_FMAP_AREAS (7 + 3)
|
||||
#else
|
||||
#define NUM_EC_FMAP_AREAS 7
|
||||
#endif
|
||||
|
||||
const struct _ec_fmap {
|
||||
FmapHeader header;
|
||||
@@ -112,16 +108,8 @@ const struct _ec_fmap {
|
||||
.area_size = CONFIG_SECTION_RO_SIZE,
|
||||
.area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO,
|
||||
},
|
||||
#ifdef CONFIG_VBOOT_SIG
|
||||
{
|
||||
.area_name = "ROOT_KEY",
|
||||
.area_offset = CONFIG_VBOOT_ROOTKEY_OFF,
|
||||
.area_size = CONFIG_VBOOT_ROOTKEY_SIZE,
|
||||
.area_flags = FMAP_AREA_STATIC | FMAP_AREA_RO,
|
||||
},
|
||||
#endif
|
||||
|
||||
/* RW Firmware */
|
||||
/* RW Firmware */
|
||||
{
|
||||
/* The range of RW firmware to be auto-updated. */
|
||||
.area_name = "EC_RW",
|
||||
@@ -139,20 +127,5 @@ const struct _ec_fmap {
|
||||
.area_size = sizeof(version_data.version),
|
||||
.area_flags = FMAP_AREA_STATIC,
|
||||
},
|
||||
|
||||
#ifdef CONFIG_VBOOT_SIG
|
||||
{
|
||||
.area_name = "FW_MAIN",
|
||||
.area_offset = CONFIG_FW_RW_OFF,
|
||||
.area_size = CONFIG_FW_RW_SIZE,
|
||||
.area_flags = FMAP_AREA_STATIC,
|
||||
},
|
||||
{
|
||||
.area_name = "VBLOCK",
|
||||
.area_offset = CONFIG_VBLOCK_RW_OFF,
|
||||
.area_size = CONFIG_VBLOCK_SIZE,
|
||||
.area_flags = FMAP_AREA_STATIC,
|
||||
},
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "task.h"
|
||||
#include "timer.h"
|
||||
#include "uart.h"
|
||||
#include "vboot.h"
|
||||
#include "watchdog.h"
|
||||
|
||||
int main(void)
|
||||
@@ -115,25 +114,6 @@ int main(void)
|
||||
keyboard_scan_init();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_VBOOT_SIG
|
||||
/*
|
||||
* Verified boot signature check. This may jump to another image, which
|
||||
* will need to reconfigure / reinitialize the system, so as little as
|
||||
* possible should be done above this step.
|
||||
*
|
||||
* Note that steps above here may be done TWICE per boot, once in the
|
||||
* RO image and once in the RW image.
|
||||
*/
|
||||
vboot_check_signature();
|
||||
|
||||
/*
|
||||
* If system is locked, disable system jumps now that vboot has had its
|
||||
* chance to jump to a RW image.
|
||||
*/
|
||||
if (system_is_locked())
|
||||
system_disable_jump();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize other driver modules. These can occur in any order.
|
||||
* Non-driver modules with tasks do their inits from their task
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
/* Copyright (c) 2012 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.
|
||||
*/
|
||||
|
||||
/* Verified boot module for Chrome EC */
|
||||
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "host_command.h"
|
||||
#include "system.h"
|
||||
#include "vboot.h"
|
||||
|
||||
/* Console output macros */
|
||||
#define CPUTS(outstr) cputs(CC_VBOOT, outstr)
|
||||
#define CPRINTF(format, args...) cprintf(CC_VBOOT, format, ## args)
|
||||
|
||||
/****************************************************************************/
|
||||
/* Host commands */
|
||||
|
||||
static int host_cmd_vboot(struct host_cmd_handler_args *args)
|
||||
{
|
||||
const struct ec_params_vboot_cmd *p = args->params;
|
||||
struct ec_params_vboot_cmd *r = args->response;
|
||||
uint8_t v;
|
||||
|
||||
switch (p->in.cmd) {
|
||||
case VBOOT_CMD_GET_FLAGS:
|
||||
v = VBOOT_FLAGS_IMAGE_MASK & system_get_image_copy();
|
||||
r->out.get_flags.val = v;
|
||||
args->response_size = sizeof(r);
|
||||
break;
|
||||
case VBOOT_CMD_SET_FLAGS:
|
||||
v = p->in.set_flags.val;
|
||||
break;
|
||||
default:
|
||||
CPRINTF("[%T LB bad cmd 0x%x]\n", p->in.cmd);
|
||||
return EC_RES_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return EC_RES_SUCCESS;
|
||||
}
|
||||
|
||||
DECLARE_HOST_COMMAND(EC_CMD_VBOOT_CMD,
|
||||
host_cmd_vboot,
|
||||
EC_VER_MASK(0));
|
||||
@@ -1,163 +0,0 @@
|
||||
/* Copyright (c) 2012 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.
|
||||
*/
|
||||
|
||||
/* Verified boot module for Chrome EC */
|
||||
|
||||
#include "board.h"
|
||||
#include "config.h"
|
||||
#include "console.h"
|
||||
#include "cryptolib.h"
|
||||
#include "gpio.h"
|
||||
#include "system.h"
|
||||
#include "timer.h"
|
||||
#include "util.h"
|
||||
#include "vboot.h"
|
||||
#include "vboot_api.h"
|
||||
#include "vboot_common.h"
|
||||
#include "vboot_struct.h"
|
||||
#include "watchdog.h"
|
||||
|
||||
/* Console output macros */
|
||||
#define CPUTS(outstr) cputs(CC_VBOOT, outstr)
|
||||
#define CPRINTF(format, args...) cprintf(CC_VBOOT, format, ## args)
|
||||
|
||||
enum howgood {
|
||||
IMAGE_IS_BAD,
|
||||
IMAGE_IS_GOOD,
|
||||
IMAGE_IS_GOOD_BUT_USE_RO_ANYWAY,
|
||||
};
|
||||
|
||||
static enum howgood good_image(uint8_t *key_data,
|
||||
uint8_t *vblock_data, uint32_t vblock_size,
|
||||
uint8_t *fv_data, uint32_t fv_size) {
|
||||
VbPublicKey *sign_key;
|
||||
VbKeyBlockHeader *key_block;
|
||||
VbECPreambleHeader *preamble;
|
||||
uint32_t now = 0;
|
||||
RSAPublicKey *rsa;
|
||||
|
||||
key_block = (VbKeyBlockHeader *)vblock_data;
|
||||
sign_key = (VbPublicKey *)key_data;
|
||||
|
||||
watchdog_reload();
|
||||
if (0 != KeyBlockVerify(key_block, vblock_size, sign_key, 0)) {
|
||||
CPRINTF("[Error verifying key block]\n");
|
||||
return IMAGE_IS_BAD;
|
||||
}
|
||||
|
||||
now += key_block->key_block_size;
|
||||
rsa = PublicKeyToRSA(&key_block->data_key);
|
||||
if (!rsa) {
|
||||
CPRINTF("[Error parsing data key]\n");
|
||||
return IMAGE_IS_BAD;
|
||||
}
|
||||
|
||||
watchdog_reload();
|
||||
preamble = (VbECPreambleHeader *)(vblock_data + now);
|
||||
if (0 != VerifyECPreamble(preamble, vblock_size - now, rsa)) {
|
||||
CPRINTF("[Error verifying preamble]\n");
|
||||
RSAPublicKeyFree(rsa);
|
||||
return IMAGE_IS_BAD;
|
||||
}
|
||||
|
||||
if (preamble->flags & VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL) {
|
||||
CPRINTF("[Flags says USE_RO_NORMAL]\n");
|
||||
RSAPublicKeyFree(rsa);
|
||||
return IMAGE_IS_GOOD_BUT_USE_RO_ANYWAY;
|
||||
}
|
||||
|
||||
watchdog_reload();
|
||||
if (0 != EqualData(fv_data, fv_size, &preamble->body_digest, rsa)) {
|
||||
CPRINTF("Error verifying firmware body]\n");
|
||||
RSAPublicKeyFree(rsa);
|
||||
return IMAGE_IS_BAD;
|
||||
}
|
||||
|
||||
RSAPublicKeyFree(rsa);
|
||||
|
||||
watchdog_reload();
|
||||
CPRINTF("[Verified!]\n");
|
||||
return IMAGE_IS_GOOD;
|
||||
}
|
||||
|
||||
/* Might I want to jump to one of the RW images? */
|
||||
static int maybe_jump_to_other_image(void)
|
||||
{
|
||||
/* We'll only jump to another image if we're currently in RO */
|
||||
if (system_get_image_copy() != SYSTEM_IMAGE_RO)
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_TASK_KEYSCAN
|
||||
/* Don't jump if recovery requested */
|
||||
if (keyboard_scan_recovery_pressed()) {
|
||||
CPUTS("[Vboot staying in RO because recovery key pressed]\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Don't jump if we're in RO becuase we jumped there (this keeps us
|
||||
* from jumping to RO only to jump right back).
|
||||
*/
|
||||
if (system_jumped_to_this_image())
|
||||
return 0;
|
||||
|
||||
#if !defined(CHIP_stm32)
|
||||
/*
|
||||
* TODO: (crosbug.com/p/8572) Daisy and Snow don't define a GPIO for
|
||||
* the recovery signal from servo, so we can't check it. BDS uses the
|
||||
* DOWN button.
|
||||
*/
|
||||
if (gpio_get_level(GPIO_RECOVERYn) == 0) {
|
||||
CPUTS("[Vboot staying in RO due to recovery signal]\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Okay, we might want to jump to a RW image. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
int vboot_check_signature(void)
|
||||
{
|
||||
enum howgood r;
|
||||
timestamp_t ts1, ts2;
|
||||
|
||||
CPRINTF("[%T Vboot init]\n");
|
||||
|
||||
if (!maybe_jump_to_other_image())
|
||||
return EC_SUCCESS;
|
||||
|
||||
CPRINTF("[%T Vboot check RW image...]\n");
|
||||
|
||||
ts1 = get_time();
|
||||
r = good_image((uint8_t *)CONFIG_VBOOT_ROOTKEY_OFF,
|
||||
(uint8_t *)CONFIG_VBLOCK_RW_OFF, CONFIG_VBLOCK_SIZE,
|
||||
(uint8_t *)CONFIG_FW_RW_OFF, CONFIG_FW_RW_SIZE);
|
||||
ts2 = get_time();
|
||||
|
||||
CPRINTF("[%T Vboot result=%d, elapsed time=%ld us]\n",
|
||||
r, ts2.val - ts1.val);
|
||||
|
||||
switch (r) {
|
||||
case IMAGE_IS_GOOD:
|
||||
CPRINTF("[RW image verified]\n");
|
||||
system_run_image_copy(SYSTEM_IMAGE_RW);
|
||||
CPRINTF("[ERROR: Unable to jump to RW image]\n");
|
||||
goto bad;
|
||||
case IMAGE_IS_GOOD_BUT_USE_RO_ANYWAY:
|
||||
CPRINTF("[RW image verified]\n");
|
||||
CPRINTF("[Staying in RO mode]\n");
|
||||
return EC_SUCCESS;
|
||||
default:
|
||||
CPRINTF("[RW image is invalid]\n");
|
||||
}
|
||||
|
||||
bad:
|
||||
CPRINTF("[Staying in RO mode]\n");
|
||||
CPRINTF("[FIXME: How to trigger recovery mode?]\n");
|
||||
return EC_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
@@ -6,24 +6,9 @@
|
||||
/* Functions needed by vboot library */
|
||||
|
||||
#define _STUB_IMPLEMENTATION_
|
||||
#include "console.h"
|
||||
#include "shared_mem.h"
|
||||
#include "util.h"
|
||||
#include "utility.h"
|
||||
|
||||
/* Console output macros */
|
||||
#define CPUTS(outstr) cputs(CC_VBOOT, outstr)
|
||||
#define CPRINTF(format, args...) cprintf(CC_VBOOT, format, ## args)
|
||||
|
||||
#if 0 /* change this to debug memory usage */
|
||||
#define DPRINTF CPRINTF
|
||||
#else
|
||||
#define DPRINTF(...)
|
||||
#endif
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void *Memcpy(void *dest, const void *src, uint64_t n)
|
||||
{
|
||||
return memcpy(dest, src, (size_t)n);
|
||||
@@ -33,137 +18,3 @@ void *Memset(void *d, const uint8_t c, uint64_t n)
|
||||
{
|
||||
return memset(d, c, n);
|
||||
}
|
||||
|
||||
int Memcmp(const void *src1, const void *src2, size_t n)
|
||||
{
|
||||
size_t i;
|
||||
const uint8_t *a = src1;
|
||||
const uint8_t *b = src2;
|
||||
for (i = 0; i < n; i++) {
|
||||
if (*a != *b)
|
||||
return (*a < *b) ? -1 : 1;
|
||||
a++;
|
||||
b++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* The vboot_api library requires some dynamic memory, but we don't have
|
||||
* malloc/free. Instead we have one chunk of shared RAM that we can gain
|
||||
* exclusive access to for a time. We'll have to experiment with various
|
||||
* algorithms to see what works best. This algorithm allocates and
|
||||
* reuses blocks, but never actually frees anything until all memory has been
|
||||
* reclaimed. */
|
||||
|
||||
/* Since we only need this stuff to boot, don't waste run-time .bss */
|
||||
static struct {
|
||||
int bucket_size; /* total RAM available */
|
||||
uint8_t *out_base; /* malloc from here */
|
||||
int out_count; /* number of active mallocs */
|
||||
int out_size; /* high-water mark */
|
||||
|
||||
/* We have a limited number of active mallocs. We never free, but we
|
||||
* do reuse slots. */
|
||||
#define MAX_SLOTS 8
|
||||
struct {
|
||||
int in_use; /* is this slot active? */
|
||||
void *ptr; /* starts here */
|
||||
size_t size; /* how big */
|
||||
} slots[MAX_SLOTS];
|
||||
} *bucket;
|
||||
|
||||
|
||||
void *VbExMalloc(size_t size)
|
||||
{
|
||||
int i, j;
|
||||
void *ptr = 0;
|
||||
|
||||
if (!bucket) {
|
||||
i = shared_mem_size();
|
||||
if (EC_SUCCESS != shared_mem_acquire(i, 1, (char **)&bucket)) {
|
||||
CPRINTF("FAILED at %s:%d\n", __FILE__, __LINE__);
|
||||
ASSERT(0);
|
||||
}
|
||||
Memset(bucket, 0, sizeof(*bucket));
|
||||
bucket->bucket_size = i;
|
||||
bucket->out_base = (uint8_t *)(bucket + 1);
|
||||
bucket->out_size = sizeof(*bucket);
|
||||
DPRINTF("grab the bucket: at 0x%x, size 0x%x\n",
|
||||
bucket, bucket->bucket_size);
|
||||
}
|
||||
|
||||
if (size % 8) {
|
||||
size_t tmp = (size + 8) & ~0x7ULL;
|
||||
DPRINTF(" %d -> %d\n", size, tmp);
|
||||
ASSERT(tmp >= size);
|
||||
size = tmp;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_SLOTS; i++) {
|
||||
if (!bucket->slots[i].in_use) {
|
||||
|
||||
/* Found an empty one, but reuse the same size if one
|
||||
* already exists. */
|
||||
for (j = i; j < MAX_SLOTS; j++) {
|
||||
if (!bucket->slots[j].in_use &&
|
||||
size == bucket->slots[j].size) {
|
||||
/* empty AND same size */
|
||||
bucket->slots[j].in_use = 1;
|
||||
ptr = bucket->slots[j].ptr;
|
||||
DPRINTF(" = %d (%d)\n", j, size);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* no exact matches, must allocate a new chunk */
|
||||
ptr = bucket->out_base + bucket->out_size;
|
||||
bucket->out_size += size;
|
||||
|
||||
bucket->slots[i].in_use = 1;
|
||||
bucket->slots[i].ptr = ptr;
|
||||
bucket->slots[i].size = size;
|
||||
DPRINTF(" + %d (%d)\n", i, size);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
CPRINTF("FAILED: no empty slots (%d/%d)\n", i, MAX_SLOTS);
|
||||
ASSERT(0);
|
||||
|
||||
out:
|
||||
bucket->out_count++;
|
||||
if (bucket->out_size >= bucket->bucket_size) {
|
||||
CPRINTF("FAILED: out of memory (%d/%d)\n",
|
||||
bucket->out_size, bucket->bucket_size);
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
void VbExFree(void *ptr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_SLOTS; i++) {
|
||||
if (ptr == bucket->slots[i].ptr) {
|
||||
bucket->slots[i].in_use = 0;
|
||||
DPRINTF(" - %d (%d)\n", i, bucket->slots[i].size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (MAX_SLOTS == i) {
|
||||
CPRINTF("FAILED: can't find ptr %x!\n", ptr);
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
bucket->out_count--;
|
||||
if (!bucket->out_count) {
|
||||
DPRINTF("dump the bucket: max used = %d\n", bucket->out_size);
|
||||
shared_mem_release(bucket);
|
||||
bucket = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -623,34 +623,9 @@ struct ec_params_lightbar_cmd {
|
||||
/* Verified boot commands */
|
||||
|
||||
/*
|
||||
* Verified boot uber-command. Details still evolving. Like the lightbar
|
||||
* command above, this takes sub-commands.
|
||||
* Note: command code 0x29 version 0 was VBOOT_CMD in Link EVT; it may be
|
||||
* reused for other purposes with version > 0.
|
||||
*/
|
||||
#define EC_CMD_VBOOT_CMD 0x29
|
||||
|
||||
struct ec_params_vboot_cmd {
|
||||
union {
|
||||
union {
|
||||
uint8_t cmd;
|
||||
struct {
|
||||
uint8_t cmd;
|
||||
/* no inputs */
|
||||
} get_flags;
|
||||
struct {
|
||||
uint8_t cmd;
|
||||
uint8_t val;
|
||||
} set_flags;
|
||||
} in;
|
||||
union {
|
||||
struct {
|
||||
uint8_t val;
|
||||
} get_flags;
|
||||
struct {
|
||||
/* no outputs */
|
||||
} set_flags;
|
||||
} out;
|
||||
};
|
||||
} __packed;
|
||||
|
||||
/* Verified boot hash command */
|
||||
#define EC_CMD_VBOOT_HASH 0x2A
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/* Copyright (c) 2012 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.
|
||||
*/
|
||||
|
||||
/* Verified boot module for Chrome EC */
|
||||
|
||||
#ifndef __CROS_EC_VBOOT_H
|
||||
#define __CROS_EC_VBOOT_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/*
|
||||
* Check verified boot signatures, and jump to one of the RW images if
|
||||
* necessary.
|
||||
*/
|
||||
int vboot_check_signature(void);
|
||||
|
||||
/* Initialize the module. */
|
||||
int vboot_init(void);
|
||||
|
||||
/* These are the vboot commands available via LPC. */
|
||||
enum vboot_command {
|
||||
VBOOT_CMD_GET_FLAGS,
|
||||
VBOOT_CMD_SET_FLAGS,
|
||||
VBOOT_NUM_CMDS,
|
||||
};
|
||||
|
||||
/*
|
||||
* These are the flags transferred across LPC. At the moment, only the devmode
|
||||
* flag can be set, and only because it's faked. Ultimately this functionality
|
||||
* will be moved elsewhere.
|
||||
*/
|
||||
#define VBOOT_FLAGS_IMAGE_MASK 0x03 /* enum system_image_copy_t */
|
||||
#define VBOOT_FLAGS_UNUSED 0x04 /* was fake dev-mode bit */
|
||||
|
||||
#endif /* __CROS_EC_VBOOT_H */
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "battery.h"
|
||||
#include "comm-host.h"
|
||||
#include "lightbar.h"
|
||||
#include "vboot.h"
|
||||
|
||||
/* Handy tricks */
|
||||
#define BUILD_ASSERT(cond) ((void)sizeof(char[1 - 2*!(cond)]))
|
||||
@@ -117,8 +116,6 @@ const char help_str[] =
|
||||
" Set the threshold temperature value for thermal engine.\n"
|
||||
" usbchargemode <port> <mode>\n"
|
||||
" Set USB charging mode\n"
|
||||
" vboot [VAL]\n"
|
||||
" Get or set vboot flags\n"
|
||||
" version\n"
|
||||
" Prints EC version\n"
|
||||
" wireless <mask>\n"
|
||||
@@ -1165,61 +1162,6 @@ static int cmd_lightbar(int argc, char **argv)
|
||||
}
|
||||
|
||||
|
||||
/* This needs to match the values defined in vboot.h. I'd like to
|
||||
* define this in one and only one place, but I can't think of a good way to do
|
||||
* that without adding bunch of complexity. This will do for now.
|
||||
*/
|
||||
static const struct {
|
||||
uint8_t insize;
|
||||
uint8_t outsize;
|
||||
} vb_command_paramcount[] = {
|
||||
{ sizeof(((struct ec_params_vboot_cmd *)0)->in.get_flags),
|
||||
sizeof(((struct ec_params_vboot_cmd *)0)->out.get_flags) },
|
||||
{ sizeof(((struct ec_params_vboot_cmd *)0)->in.set_flags),
|
||||
sizeof(((struct ec_params_vboot_cmd *)0)->out.set_flags) },
|
||||
};
|
||||
|
||||
static int cmd_vboot(int argc, char **argv)
|
||||
{
|
||||
int rv;
|
||||
uint8_t v;
|
||||
char *e;
|
||||
struct ec_params_vboot_cmd param;
|
||||
|
||||
if (argc == 1) { /* no args = get */
|
||||
param.in.cmd = VBOOT_CMD_GET_FLAGS;
|
||||
rv = ec_command(EC_CMD_VBOOT_CMD, 0,
|
||||
¶m,
|
||||
vb_command_paramcount[param.in.cmd].insize,
|
||||
¶m,
|
||||
vb_command_paramcount[param.in.cmd].outsize);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
v = param.out.get_flags.val;
|
||||
printf("0x%02x image=%s\n", v,
|
||||
image_names[VBOOT_FLAGS_IMAGE_MASK & v]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* else args => set values */
|
||||
|
||||
v = strtoul(argv[1], &e, 16) & 0xff;
|
||||
if (e && *e) {
|
||||
fprintf(stderr, "Bad value\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
param.in.cmd = VBOOT_CMD_SET_FLAGS;
|
||||
param.in.set_flags.val = v;
|
||||
rv = ec_command(EC_CMD_VBOOT_CMD, 0,
|
||||
¶m,
|
||||
vb_command_paramcount[param.in.cmd].insize,
|
||||
¶m,
|
||||
vb_command_paramcount[param.in.cmd].outsize);
|
||||
return (rv < 0 ? rv : 0);
|
||||
}
|
||||
|
||||
int cmd_usb_charge_set_mode(int argc, char *argv[])
|
||||
{
|
||||
struct ec_params_usb_charge_set_mode p;
|
||||
@@ -2125,7 +2067,6 @@ const struct command commands[] = {
|
||||
{"i2cread", cmd_i2c_read},
|
||||
{"i2cwrite", cmd_i2c_write},
|
||||
{"lightbar", cmd_lightbar},
|
||||
{"vboot", cmd_vboot},
|
||||
{"pstoreinfo", cmd_pstore_info},
|
||||
{"pstoreread", cmd_pstore_read},
|
||||
{"pstorewrite", cmd_pstore_write},
|
||||
@@ -2153,7 +2094,6 @@ int main(int argc, char *argv[])
|
||||
const struct command *cmd;
|
||||
|
||||
BUILD_ASSERT(ARRAY_SIZE(lb_command_paramcount) == LIGHTBAR_NUM_CMDS);
|
||||
BUILD_ASSERT(ARRAY_SIZE(vb_command_paramcount) == VBOOT_NUM_CMDS);
|
||||
|
||||
if (argc < 2 || !strcasecmp(argv[1], "-?") ||
|
||||
!strcasecmp(argv[1], "help")) {
|
||||
|
||||
Reference in New Issue
Block a user