1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
4 #include <cpu/intel/microcode.h>
5 #include <cpu/intel/smm_reloc.h>
6 #include <cpu/intel/common/common.h>
7 #include <cpu/x86/legacy_save_state.h>
8 #include <cpu/x86/mtrr.h>
9 #include <cpu/x86/mp.h>
10 #include <device/device.h>
11 #include <device/pci_ops.h>
14 /* Parallel MP initialization support. */
15 static void pre_mp_init(void)
17 const void *patch
= intel_microcode_find();
18 intel_microcode_load_unlocked(patch
);
20 /* Setup MTRRs based on physical address size. */
21 x86_setup_mtrrs_with_detect();
25 static int get_cpu_count(void)
27 return CONFIG_MAX_CPUS
;
30 static void get_microcode_info(const void **microcode
, int *parallel
)
32 *microcode
= intel_microcode_find();
33 *parallel
= !intel_ht_supported();
36 static void pre_mp_smm_init(void)
38 /* Clear the SMM state in the southbridge. */
39 smm_southbridge_clear_state();
42 * Run the relocation handler for on the BSP to check and set up
43 * parallel SMM relocation.
45 smm_initiate_relocation();
48 static void get_smm_info(uintptr_t *perm_smbase
, size_t *perm_smsize
,
49 size_t *smm_save_state_size
)
51 printk(BIOS_DEBUG
, "Setting up SMI for CPU\n");
55 smm_subregion(SMM_SUBREGION_HANDLER
, perm_smbase
, perm_smsize
);
57 *smm_save_state_size
= sizeof(legacy_smm_state_save_area_t
);
58 printk(BIOS_DEBUG
, "Save state size: 0x%zx bytes\n", *smm_save_state_size
);
62 * The relocation work is actually performed in SMM context, but the code
63 * resides in the ramstage module. This occurs by trampolining from the default
64 * SMRAM entry point to here.
66 static void relocation_handler(int cpu
, uintptr_t curr_smbase
, uintptr_t staggered_smbase
)
68 legacy_smm_state_save_area_t
*save_state
;
69 u32 smbase
= staggered_smbase
;
71 save_state
= (void *)(curr_smbase
+ SMM_DEFAULT_SIZE
- sizeof(*save_state
));
72 save_state
->smbase
= smbase
;
74 printk(BIOS_DEBUG
, "In relocation handler: cpu %d\n", cpu
);
75 printk(BIOS_DEBUG
, "SMM revision: 0x%08x\n", save_state
->smm_revision
);
76 printk(BIOS_DEBUG
, "New SMBASE=0x%08x\n", smbase
);
79 static void post_mp_init(void)
83 /* Now that all APs have been relocated as well as the BSP let SMIs start flowing. */
86 /* Lock down the SMRAM space. */
90 static const struct mp_ops mp_ops
= {
91 .pre_mp_init
= pre_mp_init
,
92 .get_cpu_count
= get_cpu_count
,
93 .get_smm_info
= get_smm_info
,
94 .get_microcode_info
= get_microcode_info
,
95 .pre_mp_smm_init
= pre_mp_smm_init
,
96 /* .per_cpu_smm_trigger = smm_initiate_relocation, using default */
97 .relocation_handler
= relocation_handler
,
98 .post_mp_init
= post_mp_init
,
101 void mp_init_cpus(struct bus
*cpu_bus
)
103 /* TODO: Handle mp_init_with_smm failure? */
104 mp_init_with_smm(cpu_bus
, &mp_ops
);