summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNamyoon Woo <namyoon@chromium.org>2020-02-13 10:59:06 -0800
committerCommit Bot <commit-bot@chromium.org>2020-02-20 02:08:12 +0000
commit78138c43f210c6ea59b249863d4e754a2803fd5d (patch)
tree6120fcd01f109bd5038f66e8c1222cf32e152c46
parent38f6e45971620382dd03d48a22120cef71db0179 (diff)
downloadchrome-ec-78138c43f210c6ea59b249863d4e754a2803fd5d.tar.gz
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 <namyoon@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2055363 Reviewed-by: Mary Ruthven <mruthven@chromium.org>
-rw-r--r--board/cr50/board.c9
-rw-r--r--board/cr50/board.h18
-rw-r--r--board/cr50/build.mk1
-rw-r--r--board/cr50/ec_comm.c7
-rw-r--r--board/cr50/ec_comm.h33
-rw-r--r--board/cr50/ec_efs.c76
-rw-r--r--board/cr50/rdd.c1
-rw-r--r--board/cr50/servo_state.c1
-rw-r--r--chip/g/usart.c3
-rw-r--r--include/vboot.h20
10 files changed, 148 insertions, 21 deletions
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 <stdint.h>
+#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"
diff --git a/chip/g/usart.c b/chip/g/usart.c
index 68ab726814..b597cb3f93 100644
--- a/chip/g/usart.c
+++ b/chip/g/usart.c
@@ -3,6 +3,9 @@
* found in the LICENSE file.
*/
+#ifdef BOARD_CR50
+#include "ec_comm.h"
+#endif
#include "queue.h"
#include "queue_policies.h"
#ifdef CONFIG_STREAM_SIGNATURE
diff --git a/include/vboot.h b/include/vboot.h
index 6c5f8a98b4..195db31a54 100644
--- a/include/vboot.h
+++ b/include/vboot.h
@@ -8,7 +8,9 @@
#include "common.h"
#include "vb21_struct.h"
#include "rsa.h"
+#include "sha256.h"
+#define CR50_COMM_VERSION 0x00
#define CR50_COMM_PREAMBLE 0xec
#define MIN_LENGTH_PREAMBLE 4
#define CR50_COMM_MAGIC_CHAR0 'E'
@@ -28,11 +30,12 @@
struct cr50_comm_packet {
/* Header */
uint16_t magic; /* CR50_COMM_MAGIC_WORD */
+ uint8_t version;/* Struct version. 4MSB=Major. 4LSB=Minor. */
uint8_t crc; /* checksum computed from all bytes after crc */
- uint16_t cmd; /* CR50_COMM_CMD_* if it is sent by EC. */
- /* CR50_COMM_RESPONSE(X) if it is sent by CR50. */
- uint8_t size; /* size of 'data[]' member. */
- uint8_t data[]; /* payload */
+ uint16_t cmd; /* CR50_COMM_CMD_* if EC sends */
+ /* CR50_COMM_RESPONSE(X) if CR50 sends. */
+ uint8_t size; /* Size of 'data[]' member. */
+ uint8_t data[]; /* Payload */
} __packed;
#define CR50_COMM_MAX_DATA_SIZE 32
@@ -52,8 +55,10 @@ struct cr50_comm_packet {
#define CR50_COMM_ERROR_CRC CR50_COMM_RESPONSE(0x03)
#define CR50_COMM_ERROR_SIZE CR50_COMM_RESPONSE(0x04)
#define CR50_COMM_ERROR_TIMEOUT CR50_COMM_RESPONSE(0x05)
-#define CR50_COMM_ERROR_HASH_MISMATCH CR50_COMM_RESPONSE(0x06)
-#define CR50_COMM_ERROR_UNDEFINED_CMD CR50_COMM_RESPONSE(0x07)
+#define CR50_COMM_ERROR_UNDEFINED_CMD CR50_COMM_RESPONSE(0x06)
+#define CR50_COMM_ERROR_BAD_PAYLOAD CR50_COMM_RESPONSE(0x07)
+#define CR50_COMM_ERROR_STRUCT_VERSION CR50_COMM_RESPONSE(0x08)
+#define CR50_COMM_ERROR_NVMEM CR50_COMM_RESPONSE(0x09)
/*
* BIT(0) : NO_BOOT flag
@@ -62,9 +67,6 @@ struct cr50_comm_packet {
enum ec_efs_boot_mode {
EC_EFS_BOOT_MODE_NORMAL = 0x00,
EC_EFS_BOOT_MODE_NO_BOOT = 0x01,
- EC_EFS_BOOT_MODE_RECOVERY = 0x02,
- EC_EFS_BOOT_MODE_NO_BOOT_RECOVERY = 0x03,
- EC_EFS_BOOT_MODE_RESET = 0xff,
/* boot_mode is uint8_t */
EC_EFS_BOOT_MODE_LIMIT = 255,