<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>