aboutsummaryrefslogtreecommitdiff
path: root/src/soc/intel/common/block/cse/cse_lite.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/intel/common/block/cse/cse_lite.c')
-rw-r--r--src/soc/intel/common/block/cse/cse_lite.c49
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);