[SeaBIOS] [PATCH 2/4] smm: Don't use PCIDevices list in smm_setup().

Kevin O'Connor kevin at koconnor.net
Sat Mar 9 01:53:36 CET 2013


The smm_setup() call is invoked from resume.  The PCIDevices list is
only valid during POST.  Cache the necessary PCI BDF ids so that
PCIDevices isn't needed.

Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
 src/paravirt.c |  1 +
 src/smm.c      | 66 +++++++++++++++++++++++++++++++---------------------------
 src/util.h     |  1 +
 3 files changed, 37 insertions(+), 31 deletions(-)

diff --git a/src/paravirt.c b/src/paravirt.c
index f061039..4a26c6e 100644
--- a/src/paravirt.c
+++ b/src/paravirt.c
@@ -106,6 +106,7 @@ qemu_platform_setup(void)
 
     // Initialize pci
     pci_setup();
+    smm_device_setup();
     smm_setup();
 
     // Initialize mtrr and smp
diff --git a/src/smm.c b/src/smm.c
index 490a626..a424a29 100644
--- a/src/smm.c
+++ b/src/smm.c
@@ -6,6 +6,7 @@
 // This file may be distributed under the terms of the GNU LGPLv3 license.
 
 #include "pci.h" // pci_config_writel
+#include "pci_regs.h" // PCI_DEVICE_ID
 #include "util.h" // wbinvd
 #include "config.h" // CONFIG_*
 #include "ioport.h" // outb
@@ -111,46 +112,30 @@ smm_relocate_and_restore(void)
 #define PIIX_APMC_EN    (1 << 25)
 
 // This code is hardcoded for PIIX4 Power Management device.
-static void piix4_apmc_smm_setup(struct pci_device *pci, void *arg)
+static void piix4_apmc_smm_setup(int isabdf, int i440_bdf)
 {
-    struct pci_device *i440_pci = pci_find_device(PCI_VENDOR_ID_INTEL
-                                                  , PCI_DEVICE_ID_INTEL_82441);
-    if (!i440_pci)
-        return;
-
     /* check if SMM init is already done */
-    u32 value = pci_config_readl(pci->bdf, PIIX_DEVACTB);
+    u32 value = pci_config_readl(isabdf, PIIX_DEVACTB);
     if (value & PIIX_APMC_EN)
         return;
 
     /* enable the SMM memory window */
-    pci_config_writeb(i440_pci->bdf, I440FX_SMRAM, 0x02 | 0x48);
+    pci_config_writeb(i440_bdf, I440FX_SMRAM, 0x02 | 0x48);
 
     smm_save_and_copy();
 
     /* enable SMI generation when writing to the APMC register */
-    pci_config_writel(pci->bdf, PIIX_DEVACTB, value | PIIX_APMC_EN);
+    pci_config_writel(isabdf, PIIX_DEVACTB, value | PIIX_APMC_EN);
 
     smm_relocate_and_restore();
 
     /* close the SMM memory window and enable normal SMM */
-    pci_config_writeb(i440_pci->bdf, I440FX_SMRAM, 0x02 | 0x08);
+    pci_config_writeb(i440_bdf, I440FX_SMRAM, 0x02 | 0x08);
 }
 
 /* PCI_VENDOR_ID_INTEL && PCI_DEVICE_ID_INTEL_ICH9_LPC */
-void ich9_lpc_apmc_smm_setup(struct pci_device *dev, void *arg)
+void ich9_lpc_apmc_smm_setup(int isabdf, int mch_bdf)
 {
-    struct pci_device *mch_dev;
-    int mch_bdf;
-
-    // This code is hardcoded for Q35 Power Management device.
-    mch_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
-                              PCI_DEVICE_ID_INTEL_Q35_MCH);
-    mch_bdf = mch_dev->bdf;
-
-    if (mch_bdf < 0)
-        return;
-
     /* check if SMM init is already done */
     u32 value = inl(PORT_ACPI_PM_BASE + ICH9_PMIO_SMI_EN);
     if (value & ICH9_PMIO_SMI_EN_APMC_EN)
@@ -171,21 +156,40 @@ void ich9_lpc_apmc_smm_setup(struct pci_device *dev, void *arg)
     pci_config_writeb(mch_bdf, Q35_HOST_BRIDGE_SMRAM, 0x02 | 0x08);
 }
 
-static const struct pci_device_id smm_init_tbl[] = {
-    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3,
-               piix4_apmc_smm_setup),
-    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_LPC,
-               ich9_lpc_apmc_smm_setup),
+static int SMMISADeviceBDF = -1, SMMPMDeviceBDF = -1;
+
+void
+smm_device_setup(void)
+{
+    if (!CONFIG_USE_SMM)
+	return;
 
-    PCI_DEVICE_END,
-};
+    struct pci_device *isapci, *pmpci;
+    isapci = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3);
+    pmpci = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441);
+    if (isapci && pmpci) {
+        SMMISADeviceBDF = isapci->bdf;
+        SMMPMDeviceBDF = pmpci->bdf;
+        return;
+    }
+    isapci = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_LPC);
+    pmpci = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_Q35_MCH);
+    if (isapci && pmpci) {
+        SMMISADeviceBDF = isapci->bdf;
+        SMMPMDeviceBDF = pmpci->bdf;
+    }
+}
 
 void
 smm_setup(void)
 {
-    if (!CONFIG_USE_SMM)
+    if (!CONFIG_USE_SMM || SMMISADeviceBDF < 0)
 	return;
 
     dprintf(3, "init smm\n");
-    pci_find_init_device(smm_init_tbl, NULL);
+    u16 device = pci_config_readw(SMMISADeviceBDF, PCI_DEVICE_ID);
+    if (device == PCI_DEVICE_ID_INTEL_82371AB_3)
+        piix4_apmc_smm_setup(SMMISADeviceBDF, SMMPMDeviceBDF);
+    else
+        ich9_lpc_apmc_smm_setup(SMMISADeviceBDF, SMMPMDeviceBDF);
 }
diff --git a/src/util.h b/src/util.h
index 306a8bf..af029fc 100644
--- a/src/util.h
+++ b/src/util.h
@@ -314,6 +314,7 @@ extern const u8 pci_irqs[4];
 void pci_setup(void);
 
 // smm.c
+void smm_device_setup(void);
 void smm_setup(void);
 
 // smp.c
-- 
1.7.11.7




More information about the SeaBIOS mailing list