amd/stoneyridge: Add S3 support to POST
Add/update the romstage and ramstage paths to check for S3 resume
and call the appropriate AGESA functions.
TEST=Suspend/Resume Kahlee with full S3 patch stack
BUG=b:69614064
Change-Id: Ie6ae66f88b888fff3a800b4ed55dd1f6fed712b2
Signed-off-by: Marshall Dawson <marshalldawson3rd@gmail.com>
Reviewed-on: https://review.coreboot.org/22731
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
diff --git a/src/soc/amd/stoneyridge/Kconfig b/src/soc/amd/stoneyridge/Kconfig
index 7975523..8bf577c 100644
--- a/src/soc/amd/stoneyridge/Kconfig
+++ b/src/soc/amd/stoneyridge/Kconfig
@@ -50,7 +50,7 @@
select SOC_AMD_COMMON_BLOCK_PI
select SOC_AMD_COMMON_BLOCK_PSP
select SOC_AMD_COMMON_BLOCK_CAR
- select SOC_AMD_COMMON_BLOCK_S3
+ select SOC_AMD_COMMON_BLOCK_S3 if HAVE_ACPI_RESUME
select C_ENVIRONMENT_BOOTBLOCK
select BOOTBLOCK_CONSOLE
select BOOT_DEVICE_SUPPORTS_WRITES if BOOT_DEVICE_SPI_FLASH
diff --git a/src/soc/amd/stoneyridge/chip.c b/src/soc/amd/stoneyridge/chip.c
index d3a8bc4..f5efcfd 100644
--- a/src/soc/amd/stoneyridge/chip.c
+++ b/src/soc/amd/stoneyridge/chip.c
@@ -21,6 +21,7 @@
#include <device/device.h>
#include <device/pci.h>
#include <drivers/i2c/designware/dw_i2c.h>
+#include <romstage_handoff.h>
#include <soc/cpu.h>
#include <soc/northbridge.h>
#include <soc/pci_devs.h>
@@ -110,12 +111,19 @@
static void earliest_ramstage(void *unused)
{
- post_code(0x46);
- if (IS_ENABLED(CONFIG_SOC_AMD_PSP_SELECTABLE_SMU_FW))
- psp_load_named_blob(MBOX_BIOS_CMD_SMU_FW2, "smu_fw2");
+ if (!romstage_handoff_is_resume()) {
+ post_code(0x46);
+ if (IS_ENABLED(CONFIG_SOC_AMD_PSP_SELECTABLE_SMU_FW))
+ psp_load_named_blob(MBOX_BIOS_CMD_SMU_FW2, "smu_fw2");
- post_code(0x47);
- do_agesawrapper(agesawrapper_amdinitenv, "amdinitenv");
+ post_code(0x47);
+ do_agesawrapper(agesawrapper_amdinitenv, "amdinitenv");
+ } else {
+ /* Complete the initial system restoration */
+ post_code(0x46);
+ do_agesawrapper(agesawrapper_amds3laterestore,
+ "amds3laterestore");
+ }
}
BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, earliest_ramstage, NULL);
diff --git a/src/soc/amd/stoneyridge/northbridge.c b/src/soc/amd/stoneyridge/northbridge.c
index 9d2823f..2449077 100644
--- a/src/soc/amd/stoneyridge/northbridge.c
+++ b/src/soc/amd/stoneyridge/northbridge.c
@@ -28,6 +28,7 @@
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
+#include <romstage_handoff.h>
#include <amdblocks/agesawrapper.h>
#include <amdblocks/agesawrapper_call.h>
#include <agesa_headers.h>
@@ -425,14 +426,9 @@
void domain_enable_resources(device_t dev)
{
- if (acpi_is_wakeup_s3())
- do_agesawrapper(agesawrapper_fchs3laterestore,
- "fchs3laterestore");
-
/* Must be called after PCI enumeration and resource allocation */
- else
+ if (!romstage_handoff_is_resume())
do_agesawrapper(agesawrapper_amdinitmid, "amdinitmid");
- printk(BIOS_DEBUG, " ader - leaving domain_enable_resources.\n");
}
void domain_set_resources(device_t dev)
diff --git a/src/soc/amd/stoneyridge/romstage.c b/src/soc/amd/stoneyridge/romstage.c
index 24d6289..490fd9e 100644
--- a/src/soc/amd/stoneyridge/romstage.c
+++ b/src/soc/amd/stoneyridge/romstage.c
@@ -15,6 +15,7 @@
*/
#include <arch/cpu.h>
+#include <arch/acpi.h>
#include <cpu/x86/msr.h>
#include <cpu/x86/mtrr.h>
#include <cpu/amd/mtrr.h>
@@ -24,6 +25,7 @@
#include <device/device.h>
#include <chip.h>
#include <program_loading.h>
+#include <romstage_handoff.h>
#include <amdblocks/agesawrapper.h>
#include <amdblocks/agesawrapper_call.h>
#include <soc/northbridge.h>
@@ -40,45 +42,59 @@
msr_t base, mask;
msr_t mtrr_cap = rdmsr(MTRR_CAP_MSR);
int vmtrrs = mtrr_cap.lo & MTRR_CAP_VCNT;
+ int s3_resume = acpi_s3_resume_allowed() && acpi_is_wakeup_s3();
int i;
console_init();
- post_code(0x40);
- do_agesawrapper(agesawrapper_amdinitpost, "amdinitpost");
+ if (!s3_resume) {
+ post_code(0x40);
+ do_agesawrapper(agesawrapper_amdinitpost, "amdinitpost");
- post_code(0x41);
- /*
- * TODO: This is a hack to work around current AGESA behavior. AGESA
- * needs to change to reflect that coreboot owns the MTRRs.
- *
- * After setting up DRAM, AGESA also completes the configuration of the
- * MTRRs, setting regions to WB. Anything written to memory between
- * now and and when CAR is dismantled will be in cache and lost. For
- * now, set the regions UC to ensure the writes get to DRAM.
- */
- for (i = 0 ; i < vmtrrs ; i++) {
- base = rdmsr(MTRR_PHYS_BASE(i));
- mask = rdmsr(MTRR_PHYS_MASK(i));
- if (!(mask.lo & MTRR_PHYS_MASK_VALID))
- continue;
+ post_code(0x41);
+ /*
+ * TODO: This is a hack to work around current AGESA behavior.
+ * AGESA needs to change to reflect that coreboot owns
+ * the MTRRs.
+ *
+ * After setting up DRAM, AGESA also completes the configuration
+ * of the MTRRs, setting regions to WB. Anything written to
+ * memory between now and and when CAR is dismantled will be
+ * in cache and lost. For now, set the regions UC to ensure
+ * the writes get to DRAM.
+ */
+ for (i = 0 ; i < vmtrrs ; i++) {
+ base = rdmsr(MTRR_PHYS_BASE(i));
+ mask = rdmsr(MTRR_PHYS_MASK(i));
+ if (!(mask.lo & MTRR_PHYS_MASK_VALID))
+ continue;
- if ((base.lo & 0x7) == MTRR_TYPE_WRBACK) {
- base.lo &= ~0x7;
- base.lo |= MTRR_TYPE_UNCACHEABLE;
- wrmsr(MTRR_PHYS_BASE(i), base);
+ if ((base.lo & 0x7) == MTRR_TYPE_WRBACK) {
+ base.lo &= ~0x7;
+ base.lo |= MTRR_TYPE_UNCACHEABLE;
+ wrmsr(MTRR_PHYS_BASE(i), base);
+ }
}
+ /* Disable WB from to region 4GB-TOM2. */
+ msr_t sys_cfg = rdmsr(SYSCFG_MSR);
+ sys_cfg.lo &= ~SYSCFG_MSR_TOM2WB;
+ wrmsr(SYSCFG_MSR, sys_cfg);
+ } else {
+ printk(BIOS_INFO, "S3 detected\n");
+ post_code(0x60);
+ do_agesawrapper(agesawrapper_amdinitresume, "amdinitresume");
+
+ post_code(0x61);
}
- /* Disable WB from to region 4GB-TOM2. */
- msr_t sys_cfg = rdmsr(SYSCFG_MSR);
- sys_cfg.lo &= ~SYSCFG_MSR_TOM2WB;
- wrmsr(SYSCFG_MSR, sys_cfg);
post_code(0x42);
psp_notify_dram();
post_code(0x43);
- cbmem_initialize_empty();
+ if (cbmem_recovery(s3_resume))
+ printk(BIOS_CRIT, "Failed to recover cbmem\n");
+ if (romstage_handoff_init(s3_resume))
+ printk(BIOS_ERR, "Failed to set romstage handoff data\n");
post_code(0x44);
if (postcar_frame_init(&pcf, 1 * KiB))