diff --git a/src/soc/intel/common/block/cse/cse.c b/src/soc/intel/common/block/cse/cse.c index 6389044428..53c5fe1471 100644 --- a/src/soc/intel/common/block/cse/cse.c +++ b/src/soc/intel/common/block/cse/cse.c @@ -298,6 +298,28 @@ bool cse_is_hfs1_spi_protected(void) return !hfs1.fields.mfg_mode; } +#define ME_HFSTS2_CUR_PM_EVENT_SHIFT 24 +#define ME_HFSTS2_CUR_PM_EVENT_MASK (0xf << ME_HFSTS2_CUR_PM_EVENT_SHIFT) + +static uint8_t cse_get_hfs2_current_pm_event(void) +{ + uint32_t data = me_read_config32(PCI_ME_HFSTS2); + return (uint8_t)((data & ME_HFSTS2_CUR_PM_EVENT_MASK) >> + ME_HFSTS2_CUR_PM_EVENT_SHIFT); +} + +bool cse_check_host_cold_reset(void) +{ + uint8_t event = cse_get_hfs2_current_pm_event(); + + switch (event) { + case PWR_CYCLE_RESET_CMOFF: + return true; + default: + return false; + } +} + bool cse_is_hfs3_fw_sku_lite(void) { union me_hfsts3 hfs3; diff --git a/src/soc/intel/common/block/include/intelblocks/cse.h b/src/soc/intel/common/block/include/intelblocks/cse.h index c97e4ec65c..99dd7d5e17 100644 --- a/src/soc/intel/common/block/include/intelblocks/cse.h +++ b/src/soc/intel/common/block/include/intelblocks/cse.h @@ -383,6 +383,10 @@ enum rst_req_type { CSE_RESET_ONLY = 3, }; +enum cse_fw_sts_current_pm_event { + PWR_CYCLE_RESET_CMOFF = 0xb, +}; + /* * Sends GLOBAL_RESET_REQ cmd to CSE with reset type GLOBAL_RESET. * Returns 0 on failure and 1 on success. @@ -618,4 +622,11 @@ bool is_cse_fw_update_required(void); */ bool is_cse_boot_to_rw(void); +/* + * Check if the CSE FW Status Current Power Management Event indicates that the + * host came out of cold reset. + * Returns true if the host came out of a cold reset, false otherwise. + */ +bool cse_check_host_cold_reset(void); + #endif // SOC_INTEL_COMMON_CSE_H