SMI generation requires two bits to be set in PIIX4, one for APMC interrupts specifically and a general one.
For Q35 it is the same, plus it is a good thing to lock SMIs after enabling them.
Signed-off-by: Paolo Bonzini pbonzini@redhat.com --- src/fw/dev-piix.h | 2 ++ src/fw/dev-q35.h | 3 +++ src/fw/smm.c | 12 +++++++++++- 3 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/src/fw/dev-piix.h b/src/fw/dev-piix.h index c6dce03..c389f17 100644 --- a/src/fw/dev-piix.h +++ b/src/fw/dev-piix.h @@ -17,6 +17,8 @@ /* ICH9 PM I/O registers */ #define PIIX_GPE0_BLK 0xafe0 #define PIIX_GPE0_BLK_LEN 4 +#define PIIX_PMIO_GLBCTL 0x28 +#define PIIX_PMIO_GLBCTL_SMI_EN 1
/* FADT ACPI_ENABLE/ACPI_DISABLE */ #define PIIX_ACPI_ENABLE 0xf1 diff --git a/src/fw/dev-q35.h b/src/fw/dev-q35.h index 6ae039f..c6f8bd9 100644 --- a/src/fw/dev-q35.h +++ b/src/fw/dev-q35.h @@ -23,6 +23,8 @@ #define ICH9_LPC_PIRQA_ROUT 0x60 #define ICH9_LPC_PIRQE_ROUT 0x68 #define ICH9_LPC_PIRQ_ROUT_IRQEN 0x80 +#define ICH9_LPC_GEN_PMCON_1 0xa0 +#define ICH9_LPC_GEN_PMCON_1_SMI_LOCK (1 << 4) #define ICH9_LPC_PORT_ELCR1 0x4d0 #define ICH9_LPC_PORT_ELCR2 0x4d1 #define PCI_DEVICE_ID_INTEL_ICH9_SMBUS 0x2930 @@ -38,6 +40,7 @@ #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_GLB_SMI_EN (1 << 0)
/* FADT ACPI_ENABLE/ACPI_DISABLE */ #define ICH9_APM_ACPI_ENABLE 0x2 diff --git a/src/fw/smm.c b/src/fw/smm.c index 07f9234..ca0e2fc 100644 --- a/src/fw/smm.c +++ b/src/fw/smm.c @@ -103,6 +103,11 @@ static void piix4_apmc_smm_setup(int isabdf, int i440_bdf) /* enable SMI generation when writing to the APMC register */ pci_config_writel(isabdf, PIIX_DEVACTB, value | PIIX_DEVACTB_APMC_EN);
+ /* enable SMI generation */ + value = inl(PORT_ACPI_PM_BASE + PIIX_PMIO_GLBCTL); + outl(PORT_ACPI_PM_BASE + PIIX_PMIO_GLBCTL, + value | PIIX_PMIO_GLBCTL_SMI_EN); + smm_relocate_and_restore();
/* close the SMM memory window and enable normal SMM */ @@ -123,9 +128,14 @@ void ich9_lpc_apmc_smm_setup(int isabdf, int mch_bdf) smm_save_and_copy();
/* enable SMI generation when writing to the APMC register */ - outl(value | ICH9_PMIO_SMI_EN_APMC_EN, + outl(value | ICH9_PMIO_SMI_EN_APMC_EN | ICH9_PMIO_SMI_EN_GLB_SMI_EN, PORT_ACPI_PM_BASE + ICH9_PMIO_SMI_EN);
+ /* lock SMI generation */ + value = pci_config_readw(isabdf, ICH9_LPC_GEN_PMCON_1); + pci_config_writel(isabdf, ICH9_LPC_GEN_PMCON_1, + value | ICH9_LPC_GEN_PMCON_1_SMI_LOCK); + smm_relocate_and_restore();
/* close the SMM memory window and enable normal SMM */