Kyösti Mälkki has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/34841 )
Change subject: soc/intel: Refactor em64t100 SMI handlers ......................................................................
soc/intel: Refactor em64t100 SMI handlers
Change-Id: I739940f9de97ad0392f9e7765d038ef6bf97b818 Signed-off-by: Kyösti Mälkki kyosti.malkki@gmail.com --- M src/cpu/intel/smm/Makefile.inc A src/cpu/intel/smm/em64t100.c M src/cpu/intel/smm/smm_reloc.c M src/include/cpu/intel/em64t100_save_state.h M src/include/cpu/intel/smm_reloc.h M src/soc/intel/apollolake/cpu.c M src/soc/intel/baytrail/cpu.c M src/soc/intel/braswell/cpu.c M src/soc/intel/denverton_ns/cpu.c M src/soc/intel/denverton_ns/include/soc/smm.h M src/soc/intel/fsp_baytrail/cpu.c 11 files changed, 101 insertions(+), 248 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/41/34841/1
diff --git a/src/cpu/intel/smm/Makefile.inc b/src/cpu/intel/smm/Makefile.inc index a49b796..97fedc9 100644 --- a/src/cpu/intel/smm/Makefile.inc +++ b/src/cpu/intel/smm/Makefile.inc @@ -1 +1,2 @@ ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smm_reloc.c +ramstage-$(CONFIG_HAVE_SMI_HANDLER) += em64t100.c diff --git a/src/cpu/intel/smm/em64t100.c b/src/cpu/intel/smm/em64t100.c new file mode 100644 index 0000000..dcd0c0e --- /dev/null +++ b/src/cpu/intel/smm/em64t100.c @@ -0,0 +1,53 @@ +/* + * This file is part of the coreboot project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <types.h> +#include <cpu/x86/msr.h> +#include <cpu/x86/mp.h> +#include <cpu/intel/em64t100_save_state.h> +#include <cpu/intel/smm_reloc.h> + +static void std_smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, + size_t *smm_save_state_size) +{ + fill_in_smrr(&smm_reloc_params); + + smm_subregion(SMM_SUBREGION_HANDLER, perm_smbase, perm_smsize); + *smm_save_state_size = sizeof(em64t100_smm_state_save_area_t); +} + +static void std_relocation_handler(int cpu, uintptr_t curr_smbase, + uintptr_t staggered_smbase) +{ + struct smm_relocation_params *relo_params = &smm_reloc_params; + em64t100_smm_state_save_area_t *smm_state; + + printk(BIOS_DEBUG, "In relocation handler: cpu %d SMBASE=0x%08x\n", cpu, + (u32)staggered_smbase); + + /* Make appropriate changes to the save state map. */ + smm_state = (void *)(SMM_EM64T100_SAVE_STATE_OFFSET + curr_smbase); + smm_state->smbase = staggered_smbase; + + printk(BIOS_DEBUG, "Writing SMRR. base = 0x%08x, mask=0x%08x\n", + relo_params->smrr_base.lo, relo_params->smrr_mask.lo); + + wrmsr(IA32_SMRR_PHYS_BASE, relo_params->smrr_base); + wrmsr(IA32_SMRR_PHYS_MASK, relo_params->smrr_mask); +} + +void select_mp_ops_em64t100(struct mp_ops *mp_ops) +{ + mp_ops->get_smm_info = std_smm_info; + mp_ops->relocation_handler = std_relocation_handler; +} diff --git a/src/cpu/intel/smm/smm_reloc.c b/src/cpu/intel/smm/smm_reloc.c index 860c095..78222c0 100644 --- a/src/cpu/intel/smm/smm_reloc.c +++ b/src/cpu/intel/smm/smm_reloc.c @@ -11,6 +11,27 @@ * GNU General Public License for more details. */
+#include <types.h> +#include <cpu/x86/msr.h> +#include <cpu/x86/mtrr.h> +#include <cpu/x86/smm.h> #include <cpu/intel/smm_reloc.h>
struct smm_relocation_params smm_reloc_params; + +void fill_in_smrr(struct smm_relocation_params *params) +{ + uintptr_t tseg_base; + size_t tseg_size; + + /* All range registers are aligned to 4KiB */ + const u32 rmask = ~((4 * KiB) - 1); + + smm_region(&tseg_base, &tseg_size); + + /* SMRR has 32-bits of valid address aligned to 4KiB. */ + params->smrr_base.lo = (tseg_base & rmask) | MTRR_TYPE_WRBACK; + params->smrr_base.hi = 0; + params->smrr_mask.lo = (~(tseg_size - 1) & rmask) | MTRR_PHYS_MASK_VALID; + params->smrr_mask.hi = 0; +} diff --git a/src/include/cpu/intel/em64t100_save_state.h b/src/include/cpu/intel/em64t100_save_state.h index f76fa4b..f0bdd32 100644 --- a/src/include/cpu/intel/em64t100_save_state.h +++ b/src/include/cpu/intel/em64t100_save_state.h @@ -103,4 +103,7 @@ u64 cr0; } __packed em64t100_smm_state_save_area_t;
+struct mp_ops; +void select_mp_ops_em64t100(struct mp_ops *mp_ops); + #endif diff --git a/src/include/cpu/intel/smm_reloc.h b/src/include/cpu/intel/smm_reloc.h index 9b6473b..cbcdb56 100644 --- a/src/include/cpu/intel/smm_reloc.h +++ b/src/include/cpu/intel/smm_reloc.h @@ -37,6 +37,8 @@
extern struct smm_relocation_params smm_reloc_params;
+void fill_in_smrr(struct smm_relocation_params *params); + #define MSR_PRMRR_PHYS_BASE 0x1f4 #define MSR_PRMRR_PHYS_MASK 0x1f5 #define MSR_UNCORE_PRMRR_PHYS_BASE 0x2f4 diff --git a/src/soc/intel/apollolake/cpu.c b/src/soc/intel/apollolake/cpu.c index e834142..834896e 100644 --- a/src/soc/intel/apollolake/cpu.c +++ b/src/soc/intel/apollolake/cpu.c @@ -134,13 +134,6 @@ /* * MP and SMM loading initialization. */ -struct smm_relocation_attrs { - uint32_t smbase; - uint32_t smrr_base; - uint32_t smrr_mask; -}; - -static struct smm_relocation_attrs relo_attrs;
/* * Do essential initialization tasks before APs can be fired up. @@ -204,46 +197,6 @@ } #endif
-static void get_smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, - size_t *smm_save_state_size) -{ - uintptr_t smm_base; - size_t smm_size; - uintptr_t handler_base; - size_t handler_size; - - /* All range registers are aligned to 4KiB */ - const uint32_t rmask = ~((1 << 12) - 1); - - /* Initialize global tracking state. */ - smm_region(&smm_base, &smm_size); - smm_subregion(SMM_SUBREGION_HANDLER, &handler_base, &handler_size); - - relo_attrs.smbase = smm_base; - relo_attrs.smrr_base = relo_attrs.smbase | MTRR_TYPE_WRBACK; - relo_attrs.smrr_mask = ~(smm_size - 1) & rmask; - relo_attrs.smrr_mask |= MTRR_PHYS_MASK_VALID; - - *perm_smbase = handler_base; - *perm_smsize = handler_size; - *smm_save_state_size = sizeof(em64t100_smm_state_save_area_t); -} - -static void relocation_handler(int cpu, uintptr_t curr_smbase, - uintptr_t staggered_smbase) -{ - msr_t smrr; - em64t100_smm_state_save_area_t *smm_state; - /* Set up SMRR. */ - smrr.lo = relo_attrs.smrr_base; - smrr.hi = 0; - wrmsr(IA32_SMRR_PHYS_BASE, smrr); - smrr.lo = relo_attrs.smrr_mask; - smrr.hi = 0; - wrmsr(IA32_SMRR_PHYS_MASK, smrr); - smm_state = (void *)(SMM_EM64T100_SAVE_STATE_OFFSET + curr_smbase); - smm_state->smbase = staggered_smbase; -} /* * CPU initialization recipe * @@ -260,18 +213,19 @@ mp_run_on_all_cpus(sgx_configure, NULL, 2000); }
-static const struct mp_ops mp_ops = { +static struct mp_ops mp_ops = { .pre_mp_init = pre_mp_init, .get_cpu_count = get_cpu_count, - .get_smm_info = get_smm_info, .get_microcode_info = get_microcode_info, .pre_mp_smm_init = smm_southbridge_clear_state, - .relocation_handler = relocation_handler, .post_mp_init = post_mp_init, };
void soc_init_cpus(struct bus *cpu_bus) { + if (CONFIG(HAVE_SMI_HANDLER)) + select_mp_ops_em64t100(&mp_ops); + /* Clear for take-off */ if (mp_init_with_smm(cpu_bus, &mp_ops)) printk(BIOS_ERR, "MP initialization failure.\n"); diff --git a/src/soc/intel/baytrail/cpu.c b/src/soc/intel/baytrail/cpu.c index 0f6969c..7f3e00d 100644 --- a/src/soc/intel/baytrail/cpu.c +++ b/src/soc/intel/baytrail/cpu.c @@ -83,7 +83,6 @@ .id_table = cpu_table, };
- /* * MP and SMM loading initialization. */ @@ -132,35 +131,6 @@ return pattrs->num_cpus; }
-static void fill_in_relocation_params(struct smm_relocation_params *params) -{ - uintptr_t tseg_base; - size_t tseg_size; - - /* All range registers are aligned to 4KiB */ - const u32 rmask = ~((1 << 12) - 1); - - smm_region(&tseg_base, &tseg_size); - - /* SMRR has 32-bits of valid address aligned to 4KiB. */ - params->smrr_base.lo = (tseg_base & rmask) | MTRR_TYPE_WRBACK; - params->smrr_base.hi = 0; - params->smrr_mask.lo = (~(tseg_size - 1) & rmask) | MTRR_PHYS_MASK_VALID; - params->smrr_mask.hi = 0; -} - -static void get_smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, - size_t *smm_save_state_size) -{ - printk(BIOS_DEBUG, "Setting up SMI for CPU\n"); - - fill_in_relocation_params(&smm_reloc_params); - - smm_subregion(SMM_SUBREGION_HANDLER, perm_smbase, perm_smsize); - - *smm_save_state_size = sizeof(em64t100_smm_state_save_area_t); -} - static void get_microcode_info(const void **microcode, int *parallel) { const struct pattrs *pattrs = pattrs_get(); @@ -180,28 +150,12 @@ intel_microcode_load_unlocked(pattrs->microcode_patch); }
-static void relocation_handler(int cpu, uintptr_t curr_smbase, - uintptr_t staggered_smbase) -{ - struct smm_relocation_params *relo_params = &smm_reloc_params; - em64t100_smm_state_save_area_t *smm_state; - - /* Set up SMRR. */ - wrmsr(IA32_SMRR_PHYS_BASE, relo_params->smrr_base); - wrmsr(IA32_SMRR_PHYS_MASK, relo_params->smrr_mask); - - smm_state = (void *)(SMM_EM64T100_SAVE_STATE_OFFSET + curr_smbase); - smm_state->smbase = staggered_smbase; -} - -static const struct mp_ops mp_ops = { +static struct mp_ops mp_ops = { .pre_mp_init = pre_mp_init, .get_cpu_count = get_cpu_count, - .get_smm_info = get_smm_info, .get_microcode_info = get_microcode_info, .pre_mp_smm_init = southcluster_smm_clear_state, .per_cpu_smm_trigger = per_cpu_smm_trigger, - .relocation_handler = relocation_handler, .post_mp_init = southcluster_smm_enable_smi, };
@@ -209,6 +163,9 @@ { struct bus *cpu_bus = dev->link_list;
+ if (CONFIG(HAVE_SMI_HANDLER)) + select_mp_ops_em64t100(&mp_ops); + if (mp_init_with_smm(cpu_bus, &mp_ops)) { printk(BIOS_ERR, "MP initialization failure.\n"); } diff --git a/src/soc/intel/braswell/cpu.c b/src/soc/intel/braswell/cpu.c index abf6a99..75bc45f 100644 --- a/src/soc/intel/braswell/cpu.c +++ b/src/soc/intel/braswell/cpu.c @@ -91,7 +91,6 @@ .id_table = cpu_table, };
- /* * MP and SMM loading initialization. */ @@ -140,35 +139,6 @@ return pattrs->num_cpus; }
-static void fill_in_relocation_params(struct smm_relocation_params *params) -{ - uintptr_t tseg_base; - size_t tseg_size; - - /* All range registers are aligned to 4KiB */ - const u32 rmask = ~((1 << 12) - 1); - - smm_region(&tseg_base, &tseg_size); - - /* SMRR has 32-bits of valid address aligned to 4KiB. */ - params->smrr_base.lo = (tseg_base & rmask) | MTRR_TYPE_WRBACK; - params->smrr_base.hi = 0; - params->smrr_mask.lo = (~(tseg_size - 1) & rmask) | MTRR_PHYS_MASK_VALID; - params->smrr_mask.hi = 0; -} - -static void get_smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, - size_t *smm_save_state_size) -{ - printk(BIOS_DEBUG, "Setting up SMI for CPU\n"); - - fill_in_relocation_params(&smm_reloc_params); - - smm_subregion(SMM_SUBREGION_HANDLER, perm_smbase, perm_smsize); - - *smm_save_state_size = sizeof(em64t100_smm_state_save_area_t); -} - static void get_microcode_info(const void **microcode, int *parallel) { const struct pattrs *pattrs = pattrs_get(); @@ -194,28 +164,12 @@ intel_microcode_load_unlocked(pattrs->microcode_patch); }
-static void relocation_handler(int cpu, uintptr_t curr_smbase, - uintptr_t staggered_smbase) -{ - struct smm_relocation_params *relo_params = &smm_reloc_params; - em64t100_smm_state_save_area_t *smm_state; - - /* Set up SMRR. */ - wrmsr(IA32_SMRR_PHYS_BASE, relo_params->smrr_base); - wrmsr(IA32_SMRR_PHYS_MASK, relo_params->smrr_mask); - - smm_state = (void *)(SMM_EM64T100_SAVE_STATE_OFFSET + curr_smbase); - smm_state->smbase = staggered_smbase; -} - -static const struct mp_ops mp_ops = { +static struct mp_ops mp_ops = { .pre_mp_init = pre_mp_init, .get_cpu_count = get_cpu_count, - .get_smm_info = get_smm_info, .get_microcode_info = get_microcode_info, .pre_mp_smm_init = southcluster_smm_clear_state, .per_cpu_smm_trigger = per_cpu_smm_trigger, - .relocation_handler = relocation_handler, .post_mp_init = southcluster_smm_enable_smi, };
@@ -226,6 +180,9 @@ printk(BIOS_SPEW, "%s/%s (%s)\n", __FILE__, __func__, dev_name(dev));
+ if (CONFIG(HAVE_SMI_HANDLER)) + select_mp_ops_em64t100(&mp_ops); + if (mp_init_with_smm(cpu_bus, &mp_ops)) printk(BIOS_ERR, "MP initialization failure.\n"); } diff --git a/src/soc/intel/denverton_ns/cpu.c b/src/soc/intel/denverton_ns/cpu.c index bda6d1d..684b0d7 100644 --- a/src/soc/intel/denverton_ns/cpu.c +++ b/src/soc/intel/denverton_ns/cpu.c @@ -35,8 +35,6 @@ #include <soc/smm.h> #include <soc/soc_util.h>
-static struct smm_relocation_attrs relo_attrs; - static void dnv_configure_mca(void) { msr_t msr; @@ -102,53 +100,6 @@ .id_table = cpu_table, };
-/* - * MP and SMM loading initialization. - */ - -static void relocation_handler(int cpu, uintptr_t curr_smbase, - uintptr_t staggered_smbase) -{ - msr_t smrr; - em64t100_smm_state_save_area_t *smm_state; - (void)cpu; - - /* Set up SMRR. */ - smrr.lo = relo_attrs.smrr_base; - smrr.hi = 0; - wrmsr(IA32_SMRR_PHYS_BASE, smrr); - smrr.lo = relo_attrs.smrr_mask; - smrr.hi = 0; - wrmsr(IA32_SMRR_PHYS_MASK, smrr); - smm_state = (void *)(SMM_EM64T100_SAVE_STATE_OFFSET + curr_smbase); - smm_state->smbase = staggered_smbase; -} - -static void get_smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, - size_t *smm_save_state_size) -{ - uintptr_t smm_base; - size_t smm_size; - uintptr_t handler_base; - size_t handler_size; - - /* All range registers are aligned to 4KiB */ - const uint32_t rmask = ~((1 << 12) - 1); - - /* Initialize global tracking state. */ - smm_region(&smm_base, &smm_size); - smm_subregion(SMM_SUBREGION_HANDLER, &handler_base, &handler_size); - - relo_attrs.smbase = smm_base; - relo_attrs.smrr_base = relo_attrs.smbase | MTRR_TYPE_WRBACK; - relo_attrs.smrr_mask = ~(smm_size - 1) & rmask; - relo_attrs.smrr_mask |= MTRR_PHYS_MASK_VALID; - - *perm_smbase = handler_base; - *perm_smsize = handler_size; - *smm_save_state_size = sizeof(em64t100_smm_state_save_area_t); -} - static int detect_num_cpus_via_cpuid(void) { register int ecx = 0; @@ -232,6 +183,7 @@ ((perf_ctl.lo >> 8) & 0xff) * CPU_BCLK); }
+ /* * Do essential initialization tasks before APs can be fired up * @@ -264,17 +216,18 @@ * the microcode on all cores before releasing them from reset. That means that * the BSP and all APs will come up with the same microcode revision. */ -static const struct mp_ops mp_ops = { +static struct mp_ops mp_ops = { .pre_mp_init = pre_mp_init, .get_cpu_count = get_cpu_count, - .get_smm_info = get_smm_info, .pre_mp_smm_init = southcluster_smm_clear_state, - .relocation_handler = relocation_handler, .post_mp_init = post_mp_init, };
void denverton_init_cpus(struct device *dev) { + if (CONFIG(HAVE_SMI_HANDLER)) + select_mp_ops_em64t100(&mp_ops); + /* Clear for take-off */ if (mp_init_with_smm(dev->link_list, &mp_ops) < 0) printk(BIOS_ERR, "MP initialization failure.\n"); diff --git a/src/soc/intel/denverton_ns/include/soc/smm.h b/src/soc/intel/denverton_ns/include/soc/smm.h index a020891..9de020b 100644 --- a/src/soc/intel/denverton_ns/include/soc/smm.h +++ b/src/soc/intel/denverton_ns/include/soc/smm.h @@ -18,12 +18,6 @@ #ifndef _DENVERTON_NS_SMM_H_ #define _DENVERTON_NS_SMM_H_
-struct smm_relocation_attrs { - uint32_t smbase; - uint32_t smrr_base; - uint32_t smrr_mask; -}; - #if !defined(__PRE_RAM__) && !defined(__SMM___) #include <stdint.h> void southcluster_smm_clear_state(void); diff --git a/src/soc/intel/fsp_baytrail/cpu.c b/src/soc/intel/fsp_baytrail/cpu.c index 8f925e8..8eb71c6 100644 --- a/src/soc/intel/fsp_baytrail/cpu.c +++ b/src/soc/intel/fsp_baytrail/cpu.c @@ -98,35 +98,6 @@ return pattrs->num_cpus; }
-static void fill_in_relocation_params(struct smm_relocation_params *params) -{ - uintptr_t tseg_base; - size_t tseg_size; - - /* All range registers are aligned to 4KiB */ - const u32 rmask = ~(4 * KiB - 1); - - smm_region(&tseg_base, &tseg_size); - - /* SMRR has 32-bits of valid address aligned to 4KiB. */ - params->smrr_base.lo = (tseg_base & rmask) | MTRR_TYPE_WRBACK; - params->smrr_base.hi = 0; - params->smrr_mask.lo = (~(tseg_size - 1) & rmask) | MTRR_PHYS_MASK_VALID; - params->smrr_mask.hi = 0; -} - -static void get_smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, - size_t *smm_save_state_size) -{ - printk(BIOS_DEBUG, "Setting up SMI for CPU\n"); - - fill_in_relocation_params(&smm_reloc_params); - - smm_subregion(SMM_SUBREGION_HANDLER, perm_smbase, perm_smsize); - - *smm_save_state_size = sizeof(em64t100_smm_state_save_area_t); -} - static void get_microcode_info(const void **microcode, int *parallel) { const struct pattrs *pattrs = pattrs_get(); @@ -135,33 +106,17 @@ *parallel = 1; }
-static void relocation_handler(int cpu, uintptr_t curr_smbase, - uintptr_t staggered_smbase) -{ - struct smm_relocation_params *relo_params = &smm_reloc_params; - em64t100_smm_state_save_area_t *smm_state; - - /* Set up SMRR. */ - wrmsr(IA32_SMRR_PHYS_BASE, relo_params->smrr_base); - wrmsr(IA32_SMRR_PHYS_MASK, relo_params->smrr_mask); - - smm_state = (void *)(SMM_EM64T100_SAVE_STATE_OFFSET + curr_smbase); - smm_state->smbase = staggered_smbase; -} - static void enable_smis(void) { if (CONFIG(HAVE_SMI_HANDLER)) southcluster_smm_enable_smi(); }
-static const struct mp_ops mp_ops = { +static struct mp_ops mp_ops = { .pre_mp_init = pre_mp_init, .get_cpu_count = get_cpu_count, - .get_smm_info = get_smm_info, .get_microcode_info = get_microcode_info, .pre_mp_smm_init = southcluster_smm_clear_state, - .relocation_handler = relocation_handler, .post_mp_init = enable_smis, };
@@ -169,6 +124,9 @@ { struct bus *cpu_bus = dev->link_list;
+ if (CONFIG(HAVE_SMI_HANDLER)) + select_mp_ops_em64t100(&mp_ops); + if (mp_init_with_smm(cpu_bus, &mp_ops)) { printk(BIOS_ERR, "MP initialization failure.\n"); }