Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0+
2 : /*
3 : * Hygon Processor Support for Linux
4 : *
5 : * Copyright (C) 2018 Chengdu Haiguang IC Design Co., Ltd.
6 : *
7 : * Author: Pu Wen <puwen@hygon.cn>
8 : */
9 : #include <linux/io.h>
10 :
11 : #include <asm/cpu.h>
12 : #include <asm/smp.h>
13 : #include <asm/numa.h>
14 : #include <asm/cacheinfo.h>
15 : #include <asm/spec-ctrl.h>
16 : #include <asm/delay.h>
17 :
18 : #include "cpu.h"
19 :
20 : #define APICID_SOCKET_ID_BIT 6
21 :
22 : /*
23 : * nodes_per_socket: Stores the number of nodes per socket.
24 : * Refer to CPUID Fn8000_001E_ECX Node Identifiers[10:8]
25 : */
26 : static u32 nodes_per_socket = 1;
27 :
28 : #ifdef CONFIG_NUMA
29 : /*
30 : * To workaround broken NUMA config. Read the comment in
31 : * srat_detect_node().
32 : */
33 0 : static int nearby_node(int apicid)
34 : {
35 0 : int i, node;
36 :
37 0 : for (i = apicid - 1; i >= 0; i--) {
38 0 : node = __apicid_to_node[i];
39 0 : if (node != NUMA_NO_NODE && node_online(node))
40 0 : return node;
41 : }
42 0 : for (i = apicid + 1; i < MAX_LOCAL_APIC; i++) {
43 0 : node = __apicid_to_node[i];
44 0 : if (node != NUMA_NO_NODE && node_online(node))
45 0 : return node;
46 : }
47 0 : return first_node(node_online_map); /* Shouldn't happen */
48 : }
49 : #endif
50 :
51 0 : static void hygon_get_topology_early(struct cpuinfo_x86 *c)
52 : {
53 0 : if (cpu_has(c, X86_FEATURE_TOPOEXT))
54 0 : smp_num_siblings = ((cpuid_ebx(0x8000001e) >> 8) & 0xff) + 1;
55 0 : }
56 :
57 : /*
58 : * Fixup core topology information for
59 : * (1) Hygon multi-node processors
60 : * Assumption: Number of cores in each internal node is the same.
61 : * (2) Hygon processors supporting compute units
62 : */
63 0 : static void hygon_get_topology(struct cpuinfo_x86 *c)
64 : {
65 0 : int cpu = smp_processor_id();
66 :
67 : /* get information required for multi-node processors */
68 0 : if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
69 0 : int err;
70 0 : u32 eax, ebx, ecx, edx;
71 :
72 0 : cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
73 :
74 0 : c->cpu_die_id = ecx & 0xff;
75 :
76 0 : c->cpu_core_id = ebx & 0xff;
77 :
78 0 : if (smp_num_siblings > 1)
79 0 : c->x86_max_cores /= smp_num_siblings;
80 :
81 : /*
82 : * In case leaf B is available, use it to derive
83 : * topology information.
84 : */
85 0 : err = detect_extended_topology(c);
86 0 : if (!err)
87 0 : c->x86_coreid_bits = get_count_order(c->x86_max_cores);
88 :
89 : /* Socket ID is ApicId[6] for these processors. */
90 0 : c->phys_proc_id = c->apicid >> APICID_SOCKET_ID_BIT;
91 :
92 0 : cacheinfo_hygon_init_llc_id(c, cpu);
93 0 : } else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
94 0 : u64 value;
95 :
96 0 : rdmsrl(MSR_FAM10H_NODE_ID, value);
97 0 : c->cpu_die_id = value & 7;
98 :
99 0 : per_cpu(cpu_llc_id, cpu) = c->cpu_die_id;
100 : } else
101 : return;
102 :
103 0 : if (nodes_per_socket > 1)
104 0 : set_cpu_cap(c, X86_FEATURE_AMD_DCM);
105 : }
106 :
107 : /*
108 : * On Hygon setup the lower bits of the APIC id distinguish the cores.
109 : * Assumes number of cores is a power of two.
110 : */
111 0 : static void hygon_detect_cmp(struct cpuinfo_x86 *c)
112 : {
113 0 : unsigned int bits;
114 0 : int cpu = smp_processor_id();
115 :
116 0 : bits = c->x86_coreid_bits;
117 : /* Low order bits define the core id (index of core in socket) */
118 0 : c->cpu_core_id = c->initial_apicid & ((1 << bits)-1);
119 : /* Convert the initial APIC ID into the socket ID */
120 0 : c->phys_proc_id = c->initial_apicid >> bits;
121 : /* use socket ID also for last level cache */
122 0 : per_cpu(cpu_llc_id, cpu) = c->cpu_die_id = c->phys_proc_id;
123 0 : }
124 :
125 0 : static void srat_detect_node(struct cpuinfo_x86 *c)
126 : {
127 : #ifdef CONFIG_NUMA
128 0 : int cpu = smp_processor_id();
129 0 : int node;
130 0 : unsigned int apicid = c->apicid;
131 :
132 0 : node = numa_cpu_node(cpu);
133 0 : if (node == NUMA_NO_NODE)
134 0 : node = per_cpu(cpu_llc_id, cpu);
135 :
136 : /*
137 : * On multi-fabric platform (e.g. Numascale NumaChip) a
138 : * platform-specific handler needs to be called to fixup some
139 : * IDs of the CPU.
140 : */
141 0 : if (x86_cpuinit.fixup_cpu_id)
142 0 : x86_cpuinit.fixup_cpu_id(c, node);
143 :
144 0 : if (!node_online(node)) {
145 : /*
146 : * Two possibilities here:
147 : *
148 : * - The CPU is missing memory and no node was created. In
149 : * that case try picking one from a nearby CPU.
150 : *
151 : * - The APIC IDs differ from the HyperTransport node IDs.
152 : * Assume they are all increased by a constant offset, but
153 : * in the same order as the HT nodeids. If that doesn't
154 : * result in a usable node fall back to the path for the
155 : * previous case.
156 : *
157 : * This workaround operates directly on the mapping between
158 : * APIC ID and NUMA node, assuming certain relationship
159 : * between APIC ID, HT node ID and NUMA topology. As going
160 : * through CPU mapping may alter the outcome, directly
161 : * access __apicid_to_node[].
162 : */
163 0 : int ht_nodeid = c->initial_apicid;
164 :
165 0 : if (__apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
166 0 : node = __apicid_to_node[ht_nodeid];
167 : /* Pick a nearby node */
168 0 : if (!node_online(node))
169 0 : node = nearby_node(apicid);
170 : }
171 0 : numa_set_node(cpu, node);
172 : #endif
173 0 : }
174 :
175 0 : static void early_init_hygon_mc(struct cpuinfo_x86 *c)
176 : {
177 : #ifdef CONFIG_SMP
178 0 : unsigned int bits, ecx;
179 :
180 : /* Multi core CPU? */
181 0 : if (c->extended_cpuid_level < 0x80000008)
182 : return;
183 :
184 0 : ecx = cpuid_ecx(0x80000008);
185 :
186 0 : c->x86_max_cores = (ecx & 0xff) + 1;
187 :
188 : /* CPU telling us the core id bits shift? */
189 0 : bits = (ecx >> 12) & 0xF;
190 :
191 : /* Otherwise recompute */
192 0 : if (bits == 0) {
193 0 : while ((1 << bits) < c->x86_max_cores)
194 0 : bits++;
195 : }
196 :
197 0 : c->x86_coreid_bits = bits;
198 : #endif
199 : }
200 :
201 0 : static void bsp_init_hygon(struct cpuinfo_x86 *c)
202 : {
203 0 : if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) {
204 0 : u64 val;
205 :
206 0 : rdmsrl(MSR_K7_HWCR, val);
207 0 : if (!(val & BIT(24)))
208 0 : pr_warn(FW_BUG "TSC doesn't count with P0 frequency!\n");
209 : }
210 :
211 0 : if (cpu_has(c, X86_FEATURE_MWAITX))
212 0 : use_mwaitx_delay();
213 :
214 0 : if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
215 0 : u32 ecx;
216 :
217 0 : ecx = cpuid_ecx(0x8000001e);
218 0 : nodes_per_socket = ((ecx >> 8) & 7) + 1;
219 0 : } else if (boot_cpu_has(X86_FEATURE_NODEID_MSR)) {
220 0 : u64 value;
221 :
222 0 : rdmsrl(MSR_FAM10H_NODE_ID, value);
223 0 : nodes_per_socket = ((value >> 3) & 7) + 1;
224 : }
225 :
226 0 : if (!boot_cpu_has(X86_FEATURE_AMD_SSBD) &&
227 0 : !boot_cpu_has(X86_FEATURE_VIRT_SSBD)) {
228 : /*
229 : * Try to cache the base value so further operations can
230 : * avoid RMW. If that faults, do not enable SSBD.
231 : */
232 0 : if (!rdmsrl_safe(MSR_AMD64_LS_CFG, &x86_amd_ls_cfg_base)) {
233 0 : setup_force_cpu_cap(X86_FEATURE_LS_CFG_SSBD);
234 0 : setup_force_cpu_cap(X86_FEATURE_SSBD);
235 0 : x86_amd_ls_cfg_ssbd_mask = 1ULL << 10;
236 : }
237 : }
238 0 : }
239 :
240 0 : static void early_init_hygon(struct cpuinfo_x86 *c)
241 : {
242 0 : u32 dummy;
243 :
244 0 : early_init_hygon_mc(c);
245 :
246 0 : set_cpu_cap(c, X86_FEATURE_K8);
247 :
248 0 : rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy);
249 :
250 : /*
251 : * c->x86_power is 8000_0007 edx. Bit 8 is TSC runs at constant rate
252 : * with P/T states and does not stop in deep C-states
253 : */
254 0 : if (c->x86_power & (1 << 8)) {
255 0 : set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
256 0 : set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
257 : }
258 :
259 : /* Bit 12 of 8000_0007 edx is accumulated power mechanism. */
260 0 : if (c->x86_power & BIT(12))
261 0 : set_cpu_cap(c, X86_FEATURE_ACC_POWER);
262 :
263 : #ifdef CONFIG_X86_64
264 0 : set_cpu_cap(c, X86_FEATURE_SYSCALL32);
265 : #endif
266 :
267 : #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_PCI)
268 : /*
269 : * ApicID can always be treated as an 8-bit value for Hygon APIC So, we
270 : * can safely set X86_FEATURE_EXTD_APICID unconditionally.
271 : */
272 : if (boot_cpu_has(X86_FEATURE_APIC))
273 : set_cpu_cap(c, X86_FEATURE_EXTD_APICID);
274 : #endif
275 :
276 : /*
277 : * This is only needed to tell the kernel whether to use VMCALL
278 : * and VMMCALL. VMMCALL is never executed except under virt, so
279 : * we can set it unconditionally.
280 : */
281 0 : set_cpu_cap(c, X86_FEATURE_VMMCALL);
282 :
283 0 : hygon_get_topology_early(c);
284 0 : }
285 :
286 0 : static void init_hygon(struct cpuinfo_x86 *c)
287 : {
288 0 : early_init_hygon(c);
289 :
290 : /*
291 : * Bit 31 in normal CPUID used for nonstandard 3DNow ID;
292 : * 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway
293 : */
294 0 : clear_cpu_cap(c, 0*32+31);
295 :
296 0 : set_cpu_cap(c, X86_FEATURE_REP_GOOD);
297 :
298 : /* get apicid instead of initial apic id from cpuid */
299 0 : c->apicid = hard_smp_processor_id();
300 :
301 0 : set_cpu_cap(c, X86_FEATURE_ZEN);
302 0 : set_cpu_cap(c, X86_FEATURE_CPB);
303 :
304 0 : cpu_detect_cache_sizes(c);
305 :
306 0 : hygon_detect_cmp(c);
307 0 : hygon_get_topology(c);
308 0 : srat_detect_node(c);
309 :
310 0 : init_hygon_cacheinfo(c);
311 :
312 0 : if (cpu_has(c, X86_FEATURE_XMM2)) {
313 : /*
314 : * Use LFENCE for execution serialization. On families which
315 : * don't have that MSR, LFENCE is already serializing.
316 : * msr_set_bit() uses the safe accessors, too, even if the MSR
317 : * is not present.
318 : */
319 0 : msr_set_bit(MSR_F10H_DECFG,
320 : MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT);
321 :
322 : /* A serializing LFENCE stops RDTSC speculation */
323 0 : set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
324 : }
325 :
326 : /*
327 : * Hygon processors have APIC timer running in deep C states.
328 : */
329 0 : set_cpu_cap(c, X86_FEATURE_ARAT);
330 :
331 : /* Hygon CPUs don't reset SS attributes on SYSRET, Xen does. */
332 0 : if (!cpu_has(c, X86_FEATURE_XENPV))
333 0 : set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS);
334 0 : }
335 :
336 0 : static void cpu_detect_tlb_hygon(struct cpuinfo_x86 *c)
337 : {
338 0 : u32 ebx, eax, ecx, edx;
339 0 : u16 mask = 0xfff;
340 :
341 0 : if (c->extended_cpuid_level < 0x80000006)
342 0 : return;
343 :
344 0 : cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
345 :
346 0 : tlb_lld_4k[ENTRIES] = (ebx >> 16) & mask;
347 0 : tlb_lli_4k[ENTRIES] = ebx & mask;
348 :
349 : /* Handle DTLB 2M and 4M sizes, fall back to L1 if L2 is disabled */
350 0 : if (!((eax >> 16) & mask))
351 0 : tlb_lld_2m[ENTRIES] = (cpuid_eax(0x80000005) >> 16) & 0xff;
352 : else
353 0 : tlb_lld_2m[ENTRIES] = (eax >> 16) & mask;
354 :
355 : /* a 4M entry uses two 2M entries */
356 0 : tlb_lld_4m[ENTRIES] = tlb_lld_2m[ENTRIES] >> 1;
357 :
358 : /* Handle ITLB 2M and 4M sizes, fall back to L1 if L2 is disabled */
359 0 : if (!(eax & mask)) {
360 0 : cpuid(0x80000005, &eax, &ebx, &ecx, &edx);
361 0 : tlb_lli_2m[ENTRIES] = eax & 0xff;
362 : } else
363 0 : tlb_lli_2m[ENTRIES] = eax & mask;
364 :
365 0 : tlb_lli_4m[ENTRIES] = tlb_lli_2m[ENTRIES] >> 1;
366 : }
367 :
368 : static const struct cpu_dev hygon_cpu_dev = {
369 : .c_vendor = "Hygon",
370 : .c_ident = { "HygonGenuine" },
371 : .c_early_init = early_init_hygon,
372 : .c_detect_tlb = cpu_detect_tlb_hygon,
373 : .c_bsp_init = bsp_init_hygon,
374 : .c_init = init_hygon,
375 : .c_x86_vendor = X86_VENDOR_HYGON,
376 : };
377 :
378 : cpu_dev_register(hygon_cpu_dev);
|