aboutsummaryrefslogtreecommitdiff
path: root/src/southbridge/intel/i82801gx/smi.c
diff options
context:
space:
mode:
authorSven Schnelle <svens@stackframe.org>2011-06-14 20:55:54 +0200
committerSven Schnelle <svens@stackframe.org>2011-06-15 23:11:44 +0200
commitbfe8e5186ea9916634d31182ec0437f6175e7724 (patch)
treec47d6e948425e4bbe0d9c38cc2a1eb1a954070a9 /src/southbridge/intel/i82801gx/smi.c
parentb629d14becd78c634ad412df726d964ed5d51214 (diff)
SMM: don't overwrite SMM memory on resume
Overwriting the SMM Area on resume leaves us with all variables cleared out, i.e., the GNVS pointer is no longer available, which makes SMIF function calls impossible. Change-Id: I08ab4ffd41df0922d63c017822de1f89a3ff254d Signed-off-by: Sven Schnelle <svens@stackframe.org> Reviewed-on: http://review.coreboot.org/34 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/southbridge/intel/i82801gx/smi.c')
-rw-r--r--src/southbridge/intel/i82801gx/smi.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/src/southbridge/intel/i82801gx/smi.c b/src/southbridge/intel/i82801gx/smi.c
index 95ec1129a3..5be24049be 100644
--- a/src/southbridge/intel/i82801gx/smi.c
+++ b/src/southbridge/intel/i82801gx/smi.c
@@ -320,6 +320,16 @@ static void smm_relocate(void)
static int smm_handler_copied = 0;
+static int is_wakeup(void)
+{
+ device_t dev0 = dev_find_slot(0, PCI_DEVFN(0,0));
+
+ if (!dev0)
+ return 0;
+
+ return pci_read_config32(dev0, 0xdc) == SKPAD_ACPI_S3_MAGIC;
+}
+
static void smm_install(void)
{
/* The first CPU running this gets to copy the SMM handler. But not all
@@ -329,13 +339,19 @@ static void smm_install(void)
return;
smm_handler_copied = 1;
- /* enable the SMM memory window */
- pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM,
- D_OPEN | G_SMRAME | C_BASE_SEG);
- /* copy the real SMM handler */
- memcpy((void *)0xa0000, &_binary_smm_start, (size_t)&_binary_smm_size);
- wbinvd();
+ /* if we're resuming from S3, the SMM code is already in place,
+ * so don't copy it again to keep the current SMM state */
+
+ if (!is_wakeup()) {
+ /* enable the SMM memory window */
+ pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM,
+ D_OPEN | G_SMRAME | C_BASE_SEG);
+
+ /* copy the real SMM handler */
+ memcpy((void *)0xa0000, &_binary_smm_start, (size_t)&_binary_smm_size);
+ wbinvd();
+ }
/* close the SMM memory window and enable normal SMM */
pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM,