soc/intel/common: Trigger recovery mode for CSE Lite SKU run time errors

Implement triggering recovery mode for CSE Lite SKU runtime errors. Also,
define recovery subcodes for various possible Lite SKU runtime errors.

BUG=b:153520354
TEST=Verified on hatch

Signed-off-by: Sridhar Siricilla <sridhar.siricilla@intel.com>
Change-Id: Ib7744fc4fd0e41804d9b45079bf706b300220c62
Reviewed-on: https://review.coreboot.org/c/coreboot/+/40563
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: V Sowmya <v.sowmya@intel.com>
Reviewed-by: Rizwan Qureshi <rizwan.qureshi@intel.com>
Reviewed-by: Furquan Shaikh <furquan@google.com>
This commit is contained in:
Sridhar Siricilla 2020-05-03 19:08:18 +05:30 committed by Furquan Shaikh
parent 8d09a06aa6
commit 87e36c442e
1 changed files with 42 additions and 7 deletions

View File

@ -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);