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>
This commit is contained in:
Duncan Laurie
2012-10-03 19:07:05 -07:00
committed by Ronald G. Minnich
parent 313ec9d15b
commit 11290c49b0
5 changed files with 59 additions and 3 deletions

View File

@ -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;
}