smm: complete SMM setup

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>
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 20bf631..eccef88 100644
--- a/src/fw/smm.c
+++ b/src/fw/smm.c
@@ -103,6 +103,11 @@
     /* 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(acpi_pm_base + PIIX_PMIO_GLBCTL);
+    outl(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 @@
     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,
          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 */