Patchwork [3/7] seabios: smm: move out piix4 specific logic to dev-i440fx.c

login
register
mail settings
Submitter Isaku Yamahata
Date July 12, 2010, 11:47 a.m.
Message ID <a3d99dafd746b13db918eeeab0548bec1b176b06.1278935094.git.yamahata@valinux.co.jp>
Download mbox | patch
Permalink /patch/58595/
State New
Headers show

Comments

Isaku Yamahata - July 12, 2010, 11:47 a.m.
move out piix4 specific logic to dev-i440fx.c by using pci_find_init_device().

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
 src/dev-i440fx.c |   25 +++++++++++++++++++++++++
 src/dev-i440fx.h |    1 +
 src/post.h       |    6 ++++++
 src/smm.c        |   18 +++++++++++++-----
 4 files changed, 45 insertions(+), 5 deletions(-)

Patch

diff --git a/src/dev-i440fx.c b/src/dev-i440fx.c
index 5961efc..17d42ce 100644
--- a/src/dev-i440fx.c
+++ b/src/dev-i440fx.c
@@ -16,6 +16,7 @@ 
 #include "pci_regs.h" // PCI_INTERRUPT_LINE
 #include "post.h"
 #include "dev-i440fx.h"
+#include "post.h"
 
 #define I440FX_PAM0     0x59
 
@@ -64,3 +65,27 @@  void piix4_pm_init(u16 bdf, void *arg)
     pci_config_writel(bdf, 0x90, PORT_SMB_BASE | 1);
     pci_config_writeb(bdf, 0xd2, 0x09); /* enable SMBus io space */
 }
+
+#define PIIX_DEVACTB    0x58
+#define PIIX_APMC_EN    (1 << 25)
+
+static int piix4_apmc_is_enabled(u16 bdf)
+{
+    /* check if SMM init is already done */
+    u32 value = pci_config_readl(bdf, PIIX_DEVACTB);
+    return value & PIIX_APMC_EN;
+}
+
+static void piix4_apmc_enable(u16 bdf)
+{
+    /* enable SMI generation when writing to the APMC register */
+    u32 value = pci_config_readl(bdf, PIIX_DEVACTB);
+    pci_config_writel(bdf, PIIX_DEVACTB, value | PIIX_APMC_EN);
+}
+
+void piix4_apmc_detected(u16 bdf, void *arg)
+{
+    struct apmc_ops *ops = arg;
+    ops->is_enabled = piix4_apmc_is_enabled;
+    ops->enable = piix4_apmc_enable;
+}
diff --git a/src/dev-i440fx.h b/src/dev-i440fx.h
index abcd0d1..934e7f2 100644
--- a/src/dev-i440fx.h
+++ b/src/dev-i440fx.h
@@ -7,5 +7,6 @@  void i440fx_shadow_detected(u16 bdf, void *arg);
 void piix_isa_bridge_init(u16 bdf, void *arg);
 void piix_ide_init(u16 bdf, void *arg);
 void piix4_pm_init(u16 bdf, void *arg);
+void piix4_apmc_detected(u16 bdf, void *arg);
 
 #endif // __I440FX_H
diff --git a/src/post.h b/src/post.h
index 18f89fb..2996878 100644
--- a/src/post.h
+++ b/src/post.h
@@ -10,4 +10,10 @@  struct pam_regs
     u32 pam0;
 };
 
+struct apmc_ops
+{
+    int (*is_enabled)(u16 bdf);
+    void (*enable)(u16 bdf);
+};
+
 #endif /* __POST_H */
diff --git a/src/smm.c b/src/smm.c
index 3f53ef9..baa272f 100644
--- a/src/smm.c
+++ b/src/smm.c
@@ -10,6 +10,8 @@ 
 #include "config.h" // CONFIG_*
 #include "ioport.h" // outb
 #include "pci_ids.h" // PCI_VENDOR_ID_INTEL
+#include "post.h"
+#include "dev-i440fx.h"
 
 ASM32FLAT(
     ".global smm_relocation_start\n"
@@ -72,6 +74,13 @@  ASM32FLAT(
 extern u8 smm_relocation_start, smm_relocation_end;
 extern u8 smm_code_start, smm_code_end;
 
+static const struct pci_device_id apmc_ops_tbl[] = {
+    PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3,
+               piix4_apmc_detected),
+
+    PCI_DEVICE_END,
+};
+
 void
 smm_init(void)
 {
@@ -84,8 +93,8 @@  smm_init(void)
     dprintf(3, "init smm\n");
 
     // This code is hardcoded for PIIX4 Power Management device.
-    int bdf = pci_find_device(PCI_VENDOR_ID_INTEL
-                              , PCI_DEVICE_ID_INTEL_82371AB_3);
+    struct apmc_ops apmc_ops;
+    int bdf = pci_find_init_device(apmc_ops_tbl, &apmc_ops);
     if (bdf < 0)
         // Device not found
         return;
@@ -95,8 +104,7 @@  smm_init(void)
         return;
 
     /* check if SMM init is already done */
-    u32 value = pci_config_readl(bdf, 0x58);
-    if (value & (1 << 25))
+    if (apmc_ops.is_enabled(bdf))
         return;
 
     /* enable the SMM memory window */
@@ -110,7 +118,7 @@  smm_init(void)
            &smm_relocation_end - &smm_relocation_start);
 
     /* enable SMI generation when writing to the APMC register */
-    pci_config_writel(bdf, 0x58, value | (1 << 25));
+    apmc_ops.enable(bdf);
 
     /* init APM status port */
     outb(0x01, PORT_SMI_STATUS);