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 #include #include +#include #if CONFIG_COLLECT_TIMESTAMPS #include #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 +#include +#include + +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); +}