diff --git a/src/soc/intel/common/block/cse/cse.c b/src/soc/intel/common/block/cse/cse.c index afce985fa8..5877d537f8 100644 --- a/src/soc/intel/common/block/cse/cse.c +++ b/src/soc/intel/common/block/cse/cse.c @@ -68,6 +68,9 @@ #define MEI_HDR_CSE_ADDR_START 0 #define MEI_HDR_CSE_ADDR (((1 << 8) - 1) << MEI_HDR_CSE_ADDR_START) +/* Wait up to 5 seconds for CSE to boot from RO(BP1) */ +#define CSE_DELAY_BOOT_TO_RO (5 * 1000) + static struct cse_device { uintptr_t sec_bar; } cse; @@ -304,6 +307,26 @@ uint8_t cse_wait_sec_override_mode(void) return 1; } +/* + * Polls for CSE's current operation mode 'Soft Temporary Disable'. + * The CSE enters the current operation mode when it boots from RO(BP1). + */ +uint8_t cse_wait_com_soft_temp_disable(void) +{ + struct stopwatch sw; + stopwatch_init_msecs_expire(&sw, CSE_DELAY_BOOT_TO_RO); + while (!cse_is_hfs1_com_soft_temp_disable()) { + udelay(HECI_DELAY); + if (stopwatch_expired(&sw)) { + printk(BIOS_ERR, "HECI: Timed out waiting for CSE to boot from RO!\n"); + return 0; + } + } + printk(BIOS_SPEW, "HECI: CSE took %lu ms to boot from RO\n", + stopwatch_duration_msecs(&sw)); + return 1; +} + static int wait_heci_ready(void) { struct stopwatch sw; diff --git a/src/soc/intel/common/block/include/intelblocks/cse.h b/src/soc/intel/common/block/include/intelblocks/cse.h index af8d85272d..c597a3f46f 100644 --- a/src/soc/intel/common/block/include/intelblocks/cse.h +++ b/src/soc/intel/common/block/include/intelblocks/cse.h @@ -192,4 +192,9 @@ bool cse_is_hfs1_com_soft_temp_disable(void); */ bool cse_is_hfs3_fw_sku_custom(void); +/* + * Polls for CSE's current operation mode 'Soft Temp Disable'. + * Returns 0 on failure and 1 on success. + */ +uint8_t cse_wait_com_soft_temp_disable(void); #endif // SOC_INTEL_COMMON_CSE_H