diff options
Diffstat (limited to 'common/ec_efs.c')
-rw-r--r-- | common/ec_efs.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/common/ec_efs.c b/common/ec_efs.c index 8f5bece989..f801696338 100644 --- a/common/ec_efs.c +++ b/common/ec_efs.c @@ -43,7 +43,9 @@ static struct ec_efs_context_ { */ static void set_boot_mode_(uint8_t mode_val) { - CPRINTS("boot_mode: 0x%02x -> 0x%02x", ec_efs_ctx.boot_mode, mode_val); + if (ec_efs_ctx.boot_mode != mode_val) + cprints(CC_SYSTEM, "boot_mode: 0x%02x -> 0x%02x", + ec_efs_ctx.boot_mode, mode_val); ec_efs_ctx.boot_mode = mode_val; @@ -181,9 +183,28 @@ uint16_t ec_efs_set_boot_mode(const char * const data, const uint8_t size) boot_mode = data[0]; - if (ec_efs_ctx.boot_mode != EC_EFS_BOOT_MODE_NORMAL) { + switch (boot_mode) { + case EC_EFS_BOOT_MODE_NORMAL: + /* + * Per EC-EFS2 design, CR50 accepts the repeating commands + * as long as the result is the same. It is to be tolerant + * against CR50 response loss, so that EC can resend the + * same command. + */ + if (ec_efs_ctx.boot_mode == EC_EFS_BOOT_MODE_NORMAL) + break; + /* + * Once the boot mode is NO_BOOT, then it must not be + * set to NORMAL mode without resetting EC. + */ board_reboot_ec_deferred(0); return 0; + + case EC_EFS_BOOT_MODE_NO_BOOT: + break; + + default: + return CR50_COMM_ERROR_BAD_PAYLOAD; } set_boot_mode_(boot_mode); @@ -220,6 +241,10 @@ uint16_t ec_efs_verify_hash(const char *hash_data, const uint8_t size) return CR50_COMM_ERROR_BAD_PAYLOAD; } + /* + * Once the boot mode is not NORMAL, (i.e. it is NO_BOOT), then CR50 + * should not approve the hash verification, but reset EC. + */ if (ec_efs_ctx.boot_mode != EC_EFS_BOOT_MODE_NORMAL) { board_reboot_ec_deferred(0); return 0; |