summaryrefslogtreecommitdiff
path: root/src/arch/x86
diff options
context:
space:
mode:
authorDuncan Laurie <dlaurie@chromium.org>2012-10-03 19:07:05 -0700
committerRonald G. Minnich <rminnich@gmail.com>2012-11-14 05:41:12 +0100
commit11290c49b0e7f8c13e0128b0e2005b5466b49f5d (patch)
treea8af7d2b6ddd3afc64038d153e83f767ec4626f0 /src/arch/x86
parent313ec9d15bb8c56fc76eb40be920552cb231465e (diff)
downloadcoreboot-11290c49b0e7f8c13e0128b0e2005b5466b49f5d.tar.xz
SMM: Restore GNVS pointer in the resume path
The SMM GNVS pointer is normally updated only when the ACPI tables are created, which does not happen in the resume path. In order to restore this pointer it needs to be available at resume time. The method used to locate it at creation time cannot be used again as that magic signature is overwritten with the address itself. So a new CBMEM ID is added to store the 32bit address so it can be found again easily. A new function is defined to save this pointer in CBMEM which needs to be called when the ACPI tables are created in each mainboard when write_acpi_tables() is called. The cpu_index variable had to be renamed due to a conflict when cpu/cpu.h is added for the smm_setup_structures() prototype. Change-Id: Ic764ff54525e12b617c1dd8d6a3e5c4f547c3e6b Signed-off-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: http://review.coreboot.org/1765 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/boot/acpi.c25
-rw-r--r--src/arch/x86/include/arch/acpi.h2
2 files changed, 24 insertions, 3 deletions
diff --git a/src/arch/x86/boot/acpi.c b/src/arch/x86/boot/acpi.c
index ca2f1d4562..4d405d9fe0 100644
--- a/src/arch/x86/boot/acpi.c
+++ b/src/arch/x86/boot/acpi.c
@@ -32,6 +32,7 @@
#include <device/pci.h>
#include <cbmem.h>
#include <cpu/x86/lapic_def.h>
+#include <cpu/cpu.h>
#if CONFIG_COLLECT_TIMESTAMPS
#include <timestamp.h>
#endif
@@ -140,7 +141,7 @@ int acpi_create_madt_lapic(acpi_madt_lapic_t *lapic, u8 cpu, u8 apic)
unsigned long acpi_create_madt_lapics(unsigned long current)
{
device_t cpu;
- int cpu_index = 0;
+ int index = 0;
for (cpu = all_devices; cpu; cpu = cpu->next) {
if ((cpu->path.type != DEVICE_PATH_APIC) ||
@@ -150,8 +151,8 @@ unsigned long acpi_create_madt_lapics(unsigned long current)
if (!cpu->enabled)
continue;
current += acpi_create_madt_lapic((acpi_madt_lapic_t *)current,
- cpu_index, cpu->path.apic.apic_id);
- cpu_index++;
+ index, cpu->path.apic.apic_id);
+ index++;
}
return current;
@@ -627,6 +628,17 @@ void suspend_resume(void)
/* If we happen to be resuming find wakeup vector and jump to OS. */
wake_vec = acpi_find_wakeup_vector();
if (wake_vec) {
+#if CONFIG_HAVE_SMI_HANDLER
+ u32 *gnvs_address = cbmem_find(CBMEM_ID_ACPI_GNVS);
+
+ /* Restore GNVS pointer in SMM if found */
+ if (gnvs_address && *gnvs_address) {
+ printk(BIOS_DEBUG, "Restore GNVS pointer to 0x%08x\n",
+ *gnvs_address);
+ smm_setup_structures((void *)*gnvs_address, NULL, NULL);
+ }
+#endif
+
/* Call mainboard resume handler first, if defined. */
if (mainboard_suspend_resume)
mainboard_suspend_resume();
@@ -770,3 +782,10 @@ void acpi_jump_to_wakeup(void *vector)
HIGH_MEMORY_SAVE);
}
#endif
+
+void acpi_save_gnvs(u32 gnvs_address)
+{
+ u32 *gnvs = cbmem_add(CBMEM_ID_ACPI_GNVS, sizeof(*gnvs));
+ if (gnvs)
+ *gnvs = gnvs_address;
+}
diff --git a/src/arch/x86/include/arch/acpi.h b/src/arch/x86/include/arch/acpi.h
index b39e8c074c..022a45fd52 100644
--- a/src/arch/x86/include/arch/acpi.h
+++ b/src/arch/x86/include/arch/acpi.h
@@ -552,6 +552,8 @@ void acpi_write_hest(acpi_hest_t *hest);
unsigned long acpi_create_hest_error_source(acpi_hest_t *hest, acpi_hest_esd_t *esd, u16 type, void *data, u16 len);
unsigned long acpi_fill_hest(acpi_hest_t *hest);
+void acpi_save_gnvs(u32 gnvs_address);
+
#if CONFIG_HAVE_ACPI_RESUME
/* 0 = S0, 1 = S1 ...*/
extern u8 acpi_slp_type;