Kyösti Mälkki has uploaded this change for review.

View Change

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");
}

To view, visit change 34841. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I739940f9de97ad0392f9e7765d038ef6bf97b818
Gerrit-Change-Number: 34841
Gerrit-PatchSet: 1
Gerrit-Owner: Kyösti Mälkki <kyosti.malkki@gmail.com>
Gerrit-MessageType: newchange