From 5602f4d5155a6ea0eefbd514871c069b381dbd0a Mon Sep 17 00:00:00 2001 From: Shawn Nematbakhsh Date: Wed, 26 Oct 2016 16:11:45 -0700 Subject: [PATCH] i2c: Lock out i2c passthru except for desired ports Lock out all non-essential i2c passthru ports when system is protected. BUG=chrome-os-partner:58859 BRANCH=gru TEST='ectool i2cxfer 0 0 0 0' on locked system, verify that "ACCESS DENIED" is returned. Change-Id: If4119bbb319aa491d0e79a9ed80c94daa7950c2f Signed-off-by: Shawn Nematbakhsh Reviewed-on: https://chromium-review.googlesource.com/403543 Tested-by: Philip Chen Reviewed-by: Aseda Aboagye Reviewed-by: Philip Chen Commit-Queue: Philip Chen (cherry picked from commit d29fdb5484b994937c6586a50dd2818028f15f3f) Reviewed-on: https://chromium-review.googlesource.com/415493 Commit-Ready: Shawn N Tested-by: Shawn N Reviewed-by: Shawn N --- board/kevin/board.c | 5 +++++ board/kevin/board.h | 1 + board/rambi/board.c | 5 +++++ common/i2c.c | 15 +++++++++------ include/i2c.h | 9 +++++++++ 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/board/kevin/board.c b/board/kevin/board.c index 180ad6a025..889ee6ccab 100644 --- a/board/kevin/board.c +++ b/board/kevin/board.c @@ -752,3 +752,8 @@ static void pwm_displight_preserve_state(void) sizeof(pwm_displight_duty), &pwm_displight_duty); } DECLARE_HOOK(HOOK_SYSJUMP, pwm_displight_preserve_state, HOOK_PRIO_DEFAULT); + +int board_allow_i2c_passthru(int port) +{ + return (port == I2C_PORT_VIRTUAL_BATTERY); +} diff --git a/board/kevin/board.h b/board/kevin/board.h index 2004263987..5fb35ea8f5 100644 --- a/board/kevin/board.h +++ b/board/kevin/board.h @@ -17,6 +17,7 @@ #define CONFIG_I2C #define CONFIG_I2C_MASTER #define CONFIG_I2C_VIRTUAL_BATTERY +#define CONFIG_I2C_PASSTHRU_RESTRICTED #define CONFIG_LED_COMMON #define CONFIG_LOW_POWER_IDLE #define CONFIG_POWER_COMMON diff --git a/board/rambi/board.c b/board/rambi/board.c index 0063e56b0f..28089cea1c 100644 --- a/board/rambi/board.c +++ b/board/rambi/board.c @@ -103,3 +103,8 @@ const struct temp_sensor_t temp_sensors[] = { {"Battery", TEMP_SENSOR_TYPE_BATTERY, charge_get_battery_temp, 0, 4}, }; BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT); + +int board_allow_i2c_passthru(int port) +{ + return 0; +} diff --git a/common/i2c.c b/common/i2c.c index 165f343aa1..cd54ceccc7 100644 --- a/common/i2c.c +++ b/common/i2c.c @@ -542,11 +542,6 @@ static int i2c_command_passthru(struct host_cmd_handler_args *args) uint8_t batt_param = 0; #endif -#ifdef CONFIG_I2C_PASSTHRU_RESTRICTED - if (system_is_locked()) - return EC_RES_ACCESS_DENIED; -#endif - #ifdef CONFIG_BATTERY_CUT_OFF /* * Some batteries would wake up after cut-off if we talk to it. @@ -624,9 +619,17 @@ static int i2c_command_passthru(struct host_cmd_handler_args *args) "write_len=%x, data=%p, read_len=%x, flags=%x", params->port, addr, out, write_len, &resp->data[in_len], read_len, xferflags); - if (rv) + if (rv) { +#ifdef CONFIG_I2C_PASSTHRU_RESTRICTED + if (system_is_locked() && + !board_allow_i2c_passthru(params->port)) { + i2c_lock(params->port, 0); + return EC_RES_ACCESS_DENIED; + } +#endif rv = i2c_xfer(params->port, addr, out, write_len, &resp->data[in_len], read_len, xferflags); + } if (rv) { /* Driver will have sent a stop bit here */ diff --git a/include/i2c.h b/include/i2c.h index 38e632e38e..73716cf705 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -324,4 +324,13 @@ int i2c_set_response(int port, uint8_t *buf, int len); */ void i2cm_init(void); +/** + * Board-level function to determine whether i2c passthru should be allowed + * on a given port. + * + * @parm port I2C port + * + * @return true, if passthru should be allowed on the port. + */ +int board_allow_i2c_passthru(int port); #endif /* __CROS_EC_I2C_H */