diff options
author | Namyoon Woo <namyoon@chromium.org> | 2020-02-06 10:30:30 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-02-20 09:11:47 +0000 |
commit | f469dcd53ba83992d983dfab6cd5f79c0a5b2e90 (patch) | |
tree | 3c89e5de06767b88784a3c86e22224cd7ae4b4a4 | |
parent | 78138c43f210c6ea59b249863d4e754a2803fd5d (diff) | |
download | chrome-ec-f469dcd53ba83992d983dfab6cd5f79c0a5b2e90.tar.gz |
ccdblock can block EC-CR50 communication
This patch introduces 'EC_CR50_COMM' a new option for ccdblock
console command.
It can be useful for system rescue purpose like you want to
force cr50 to yield EC_UART (especially TX) port to servo.
BUG=chromium:1047287
BRANCH=cr50, cr50-mp
TEST=ran manually ccdblock.
> ccdstate
AP: off
AP UART: off
EC: on
Rdd: connected
Servo: undetectable
CCD EXT: enabled
State flags: UARTEC+TX I2C SPI
CCD ports blocked: (none)
>
>
> ccdblock EC_CR50_COMM enable
CCD ports blocked: EC_CR50_COMM
> [73.386550 CCD state: UARTEC I2C SPI]
>
> ccdstate
AP: off
AP UART: off
EC: on
Rdd: connected
Servo: disconnected
CCD EXT: enabled
State flags: UARTEC I2C SPI
CCD ports blocked: EC_CR50_COMM
>
>
> ccdblock EC_CR50_COMM disable
CCD ports blocked: (none)
> [104.781623 CCD state: UARTEC+TX I2C SPI]
ccdstate
AP: off
AP UART: off
EC: on
Rdd: connected
Servo: undetectable
CCD EXT: enabled
State flags: UARTEC+TX I2C SPI
CCD ports blocked: (none)
Change-Id: I7816c201054f1793906bd19d4b58755593d2fbac
Signed-off-by: Namyoon Woo <namyoon@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2042118
Reviewed-by: Mary Ruthven <mruthven@chromium.org>
-rw-r--r-- | board/cr50/ec_comm.c | 23 | ||||
-rw-r--r-- | board/cr50/ec_comm.h | 6 | ||||
-rw-r--r-- | board/cr50/rdd.c | 23 |
3 files changed, 48 insertions, 4 deletions
diff --git a/board/cr50/ec_comm.c b/board/cr50/ec_comm.c index d9b01c92e2..c4a3603c82 100644 --- a/board/cr50/ec_comm.c +++ b/board/cr50/ec_comm.c @@ -73,3 +73,26 @@ int ec_comm_is_uart_in_packet_mode(int uart) { return uart == ec_comm_ctx.uart; } + +void ec_comm_block(int block) +{ + static int is_blocked; + + if (is_blocked == block) + return; + + if (block) { + gpio_disable_interrupt(GPIO_EC_PACKET_MODE_EN); + gpio_disable_interrupt(GPIO_EC_PACKET_MODE_DIS); + + if (ec_comm_is_uart_in_packet_mode(UART_EC)) + ec_comm_packet_mode_dis(GPIO_EC_PACKET_MODE_DIS); + } else { + gpio_enable_interrupt(GPIO_EC_PACKET_MODE_EN); + gpio_enable_interrupt(GPIO_EC_PACKET_MODE_DIS); + } + + is_blocked = block; + + /* Note: ccd_update_state() should be called to change UART status. */ +} diff --git a/board/cr50/ec_comm.h b/board/cr50/ec_comm.h index 37732e69c2..9e84a715e1 100644 --- a/board/cr50/ec_comm.h +++ b/board/cr50/ec_comm.h @@ -24,6 +24,12 @@ int ec_comm_is_uart_in_packet_mode(int uart); * 0 otherwise. */ int ec_comm_process_packet(uint8_t ch); +/* + * Block or unblock EC-CR50 communication. + * @param block non-zero value blocks EC-CR50 communication. + * Zero value unblocks it. + */ +void ec_comm_block(int block); /* Reset EC EFS context */ void ec_efs_reset(void); /* Set EC-EFS boot_mode */ diff --git a/board/cr50/rdd.c b/board/cr50/rdd.c index 2e5ccc7e81..228f076831 100644 --- a/board/cr50/rdd.c +++ b/board/cr50/rdd.c @@ -56,7 +56,13 @@ enum ccd_block_flags { * uart while servo is connected, it could break the hardware and the * ccd uart could become permanently unusable. */ - CCD_BLOCK_IGNORE_SERVO = BIT(3) + CCD_BLOCK_IGNORE_SERVO = BIT(3), + + /* + * This will block EC-CR50-communication. CR50 should not enable EC + * UART. + */ + CCD_BLOCK_EC_CR50_COMM = BIT(4) }; /* Which UARTs are blocked by console command */ @@ -300,9 +306,11 @@ static void ccd_state_change_hook(void) /* * EC UART flags are cleared if ccd ext is not detected or if ccd block * EC UART is enabled. EC-CR50 comm trumps both of those conditions. - * Re-enable the EC UART flags if EC-CR50 comm is enabled. + * Re-enable the EC UART flags if EC-CR50 comm is enabled and + * CCD_BLOCK_EC_CR50_COMM must be off in ccd_block bitmap. */ - if (ec_comm_is_uart_in_packet_mode(UART_EC)) + if (ec_comm_is_uart_in_packet_mode(UART_EC) && + !(ccd_block & CCD_BLOCK_EC_CR50_COMM)) flags_want |= (CCD_ENABLE_UART_EC | CCD_ENABLE_UART_EC_TX); /* @@ -442,6 +450,8 @@ static void print_ccd_ports_blocked(void) ccputs("\nWARNING: enabling UART while servo is connected may " "damage hardware"); } + if (ccd_block & CCD_BLOCK_EC_CR50_COMM) + ccputs(" EC_CR50_COMM"); if (!ccd_block) ccputs(" (none)"); ccputs("\n"); @@ -484,6 +494,8 @@ static int command_ccd_block(int argc, char **argv) block_flag = CCD_BLOCK_SERVO_SHARED; else if (!strcasecmp(argv[1], "IGNORE_SERVO")) block_flag = CCD_BLOCK_IGNORE_SERVO; + else if (!strcasecmp(argv[1], "EC_CR50_COMM")) + block_flag = CCD_BLOCK_EC_CR50_COMM; else return EC_ERROR_PARAM1; @@ -497,6 +509,8 @@ static int command_ccd_block(int argc, char **argv) if (block_flag == CCD_BLOCK_IGNORE_SERVO) servo_ignore(new_state); + else if (block_flag == CCD_BLOCK_EC_CR50_COMM) + ec_comm_block(new_state); /* Update blocked state in deferred function */ ccd_update_state(); @@ -507,5 +521,6 @@ static int command_ccd_block(int argc, char **argv) return EC_SUCCESS; } DECLARE_CONSOLE_COMMAND(ccdblock, command_ccd_block, - "[<AP | EC | SERVO | IGNORE_SERVO> [BOOLEAN]]", + "[<AP | EC | SERVO | IGNORE_SERVO | EC_CR50_COMM>" + " [BOOLEAN]]", "Force CCD ports disabled"); |