diff options
-rw-r--r-- | src/soc/intel/common/block/cse/cse_lite.c | 49 |
1 files changed, 42 insertions, 7 deletions
diff --git a/src/soc/intel/common/block/cse/cse_lite.c b/src/soc/intel/common/block/cse/cse_lite.c index b985a94628..1f9e2ce225 100644 --- a/src/soc/intel/common/block/cse/cse_lite.c +++ b/src/soc/intel/common/block/cse/cse_lite.c @@ -4,6 +4,8 @@ #include <soc/intel/common/reset.h> #include <intelblocks/cse.h> #include <security/vboot/vboot_common.h> +#include <security/vboot/misc.h> +#include <vb2_api.h> /* Converts bp index to boot partition string */ #define GET_BP_STR(bp_index) (bp_index ? "RW" : "RO") @@ -27,6 +29,30 @@ enum boot_partition_id { RW = 1 }; +/* CSE recovery sub-error codes */ +enum csme_failure_reason { + /* Unspecified error */ + CSE_LITE_SKU_UNSPECIFIED = 1, + + /* CSE fails to boot from RW */ + CSE_LITE_SKU_RW_JUMP_ERROR = 2, + + /* CSE RW boot partition access error */ + CSE_LITE_SKU_RW_ACCESS_ERROR = 3, + + /* Fails to set next boot partition as RW */ + CSE_LITE_SKU_RW_SWITCH_ERROR = 4, + + /* CSE firmware update failure */ + CSE_LITE_SKU_FW_UPDATE_ERROR = 5, + + /* Fails to communicate with CSE */ + CSE_LITE_SKU_COMMUNICATION_ERROR = 6, + + /* Fails to wipe CSE runtime data */ + CSE_LITE_SKU_DATA_WIPE_ERROR = 7 +}; + /* * Boot partition status. * The status is returned in response to MKHI_BUP_COMMON_GET_BOOT_PARTITION_INFO cmd. @@ -112,6 +138,19 @@ struct get_bp_info_rsp { struct cse_bp_info bp_info; } __packed; +static void cse_trigger_recovery(uint8_t rec_sub_code) +{ + if (CONFIG(VBOOT)) { + struct vb2_context *ctx; + ctx = vboot_get_context(); + vb2api_fail(ctx, VB2_RECOVERY_INTEL_CSE_LITE_SKU, rec_sub_code); + vboot_save_data(ctx); + vboot_reboot(); + } + + die("cse_lite: Failed to trigger recovery mode(recovery subcode:%d)\n", rec_sub_code); +} + static uint8_t cse_get_current_bp(const struct cse_bp_info *cse_bp_info) { return cse_bp_info->current_bp; @@ -306,22 +345,18 @@ void cse_fw_sync(void *unused) if (!cse_get_bp_info(&cse_bp_info)) { printk(BIOS_ERR, "cse_bp: Failed to get CSE boot partition info\n"); - goto failed; + cse_trigger_recovery(CSE_LITE_SKU_COMMUNICATION_ERROR); } - if (!cse_is_rw_info_valid(&cse_bp_info.bp_info)) { printk(BIOS_ERR, "cse_bp: CSE RW partition is not valid\n"); - goto failed; + cse_trigger_recovery(CSE_LITE_SKU_RW_JUMP_ERROR); } if (!cse_boot_to_rw(&cse_bp_info.bp_info)) { printk(BIOS_ERR, "cse_bp: Failed to switch to RW\n"); - goto failed; + cse_trigger_recovery(CSE_LITE_SKU_RW_SWITCH_ERROR); } - return; -failed: - do_global_reset(); } BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, cse_fw_sync, NULL); |