summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMary Ruthven <mruthven@chromium.org>2019-03-05 20:53:11 -0800
committerchrome-bot <chrome-bot@chromium.org>2019-04-03 18:13:54 -0700
commit351f46632d5f0a051f298742fb68c7b7c9e3f8d4 (patch)
treed3a323294d8d1514b7d111c9a53547a28ab90076
parent3fcecc07e122d06cba6eb38186f39df83dbc5b3d (diff)
downloadchrome-ec-351f46632d5f0a051f298742fb68c7b7c9e3f8d4.tar.gz
cr50: add command to override BATT_PRES_L
We use BATT_PRES_L to determine if factory mode can be enabled. We need to be able to control this for cr50 testing. Add a command that can be used to override battery presence. This change also adds a ccd capability to control access to this command. If this capability is enabled, someone can easily use console commands and AP commands to enable factory mode, so it should be controlled separately from WP and GscFullConsole. BUG=b:126197850 BRANCH=cr50 TEST=override battery presence using bpforce. Make sure the state lasts through reboot, deep sleep, and power-on reset. When bp is forced disabled you can do ccd open without physical presence and you can enable factory mode. Change-Id: I026a537142b6780824192caa2a147c7bdac1545c Signed-off-by: Mary Ruthven <mruthven@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1505213 Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-by: Keith Short <keithshort@chromium.org>
-rw-r--r--board/cr50/wp.c94
-rw-r--r--board/cr50/wp.h4
-rw-r--r--common/ccd_config.c10
-rw-r--r--include/ccd_config.h13
4 files changed, 107 insertions, 14 deletions
diff --git a/board/cr50/wp.c b/board/cr50/wp.c
index ba7e2f7de1..b3d50e4dad 100644
--- a/board/cr50/wp.c
+++ b/board/cr50/wp.c
@@ -21,13 +21,15 @@
#define CPRINTS(format, args...) cprints(CC_RBOX, format, ## args)
#define CPRINTF(format, args...) cprintf(CC_RBOX, format, ## args)
+uint8_t bp_connect;
+uint8_t bp_forced;
/**
* Return non-zero if battery is present
*/
int board_battery_is_present(void)
{
/* Invert because battery-present signal is active low */
- return !gpio_get_level(GPIO_BATT_PRES_L);
+ return bp_forced ? bp_connect : !gpio_get_level(GPIO_BATT_PRES_L);
}
/**
@@ -145,18 +147,64 @@ static enum vendor_cmd_rc vc_set_wp(enum vendor_cmd_cc code,
}
DECLARE_VENDOR_COMMAND(VENDOR_CC_WP, vc_set_wp);
-static int command_wp(int argc, char **argv)
+static int command_bpforce(int argc, char **argv)
{
int val = 1;
int forced = 1;
if (argc > 1) {
+ /* Make sure we're allowed to override battery presence */
+ if (!ccd_is_cap_enabled(CCD_CAP_OVERRIDE_BATT_STATE))
+ return EC_ERROR_ACCESS_DENIED;
+
+ /* Update BP */
+ if (!strncasecmp(argv[1], "follow", 6))
+ forced = 0;
+ else if (!strncasecmp(argv[1], "dis", 3))
+ val = 0;
+ else if (strncasecmp(argv[1], "con", 3))
+ return EC_ERROR_PARAM2;
+
+ bp_forced = forced;
+ bp_connect = val;
+
+ if (argc > 2 && !strcasecmp(argv[2], "atboot")) {
+ /* Change override at boot to match */
+ ccd_set_flag(CCD_FLAG_OVERRIDE_BATT_AT_BOOT, bp_forced);
+ ccd_set_flag(CCD_FLAG_OVERRIDE_BATT_STATE_CONNECT,
+ bp_connect);
+ }
+ /* Update the WP state based on new battery presence setting */
+ check_wp_battery_presence();
+ }
+
+ ccprintf("batt pres: %s%sconnect\n", bp_forced ? "forced " : "",
+ board_battery_is_present() ? "" : "dis");
+ ccprintf(" at boot: ");
+ if (ccd_get_flag(CCD_FLAG_OVERRIDE_BATT_AT_BOOT))
+ ccprintf("forced %sconnect\n",
+ ccd_get_flag(CCD_FLAG_OVERRIDE_BATT_STATE_CONNECT) ? ""
+ : "dis");
+ else
+ ccprintf("follow_batt_pres\n");
+ return EC_SUCCESS;
+}
+DECLARE_SAFE_CONSOLE_COMMAND(bpforce, command_bpforce,
+ "[connect|disconnect|follow_batt_pres [atboot]]",
+ "Get/set BATT_PRES_L signal override");
+
+static int command_wp(int argc, char **argv)
+{
+ int val;
+ int forced;
+
+ if (argc > 1) {
/* Make sure we're allowed to override WP settings */
if (!ccd_is_cap_enabled(CCD_CAP_OVERRIDE_WP))
return EC_ERROR_ACCESS_DENIED;
/* Update WP */
- if (strncasecmp(argv[1], "follow_batt_pres", 16) == 0)
+ if (!strncasecmp(argv[1], "follow", 6))
forced = 0;
else if (parse_bool(argv[1], &val))
forced = 1;
@@ -172,14 +220,13 @@ static int command_wp(int argc, char **argv)
}
}
- ccprintf("Flash WP: %s%s\n", board_forcing_wp() ? "forced " : "",
- wp_is_asserted() ? "enabled" : "disabled");
-
+ ccprintf("Flash WP: %s%sabled\n", board_forcing_wp() ? "forced " : "",
+ wp_is_asserted() ? "en" : "dis");
ccprintf(" at boot: ");
if (ccd_get_flag(CCD_FLAG_OVERRIDE_WP_AT_BOOT))
- ccprintf("forced %s\n",
+ ccprintf("forced %sabled\n",
ccd_get_flag(CCD_FLAG_OVERRIDE_WP_STATE_ENABLED)
- ? "enabled" : "disabled");
+ ? "en" : "dis");
else
ccprintf("follow_batt_pres\n");
@@ -189,7 +236,18 @@ DECLARE_SAFE_CONSOLE_COMMAND(wp, command_wp,
"[<BOOLEAN>/follow_batt_pres [atboot]]",
"Get/set the flash HW write-protect signal");
-void set_wp_follow_ccd_config(void)
+void set_bp_follow_ccd_config(void)
+{
+ if (ccd_get_flag(CCD_FLAG_OVERRIDE_BATT_AT_BOOT)) {
+ /* Reset to at-boot state specified by CCD */
+ bp_forced = 1;
+ bp_connect = ccd_get_flag(CCD_FLAG_OVERRIDE_BATT_STATE_CONNECT);
+ } else {
+ bp_forced = 0;
+ }
+}
+
+static void set_wp_follow_ccd_config(void)
{
if (ccd_get_flag(CCD_FLAG_OVERRIDE_WP_AT_BOOT)) {
/* Reset to at-boot state specified by CCD */
@@ -201,8 +259,26 @@ void set_wp_follow_ccd_config(void)
}
}
+void board_wp_follow_ccd_config(void)
+{
+ /*
+ * Battery presence can be overidden using CCD. Get that setting before
+ * configuring write protect.
+ */
+ set_bp_follow_ccd_config();
+
+ /* Update write protect setting based on ccd config */
+ set_wp_follow_ccd_config();
+}
+
void init_wp_state(void)
{
+ /*
+ * Battery presence can be overidden using CCD. Get that setting before
+ * configuring write protect.
+ */
+ set_bp_follow_ccd_config();
+
/* Check system reset flags after CCD config is initially loaded */
if ((system_get_reset_flags() & RESET_FLAG_HIBERNATE) &&
!system_rollback_detected()) {
diff --git a/board/cr50/wp.h b/board/cr50/wp.h
index 501067233f..d5cbade855 100644
--- a/board/cr50/wp.h
+++ b/board/cr50/wp.h
@@ -29,8 +29,8 @@ int wp_is_asserted(void);
void read_fwmp(void);
/**
- * Set WP as dicated by CCD configuration.
+ * Set WP and battery presence as dicated by CCD configuration.
*/
-void set_wp_follow_ccd_config(void);
+void board_wp_follow_ccd_config(void);
#endif /* ! __EC_BOARD_CR50_WP_H */
diff --git a/common/ccd_config.c b/common/ccd_config.c
index 8896e9cde6..c2a92aeb30 100644
--- a/common/ccd_config.c
+++ b/common/ccd_config.c
@@ -96,7 +96,9 @@ static const uint8_t k_ccd_config = NVMEM_VAR_CCD_CONFIG;
/* Flags which can be set via ccd_set_flag() */
static const uint32_t k_public_flags =
CCD_FLAG_OVERRIDE_WP_AT_BOOT |
- CCD_FLAG_OVERRIDE_WP_STATE_ENABLED;
+ CCD_FLAG_OVERRIDE_WP_STATE_ENABLED |
+ CCD_FLAG_OVERRIDE_BATT_AT_BOOT |
+ CCD_FLAG_OVERRIDE_BATT_STATE_CONNECT;
/* List of CCD capability info; must be in same order as enum ccd_capability */
static const struct ccd_capability_info cap_info[CCD_CAP_COUNT] = CAP_INFO_DATA;
@@ -470,6 +472,8 @@ int ccd_reset_config(unsigned int flags)
/* Reset the entire config */
memset(&config, 0, sizeof(config));
config.version = CCD_CONFIG_VERSION;
+ /* Update write protect after resetting the config */
+ board_wp_follow_ccd_config();
}
if (flags & CCD_RESET_FACTORY) {
@@ -485,7 +489,7 @@ int ccd_reset_config(unsigned int flags)
/* Force WP disabled at boot */
raw_set_flag(CCD_FLAG_OVERRIDE_WP_AT_BOOT, 1);
raw_set_flag(CCD_FLAG_OVERRIDE_WP_STATE_ENABLED, 0);
- set_wp_follow_ccd_config();
+ board_wp_follow_ccd_config();
}
/* Restore test lab flag unless explicitly resetting it */
@@ -1522,7 +1526,7 @@ static enum vendor_cmd_rc ccd_disable_factory_mode(enum vendor_cmd_cc code,
* TODO(rspangler): sort out CCD state and WP correlation,
* b/73075443.
*/
- set_wp_follow_ccd_config();
+ board_wp_follow_ccd_config();
/*
* Use raw_set_flag() because the factory mode flag is internal
diff --git a/include/ccd_config.h b/include/ccd_config.h
index 23a6ebfa05..3952cb9bc9 100644
--- a/include/ccd_config.h
+++ b/include/ccd_config.h
@@ -49,6 +49,15 @@ enum ccd_flag {
/* Flags that can be set via ccd_set_flags(); fill from top down */
+ /* Override BATT_PRES_L at boot */
+ CCD_FLAG_OVERRIDE_BATT_AT_BOOT = BIT(20),
+
+ /*
+ * If overriding BATT_PRES_L at boot, set it to what value
+ * (0=disconnect, 1=connected)
+ */
+ CCD_FLAG_OVERRIDE_BATT_STATE_CONNECT = BIT(21),
+
/* Override write protect at boot */
CCD_FLAG_OVERRIDE_WP_AT_BOOT = BIT(22),
@@ -112,6 +121,9 @@ enum ccd_capability {
/* Allow ccd open from usb */
CCD_CAP_OPEN_FROM_USB = 18,
+ /* Override battery presence temporarily or at boot */
+ CCD_CAP_OVERRIDE_BATT_STATE = 19,
+
/* Number of currently defined capabilities */
CCD_CAP_COUNT
};
@@ -173,6 +185,7 @@ struct ccd_capability_info {
{"FlashRead", CCD_CAP_STATE_ALWAYS}, \
{"OpenNoDevMode", CCD_CAP_STATE_OPEN_REQ}, \
{"OpenFromUSB", CCD_CAP_STATE_OPEN_REQ}, \
+ {"OverrideBatt", CCD_CAP_STATE_IF_OPENED}, \
}
#define CCD_STATE_NAMES { "Locked", "Unlocked", "Opened" }