From d9c84ca7ef0142df99c01832fe8683faec257436 Mon Sep 17 00:00:00 2001 From: Hannah Williams Date: Fri, 13 May 2016 00:47:14 -0700 Subject: soc/apollolake: SOC specific SMM code Add SMI handlers that map to SOC specific SMI events Update relocation_handler in mp_ops Change-Id: Idefddaf41cf28240f5f8172b00462a7f893889e7 Signed-off-by: Hannah Williams Reviewed-on: https://review.coreboot.org/14808 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin --- src/soc/intel/apollolake/cpu.c | 53 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'src/soc/intel/apollolake/cpu.c') diff --git a/src/soc/intel/apollolake/cpu.c b/src/soc/intel/apollolake/cpu.c index 99cb5adb89..4f74def886 100644 --- a/src/soc/intel/apollolake/cpu.c +++ b/src/soc/intel/apollolake/cpu.c @@ -25,6 +25,7 @@ #include #include #include +#include static struct device_operations cpu_dev_ops = { .init = DEVICE_NOOP, @@ -41,6 +42,18 @@ static const struct cpu_driver driver __cpu_driver = { .id_table = cpu_table, }; + +/* + * 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; + static void read_cpu_topology(unsigned int *num_phys, unsigned int *num_virt) { msr_t msr; @@ -75,6 +88,42 @@ static int get_cpu_count(void) return num_virt_cores; } +static void get_smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, + size_t *smm_save_state_size) +{ + void *smm_base; + size_t smm_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); + relo_attrs.smbase = (uint32_t)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 = relo_attrs.smbase; + *perm_smsize = smm_size - CONFIG_SMM_RESERVED_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(SMRR_PHYS_BASE, smrr); + smrr.lo = relo_attrs.smrr_mask; + smrr.hi = 0; + wrmsr(SMRR_PHYS_MASK, smrr); + smm_state = (void *)(SMM_EM64T100_SAVE_STATE_OFFSET + curr_smbase); + smm_state->smbase = staggered_smbase; +} /* * CPU initialization recipe * @@ -85,6 +134,10 @@ static int get_cpu_count(void) static const 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 = southbridge_smm_clear_state, + .relocation_handler = relocation_handler, + .post_mp_init = southbridge_smm_enable_smi, }; void apollolake_init_cpus(device_t dev) -- cgit v1.2.3