[SeaBIOS] [PATCH 5/5] smm: communicate end of SMI to chipset
Paolo Bonzini
pbonzini at redhat.com
Thu May 15 13:22:30 CEST 2014
Both the PIIX and ICH9 require two writes to re-enable SMIs, one for all
SMIs (EOS) and one specific to port 0xb2 SMIs (APM_STS). Configure the
values at setup time, and perform the I/O while in SMM. The variables
reside in SMRAM themselves, and are accessed with a CS segment override.
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
---
src/fw/dev-piix.h | 3 +++
src/fw/dev-q35.h | 3 +++
src/fw/smm.c | 26 ++++++++++++++++++++++++++
3 files changed, 32 insertions(+)
diff --git a/src/fw/dev-piix.h b/src/fw/dev-piix.h
index c389f17..5df0a89 100644
--- a/src/fw/dev-piix.h
+++ b/src/fw/dev-piix.h
@@ -17,7 +17,10 @@
/* ICH9 PM I/O registers */
#define PIIX_GPE0_BLK 0xafe0
#define PIIX_GPE0_BLK_LEN 4
+#define PIIX_PMIO_GLBSTS 0x18
+#define PIIX_PMIO_GLBSTS_APM_STS (1 << 5)
#define PIIX_PMIO_GLBCTL 0x28
+#define PIIX_PMIO_GLBCTL_EOS (1 << 16)
#define PIIX_PMIO_GLBCTL_SMI_EN 1
/* FADT ACPI_ENABLE/ACPI_DISABLE */
diff --git a/src/fw/dev-q35.h b/src/fw/dev-q35.h
index c6f8bd9..3f8b8d6 100644
--- a/src/fw/dev-q35.h
+++ b/src/fw/dev-q35.h
@@ -40,7 +40,10 @@
#define ICH9_PMIO_GPE0_BLK_LEN 0x10
#define ICH9_PMIO_SMI_EN 0x30
#define ICH9_PMIO_SMI_EN_APMC_EN (1 << 5)
+#define ICH9_PMIO_SMI_EN_EOS (1 << 1)
#define ICH9_PMIO_SMI_EN_GLB_SMI_EN (1 << 0)
+#define ICH9_PMIO_SMI_STS 0x34
+#define ICH9_PMIO_SMI_STS_APM_STS (1 << 5)
/* FADT ACPI_ENABLE/ACPI_DISABLE */
#define ICH9_APM_ACPI_ENABLE 0x2
diff --git a/src/fw/smm.c b/src/fw/smm.c
index b0cc6f5..dbb9f82 100644
--- a/src/fw/smm.c
+++ b/src/fw/smm.c
@@ -19,6 +19,10 @@
extern u8 smm_code_start, smm_code_end;
+extern u16 smm_eos_port, smm_status_port;
+extern u32 smm_eos_value, smm_status_value;
+#define SMMVAR(x) "%cs:("__stringify(x)" - smm_code_start + 0x8000)"
+
ASM32FLAT(
".global smm_code_start, smm_code_end\n"
" .code16gcc\n"
@@ -44,7 +48,19 @@ ASM32FLAT(
" movw $" __stringify(PORT_SMI_STATUS) ", %dx\n"
" outb %al, %dx\n"
"smm_exit:\n"
+ " movw "SMMVAR(smm_status_port)", %dx\n"
+ " movl "SMMVAR(smm_status_value)", %eax\n"
+ " outl %eax, %dx\n" // The SMM status register is write-1-clears
+ " movw "SMMVAR(smm_eos_port)", %dx\n"
+ " inl %dx, %eax\n"
+ " orl "SMMVAR(smm_eos_value)", %eax\n"
+ " outl %eax, %dx\n"
" rsm\n"
+ ".align 4\n"
+ "smm_eos_port: .word 0\n"
+ "smm_status_port: .word 0\n"
+ "smm_eos_value: .long 0\n"
+ "smm_status_value: .long 0\n"
"smm_code_end:\n"
" .code32\n"
);
@@ -90,6 +106,11 @@ static void piix4_apmc_smm_setup(int isabdf, int i440_bdf)
if (value & PIIX_DEVACTB_APMC_EN)
return;
+ smm_eos_port = PORT_ACPI_PM_BASE + PIIX_PMIO_GLBCTL;
+ smm_eos_value = PIIX_PMIO_GLBCTL_EOS;
+ smm_status_port = PORT_ACPI_PM_BASE + PIIX_PMIO_GLBSTS;
+ smm_status_value = PIIX_PMIO_GLBSTS_APM_STS;
+
/* enable the SMM memory window */
pci_config_writeb(i440_bdf, I440FX_SMRAM, 0x02 | 0x48);
@@ -117,6 +138,11 @@ void ich9_lpc_apmc_smm_setup(int isabdf, int mch_bdf)
if (value & ICH9_PMIO_SMI_EN_APMC_EN)
return;
+ smm_eos_port = PORT_ACPI_PM_BASE + ICH9_PMIO_SMI_EN;
+ smm_eos_value = ICH9_PMIO_SMI_EN_EOS;
+ smm_status_port = PORT_ACPI_PM_BASE + ICH9_PMIO_SMI_STS;
+ smm_status_value = ICH9_PMIO_SMI_STS_APM_STS;
+
/* enable the SMM memory window */
pci_config_writeb(mch_bdf, Q35_HOST_BRIDGE_SMRAM, 0x02 | 0x48);
--
1.9.0
More information about the SeaBIOS
mailing list