Anil Kumar K has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/74577 )
Change subject: [Test] [Do not Merge] soc/intel/cse_lite: Backup PSR data during CSE FW downgrade ......................................................................
[Test] [Do not Merge] soc/intel/cse_lite: Backup PSR data during CSE FW downgrade
Change-Id: I135d197b5df0a20def823fe615860b5ead4391f8 --- M src/commonlib/bsd/include/commonlib/bsd/elog.h M src/soc/intel/common/block/cse/cse_lite.c M src/soc/intel/common/block/include/intelblocks/cse.h M util/cbfstool/eventlog.c 4 files changed, 107 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/77/74577/1
diff --git a/src/commonlib/bsd/include/commonlib/bsd/elog.h b/src/commonlib/bsd/include/commonlib/bsd/elog.h index 783557f..e32c46f 100644 --- a/src/commonlib/bsd/include/commonlib/bsd/elog.h +++ b/src/commonlib/bsd/include/commonlib/bsd/elog.h @@ -216,6 +216,7 @@ #define ELOG_ME_PATH_RECOVERY 0x03 #define ELOG_ME_PATH_DISABLED 0x04 #define ELOG_ME_PATH_FW_UPDATE 0x05 +#define ELOG_ME_PATH_PSR_BACKUP_FAILED 0x06
#define ELOG_TYPE_MANAGEMENT_ENGINE_EXT 0xa4 #define ELOG_ME_PHASE_ROM 0 @@ -225,6 +226,7 @@ #define ELOG_ME_PHASE_MODULE 4 #define ELOG_ME_PHASE_UNKNOWN 5 #define ELOG_ME_PHASE_HOST 6 + struct elog_event_data_me_extended { uint8_t current_working_state; uint8_t operation_state; diff --git a/src/soc/intel/common/block/cse/cse_lite.c b/src/soc/intel/common/block/cse/cse_lite.c index 4cc9e19..8364ef8 100644 --- a/src/soc/intel/common/block/cse/cse_lite.c +++ b/src/soc/intel/common/block/cse/cse_lite.c @@ -11,10 +11,12 @@ #include <intelblocks/cse.h> #include <intelblocks/cse_layout.h> #include <intelblocks/spi.h> +#include <pc80/mc146818rtc.h> #include <security/vboot/misc.h> #include <security/vboot/vboot_common.h> #include <soc/intel/common/reset.h> #include <timestamp.h> +#include <elog.h>
#define BPDT_HEADER_SZ sizeof(struct bpdt_header) #define BPDT_ENTRY_SZ sizeof(struct bpdt_entry) @@ -132,8 +134,39 @@ struct cse_bp_info bp_info; } __packed;
+#if 0 +struct psr_heci_fw_downgrade_backup_res { + struct psr_heci_header header; + PSR_STATUS status; +} __packed; +#endif static const char * const cse_regions[] = {"RO", "RW"};
+#if 0 +static enum cb_err cse_backup_psr(struct psr_heci_fw_downgrade_backup_res *res) +{ + + struct psr_heci_fw_downgrade_backup_req { + struct psr_heci_header header; + } __packed; + + struct psr_heci_fw_downgrade_backup_req req = { + .header.command = PSR_HECI_FW_DOWNGRADE_BKUP, + }; + + printk(BIOS_DEBUG, "cse_lite: backup PSR command setting client address to 4\n"); + size_t resp_size = sizeof(struct psr_heci_fw_downgrade_backup_res); + + if (heci_send_receive(&req, sizeof(req), + res, &resp_size, 0x4)) { + printk(BIOS_ERR, "cse_lite: backup PSR command error\n"); + return CB_ERR; + } + + return CB_SUCCESS; +} +#endif + void cse_log_ro_write_protection_info(bool mfg_mode) { bool cse_ro_wp_en = is_spi_wp_cse_ro_en(); @@ -728,6 +761,35 @@ static enum cb_err cse_prep_for_rw_update(const struct cse_bp_info *cse_bp_info, enum cse_update_status status) { + +#if 1 + //static struct psr_heci_fw_downgrade_backup_res backup_psr_resp; + + /* In case of CSE downgrade, before clearing CSE data we need to take a backup of + * PSR data. + */ + + if (status == CSE_UPDATE_DOWNGRADE) { + printk(BIOS_DEBUG, "AKK: doing a firmware downgrade\n"); + /* switch to RW to issue backup PSR command */ + if (0x55 != cmos_read(PSR_BACKUP_STATUS_CMOS_OFFSET)) { + printk(BIOS_DEBUG, "AKK: boot CSE to RW\n"); + if (CB_SUCCESS == cse_boot_to_rw(cse_bp_info)) { + //if (CB_SUCCESS == cse_backup_psr(&backup_psr_resp)) { + printk(BIOS_DEBUG, "cse_lite: backup PSR command sent!\n"); + /* update CMOS address with backup status + * Backup done = 0x55 + * Backup pending = 0x33 + */ + printk(BIOS_DEBUG, "cse_lite: set PSR_BACKUP_STATUS_CMOS_OFFSET to 0x55!\n"); + cmos_write(0x55, PSR_BACKUP_STATUS_CMOS_OFFSET); + //if (PSR_STATUS_SUCCESS != backup_psr_resp.status) + // printk(BIOS_DEBUG, "cse_lite: backup PSR command returned %d\n", backup_psr_resp.status); + //} + } + } + } +#endif /* * To set CSE's operation mode to HMRFPO mode: * 1. Ensure CSE to boot from RO(BP1) @@ -741,6 +803,8 @@ printk(BIOS_ERR, "cse_lite: CSE data clear failed!\n"); return CB_SUCCESS; } + /* reset the CMOS address */ + cmos_write(0x22, PSR_BACKUP_STATUS_CMOS_OFFSET); }
return cse_hmrfpo_enable(); @@ -808,6 +872,8 @@ return CSE_LITE_SKU_RW_ACCESS_ERROR; }
+ printk(BIOS_DEBUG, "cse_lite: Add elog event \n"); + elog_add_event_byte(ELOG_TYPE_MANAGEMENT_ENGINE, ELOG_ME_PATH_PSR_BACKUP_FAILED); status = cse_check_update_status(cse_bp_info, &target_rdev); if (status == CSE_UPDATE_NOT_REQUIRED) return CSE_NO_ERROR; diff --git a/src/soc/intel/common/block/include/intelblocks/cse.h b/src/soc/intel/common/block/include/intelblocks/cse.h index 6b708ca..ec9ca28 100644 --- a/src/soc/intel/common/block/include/intelblocks/cse.h +++ b/src/soc/intel/common/block/include/intelblocks/cse.h @@ -76,6 +76,12 @@ /* Number of cse boot performance data */ #define NUM_CSE_BOOT_PERF_DATA 64
+/* PSR_HECI_FW_DOWNGRADE_BACKUP Command */ +#define PSR_HECI_FW_DOWNGRADE_BKUP 0x3 + +/* CMOS address to store PSR_HECI_FW_DOWNGRADE_BACKUP command send status */ +#define PSR_BACKUP_STATUS_CMOS_OFFSET 161 + /* HFSTS register offsets in PCI config space */ enum { PCI_ME_HFSTS1 = 0x40, @@ -101,6 +107,27 @@ uint8_t result; } __packed;
+#if 1 +/* PSR HECI message status */ +typedef enum +{ + PSR_STATUS_SUCCESS, + PSR_STATUS_FEATURE_NOT_SUPPORTED, + PSR_STATUS_UPID_DISABLED, + PSR_STATUS_ACTION_NOT_ALLOWED, + PSR_STATUS_INVALID_INPUT_PARAMETER, + PSR_STATUS_INTERNAL_ERROR, + PSR_STATUS_NOT_ALLOWED_AFTER_EOP, +} PSR_STATUS; + +/* PSR HECI message header */ +struct psr_heci_header { + uint8_t command; + uint8_t reserved; + uint16_t length; +} __packed; +#endif + /* CSE FW Version */ struct fw_version { uint16_t major; diff --git a/util/cbfstool/eventlog.c b/util/cbfstool/eventlog.c index 93590a1..079dc9d 100644 --- a/util/cbfstool/eventlog.c +++ b/util/cbfstool/eventlog.c @@ -179,6 +179,7 @@ return; }
+ printf("AKK print eventlog type\n"); eventlog_printf("%s", type); }
@@ -366,6 +367,7 @@ {ELOG_ME_PATH_RECOVERY, "Recovery"}, {ELOG_ME_PATH_DISABLED, "Disabled"}, {ELOG_ME_PATH_FW_UPDATE, "Firmware Update"}, + {ELOG_ME_PATH_PSR_BACKUP_FAILED, "PSR backup command Error"}, {0, NULL}, }; static const struct valstr coreboot_post_codes[] = { @@ -564,6 +566,7 @@ case ELOG_TYPE_MANAGEMENT_ENGINE: { const uint8_t *path = event_get_data(event); eventlog_printf("%s", val2str(*path, me_path_types)); + printf("AKK %d\n", *path); break; } case ELOG_TYPE_MEM_CACHE_UPDATE: {