summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSheng-Liang Song <ssl@chromium.org>2015-03-15 21:51:18 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-03-27 05:24:39 +0000
commitbf931b2cced0fac2f2810999ac672a3344b0849b (patch)
tree935fb595e1980ee6fa2ec20162a51c4d5d1a6c46
parentbe42949a4fadd368fc75e8f688b1b309a69051de (diff)
downloadchrome-ec-stabilize-6919.B.tar.gz
sb_firmware: update arguments and configsstabilize-6919.B
- 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 <ssl@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/260210 Reviewed-by: Shawn N <shawnn@chromium.org>
-rw-r--r--util/ec_sb_firmware_update.c151
1 files 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
-#include "lock/gec_lock.h"
#include "comm-host.h"
-#include "misc_util.h"
#include "ec_sb_firmware_update.h"
#include "ec_commands.h"
-#include <unistd.h>
+#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;
}