0001
0002
0003
0004
0005
0006 #define pr_fmt(fmt) "dt-cpu-ftrs: " fmt
0007
0008 #include <linux/export.h>
0009 #include <linux/init.h>
0010 #include <linux/jump_label.h>
0011 #include <linux/libfdt.h>
0012 #include <linux/memblock.h>
0013 #include <linux/of_fdt.h>
0014 #include <linux/printk.h>
0015 #include <linux/sched.h>
0016 #include <linux/string.h>
0017 #include <linux/threads.h>
0018
0019 #include <asm/cputable.h>
0020 #include <asm/dt_cpu_ftrs.h>
0021 #include <asm/mce.h>
0022 #include <asm/mmu.h>
0023 #include <asm/setup.h>
0024
0025
0026
0027 #define ISA_V3_0B 3000
0028 #define ISA_V3_1 3100
0029
0030 #define USABLE_PR (1U << 0)
0031 #define USABLE_OS (1U << 1)
0032 #define USABLE_HV (1U << 2)
0033
0034 #define HV_SUPPORT_HFSCR (1U << 0)
0035 #define OS_SUPPORT_FSCR (1U << 0)
0036
0037
0038 #define HV_SUPPORT_NONE 0xffffffffU
0039 #define OS_SUPPORT_NONE 0xffffffffU
0040
0041 struct dt_cpu_feature {
0042 const char *name;
0043 uint32_t isa;
0044 uint32_t usable_privilege;
0045 uint32_t hv_support;
0046 uint32_t os_support;
0047 uint32_t hfscr_bit_nr;
0048 uint32_t fscr_bit_nr;
0049 uint32_t hwcap_bit_nr;
0050
0051 unsigned long node;
0052 int enabled;
0053 int disabled;
0054 };
0055
0056 #define MMU_FTRS_HASH_BASE (MMU_FTRS_POWER8)
0057
0058 #define COMMON_USER_BASE (PPC_FEATURE_32 | PPC_FEATURE_64 | \
0059 PPC_FEATURE_ARCH_2_06 |\
0060 PPC_FEATURE_ICACHE_SNOOP)
0061 #define COMMON_USER2_BASE (PPC_FEATURE2_ARCH_2_07 | \
0062 PPC_FEATURE2_ISEL)
0063
0064
0065
0066
0067 static int hv_mode;
0068
0069 static struct {
0070 u64 lpcr;
0071 u64 hfscr;
0072 u64 fscr;
0073 u64 pcr;
0074 } system_registers;
0075
0076 static void (*init_pmu_registers)(void);
0077
0078 static void __restore_cpu_cpufeatures(void)
0079 {
0080 mtspr(SPRN_LPCR, system_registers.lpcr);
0081 if (hv_mode) {
0082 mtspr(SPRN_LPID, 0);
0083 mtspr(SPRN_AMOR, ~0);
0084 mtspr(SPRN_HFSCR, system_registers.hfscr);
0085 mtspr(SPRN_PCR, system_registers.pcr);
0086 }
0087 mtspr(SPRN_FSCR, system_registers.fscr);
0088
0089 if (init_pmu_registers)
0090 init_pmu_registers();
0091 }
0092
0093 static char dt_cpu_name[64];
0094
0095 static struct cpu_spec __initdata base_cpu_spec = {
0096 .cpu_name = NULL,
0097 .cpu_features = CPU_FTRS_DT_CPU_BASE,
0098 .cpu_user_features = COMMON_USER_BASE,
0099 .cpu_user_features2 = COMMON_USER2_BASE,
0100 .mmu_features = 0,
0101 .icache_bsize = 32,
0102 .dcache_bsize = 32,
0103 .num_pmcs = 0,
0104 .pmc_type = PPC_PMC_DEFAULT,
0105 .cpu_setup = NULL,
0106 .cpu_restore = __restore_cpu_cpufeatures,
0107 .machine_check_early = NULL,
0108 .platform = NULL,
0109 };
0110
0111 static void __init cpufeatures_setup_cpu(void)
0112 {
0113 set_cur_cpu_spec(&base_cpu_spec);
0114
0115 cur_cpu_spec->pvr_mask = -1;
0116 cur_cpu_spec->pvr_value = mfspr(SPRN_PVR);
0117
0118
0119 hv_mode = !!(mfmsr() & MSR_HV);
0120 if (hv_mode) {
0121 cur_cpu_spec->cpu_features |= CPU_FTR_HVMODE;
0122 mtspr(SPRN_HFSCR, 0);
0123 }
0124 mtspr(SPRN_FSCR, 0);
0125 mtspr(SPRN_PCR, PCR_MASK);
0126
0127
0128
0129
0130
0131
0132 }
0133
0134 static int __init feat_try_enable_unknown(struct dt_cpu_feature *f)
0135 {
0136 if (f->hv_support == HV_SUPPORT_NONE) {
0137 } else if (f->hv_support & HV_SUPPORT_HFSCR) {
0138 u64 hfscr = mfspr(SPRN_HFSCR);
0139 hfscr |= 1UL << f->hfscr_bit_nr;
0140 mtspr(SPRN_HFSCR, hfscr);
0141 } else {
0142
0143 return 0;
0144 }
0145
0146 if (f->os_support == OS_SUPPORT_NONE) {
0147 } else if (f->os_support & OS_SUPPORT_FSCR) {
0148 u64 fscr = mfspr(SPRN_FSCR);
0149 fscr |= 1UL << f->fscr_bit_nr;
0150 mtspr(SPRN_FSCR, fscr);
0151 } else {
0152
0153 return 0;
0154 }
0155
0156 if ((f->usable_privilege & USABLE_PR) && (f->hwcap_bit_nr != -1)) {
0157 uint32_t word = f->hwcap_bit_nr / 32;
0158 uint32_t bit = f->hwcap_bit_nr % 32;
0159
0160 if (word == 0)
0161 cur_cpu_spec->cpu_user_features |= 1U << bit;
0162 else if (word == 1)
0163 cur_cpu_spec->cpu_user_features2 |= 1U << bit;
0164 else
0165 pr_err("%s could not advertise to user (no hwcap bits)\n", f->name);
0166 }
0167
0168 return 1;
0169 }
0170
0171 static int __init feat_enable(struct dt_cpu_feature *f)
0172 {
0173 if (f->hv_support != HV_SUPPORT_NONE) {
0174 if (f->hfscr_bit_nr != -1) {
0175 u64 hfscr = mfspr(SPRN_HFSCR);
0176 hfscr |= 1UL << f->hfscr_bit_nr;
0177 mtspr(SPRN_HFSCR, hfscr);
0178 }
0179 }
0180
0181 if (f->os_support != OS_SUPPORT_NONE) {
0182 if (f->fscr_bit_nr != -1) {
0183 u64 fscr = mfspr(SPRN_FSCR);
0184 fscr |= 1UL << f->fscr_bit_nr;
0185 mtspr(SPRN_FSCR, fscr);
0186 }
0187 }
0188
0189 if ((f->usable_privilege & USABLE_PR) && (f->hwcap_bit_nr != -1)) {
0190 uint32_t word = f->hwcap_bit_nr / 32;
0191 uint32_t bit = f->hwcap_bit_nr % 32;
0192
0193 if (word == 0)
0194 cur_cpu_spec->cpu_user_features |= 1U << bit;
0195 else if (word == 1)
0196 cur_cpu_spec->cpu_user_features2 |= 1U << bit;
0197 else
0198 pr_err("CPU feature: %s could not advertise to user (no hwcap bits)\n", f->name);
0199 }
0200
0201 return 1;
0202 }
0203
0204 static int __init feat_disable(struct dt_cpu_feature *f)
0205 {
0206 return 0;
0207 }
0208
0209 static int __init feat_enable_hv(struct dt_cpu_feature *f)
0210 {
0211 u64 lpcr;
0212
0213 if (!hv_mode) {
0214 pr_err("CPU feature hypervisor present in device tree but HV mode not enabled in the CPU. Ignoring.\n");
0215 return 0;
0216 }
0217
0218 mtspr(SPRN_LPID, 0);
0219 mtspr(SPRN_AMOR, ~0);
0220
0221 lpcr = mfspr(SPRN_LPCR);
0222 lpcr &= ~LPCR_LPES0;
0223 mtspr(SPRN_LPCR, lpcr);
0224
0225 cur_cpu_spec->cpu_features |= CPU_FTR_HVMODE;
0226
0227 return 1;
0228 }
0229
0230 static int __init feat_enable_le(struct dt_cpu_feature *f)
0231 {
0232 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_TRUE_LE;
0233 return 1;
0234 }
0235
0236 static int __init feat_enable_smt(struct dt_cpu_feature *f)
0237 {
0238 cur_cpu_spec->cpu_features |= CPU_FTR_SMT;
0239 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_SMT;
0240 return 1;
0241 }
0242
0243 static int __init feat_enable_idle_nap(struct dt_cpu_feature *f)
0244 {
0245 u64 lpcr;
0246
0247
0248 lpcr = mfspr(SPRN_LPCR);
0249 lpcr |= LPCR_PECE0;
0250 lpcr |= LPCR_PECE1;
0251 lpcr |= LPCR_PECE2;
0252 mtspr(SPRN_LPCR, lpcr);
0253
0254 return 1;
0255 }
0256
0257 static int __init feat_enable_idle_stop(struct dt_cpu_feature *f)
0258 {
0259 u64 lpcr;
0260
0261
0262 lpcr = mfspr(SPRN_LPCR);
0263 lpcr |= LPCR_PECE0;
0264 lpcr |= LPCR_PECE1;
0265 lpcr |= LPCR_PECE2;
0266 mtspr(SPRN_LPCR, lpcr);
0267
0268 return 1;
0269 }
0270
0271 static int __init feat_enable_mmu_hash(struct dt_cpu_feature *f)
0272 {
0273 u64 lpcr;
0274
0275 if (!IS_ENABLED(CONFIG_PPC_64S_HASH_MMU))
0276 return 0;
0277
0278 lpcr = mfspr(SPRN_LPCR);
0279 lpcr &= ~LPCR_ISL;
0280
0281
0282 lpcr |= LPCR_VPM0;
0283 lpcr &= ~LPCR_VPM1;
0284 lpcr |= 0x10UL << LPCR_VRMASD_SH;
0285 mtspr(SPRN_LPCR, lpcr);
0286
0287 cur_cpu_spec->mmu_features |= MMU_FTRS_HASH_BASE;
0288 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_MMU;
0289
0290 return 1;
0291 }
0292
0293 static int __init feat_enable_mmu_hash_v3(struct dt_cpu_feature *f)
0294 {
0295 u64 lpcr;
0296
0297 if (!IS_ENABLED(CONFIG_PPC_64S_HASH_MMU))
0298 return 0;
0299
0300 lpcr = mfspr(SPRN_LPCR);
0301 lpcr &= ~(LPCR_ISL | LPCR_UPRT | LPCR_HR);
0302 mtspr(SPRN_LPCR, lpcr);
0303
0304 cur_cpu_spec->mmu_features |= MMU_FTRS_HASH_BASE;
0305 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_MMU;
0306
0307 return 1;
0308 }
0309
0310
0311 static int __init feat_enable_mmu_radix(struct dt_cpu_feature *f)
0312 {
0313 if (!IS_ENABLED(CONFIG_PPC_RADIX_MMU))
0314 return 0;
0315
0316 cur_cpu_spec->mmu_features |= MMU_FTR_KERNEL_RO;
0317 cur_cpu_spec->mmu_features |= MMU_FTR_TYPE_RADIX;
0318 cur_cpu_spec->mmu_features |= MMU_FTR_GTSE;
0319 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_MMU;
0320
0321 return 1;
0322 }
0323
0324 static int __init feat_enable_dscr(struct dt_cpu_feature *f)
0325 {
0326 u64 lpcr;
0327
0328
0329
0330
0331
0332
0333
0334 f->fscr_bit_nr = -1;
0335
0336 feat_enable(f);
0337
0338 lpcr = mfspr(SPRN_LPCR);
0339 lpcr &= ~LPCR_DPFD;
0340 lpcr |= (4UL << LPCR_DPFD_SH);
0341 mtspr(SPRN_LPCR, lpcr);
0342
0343 return 1;
0344 }
0345
0346 static void __init hfscr_pmu_enable(void)
0347 {
0348 u64 hfscr = mfspr(SPRN_HFSCR);
0349 hfscr |= PPC_BIT(60);
0350 mtspr(SPRN_HFSCR, hfscr);
0351 }
0352
0353 static void init_pmu_power8(void)
0354 {
0355 if (hv_mode) {
0356 mtspr(SPRN_MMCRC, 0);
0357 mtspr(SPRN_MMCRH, 0);
0358 }
0359
0360 mtspr(SPRN_MMCRA, 0);
0361 mtspr(SPRN_MMCR0, MMCR0_FC);
0362 mtspr(SPRN_MMCR1, 0);
0363 mtspr(SPRN_MMCR2, 0);
0364 mtspr(SPRN_MMCRS, 0);
0365 }
0366
0367 static int __init feat_enable_mce_power8(struct dt_cpu_feature *f)
0368 {
0369 cur_cpu_spec->platform = "power8";
0370 cur_cpu_spec->machine_check_early = __machine_check_early_realmode_p8;
0371
0372 return 1;
0373 }
0374
0375 static int __init feat_enable_pmu_power8(struct dt_cpu_feature *f)
0376 {
0377 hfscr_pmu_enable();
0378
0379 init_pmu_power8();
0380 init_pmu_registers = init_pmu_power8;
0381
0382 cur_cpu_spec->cpu_features |= CPU_FTR_MMCRA;
0383 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_PSERIES_PERFMON_COMPAT;
0384 if (pvr_version_is(PVR_POWER8E))
0385 cur_cpu_spec->cpu_features |= CPU_FTR_PMAO_BUG;
0386
0387 cur_cpu_spec->num_pmcs = 6;
0388 cur_cpu_spec->pmc_type = PPC_PMC_IBM;
0389
0390 return 1;
0391 }
0392
0393 static void init_pmu_power9(void)
0394 {
0395 if (hv_mode)
0396 mtspr(SPRN_MMCRC, 0);
0397
0398 mtspr(SPRN_MMCRA, 0);
0399 mtspr(SPRN_MMCR0, MMCR0_FC);
0400 mtspr(SPRN_MMCR1, 0);
0401 mtspr(SPRN_MMCR2, 0);
0402 }
0403
0404 static int __init feat_enable_mce_power9(struct dt_cpu_feature *f)
0405 {
0406 cur_cpu_spec->platform = "power9";
0407 cur_cpu_spec->machine_check_early = __machine_check_early_realmode_p9;
0408
0409 return 1;
0410 }
0411
0412 static int __init feat_enable_pmu_power9(struct dt_cpu_feature *f)
0413 {
0414 hfscr_pmu_enable();
0415
0416 init_pmu_power9();
0417 init_pmu_registers = init_pmu_power9;
0418
0419 cur_cpu_spec->cpu_features |= CPU_FTR_MMCRA;
0420 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_PSERIES_PERFMON_COMPAT;
0421
0422 cur_cpu_spec->num_pmcs = 6;
0423 cur_cpu_spec->pmc_type = PPC_PMC_IBM;
0424
0425 return 1;
0426 }
0427
0428 static void init_pmu_power10(void)
0429 {
0430 init_pmu_power9();
0431
0432 mtspr(SPRN_MMCR3, 0);
0433 mtspr(SPRN_MMCRA, MMCRA_BHRB_DISABLE);
0434 mtspr(SPRN_MMCR0, MMCR0_FC | MMCR0_PMCCEXT);
0435 }
0436
0437 static int __init feat_enable_pmu_power10(struct dt_cpu_feature *f)
0438 {
0439 hfscr_pmu_enable();
0440
0441 init_pmu_power10();
0442 init_pmu_registers = init_pmu_power10;
0443
0444 cur_cpu_spec->cpu_features |= CPU_FTR_MMCRA;
0445 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_PSERIES_PERFMON_COMPAT;
0446
0447 cur_cpu_spec->num_pmcs = 6;
0448 cur_cpu_spec->pmc_type = PPC_PMC_IBM;
0449
0450 return 1;
0451 }
0452
0453 static int __init feat_enable_mce_power10(struct dt_cpu_feature *f)
0454 {
0455 cur_cpu_spec->platform = "power10";
0456 cur_cpu_spec->machine_check_early = __machine_check_early_realmode_p10;
0457
0458 return 1;
0459 }
0460
0461 static int __init feat_enable_tm(struct dt_cpu_feature *f)
0462 {
0463 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
0464 feat_enable(f);
0465 cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_HTM_NOSC;
0466 return 1;
0467 #endif
0468 return 0;
0469 }
0470
0471 static int __init feat_enable_fp(struct dt_cpu_feature *f)
0472 {
0473 feat_enable(f);
0474 cur_cpu_spec->cpu_features &= ~CPU_FTR_FPU_UNAVAILABLE;
0475
0476 return 1;
0477 }
0478
0479 static int __init feat_enable_vector(struct dt_cpu_feature *f)
0480 {
0481 #ifdef CONFIG_ALTIVEC
0482 feat_enable(f);
0483 cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
0484 cur_cpu_spec->cpu_features |= CPU_FTR_VMX_COPY;
0485 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
0486
0487 return 1;
0488 #endif
0489 return 0;
0490 }
0491
0492 static int __init feat_enable_vsx(struct dt_cpu_feature *f)
0493 {
0494 #ifdef CONFIG_VSX
0495 feat_enable(f);
0496 cur_cpu_spec->cpu_features |= CPU_FTR_VSX;
0497 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_VSX;
0498
0499 return 1;
0500 #endif
0501 return 0;
0502 }
0503
0504 static int __init feat_enable_purr(struct dt_cpu_feature *f)
0505 {
0506 cur_cpu_spec->cpu_features |= CPU_FTR_PURR | CPU_FTR_SPURR;
0507
0508 return 1;
0509 }
0510
0511 static int __init feat_enable_ebb(struct dt_cpu_feature *f)
0512 {
0513
0514
0515
0516
0517
0518
0519 f->hwcap_bit_nr = -1;
0520 feat_enable(f);
0521
0522 return 1;
0523 }
0524
0525 static int __init feat_enable_dbell(struct dt_cpu_feature *f)
0526 {
0527 u64 lpcr;
0528
0529
0530 feat_enable(f);
0531
0532 cur_cpu_spec->cpu_features |= CPU_FTR_DBELL;
0533
0534 lpcr = mfspr(SPRN_LPCR);
0535 lpcr |= LPCR_PECEDH;
0536 mtspr(SPRN_LPCR, lpcr);
0537
0538 return 1;
0539 }
0540
0541 static int __init feat_enable_hvi(struct dt_cpu_feature *f)
0542 {
0543 u64 lpcr;
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557 lpcr = mfspr(SPRN_LPCR);
0558 lpcr |= LPCR_HVICE;
0559 lpcr |= LPCR_HEIC;
0560 lpcr |= LPCR_PECE_HVEE;
0561 mtspr(SPRN_LPCR, lpcr);
0562
0563 return 1;
0564 }
0565
0566 static int __init feat_enable_large_ci(struct dt_cpu_feature *f)
0567 {
0568 cur_cpu_spec->mmu_features |= MMU_FTR_CI_LARGE_PAGE;
0569
0570 return 1;
0571 }
0572
0573 static int __init feat_enable_mma(struct dt_cpu_feature *f)
0574 {
0575 u64 pcr;
0576
0577 feat_enable(f);
0578 pcr = mfspr(SPRN_PCR);
0579 pcr &= ~PCR_MMA_DIS;
0580 mtspr(SPRN_PCR, pcr);
0581
0582 return 1;
0583 }
0584
0585 struct dt_cpu_feature_match {
0586 const char *name;
0587 int (*enable)(struct dt_cpu_feature *f);
0588 u64 cpu_ftr_bit_mask;
0589 };
0590
0591 static struct dt_cpu_feature_match __initdata
0592 dt_cpu_feature_match_table[] = {
0593 {"hypervisor", feat_enable_hv, 0},
0594 {"big-endian", feat_enable, 0},
0595 {"little-endian", feat_enable_le, CPU_FTR_REAL_LE},
0596 {"smt", feat_enable_smt, 0},
0597 {"interrupt-facilities", feat_enable, 0},
0598 {"system-call-vectored", feat_enable, 0},
0599 {"timer-facilities", feat_enable, 0},
0600 {"timer-facilities-v3", feat_enable, 0},
0601 {"debug-facilities", feat_enable, 0},
0602 {"come-from-address-register", feat_enable, CPU_FTR_CFAR},
0603 {"branch-tracing", feat_enable, 0},
0604 {"floating-point", feat_enable_fp, 0},
0605 {"vector", feat_enable_vector, 0},
0606 {"vector-scalar", feat_enable_vsx, 0},
0607 {"vector-scalar-v3", feat_enable, 0},
0608 {"decimal-floating-point", feat_enable, 0},
0609 {"decimal-integer", feat_enable, 0},
0610 {"quadword-load-store", feat_enable, 0},
0611 {"vector-crypto", feat_enable, 0},
0612 {"mmu-hash", feat_enable_mmu_hash, 0},
0613 {"mmu-radix", feat_enable_mmu_radix, 0},
0614 {"mmu-hash-v3", feat_enable_mmu_hash_v3, 0},
0615 {"virtual-page-class-key-protection", feat_enable, 0},
0616 {"transactional-memory", feat_enable_tm, CPU_FTR_TM},
0617 {"transactional-memory-v3", feat_enable_tm, 0},
0618 {"tm-suspend-hypervisor-assist", feat_enable, CPU_FTR_P9_TM_HV_ASSIST},
0619 {"tm-suspend-xer-so-bug", feat_enable, CPU_FTR_P9_TM_XER_SO_BUG},
0620 {"idle-nap", feat_enable_idle_nap, 0},
0621
0622 {"idle-stop", feat_enable_idle_stop, 0},
0623 {"machine-check-power8", feat_enable_mce_power8, 0},
0624 {"performance-monitor-power8", feat_enable_pmu_power8, 0},
0625 {"data-stream-control-register", feat_enable_dscr, CPU_FTR_DSCR},
0626 {"event-based-branch", feat_enable_ebb, 0},
0627 {"target-address-register", feat_enable, 0},
0628 {"branch-history-rolling-buffer", feat_enable, 0},
0629 {"control-register", feat_enable, CPU_FTR_CTRL},
0630 {"processor-control-facility", feat_enable_dbell, CPU_FTR_DBELL},
0631 {"processor-control-facility-v3", feat_enable_dbell, CPU_FTR_DBELL},
0632 {"processor-utilization-of-resources-register", feat_enable_purr, 0},
0633 {"no-execute", feat_enable, 0},
0634 {"strong-access-ordering", feat_enable, CPU_FTR_SAO},
0635 {"cache-inhibited-large-page", feat_enable_large_ci, 0},
0636 {"coprocessor-icswx", feat_enable, 0},
0637 {"hypervisor-virtualization-interrupt", feat_enable_hvi, 0},
0638 {"program-priority-register", feat_enable, CPU_FTR_HAS_PPR},
0639 {"wait", feat_enable, 0},
0640 {"atomic-memory-operations", feat_enable, 0},
0641 {"branch-v3", feat_enable, 0},
0642 {"copy-paste", feat_enable, 0},
0643 {"decimal-floating-point-v3", feat_enable, 0},
0644 {"decimal-integer-v3", feat_enable, 0},
0645 {"fixed-point-v3", feat_enable, 0},
0646 {"floating-point-v3", feat_enable, 0},
0647 {"group-start-register", feat_enable, 0},
0648 {"pc-relative-addressing", feat_enable, 0},
0649 {"machine-check-power9", feat_enable_mce_power9, 0},
0650 {"machine-check-power10", feat_enable_mce_power10, 0},
0651 {"performance-monitor-power9", feat_enable_pmu_power9, 0},
0652 {"performance-monitor-power10", feat_enable_pmu_power10, 0},
0653 {"event-based-branch-v3", feat_enable, 0},
0654 {"random-number-generator", feat_enable, 0},
0655 {"system-call-vectored", feat_disable, 0},
0656 {"trace-interrupt-v3", feat_enable, 0},
0657 {"vector-v3", feat_enable, 0},
0658 {"vector-binary128", feat_enable, 0},
0659 {"vector-binary16", feat_enable, 0},
0660 {"wait-v3", feat_enable, 0},
0661 {"prefix-instructions", feat_enable, 0},
0662 {"matrix-multiply-assist", feat_enable_mma, 0},
0663 {"debug-facilities-v31", feat_enable, CPU_FTR_DAWR1},
0664 };
0665
0666 static bool __initdata using_dt_cpu_ftrs;
0667 static bool __initdata enable_unknown = true;
0668
0669 static int __init dt_cpu_ftrs_parse(char *str)
0670 {
0671 if (!str)
0672 return 0;
0673
0674 if (!strcmp(str, "off"))
0675 using_dt_cpu_ftrs = false;
0676 else if (!strcmp(str, "known"))
0677 enable_unknown = false;
0678 else
0679 return 1;
0680
0681 return 0;
0682 }
0683 early_param("dt_cpu_ftrs", dt_cpu_ftrs_parse);
0684
0685 static void __init cpufeatures_setup_start(u32 isa)
0686 {
0687 pr_info("setup for ISA %d\n", isa);
0688
0689 if (isa >= ISA_V3_0B) {
0690 cur_cpu_spec->cpu_features |= CPU_FTR_ARCH_300;
0691 cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_ARCH_3_00;
0692 }
0693
0694 if (isa >= ISA_V3_1) {
0695 cur_cpu_spec->cpu_features |= CPU_FTR_ARCH_31;
0696 cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_ARCH_3_1;
0697 }
0698 }
0699
0700 static bool __init cpufeatures_process_feature(struct dt_cpu_feature *f)
0701 {
0702 const struct dt_cpu_feature_match *m;
0703 bool known = false;
0704 int i;
0705
0706 for (i = 0; i < ARRAY_SIZE(dt_cpu_feature_match_table); i++) {
0707 m = &dt_cpu_feature_match_table[i];
0708 if (!strcmp(f->name, m->name)) {
0709 known = true;
0710 if (m->enable(f)) {
0711 cur_cpu_spec->cpu_features |= m->cpu_ftr_bit_mask;
0712 break;
0713 }
0714
0715 pr_info("not enabling: %s (disabled or unsupported by kernel)\n",
0716 f->name);
0717 return false;
0718 }
0719 }
0720
0721 if (!known && (!enable_unknown || !feat_try_enable_unknown(f))) {
0722 pr_info("not enabling: %s (unknown and unsupported by kernel)\n",
0723 f->name);
0724 return false;
0725 }
0726
0727 if (known)
0728 pr_debug("enabling: %s\n", f->name);
0729 else
0730 pr_debug("enabling: %s (unknown)\n", f->name);
0731
0732 return true;
0733 }
0734
0735
0736
0737
0738
0739 static __init void update_tlbie_feature_flag(unsigned long pvr)
0740 {
0741 if (PVR_VER(pvr) == PVR_POWER9) {
0742
0743
0744
0745
0746 if ((pvr & 0xe000) == 0) {
0747
0748 if ((pvr & 0xfff) < 0x203)
0749 cur_cpu_spec->cpu_features |= CPU_FTR_P9_TLBIE_STQ_BUG;
0750 } else if ((pvr & 0xc000) == 0) {
0751
0752 if ((pvr & 0xfff) < 0x103)
0753 cur_cpu_spec->cpu_features |= CPU_FTR_P9_TLBIE_STQ_BUG;
0754 } else {
0755 WARN_ONCE(1, "Unknown PVR");
0756 cur_cpu_spec->cpu_features |= CPU_FTR_P9_TLBIE_STQ_BUG;
0757 }
0758
0759 cur_cpu_spec->cpu_features |= CPU_FTR_P9_TLBIE_ERAT_BUG;
0760 }
0761 }
0762
0763 static __init void cpufeatures_cpu_quirks(void)
0764 {
0765 unsigned long version = mfspr(SPRN_PVR);
0766
0767
0768
0769
0770 if ((version & 0xffffefff) == 0x004e0200) {
0771
0772 cur_cpu_spec->cpu_features |= CPU_FTR_P9_RADIX_PREFETCH_BUG;
0773 cur_cpu_spec->cpu_features &= ~(CPU_FTR_DAWR);
0774 } else if ((version & 0xffffefff) == 0x004e0201) {
0775 cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD2_1;
0776 cur_cpu_spec->cpu_features |= CPU_FTR_P9_RADIX_PREFETCH_BUG;
0777 cur_cpu_spec->cpu_features &= ~(CPU_FTR_DAWR);
0778 } else if ((version & 0xffffefff) == 0x004e0202) {
0779 cur_cpu_spec->cpu_features |= CPU_FTR_P9_TM_HV_ASSIST;
0780 cur_cpu_spec->cpu_features |= CPU_FTR_P9_TM_XER_SO_BUG;
0781 cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD2_1;
0782 cur_cpu_spec->cpu_features &= ~(CPU_FTR_DAWR);
0783 } else if ((version & 0xffffefff) == 0x004e0203) {
0784 cur_cpu_spec->cpu_features |= CPU_FTR_P9_TM_HV_ASSIST;
0785 cur_cpu_spec->cpu_features |= CPU_FTR_P9_TM_XER_SO_BUG;
0786 cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD2_1;
0787 } else if ((version & 0xffff0000) == 0x004e0000) {
0788
0789 cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD2_1;
0790 }
0791
0792 if ((version & 0xffff0000) == 0x004e0000) {
0793 cur_cpu_spec->cpu_features |= CPU_FTR_P9_TIDR;
0794 }
0795
0796 update_tlbie_feature_flag(version);
0797 }
0798
0799 static void __init cpufeatures_setup_finished(void)
0800 {
0801 cpufeatures_cpu_quirks();
0802
0803 if (hv_mode && !(cur_cpu_spec->cpu_features & CPU_FTR_HVMODE)) {
0804 pr_err("hypervisor not present in device tree but HV mode is enabled in the CPU. Enabling.\n");
0805 cur_cpu_spec->cpu_features |= CPU_FTR_HVMODE;
0806 }
0807
0808
0809 powerpc_base_platform = cur_cpu_spec->platform;
0810
0811 system_registers.lpcr = mfspr(SPRN_LPCR);
0812 system_registers.hfscr = mfspr(SPRN_HFSCR);
0813 system_registers.fscr = mfspr(SPRN_FSCR);
0814 system_registers.pcr = mfspr(SPRN_PCR);
0815
0816 pr_info("final cpu/mmu features = 0x%016lx 0x%08x\n",
0817 cur_cpu_spec->cpu_features, cur_cpu_spec->mmu_features);
0818 }
0819
0820 static int __init disabled_on_cmdline(void)
0821 {
0822 unsigned long root, chosen;
0823 const char *p;
0824
0825 root = of_get_flat_dt_root();
0826 chosen = of_get_flat_dt_subnode_by_name(root, "chosen");
0827 if (chosen == -FDT_ERR_NOTFOUND)
0828 return false;
0829
0830 p = of_get_flat_dt_prop(chosen, "bootargs", NULL);
0831 if (!p)
0832 return false;
0833
0834 if (strstr(p, "dt_cpu_ftrs=off"))
0835 return true;
0836
0837 return false;
0838 }
0839
0840 static int __init fdt_find_cpu_features(unsigned long node, const char *uname,
0841 int depth, void *data)
0842 {
0843 if (of_flat_dt_is_compatible(node, "ibm,powerpc-cpu-features")
0844 && of_get_flat_dt_prop(node, "isa", NULL))
0845 return 1;
0846
0847 return 0;
0848 }
0849
0850 bool __init dt_cpu_ftrs_in_use(void)
0851 {
0852 return using_dt_cpu_ftrs;
0853 }
0854
0855 bool __init dt_cpu_ftrs_init(void *fdt)
0856 {
0857 using_dt_cpu_ftrs = false;
0858
0859
0860 if (!early_init_dt_verify(fdt))
0861 return false;
0862
0863 if (!of_scan_flat_dt(fdt_find_cpu_features, NULL))
0864 return false;
0865
0866 if (disabled_on_cmdline())
0867 return false;
0868
0869 cpufeatures_setup_cpu();
0870
0871 using_dt_cpu_ftrs = true;
0872 return true;
0873 }
0874
0875 static int nr_dt_cpu_features;
0876 static struct dt_cpu_feature *dt_cpu_features;
0877
0878 static int __init process_cpufeatures_node(unsigned long node,
0879 const char *uname, int i)
0880 {
0881 const __be32 *prop;
0882 struct dt_cpu_feature *f;
0883 int len;
0884
0885 f = &dt_cpu_features[i];
0886
0887 f->node = node;
0888
0889 f->name = uname;
0890
0891 prop = of_get_flat_dt_prop(node, "isa", &len);
0892 if (!prop) {
0893 pr_warn("%s: missing isa property\n", uname);
0894 return 0;
0895 }
0896 f->isa = be32_to_cpup(prop);
0897
0898 prop = of_get_flat_dt_prop(node, "usable-privilege", &len);
0899 if (!prop) {
0900 pr_warn("%s: missing usable-privilege property", uname);
0901 return 0;
0902 }
0903 f->usable_privilege = be32_to_cpup(prop);
0904
0905 prop = of_get_flat_dt_prop(node, "hv-support", &len);
0906 if (prop)
0907 f->hv_support = be32_to_cpup(prop);
0908 else
0909 f->hv_support = HV_SUPPORT_NONE;
0910
0911 prop = of_get_flat_dt_prop(node, "os-support", &len);
0912 if (prop)
0913 f->os_support = be32_to_cpup(prop);
0914 else
0915 f->os_support = OS_SUPPORT_NONE;
0916
0917 prop = of_get_flat_dt_prop(node, "hfscr-bit-nr", &len);
0918 if (prop)
0919 f->hfscr_bit_nr = be32_to_cpup(prop);
0920 else
0921 f->hfscr_bit_nr = -1;
0922 prop = of_get_flat_dt_prop(node, "fscr-bit-nr", &len);
0923 if (prop)
0924 f->fscr_bit_nr = be32_to_cpup(prop);
0925 else
0926 f->fscr_bit_nr = -1;
0927 prop = of_get_flat_dt_prop(node, "hwcap-bit-nr", &len);
0928 if (prop)
0929 f->hwcap_bit_nr = be32_to_cpup(prop);
0930 else
0931 f->hwcap_bit_nr = -1;
0932
0933 if (f->usable_privilege & USABLE_HV) {
0934 if (!(mfmsr() & MSR_HV)) {
0935 pr_warn("%s: HV feature passed to guest\n", uname);
0936 return 0;
0937 }
0938
0939 if (f->hv_support == HV_SUPPORT_NONE && f->hfscr_bit_nr != -1) {
0940 pr_warn("%s: unwanted hfscr_bit_nr\n", uname);
0941 return 0;
0942 }
0943
0944 if (f->hv_support == HV_SUPPORT_HFSCR) {
0945 if (f->hfscr_bit_nr == -1) {
0946 pr_warn("%s: missing hfscr_bit_nr\n", uname);
0947 return 0;
0948 }
0949 }
0950 } else {
0951 if (f->hv_support != HV_SUPPORT_NONE || f->hfscr_bit_nr != -1) {
0952 pr_warn("%s: unwanted hv_support/hfscr_bit_nr\n", uname);
0953 return 0;
0954 }
0955 }
0956
0957 if (f->usable_privilege & USABLE_OS) {
0958 if (f->os_support == OS_SUPPORT_NONE && f->fscr_bit_nr != -1) {
0959 pr_warn("%s: unwanted fscr_bit_nr\n", uname);
0960 return 0;
0961 }
0962
0963 if (f->os_support == OS_SUPPORT_FSCR) {
0964 if (f->fscr_bit_nr == -1) {
0965 pr_warn("%s: missing fscr_bit_nr\n", uname);
0966 return 0;
0967 }
0968 }
0969 } else {
0970 if (f->os_support != OS_SUPPORT_NONE || f->fscr_bit_nr != -1) {
0971 pr_warn("%s: unwanted os_support/fscr_bit_nr\n", uname);
0972 return 0;
0973 }
0974 }
0975
0976 if (!(f->usable_privilege & USABLE_PR)) {
0977 if (f->hwcap_bit_nr != -1) {
0978 pr_warn("%s: unwanted hwcap_bit_nr\n", uname);
0979 return 0;
0980 }
0981 }
0982
0983
0984 if (!of_get_flat_dt_prop(node, "dependencies", &len)) {
0985 if (cpufeatures_process_feature(f))
0986 f->enabled = 1;
0987 else
0988 f->disabled = 1;
0989 }
0990
0991 return 0;
0992 }
0993
0994 static void __init cpufeatures_deps_enable(struct dt_cpu_feature *f)
0995 {
0996 const __be32 *prop;
0997 int len;
0998 int nr_deps;
0999 int i;
1000
1001 if (f->enabled || f->disabled)
1002 return;
1003
1004 prop = of_get_flat_dt_prop(f->node, "dependencies", &len);
1005 if (!prop) {
1006 pr_warn("%s: missing dependencies property", f->name);
1007 return;
1008 }
1009
1010 nr_deps = len / sizeof(int);
1011
1012 for (i = 0; i < nr_deps; i++) {
1013 unsigned long phandle = be32_to_cpu(prop[i]);
1014 int j;
1015
1016 for (j = 0; j < nr_dt_cpu_features; j++) {
1017 struct dt_cpu_feature *d = &dt_cpu_features[j];
1018
1019 if (of_get_flat_dt_phandle(d->node) == phandle) {
1020 cpufeatures_deps_enable(d);
1021 if (d->disabled) {
1022 f->disabled = 1;
1023 return;
1024 }
1025 }
1026 }
1027 }
1028
1029 if (cpufeatures_process_feature(f))
1030 f->enabled = 1;
1031 else
1032 f->disabled = 1;
1033 }
1034
1035 static int __init scan_cpufeatures_subnodes(unsigned long node,
1036 const char *uname,
1037 void *data)
1038 {
1039 int *count = data;
1040
1041 process_cpufeatures_node(node, uname, *count);
1042
1043 (*count)++;
1044
1045 return 0;
1046 }
1047
1048 static int __init count_cpufeatures_subnodes(unsigned long node,
1049 const char *uname,
1050 void *data)
1051 {
1052 int *count = data;
1053
1054 (*count)++;
1055
1056 return 0;
1057 }
1058
1059 static int __init dt_cpu_ftrs_scan_callback(unsigned long node, const char
1060 *uname, int depth, void *data)
1061 {
1062 const __be32 *prop;
1063 int count, i;
1064 u32 isa;
1065
1066
1067 if (!of_flat_dt_is_compatible(node, "ibm,powerpc-cpu-features"))
1068 return 0;
1069
1070 prop = of_get_flat_dt_prop(node, "isa", NULL);
1071 if (!prop)
1072
1073 return 0;
1074
1075 isa = be32_to_cpup(prop);
1076
1077
1078 of_scan_flat_dt_subnodes(node, count_cpufeatures_subnodes,
1079 &nr_dt_cpu_features);
1080 dt_cpu_features = memblock_alloc(sizeof(struct dt_cpu_feature) * nr_dt_cpu_features, PAGE_SIZE);
1081 if (!dt_cpu_features)
1082 panic("%s: Failed to allocate %zu bytes align=0x%lx\n",
1083 __func__,
1084 sizeof(struct dt_cpu_feature) * nr_dt_cpu_features,
1085 PAGE_SIZE);
1086
1087 cpufeatures_setup_start(isa);
1088
1089
1090 count = 0;
1091 of_scan_flat_dt_subnodes(node, scan_cpufeatures_subnodes, &count);
1092
1093
1094 for (i = 0; i < nr_dt_cpu_features; i++) {
1095 struct dt_cpu_feature *f = &dt_cpu_features[i];
1096
1097 cpufeatures_deps_enable(f);
1098 }
1099
1100 prop = of_get_flat_dt_prop(node, "display-name", NULL);
1101 if (prop && strlen((char *)prop) != 0) {
1102 strlcpy(dt_cpu_name, (char *)prop, sizeof(dt_cpu_name));
1103 cur_cpu_spec->cpu_name = dt_cpu_name;
1104 }
1105
1106 cpufeatures_setup_finished();
1107
1108 memblock_free(dt_cpu_features,
1109 sizeof(struct dt_cpu_feature) * nr_dt_cpu_features);
1110
1111 return 0;
1112 }
1113
1114 void __init dt_cpu_ftrs_scan(void)
1115 {
1116 if (!using_dt_cpu_ftrs)
1117 return;
1118
1119 of_scan_flat_dt(dt_cpu_ftrs_scan_callback, NULL);
1120 }