summaryrefslogtreecommitdiffstats
path: root/src/southbridge/intel/i82801gx/smihandler.c
diff options
context:
space:
mode:
authorArthur Heymans <arthur@aheymans.xyz>2018-04-10 12:56:19 +0200
committerArthur Heymans <arthur@aheymans.xyz>2018-11-27 12:09:53 +0000
commit31312b21d147938cb4d88ed90e570ac7804c930d (patch)
tree57a714d7939d23838e990686b089f9364dc049ef /src/southbridge/intel/i82801gx/smihandler.c
parent516f06e0fb7e4ba4e9ae6c024ab36a079b7cbb76 (diff)
downloadcoreboot-31312b21d147938cb4d88ed90e570ac7804c930d.tar.gz
coreboot-31312b21d147938cb4d88ed90e570ac7804c930d.tar.bz2
coreboot-31312b21d147938cb4d88ed90e570ac7804c930d.zip
sb/intel/i82801gx: Use common Intel SMM code
Use the common Intel code to set up smm and the smihandler. This is expected to break S3 resume and other smihandler related functionality as this code is meant to be used with CONFIG_SMM_TSEG. Platforms (i945, pineview, x4x) using this southbridge will adapt the CONFIG_SMM_TSEG codepath in subsequent patches. Tested on Intel D945GCLF, still boots fine but breaks S3 resume support because it hangs on SMI. Change-Id: If7016a3b98fc5f14c287ce800325084f9dc602a0 Signed-off-by: Arthur Heymans <arthur@aheymans.xyz> Reviewed-on: https://review.coreboot.org/c/25594 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Patrick Georgi <pgeorgi@google.com>
Diffstat (limited to 'src/southbridge/intel/i82801gx/smihandler.c')
-rw-r--r--src/southbridge/intel/i82801gx/smihandler.c626
1 files changed, 6 insertions, 620 deletions
diff --git a/src/southbridge/intel/i82801gx/smihandler.c b/src/southbridge/intel/i82801gx/smihandler.c
index 3f537c07f09c..1b4a063d0e24 100644
--- a/src/southbridge/intel/i82801gx/smihandler.c
+++ b/src/southbridge/intel/i82801gx/smihandler.c
@@ -22,6 +22,7 @@
#include <device/pci_def.h>
#include <halt.h>
#include <pc80/mc146818rtc.h>
+#include <southbridge/intel/common/pmutil.h>
#include "i82801gx.h"
/* I945 */
@@ -45,246 +46,10 @@ u8 smm_initialized = 0;
*/
global_nvs_t *gnvs = (global_nvs_t *)0x0;
-static void alt_gpi_mask(u16 clr, u16 set)
+void southbridge_update_gnvs(u8 apm_cnt, int *smm_done)
{
- u16 alt_gp = inw(pmbase + ALT_GP_SMI_EN);
- alt_gp &= ~clr;
- alt_gp |= set;
- outw(alt_gp, pmbase + ALT_GP_SMI_EN);
-}
-
-static void gpe0_mask(u32 clr, u32 set)
-{
- u32 gpe0 = inl(pmbase + GPE0_EN);
- gpe0 &= ~clr;
- gpe0 |= set;
- outl(gpe0, pmbase + GPE0_EN);
-}
-
-void gpi_route_interrupt(u8 gpi, u8 mode)
-{
- u32 gpi_rout;
- if (gpi >= 16)
- return;
-
- alt_gpi_mask(1 << gpi, 0);
- gpe0_mask(1 << (gpi+16), 0);
-
- gpi_rout = pci_read_config32(PCI_DEV(0, 0x1f, 0), GPIO_ROUT);
- gpi_rout &= ~(3 << (2 * gpi));
- gpi_rout |= ((mode & 3) << (2 * gpi));
- pci_write_config32(PCI_DEV(0, 0x1f, 0), GPIO_ROUT, gpi_rout);
-
- if (mode == GPI_IS_SCI)
- gpe0_mask(0, 1 << (gpi+16));
- else if (mode == GPI_IS_SMI)
- alt_gpi_mask(0, 1 << gpi);
-}
-
-/**
- * @brief read and clear PM1_STS
- * @return PM1_STS register
- */
-static u16 reset_pm1_status(void)
-{
- u16 reg16;
-
- reg16 = inw(pmbase + PM1_STS);
- /* set status bits are cleared by writing 1 to them */
- outw(reg16, pmbase + PM1_STS);
-
- return reg16;
-}
-
-static void dump_pm1_status(u16 pm1_sts)
-{
- printk(BIOS_SPEW, "PM1_STS: ");
- if (pm1_sts & (1 << 15))
- printk(BIOS_SPEW, "WAK ");
- if (pm1_sts & (1 << 14))
- printk(BIOS_SPEW, "PCIEXPWAK ");
- if (pm1_sts & (1 << 11))
- printk(BIOS_SPEW, "PRBTNOR ");
- if (pm1_sts & (1 << 10))
- printk(BIOS_SPEW, "RTC ");
- if (pm1_sts & (1 << 8))
- printk(BIOS_SPEW, "PWRBTN ");
- if (pm1_sts & (1 << 5))
- printk(BIOS_SPEW, "GBL ");
- if (pm1_sts & (1 << 4))
- printk(BIOS_SPEW, "BM ");
- if (pm1_sts & (1 << 0))
- printk(BIOS_SPEW, "TMROF ");
- printk(BIOS_SPEW, "\n");
- int reg16 = inw(pmbase + PM1_EN);
- printk(BIOS_SPEW, "PM1_EN: %x\n", reg16);
-}
-
-/**
- * @brief read and clear SMI_STS
- * @return SMI_STS register
- */
-static u32 reset_smi_status(void)
-{
- u32 reg32;
-
- reg32 = inl(pmbase + SMI_STS);
- /* set status bits are cleared by writing 1 to them */
- outl(reg32, pmbase + SMI_STS);
-
- return reg32;
-}
-
-static void dump_smi_status(u32 smi_sts)
-{
- printk(BIOS_DEBUG, "SMI_STS: ");
- if (smi_sts & (1 << 26))
- printk(BIOS_DEBUG, "SPI ");
- if (smi_sts & (1 << 25))
- printk(BIOS_DEBUG, "EL_SMI ");
- if (smi_sts & (1 << 21))
- printk(BIOS_DEBUG, "MONITOR ");
- if (smi_sts & (1 << 20))
- printk(BIOS_DEBUG, "PCI_EXP_SMI ");
- if (smi_sts & (1 << 18))
- printk(BIOS_DEBUG, "INTEL_USB2 ");
- if (smi_sts & (1 << 17))
- printk(BIOS_DEBUG, "LEGACY_USB2 ");
- if (smi_sts & (1 << 16))
- printk(BIOS_DEBUG, "SMBUS_SMI ");
- if (smi_sts & (1 << 15))
- printk(BIOS_DEBUG, "SERIRQ_SMI ");
- if (smi_sts & (1 << 14))
- printk(BIOS_DEBUG, "PERIODIC ");
- if (smi_sts & (1 << 13))
- printk(BIOS_DEBUG, "TCO ");
- if (smi_sts & (1 << 12))
- printk(BIOS_DEBUG, "DEVMON ");
- if (smi_sts & (1 << 11))
- printk(BIOS_DEBUG, "MCSMI ");
- if (smi_sts & (1 << 10))
- printk(BIOS_DEBUG, "GPI ");
- if (smi_sts & (1 << 9))
- printk(BIOS_DEBUG, "GPE0 ");
- if (smi_sts & (1 << 8))
- printk(BIOS_DEBUG, "PM1 ");
- if (smi_sts & (1 << 6))
- printk(BIOS_DEBUG, "SWSMI_TMR ");
- if (smi_sts & (1 << 5))
- printk(BIOS_DEBUG, "APM ");
- if (smi_sts & (1 << 4))
- printk(BIOS_DEBUG, "SLP_SMI ");
- if (smi_sts & (1 << 3))
- printk(BIOS_DEBUG, "LEGACY_USB ");
- if (smi_sts & (1 << 2))
- printk(BIOS_DEBUG, "BIOS ");
- printk(BIOS_DEBUG, "\n");
-}
-
-
-/**
- * @brief read and clear GPE0_STS
- * @return GPE0_STS register
- */
-static u32 reset_gpe0_status(void)
-{
- u32 reg32;
-
- reg32 = inl(pmbase + GPE0_STS);
- /* set status bits are cleared by writing 1 to them */
- outl(reg32, pmbase + GPE0_STS);
-
- return reg32;
-}
-
-static void dump_gpe0_status(u32 gpe0_sts)
-{
- int i;
- printk(BIOS_DEBUG, "GPE0_STS: ");
- for (i = 31; i >= 16; i--) {
- if (gpe0_sts & (1 << i))
- printk(BIOS_DEBUG, "GPIO%d ", (i-16));
- }
- if (gpe0_sts & (1 << 14))
- printk(BIOS_DEBUG, "USB4 ");
- if (gpe0_sts & (1 << 13))
- printk(BIOS_DEBUG, "PME_B0 ");
- if (gpe0_sts & (1 << 12))
- printk(BIOS_DEBUG, "USB3 ");
- if (gpe0_sts & (1 << 11))
- printk(BIOS_DEBUG, "PME ");
- if (gpe0_sts & (1 << 10))
- printk(BIOS_DEBUG, "EL_SCI/BATLOW ");
- if (gpe0_sts & (1 << 9))
- printk(BIOS_DEBUG, "PCI_EXP ");
- if (gpe0_sts & (1 << 8))
- printk(BIOS_DEBUG, "RI ");
- if (gpe0_sts & (1 << 7))
- printk(BIOS_DEBUG, "SMB_WAK ");
- if (gpe0_sts & (1 << 6))
- printk(BIOS_DEBUG, "TCO_SCI ");
- if (gpe0_sts & (1 << 5))
- printk(BIOS_DEBUG, "AC97 ");
- if (gpe0_sts & (1 << 4))
- printk(BIOS_DEBUG, "USB2 ");
- if (gpe0_sts & (1 << 3))
- printk(BIOS_DEBUG, "USB1 ");
- if (gpe0_sts & (1 << 2))
- printk(BIOS_DEBUG, "HOT_PLUG ");
- if (gpe0_sts & (1 << 0))
- printk(BIOS_DEBUG, "THRM ");
- printk(BIOS_DEBUG, "\n");
-}
-
-
-/**
- * @brief read and clear TCOx_STS
- * @return TCOx_STS registers
- */
-static u32 reset_tco_status(void)
-{
- u32 tcobase = pmbase + 0x60;
- u32 reg32;
-
- reg32 = inl(tcobase + 0x04);
- /* set status bits are cleared by writing 1 to them */
- outl(reg32 & ~(1 << 18), tcobase + 0x04); // Don't clear BOOT_STS before SECOND_TO_STS
- if (reg32 & (1 << 18))
- outl(reg32 & (1 << 18), tcobase + 0x04); // clear BOOT_STS
-
- return reg32;
-}
-
-static void dump_tco_status(u32 tco_sts)
-{
- printk(BIOS_DEBUG, "TCO_STS: ");
- if (tco_sts & (1 << 20))
- printk(BIOS_DEBUG, "SMLINK_SLV ");
- if (tco_sts & (1 << 18))
- printk(BIOS_DEBUG, "BOOT ");
- if (tco_sts & (1 << 17))
- printk(BIOS_DEBUG, "SECOND_TO ");
- if (tco_sts & (1 << 16))
- printk(BIOS_DEBUG, "INTRD_DET ");
- if (tco_sts & (1 << 12))
- printk(BIOS_DEBUG, "DMISERR ");
- if (tco_sts & (1 << 10))
- printk(BIOS_DEBUG, "DMISMI ");
- if (tco_sts & (1 << 9))
- printk(BIOS_DEBUG, "DMISCI ");
- if (tco_sts & (1 << 8))
- printk(BIOS_DEBUG, "BIOSWR ");
- if (tco_sts & (1 << 7))
- printk(BIOS_DEBUG, "NEWCENTURY ");
- if (tco_sts & (1 << 3))
- printk(BIOS_DEBUG, "TIMEOUT ");
- if (tco_sts & (1 << 2))
- printk(BIOS_DEBUG, "TCO_INT ");
- if (tco_sts & (1 << 1))
- printk(BIOS_DEBUG, "SW_TCO ");
- if (tco_sts & (1 << 0))
- printk(BIOS_DEBUG, "NMI2SMI ");
- printk(BIOS_DEBUG, "\n");
+ gnvs = *(global_nvs_t **)0x500;
+ *smm_done = 1;
}
int southbridge_io_trap_handler(int smif)
@@ -304,312 +69,7 @@ int southbridge_io_trap_handler(int smif)
return 0;
}
-/**
- * @brief Set the EOS bit
- */
-void southbridge_smi_set_eos(void)
-{
- u8 reg8;
-
- reg8 = inb(pmbase + SMI_EN);
- reg8 |= EOS;
- outb(reg8, pmbase + SMI_EN);
-}
-
-static void busmaster_disable_on_bus(int bus)
-{
- int slot, func;
- unsigned int val;
- unsigned char hdr;
-
- for (slot = 0; slot < 0x20; slot++) {
- for (func = 0; func < 8; func++) {
- u32 reg32;
- pci_devfn_t dev = PCI_DEV(bus, slot, func);
-
- val = pci_read_config32(dev, PCI_VENDOR_ID);
-
- if (val == 0xffffffff || val == 0x00000000 ||
- val == 0x0000ffff || val == 0xffff0000)
- continue;
-
- /* Disable Bus Mastering for this one device */
- reg32 = pci_read_config32(dev, PCI_COMMAND);
- reg32 &= ~PCI_COMMAND_MASTER;
- pci_write_config32(dev, PCI_COMMAND, reg32);
-
- /* If this is a bridge, then follow it. */
- hdr = pci_read_config8(dev, PCI_HEADER_TYPE);
- hdr &= 0x7f;
- if (hdr == PCI_HEADER_TYPE_BRIDGE ||
- hdr == PCI_HEADER_TYPE_CARDBUS) {
- unsigned int buses;
- buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
- busmaster_disable_on_bus((buses >> 8) & 0xff);
- }
- }
- }
-}
-
-
-static void southbridge_smi_sleep(unsigned int node, smm_state_save_area_t *state_save)
-{
- u8 reg8;
- u32 reg32;
- u8 slp_typ;
- u8 s5pwr = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
-
- // save and recover RTC port values
- u8 tmp70, tmp72;
- tmp70 = inb(0x70);
- tmp72 = inb(0x72);
- get_option(&s5pwr, "power_on_after_fail");
- outb(tmp70, 0x70);
- outb(tmp72, 0x72);
-
- /* First, disable further SMIs */
- reg8 = inb(pmbase + SMI_EN);
- reg8 &= ~SLP_SMI_EN;
- outb(reg8, pmbase + SMI_EN);
-
- /* Figure out SLP_TYP */
- reg32 = inl(pmbase + PM1_CNT);
- printk(BIOS_SPEW, "SMI#: SLP = 0x%08x\n", reg32);
- slp_typ = acpi_sleep_from_pm1(reg32);
-
- /* Next, do the deed.
- */
-
- switch (slp_typ) {
- case ACPI_S0:
- printk(BIOS_DEBUG, "SMI#: Entering S0 (On)\n"); break;
- case ACPI_S1:
- printk(BIOS_DEBUG, "SMI#: Entering S1 (Assert STPCLK#)\n"); break;
- case ACPI_S3:
- printk(BIOS_DEBUG, "SMI#: Entering S3 (Suspend-To-RAM)\n");
- /* Invalidate the cache before going to S3 */
- wbinvd();
- break;
- case ACPI_S4:
- printk(BIOS_DEBUG, "SMI#: Entering S4 (Suspend-To-Disk)\n"); break;
- case ACPI_S5:
- printk(BIOS_DEBUG, "SMI#: Entering S5 (Soft Power off)\n");
-
- outl(0, pmbase + GPE0_EN);
-
- /* Always set the flag in case CMOS was changed on runtime. For
- * "KEEP", switch to "OFF" - KEEP is software emulated
- */
- reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_3);
- if (s5pwr == MAINBOARD_POWER_ON)
- reg8 &= ~1;
- else
- reg8 |= 1;
- pci_write_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_3, reg8);
-
- /* also iterates over all bridges on bus 0 */
- busmaster_disable_on_bus(0);
- break;
- default:
- printk(BIOS_DEBUG, "SMI#: ERROR: SLP_TYP reserved\n"); break;
- }
-
-#if !IS_ENABLED(CONFIG_SMM_TSEG)
- /* Unlock the SMI semaphore. We're currently in SMM, and the semaphore
- * will never be unlocked because the next outl will switch off the CPU.
- * This might open a small race between the smi_release_lock() and the outl()
- * for other SMI handlers. Not sure if this could cause trouble. */
- if (slp_typ == ACPI_S3)
- smi_release_lock();
-#endif
-
- /* Write back to the SLP register to cause the originally intended
- * event again. We need to set BIT13 (SLP_EN) though to make the
- * sleep happen.
- */
- outl(reg32 | SLP_EN, pmbase + PM1_CNT);
-
- /* Make sure to stop executing code here for S3/S4/S5 */
- if (slp_typ >= ACPI_S3)
- halt();
- /* In most sleep states, the code flow of this function ends at
- * the line above. However, if we entered sleep state S1 and wake
- * up again, we will continue to execute code in this function.
- */
- reg32 = inl(pmbase + PM1_CNT);
- if (reg32 & SCI_EN) {
- /* The OS is not an ACPI OS, so we set the state to S0 */
- reg32 &= ~(SLP_EN | SLP_TYP);
- outl(reg32, pmbase + PM1_CNT);
- }
-}
-
-static void southbridge_smi_apmc(unsigned int node, smm_state_save_area_t *state_save)
-{
- u32 pmctrl;
- u8 reg8;
-
- /* Emulate B2 register as the FADT / Linux expects it */
-
- reg8 = inb(APM_CNT);
- if (mainboard_smi_apmc(reg8))
- return;
-
- switch (reg8) {
- case APM_CNT_CST_CONTROL:
- /* Calling this function seems to cause
- * some kind of race condition in Linux
- * and causes a kernel oops
- */
- printk(BIOS_DEBUG, "C-state control\n");
- break;
- case APM_CNT_PST_CONTROL:
- /* Calling this function seems to cause
- * some kind of race condition in Linux
- * and causes a kernel oops
- */
- printk(BIOS_DEBUG, "P-state control\n");
- break;
- case APM_CNT_ACPI_DISABLE:
- pmctrl = inl(pmbase + PM1_CNT);
- pmctrl &= ~SCI_EN;
- outl(pmctrl, pmbase + PM1_CNT);
- printk(BIOS_DEBUG, "SMI#: ACPI disabled.\n");
- break;
- case APM_CNT_ACPI_ENABLE:
- pmctrl = inl(pmbase + PM1_CNT);
- pmctrl |= SCI_EN;
- outl(pmctrl, pmbase + PM1_CNT);
- printk(BIOS_DEBUG, "SMI#: ACPI enabled.\n");
- break;
- case APM_CNT_GNVS_UPDATE:
- if (smm_initialized) {
- printk(BIOS_DEBUG, "SMI#: SMM structures already initialized!\n");
- return;
- }
- gnvs = *(global_nvs_t **)0x500;
- smm_initialized = 1;
- printk(BIOS_DEBUG, "SMI#: Setting up structures to %p\n", gnvs);
- break;
- default:
- printk(BIOS_DEBUG, "SMI#: Unknown function APM_CNT=%02x\n", reg8);
- }
-}
-
-static void southbridge_smi_pm1(unsigned int node, smm_state_save_area_t *state_save)
-{
- u16 pm1_sts;
- volatile u8 cmos_status;
-
- pm1_sts = reset_pm1_status();
- dump_pm1_status(pm1_sts);
-
- /* While OSPM is not active, poweroff immediately
- * on a power button event.
- */
- if (pm1_sts & PWRBTN_STS) {
- // power button pressed
- u32 reg32;
- reg32 = (7 << 10) | (1 << 13);
- outl(reg32, pmbase + PM1_CNT);
- }
-
- if (pm1_sts & RTC_STS) {
- /* read RTC status register to disable the interrupt */
- cmos_status = cmos_read(RTC_REG_C);
- printk(BIOS_DEBUG, "RTC IRQ status: %02X\n", cmos_status);
- }
-}
-
-static void southbridge_smi_gpe0(unsigned int node, smm_state_save_area_t *state_save)
-{
- u32 gpe0_sts;
-
- gpe0_sts = reset_gpe0_status();
- dump_gpe0_status(gpe0_sts);
-}
-
-static void southbridge_smi_gpi(unsigned int node, smm_state_save_area_t *state_save)
-{
- u16 reg16;
- reg16 = inw(pmbase + ALT_GP_SMI_STS);
- outw(reg16, pmbase + ALT_GP_SMI_STS);
-
- reg16 &= inw(pmbase + ALT_GP_SMI_EN);
-
- mainboard_smi_gpi(reg16);
-
- if (reg16)
- printk(BIOS_DEBUG, "GPI (mask %04x)\n", reg16);
-}
-
-static void southbridge_smi_mc(unsigned int node, smm_state_save_area_t *state_save)
-{
- u32 reg32;
-
- reg32 = inl(pmbase + SMI_EN);
-
- /* Are periodic SMIs enabled? */
- if ((reg32 & MCSMI_EN) == 0)
- return;
-
- printk(BIOS_DEBUG, "Microcontroller SMI.\n");
-}
-
-
-
-static void southbridge_smi_tco(unsigned int node, smm_state_save_area_t *state_save)
-{
- u32 tco_sts;
-
- tco_sts = reset_tco_status();
-
- /* Any TCO event? */
- if (!tco_sts)
- return;
-
- if (tco_sts & (1 << 8)) {
- /* BIOSWR */
- u8 bios_cntl;
-
- bios_cntl = pci_read_config16(PCI_DEV(0, 0x1f, 0), 0xdc);
-
- if (bios_cntl & 1) {
- /* BWE is RW, so the SMI was caused by a
- * write to BWE, not by a write to the BIOS
- */
-
- /* This is the place where we notice someone
- * is trying to tinker with the BIOS. We are
- * trying to be nice and just ignore it. A more
- * resolute answer would be to power down the
- * box.
- */
- printk(BIOS_DEBUG, "Switching back to RO\n");
- pci_write_config32(PCI_DEV(0, 0x1f, 0), 0xdc, (bios_cntl & ~1));
- } /* No else for now? */
- } else if (tco_sts & (1 << 3)) { /* TIMEOUT */
- /* Handle TCO timeout */
- printk(BIOS_DEBUG, "TCO Timeout.\n");
- } else if (!tco_sts) {
- dump_tco_status(tco_sts);
- }
-}
-
-static void southbridge_smi_periodic(unsigned int node, smm_state_save_area_t *state_save)
-{
- u32 reg32;
-
- reg32 = inl(pmbase + SMI_EN);
-
- /* Are periodic SMIs enabled? */
- if ((reg32 & PERIODIC_EN) == 0)
- return;
-
- printk(BIOS_DEBUG, "Periodic SMI.\n");
-}
-
-static void southbridge_smi_monitor(unsigned int node, smm_state_save_area_t *state_save)
+void southbridge_smi_monitor(void)
{
#define IOTRAP(x) (trap_sts & (1 << x))
u32 trap_sts, trap_cycle;
@@ -654,80 +114,6 @@ static void southbridge_smi_monitor(unsigned int node, smm_state_save_area_t *st
#undef IOTRAP
}
-typedef void (*smi_handler_t)(unsigned int node,
- smm_state_save_area_t *state_save);
-
-smi_handler_t southbridge_smi[32] = {
- NULL, // [0] reserved
- NULL, // [1] reserved
- NULL, // [2] BIOS_STS
- NULL, // [3] LEGACY_USB_STS
- southbridge_smi_sleep, // [4] SLP_SMI_STS
- southbridge_smi_apmc, // [5] APM_STS
- NULL, // [6] SWSMI_TMR_STS
- NULL, // [7] reserved
- southbridge_smi_pm1, // [8] PM1_STS
- southbridge_smi_gpe0, // [9] GPE0_STS
- southbridge_smi_gpi, // [10] GPI_STS
- southbridge_smi_mc, // [11] MCSMI_STS
- NULL, // [12] DEVMON_STS
- southbridge_smi_tco, // [13] TCO_STS
- southbridge_smi_periodic, // [14] PERIODIC_STS
- NULL, // [15] SERIRQ_SMI_STS
- NULL, // [16] SMBUS_SMI_STS
- NULL, // [17] LEGACY_USB2_STS
- NULL, // [18] INTEL_USB2_STS
- NULL, // [19] reserved
- NULL, // [20] PCI_EXP_SMI_STS
- southbridge_smi_monitor, // [21] MONITOR_STS
- NULL, // [22] reserved
- NULL, // [23] reserved
- NULL, // [24] reserved
- NULL, // [25] EL_SMI_STS
- NULL, // [26] SPI_STS
- NULL, // [27] reserved
- NULL, // [28] reserved
- NULL, // [29] reserved
- NULL, // [30] reserved
- NULL // [31] reserved
-};
-
-/**
- * @brief Interrupt handler for SMI#
- * @param node
- * @param state_save
- */
-
-void southbridge_smi_handler(unsigned int node, smm_state_save_area_t *state_save)
+void southbridge_finalize_all(void)
{
- int i, dump = 0;
- u32 smi_sts;
-
- /* Update global variable pmbase */
- pmbase = pci_read_config16(PCI_DEV(0, 0x1f, 0), 0x40) & 0xfffc;
-
- /* We need to clear the SMI status registers, or we won't see what's
- * happening in the following calls.
- */
- smi_sts = reset_smi_status();
-
- /* Filter all non-enabled SMI events */
- // FIXME Double check, this clears MONITOR
- // smi_sts &= inl(pmbase + SMI_EN);
-
- /* Call SMI sub handler for each of the status bits */
- for (i = 0; i < 31; i++) {
- if (smi_sts & (1 << i)) {
- if (southbridge_smi[i])
- southbridge_smi[i](node, state_save);
- else {
- printk(BIOS_DEBUG, "SMI_STS[%d] occured, but no "
- "handler available.\n", i);
- dump = 1;
- }
- }
- }
-
- if (dump)
- dump_smi_status(smi_sts);
}