<p>Subrata Banik would like Brandon Breitenstein to <strong>review</strong> this change.</p><p><a href="https://review.coreboot.org/22826">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">soc/intel/skylake: Make use of common SMM code for SKL<br><br>This patch ensures skylake soc is using common SMM code<br>from intel common block.<br><br>TEST=Build and boot soraka/eve<br><br>Change-Id: I8163dc7e18bb417e8c18a12628988959c128b3df<br>Signed-off-by: Subrata Banik <subrata.banik@intel.com><br>Signed-off-by: Brandon Breitenstein <brandon.breitenstein@intel.com><br>---<br>M src/soc/intel/skylake/Kconfig<br>M src/soc/intel/skylake/Makefile.inc<br>M src/soc/intel/skylake/cpu.c<br>M src/soc/intel/skylake/include/soc/nvs.h<br>M src/soc/intel/skylake/include/soc/pm.h<br>M src/soc/intel/skylake/include/soc/smbus.h<br>M src/soc/intel/skylake/memmap.c<br>M src/soc/intel/skylake/pei_data.c<br>D src/soc/intel/skylake/smi.c<br>M src/soc/intel/skylake/smihandler.c<br>M src/soc/intel/skylake/smmrelocate.c<br>11 files changed, 39 insertions(+), 654 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/26/22826/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig<br>index 2dbf4a2..156f942 100644<br>--- a/src/soc/intel/skylake/Kconfig<br>+++ b/src/soc/intel/skylake/Kconfig<br>@@ -76,6 +76,8 @@<br>     select SOC_INTEL_COMMON_BLOCK_SCS<br>     select SOC_INTEL_COMMON_BLOCK_SGX<br>     select SOC_INTEL_COMMON_BLOCK_SMBUS<br>+  select SOC_INTEL_COMMON_BLOCK_SMM<br>+    select SOC_INTEL_COMMON_BLOCK_SMM_IO_TRAP<br>     select SOC_INTEL_COMMON_BLOCK_SPI<br>     select SOC_INTEL_COMMON_BLOCK_TIMER<br>   select SOC_INTEL_COMMON_BLOCK_UART<br>diff --git a/src/soc/intel/skylake/Makefile.inc b/src/soc/intel/skylake/Makefile.inc<br>index 16f8c06..ef95cf7 100644<br>--- a/src/soc/intel/skylake/Makefile.inc<br>+++ b/src/soc/intel/skylake/Makefile.inc<br>@@ -59,7 +59,6 @@<br> ramstage-y += pmutil.c<br> ramstage-$(CONFIG_PLATFORM_USES_FSP2_0) += reset.c<br> ramstage-y += sd.c<br>-ramstage-y += smi.c<br> ramstage-y += smmrelocate.c<br> ramstage-y += spi.c<br> ramstage-y += systemagent.c<br>diff --git a/src/soc/intel/skylake/cpu.c b/src/soc/intel/skylake/cpu.c<br>index ca844df..8f9f5d1 100644<br>--- a/src/soc/intel/skylake/cpu.c<br>+++ b/src/soc/intel/skylake/cpu.c<br>@@ -38,6 +38,7 @@<br> #include <intelblocks/fast_spi.h><br> #include <intelblocks/mp_init.h><br> #include <intelblocks/sgx.h><br>+#include <intelblocks/smm.h><br> #include <pc80/mc146818rtc.h><br> #include <soc/cpu.h><br> #include <soc/msr.h><br>@@ -436,7 +437,7 @@<br>    * Now that all APs have been relocated as well as the BSP let SMIs<br>    * start flowing.<br>      */<br>-  southbridge_smm_enable_smi();<br>+        smm_southbridge_enable();<br> <br>  /* Lock down the SMRAM space. */<br> #if IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)<br>diff --git a/src/soc/intel/skylake/include/soc/nvs.h b/src/soc/intel/skylake/include/soc/nvs.h<br>index da6b2af..8bc4d8d 100644<br>--- a/src/soc/intel/skylake/include/soc/nvs.h<br>+++ b/src/soc/intel/skylake/include/soc/nvs.h<br>@@ -69,9 +69,4 @@<br> } __packed global_nvs_t;<br> check_member(global_nvs_t, chromeos, 0x100);<br> <br>-#if ENV_SMM<br>-/* Used in SMM to find the ACPI GNVS address */<br>-global_nvs_t *smm_get_gnvs(void);<br>-#endif<br>-<br> #endif<br>diff --git a/src/soc/intel/skylake/include/soc/pm.h b/src/soc/intel/skylake/include/soc/pm.h<br>index 0057818..7fdc327 100644<br>--- a/src/soc/intel/skylake/include/soc/pm.h<br>+++ b/src/soc/intel/skylake/include/soc/pm.h<br>@@ -23,6 +23,7 @@<br> #include <soc/gpe.h><br> #include <soc/iomap.h><br> #include <soc/pmc.h><br>+#include <soc/smbus.h><br> <br> /* ACPI_BASE_ADDRESS / PMBASE */<br> <br>@@ -135,6 +136,19 @@<br> <br> #define GBLRST_CAUSE0_THERMTRIP        (1 << 5)<br> <br>+/*<br>+ * Enable SMI generation:<br>+ *  - on APMC writes (io 0xb2)<br>+ *  - on writes to SLP_EN (sleep states)<br>+ *  - on writes to GBL_RLS (bios commands)<br>+ *  - on eSPI events (does nothing on LPC systems)<br>+ * No SMIs:<br>+ *  - on microcontroller writes (io 0x62/0x66)<br>+ *  - on TCO events<br>+ */<br>+#define ENABLE_SMI_PARAMS \<br>+    (APMC_EN | SLP_SMI_EN | GBL_SMI_EN | ESPI_SMI_EN | EOS)<br>+<br> #define MAINBOARD_POWER_OFF        0<br> #define MAINBOARD_POWER_ON  1<br> #define MAINBOARD_POWER_KEEP        2<br>diff --git a/src/soc/intel/skylake/include/soc/smbus.h b/src/soc/intel/skylake/include/soc/smbus.h<br>index ad5ae26..aeaf1d9 100644<br>--- a/src/soc/intel/skylake/include/soc/smbus.h<br>+++ b/src/soc/intel/skylake/include/soc/smbus.h<br>@@ -4,7 +4,7 @@<br>  * Copyright (C) 2005 Yinghai Lu <yinghailu@gmail.com><br>  * Copyright (C) 2009 coresystems GmbH<br>  * Copyright (C) 2014 Google Inc.<br>- * Copyright (C) 2015 Intel Corporation.<br>+ * Copyright (C) 2015-2017 Intel Corporation.<br>  *<br>  * This program is free software; you can redistribute it and/or modify<br>  * it under the terms of the GNU General Public License as published by<br>@@ -29,6 +29,7 @@<br> <br> /* TCO registers and fields live behind TCOBASE I/O bar in SMBus device. */<br> #define TCO1_STS                  0x04<br>+#define  TCO_TIMEOUT                     (1 << 3)<br> #define TCO2_STS                       0x06<br> #define TCO2_STS_SECOND_TO               0x02<br> #define TCO2_STS_BOOT                    0x04<br>diff --git a/src/soc/intel/skylake/memmap.c b/src/soc/intel/skylake/memmap.c<br>index b7be21a..c5dc8ac 100644<br>--- a/src/soc/intel/skylake/memmap.c<br>+++ b/src/soc/intel/skylake/memmap.c<br>@@ -21,11 +21,11 @@<br> #include <console/console.h><br> #include <device/device.h><br> #include <device/pci.h><br>+#include <fsp/memmap.h><br> #include <intelblocks/ebda.h><br> #include <intelblocks/systemagent.h><br> #include <soc/msr.h><br> #include <soc/pci_devs.h><br>-#include <soc/smm.h><br> #include <soc/systemagent.h><br> #include <stdlib.h><br> <br>diff --git a/src/soc/intel/skylake/pei_data.c b/src/soc/intel/skylake/pei_data.c<br>index 43409ef..8b840c9 100644<br>--- a/src/soc/intel/skylake/pei_data.c<br>+++ b/src/soc/intel/skylake/pei_data.c<br>@@ -25,7 +25,6 @@<br> #include <soc/pci_devs.h><br> #include <soc/pei_data.h><br> #include <soc/pei_wrapper.h><br>-#include <soc/smm.h><br> <br> static void ABI_X86 send_to_console(unsigned char b)<br> {<br>diff --git a/src/soc/intel/skylake/smi.c b/src/soc/intel/skylake/smi.c<br>deleted file mode 100644<br>index f11a9d8..0000000<br>--- a/src/soc/intel/skylake/smi.c<br>+++ /dev/null<br>@@ -1,107 +0,0 @@<br>-/*<br>- * This file is part of the coreboot project.<br>- *<br>- * Copyright (C) 2008-2009 coresystems GmbH<br>- * Copyright (C) 2014 Google Inc.<br>- * Copyright (C) 2015 Intel Corporation.<br>- *<br>- * This program is free software; you can redistribute it and/or modify<br>- * it under the terms of the GNU General Public License as published by<br>- * the Free Software Foundation; version 2 of the License.<br>- *<br>- * This program is distributed in the hope that it will be useful,<br>- * but WITHOUT ANY WARRANTY; without even the implied warranty of<br>- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br>- * GNU General Public License for more details.<br>- */<br>-<br>-#include <bootstate.h><br>-#include <device/device.h><br>-#include <device/pci.h><br>-#include <console/console.h><br>-#include <arch/io.h><br>-#include <cpu/cpu.h><br>-#include <cpu/x86/cache.h><br>-#include <cpu/x86/smm.h><br>-#include <intelblocks/pmclib.h><br>-#include <string.h><br>-#include <soc/iomap.h><br>-#include <soc/pch.h><br>-#include <soc/pm.h><br>-#include <soc/smm.h><br>-<br>-void southbridge_smm_clear_state(void)<br>-{<br>-  u32 smi_en;<br>-<br>-       printk(BIOS_DEBUG, "Initializing Southbridge SMI...");<br>-     printk(BIOS_SPEW, " ... pmbase = 0x%04x\n", ACPI_BASE_ADDRESS);<br>-<br>- smi_en = inl(ACPI_BASE_ADDRESS + SMI_EN);<br>-    if (smi_en & APMC_EN) {<br>-          printk(BIOS_INFO, "SMI# handler already enabled?\n");<br>-              return;<br>-      }<br>-<br>- printk(BIOS_DEBUG, "\n");<br>-<br>-       /* Dump and clear status registers */<br>-        pmc_clear_smi_status();<br>-      pmc_clear_pm1_status();<br>-      pmc_clear_tco_status();<br>-      pmc_clear_all_gpe_status();<br>-}<br>-<br>-void southbridge_smm_enable_smi(void)<br>-{<br>-       printk(BIOS_DEBUG, "Enabling SMIs.\n");<br>-    /* Configure events */<br>-       pmc_enable_pm1(GBL_EN);<br>-      pmc_disable_std_gpe(PME_B0_EN);<br>-<br>-   /*<br>-    * Enable SMI generation:<br>-     *  - on APMC writes (io 0xb2)<br>-        *  - on writes to SLP_EN (sleep states)<br>-      *  - on writes to GBL_RLS (bios commands)<br>-    *  - on eSPI events (does nothing on LPC systems)<br>-    * No SMIs:<br>-   *  - on microcontroller writes (io 0x62/0x66)<br>-        *  - on TCO events<br>-   */<br>-  pmc_enable_smi(APMC_EN | SLP_SMI_EN | GBL_SMI_EN | ESPI_SMI_EN | EOS);<br>-}<br>-<br>-void smm_setup_structures(void *gnvs, void *tcg, void *smi1)<br>-{<br>-     /*<br>-    * Issue SMI to set the gnvs pointer in SMM.<br>-  * tcg and smi1 are unused.<br>-   *<br>-    * EAX = APM_CNT_GNVS_UPDATE<br>-  * EBX = gnvs pointer<br>-         * EDX = APM_CNT<br>-      */<br>-  asm volatile (<br>-               "outb %%al, %%dx\n\t"<br>-              : /* ignore result */<br>-                : "a" (APM_CNT_GNVS_UPDATE),<br>-                 "b" ((u32)gnvs),<br>-           "d" (APM_CNT)<br>-    );<br>-}<br>-<br>-static void pm1_enable_pwrbtn_smi(void *unused)<br>-{<br>-      /*<br>-    * Enable power button SMI only before jumping to payload. This ensures<br>-       * that:<br>-      * 1. Power button SMI is enabled only after coreboot is done.<br>-        * 2. On resume path, power button SMI is not enabled and thus avoids<br>-         * any shutdowns because of power button presses due to power button<br>-  * press in resume path.<br>-      */<br>-  pmc_update_pm1_enable(PWRBTN_EN);<br>-}<br>-<br>-BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, pm1_enable_pwrbtn_smi, NULL);<br>diff --git a/src/soc/intel/skylake/smihandler.c b/src/soc/intel/skylake/smihandler.c<br>index 211432c..f438d4e 100644<br>--- a/src/soc/intel/skylake/smihandler.c<br>+++ b/src/soc/intel/skylake/smihandler.c<br>@@ -3,7 +3,7 @@<br>  *<br>  * Copyright (C) 2008-2009 coresystems GmbH<br>  * Copyright (C) 2014 Google Inc.<br>- * Copyright (C) 2015 Intel Corporation.<br>+ * Copyright (C) 2015-2017 Intel Corporation.<br>  *<br>  * This program is free software; you can redistribute it and/or modify<br>  * it under the terms of the GNU General Public License as published by<br>@@ -15,543 +15,23 @@<br>  * GNU General Public License for more details.<br>  */<br> <br>-#include <arch/hlt.h><br>-#include <arch/io.h><br>-#include <console/console.h><br>-#include <cpu/x86/cache.h><br>-#include <cpu/x86/smm.h><br>-#include <device/pci_def.h><br>-#include <elog.h><br>-#include <intelblocks/fast_spi.h><br>-#include <intelblocks/pcr.h><br>-#include <intelblocks/uart.h><br>-#include <intelblocks/pmclib.h><br>-#include <delay.h><br>-#include <device/pci_def.h><br>-#include <elog.h><br>-#include <pc80/mc146818rtc.h><br>-#include <spi-generic.h><br>-#include <soc/iomap.h><br>-#include <soc/nvs.h><br>-#include <soc/pci_devs.h><br>-#include <soc/pch.h><br>-#include <soc/pcr_ids.h><br> #include <soc/pm.h><br>-#include <soc/pmc.h><br>-#include <soc/smm.h><br>-#include <types.h><br>+#include <intelblocks/smihandler.h><br> <br>-/* IO Trap PCRs */<br>-/* Trap status Register */<br>-#define PCR_PSTH_TRPST 0x1E00<br>-/* Trapped cycle */<br>-#define PCR_PSTH_TRPC    0x1E10<br>-/* Trapped write data */<br>-#define PCR_PSTH_TRPD       0x1E18<br>-<br>-static u8 smm_initialized = 0;<br>-<br>-/*<br>- * GNVS needs to be updated by an 0xEA PM Trap (B2) after it has been located<br>- * by coreboot.<br>- */<br>-static global_nvs_t *gnvs;<br>-global_nvs_t *smm_get_gnvs(void)<br>+const struct smm_save_state_ops *get_smm_save_state_ops(void)<br> {<br>-       return gnvs;<br>+ return &em64t101_smm_ops;<br> }<br> <br>-int southbridge_io_trap_handler(int smif)<br>-{<br>- switch (smif) {<br>-      case 0x32:<br>-           printk(BIOS_DEBUG, "OS Init\n");<br>-           /*<br>-            * gnvs->smif:<br>-             * - On success, the IO Trap Handler returns 0<br>-                * - On failure, the IO Trap Handler returns a value != 0<br>-             */<br>-          gnvs->smif = 0;<br>-           return 1; /* IO trap handled */<br>-      }<br>-<br>- /* Not handled */<br>-    return 0;<br>-}<br>-<br>-/* Set the EOS bit */<br>-void southbridge_smi_set_eos(void)<br>-{<br>-    pmc_enable_smi(EOS);<br>-}<br>-<br>-static void busmaster_disable_on_bus(int bus)<br>-{<br>-      int slot, func;<br>-      unsigned int val;<br>-    unsigned char hdr;<br>-<br>-        for (slot = 0; slot < 0x20; slot++) {<br>-             for (func = 0; func < 8; func++) {<br>-                        u32 reg32;<br>-                   device_t dev = PCI_DEV(bus, slot, func);<br>-<br>-                  val = pci_read_config32(dev, PCI_VENDOR_ID);<br>-<br>-                      if (val == 0xffffffff || val == 0x00000000 ||<br>-                            val == 0x0000ffff || val == 0xffff0000)<br>-                          continue;<br>-<br>-                 /* Disable Bus Mastering for this one device */<br>-                      reg32 = pci_read_config32(dev, PCI_COMMAND);<br>-                 reg32 &= ~PCI_COMMAND_MASTER;<br>-                    pci_write_config32(dev, PCI_COMMAND, reg32);<br>-<br>-                      /* If this is a bridge, then follow it. */<br>-                   hdr = pci_read_config8(dev, PCI_HEADER_TYPE);<br>-                        hdr &= 0x7f;<br>-                     if (hdr == PCI_HEADER_TYPE_BRIDGE ||<br>-                     hdr == PCI_HEADER_TYPE_CARDBUS) {<br>-                                unsigned int buses;<br>-                          buses = pci_read_config32(dev, PCI_PRIMARY_BUS);<br>-                             busmaster_disable_on_bus((buses >> 8) & 0xff);<br>-                     }<br>-            }<br>-    }<br>-}<br>-<br>-<br>-static void southbridge_smi_sleep(void)<br>-{<br>-    u8 reg8;<br>-     u32 reg32;<br>-   u8 slp_typ;<br>-  u8 s5pwr = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;<br>-<br>-    /* save and recover RTC port values */<br>-       u8 tmp70, tmp72;<br>-     tmp70 = inb(0x70);<br>-   tmp72 = inb(0x72);<br>-   get_option(&s5pwr, "power_on_after_fail");<br>-     outb(tmp70, 0x70);<br>-   outb(tmp72, 0x72);<br>-<br>-        /* First, disable further SMIs */<br>-    pmc_disable_smi(SLP_SMI_EN);<br>-<br>-      /* Figure out SLP_TYP */<br>-     reg32 = pmc_read_pm1_control();<br>-      printk(BIOS_SPEW, "SMI#: SLP = 0x%08x\n", reg32);<br>-  slp_typ = acpi_sleep_from_pm1(reg32);<br>-<br>-     /* Do any mainboard sleep handling */<br>-        mainboard_smi_sleep(slp_typ);<br>-<br>-     if (IS_ENABLED(CONFIG_ELOG_GSMI))<br>-            /* Log S3, S4, and S5 entry */<br>-               if (slp_typ >= ACPI_S3)<br>-                   elog_add_event_byte(ELOG_TYPE_ACPI_ENTER, slp_typ);<br>-<br>-       /* Clear pending GPE events */<br>-       pmc_clear_all_gpe_status();<br>-<br>-       /* Next, do the deed. */<br>-     switch (slp_typ) {<br>-   case ACPI_S0:<br>-                printk(BIOS_DEBUG, "SMI#: Entering S0 (On)\n");<br>-            break;<br>-       case ACPI_S1:<br>-                printk(BIOS_DEBUG, "SMI#: Entering S1 (Assert STPCLK#)\n");<br>-                break;<br>-       case ACPI_S3:<br>-                printk(BIOS_DEBUG, "SMI#: Entering S3 (Suspend-To-RAM)\n");<br>-<br>-             gnvs->uior = uart_debug_controller_is_initialized();<br>-<br>-           /* Invalidate the cache before going to S3 */<br>-                wbinvd();<br>-            break;<br>-       case ACPI_S5:<br>-                printk(BIOS_DEBUG, "SMI#: Entering S5 (Soft Power off)\n");<br>-                /*TODO: cmos_layout.bin need to verify; cause wrong CMOS setup*/<br>-             s5pwr = MAINBOARD_POWER_ON;<br>-          /* Disable all GPE */<br>-                pmc_disable_all_gpe();<br>-<br>-            /*<br>-            * Always set the flag in case CMOS was changed on runtime. For<br>-               * "KEEP", switch to "OFF" - KEEP is software emulated<br>-            */<br>-          reg8 = pci_read_config8(PCH_DEV_PMC, GEN_PMCON_B);<br>-           if (s5pwr == MAINBOARD_POWER_ON)<br>-                     reg8 &= ~1;<br>-              else<br>-                 reg8 |= 1;<br>-           pci_write_config8(PCH_DEV_PMC, GEN_PMCON_B, reg8);<br>-<br>-                /* also iterates over all bridges on bus 0 */<br>-                busmaster_disable_on_bus(0);<br>-         break;<br>-       default:<br>-             printk(BIOS_DEBUG, "SMI#: ERROR: SLP_TYP reserved\n");<br>-             break;<br>-       }<br>-<br>- /*<br>-    * Write back to the SLP register to cause the originally intended<br>-    * event again. We need to set BIT13 (SLP_EN) though to make the<br>-      * sleep happen.<br>-      */<br>-  pmc_enable_pm1_control(SLP_EN);<br>-<br>-   /* Make sure to stop executing code here for S3/S4/S5 */<br>-     if (slp_typ >= ACPI_S3)<br>-           hlt();<br>-<br>-    /*<br>-    * In most sleep states, the code flow of this function ends at<br>-       * the line above. However, if we entered sleep state S1 and wake<br>-     * up again, we will continue to execute code in this function.<br>-       */<br>-  if (pmc_read_pm1_control() & SCI_EN) {<br>-           /* The OS is not an ACPI OS, so we set the state to S0 */<br>-            pmc_disable_pm1_control(SLP_EN | SLP_TYP);<br>-   }<br>-}<br>-<br>-/*<br>- * Look for Synchronous IO SMI and use save state from that<br>- * core in case we are not running on the same core that<br>- * initiated the IO transaction.<br>- */<br>-static em64t101_smm_state_save_area_t *smi_apmc_find_state_save(u8 cmd)<br>-{<br>-        em64t101_smm_state_save_area_t *state;<br>-       int node;<br>-<br>- /* Check all nodes looking for the one that issued the IO */<br>- for (node = 0; node < CONFIG_MAX_CPUS; node++) {<br>-          state = smm_get_save_state(node);<br>-<br>-         /* Check for Synchronous IO (bit0==1) */<br>-             if (!(state->io_misc_info & (1 << 0)))<br>-                  continue;<br>-<br>-         /* Make sure it was a write (bit4==0) */<br>-             if (state->io_misc_info & (1 << 4))<br>-                     continue;<br>-<br>-         /* Check for APMC IO port */<br>-         if (((state->io_misc_info >> 16) & 0xff) != APM_CNT)<br>-                    continue;<br>-<br>-         /* Check AX against the requested command */<br>-         if ((state->rax & 0xff) != cmd)<br>-                       continue;<br>-<br>-         return state;<br>-        }<br>-<br>- return NULL;<br>-}<br>-<br>-static void southbridge_smi_gsmi(void)<br>-{<br>-#if IS_ENABLED(CONFIG_ELOG_GSMI)<br>-  u32 *ret, *param;<br>-    u8 sub_command;<br>-      em64t101_smm_state_save_area_t *io_smi =<br>-             smi_apmc_find_state_save(ELOG_GSMI_APM_CNT);<br>-<br>-      if (!io_smi)<br>-         return;<br>-<br>-   /* Command and return value in EAX */<br>-        ret = (u32 *)&io_smi->rax;<br>-    sub_command = (u8)(*ret >> 8);<br>-<br>-      /* Parameter buffer in EBX */<br>-        param = (u32 *)&io_smi->rbx;<br>-<br>-       /* drivers/elog/gsmi.c */<br>-    *ret = gsmi_exec(sub_command, param);<br>-#endif<br>-}<br>-<br>-static void finalize(void)<br>-{<br>-       static int finalize_done;<br>-<br>- if (finalize_done) {<br>-         printk(BIOS_DEBUG, "SMM already finalized.\n");<br>-            return;<br>-      }<br>-    finalize_done = 1;<br>-<br>-        if (IS_ENABLED(CONFIG_SPI_FLASH_SMM))<br>-                /* Re-init SPI driver to handle locked BAR */<br>-                fast_spi_init();<br>-}<br>-<br>-static void southbridge_smi_apmc(void)<br>-{<br>- u8 reg8;<br>-     em64t101_smm_state_save_area_t *state;<br>-<br>-    /* Emulate B2 register as the FADT / Linux expects it */<br>-<br>-  reg8 = inb(APM_CNT);<br>- switch (reg8) {<br>-      case APM_CNT_PST_CONTROL:<br>-            printk(BIOS_DEBUG, "P-state control\n");<br>-           break;<br>-       case APM_CNT_ACPI_DISABLE:<br>-           pmc_disable_pm1_control(SCI_EN);<br>-             printk(BIOS_DEBUG, "SMI#: ACPI disabled.\n");<br>-              break;<br>-       case APM_CNT_ACPI_ENABLE:<br>-            pmc_enable_pm1_control(SCI_EN);<br>-              printk(BIOS_DEBUG, "SMI#: ACPI enabled.\n");<br>-               break;<br>-       case APM_CNT_FINALIZE:<br>-               finalize();<br>-          break;<br>-       case APM_CNT_GNVS_UPDATE:<br>-            if (smm_initialized) {<br>-                       printk(BIOS_DEBUG,<br>-                          "SMI#: SMM structures already initialized!\n");<br>-                     return;<br>-              }<br>-            state = smi_apmc_find_state_save(reg8);<br>-              if (state) {<br>-                 /* EBX in the state save contains the GNVS pointer */<br>-                        gnvs = (global_nvs_t *)((u32)state->rbx);<br>-                 smm_initialized = 1;<br>-                 printk(BIOS_DEBUG, "SMI#: Setting GNVS to %p\n", gnvs);<br>-            }<br>-            break;<br>-       case ELOG_GSMI_APM_CNT:<br>-              if (IS_ENABLED(CONFIG_ELOG_GSMI))<br>-                    southbridge_smi_gsmi();<br>-              break;<br>-       }<br>-<br>- mainboard_smi_apmc(reg8);<br>-}<br>-<br>-static void southbridge_smi_pm1(void)<br>-{<br>- u16 pm1_sts = pmc_clear_pm1_status();<br>-        u16 pm1_en = pmc_read_pm1_enable();<br>-<br>-       /*<br>-    * While OSPM is not active, poweroff immediately on a power button<br>-   * event.<br>-     */<br>-  if ((pm1_sts & PWRBTN_STS) && (pm1_en & PWRBTN_EN)) {<br>-                /* power button pressed */<br>-           if (IS_ENABLED(CONFIG_ELOG_GSMI))<br>-                    elog_add_event(ELOG_TYPE_POWER_BUTTON);<br>-              pmc_disable_pm1_control(-1UL);<br>-               pmc_enable_pm1_control(SLP_EN | (SLP_TYP_S5 << 10));<br>-   }<br>-}<br>-<br>-static void southbridge_smi_gpe0(void)<br>-{<br>-        pmc_clear_all_gpe_status();<br>-}<br>-<br>-void __attribute__((weak))<br>-mainboard_smi_gpi_handler(const struct gpi_status *sts) { }<br>-<br>-static void southbridge_smi_gpi(void)<br>-{<br>- struct gpi_status smi_sts;<br>-<br>-        gpi_clear_get_smi_status(&smi_sts);<br>-      mainboard_smi_gpi_handler(&smi_sts);<br>-<br>-  /* Clear again after mainboard handler */<br>-    gpi_clear_get_smi_status(&smi_sts);<br>-}<br>-<br>-void __attribute__((weak)) mainboard_smi_espi_handler(void) { }<br>-static void southbridge_smi_espi(void)<br>-{<br>-        mainboard_smi_espi_handler();<br>-}<br>-<br>-static void southbridge_smi_mc(void)<br>-{<br>-      u32 reg32 = inl(ACPI_BASE_ADDRESS + SMI_EN);<br>-<br>-      /* Are microcontroller SMIs enabled? */<br>-      if ((reg32 & MCSMI_EN) == 0)<br>-             return;<br>-<br>-   printk(BIOS_DEBUG, "Microcontroller SMI.\n");<br>-}<br>-<br>-static void southbridge_smi_tco(void)<br>-{<br>-   u32 tco_sts = pmc_clear_tco_status();<br>-<br>-     /* Any TCO event? */<br>- if (!tco_sts)<br>-                return;<br>-<br>-   if (tco_sts & (1 << 8)) { /* BIOSWR */<br>-             if (IS_ENABLED(CONFIG_SPI_FLASH_SMM)) {<br>-                      if (fast_spi_wpd_status()) {<br>-                         /*<br>-                            * BWE is RW, so the SMI was caused by a<br>-                              * write to BWE, not by a write to the BIOS<br>-                           *<br>-                            * This is the place where we notice someone<br>-                          * is trying to tinker with the BIOS. We are<br>-                          * trying to be nice and just ignore it. A more<br>-                               * resolute answer would be to power down the<br>-                                 * box.<br>-                               */<br>-                          printk(BIOS_DEBUG, "Switching back to RO\n");<br>-                              fast_spi_enable_wp();<br>-                        } /* No else for now? */<br>-             }<br>-    } else if (tco_sts & (1 << 3)) { /* TIMEOUT */<br>-             /* Handle TCO timeout */<br>-             printk(BIOS_DEBUG, "TCO Timeout.\n");<br>-      }<br>-}<br>-<br>-static void southbridge_smi_periodic(void)<br>-{<br>-    u32 reg32 = inl(ACPI_BASE_ADDRESS + SMI_EN);<br>-<br>-      /* Are periodic SMIs enabled? */<br>-     if ((reg32 & PERIODIC_EN) == 0)<br>-          return;<br>-<br>-   printk(BIOS_DEBUG, "Periodic SMI.\n");<br>-}<br>-<br>-static void southbridge_smi_monitor(void)<br>-{<br>-#define IOTRAP(x) (trap_sts & (1 << x))<br>-  u32 trap_cycle;<br>-      u32 data, mask = 0;<br>-  u8 trap_sts;<br>- int i;<br>-       /* TRSR - Trap Status Register */<br>-    trap_sts = pcr_read8(PID_PSTH, PCR_PSTH_TRPST);<br>-      /* Clear trap(s) in TRSR */<br>-  pcr_write8(PID_PSTH, PCR_PSTH_TRPST, trap_sts);<br>-<br>-   /* TRPC - Trapped cycle */<br>-   trap_cycle = pcr_read32(PID_PSTH, PCR_PSTH_TRPC);<br>-    for (i = 16; i < 20; i++) {<br>-               if (trap_cycle & (1 << i))<br>-                 mask |= (0xff << ((i - 16) << 2));<br>-       }<br>-<br>-<br>-      /* IOTRAP(3) SMI function call */<br>-    if (IOTRAP(3)) {<br>-             if (gnvs && gnvs->smif)<br>-                   io_trap_handler(gnvs->smif); /* call function smif */<br>-             return;<br>-      }<br>-<br>- /*<br>-    * IOTRAP(2) currently unused<br>-         * IOTRAP(1) currently unused<br>-         */<br>-<br>-       /* IOTRAP(0) SMIC */<br>- if (IOTRAP(0)) {<br>-             if (!(trap_cycle & (1 << 24))) { /* It's a write */<br>-                    printk(BIOS_DEBUG, "SMI1 command\n");<br>-                      /* Trapped write data */<br>-                     data = pcr_read32(PID_PSTH, PCR_PSTH_TRPD);<br>-                  data &= mask;<br>-            }<br>-    }<br>-<br>- printk(BIOS_DEBUG, "  trapped io address = 0x%x\n",<br>-               trap_cycle & 0xfffc);<br>-     for (i = 0; i < 4; i++)<br>-           if (IOTRAP(i))<br>-                       printk(BIOS_DEBUG, "  TRAP = %d\n", i);<br>-    printk(BIOS_DEBUG, "  AHBE = %x\n", (trap_cycle >> 16) & 0xf);<br>-   printk(BIOS_DEBUG, "  MASK = 0x%08x\n", mask);<br>-     printk(BIOS_DEBUG, "  read/write: %s\n",<br>-          (trap_cycle & (1 << 24)) ? "read" : "write");<br>-<br>-        if (!(trap_cycle & (1 << 24))) {<br>-           /* Write Cycle */<br>-            data = pcr_read32(PID_PSTH, PCR_PSTH_TRPD);<br>-          printk(BIOS_DEBUG, "  iotrap written data = 0x%08x\n", data);<br>-      }<br>-#undef IOTRAP<br>-}<br>-<br>-typedef void (*smi_handler_t)(void);<br>-<br>-static smi_handler_t southbridge_smi[SMI_STS_BITS] = {<br>-  [SMI_ON_SLP_EN_STS_BIT] = southbridge_smi_sleep,<br>-     [APM_STS_BIT] = southbridge_smi_apmc,<br>-        [PM1_STS_BIT] = southbridge_smi_pm1,<br>- [GPE0_STS_BIT] = southbridge_smi_gpe0,<br>-       [GPIO_STS_BIT] = southbridge_smi_gpi,<br>-        [ESPI_SMI_STS_BIT] = southbridge_smi_espi,<br>-   [MCSMI_STS_BIT] = southbridge_smi_mc,<br>-        [TCO_STS_BIT] = southbridge_smi_tco,<br>- [PERIODIC_STS_BIT] = southbridge_smi_periodic,<br>-       [MONITOR_STS_BIT] = southbridge_smi_monitor,<br>-};<br>-<br>-#define SMI_HANDLER_SCI_EN(__bit)        (1 << (__bit))<br>-<br>-/* SMI handlers that should be serviced in SCI mode too. */<br>-uint32_t smi_handler_sci_mask =<br>-      SMI_HANDLER_SCI_EN(APM_STS_BIT) |<br>-    SMI_HANDLER_SCI_EN(SMI_ON_SLP_EN_STS_BIT);<br>-<br>-/*<br>- * Interrupt handler for SMI#<br>- */<br>-void southbridge_smi_handler(void)<br>-{<br>-    int i;<br>-       u32 smi_sts;<br>-<br>-      /*<br>-    * We need to clear the SMI status registers, or we won't see what's<br>-  * happening in the following calls.<br>-  */<br>-  smi_sts = pmc_clear_smi_status();<br>-<br>- /*<br>-    * In SCI mode, execute only those SMI handlers that have<br>-     * declared themselves as available for service in that mode<br>-  * using smi_handler_sci_mask.<br>-        */<br>-  if (pmc_read_pm1_control() & SCI_EN)<br>-             smi_sts &= smi_handler_sci_mask;<br>-<br>-      if (!smi_sts)<br>-                return;<br>-<br>-   /* Call SMI sub handler for each of the status bits */<br>-       for (i = 0; i < ARRAY_SIZE(southbridge_smi); i++) {<br>-               if (smi_sts & (1 << i)) {<br>-                  if (southbridge_smi[i]) {<br>-                            southbridge_smi[i]();<br>-                        } else {<br>-                             printk(BIOS_DEBUG,<br>-                               "SMI_STS[%d] occurred, but no handler available.\n",<br>-                               i);<br>-                      }<br>-            }<br>-    }<br>-}<br>+const smi_handler_t southbridge_smi[SMI_STS_BITS] = {<br>+        [SMI_ON_SLP_EN_STS_BIT] = smihandler_southbridge_sleep,<br>+      [APM_STS_BIT] = smihandler_southbridge_apmc,<br>+ [PM1_STS_BIT] = smihandler_southbridge_pm1,<br>+  [GPE0_STS_BIT] = smihandler_southbridge_gpe0,<br>+        [GPIO_STS_BIT] = smihandler_southbridge_gpi,<br>+ [ESPI_SMI_STS_BIT] = smihandler_southbridge_espi,<br>+    [MCSMI_STS_BIT] = smihandler_southbridge_mc,<br>+ [TCO_STS_BIT] = smihandler_southbridge_tco,<br>+  [PERIODIC_STS_BIT] = smihandler_southbridge_periodic,<br>+        [MONITOR_STS_BIT] = smihandler_southbridge_monitor,<br>+};<br>\ No newline at end of file<br>diff --git a/src/soc/intel/skylake/smmrelocate.c b/src/soc/intel/skylake/smmrelocate.c<br>index dbe0c94..b477b11 100644<br>--- a/src/soc/intel/skylake/smmrelocate.c<br>+++ b/src/soc/intel/skylake/smmrelocate.c<br>@@ -26,6 +26,7 @@<br> #include <cpu/x86/mtrr.h><br> #include <cpu/x86/smm.h><br> #include <console/console.h><br>+#include <intelblocks/smm.h><br> #include <soc/cpu.h><br> #include <soc/msr.h><br> #include <soc/pci_devs.h><br>@@ -281,7 +282,7 @@<br> void smm_initialize(void)<br> {<br>   /* Clear the SMM state in the southbridge. */<br>-        southbridge_smm_clear_state();<br>+       smm_southbridge_clear_state();<br> <br>     /*<br>     * Run the relocation handler for on the BSP to check and set up<br></pre><p>To view, visit <a href="https://review.coreboot.org/22826">change 22826</a>. To unsubscribe, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/22826"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I8163dc7e18bb417e8c18a12628988959c128b3df </div>
<div style="display:none"> Gerrit-Change-Number: 22826 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Subrata Banik <subrata.banik@intel.com> </div>
<div style="display:none"> Gerrit-Reviewer: Brandon Breitenstein <brandon.breitenstein@intel.com> </div>