summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorKarthikeyan Ramasubramanian <kramasub@chromium.org>2018-12-19 14:01:42 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2019-01-09 20:37:25 +0000
commit0e38d32fac4ad46fb29f804b5f6700dd36d21d3d (patch)
treef8574c926313915cb4bd0b6ab22d2508c32ce23b /common
parentec1ab7791808513a5271f87feb558115e408e45c (diff)
downloadchrome-ec-0e38d32fac4ad46fb29f804b5f6700dd36d21d3d.tar.gz
i2c_master: Protect TCPC I2C tunnels as part of EC_REBOOT_DISABLE_JUMP
Currently EC keeps the I2C tunnels open enabling depthcharge to perform firmware update on those ports. Once the firmware update is done, depthcharge triggers a command to protect the I2C tunnels. But not all TCPC ports are registered for firmware update in depthcharge. This causes some I2C tunnels to be left unprotected. Update EC to protect all the TCPC I2C tunnels when depthcharge invokes EC_REBOOT_DISABLE_JUMP command. This usually happens when the EC software sync is complete and the control jumps to OS. Also protect the TCPC I2C tunnels only when the WP is enabled. BUG=b:119130829 BRANCH=octopus TEST=make -j buildall && Boot to ChromeOS and ensure that the TCPC I2C tunnels are protected. Change-Id: Ice681038bbf725b3aa44b13ff71724937c6045e9 Signed-off-by: Karthikeyan Ramasubramanian <kramasub@google.com> Reviewed-on: https://chromium-review.googlesource.com/1390944 Commit-Ready: Karthikeyan Ramasubramanian <kramasub@chromium.org> Tested-by: Karthikeyan Ramasubramanian <kramasub@chromium.org> Reviewed-by: Jett Rink <jettrink@chromium.org> (cherry picked from commit 9e4474e561ec165cf24e8aa249c2aeeed8e7f1ef) Reviewed-on: https://chromium-review.googlesource.com/c/1403853 Reviewed-by: Karthikeyan Ramasubramanian <kramasub@chromium.org> Commit-Queue: Karthikeyan Ramasubramanian <kramasub@chromium.org> Trybot-Ready: Karthikeyan Ramasubramanian <kramasub@chromium.org>
Diffstat (limited to 'common')
-rw-r--r--common/i2c_master.c12
-rw-r--r--common/system.c33
2 files changed, 43 insertions, 2 deletions
diff --git a/common/i2c_master.c b/common/i2c_master.c
index ec2cad96df..c2cc22f06c 100644
--- a/common/i2c_master.c
+++ b/common/i2c_master.c
@@ -37,7 +37,7 @@ static struct mutex port_mutex[I2C_CONTROLLER_COUNT];
/* A bitmap of the controllers which are currently servicing a request. */
static uint32_t i2c_port_active_list;
BUILD_ASSERT(I2C_CONTROLLER_COUNT < 32);
-static uint8_t port_protected[I2C_CONTROLLER_COUNT];
+static uint8_t port_protected[I2C_PORT_COUNT];
/**
* Non-deterministically test the lock status of the port. If another task
@@ -761,6 +761,14 @@ static int i2c_command_passthru(struct host_cmd_handler_args *args)
}
DECLARE_HOST_COMMAND(EC_CMD_I2C_PASSTHRU, i2c_command_passthru, EC_VER_MASK(0));
+void i2c_passthru_protect_port(uint32_t port)
+{
+ if (port < I2C_PORT_COUNT)
+ port_protected[port] = 1;
+ else
+ PTHRUPRINTF("Invalid I2C port %d to be protected\n", port);
+}
+
static int i2c_command_passthru_protect(struct host_cmd_handler_args *args)
{
const struct ec_params_i2c_passthru_protect *params = args->params;
@@ -790,7 +798,7 @@ static int i2c_command_passthru_protect(struct host_cmd_handler_args *args)
resp->status = port_protected[params->port];
args->response_size = sizeof(*resp);
} else if (params->subcmd == EC_CMD_I2C_PASSTHRU_PROTECT_ENABLE) {
- port_protected[params->port] = 1;
+ i2c_passthru_protect_port(params->port);
} else {
return EC_RES_INVALID_COMMAND;
}
diff --git a/common/system.c b/common/system.c
index a5f1ab9532..6cd5702c30 100644
--- a/common/system.c
+++ b/common/system.c
@@ -32,6 +32,7 @@
#include "timer.h"
#include "uart.h"
#include "usb_pd.h"
+#include "usb_pd_tcpm.h"
#include "util.h"
#include "version.h"
#include "watchdog.h"
@@ -350,6 +351,36 @@ const uint8_t *system_get_jump_tag(uint16_t tag, int *version, int *size)
return NULL;
}
+#if defined(CONFIG_USB_POWER_DELIVERY) && !defined(CONFIG_USB_PD_TCPM_STUB) && \
+ defined(CONFIG_I2C_MASTER)
+extern const struct tcpc_config_t tcpc_config[];
+
+static void system_protect_tcpc_i2c_ports(void)
+{
+ uint32_t locked = system_is_locked();
+ int i;
+
+ /*
+ * If WP is not enabled i.e. system is not locked leave the tunnels open
+ * so that factory line can do updates without a new RO BIOS.
+ */
+ if (!locked) {
+ CPRINTS("System unlocked, TCPC I2C tunnels may be unprotected");
+ return;
+ }
+
+ for (i = 0; i < CONFIG_USB_PD_PORT_COUNT; i++)
+ i2c_passthru_protect_port(tcpc_config[i].i2c_host_port);
+}
+
+#else
+
+static void system_protect_tcpc_i2c_ports(void)
+{
+}
+
+#endif
+
void system_disable_jump(void)
{
disable_jump = 1;
@@ -915,6 +946,7 @@ static int handle_pending_reboot(enum ec_reboot_cmd cmd)
/* That shouldn't return... */
return EC_ERROR_UNKNOWN;
case EC_REBOOT_DISABLE_JUMP:
+ system_protect_tcpc_i2c_ports();
system_disable_jump();
return EC_SUCCESS;
#ifdef CONFIG_HIBERNATE
@@ -1169,6 +1201,7 @@ static int command_sysjump(int argc, char **argv)
return EC_ERROR_PARAM1;
#endif
} else if (!strcasecmp(argv[1], "disable")) {
+ system_protect_tcpc_i2c_ports();
system_disable_jump();
return EC_SUCCESS;
}