diff options
Diffstat (limited to 'src/cpu/x86')
-rw-r--r-- | src/cpu/x86/smm/smi_trigger.c | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/src/cpu/x86/smm/smi_trigger.c b/src/cpu/x86/smm/smi_trigger.c index f1031a00f6..4b637450b7 100644 --- a/src/cpu/x86/smm/smi_trigger.c +++ b/src/cpu/x86/smm/smi_trigger.c @@ -1,9 +1,12 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include <acpi/acpi_gnvs.h> #include <arch/io.h> #include <console/console.h> #include <cpu/x86/smm.h> +static void set_smm_gnvs_ptr(void); + int apm_control(u8 cmd) { if (!CONFIG(HAVE_SMI_HANDLER)) @@ -21,7 +24,8 @@ int apm_control(u8 cmd) printk(BIOS_DEBUG, "Enabling ACPI via APMC.\n"); break; case APM_CNT_GNVS_UPDATE: - break; + set_smm_gnvs_ptr(); + return 0; case APM_CNT_FINALIZE: printk(BIOS_DEBUG, "Finalizing SMM.\n"); break; @@ -41,3 +45,32 @@ int apm_control(u8 cmd) printk(BIOS_DEBUG, "APMC done.\n"); return 0; } + +static void set_smm_gnvs_ptr(void) +{ + uintptr_t gnvs_address; + + if (CONFIG(ACPI_NO_SMI_GNVS)) { + printk(BIOS_WARNING, "%s() is not implemented\n", __func__); + return; + } + + gnvs_address = (uintptr_t)acpi_get_gnvs(); + if (!gnvs_address) + return; + + /* + * Issue SMI to set the gnvs pointer in SMM. + * + * EAX = APM_CNT_GNVS_UPDATE + * EBX = gnvs pointer + * EDX = APM_CNT + */ + asm volatile ( + "outb %%al, %%dx\n\t" + : /* ignore result */ + : "a" (APM_CNT_GNVS_UPDATE), + "b" (gnvs_address), + "d" (APM_CNT) + ); +} |