blob: 50b2d544361e02479b8af67691e26008f6225631 [file] [log] [blame]
Thomas Gleixnerf50a7f32019-05-28 09:57:18 -07001// SPDX-License-Identifier: GPL-2.0-only
Nicholas Piggin5a61ef72017-05-09 13:16:52 +10002/*
3 * Copyright 2017, Nicholas Piggin, IBM Corporation
Nicholas Piggin5a61ef72017-05-09 13:16:52 +10004 */
5
6#define pr_fmt(fmt) "dt-cpu-ftrs: " fmt
7
8#include <linux/export.h>
9#include <linux/init.h>
10#include <linux/jump_label.h>
Nicholas Piggina2b05b72017-05-11 21:24:41 +100011#include <linux/libfdt.h>
Nicholas Piggin5a61ef72017-05-09 13:16:52 +100012#include <linux/memblock.h>
13#include <linux/printk.h>
14#include <linux/sched.h>
15#include <linux/string.h>
16#include <linux/threads.h>
17
18#include <asm/cputable.h>
19#include <asm/dt_cpu_ftrs.h>
20#include <asm/mmu.h>
21#include <asm/oprofile_impl.h>
22#include <asm/prom.h>
23#include <asm/setup.h>
24
25
26/* Device-tree visible constants follow */
27#define ISA_V2_07B 2070
28#define ISA_V3_0B 3000
Alistair Popple43d0d372020-05-21 11:43:37 +100029#define ISA_V3_1 3100
Nicholas Piggin5a61ef72017-05-09 13:16:52 +100030
31#define USABLE_PR (1U << 0)
32#define USABLE_OS (1U << 1)
33#define USABLE_HV (1U << 2)
34
35#define HV_SUPPORT_HFSCR (1U << 0)
36#define OS_SUPPORT_FSCR (1U << 0)
37
38/* For parsing, we define all bits set as "NONE" case */
39#define HV_SUPPORT_NONE 0xffffffffU
40#define OS_SUPPORT_NONE 0xffffffffU
41
42struct dt_cpu_feature {
43 const char *name;
44 uint32_t isa;
45 uint32_t usable_privilege;
46 uint32_t hv_support;
47 uint32_t os_support;
48 uint32_t hfscr_bit_nr;
49 uint32_t fscr_bit_nr;
50 uint32_t hwcap_bit_nr;
51 /* fdt parsing */
52 unsigned long node;
53 int enabled;
54 int disabled;
55};
56
Nicholas Piggin5a61ef72017-05-09 13:16:52 +100057#define MMU_FTRS_HASH_BASE (MMU_FTRS_POWER8)
58
59#define COMMON_USER_BASE (PPC_FEATURE_32 | PPC_FEATURE_64 | \
60 PPC_FEATURE_ARCH_2_06 |\
61 PPC_FEATURE_ICACHE_SNOOP)
62#define COMMON_USER2_BASE (PPC_FEATURE2_ARCH_2_07 | \
63 PPC_FEATURE2_ISEL)
64/*
65 * Set up the base CPU
66 */
67
Nicholas Piggin5a61ef72017-05-09 13:16:52 +100068extern long __machine_check_early_realmode_p8(struct pt_regs *regs);
69extern long __machine_check_early_realmode_p9(struct pt_regs *regs);
70
71static int hv_mode;
72
73static struct {
74 u64 lpcr;
Nicholas Piggina57ac412018-04-05 15:50:49 +100075 u64 lpcr_clear;
Nicholas Piggin5a61ef72017-05-09 13:16:52 +100076 u64 hfscr;
77 u64 fscr;
Alistair Popple87939d52020-05-21 11:43:40 +100078 u64 pcr;
Nicholas Piggin5a61ef72017-05-09 13:16:52 +100079} system_registers;
80
81static void (*init_pmu_registers)(void);
82
Nicholas Piggin5a61ef72017-05-09 13:16:52 +100083static void __restore_cpu_cpufeatures(void)
84{
Nicholas Piggina57ac412018-04-05 15:50:49 +100085 u64 lpcr;
86
Nicholas Piggin5a61ef72017-05-09 13:16:52 +100087 /*
88 * LPCR is restored by the power on engine already. It can be changed
89 * after early init e.g., by radix enable, and we have no unified API
90 * for saving and restoring such SPRs.
91 *
92 * This ->restore hook should really be removed from idle and register
93 * restore moved directly into the idle restore code, because this code
94 * doesn't know how idle is implemented or what it needs restored here.
95 *
96 * The best we can do to accommodate secondary boot and idle restore
97 * for now is "or" LPCR with existing.
98 */
Nicholas Piggina57ac412018-04-05 15:50:49 +100099 lpcr = mfspr(SPRN_LPCR);
100 lpcr |= system_registers.lpcr;
101 lpcr &= ~system_registers.lpcr_clear;
102 mtspr(SPRN_LPCR, lpcr);
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000103 if (hv_mode) {
104 mtspr(SPRN_LPID, 0);
105 mtspr(SPRN_HFSCR, system_registers.hfscr);
Alistair Popple87939d52020-05-21 11:43:40 +1000106 mtspr(SPRN_PCR, system_registers.pcr);
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000107 }
108 mtspr(SPRN_FSCR, system_registers.fscr);
109
110 if (init_pmu_registers)
111 init_pmu_registers();
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000112}
113
114static char dt_cpu_name[64];
115
116static struct cpu_spec __initdata base_cpu_spec = {
117 .cpu_name = NULL,
Michael Ellerman81b654c2018-04-12 22:24:45 +1000118 .cpu_features = CPU_FTRS_DT_CPU_BASE,
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000119 .cpu_user_features = COMMON_USER_BASE,
120 .cpu_user_features2 = COMMON_USER2_BASE,
121 .mmu_features = 0,
122 .icache_bsize = 32, /* minimum block size, fixed by */
123 .dcache_bsize = 32, /* cache info init. */
124 .num_pmcs = 0,
125 .pmc_type = PPC_PMC_DEFAULT,
126 .oprofile_cpu_type = NULL,
127 .oprofile_type = PPC_OPROFILE_INVALID,
128 .cpu_setup = NULL,
129 .cpu_restore = __restore_cpu_cpufeatures,
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000130 .machine_check_early = NULL,
131 .platform = NULL,
132};
133
134static void __init cpufeatures_setup_cpu(void)
135{
136 set_cur_cpu_spec(&base_cpu_spec);
137
138 cur_cpu_spec->pvr_mask = -1;
139 cur_cpu_spec->pvr_value = mfspr(SPRN_PVR);
140
141 /* Initialize the base environment -- clear FSCR/HFSCR. */
142 hv_mode = !!(mfmsr() & MSR_HV);
143 if (hv_mode) {
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000144 cur_cpu_spec->cpu_features |= CPU_FTR_HVMODE;
145 mtspr(SPRN_HFSCR, 0);
146 }
147 mtspr(SPRN_FSCR, 0);
Jordan Niethe13c7bb32019-09-17 10:46:05 +1000148 mtspr(SPRN_PCR, PCR_MASK);
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000149
150 /*
151 * LPCR does not get cleared, to match behaviour with secondaries
152 * in __restore_cpu_cpufeatures. Once the idle code is fixed, this
153 * could clear LPCR too.
154 */
155}
156
157static int __init feat_try_enable_unknown(struct dt_cpu_feature *f)
158{
159 if (f->hv_support == HV_SUPPORT_NONE) {
160 } else if (f->hv_support & HV_SUPPORT_HFSCR) {
161 u64 hfscr = mfspr(SPRN_HFSCR);
162 hfscr |= 1UL << f->hfscr_bit_nr;
163 mtspr(SPRN_HFSCR, hfscr);
164 } else {
165 /* Does not have a known recipe */
166 return 0;
167 }
168
169 if (f->os_support == OS_SUPPORT_NONE) {
170 } else if (f->os_support & OS_SUPPORT_FSCR) {
171 u64 fscr = mfspr(SPRN_FSCR);
172 fscr |= 1UL << f->fscr_bit_nr;
173 mtspr(SPRN_FSCR, fscr);
174 } else {
175 /* Does not have a known recipe */
176 return 0;
177 }
178
179 if ((f->usable_privilege & USABLE_PR) && (f->hwcap_bit_nr != -1)) {
180 uint32_t word = f->hwcap_bit_nr / 32;
181 uint32_t bit = f->hwcap_bit_nr % 32;
182
183 if (word == 0)
184 cur_cpu_spec->cpu_user_features |= 1U << bit;
185 else if (word == 1)
186 cur_cpu_spec->cpu_user_features2 |= 1U << bit;
187 else
188 pr_err("%s could not advertise to user (no hwcap bits)\n", f->name);
189 }
190
191 return 1;
192}
193
194static int __init feat_enable(struct dt_cpu_feature *f)
195{
196 if (f->hv_support != HV_SUPPORT_NONE) {
197 if (f->hfscr_bit_nr != -1) {
198 u64 hfscr = mfspr(SPRN_HFSCR);
199 hfscr |= 1UL << f->hfscr_bit_nr;
200 mtspr(SPRN_HFSCR, hfscr);
201 }
202 }
203
204 if (f->os_support != OS_SUPPORT_NONE) {
205 if (f->fscr_bit_nr != -1) {
206 u64 fscr = mfspr(SPRN_FSCR);
207 fscr |= 1UL << f->fscr_bit_nr;
208 mtspr(SPRN_FSCR, fscr);
209 }
210 }
211
212 if ((f->usable_privilege & USABLE_PR) && (f->hwcap_bit_nr != -1)) {
213 uint32_t word = f->hwcap_bit_nr / 32;
214 uint32_t bit = f->hwcap_bit_nr % 32;
215
216 if (word == 0)
217 cur_cpu_spec->cpu_user_features |= 1U << bit;
218 else if (word == 1)
219 cur_cpu_spec->cpu_user_features2 |= 1U << bit;
220 else
221 pr_err("CPU feature: %s could not advertise to user (no hwcap bits)\n", f->name);
222 }
223
224 return 1;
225}
226
227static int __init feat_disable(struct dt_cpu_feature *f)
228{
229 return 0;
230}
231
232static int __init feat_enable_hv(struct dt_cpu_feature *f)
233{
234 u64 lpcr;
235
236 if (!hv_mode) {
237 pr_err("CPU feature hypervisor present in device tree but HV mode not enabled in the CPU. Ignoring.\n");
238 return 0;
239 }
240
241 mtspr(SPRN_LPID, 0);
242
243 lpcr = mfspr(SPRN_LPCR);
244 lpcr &= ~LPCR_LPES0; /* HV external interrupts */
245 mtspr(SPRN_LPCR, lpcr);
246
247 cur_cpu_spec->cpu_features |= CPU_FTR_HVMODE;
248
249 return 1;
250}
251
252static int __init feat_enable_le(struct dt_cpu_feature *f)
253{
254 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_TRUE_LE;
255 return 1;
256}
257
258static int __init feat_enable_smt(struct dt_cpu_feature *f)
259{
260 cur_cpu_spec->cpu_features |= CPU_FTR_SMT;
261 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_SMT;
262 return 1;
263}
264
265static int __init feat_enable_idle_nap(struct dt_cpu_feature *f)
266{
267 u64 lpcr;
268
269 /* Set PECE wakeup modes for ISA 207 */
270 lpcr = mfspr(SPRN_LPCR);
271 lpcr |= LPCR_PECE0;
272 lpcr |= LPCR_PECE1;
273 lpcr |= LPCR_PECE2;
274 mtspr(SPRN_LPCR, lpcr);
275
276 return 1;
277}
278
279static int __init feat_enable_align_dsisr(struct dt_cpu_feature *f)
280{
281 cur_cpu_spec->cpu_features &= ~CPU_FTR_NODSISRALIGN;
282
283 return 1;
284}
285
286static int __init feat_enable_idle_stop(struct dt_cpu_feature *f)
287{
288 u64 lpcr;
289
290 /* Set PECE wakeup modes for ISAv3.0B */
291 lpcr = mfspr(SPRN_LPCR);
292 lpcr |= LPCR_PECE0;
293 lpcr |= LPCR_PECE1;
294 lpcr |= LPCR_PECE2;
295 mtspr(SPRN_LPCR, lpcr);
296
297 return 1;
298}
299
300static int __init feat_enable_mmu_hash(struct dt_cpu_feature *f)
301{
302 u64 lpcr;
303
304 lpcr = mfspr(SPRN_LPCR);
305 lpcr &= ~LPCR_ISL;
306
307 /* VRMASD */
308 lpcr |= LPCR_VPM0;
309 lpcr &= ~LPCR_VPM1;
310 lpcr |= 0x10UL << LPCR_VRMASD_SH; /* L=1 LP=00 */
311 mtspr(SPRN_LPCR, lpcr);
312
313 cur_cpu_spec->mmu_features |= MMU_FTRS_HASH_BASE;
314 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_MMU;
315
316 return 1;
317}
318
319static int __init feat_enable_mmu_hash_v3(struct dt_cpu_feature *f)
320{
321 u64 lpcr;
322
Nicholas Piggina57ac412018-04-05 15:50:49 +1000323 system_registers.lpcr_clear |= (LPCR_ISL | LPCR_UPRT | LPCR_HR);
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000324 lpcr = mfspr(SPRN_LPCR);
Nicholas Piggina57ac412018-04-05 15:50:49 +1000325 lpcr &= ~(LPCR_ISL | LPCR_UPRT | LPCR_HR);
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000326 mtspr(SPRN_LPCR, lpcr);
327
328 cur_cpu_spec->mmu_features |= MMU_FTRS_HASH_BASE;
329 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_MMU;
330
331 return 1;
332}
333
334
335static int __init feat_enable_mmu_radix(struct dt_cpu_feature *f)
336{
337#ifdef CONFIG_PPC_RADIX_MMU
338 cur_cpu_spec->mmu_features |= MMU_FTR_TYPE_RADIX;
339 cur_cpu_spec->mmu_features |= MMU_FTRS_HASH_BASE;
340 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_MMU;
341
342 return 1;
343#endif
344 return 0;
345}
346
347static int __init feat_enable_dscr(struct dt_cpu_feature *f)
348{
349 u64 lpcr;
350
Michael Ellerman993e3d92020-05-28 00:58:41 +1000351 /*
352 * Linux relies on FSCR[DSCR] being clear, so that we can take the
353 * facility unavailable interrupt and track the task's usage of DSCR.
354 * See facility_unavailable_exception().
355 * Clear the bit here so that feat_enable() doesn't set it.
356 */
357 f->fscr_bit_nr = -1;
358
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000359 feat_enable(f);
360
361 lpcr = mfspr(SPRN_LPCR);
362 lpcr &= ~LPCR_DPFD;
363 lpcr |= (4UL << LPCR_DPFD_SH);
364 mtspr(SPRN_LPCR, lpcr);
365
366 return 1;
367}
368
369static void hfscr_pmu_enable(void)
370{
371 u64 hfscr = mfspr(SPRN_HFSCR);
372 hfscr |= PPC_BIT(60);
373 mtspr(SPRN_HFSCR, hfscr);
374}
375
376static void init_pmu_power8(void)
377{
378 if (hv_mode) {
379 mtspr(SPRN_MMCRC, 0);
380 mtspr(SPRN_MMCRH, 0);
381 }
382
383 mtspr(SPRN_MMCRA, 0);
384 mtspr(SPRN_MMCR0, 0);
385 mtspr(SPRN_MMCR1, 0);
386 mtspr(SPRN_MMCR2, 0);
387 mtspr(SPRN_MMCRS, 0);
388}
389
390static int __init feat_enable_mce_power8(struct dt_cpu_feature *f)
391{
392 cur_cpu_spec->platform = "power8";
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000393 cur_cpu_spec->machine_check_early = __machine_check_early_realmode_p8;
394
395 return 1;
396}
397
398static int __init feat_enable_pmu_power8(struct dt_cpu_feature *f)
399{
400 hfscr_pmu_enable();
401
402 init_pmu_power8();
403 init_pmu_registers = init_pmu_power8;
404
405 cur_cpu_spec->cpu_features |= CPU_FTR_MMCRA;
406 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_PSERIES_PERFMON_COMPAT;
407 if (pvr_version_is(PVR_POWER8E))
408 cur_cpu_spec->cpu_features |= CPU_FTR_PMAO_BUG;
409
410 cur_cpu_spec->num_pmcs = 6;
411 cur_cpu_spec->pmc_type = PPC_PMC_IBM;
412 cur_cpu_spec->oprofile_cpu_type = "ppc64/power8";
413
414 return 1;
415}
416
417static void init_pmu_power9(void)
418{
419 if (hv_mode)
420 mtspr(SPRN_MMCRC, 0);
421
422 mtspr(SPRN_MMCRA, 0);
423 mtspr(SPRN_MMCR0, 0);
424 mtspr(SPRN_MMCR1, 0);
425 mtspr(SPRN_MMCR2, 0);
426}
427
428static int __init feat_enable_mce_power9(struct dt_cpu_feature *f)
429{
430 cur_cpu_spec->platform = "power9";
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000431 cur_cpu_spec->machine_check_early = __machine_check_early_realmode_p9;
432
433 return 1;
434}
435
436static int __init feat_enable_pmu_power9(struct dt_cpu_feature *f)
437{
438 hfscr_pmu_enable();
439
440 init_pmu_power9();
441 init_pmu_registers = init_pmu_power9;
442
443 cur_cpu_spec->cpu_features |= CPU_FTR_MMCRA;
444 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_PSERIES_PERFMON_COMPAT;
445
446 cur_cpu_spec->num_pmcs = 6;
447 cur_cpu_spec->pmc_type = PPC_PMC_IBM;
448 cur_cpu_spec->oprofile_cpu_type = "ppc64/power9";
449
450 return 1;
451}
452
453static int __init feat_enable_tm(struct dt_cpu_feature *f)
454{
455#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
456 feat_enable(f);
457 cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_HTM_NOSC;
458 return 1;
459#endif
460 return 0;
461}
462
463static int __init feat_enable_fp(struct dt_cpu_feature *f)
464{
465 feat_enable(f);
466 cur_cpu_spec->cpu_features &= ~CPU_FTR_FPU_UNAVAILABLE;
467
468 return 1;
469}
470
471static int __init feat_enable_vector(struct dt_cpu_feature *f)
472{
473#ifdef CONFIG_ALTIVEC
474 feat_enable(f);
475 cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
476 cur_cpu_spec->cpu_features |= CPU_FTR_VMX_COPY;
477 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
478
479 return 1;
480#endif
481 return 0;
482}
483
484static int __init feat_enable_vsx(struct dt_cpu_feature *f)
485{
486#ifdef CONFIG_VSX
487 feat_enable(f);
488 cur_cpu_spec->cpu_features |= CPU_FTR_VSX;
489 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_VSX;
490
491 return 1;
492#endif
493 return 0;
494}
495
496static int __init feat_enable_purr(struct dt_cpu_feature *f)
497{
498 cur_cpu_spec->cpu_features |= CPU_FTR_PURR | CPU_FTR_SPURR;
499
500 return 1;
501}
502
503static int __init feat_enable_ebb(struct dt_cpu_feature *f)
504{
505 /*
506 * PPC_FEATURE2_EBB is enabled in PMU init code because it has
507 * historically been related to the PMU facility. This may have
508 * to be decoupled if EBB becomes more generic. For now, follow
509 * existing convention.
510 */
511 f->hwcap_bit_nr = -1;
512 feat_enable(f);
513
514 return 1;
515}
516
517static int __init feat_enable_dbell(struct dt_cpu_feature *f)
518{
519 u64 lpcr;
520
521 /* P9 has an HFSCR for privileged state */
522 feat_enable(f);
523
524 cur_cpu_spec->cpu_features |= CPU_FTR_DBELL;
525
526 lpcr = mfspr(SPRN_LPCR);
527 lpcr |= LPCR_PECEDH; /* hyp doorbell wakeup */
528 mtspr(SPRN_LPCR, lpcr);
529
530 return 1;
531}
532
533static int __init feat_enable_hvi(struct dt_cpu_feature *f)
534{
535 u64 lpcr;
536
537 /*
538 * POWER9 XIVE interrupts including in OPAL XICS compatibility
539 * are always delivered as hypervisor virtualization interrupts (HVI)
540 * rather than EE.
541 *
542 * However LPES0 is not set here, in the chance that an EE does get
543 * delivered to the host somehow, the EE handler would not expect it
544 * to be delivered in LPES0 mode (e.g., using SRR[01]). This could
545 * happen if there is a bug in interrupt controller code, or IC is
546 * misconfigured in systemsim.
547 */
548
549 lpcr = mfspr(SPRN_LPCR);
550 lpcr |= LPCR_HVICE; /* enable hvi interrupts */
551 lpcr |= LPCR_HEIC; /* disable ee interrupts when MSR_HV */
552 lpcr |= LPCR_PECE_HVEE; /* hvi can wake from stop */
553 mtspr(SPRN_LPCR, lpcr);
554
555 return 1;
556}
557
558static int __init feat_enable_large_ci(struct dt_cpu_feature *f)
559{
560 cur_cpu_spec->mmu_features |= MMU_FTR_CI_LARGE_PAGE;
561
562 return 1;
563}
564
Alistair Popple87939d52020-05-21 11:43:40 +1000565static int __init feat_enable_mma(struct dt_cpu_feature *f)
566{
567 u64 pcr;
568
569 feat_enable(f);
570 pcr = mfspr(SPRN_PCR);
571 pcr &= ~PCR_MMA_DIS;
572 mtspr(SPRN_PCR, pcr);
573
574 return 1;
575}
576
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000577struct dt_cpu_feature_match {
578 const char *name;
579 int (*enable)(struct dt_cpu_feature *f);
580 u64 cpu_ftr_bit_mask;
581};
582
583static struct dt_cpu_feature_match __initdata
584 dt_cpu_feature_match_table[] = {
585 {"hypervisor", feat_enable_hv, 0},
586 {"big-endian", feat_enable, 0},
587 {"little-endian", feat_enable_le, CPU_FTR_REAL_LE},
588 {"smt", feat_enable_smt, 0},
589 {"interrupt-facilities", feat_enable, 0},
Nicholas Piggin7fa95f92020-06-11 18:12:03 +1000590 {"system-call-vectored", feat_enable, 0},
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000591 {"timer-facilities", feat_enable, 0},
592 {"timer-facilities-v3", feat_enable, 0},
593 {"debug-facilities", feat_enable, 0},
594 {"come-from-address-register", feat_enable, CPU_FTR_CFAR},
595 {"branch-tracing", feat_enable, 0},
596 {"floating-point", feat_enable_fp, 0},
597 {"vector", feat_enable_vector, 0},
598 {"vector-scalar", feat_enable_vsx, 0},
599 {"vector-scalar-v3", feat_enable, 0},
600 {"decimal-floating-point", feat_enable, 0},
601 {"decimal-integer", feat_enable, 0},
602 {"quadword-load-store", feat_enable, 0},
603 {"vector-crypto", feat_enable, 0},
604 {"mmu-hash", feat_enable_mmu_hash, 0},
605 {"mmu-radix", feat_enable_mmu_radix, 0},
606 {"mmu-hash-v3", feat_enable_mmu_hash_v3, 0},
607 {"virtual-page-class-key-protection", feat_enable, 0},
608 {"transactional-memory", feat_enable_tm, CPU_FTR_TM},
609 {"transactional-memory-v3", feat_enable_tm, 0},
Paul Mackerrasb5af4f22018-03-21 21:31:59 +1100610 {"tm-suspend-hypervisor-assist", feat_enable, CPU_FTR_P9_TM_HV_ASSIST},
611 {"tm-suspend-xer-so-bug", feat_enable, CPU_FTR_P9_TM_XER_SO_BUG},
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000612 {"idle-nap", feat_enable_idle_nap, 0},
613 {"alignment-interrupt-dsisr", feat_enable_align_dsisr, 0},
614 {"idle-stop", feat_enable_idle_stop, 0},
615 {"machine-check-power8", feat_enable_mce_power8, 0},
616 {"performance-monitor-power8", feat_enable_pmu_power8, 0},
617 {"data-stream-control-register", feat_enable_dscr, CPU_FTR_DSCR},
618 {"event-based-branch", feat_enable_ebb, 0},
619 {"target-address-register", feat_enable, 0},
620 {"branch-history-rolling-buffer", feat_enable, 0},
621 {"control-register", feat_enable, CPU_FTR_CTRL},
622 {"processor-control-facility", feat_enable_dbell, CPU_FTR_DBELL},
623 {"processor-control-facility-v3", feat_enable_dbell, CPU_FTR_DBELL},
624 {"processor-utilization-of-resources-register", feat_enable_purr, 0},
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000625 {"no-execute", feat_enable, 0},
626 {"strong-access-ordering", feat_enable, CPU_FTR_SAO},
627 {"cache-inhibited-large-page", feat_enable_large_ci, 0},
Michael Ellermanc1807e32017-10-19 15:08:19 +1100628 {"coprocessor-icswx", feat_enable, 0},
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000629 {"hypervisor-virtualization-interrupt", feat_enable_hvi, 0},
630 {"program-priority-register", feat_enable, CPU_FTR_HAS_PPR},
631 {"wait", feat_enable, 0},
632 {"atomic-memory-operations", feat_enable, 0},
633 {"branch-v3", feat_enable, 0},
634 {"copy-paste", feat_enable, 0},
635 {"decimal-floating-point-v3", feat_enable, 0},
636 {"decimal-integer-v3", feat_enable, 0},
637 {"fixed-point-v3", feat_enable, 0},
638 {"floating-point-v3", feat_enable, 0},
639 {"group-start-register", feat_enable, 0},
640 {"pc-relative-addressing", feat_enable, 0},
641 {"machine-check-power9", feat_enable_mce_power9, 0},
642 {"performance-monitor-power9", feat_enable_pmu_power9, 0},
643 {"event-based-branch-v3", feat_enable, 0},
644 {"random-number-generator", feat_enable, 0},
645 {"system-call-vectored", feat_disable, 0},
646 {"trace-interrupt-v3", feat_enable, 0},
647 {"vector-v3", feat_enable, 0},
648 {"vector-binary128", feat_enable, 0},
649 {"vector-binary16", feat_enable, 0},
650 {"wait-v3", feat_enable, 0},
Alistair Popplec63d6882020-05-21 11:43:39 +1000651 {"prefix-instructions", feat_enable, 0},
Alistair Popple87939d52020-05-21 11:43:40 +1000652 {"matrix-multiply-assist", feat_enable_mma, 0},
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000653};
654
Nicholas Piggina2b05b72017-05-11 21:24:41 +1000655static bool __initdata using_dt_cpu_ftrs;
656static bool __initdata enable_unknown = true;
657
658static int __init dt_cpu_ftrs_parse(char *str)
659{
660 if (!str)
661 return 0;
662
663 if (!strcmp(str, "off"))
664 using_dt_cpu_ftrs = false;
665 else if (!strcmp(str, "known"))
666 enable_unknown = false;
667 else
668 return 1;
669
670 return 0;
671}
672early_param("dt_cpu_ftrs", dt_cpu_ftrs_parse);
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000673
674static void __init cpufeatures_setup_start(u32 isa)
675{
676 pr_info("setup for ISA %d\n", isa);
677
678 if (isa >= 3000) {
679 cur_cpu_spec->cpu_features |= CPU_FTR_ARCH_300;
680 cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_ARCH_3_00;
681 }
Alistair Popple43d0d372020-05-21 11:43:37 +1000682
683 if (isa >= 3100) {
684 cur_cpu_spec->cpu_features |= CPU_FTR_ARCH_31;
685 cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_ARCH_3_1;
686 }
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000687}
688
689static bool __init cpufeatures_process_feature(struct dt_cpu_feature *f)
690{
691 const struct dt_cpu_feature_match *m;
692 bool known = false;
693 int i;
694
695 for (i = 0; i < ARRAY_SIZE(dt_cpu_feature_match_table); i++) {
696 m = &dt_cpu_feature_match_table[i];
697 if (!strcmp(f->name, m->name)) {
698 known = true;
Michael Ellerman8cfaf102019-02-11 11:20:01 +1100699 if (m->enable(f)) {
700 cur_cpu_spec->cpu_features |= m->cpu_ftr_bit_mask;
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000701 break;
Michael Ellerman8cfaf102019-02-11 11:20:01 +1100702 }
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000703
704 pr_info("not enabling: %s (disabled or unsupported by kernel)\n",
705 f->name);
706 return false;
707 }
708 }
709
Michael Ellerman8cfaf102019-02-11 11:20:01 +1100710 if (!known && (!enable_unknown || !feat_try_enable_unknown(f))) {
711 pr_info("not enabling: %s (unknown and unsupported by kernel)\n",
712 f->name);
713 return false;
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000714 }
715
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000716 if (known)
717 pr_debug("enabling: %s\n", f->name);
718 else
719 pr_debug("enabling: %s (unknown)\n", f->name);
720
721 return true;
722}
723
Aneesh Kumar K.V677733e2019-09-24 09:22:51 +0530724/*
725 * Handle POWER9 broadcast tlbie invalidation issue using
726 * cpu feature flag.
727 */
728static __init void update_tlbie_feature_flag(unsigned long pvr)
729{
730 if (PVR_VER(pvr) == PVR_POWER9) {
731 /*
732 * Set the tlbie feature flag for anything below
733 * Nimbus DD 2.3 and Cumulus DD 1.3
734 */
735 if ((pvr & 0xe000) == 0) {
736 /* Nimbus */
737 if ((pvr & 0xfff) < 0x203)
Aneesh Kumar K.V09ce98c2019-09-24 09:22:52 +0530738 cur_cpu_spec->cpu_features |= CPU_FTR_P9_TLBIE_STQ_BUG;
Aneesh Kumar K.V677733e2019-09-24 09:22:51 +0530739 } else if ((pvr & 0xc000) == 0) {
740 /* Cumulus */
741 if ((pvr & 0xfff) < 0x103)
Aneesh Kumar K.V09ce98c2019-09-24 09:22:52 +0530742 cur_cpu_spec->cpu_features |= CPU_FTR_P9_TLBIE_STQ_BUG;
Aneesh Kumar K.V677733e2019-09-24 09:22:51 +0530743 } else {
744 WARN_ONCE(1, "Unknown PVR");
Aneesh Kumar K.V09ce98c2019-09-24 09:22:52 +0530745 cur_cpu_spec->cpu_features |= CPU_FTR_P9_TLBIE_STQ_BUG;
Aneesh Kumar K.V677733e2019-09-24 09:22:51 +0530746 }
Aneesh Kumar K.V047e6572019-09-24 09:22:53 +0530747
748 cur_cpu_spec->cpu_features |= CPU_FTR_P9_TLBIE_ERAT_BUG;
Aneesh Kumar K.V677733e2019-09-24 09:22:51 +0530749 }
750}
751
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000752static __init void cpufeatures_cpu_quirks(void)
753{
Aneesh Kumar K.V677733e2019-09-24 09:22:51 +0530754 unsigned long version = mfspr(SPRN_PVR);
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000755
756 /*
757 * Not all quirks can be derived from the cpufeatures device tree.
758 */
Jordan Niethe736bcdd2019-12-06 14:17:22 +1100759 if ((version & 0xffffefff) == 0x004e0200) {
760 /* DD2.0 has no feature flag */
761 cur_cpu_spec->cpu_features |= CPU_FTR_P9_RADIX_PREFETCH_BUG;
762 } else if ((version & 0xffffefff) == 0x004e0201) {
Michael Ellerman4d6c51b2017-11-22 23:17:01 +1100763 cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD2_1;
Jordan Niethe736bcdd2019-12-06 14:17:22 +1100764 cur_cpu_spec->cpu_features |= CPU_FTR_P9_RADIX_PREFETCH_BUG;
765 } else if ((version & 0xffffefff) == 0x004e0202) {
Nicholas Piggin9e9626e2018-02-21 05:08:27 +1000766 cur_cpu_spec->cpu_features |= CPU_FTR_P9_TM_HV_ASSIST;
767 cur_cpu_spec->cpu_features |= CPU_FTR_P9_TM_XER_SO_BUG;
768 cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD2_1;
Jordan Niethe736bcdd2019-12-06 14:17:22 +1100769 } else if ((version & 0xffff0000) == 0x004e0000) {
Michael Ellerman749a0272018-06-13 23:23:56 +1000770 /* DD2.1 and up have DD2_1 */
Nicholas Piggin9e9626e2018-02-21 05:08:27 +1000771 cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD2_1;
Jordan Niethe736bcdd2019-12-06 14:17:22 +1100772 }
Michael Neuling622aa352018-03-27 15:37:23 +1100773
Michael Ellerman95dff482018-03-28 22:59:50 +1100774 if ((version & 0xffff0000) == 0x004e0000) {
Michael Neuling622aa352018-03-27 15:37:23 +1100775 cur_cpu_spec->cpu_features &= ~(CPU_FTR_DAWR);
Alastair D'Silva81984422018-05-11 16:12:57 +1000776 cur_cpu_spec->cpu_features |= CPU_FTR_P9_TIDR;
Michael Ellerman95dff482018-03-28 22:59:50 +1100777 }
Nicholas Pigginc1301532018-04-05 15:57:54 +1000778
Aneesh Kumar K.V677733e2019-09-24 09:22:51 +0530779 update_tlbie_feature_flag(version);
Nicholas Pigginc1301532018-04-05 15:57:54 +1000780 /*
781 * PKEY was not in the initial base or feature node
782 * specification, but it should become optional in the next
783 * cpu feature version sequence.
784 */
785 cur_cpu_spec->cpu_features |= CPU_FTR_PKEY;
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000786}
787
788static void __init cpufeatures_setup_finished(void)
789{
790 cpufeatures_cpu_quirks();
791
792 if (hv_mode && !(cur_cpu_spec->cpu_features & CPU_FTR_HVMODE)) {
793 pr_err("hypervisor not present in device tree but HV mode is enabled in the CPU. Enabling.\n");
794 cur_cpu_spec->cpu_features |= CPU_FTR_HVMODE;
795 }
796
Michael Ellermane4b79902018-03-13 15:58:11 +1100797 /* Make sure powerpc_base_platform is non-NULL */
798 powerpc_base_platform = cur_cpu_spec->platform;
799
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000800 system_registers.lpcr = mfspr(SPRN_LPCR);
801 system_registers.hfscr = mfspr(SPRN_HFSCR);
802 system_registers.fscr = mfspr(SPRN_FSCR);
Alistair Popple87939d52020-05-21 11:43:40 +1000803 system_registers.pcr = mfspr(SPRN_PCR);
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000804
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000805 pr_info("final cpu/mmu features = 0x%016lx 0x%08x\n",
806 cur_cpu_spec->cpu_features, cur_cpu_spec->mmu_features);
807}
808
Nicholas Piggina2b05b72017-05-11 21:24:41 +1000809static int __init disabled_on_cmdline(void)
810{
811 unsigned long root, chosen;
812 const char *p;
813
814 root = of_get_flat_dt_root();
815 chosen = of_get_flat_dt_subnode_by_name(root, "chosen");
816 if (chosen == -FDT_ERR_NOTFOUND)
817 return false;
818
819 p = of_get_flat_dt_prop(chosen, "bootargs", NULL);
820 if (!p)
821 return false;
822
823 if (strstr(p, "dt_cpu_ftrs=off"))
824 return true;
825
826 return false;
827}
828
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000829static int __init fdt_find_cpu_features(unsigned long node, const char *uname,
830 int depth, void *data)
831{
832 if (of_flat_dt_is_compatible(node, "ibm,powerpc-cpu-features")
833 && of_get_flat_dt_prop(node, "isa", NULL))
834 return 1;
835
836 return 0;
837}
838
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000839bool __init dt_cpu_ftrs_in_use(void)
840{
841 return using_dt_cpu_ftrs;
842}
843
844bool __init dt_cpu_ftrs_init(void *fdt)
845{
Nicholas Piggina2b05b72017-05-11 21:24:41 +1000846 using_dt_cpu_ftrs = false;
847
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000848 /* Setup and verify the FDT, if it fails we just bail */
849 if (!early_init_dt_verify(fdt))
850 return false;
851
852 if (!of_scan_flat_dt(fdt_find_cpu_features, NULL))
853 return false;
854
Nicholas Piggina2b05b72017-05-11 21:24:41 +1000855 if (disabled_on_cmdline())
856 return false;
857
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000858 cpufeatures_setup_cpu();
859
860 using_dt_cpu_ftrs = true;
861 return true;
862}
863
864static int nr_dt_cpu_features;
865static struct dt_cpu_feature *dt_cpu_features;
866
867static int __init process_cpufeatures_node(unsigned long node,
868 const char *uname, int i)
869{
870 const __be32 *prop;
871 struct dt_cpu_feature *f;
872 int len;
873
874 f = &dt_cpu_features[i];
Nicholas Piggin5a61ef72017-05-09 13:16:52 +1000875
876 f->node = node;
877
878 f->name = uname;
879
880 prop = of_get_flat_dt_prop(node, "isa", &len);
881 if (!prop) {
882 pr_warn("%s: missing isa property\n", uname);
883 return 0;
884 }
885 f->isa = be32_to_cpup(prop);
886
887 prop = of_get_flat_dt_prop(node, "usable-privilege", &len);
888 if (!prop) {
889 pr_warn("%s: missing usable-privilege property", uname);
890 return 0;
891 }
892 f->usable_privilege = be32_to_cpup(prop);
893
894 prop = of_get_flat_dt_prop(node, "hv-support", &len);
895 if (prop)
896 f->hv_support = be32_to_cpup(prop);
897 else
898 f->hv_support = HV_SUPPORT_NONE;
899
900 prop = of_get_flat_dt_prop(node, "os-support", &len);
901 if (prop)
902 f->os_support = be32_to_cpup(prop);
903 else
904 f->os_support = OS_SUPPORT_NONE;
905
906 prop = of_get_flat_dt_prop(node, "hfscr-bit-nr", &len);
907 if (prop)
908 f->hfscr_bit_nr = be32_to_cpup(prop);
909 else
910 f->hfscr_bit_nr = -1;
911 prop = of_get_flat_dt_prop(node, "fscr-bit-nr", &len);
912 if (prop)
913 f->fscr_bit_nr = be32_to_cpup(prop);
914 else
915 f->fscr_bit_nr = -1;
916 prop = of_get_flat_dt_prop(node, "hwcap-bit-nr", &len);
917 if (prop)
918 f->hwcap_bit_nr = be32_to_cpup(prop);
919 else
920 f->hwcap_bit_nr = -1;
921
922 if (f->usable_privilege & USABLE_HV) {
923 if (!(mfmsr() & MSR_HV)) {
924 pr_warn("%s: HV feature passed to guest\n", uname);
925 return 0;
926 }
927
928 if (f->hv_support == HV_SUPPORT_NONE && f->hfscr_bit_nr != -1) {
929 pr_warn("%s: unwanted hfscr_bit_nr\n", uname);
930 return 0;
931 }
932
933 if (f->hv_support == HV_SUPPORT_HFSCR) {
934 if (f->hfscr_bit_nr == -1) {
935 pr_warn("%s: missing hfscr_bit_nr\n", uname);
936 return 0;
937 }
938 }
939 } else {
940 if (f->hv_support != HV_SUPPORT_NONE || f->hfscr_bit_nr != -1) {
941 pr_warn("%s: unwanted hv_support/hfscr_bit_nr\n", uname);
942 return 0;
943 }
944 }
945
946 if (f->usable_privilege & USABLE_OS) {
947 if (f->os_support == OS_SUPPORT_NONE && f->fscr_bit_nr != -1) {
948 pr_warn("%s: unwanted fscr_bit_nr\n", uname);
949 return 0;
950 }
951
952 if (f->os_support == OS_SUPPORT_FSCR) {
953 if (f->fscr_bit_nr == -1) {
954 pr_warn("%s: missing fscr_bit_nr\n", uname);
955 return 0;
956 }
957 }
958 } else {
959 if (f->os_support != OS_SUPPORT_NONE || f->fscr_bit_nr != -1) {
960 pr_warn("%s: unwanted os_support/fscr_bit_nr\n", uname);
961 return 0;
962 }
963 }
964
965 if (!(f->usable_privilege & USABLE_PR)) {
966 if (f->hwcap_bit_nr != -1) {
967 pr_warn("%s: unwanted hwcap_bit_nr\n", uname);
968 return 0;
969 }
970 }
971
972 /* Do all the independent features in the first pass */
973 if (!of_get_flat_dt_prop(node, "dependencies", &len)) {
974 if (cpufeatures_process_feature(f))
975 f->enabled = 1;
976 else
977 f->disabled = 1;
978 }
979
980 return 0;
981}
982
983static void __init cpufeatures_deps_enable(struct dt_cpu_feature *f)
984{
985 const __be32 *prop;
986 int len;
987 int nr_deps;
988 int i;
989
990 if (f->enabled || f->disabled)
991 return;
992
993 prop = of_get_flat_dt_prop(f->node, "dependencies", &len);
994 if (!prop) {
995 pr_warn("%s: missing dependencies property", f->name);
996 return;
997 }
998
999 nr_deps = len / sizeof(int);
1000
1001 for (i = 0; i < nr_deps; i++) {
1002 unsigned long phandle = be32_to_cpu(prop[i]);
1003 int j;
1004
1005 for (j = 0; j < nr_dt_cpu_features; j++) {
1006 struct dt_cpu_feature *d = &dt_cpu_features[j];
1007
1008 if (of_get_flat_dt_phandle(d->node) == phandle) {
1009 cpufeatures_deps_enable(d);
1010 if (d->disabled) {
1011 f->disabled = 1;
1012 return;
1013 }
1014 }
1015 }
1016 }
1017
1018 if (cpufeatures_process_feature(f))
1019 f->enabled = 1;
1020 else
1021 f->disabled = 1;
1022}
1023
1024static int __init scan_cpufeatures_subnodes(unsigned long node,
1025 const char *uname,
1026 void *data)
1027{
1028 int *count = data;
1029
1030 process_cpufeatures_node(node, uname, *count);
1031
1032 (*count)++;
1033
1034 return 0;
1035}
1036
1037static int __init count_cpufeatures_subnodes(unsigned long node,
1038 const char *uname,
1039 void *data)
1040{
1041 int *count = data;
1042
1043 (*count)++;
1044
1045 return 0;
1046}
1047
1048static int __init dt_cpu_ftrs_scan_callback(unsigned long node, const char
1049 *uname, int depth, void *data)
1050{
1051 const __be32 *prop;
1052 int count, i;
1053 u32 isa;
1054
1055 /* We are scanning "ibm,powerpc-cpu-features" nodes only */
1056 if (!of_flat_dt_is_compatible(node, "ibm,powerpc-cpu-features"))
1057 return 0;
1058
1059 prop = of_get_flat_dt_prop(node, "isa", NULL);
1060 if (!prop)
1061 /* We checked before, "can't happen" */
1062 return 0;
1063
1064 isa = be32_to_cpup(prop);
1065
1066 /* Count and allocate space for cpu features */
1067 of_scan_flat_dt_subnodes(node, count_cpufeatures_subnodes,
1068 &nr_dt_cpu_features);
Christophe Leroy1269f7b2019-03-11 23:29:00 -07001069 dt_cpu_features = memblock_alloc(sizeof(struct dt_cpu_feature) * nr_dt_cpu_features, PAGE_SIZE);
Mike Rapoport8a7f97b2019-03-11 23:30:31 -07001070 if (!dt_cpu_features)
1071 panic("%s: Failed to allocate %zu bytes align=0x%lx\n",
1072 __func__,
1073 sizeof(struct dt_cpu_feature) * nr_dt_cpu_features,
1074 PAGE_SIZE);
Nicholas Piggin5a61ef72017-05-09 13:16:52 +10001075
1076 cpufeatures_setup_start(isa);
1077
1078 /* Scan nodes into dt_cpu_features and enable those without deps */
1079 count = 0;
1080 of_scan_flat_dt_subnodes(node, scan_cpufeatures_subnodes, &count);
1081
1082 /* Recursive enable remaining features with dependencies */
1083 for (i = 0; i < nr_dt_cpu_features; i++) {
1084 struct dt_cpu_feature *f = &dt_cpu_features[i];
1085
1086 cpufeatures_deps_enable(f);
1087 }
1088
1089 prop = of_get_flat_dt_prop(node, "display-name", NULL);
1090 if (prop && strlen((char *)prop) != 0) {
1091 strlcpy(dt_cpu_name, (char *)prop, sizeof(dt_cpu_name));
1092 cur_cpu_spec->cpu_name = dt_cpu_name;
1093 }
1094
1095 cpufeatures_setup_finished();
1096
1097 memblock_free(__pa(dt_cpu_features),
1098 sizeof(struct dt_cpu_feature)*nr_dt_cpu_features);
1099
1100 return 0;
1101}
1102
1103void __init dt_cpu_ftrs_scan(void)
1104{
Nicholas Piggina2b05b72017-05-11 21:24:41 +10001105 if (!using_dt_cpu_ftrs)
1106 return;
1107
Nicholas Piggin5a61ef72017-05-09 13:16:52 +10001108 of_scan_flat_dt(dt_cpu_ftrs_scan_callback, NULL);
1109}