From 78138c43f210c6ea59b249863d4e754a2803fd5d Mon Sep 17 00:00:00 2001 From: Namyoon Woo Date: Thu, 13 Feb 2020 10:59:06 -0800 Subject: restructure EC-EFS module - add ec_efs, which tracks the system boot mode. - add ec_comm.h header file for EC-EFS related functions. - revised vboot.h header file. BUG=b:141143112 BRANCH=cr50 TEST=none Change-Id: Iec1bf466b832bac5ad6be8a52304c1d699a38fb2 Signed-off-by: Namyoon Woo Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2055363 Reviewed-by: Mary Ruthven --- board/cr50/board.c | 9 ++++++ board/cr50/board.h | 18 ++++-------- board/cr50/build.mk | 1 + board/cr50/ec_comm.c | 7 +++++ board/cr50/ec_comm.h | 33 +++++++++++++++++++++ board/cr50/ec_efs.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ board/cr50/rdd.c | 1 + board/cr50/servo_state.c | 1 + 8 files changed, 134 insertions(+), 12 deletions(-) create mode 100644 board/cr50/ec_comm.h create mode 100644 board/cr50/ec_efs.c (limited to 'board') diff --git a/board/cr50/board.c b/board/cr50/board.c index 2edf27a511..f1d4d2a743 100644 --- a/board/cr50/board.c +++ b/board/cr50/board.c @@ -9,6 +9,7 @@ #include "common.h" #include "console.h" #include "dcrypto/dcrypto.h" +#include "ec_comm.h" #include "ec_version.h" #include "endian.h" #include "extension.h" @@ -1045,6 +1046,12 @@ void board_reboot_ec(void) } DECLARE_DEFERRED(board_reboot_ec); +void board_reboot_ec_deferred(int32_t usec_delay) +{ + if (usec_delay >= 0) + hook_call_deferred(&board_reboot_ec_data, usec_delay); +} + /* * This interrupt handler will be called if the RBOX key combo is detected. */ @@ -1141,6 +1148,8 @@ void assert_ec_rst(void) /* Prevent bit bang interrupt storm. */ if (uart_bitbang_is_enabled()) task_disable_irq(bitbang_config.rx_irq); + else if (board_has_ec_cr50_comm_support()) + ec_efs_reset(); wait_ec_rst(1); diff --git a/board/cr50/board.h b/board/cr50/board.h index 4c35fb9e07..25f8452503 100644 --- a/board/cr50/board.h +++ b/board/cr50/board.h @@ -341,6 +341,12 @@ int board_fwmp_allows_unlock(void); int board_vboot_dev_mode_enabled(void); void board_reboot_ap(void); void board_reboot_ec(void); +/** + * Reboot the EC + * @param usec_delay microseconds to delay in rebooting EC. + * negative input shall be disregarded. + */ +void board_reboot_ec_deferred(int usec_delay); void board_closed_loop_reset(void); int board_wipe_tpm(int reset_required); int board_is_first_factory_boot(void); @@ -380,18 +386,6 @@ void board_unwedge_i2cs(void); int board_in_prod_mode(void); -/* GPIO Interrupt handler for GPIO_EC_PACKET_MODE_EN rising edge */ -void ec_comm_packet_mode_en(enum gpio_signal unsed); - -/* GPIO Interrupt handler for GPIO_EC_PACKET_MODE_DIS falling edge */ -void ec_comm_packet_mode_dis(enum gpio_signal unsed); - -/* - * Return True if the given UART is in packet mode, in which EC-CR50 - * communication is on-going. - */ -int ec_comm_is_uart_in_packet_mode(int uart); - #endif /* !__ASSEMBLER__ */ /* USB interface indexes (use define rather than enum to expand them) */ diff --git a/board/cr50/build.mk b/board/cr50/build.mk index dfef2b1847..4b28c91641 100644 --- a/board/cr50/build.mk +++ b/board/cr50/build.mk @@ -43,6 +43,7 @@ board-y = board.o board-y += ap_state.o board-y += closed_source_set1.o board-y += ec_comm.o +board-y += ec_efs.o board-y += ec_state.o board-y += power_button.o board-y += servo_state.o diff --git a/board/cr50/ec_comm.c b/board/cr50/ec_comm.c index 3e9a343f2c..d9b01c92e2 100644 --- a/board/cr50/ec_comm.c +++ b/board/cr50/ec_comm.c @@ -6,6 +6,7 @@ */ #include "common.h" #include "console.h" +#include "ec_comm.h" #include "gpio.h" #include "hooks.h" #include "system.h" @@ -44,6 +45,12 @@ static void ec_comm_init_(void) } DECLARE_HOOK(HOOK_INIT, ec_comm_init_, HOOK_PRIO_DEFAULT + 1); +int ec_comm_process_packet(uint8_t ch) +{ + /* TODO(b:141143112): Implement this */ + return 0; +} + void ec_comm_packet_mode_en(enum gpio_signal unsed) { disable_sleep(SLEEP_MASK_EC_CR50_COMM); diff --git a/board/cr50/ec_comm.h b/board/cr50/ec_comm.h new file mode 100644 index 0000000000..37732e69c2 --- /dev/null +++ b/board/cr50/ec_comm.h @@ -0,0 +1,33 @@ +/* Copyright 2020 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#ifndef __CROS_EC_COMM_H +#define __CROS_EC_COMM_H +#include +#include "common.h" +/* GPIO Interrupt handler for GPIO_EC_PACKET_MODE_EN rising edge */ +void ec_comm_packet_mode_en(enum gpio_signal unsed); +/* GPIO Interrupt handler for GPIO_EC_PACKET_MODE_DIS falling edge */ +void ec_comm_packet_mode_dis(enum gpio_signal unsed); +/* + * Return True if the given UART is in packet mode, in which EC-CR50 + * communication is on-going. + */ +int ec_comm_is_uart_in_packet_mode(int uart); +/* + * Try to process the given char as a EC-CR50 communication packet. + * If EC-CR50 communication is broken or uninitiated yet, then + * it does not process it. + * + * @return 1 if the given char was detected and processed as a part of packet. + * 0 otherwise. + */ +int ec_comm_process_packet(uint8_t ch); +/* Reset EC EFS context */ +void ec_efs_reset(void); +/* Set EC-EFS boot_mode */ +uint16_t ec_efs_set_boot_mode(const char *data, const uint8_t size); +/* Verify the given hash data against the EC-FW hash from kernel secdata */ +uint16_t ec_efs_verify_hash(const char *hash_data, const uint8_t size); +#endif /* __CROS_EC_COMM_H */ diff --git a/board/cr50/ec_efs.c b/board/cr50/ec_efs.c new file mode 100644 index 0000000000..da5a31f019 --- /dev/null +++ b/board/cr50/ec_efs.c @@ -0,0 +1,76 @@ +/* Copyright 2020 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * EC-EFS (Early Firmware Selection) + */ +#include "common.h" +#include "console.h" +#include "ec_comm.h" +#include "ec_commands.h" +#include "hooks.h" +#include "registers.h" +#include "system.h" +#include "vboot.h" + +#ifdef CR50_DEV +#define CPRINTS(format, args...) cprints(CC_TASK, "EC-EFS: " format, ## args) +#else +#define CPRINTS(format, args...) do { } while (0) +#endif + +/* + * Context of EC-EFS + */ +static struct ec_efs_context_ { + uint32_t boot_mode:8; /* enum ec_efs_boot_mode */ + uint32_t hash_is_loaded:1; /* Is EC hash loaded from nvmem */ + uint32_t reserved:23; + + uint32_t secdata_error_code; + + uint8_t hash[SHA256_DIGEST_SIZE]; /* EC-RW digest */ +} ec_efs_ctx; + +/* + * Change the boot mode + * + * @param mode_val New boot mode value to change + */ +static void set_boot_mode_(uint8_t mode_val) +{ + CPRINTS("boot_mode: 0x%02x -> 0x%02x", ec_efs_ctx.boot_mode, mode_val); + + ec_efs_ctx.boot_mode = mode_val; + + /* Backup some ec_efs context to scratch register */ + GREG32(PMU, PWRDN_SCRATCH20) &= ~0xff; + GREG32(PMU, PWRDN_SCRATCH20) |= mode_val; +} + +/* + * Initialize EC-EFS context. + */ +static void ec_efs_init_(void) +{ + if (!board_has_ec_cr50_comm_support()) + return; + + /* + * If it is a wakeup from deep sleep, then recover some core EC-EFS + * context values, including the boot_mode value, from a PWRD_SCRATCH + * register. Otherwise, reset boot_mode. + */ + if (system_get_reset_flags() & EC_RESET_FLAG_HIBERNATE) + set_boot_mode_(GREG32(PMU, PWRDN_SCRATCH20) & 0xff); + else + ec_efs_reset(); + + /* TODO(crbug/1020578): Read Hash from Kernel NV Index */ +} +DECLARE_HOOK(HOOK_INIT, ec_efs_init_, HOOK_PRIO_DEFAULT); + +void ec_efs_reset(void) +{ + set_boot_mode_(EC_EFS_BOOT_MODE_NORMAL); +} diff --git a/board/cr50/rdd.c b/board/cr50/rdd.c index 7a4b2de8d3..2e5ccc7e81 100644 --- a/board/cr50/rdd.c +++ b/board/cr50/rdd.c @@ -6,6 +6,7 @@ #include "case_closed_debug.h" /* For ccd_ext_is_enabled() */ #include "ccd_config.h" #include "console.h" +#include "ec_comm.h" #include "gpio.h" #include "hooks.h" #include "i2c.h" diff --git a/board/cr50/servo_state.c b/board/cr50/servo_state.c index 5c05d2bb77..4e3cdff27c 100644 --- a/board/cr50/servo_state.c +++ b/board/cr50/servo_state.c @@ -6,6 +6,7 @@ */ #include "common.h" #include "console.h" +#include "ec_comm.h" #include "gpio.h" #include "hooks.h" #include "uart_bitbang.h" -- cgit v1.2.1