Arthur Heymans has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/33209
Change subject: cpu/intel/haswell: Use common smm code. ......................................................................
cpu/intel/haswell: Use common smm code.
Change-Id: I1e37200ffbc9b33dc6e00298fafdb12d7fb5a91a Signed-off-by: Arthur Heymans arthur@aheymans.xyz --- M src/cpu/intel/haswell/acpi.c M src/cpu/intel/haswell/haswell_init.c M src/mainboard/google/slippy/smihandler.c M src/northbridge/intel/haswell/gma.c M src/southbridge/intel/common/smihandler.c M src/southbridge/intel/lynxpoint/Kconfig M src/southbridge/intel/lynxpoint/Makefile.inc M src/southbridge/intel/lynxpoint/lpc.c M src/southbridge/intel/lynxpoint/pch.c M src/southbridge/intel/lynxpoint/pch.h M src/southbridge/intel/lynxpoint/pmutil.c M src/southbridge/intel/lynxpoint/smihandler.c 12 files changed, 36 insertions(+), 483 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/09/33209/1
diff --git a/src/cpu/intel/haswell/acpi.c b/src/cpu/intel/haswell/acpi.c index 9dcd8ec..88e48e7 100644 --- a/src/cpu/intel/haswell/acpi.c +++ b/src/cpu/intel/haswell/acpi.c @@ -28,6 +28,7 @@ #include "chip.h"
#include <southbridge/intel/lynxpoint/pch.h> +#include <southbridge/intel/common/pmutil.h>
static int get_cores_per_package(void) { diff --git a/src/cpu/intel/haswell/haswell_init.c b/src/cpu/intel/haswell/haswell_init.c index 25cf243..3db2aa6 100644 --- a/src/cpu/intel/haswell/haswell_init.c +++ b/src/cpu/intel/haswell/haswell_init.c @@ -32,6 +32,7 @@ #include <delay.h> #include <northbridge/intel/haswell/haswell.h> #include <southbridge/intel/lynxpoint/pch.h> +#include <southbridge/intel/common/pmutil.h> #include <cpu/intel/common/common.h> #include "haswell.h" #include "chip.h" @@ -761,7 +762,7 @@ { /* Now that all APs have been relocated as well as the BSP let SMIs * start flowing. */ - southbridge_smm_enable_smi(); + southbridge_smm_init();
/* Lock down the SMRAM space. */ smm_lock(); diff --git a/src/mainboard/google/slippy/smihandler.c b/src/mainboard/google/slippy/smihandler.c index 81a772c..f1ac1d1 100644 --- a/src/mainboard/google/slippy/smihandler.c +++ b/src/mainboard/google/slippy/smihandler.c @@ -21,6 +21,7 @@ #include <southbridge/intel/lynxpoint/nvs.h> #include <southbridge/intel/lynxpoint/pch.h> #include <southbridge/intel/common/gpio.h> +#include <southbridge/intel/common/pmutil.h> #include <southbridge/intel/lynxpoint/me.h> #include <northbridge/intel/haswell/haswell.h> #include <cpu/intel/haswell/haswell.h> diff --git a/src/northbridge/intel/haswell/gma.c b/src/northbridge/intel/haswell/gma.c index ca446e2..bc81377 100644 --- a/src/northbridge/intel/haswell/gma.c +++ b/src/northbridge/intel/haswell/gma.c @@ -29,6 +29,7 @@ #include <cpu/intel/haswell/haswell.h> #include <drivers/intel/gma/opregion.h> #include <southbridge/intel/lynxpoint/nvs.h> +#include <southbridge/intel/common/pmutil.h> #include <stdlib.h> #include <string.h> #include <types.h> diff --git a/src/southbridge/intel/common/smihandler.c b/src/southbridge/intel/common/smihandler.c index 8a16aaa..1a170f0 100644 --- a/src/southbridge/intel/common/smihandler.c +++ b/src/southbridge/intel/common/smihandler.c @@ -316,6 +316,11 @@ southbridge_finalize_all(); mainboard_finalized = 1; break; +#if 0 + case 0xca: + usb_xhci_route_all(); + break; +#endif #if CONFIG(ELOG_GSMI) case APM_CNT_ELOG_GSMI: southbridge_smi_gsmi(); diff --git a/src/southbridge/intel/lynxpoint/Kconfig b/src/southbridge/intel/lynxpoint/Kconfig index a600a3ff..35ca64d 100644 --- a/src/southbridge/intel/lynxpoint/Kconfig +++ b/src/southbridge/intel/lynxpoint/Kconfig @@ -29,6 +29,7 @@ select SOUTHBRIDGE_INTEL_COMMON_PMCLIB select SOUTHBRIDGE_INTEL_COMMON_PMBASE select SOUTHBRIDGE_INTEL_COMMON_RTC + select SOUTHBRIDGE_INTEL_COMMON_SMM select IOAPIC select HAVE_SMI_HANDLER select HAVE_USBDEBUG_OPTIONS diff --git a/src/southbridge/intel/lynxpoint/Makefile.inc b/src/southbridge/intel/lynxpoint/Makefile.inc index 3e3ef35..2f6e6ee 100644 --- a/src/southbridge/intel/lynxpoint/Makefile.inc +++ b/src/southbridge/intel/lynxpoint/Makefile.inc @@ -38,16 +38,17 @@ ramstage-y += rcba.c ramstage-y += me_status.c ramstage-y += acpi.c +ramstage-y += pmutil.c
ramstage-$(CONFIG_ELOG) += elog.c
-ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c pmutil.c +#ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c pmutil.c smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c me_9.x.c pch.c -smm-$(CONFIG_HAVE_SMI_HANDLER) += pmutil.c usb_ehci.c usb_xhci.c +smm-$(CONFIG_HAVE_SMI_HANDLER) += usb_ehci.c usb_xhci.c
bootblock-y += early_pch.c romstage-y += early_usb.c early_smbus.c early_me.c me_status.c early_pch.c -romstage-y += rcba.c pmutil.c +romstage-y += rcba.c
ifeq ($(CONFIG_INTEL_LYNXPOINT_LP),y) romstage-y += lp_gpio.c diff --git a/src/southbridge/intel/lynxpoint/lpc.c b/src/southbridge/intel/lynxpoint/lpc.c index b0f57c1..a99888b 100644 --- a/src/southbridge/intel/lynxpoint/lpc.c +++ b/src/southbridge/intel/lynxpoint/lpc.c @@ -36,6 +36,7 @@ #include <drivers/intel/gma/i915.h> #include <southbridge/intel/common/acpi_pirq_gen.h> #include <southbridge/intel/common/rtc.h> +#include <southbridge/intel/common/pmutil.h>
#define NMI_OFF 0
diff --git a/src/southbridge/intel/lynxpoint/pch.c b/src/southbridge/intel/lynxpoint/pch.c index a57bae3..1913994 100644 --- a/src/southbridge/intel/lynxpoint/pch.c +++ b/src/southbridge/intel/lynxpoint/pch.c @@ -70,16 +70,6 @@ return pch_silicon_type() == PCH_TYPE_LPT_LP; }
-u16 get_pmbase(void) -{ - static u16 pmbase; - - if (!pmbase) - pmbase = pci_read_config16(pch_get_lpc_device(), - PMBASE) & 0xfffc; - return pmbase; -} - u16 get_gpiobase(void) { static u16 gpiobase; diff --git a/src/southbridge/intel/lynxpoint/pch.h b/src/southbridge/intel/lynxpoint/pch.h index 93c2bc5..462e8de 100644 --- a/src/southbridge/intel/lynxpoint/pch.h +++ b/src/southbridge/intel/lynxpoint/pch.h @@ -141,7 +141,6 @@ int pch_silicon_id(void); int pch_silicon_type(void); int pch_is_lp(void); -u16 get_pmbase(void); u16 get_gpiobase(void);
/* Power Management register handling in pmutil.c */ diff --git a/src/southbridge/intel/lynxpoint/pmutil.c b/src/southbridge/intel/lynxpoint/pmutil.c index cc49477..117d340 100644 --- a/src/southbridge/intel/lynxpoint/pmutil.c +++ b/src/southbridge/intel/lynxpoint/pmutil.c @@ -27,6 +27,7 @@ #include <security/vboot/vbnv.h> #include <security/vboot/vboot_common.h> #include <southbridge/intel/common/rtc.h> +#include <southbridge/intel/common/pmutil.h> #include "pch.h"
#if CONFIG(INTEL_LYNXPOINT_LP) @@ -97,14 +98,6 @@ * PM1 */
-/* Clear and return PM1 status register */ -static u16 reset_pm1_status(void) -{ - u16 pm1_sts = inw(get_pmbase() + PM1_STS); - outw(pm1_sts, get_pmbase() + PM1_STS); - return pm1_sts; -} - /* Print PM1 status bits */ static u16 print_pm1_status(u16 pm1_sts) { @@ -146,13 +139,6 @@ * SMI */
-/* Clear and return SMI status register */ -static u32 reset_smi_status(void) -{ - u32 smi_sts = inl(get_pmbase() + SMI_STS); - outl(smi_sts, get_pmbase() + SMI_STS); - return smi_sts; -}
/* Print SMI status bits */ static u32 print_smi_status(u32 smi_sts) @@ -317,23 +303,6 @@ * TCO */
-/* Clear TCO status and return events that are enabled and active */ -static u32 reset_tco_status(void) -{ - u32 tcobase = get_pmbase() + 0x60; - u32 tco_sts = inl(tcobase + 0x04); - u32 tco_en = inl(get_pmbase() + 0x68); - - /* Don't clear BOOT_STS before SECOND_TO_STS */ - outl(tco_sts & ~(1 << 18), tcobase + 0x04); - - /* Clear BOOT_STS */ - if (tco_sts & (1 << 18)) - outl(tco_sts & (1 << 18), tcobase + 0x04); - - return tco_sts & tco_en; -} - /* Print TCO status bits */ static u32 print_tco_status(u32 tco_sts) { diff --git a/src/southbridge/intel/lynxpoint/smihandler.c b/src/southbridge/intel/lynxpoint/smihandler.c index 88c599f..9982bda 100644 --- a/src/southbridge/intel/lynxpoint/smihandler.c +++ b/src/southbridge/intel/lynxpoint/smihandler.c @@ -27,14 +27,13 @@ #include <pc80/mc146818rtc.h> #include <southbridge/intel/common/finalize.h> #include <northbridge/intel/haswell/haswell.h> +#include <southbridge/intel/common/pmutil.h> #include <cpu/intel/haswell/haswell.h>
#include "me.h" #include "pch.h" #include "nvs.h"
-static u8 smm_initialized = 0; - /* GNVS needs to be updated by an 0xEA PM Trap (B2) after it has been located * by coreboot. */ @@ -44,6 +43,18 @@ return gnvs; }
+void southbridge_update_gnvs(u8 apm_cnt, int *smm_done) +{ + em64t101_smm_state_save_area_t *state = + smi_apmc_find_state_save(apm_cnt); + if (state) { + /* EBX in the state save contains the GNVS pointer */ + gnvs = (global_nvs_t *)((u32)state->rbx); + *smm_done = 1; + printk(BIOS_DEBUG, "SMI#: Setting GNVS to %p\n", gnvs); + } +} + int southbridge_io_trap_handler(int smif) { switch (smif) { @@ -61,379 +72,7 @@ return 0; }
-/** - * @brief Set the EOS bit - */ -void southbridge_smi_set_eos(void) -{ - enable_smi(EOS); -} - -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(void) -{ - u8 reg8; - u32 reg32; - u8 slp_typ; - u8 s5pwr = CONFIG_MAINBOARD_POWER_FAILURE_STATE; - u16 pmbase = get_pmbase(); - - // 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 */ - disable_smi(SLP_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); - - /* Do any mainboard sleep handling */ - mainboard_smi_sleep(slp_typ); - - /* USB sleep preparations */ -#if !CONFIG(FINALIZE_USB_ROUTE_XHCI) - usb_ehci_sleep_prepare(PCH_EHCI1_DEV, slp_typ); - usb_ehci_sleep_prepare(PCH_EHCI2_DEV, slp_typ); -#endif - usb_xhci_sleep_prepare(PCH_XHCI_DEV, slp_typ); - -#if CONFIG(ELOG_GSMI) - /* Log S3, S4, and S5 entry */ - if (slp_typ >= ACPI_S3) - elog_add_event_byte(ELOG_TYPE_ACPI_ENTER, slp_typ); -#endif - - /* 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"); - - /* Disable all GPE */ - disable_all_gpe(); - - /* 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; - } - - /* 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. - */ - enable_pm1_control(SLP_EN); - - /* 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 */ - disable_pm1_control(SLP_EN | SLP_TYP); - } -} - -/* - * Look for Synchronous IO SMI and use save state from that - * core in case we are not running on the same core that - * initiated the IO transaction. - */ -static em64t101_smm_state_save_area_t *smi_apmc_find_state_save(u8 cmd) -{ - em64t101_smm_state_save_area_t *state; - int node; - - /* Check all nodes looking for the one that issued the IO */ - for (node = 0; node < CONFIG_MAX_CPUS; node++) { - state = smm_get_save_state(node); - - /* Check for Synchronous IO (bit0 == 1) */ - if (!(state->io_misc_info & (1 << 0))) - continue; - - /* Make sure it was a write (bit4 == 0) */ - if (state->io_misc_info & (1 << 4)) - continue; - - /* Check for APMC IO port */ - if (((state->io_misc_info >> 16) & 0xff) != APM_CNT) - continue; - - /* Check AX against the requested command */ - if ((state->rax & 0xff) != cmd) - continue; - - return state; - } - - return NULL; -} - -#if CONFIG(ELOG_GSMI) -static void southbridge_smi_gsmi(void) -{ - u32 *ret, *param; - u8 sub_command; - em64t101_smm_state_save_area_t *io_smi = - smi_apmc_find_state_save(APM_CNT_ELOG_GSMI); - - if (!io_smi) - return; - - /* Command and return value in EAX */ - ret = (u32*)&io_smi->rax; - sub_command = (u8)(*ret >> 8); - - /* Parameter buffer in EBX */ - param = (u32*)&io_smi->rbx; - - /* drivers/elog/gsmi.c */ - *ret = gsmi_exec(sub_command, param); -} -#endif - -static void southbridge_smi_apmc(void) -{ - u8 reg8; - em64t101_smm_state_save_area_t *state; - static int chipset_finalized = 0; - - /* Emulate B2 register as the FADT / Linux expects it */ - - reg8 = inb(APM_CNT); - switch (reg8) { - case APM_CNT_FINALIZE: - if (chipset_finalized) { - printk(BIOS_DEBUG, "SMI#: Already finalized\n"); - return; - } - - intel_me_finalize_smm(); - intel_pch_finalize_smm(); - intel_northbridge_haswell_finalize_smm(); - intel_cpu_haswell_finalize_smm(); - - chipset_finalized = 1; - break; - 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: - disable_pm1_control(SCI_EN); - printk(BIOS_DEBUG, "SMI#: ACPI disabled.\n"); - break; - case APM_CNT_ACPI_ENABLE: - enable_pm1_control(SCI_EN); - 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; - } - state = smi_apmc_find_state_save(reg8); - if (state) { - /* EBX in the state save contains the GNVS pointer */ - gnvs = (global_nvs_t *)((u32)state->rbx); - smm_initialized = 1; - printk(BIOS_DEBUG, "SMI#: Setting GNVS to %p\n", gnvs); - } - break; - case 0xca: - usb_xhci_route_all(); - break; -#if CONFIG(ELOG_GSMI) - case APM_CNT_ELOG_GSMI: - southbridge_smi_gsmi(); - break; -#endif - } - - mainboard_smi_apmc(reg8); -} - -static void southbridge_smi_pm1(void) -{ - u16 pm1_sts = clear_pm1_status(); - - /* While OSPM is not active, poweroff immediately - * on a power button event. - */ - if (pm1_sts & PWRBTN_STS) { - // power button pressed -#if CONFIG(ELOG_GSMI) - elog_add_event(ELOG_TYPE_POWER_BUTTON); -#endif - disable_pm1_control(-1UL); - enable_pm1_control(SLP_EN | (SLP_TYP_S5 << 10)); - } -} - -static void southbridge_smi_gpe0(void) -{ - clear_gpe_status(); -} - -static void southbridge_smi_gpi(void) -{ - mainboard_smi_gpi(clear_alt_smi_status()); - - /* Clear again after mainboard handler */ - clear_alt_smi_status(); -} - -static void southbridge_smi_mc(void) -{ - u32 reg32; - - reg32 = inl(get_pmbase() + SMI_EN); - - /* Are microcontroller SMIs enabled? */ - if ((reg32 & MCSMI_EN) == 0) - return; - - printk(BIOS_DEBUG, "Microcontroller SMI.\n"); -} - - - -static void southbridge_smi_tco(void) -{ - u32 tco_sts = clear_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"); - } -} - -static void southbridge_smi_periodic(void) -{ - u32 reg32; - - reg32 = inl(get_pmbase() + SMI_EN); - - /* Are periodic SMIs enabled? */ - if ((reg32 & PERIODIC_EN) == 0) - return; - - printk(BIOS_DEBUG, "Periodic SMI.\n"); -} - -static void southbridge_smi_monitor(void) +void southbridge_smi_monitor(void) { #define IOTRAP(x) (trap_sts & (1 << x)) u32 trap_sts, trap_cycle; @@ -490,66 +129,10 @@ #undef IOTRAP }
-typedef void (*smi_handler_t)(void); - -static 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# - */ -void southbridge_smi_handler(void) +void southbridge_finalize_all(void) { - int i; - u32 smi_sts; - - /* We need to clear the SMI status registers, or we won't see what's - * happening in the following calls. - */ - smi_sts = clear_smi_status(); - - /* 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](); - } else { - printk(BIOS_DEBUG, - "SMI_STS[%d] occurred, but no " - "handler available.\n", i); - } - } - } + intel_me_finalize_smm(); + intel_pch_finalize_smm(); + intel_northbridge_haswell_finalize_smm(); + intel_cpu_haswell_finalize_smm(); }