xref: /aosp_15_r20/external/coreboot/src/cpu/intel/model_2065x/model_2065x_init.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <assert.h>
4 #include <console/console.h>
5 #include <device/device.h>
6 #include <cpu/cpu.h>
7 #include <cpu/x86/mtrr.h>
8 #include <cpu/x86/msr.h>
9 #include <cpu/x86/lapic.h>
10 #include <cpu/x86/mp.h>
11 #include <cpu/intel/microcode.h>
12 #include <cpu/intel/speedstep.h>
13 #include <cpu/intel/turbo.h>
14 #include <cpu/x86/cache.h>
15 #include <cpu/x86/name.h>
16 #include "model_2065x.h"
17 #include "chip.h"
18 #include <cpu/intel/smm_reloc.h>
19 #include <cpu/intel/common/common.h>
20 #include <smp/node.h>
21 #include <types.h>
22 
configure_thermal_target(struct device * dev)23 static void configure_thermal_target(struct device *dev)
24 {
25 	struct cpu_intel_model_2065x_config *conf = dev->upstream->dev->chip_info;
26 	msr_t msr;
27 
28 	/* Set TCC activation offset if supported */
29 	msr = rdmsr(MSR_PLATFORM_INFO);
30 	if ((msr.lo & (1 << 30)) && conf->tcc_offset) {
31 		msr = rdmsr(MSR_TEMPERATURE_TARGET);
32 		msr.lo &= ~(0xf << 24); /* Bits 27:24 */
33 		msr.lo |= (conf->tcc_offset & 0xf) << 24;
34 		wrmsr(MSR_TEMPERATURE_TARGET, msr);
35 	}
36 }
37 
configure_misc(void)38 static void configure_misc(void)
39 {
40 	msr_t msr;
41 
42 	msr = rdmsr(IA32_MISC_ENABLE);
43 	msr.lo |= (1 << 0);	  /* Fast String enable */
44 	msr.lo |= (1 << 3);	  /* TM1/TM2/EMTTM enable */
45 	msr.lo |= (1 << 16);	  /* Enhanced SpeedStep Enable */
46 	wrmsr(IA32_MISC_ENABLE, msr);
47 
48 	/* Disable Thermal interrupts */
49 	msr.lo = 0;
50 	msr.hi = 0;
51 	wrmsr(IA32_THERM_INTERRUPT, msr);
52 }
53 
set_max_ratio(void)54 static void set_max_ratio(void)
55 {
56 	msr_t msr, perf_ctl;
57 
58 	perf_ctl.hi = 0;
59 
60 	/* Platform Info bits 15:8 give max ratio */
61 	msr = rdmsr(MSR_PLATFORM_INFO);
62 	perf_ctl.lo = msr.lo & 0xff00;
63 	wrmsr(IA32_PERF_CTL, perf_ctl);
64 
65 	printk(BIOS_DEBUG, "model_x065x: frequency set to %d\n",
66 	       ((perf_ctl.lo >> 8) & 0xff) * IRONLAKE_BCLK);
67 }
68 
model_2065x_init(struct device * cpu)69 static void model_2065x_init(struct device *cpu)
70 {
71 	char processor_name[49];
72 
73 	/* Clear out pending MCEs */
74 	/* This should only be done on a cold boot */
75 	mca_clear_status();
76 
77 	/* Print processor name */
78 	fill_processor_name(processor_name);
79 	printk(BIOS_INFO, "CPU: %s.\n", processor_name);
80 	printk(BIOS_INFO, "CPU:lapic=%d, boot_cpu=%d\n", lapicid(),
81 		boot_cpu());
82 
83 	/* Setup Page Attribute Tables (PAT) */
84 	// TODO set up PAT
85 
86 	enable_lapic_tpr();
87 
88 	/* Set virtualization based on Kconfig option */
89 	set_vmx_and_lock();
90 
91 	set_aesni_lock();
92 
93 	/* Configure Enhanced SpeedStep and Thermal Sensors */
94 	configure_misc();
95 
96 	/* Thermal throttle activation offset */
97 	configure_thermal_target(cpu);
98 
99 	/* Set Max Ratio */
100 	set_max_ratio();
101 
102 	/* Enable Turbo */
103 	enable_turbo();
104 }
105 
106 /* MP initialization support. */
pre_mp_init(void)107 static void pre_mp_init(void)
108 {
109 	/* Setup MTRRs based on physical address size. */
110 	x86_setup_mtrrs_with_detect();
111 	x86_mtrr_check();
112 }
113 
get_cpu_count(void)114 static int get_cpu_count(void)
115 {
116 	msr_t msr;
117 	unsigned int num_threads;
118 	unsigned int num_cores;
119 
120 	msr = rdmsr(MSR_CORE_THREAD_COUNT);
121 	num_threads = (msr.lo >> 0) & 0xffff;
122 	num_cores = (msr.lo >> 16) & 0xffff;
123 	printk(BIOS_DEBUG, "CPU has %u cores, %u threads enabled.\n",
124 	       num_cores, num_threads);
125 
126 	return num_threads;
127 }
128 
get_microcode_info(const void ** microcode,int * parallel)129 static void get_microcode_info(const void **microcode, int *parallel)
130 {
131 	*microcode = intel_microcode_find();
132 	*parallel = !intel_ht_supported();
133 }
134 
per_cpu_smm_trigger(void)135 static void per_cpu_smm_trigger(void)
136 {
137 	/* Relocate the SMM handler. */
138 	smm_relocate();
139 
140 	/* After SMM relocation a 2nd microcode load is required. */
141 	const void *microcode_patch = intel_microcode_find();
142 	intel_microcode_load_unlocked(microcode_patch);
143 }
144 
post_mp_init(void)145 static void post_mp_init(void)
146 {
147 	/* Now that all APs have been relocated as well as the BSP let SMIs
148 	 * start flowing. */
149 	global_smi_enable();
150 
151 	/* Lock down the SMRAM space. */
152 	smm_lock();
153 }
154 
155 static const struct mp_ops mp_ops = {
156 	.pre_mp_init = pre_mp_init,
157 	.get_cpu_count = get_cpu_count,
158 	.get_smm_info = smm_info,
159 	.get_microcode_info = get_microcode_info,
160 	.pre_mp_smm_init = smm_initialize,
161 	.per_cpu_smm_trigger = per_cpu_smm_trigger,
162 	.relocation_handler = smm_relocation_handler,
163 	.post_mp_init = post_mp_init,
164 };
165 
mp_init_cpus(struct bus * cpu_bus)166 void mp_init_cpus(struct bus *cpu_bus)
167 {
168 	/* TODO: Handle mp_init_with_smm failure? */
169 	mp_init_with_smm(cpu_bus, &mp_ops);
170 }
171 
172 static struct device_operations cpu_dev_ops = {
173 	.init     = model_2065x_init,
174 };
175 
176 /* Arrandale / Clarkdale CPU IDs */
177 static const struct cpu_device_id cpu_table[] = {
178 	{ X86_VENDOR_INTEL, 0x20650, CPUID_EXACT_MATCH_MASK },
179 	{ X86_VENDOR_INTEL, 0x20651, CPUID_EXACT_MATCH_MASK },
180 	{ X86_VENDOR_INTEL, 0x20652, CPUID_EXACT_MATCH_MASK },
181 	{ X86_VENDOR_INTEL, 0x20654, CPUID_EXACT_MATCH_MASK },
182 	{ X86_VENDOR_INTEL, 0x20655, CPUID_EXACT_MATCH_MASK },
183 	CPU_TABLE_END
184 };
185 
186 static const struct cpu_driver driver __cpu_driver = {
187 	.ops      = &cpu_dev_ops,
188 	.id_table = cpu_table,
189 };
190