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(-)
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);