<p>Lijian Zhao has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/21543">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">[wip]soc/intel/cannonlake: Fill the SMI usage<br><br>Change-Id: I9aab141c528709b30804d327804c4031c59fcfff<br>Signed-off-by: Lijian Zhao <lijian.zhao@intel.com><br>---<br>M src/soc/intel/cannonlake/Kconfig<br>M src/soc/intel/cannonlake/Makefile.inc<br>M src/soc/intel/cannonlake/cpu.c<br>M src/soc/intel/cannonlake/include/soc/msr.h<br>A src/soc/intel/cannonlake/include/soc/smm.h<br>M src/soc/intel/cannonlake/memmap.c<br>M src/soc/intel/cannonlake/smihandler.c<br>A src/soc/intel/cannonlake/smmrelocate.c<br>M src/soc/intel/common/block/include/intelblocks/smihandler.h<br>M src/soc/intel/common/block/smm/smitraphandler.c<br>10 files changed, 496 insertions(+), 11 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/43/21543/12</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/src/soc/intel/cannonlake/Kconfig b/src/soc/intel/cannonlake/Kconfig<br>index fe80a20..bf47270 100644<br>--- a/src/soc/intel/cannonlake/Kconfig<br>+++ b/src/soc/intel/cannonlake/Kconfig<br>@@ -21,6 +21,7 @@<br>         select HAVE_HARD_RESET<br>        select HAVE_INTEL_FIRMWARE<br>    select HAVE_MONOTONIC_TIMER<br>+  select HAVE_SMI_HANDLER<br>       select INTEL_CAR_NEM_ENHANCED<br>         select PARALLEL_MP<br>    select PARALLEL_MP_AP_WORK<br>@@ -28,7 +29,9 @@<br>         select POSTCAR_CONSOLE<br>        select POSTCAR_STAGE<br>  select REG_SCRIPT<br>+    select RELOCATABLE_MODULES<br>    select RELOCATABLE_RAMSTAGE<br>+  select SMM_TSEG<br>       select SMP<br>    select SOC_INTEL_COMMON<br>       select SOC_INTEL_COMMON_ACPI_WAKE_SOURCE<br>@@ -53,6 +56,7 @@<br>   select SOC_INTEL_COMMON_BLOCK_UART<br>    select SOC_INTEL_COMMON_SPI_FLASH_PROTECT<br>     select SOC_INTEL_COMMON_RESET<br>+        select SSE2<br>   select SUPPORT_CPU_UCODE_IN_CBFS<br>      select TSC_CONSTANT_RATE<br>      select TSC_MONOTONIC_TIMER<br>diff --git a/src/soc/intel/cannonlake/Makefile.inc b/src/soc/intel/cannonlake/Makefile.inc<br>index 0493c1b..1797845 100644<br>--- a/src/soc/intel/cannonlake/Makefile.inc<br>+++ b/src/soc/intel/cannonlake/Makefile.inc<br>@@ -5,6 +5,7 @@<br> subdirs-y += ../../../cpu/intel/turbo<br> subdirs-y += ../../../cpu/x86/lapic<br> subdirs-y += ../../../cpu/x86/mtrr<br>+subdirs-y += ../../../cpu/x86/smm<br> subdirs-y += ../../../cpu/x86/tsc<br> <br> bootblock-y += bootblock/bootblock.c<br>@@ -34,12 +35,20 @@<br> ramstage-y += memmap.c<br> ramstage-y += pmutil.c<br> ramstage-$(CONFIG_PLATFORM_USES_FSP2_0) += reset.c<br>+ramstage-y += smmrelocate.c<br> ramstage-y += spi.c<br> ramstage-y += systemagent.c<br> ramstage-$(CONFIG_UART_DEBUG) += uart.c<br> ramstage-$(CONFIG_UART_DEBUG) += uart_pch.c<br> ramstage-y += vr_config.c<br> <br>+smm-y += gpio.c<br>+smm-y += pmutil.c<br>+smm-y += smihandler.c<br>+smm-$(CONFIG_SPI_FLASH_SMM) += spi.c<br>+smm-$(CONFIG_UART_DEBUG) += uart.c<br>+smm-$(CONFIG_UART_DEBUG) += uart_pch.c<br>+<br> postcar-y += memmap.c<br> postcar-y += pmutil.c<br> postcar-y += spi.c<br>diff --git a/src/soc/intel/cannonlake/cpu.c b/src/soc/intel/cannonlake/cpu.c<br>index 4e06577..23ffe8f 100644<br>--- a/src/soc/intel/cannonlake/cpu.c<br>+++ b/src/soc/intel/cannonlake/cpu.c<br>@@ -21,10 +21,12 @@<br> #include <cpu/intel/turbo.h><br> #include <intelblocks/cpulib.h><br> #include <intelblocks/mp_init.h><br>+#include <intelblocks/smm.h><br> #include <romstage_handoff.h><br> #include <soc/cpu.h><br> #include <soc/msr.h><br> #include <soc/pci_devs.h><br>+#include <soc/smm.h><br> <br> static void soc_fsp_load(void)<br> {<br>@@ -197,13 +199,29 @@<br> <br>       /* Enable Turbo */<br>    enable_turbo();<br>+}<br> <br>+static void per_cpu_smm_trigger(void)<br>+{<br>+   /* Relocate the SMM handler. */<br>+      smm_relocate();<br> }<br> <br> static void post_mp_init(void)<br> {<br>   /* Set Max Ratio */<br>   cpu_set_max_ratio();<br>+<br>+      /*<br>+    * Now that all APs have been relocated as well as the BSP let SMIs<br>+   * start flowing.<br>+     */<br>+  smm_southbridge_enable();<br>+<br>+ /* Lock down the SMRAM space. */<br>+#if IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)<br>+   smm_lock();<br>+#endif<br> }<br> <br> static const struct mp_ops mp_ops = {<br>@@ -214,7 +232,11 @@<br>      */<br>   .pre_mp_init = soc_fsp_load,<br>  .get_cpu_count = get_cpu_count,<br>+      .get_smm_info = smm_info,<br>     .get_microcode_info = get_microcode_info,<br>+    .pre_mp_smm_init = smm_initialize,<br>+   .per_cpu_smm_trigger = per_cpu_smm_trigger,<br>+  .relocation_handler = smm_relocation_handler,<br>         .post_mp_init = post_mp_init,<br> };<br> <br>diff --git a/src/soc/intel/cannonlake/include/soc/msr.h b/src/soc/intel/cannonlake/include/soc/msr.h<br>index 931281a..6617d7f 100644<br>--- a/src/soc/intel/cannonlake/include/soc/msr.h<br>+++ b/src/soc/intel/cannonlake/include/soc/msr.h<br>@@ -20,22 +20,13 @@<br> #include <intelblocks/msr.h><br> <br> #define MSR_PIC_MSG_CONTROL               0x2e<br>-#define MSR_BIOS_UPGD_TRIG               0x7a<br> #define IA32_THERM_INTERRUPT             0x19b<br> #define IA32_ENERGY_PERFORMANCE_BIAS    0x1b0<br> #define  ENERGY_POLICY_PERFORMANCE      0<br> #define  ENERGY_POLICY_NORMAL               6<br> #define  ENERGY_POLICY_POWERSAVE    15<br> #define IA32_PACKAGE_THERM_INTERRUPT       0x1b2<br>-#define PRMRR_PHYS_BASE_MSR             0x1f4<br>-#define IA32_PLATFORM_DCA_CAP           0x1f8<br>-#define MSR_LT_LOCK_MEMORY              0x2e7<br>-#define MSR_SGX_OWNEREPOCH0             0x300<br>-#define MSR_SGX_OWNEREPOCH1             0x301<br>-#define MSR_VR_CURRENT_CONFIG           0x601<br>-#define MSR_VR_MISC_CONFIG              0x603<br>+#define IA32_PLATFORM_DCA_CAP           0x1f9<br> #define MSR_VR_MISC_CONFIG2             0x636<br>-#define MSR_PP0_POWER_LIMIT             0x638<br>-#define MSR_PP1_POWER_LIMIT             0x640<br> <br> #endif<br>diff --git a/src/soc/intel/cannonlake/include/soc/smm.h b/src/soc/intel/cannonlake/include/soc/smm.h<br>new file mode 100644<br>index 0000000..9121ac3<br>--- /dev/null<br>+++ b/src/soc/intel/cannonlake/include/soc/smm.h<br>@@ -0,0 +1,71 @@<br>+/*<br>+ * This file is part of the coreboot project.<br>+ *<br>+ * Copyright (C) 2014 Google Inc.<br>+ * Copyright (C) 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>+ * 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>+#ifndef _SOC_SMM_H_<br>+#define _SOC_SMM_H_<br>+<br>+#include <stdint.h><br>+#include <cpu/x86/msr.h><br>+#include <fsp/memmap.h><br>+#include <soc/gpio.h><br>+<br>+struct ied_header {<br>+       char signature[10];<br>+  u32 size;<br>+    u8 reserved[34];<br>+} __packed;<br>+<br>+struct smm_relocation_params {<br>+   u32 smram_base;<br>+      u32 smram_size;<br>+      u32 ied_base;<br>+        u32 ied_size;<br>+        msr_t smrr_base;<br>+     msr_t smrr_mask;<br>+     msr_t emrr_base;<br>+     msr_t emrr_mask;<br>+     msr_t uncore_emrr_base;<br>+      msr_t uncore_emrr_mask;<br>+      /*<br>+    * The smm_save_state_in_msrs field indicates if SMM save state<br>+       * locations live in MSRs. This indicates to the CPUs how to adjust<br>+   * the SMMBASE and IEDBASE<br>+    */<br>+  int smm_save_state_in_msrs;<br>+};<br>+<br>+/* Mainboard handler for eSPI SMIs */<br>+void mainboard_smi_espi_handler(void);<br>+<br>+#if IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)<br>+void smm_relocation_handler(int cpu, uintptr_t curr_smbase,<br>+                              uintptr_t staggered_smbase);<br>+void smm_info(uintptr_t *perm_smbase, size_t *perm_smsize,<br>+            size_t *smm_save_state_size);<br>+void smm_initialize(void);<br>+void smm_relocate(void);<br>+<br>+#else        /* CONFIG_HAVE_SMI_HANDLER */<br>+static inline void smm_relocation_handler(int cpu, uintptr_t curr_smbase,<br>+                            uintptr_t staggered_smbase) {}<br>+static inline void smm_info(uintptr_t *perm_smbase, size_t *perm_smsize,<br>+            size_t *smm_save_state_size) {}<br>+static inline void smm_initialize(void) {}<br>+<br>+static inline void smm_relocate(void) {}<br>+#endif     /* CONFIG_HAVE_SMI_HANDLER */<br>+<br>+#endif<br>diff --git a/src/soc/intel/cannonlake/memmap.c b/src/soc/intel/cannonlake/memmap.c<br>index 29f25f2..0259cda 100644<br>--- a/src/soc/intel/cannonlake/memmap.c<br>+++ b/src/soc/intel/cannonlake/memmap.c<br>@@ -23,9 +23,64 @@<br> #include <intelblocks/systemagent.h><br> #include <soc/bootblock.h><br> #include <soc/pci_devs.h><br>+#include <soc/smm.h><br> #include <soc/systemagent.h><br> #include <stdlib.h><br> <br>+void smm_region(void **start, size_t *size)<br>+{<br>+      *start = (void *)sa_get_tseg_base();<br>+ *size = sa_get_tseg_size();<br>+}<br>+<br>+/*<br>+ *        Subregions within SMM<br>+ *     +-------------------------+ BGSM<br>+ *     |          IED            | IED_REGION_SIZE<br>+ *     +-------------------------+<br>+ *     |  External Stage Cache   | SMM_RESERVED_SIZE<br>+ *     +-------------------------+<br>+ *     |      code and data      |<br>+ *     |         (TSEG)          |<br>+ *     +-------------------------+ TSEG<br>+ */<br>+int smm_subregion(int sub, void **start, size_t *size)<br>+{<br>+     uintptr_t sub_base;<br>+  size_t sub_size;<br>+     void *smm_base;<br>+      const size_t ied_size = CONFIG_IED_REGION_SIZE;<br>+      const size_t cache_size = CONFIG_SMM_RESERVED_SIZE;<br>+<br>+       smm_region(&smm_base, &sub_size);<br>+    sub_base = (uintptr_t)smm_base;<br>+<br>+   switch (sub) {<br>+       case SMM_SUBREGION_HANDLER:<br>+          /* Handler starts at the base of TSEG. */<br>+            sub_size -= ied_size;<br>+                sub_size -= cache_size;<br>+              break;<br>+       case SMM_SUBREGION_CACHE:<br>+            /* External cache is in the middle of TSEG. */<br>+               sub_base += sub_size - (ied_size + cache_size);<br>+              sub_size = cache_size;<br>+               break;<br>+       case SMM_SUBREGION_CHIPSET:<br>+          /* IED is at the top. */<br>+             sub_base += sub_size - ied_size;<br>+             sub_size = ied_size;<br>+         break;<br>+       default:<br>+             return -1;<br>+   }<br>+<br>+ *start = (void *)sub_base;<br>+   *size = sub_size;<br>+<br>+ return 0;<br>+}<br>+<br> static void *top_of_ram_register(void)<br> {<br>         int num;<br>diff --git a/src/soc/intel/cannonlake/smihandler.c b/src/soc/intel/cannonlake/smihandler.c<br>index eb3c5e3..0653e9f 100644<br>--- a/src/soc/intel/cannonlake/smihandler.c<br>+++ b/src/soc/intel/cannonlake/smihandler.c<br>@@ -16,8 +16,14 @@<br>  */<br> <br> #include <intelblocks/smihandler.h><br>+#include <soc/pm.h><br> <br>-static smi_handler_t southbridge_smi[SMI_STS_BITS] = {<br>+const struct smm_save_state_ops *get_smm_save_state_ops(void)<br>+{<br>+   return &em64t101_smm_ops;<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>diff --git a/src/soc/intel/cannonlake/smmrelocate.c b/src/soc/intel/cannonlake/smmrelocate.c<br>new file mode 100644<br>index 0000000..d5d5b8e<br>--- /dev/null<br>+++ b/src/soc/intel/cannonlake/smmrelocate.c<br>@@ -0,0 +1,310 @@<br>+/*<br>+ * This file is part of the coreboot project.<br>+ *<br>+ * Copyright (C) 2014 Google Inc.<br>+ * Copyright (C) 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>+ * 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 <types.h><br>+#include <string.h><br>+#include <device/device.h><br>+#include <device/pci.h><br>+#include <cpu/cpu.h><br>+#include <cpu/x86/cache.h><br>+#include <cpu/x86/lapic.h><br>+#include <cpu/x86/mp.h><br>+#include <cpu/x86/msr.h><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>+#include <soc/smm.h><br>+#include <soc/systemagent.h><br>+#include "chip.h"<br>+<br>+/* This gets filled in and used during relocation. */<br>+static struct smm_relocation_params smm_reloc_params;<br>+<br>+static inline void write_smrr(struct smm_relocation_params *relo_params)<br>+{<br>+       printk(BIOS_DEBUG, "Writing SMRR. base = 0x%08x, mask=0x%08x\n",<br>+          relo_params->smrr_base.lo, relo_params->smrr_mask.lo);<br>+  wrmsr(SMRR_PHYS_BASE, relo_params->smrr_base);<br>+    wrmsr(SMRR_PHYS_MASK, relo_params->smrr_mask);<br>+}<br>+<br>+static void update_save_state(int cpu, uintptr_t curr_smbase,<br>+                             uintptr_t staggered_smbase,<br>+                          struct smm_relocation_params *relo_params)<br>+{<br>+       u32 smbase;<br>+  u32 iedbase;<br>+<br>+      /*<br>+    * The relocated handler runs with all CPUs concurrently. Therefore<br>+   * stagger the entry points adjusting SMBASE downwards by save state<br>+  * size * CPU num.<br>+    */<br>+  smbase = staggered_smbase;<br>+   iedbase = relo_params->ied_base;<br>+<br>+       printk(BIOS_DEBUG, "New SMBASE=0x%08x IEDBASE=0x%08x\n",<br>+          smbase, iedbase);<br>+<br>+  /*<br>+    * All threads need to set IEDBASE and SMBASE to the relocated<br>+        * handler region. However, the save state location depends on the<br>+    * smm_save_state_in_msrs field in the relocation parameters. If<br>+      * smm_save_state_in_msrs is non-zero then the CPUs are relocating<br>+    * the SMM handler in parallel, and each CPUs save state area is<br>+      * located in their respective MSR space. If smm_save_state_in_msrs<br>+   * is zero then the SMM relocation is happening serially so the<br>+       * save state is at the same default location for all CPUs.<br>+   */<br>+  if (relo_params->smm_save_state_in_msrs) {<br>+                msr_t smbase_msr;<br>+            msr_t iedbase_msr;<br>+<br>+                smbase_msr.lo = smbase;<br>+              smbase_msr.hi = 0;<br>+<br>+                /*<br>+            * According the BWG the IEDBASE MSR is in bits 63:32. It's<br>+               * not clear why it differs from the SMBASE MSR.<br>+              */<br>+          iedbase_msr.lo = 0;<br>+          iedbase_msr.hi = iedbase;<br>+<br>+         wrmsr(SMBASE_MSR, smbase_msr);<br>+               wrmsr(IEDBASE_MSR, iedbase_msr);<br>+     } else {<br>+             em64t101_smm_state_save_area_t *save_state;<br>+<br>+               save_state = (void *)(curr_smbase + SMM_DEFAULT_SIZE -<br>+                                     sizeof(*save_state));<br>+<br>+               save_state->smbase = smbase;<br>+              save_state->iedbase = iedbase;<br>+    }<br>+}<br>+<br>+/* Returns 1 if SMM MSR save state was set. */<br>+static int bsp_setup_msr_save_state(struct smm_relocation_params *relo_params)<br>+{<br>+       msr_t smm_mca_cap;<br>+<br>+        smm_mca_cap = rdmsr(SMM_MCA_CAP_MSR);<br>+        if (smm_mca_cap.hi & SMM_CPU_SVRSTR_MASK) {<br>+              msr_t smm_feature_control;<br>+<br>+                smm_feature_control = rdmsr(SMM_FEATURE_CONTROL_MSR);<br>+                smm_feature_control.hi = 0;<br>+          smm_feature_control.lo |= SMM_CPU_SAVE_EN;<br>+           wrmsr(SMM_FEATURE_CONTROL_MSR, smm_feature_control);<br>+         relo_params->smm_save_state_in_msrs = 1;<br>+  }<br>+    return relo_params->smm_save_state_in_msrs;<br>+}<br>+<br>+/*<br>+ * The relocation work is actually performed in SMM context, but the code<br>+ * resides in the ramstage module. This occurs by trampolining from the default<br>+ * SMRAM entry point to here.<br>+ */<br>+void smm_relocation_handler(int cpu, uintptr_t curr_smbase,<br>+                         uintptr_t staggered_smbase)<br>+{<br>+      msr_t mtrr_cap;<br>+      struct smm_relocation_params *relo_params = &smm_reloc_params;<br>+<br>+        printk(BIOS_DEBUG, "In relocation handler: CPU %d\n", cpu);<br>+<br>+     /*<br>+    * Determine if the processor supports saving state in MSRs. If so,<br>+   * enable it before the non-BSPs run so that SMM relocation can occur<br>+         * in parallel in the non-BSP CPUs.<br>+   */<br>+  if (cpu == 0) {<br>+              /*<br>+            * If smm_save_state_in_msrs is 1 then that means this is the<br>+                 * 2nd time through the relocation handler for the BSP.<br>+               * Parallel SMM handler relocation is taking place. However,<br>+          * it is desired to access other CPUs save state in the real<br>+          * SMM handler. Therefore, disable the SMM save state in MSRs<br>+                 * feature.<br>+           */<br>+          if (relo_params->smm_save_state_in_msrs) {<br>+                        msr_t smm_feature_control;<br>+<br>+                        smm_feature_control = rdmsr(SMM_FEATURE_CONTROL_MSR);<br>+                        smm_feature_control.lo &= ~SMM_CPU_SAVE_EN;<br>+                      wrmsr(SMM_FEATURE_CONTROL_MSR, smm_feature_control);<br>+         } else if (bsp_setup_msr_save_state(relo_params))<br>+                    /*<br>+                    * Just return from relocation handler if MSR save<br>+                    * state is enabled. In that case the BSP will come<br>+                   * back into the relocation handler to setup the new<br>+                  * SMBASE as well disabling SMM save state in MSRs.<br>+                   */<br>+                  return;<br>+      }<br>+<br>+ /* Make appropriate changes to the save state map. */<br>+        update_save_state(cpu, curr_smbase, staggered_smbase, relo_params);<br>+<br>+       /* Write EMRR and SMRR MSRs based on indicated support. */<br>+   mtrr_cap = rdmsr(MTRR_CAP_MSR);<br>+      if (mtrr_cap.lo & SMRR_SUPPORTED)<br>+                write_smrr(relo_params);<br>+}<br>+<br>+static void fill_in_relocation_params(device_t dev,<br>+                                      struct smm_relocation_params *params)<br>+{<br>+      void *handler_base;<br>+  size_t handler_size;<br>+ void *ied_base;<br>+      size_t ied_size;<br>+     void *tseg_base;<br>+     size_t tseg_size;<br>+    u32 emrr_base;<br>+       u32 emrr_size;<br>+       int phys_bits;<br>+       /* All range registers are aligned to 4KiB */<br>+        const u32 rmask = ~((1 << 12) - 1);<br>+<br>+ /*<br>+    * Some of the range registers are dependent on the number of physical<br>+        * address bits supported.<br>+    */<br>+  phys_bits = cpuid_eax(0x80000008) & 0xff;<br>+<br>+     smm_region(&tseg_base, &tseg_size);<br>+  smm_subregion(SMM_SUBREGION_HANDLER, &handler_base, &handler_size);<br>+  smm_subregion(SMM_SUBREGION_CHIPSET, &ied_base, &ied_size);<br>+<br>+       params->smram_size = handler_size;<br>+        params->smram_base = (uintptr_t)handler_base;<br>+<br>+  params->ied_base = (uintptr_t)ied_base;<br>+   params->ied_size = ied_size;<br>+<br>+   /* SMRR has 32-bits of valid address aligned to 4KiB. */<br>+     params->smrr_base.lo = (params->smram_base & rmask) | MTRR_TYPE_WRBACK;<br>+    params->smrr_base.hi = 0;<br>+ params->smrr_mask.lo = (~(tseg_size - 1) & rmask)<br>+             | MTRR_PHYS_MASK_VALID;<br>+      params->smrr_mask.hi = 0;<br>+<br>+      /* The EMRR and UNCORE_EMRR are at IEDBASE + 2MiB */<br>+ emrr_base = (params->ied_base + (2 << 20)) & rmask;<br>+     emrr_size = params->ied_size - (2 << 20);<br>+<br>+        /*<br>+    * EMRR has 46 bits of valid address aligned to 4KiB. It's dependent<br>+      * on the number of physical address bits supported.<br>+  */<br>+  params->emrr_base.lo = emrr_base | MTRR_TYPE_WRBACK;<br>+      params->emrr_base.hi = 0;<br>+ params->emrr_mask.lo = (~(emrr_size - 1) & rmask)<br>+             | MTRR_PHYS_MASK_VALID;<br>+      params->emrr_mask.hi = (1 << (phys_bits - 32)) - 1;<br>+<br>+      /* UNCORE_EMRR has 39 bits of valid address aligned to 4KiB. */<br>+      params->uncore_emrr_base.lo = emrr_base;<br>+  params->uncore_emrr_base.hi = 0;<br>+  params->uncore_emrr_mask.lo = (~(emrr_size - 1) & rmask) |<br>+                                    MTRR_PHYS_MASK_VALID;<br>+        params->uncore_emrr_mask.hi = (1 << (39 - 32)) - 1;<br>+}<br>+<br>+static void setup_ied_area(struct smm_relocation_params *params)<br>+{<br>+   char *ied_base;<br>+<br>+   struct ied_header ied = {<br>+            .signature = "INTEL RSVD",<br>+         .size = params->ied_size,<br>+         .reserved = {0},<br>+     };<br>+<br>+        ied_base = (void *)params->ied_base;<br>+<br>+   printk(BIOS_DEBUG, "IED base = 0x%08x\n", params->ied_base);<br>+    printk(BIOS_DEBUG, "IED size = 0x%08x\n", params->ied_size);<br>+<br>+ /* Place IED header at IEDBASE. */<br>+   memcpy(ied_base, &ied, sizeof(ied));<br>+<br>+  /* Zero out 32KiB at IEDBASE + 1MiB */<br>+       memset(ied_base + (1 << 20), 0, (32 << 10));<br>+}<br>+<br>+void smm_info(uintptr_t *perm_smbase, size_t *perm_smsize,<br>+                         size_t *smm_save_state_size)<br>+{<br>+     device_t dev = SA_DEV_ROOT;<br>+<br>+       printk(BIOS_DEBUG, "Setting up SMI for CPU\n");<br>+<br>+ fill_in_relocation_params(dev, &smm_reloc_params);<br>+<br>+    if (smm_reloc_params.ied_size)<br>+               setup_ied_area(&smm_reloc_params);<br>+<br>+    *perm_smbase = smm_reloc_params.smram_base;<br>+  *perm_smsize = smm_reloc_params.smram_size;<br>+  *smm_save_state_size = sizeof(em64t101_smm_state_save_area_t);<br>+}<br>+<br>+void smm_initialize(void)<br>+{<br>+        /* Clear the SMM state in the southbridge. */<br>+        smm_southbridge_clear_state();<br>+<br>+    /*<br>+    * Run the relocation handler for on the BSP to check and set up<br>+      * parallel SMM relocation.<br>+   */<br>+  smm_initiate_relocation();<br>+<br>+        if (smm_reloc_params.smm_save_state_in_msrs)<br>+         printk(BIOS_DEBUG, "Doing parallel SMM relocation.\n");<br>+}<br>+<br>+void smm_relocate(void)<br>+{<br>+       /*<br>+    * If smm_save_state_in_msrs is non-zero then parallel SMM relocation<br>+         * shall take place. Run the relocation handler a second time on the<br>+  * BSP to do * the final move. For APs, a relocation handler always<br>+   * needs to be run.<br>+   */<br>+  if (smm_reloc_params.smm_save_state_in_msrs)<br>+         smm_initiate_relocation_parallel();<br>+  else if (!boot_cpu())<br>+                smm_initiate_relocation();<br>+}<br>+<br>+void smm_lock(void)<br>+{<br>+  /*<br>+    * LOCK the SMM memory window and enable normal SMM.<br>+  * After running this function, only a full reset can<br>+         * make the SMM registers writable again.<br>+     */<br>+  printk(BIOS_DEBUG, "Locking SMM.\n");<br>+      pci_write_config8(SA_DEV_ROOT, SMRAM, D_LCK | G_SMRAME | C_BASE_SEG);<br>+}<br>diff --git a/src/soc/intel/common/block/include/intelblocks/smihandler.h b/src/soc/intel/common/block/include/intelblocks/smihandler.h<br>index 389d241..5df5552 100644<br>--- a/src/soc/intel/common/block/include/intelblocks/smihandler.h<br>+++ b/src/soc/intel/common/block/include/intelblocks/smihandler.h<br>@@ -94,6 +94,21 @@<br> <br> /*<br>  * This function should be implemented in SOC specific code to handle<br>+ * MC event. The default functionality is provided in<br>+ * soc/intel/common/block/smm/smihandler.c<br>+ */<br>+void smihandler_southbridge_mc(<br>+      const struct smm_save_state_ops *save_state_ops);<br>+<br>+/*<br>+ * This function should be implemented in SOC specific code to handle<br>+ * minitor event. The default functionality is provided in<br>+ * soc/intel/common/block/smm/smihandler.c<br>+ */<br>+void smihandler_southbridge_monitor(<br>+     const struct smm_save_state_ops *save_state_ops);<br>+/*<br>+ * This function should be implemented in SOC specific code to handle<br>  * SMI_TCO event. The default functionality is provided in<br>  * soc/intel/common/block/smm/smihandler.c<br>  */<br>diff --git a/src/soc/intel/common/block/smm/smitraphandler.c b/src/soc/intel/common/block/smm/smitraphandler.c<br>index 4a51cde..bfa9846 100644<br>--- a/src/soc/intel/common/block/smm/smitraphandler.c<br>+++ b/src/soc/intel/common/block/smm/smitraphandler.c<br>@@ -75,6 +75,8 @@<br>        u32 data, mask = 0;<br>   u8 trap_sts;<br>  int i;<br>+       global_nvs_t *gnvs = smm_get_gnvs();<br>+<br>       /* TRSR - Trap Status Register */<br>     trap_sts = pcr_read8(PID_PSTH, PCR_PSTH_TRPST);<br>       /* Clear trap(s) in TRSR */<br></pre><p>To view, visit <a href="https://review.coreboot.org/21543">change 21543</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/21543"/><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: I9aab141c528709b30804d327804c4031c59fcfff </div>
<div style="display:none"> Gerrit-Change-Number: 21543 </div>
<div style="display:none"> Gerrit-PatchSet: 12 </div>
<div style="display:none"> Gerrit-Owner: Lijian Zhao <lijian.zhao@intel.com> </div>
<div style="display:none"> Gerrit-Reviewer: AndreX Andraos <andrex.andraos@intel.com> </div>
<div style="display:none"> Gerrit-Reviewer: Bora Guvendik <bora.guvendik@intel.com> </div>
<div style="display:none"> Gerrit-Reviewer: Brandon Breitenstein <brandon.breitenstein@intel.com> </div>
<div style="display:none"> Gerrit-Reviewer: Krzysztof M Sywula <krzysztof.m.sywula@intel.com> </div>
<div style="display:none"> Gerrit-Reviewer: Pratikkumar V Prajapati <pratikkumar.v.prajapati@intel.com> </div>
<div style="display:none"> Gerrit-Reviewer: Ravishankar Sarawadi <ravishankar.sarawadi@intel.com> </div>
<div style="display:none"> Gerrit-Reviewer: Subrata Banik <subrata.banik@intel.com> </div>
<div style="display:none"> Gerrit-Reviewer: build bot (Jenkins) <no-reply@coreboot.org> </div>