From bf931b2cced0fac2f2810999ac672a3344b0849b Mon Sep 17 00:00:00 2001 From: Sheng-Liang Song Date: Sun, 15 Mar 2015 21:51:18 -0700 Subject: sb_firmware: update arguments and configs - Updated arguments to support two sub commands: - check: check if AC adapter is connect. - update: trigger battery firmware update. - All Delay values are from .cfg file. BUG=chrome-os-partner:36310 BRANCH=none CQ-DEPEND=CL:260868 TEST=Verified on Glimmer. crosh> battery_firmware check crosh> battery_firmware update Change-Id: I7324e1f329383cf5ee62660f4ac4cb0b1c30c056 Signed-off-by: Sheng-Liang Song Reviewed-on: https://chromium-review.googlesource.com/260210 Reviewed-by: Shawn N --- util/ec_sb_firmware_update.c | 151 ++++++++++++++++++++++++++++++------------- 1 file changed, 106 insertions(+), 45 deletions(-) diff --git a/util/ec_sb_firmware_update.c b/util/ec_sb_firmware_update.c index 0d8edb3c0b..3e1d51a205 100644 --- a/util/ec_sb_firmware_update.c +++ b/util/ec_sb_firmware_update.c @@ -8,34 +8,43 @@ #include #include #include +#include -#include "lock/gec_lock.h" #include "comm-host.h" -#include "misc_util.h" #include "ec_sb_firmware_update.h" #include "ec_commands.h" -#include +#include "lock/gec_lock.h" +#include "misc_util.h" +#include "powerd_lock.h" +/* Subcommands: [check|update] */ enum { - BEGIN_DELAY = 0, - SETUP_DELAY = 1, - WRITE_DELAY = 2, - END_DELAY = 3, - NUM_DELAYS = 4 + OP_UNKNOWN = 0, + OP_CHECK = 1, + OP_UPDATE = 2, }; +#define SETUP_DELAY_STEPS 11 +#define WRITE_DELAY_STEPS (SETUP_DELAY_STEPS+512) + +/* Delay Configure Indexes */ enum { - F_AC_PRESENT = 1,/* AC Present */ - F_VERSION_CHECK = 2 /* do firmware version check */ + BEGIN_DELAY = 0, + SETUP_DELAY = 1, + WRITE1_DELAY = 2, + WRITE2_DELAY = 3, + END_DELAY = 4, + NUM_DELAYS = 5 }; const char *delay_names[NUM_DELAYS] = { - "BEGIN", - "SETUP", - "WRITE", - "END" + [BEGIN_DELAY] = "BEGIN", + [SETUP_DELAY] = "SETUP", + [WRITE1_DELAY] = "WRITE1", + [WRITE2_DELAY] = "WRITE2", + [END_DELAY] = "END" }; -uint32_t delay_values[NUM_DELAYS]; +static uint32_t delay_values[NUM_DELAYS]; enum fw_update_state { S0_READ_STATUS = 0, @@ -52,6 +61,16 @@ enum fw_update_state { }; #define MAX_FW_IMAGE_NAME_SIZE 80 + +/* Firmware Update Control Flags */ +enum { + F_AC_PRESENT = 0x1, /* AC Present */ + F_VERSION_CHECK = 0x2, /* do firmware version check */ + F_UPDATE = 0x4, /* do firmware update */ + F_NEED_UPDATE = 0x8, /* need firmware update */ + F_POWERD_DISABLED = 0x10 /* powerd is disabled */ +}; + struct fw_update_ctrl { uint32_t flags; /* fw update control flags */ int size; /* size of battery firmware image */ @@ -82,11 +101,6 @@ static int get_key_value(const char *filename, int i = BEGIN_DELAY; FILE *fp = fopen(filename, "r"); - values[BEGIN_DELAY] = 500000; - values[SETUP_DELAY] = 9000000; - values[WRITE_DELAY] = 500000; - values[END_DELAY] = 1000000; - if (fp == NULL) return -1; @@ -95,7 +109,8 @@ static int get_key_value(const char *filename, continue; sprintf(cmd, "%s=%%d", keys[i]); - sscanf(line, cmd, &values[i]); + if (0 == values[i]) + sscanf(line, cmd, &values[i]); if (++i == NUM_DELAYS) break; @@ -328,19 +343,21 @@ static int send_subcmd(int subcmd) return EC_RES_SUCCESS; } -static int write_block(const uint8_t *ptr, int bsize) +static int write_block(struct fw_update_ctrl *fw_update, + int offset, int bsize) { int rv; struct ec_params_sb_fw_update *param = (struct ec_params_sb_fw_update *)ec_outbuf; - memcpy(param->write.data, ptr, bsize); + memcpy(param->write.data, fw_update->ptr+offset, bsize); param->hdr.subcmd = EC_SB_FW_UPDATE_WRITE; rv = ec_command(EC_CMD_SB_FW_UPDATE, 0, param, sizeof(struct ec_params_sb_fw_update), NULL, 0); if (rv < 0) { - printf("Firmware Update Write Error offset@%p\n", ptr); + printf("Firmware Update Write Error ptr:%p offset@%x\n", + fw_update->ptr, offset); return -EC_RES_ERROR; } return EC_RES_SUCCESS; @@ -438,7 +455,7 @@ static enum fw_update_state s1_read_battery_info( rv = check_if_valid_fw(fw_update->fw_img_hdr, &fw_update->info); if (rv == 0) { - fw_update->rv = EC_RES_INVALID_PARAM; + fw_update->rv = -EC_RES_INVALID_PARAM; log_msg(fw_update, S1_READ_INFO, "Invalid Firmware"); return S10_TERMINAL; } @@ -450,6 +467,13 @@ static enum fw_update_state s1_read_battery_info( return S10_TERMINAL; } + fw_update->flags |= F_NEED_UPDATE; + + if (!(fw_update->flags & F_UPDATE)) { + fw_update->rv = 0; + return S10_TERMINAL; + } + if (!(fw_update->flags & F_AC_PRESENT)) { fw_update->rv = 0; log_msg(fw_update, S1_READ_INFO, @@ -462,6 +486,14 @@ static enum fw_update_state s1_read_battery_info( static enum fw_update_state s2_write_prepare(struct fw_update_ctrl *fw_update) { int rv; + rv = disable_power_management(); + if (rv) { + fw_update->rv = -1; + log_msg(fw_update, S2_WRITE_PREPARE, + "disable power management error"); + return S10_TERMINAL; + } + fw_update->flags |= F_POWERD_DISABLED; rv = send_subcmd(EC_SB_FW_UPDATE_PREPARE); if (rv) { fw_update->rv = -1; @@ -537,17 +569,19 @@ static enum fw_update_state s6_write_block(struct fw_update_ctrl *fw_update) } fw_update->fec_err_retry_cnt--; - rv = write_block(fw_update->ptr+offset, bsize); + rv = write_block(fw_update, offset, bsize); if (rv) { fw_update->rv = -1; log_msg(fw_update, S6_WRITE_BLOCK, "Interface Error"); return S10_TERMINAL; } - if (offset <= fw_update->step_size * 10) + if (offset < (fw_update->step_size * SETUP_DELAY_STEPS)) usleep(delay_values[SETUP_DELAY]); + else if (offset < (fw_update->step_size * WRITE_DELAY_STEPS)) + usleep(delay_values[WRITE1_DELAY]); else - usleep(delay_values[WRITE_DELAY]); + usleep(delay_values[WRITE2_DELAY]); return S7_READ_STATUS; } @@ -635,6 +669,7 @@ static enum fw_update_state s9_read_status(struct fw_update_ctrl *fw_update) return S9_READ_STATUS; } log_msg(fw_update, S9_READ_STATUS, "Complete"); + fw_update->flags &= ~F_NEED_UPDATE; return S10_TERMINAL; } @@ -682,26 +717,37 @@ static int ec_sb_firmware_update(struct fw_update_ctrl *fw_update) } #define GEC_LOCK_TIMEOUT_SECS 30 /* 30 secs */ +void usage(char *argv[]) +{ + printf("Usage: %s [check|update]\n" + " check: check if AC Adaptor is connected.\n" + " update: trigger battery firmware update.\n", + argv[0]); +} int main(int argc, char *argv[]) { int rv = 0, interfaces = COMM_LPC; + int op = OP_UNKNOWN; + uint8_t val = 0; + /* local test flags */ int protect = 1; int version_check = 1; - uint8_t val = 0; - if (argc > 3) { - printf("Usage: %s [protect] [version_check]\n" - " protect: 0 or 1, default 1\n" - " version_check: 0 or 1, default 1\n", - argv[0]); + + if (argc != 2) { + usage(argv); return -1; } - if (argc >= 2) - protect = atoi(argv[1]); - - if (argc >= 3) - version_check = atoi(argv[2]); + if (!strcmp(argv[1], "check")) + op = OP_CHECK; + else if (!strcmp(argv[1], "update")) + op = OP_UPDATE; + else { + op = OP_UNKNOWN; + usage(argv); + return -1; + } if (acquire_gec_lock(GEC_LOCK_TIMEOUT_SECS) < 0) { printf("Could not acquire GEC lock.\n"); @@ -720,23 +766,38 @@ int main(int argc, char *argv[]) goto out; } + if (val & EC_BATT_FLAG_AC_PRESENT) { + fw_update.flags |= F_AC_PRESENT; + printf("AC_PRESENT\n"); + } + + if (op == OP_UPDATE) + fw_update.flags |= F_UPDATE; + if (version_check) fw_update.flags |= F_VERSION_CHECK; - if (val & EC_BATT_FLAG_AC_PRESENT) - fw_update.flags |= F_AC_PRESENT; - rv = ec_sb_firmware_update(&fw_update); - printf("Battery Firmware Update:0x%02x %s%s\n", + printf("Battery Firmware Update:0x%02x (%d %d %d %d %d) %s\n%s\n", fw_update.flags, + delay_values[BEGIN_DELAY], + delay_values[SETUP_DELAY], + delay_values[WRITE1_DELAY], + delay_values[WRITE2_DELAY], + delay_values[END_DELAY], ((rv) ? "FAIL " : " "), fw_update.msg); /* Update battery firmware update interface to be protected */ - if (protect) + if (protect && !(fw_update.flags & F_NEED_UPDATE)) rv |= send_subcmd(EC_SB_FW_UPDATE_PROTECT); + if (fw_update.flags & F_POWERD_DISABLED) + rv |= restore_power_management(); out: release_gec_lock(); - return rv; + if (rv) + return -1; + else + return fw_update.flags & F_NEED_UPDATE; } -- cgit v1.2.1