From a554b71e3207556dd563c5253e79ff15a601dc0e Mon Sep 17 00:00:00 2001 From: Aaron Durbin Date: Fri, 10 Jun 2016 18:04:21 -0500 Subject: [PATCH] soc/intel/apollolake: provide fake PM1 SMI status bit It appears that PM1 is not wired up to the SMI status register, but it does definitely cause SMIs to trigger. Therefore, provide a fake PM1 status bit by checking the power button status when SMI status is indicating no status as well as the PM1 control indicating that SCI mode is not enabled. BUG=chrome-os-partner:54262 TEST=Smashed power button on reef to cause SMI in firmware. No longer loops infinitely with constant SMIs firing. Change-Id: I9aa1b5f79b651cbc19a2d3353d9ef65429386889 Signed-off-by: Aaron Durbin Reviewed-on: https://review.coreboot.org/15155 Tested-by: build bot (Jenkins) Reviewed-by: Duncan Laurie Reviewed-by: Furquan Shaikh --- src/soc/intel/apollolake/include/soc/pm.h | 1 + src/soc/intel/apollolake/pmutil.c | 19 ++++++++++++++++++- src/soc/intel/apollolake/smihandler.c | 1 + 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/soc/intel/apollolake/include/soc/pm.h b/src/soc/intel/apollolake/include/soc/pm.h index c889453f2e..856872ed97 100644 --- a/src/soc/intel/apollolake/include/soc/pm.h +++ b/src/soc/intel/apollolake/include/soc/pm.h @@ -100,6 +100,7 @@ #define MC_SMI_STS 12 #define GPIO_UNLOCK_SMI_STS 11 #define GPIO_SMI_STS 10 +#define FAKE_PM1_SMI_STS 8 #define SWSMI_TMR_SMI_STS 6 #define APM_SMI_STS 5 #define SLP_SMI_STS 4 diff --git a/src/soc/intel/apollolake/pmutil.c b/src/soc/intel/apollolake/pmutil.c index bebc1c7178..6e47911fcd 100644 --- a/src/soc/intel/apollolake/pmutil.c +++ b/src/soc/intel/apollolake/pmutil.c @@ -60,6 +60,7 @@ static uint32_t print_smi_status(uint32_t smi_sts) [SLP_SMI_STS] = "SLP_SMI", [APM_SMI_STS] = "APM", [SWSMI_TMR_SMI_STS] = "SWSMI_TMR", + [FAKE_PM1_SMI_STS] = "PM1", [GPIO_SMI_STS]= "GPIO_SMI", [GPIO_UNLOCK_SMI_STS]= "GPIO_UNLOCK_SSMI", [MC_SMI_STS] = "MCSMI", @@ -96,7 +97,23 @@ static uint32_t reset_smi_status(void) uint32_t clear_smi_status(void) { - return print_smi_status(reset_smi_status()); + uint32_t sts = reset_smi_status(); + + /* + * Check for power button status if nothing else is indicating an SMI + * and SMIs aren't turned into SCIs. Apparently, there is no PM1 status + * bit in the SMI status register. That makes things difficult for + * determining if the power button caused an SMI. + */ + if (sts == 0 && !(inl(ACPI_PMIO_BASE + PM1_CNT) & SCI_EN)) { + uint16_t pm1_sts = inw(ACPI_PMIO_BASE + PM1_STS); + + /* Fake PM1 status bit if power button pressed. */ + if (pm1_sts & PWRBTN_STS) + sts |= (1 << FAKE_PM1_SMI_STS); + } + + return print_smi_status(sts); } uint32_t get_smi_en(void) diff --git a/src/soc/intel/apollolake/smihandler.c b/src/soc/intel/apollolake/smihandler.c index fd175e30d8..1521920fa1 100644 --- a/src/soc/intel/apollolake/smihandler.c +++ b/src/soc/intel/apollolake/smihandler.c @@ -46,6 +46,7 @@ const struct smm_save_state_ops *get_smm_save_state_ops(void) const smi_handler_t southbridge_smi[32] = { [SLP_SMI_STS] = southbridge_smi_sleep, [APM_SMI_STS] = southbridge_smi_apmc, + [FAKE_PM1_SMI_STS] = southbridge_smi_pm1, [TCO_SMI_STS] = southbridge_smi_tco, [PERIODIC_SMI_STS] = southbridge_smi_periodic, };