mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-11 10:25:20 +00:00
Add LPC command to handle vboot stuff.
This adds "ectool vboot", which works like so: # ./ectool vboot 0x06 image=A fake_dev=1 # ./ectool vboot 0 # ./ectool vboot 0x02 image=A fake_dev=0 # ./ectool vboot ff # ./ectool vboot 0x06 image=A fake_dev=1 You can set or unset the fake dev-switch, and see which firmware image the EC is running from. BUG=chrome-os-partner:8313 TEST=manual Boot the host, use crossystem to see the devsw_boot state. Change it with the ectool command, reboot, see that it's changed. Change-Id: Iaac40267338c6a07bc47b80e925e829bf1e1ae0c Signed-off-by: Bill Richardson <wfrichar@chromium.org>
This commit is contained in:
@@ -7,7 +7,9 @@
|
||||
|
||||
#include "console.h"
|
||||
#include "cryptolib.h"
|
||||
#include "eoption.h"
|
||||
#include "gpio.h"
|
||||
#include "host_command.h"
|
||||
#include "keyboard_scan.h"
|
||||
#include "system.h"
|
||||
#include "timer.h"
|
||||
@@ -197,3 +199,45 @@ bad:
|
||||
CPRINTF("[FIXME: How to trigger recovery mode?]\n");
|
||||
return EC_ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* Host commands via LPC bus */
|
||||
/****************************************************************************/
|
||||
|
||||
static int host_cmd_vboot(uint8_t *data, int *resp_size)
|
||||
{
|
||||
struct ec_params_vboot_cmd *ptr =
|
||||
(struct ec_params_vboot_cmd *)data;
|
||||
uint8_t v;
|
||||
|
||||
switch (ptr->in.cmd) {
|
||||
case VBOOT_CMD_GET_FLAGS:
|
||||
v = VBOOT_FLAGS_IMAGE_MASK & system_get_image_copy();
|
||||
#ifdef CONFIG_FAKE_DEV_SWITCH
|
||||
if (eoption_get_bool(EOPTION_BOOL_FAKE_DEV))
|
||||
v |= VBOOT_FLAGS_FAKE_DEVMODE;
|
||||
#endif
|
||||
ptr->out.get_flags.val = v;
|
||||
*resp_size = sizeof(struct ec_params_vboot_cmd);
|
||||
break;
|
||||
case VBOOT_CMD_SET_FLAGS:
|
||||
v = ptr->in.set_flags.val;
|
||||
#ifdef CONFIG_FAKE_DEV_SWITCH
|
||||
if (v & VBOOT_FLAGS_FAKE_DEVMODE) {
|
||||
eoption_set_bool(EOPTION_BOOL_FAKE_DEV, 1);
|
||||
CPUTS("[Enabling fake dev-mode]\n");
|
||||
} else {
|
||||
eoption_set_bool(EOPTION_BOOL_FAKE_DEV, 0);
|
||||
CPUTS("[Disabling fake dev-mode]\n");
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
CPRINTF("[%T LB bad cmd 0x%x]\n", ptr->in.cmd);
|
||||
return EC_RES_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return EC_RES_SUCCESS;
|
||||
}
|
||||
|
||||
DECLARE_HOST_COMMAND(EC_CMD_VBOOT_CMD, host_cmd_vboot);
|
||||
|
||||
@@ -417,6 +417,33 @@ struct ec_params_lightbar_cmd {
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Verified boot commands. Details still evolving. */
|
||||
#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;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/*****************************************************************************/
|
||||
/* USB charging control commands */
|
||||
|
||||
|
||||
@@ -17,4 +17,17 @@ int vboot_pre_init(void);
|
||||
/* Initializes 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_FAKE_DEVMODE 0x04 /* fake dev-mode bit */
|
||||
|
||||
#endif /* __CROS_EC_VBOOT_H */
|
||||
|
||||
@@ -12,8 +12,10 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "battery.h"
|
||||
#include "lightbar.h"
|
||||
#include "ec_commands.h"
|
||||
#include "lightbar.h"
|
||||
#include "system.h"
|
||||
#include "vboot.h"
|
||||
|
||||
/* Handy tricks */
|
||||
#define BUILD_ASSERT(cond) ((void)sizeof(char[1 - 2*!(cond)]))
|
||||
@@ -54,10 +56,12 @@ const char help_str[] =
|
||||
" Erases EC flash\n"
|
||||
" hello\n"
|
||||
" Checks for basic communication with EC\n"
|
||||
" lightbar reset\n"
|
||||
" Puts the lightbar into idle mode\n"
|
||||
" lightbar test [NUM]\n"
|
||||
" Cycles lights once. Optional argument does nothing.\n"
|
||||
" lightbar [CMDS]\n"
|
||||
" Various lightbar control commands\n"
|
||||
" vboot get\n"
|
||||
" Get vboot flags\n"
|
||||
" vboot set VAL\n"
|
||||
" Set vboot flags\n"
|
||||
" pstoreinfo\n"
|
||||
" Prints information on the EC host persistent storage\n"
|
||||
" pstoreread <offset> <size> <outfile>\n"
|
||||
@@ -1031,6 +1035,66 @@ static int cmd_lightbar(int argc, char **argv)
|
||||
return lb_help(argv[0]);
|
||||
}
|
||||
|
||||
|
||||
/* 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) },
|
||||
};
|
||||
|
||||
/* Note: depends on enum system_image_copy_t */
|
||||
static const char * const image_names[] = {"unknown", "RO", "A", "B"};
|
||||
|
||||
static int cmd_vboot(int argc, char **argv)
|
||||
{
|
||||
int r;
|
||||
uint8_t v;
|
||||
char *e;
|
||||
struct ec_params_vboot_cmd param;
|
||||
|
||||
if (argc == 1) { /* no args = get */
|
||||
param.in.cmd = VBOOT_CMD_GET_FLAGS;
|
||||
r = ec_command(EC_CMD_VBOOT_CMD,
|
||||
¶m,
|
||||
vb_command_paramcount[param.in.cmd].insize,
|
||||
¶m,
|
||||
vb_command_paramcount[param.in.cmd].outsize);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
v = param.out.get_flags.val;
|
||||
printf("0x%02x image=%s fake_dev=%d\n", v,
|
||||
image_names[VBOOT_FLAGS_IMAGE_MASK & v],
|
||||
VBOOT_FLAGS_FAKE_DEVMODE & v ? 1 : 0);
|
||||
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;
|
||||
r = ec_command(EC_CMD_VBOOT_CMD,
|
||||
¶m,
|
||||
vb_command_paramcount[param.in.cmd].insize,
|
||||
¶m,
|
||||
vb_command_paramcount[param.in.cmd].outsize);
|
||||
return r;
|
||||
}
|
||||
|
||||
int cmd_usb_charge_set_mode(int argc, char *argv[])
|
||||
{
|
||||
struct ec_params_usb_charge_set_mode p;
|
||||
@@ -1482,6 +1546,7 @@ const struct command commands[] = {
|
||||
{"flashinfo", cmd_flash_info},
|
||||
{"hello", cmd_hello},
|
||||
{"lightbar", cmd_lightbar},
|
||||
{"vboot", cmd_vboot},
|
||||
{"pstoreinfo", cmd_pstore_info},
|
||||
{"pstoreread", cmd_pstore_read},
|
||||
{"pstorewrite", cmd_pstore_write},
|
||||
@@ -1509,6 +1574,7 @@ 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