Richard Spiegel has uploaded this change for review. ( https://review.coreboot.org/28247
Change subject: soc/amd/stoneyridge/smihandler.c: Report pending wake event ......................................................................
soc/amd/stoneyridge/smihandler.c: Report pending wake event
There's a small window of opportunity when CPU is already in SMM but has not yet entered S3 for a wake event to happen, which would cause a failed S3 entry. Check for pending events at the very last moment possible, and if there are pending wake events report them.
BUG=b:111100312 TEST=build and boot grunt.
Change-Id: I9472fdf481897fcf9f4c669f6b1514ef479fce7a Signed-off-by: Richard Spiegel richard.spiegel@silverbackltd.com --- M src/soc/amd/stoneyridge/smihandler.c 1 file changed, 29 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/47/28247/1
diff --git a/src/soc/amd/stoneyridge/smihandler.c b/src/soc/amd/stoneyridge/smihandler.c index ef24baa..f00ead6 100644 --- a/src/soc/amd/stoneyridge/smihandler.c +++ b/src/soc/amd/stoneyridge/smihandler.c @@ -122,7 +122,8 @@
static void sb_slp_typ_handler(void) { - uint32_t pm1cnt, pci_ctrl; + uint32_t pm1cnt, pci_ctrl, reg32; + uint16_t reg16; uint8_t slp_typ, rst_ctrl;
/* Figure out SLP_TYP */ @@ -171,6 +172,33 @@ rst_ctrl |= SLPTYPE_CONTROL_EN; pm_write8(PM_RST_CTRL1, rst_ctrl);
+ /* + * Before the final command, check if there's pending wake + * event. Read enable first, so that reading the actual status + * is as close as possible to entering S3. The idea is to + * minimize the opportunity for a wake event to happen before + * actually entering S3. If there's a pending wake event, log + * it and continue normal path. S3 will fail and the wake event + * becomes a SCI. + */ + reg16 = inw(ACPI_PM1_EN); + reg32 = inl(ACPI_GPE0_EN); + if (IS_ENABLED(CONFIG_ELOG_GSMI)) { + if ((reg16 & inw(ACPI_PM1_STS)) || + (reg32 & inl(ACPI_GPE0_STS))) { + reg16 &= inw(ACPI_PM1_STS); + if (reg16) + elog_add_error( + ELOG_SLEEP_PENDING_PM1_WAKE, + (u32)reg16); + reg32 &= inl(ACPI_GPE0_STS); + if (reg32) + elog_add_error( + ELOG_SLEEP_PENDING_GPE0_WAKE, + reg32); + } + } /* if (IS_ENABLED(CONFIG_ELOG_GSMI)) */ + /* Reissue Pm1 write */ outl(pm1cnt | SLP_EN, pm_acpi_pm_cnt_blk()); hlt();