diff options
author | Duncan Laurie <dlaurie@chromium.org> | 2012-10-03 19:07:05 -0700 |
---|---|---|
committer | Ronald G. Minnich <rminnich@gmail.com> | 2012-11-14 05:41:12 +0100 |
commit | 11290c49b0e7f8c13e0128b0e2005b5466b49f5d (patch) | |
tree | a8af7d2b6ddd3afc64038d153e83f767ec4626f0 | |
parent | 313ec9d15bb8c56fc76eb40be920552cb231465e (diff) |
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>
-rw-r--r-- | src/arch/x86/boot/acpi.c | 25 | ||||
-rw-r--r-- | src/arch/x86/include/arch/acpi.h | 2 | ||||
-rw-r--r-- | src/include/cbmem.h | 1 | ||||
-rw-r--r-- | src/southbridge/via/vt8237r/Makefile.inc | 1 | ||||
-rw-r--r-- | src/southbridge/via/vt8237r/smi.c | 33 |
5 files changed, 59 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; diff --git a/src/include/cbmem.h b/src/include/cbmem.h index b43c97233d..21efe77b0a 100644 --- a/src/include/cbmem.h +++ b/src/include/cbmem.h @@ -44,6 +44,7 @@ #define CBMEM_ID_FREESPACE 0x46524545 #define CBMEM_ID_GDT 0x4c474454 #define CBMEM_ID_ACPI 0x41435049 +#define CBMEM_ID_ACPI_GNVS 0x474e5653 #define CBMEM_ID_CBTABLE 0x43425442 #define CBMEM_ID_PIRQ 0x49525154 #define CBMEM_ID_MPTABLE 0x534d5054 diff --git a/src/southbridge/via/vt8237r/Makefile.inc b/src/southbridge/via/vt8237r/Makefile.inc index 08545feca2..6474e585e7 100644 --- a/src/southbridge/via/vt8237r/Makefile.inc +++ b/src/southbridge/via/vt8237r/Makefile.inc @@ -25,4 +25,5 @@ driver-y += sata.c driver-y += usb.c driver-$(CONFIG_PIRQ_ROUTE) += pirq.c ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += fadt.c +ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c diff --git a/src/southbridge/via/vt8237r/smi.c b/src/southbridge/via/vt8237r/smi.c new file mode 100644 index 0000000000..b865a5b0b0 --- /dev/null +++ b/src/southbridge/via/vt8237r/smi.c @@ -0,0 +1,33 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008-2009 coresystems GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stdint.h> +#include <arch/io.h> +#include <cpu/cpu.h> + +void smm_setup_structures(void *gnvs, void *tcg, void *smi1) +{ + /* The GDT or coreboot table is going to live here. But a long time + * after we relocated the GNVS, so this is not troublesome. + */ + *(u32 *)0x500 = (u32)gnvs; + *(u32 *)0x504 = (u32)tcg; + *(u32 *)0x508 = (u32)smi1; + outb(0xea, 0xb2); +} |