Branch data Line data Source code
1 : : // SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
2 : : /*
3 : : * This file deals with setup of /cpus/ibm,powerpc-cpu-features dt
4 : : *
5 : : * Copyright 2017-2019 IBM Corp.
6 : : */
7 : :
8 : : #include <skiboot.h>
9 : : #include <cpu.h>
10 : : #include <processor.h>
11 : : #include <ccan/str/str.h>
12 : : #include <device.h>
13 : :
14 : : #ifdef DEBUG
15 : : #define DBG(fmt, a...) prlog(PR_DEBUG, "CPUFT: " fmt, ##a)
16 : : #else
17 : : #define DBG(fmt, a...)
18 : : #endif
19 : :
20 : : /* Device-tree visible constants follow */
21 : : #define ISA_V2_07B 2070
22 : : #define ISA_V3_0B 3000
23 : : #define ISA_V3_1 3100
24 : :
25 : : #define USABLE_PR (1U << 0)
26 : : #define USABLE_OS (1U << 1)
27 : : #define USABLE_HV (1U << 2)
28 : :
29 : : #define HV_SUPPORT_HFSCR (1U << 0)
30 : : #define OS_SUPPORT_FSCR (1U << 0)
31 : :
32 : : /* Following are definitions for the match tables, not the DT binding itself */
33 : : #define ISA_BASE 0
34 : :
35 : : #define HV_NONE 0
36 : : #define HV_CUSTOM 1
37 : : #define HV_HFSCR 2
38 : :
39 : : #define OS_NONE 0
40 : : #define OS_CUSTOM 1
41 : : #define OS_FSCR 2
42 : :
43 : : /* CPU bitmasks for match table */
44 : : #define CPU_P8_DD1 (1U << 0)
45 : : #define CPU_P8_DD2 (1U << 1)
46 : : #define CPU_P9_DD1 (1U << 2)
47 : : #define CPU_P9_DD2_0_1 (1U << 3) // 2.01 or 2.1
48 : : #define CPU_P9P (1U << 4)
49 : : #define CPU_P9_DD2_2 (1U << 5)
50 : : #define CPU_P9_DD2_3 (1U << 6)
51 : : #define CPU_P10 (1U << 7)
52 : : #define CPU_P11 (1U << 8)
53 : :
54 : : #define CPU_P9_DD2 (CPU_P9_DD2_0_1|CPU_P9_DD2_2|CPU_P9_DD2_3|CPU_P9P)
55 : :
56 : : #define CPU_P8 (CPU_P8_DD1|CPU_P8_DD2)
57 : : #define CPU_P9 (CPU_P9_DD1|CPU_P9_DD2|CPU_P9P)
58 : : #define CPU_ALL (CPU_P8|CPU_P9|CPU_P10|CPU_P11)
59 : :
60 : : struct cpu_feature {
61 : : const char *name;
62 : : uint32_t cpus_supported;
63 : : uint32_t isa;
64 : : uint32_t usable_privilege;
65 : : uint32_t hv_support;
66 : : uint32_t os_support;
67 : : uint32_t hfscr_bit_nr;
68 : : uint32_t fscr_bit_nr;
69 : : uint32_t hwcap_bit_nr;
70 : : const char *dependencies_names; /* space-delimited names */
71 : : };
72 : :
73 : : /*
74 : : * The base (or NULL) cpu feature set is the CPU features available
75 : : * when no child nodes of the /cpus/ibm,powerpc-cpu-features node exist. The
76 : : * base feature set is POWER8 (ISAv2.07B), less features that are listed
77 : : * explicitly.
78 : : *
79 : : * XXX: currently, the feature dependencies are not necessarily captured
80 : : * exactly or completely. This is somewhat acceptable because all
81 : : * implementations must be aware of all these features.
82 : : */
83 : : static const struct cpu_feature cpu_features_table[] = {
84 : : /*
85 : : * Big endian as in ISAv2.07B, MSR_LE=0
86 : : */
87 : : { "big-endian",
88 : : CPU_ALL,
89 : : ISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,
90 : : HV_CUSTOM, OS_CUSTOM,
91 : : -1, -1, -1,
92 : : NULL, },
93 : :
94 : : /*
95 : : * Little endian as in ISAv2.07B, MSR_LE=1.
96 : : *
97 : : * When both big and little endian are defined, there is an LPCR ILE
98 : : * bit and implementation specific way to switch HILE mode, MSR_SLE,
99 : : * etc.
100 : : */
101 : : { "little-endian",
102 : : CPU_ALL,
103 : : ISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,
104 : : HV_CUSTOM, OS_CUSTOM,
105 : : -1, -1, -1,
106 : : NULL, },
107 : :
108 : : /*
109 : : * MSR_HV=1 mode as in ISAv2.07B (i.e., hypervisor privileged
110 : : * instructions and registers).
111 : : */
112 : : { "hypervisor",
113 : : CPU_ALL,
114 : : ISA_BASE, USABLE_HV,
115 : : HV_CUSTOM, OS_NONE,
116 : : -1, -1, -1,
117 : : NULL, },
118 : :
119 : : /*
120 : : * ISAv2.07B interrupt vectors, registers, and control registers
121 : : * (e.g., AIL, ILE, HV, etc LPCR bits).
122 : : *
123 : : * This does not necessarily specify all possible interrupt types.
124 : : * floating-point, for example requires some ways to handle floating
125 : : * point exceptions, but the low level details of interrupt handler
126 : : * is not a dependency there. There will always be *some* interrupt
127 : : * handler, (and some way to provide memory magagement, etc.).
128 : : */
129 : : { "interrupt-facilities",
130 : : CPU_ALL,
131 : : ISA_BASE, USABLE_HV|USABLE_OS,
132 : : HV_CUSTOM, OS_CUSTOM,
133 : : -1, -1, -1,
134 : : NULL, },
135 : :
136 : : { "smt",
137 : : CPU_ALL,
138 : : ISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,
139 : : HV_CUSTOM, OS_CUSTOM,
140 : : -1, -1, 14,
141 : : NULL, },
142 : :
143 : : /*
144 : : * ISAv2.07B Program Priority Registers (PPR)
145 : : * PPR and associated control registers (e.g. RPR, PSPB),
146 : : * priority "or" instructions, etc.
147 : : */
148 : : { "program-priority-register",
149 : : CPU_ALL,
150 : : ISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,
151 : : HV_NONE, OS_NONE,
152 : : -1, -1, -1,
153 : : NULL, },
154 : :
155 : : /*
156 : : * ISAv2.07B Book3S Chapter 5.7.9.1. Virtual Page Class Key Protecion
157 : : * AMR, IAMR, AMOR, UAMOR, etc registers and MMU key bits.
158 : : */
159 : : { "virtual-page-class-key-protection",
160 : : CPU_ALL,
161 : : ISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,
162 : : HV_CUSTOM, OS_CUSTOM,
163 : : -1, -1, -1,
164 : : NULL, },
165 : :
166 : : /*
167 : : * ISAv2.07B SAO storage control attribute
168 : : */
169 : : { "strong-access-ordering",
170 : : CPU_ALL & ~CPU_P9_DD1,
171 : : ISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,
172 : : HV_CUSTOM, OS_CUSTOM,
173 : : -1, -1, -1,
174 : : NULL, },
175 : :
176 : : /*
177 : : * ISAv2.07B no-execute storage control attribute
178 : : */
179 : : { "no-execute",
180 : : CPU_ALL,
181 : : ISA_BASE, USABLE_HV|USABLE_OS,
182 : : HV_CUSTOM, OS_CUSTOM,
183 : : -1, -1, -1,
184 : : NULL, },
185 : :
186 : : /*
187 : : * Cache inhibited attribute supported on large pages.
188 : : */
189 : : { "cache-inhibited-large-page",
190 : : CPU_ALL,
191 : : ISA_BASE, USABLE_HV|USABLE_OS,
192 : : HV_CUSTOM, OS_CUSTOM,
193 : : -1, -1, -1,
194 : : NULL, },
195 : :
196 : : /*
197 : : * ISAv2.07B Book3S Chapter 8. Debug Facilities
198 : : * CIEA, CIABR, DEAW, MEte, trace interrupt, etc.
199 : : * Except CFAR, branch tracing.
200 : : */
201 : : { "debug-facilities",
202 : : CPU_ALL,
203 : : ISA_BASE, USABLE_HV|USABLE_OS,
204 : : HV_CUSTOM, OS_CUSTOM,
205 : : -1, -1, -1,
206 : : NULL, },
207 : :
208 : : /*
209 : : * DAWR1, DAWRX1 etc.
210 : : */
211 : : { "debug-facilities-v31",
212 : : CPU_P10|CPU_P11,
213 : : ISA_V3_1, USABLE_HV|USABLE_OS,
214 : : HV_CUSTOM, OS_CUSTOM,
215 : : -1, -1, -1,
216 : : NULL, },
217 : :
218 : : /*
219 : : * ISAv2.07B CFAR
220 : : */
221 : : { "come-from-address-register",
222 : : CPU_ALL,
223 : : ISA_BASE, USABLE_HV|USABLE_OS,
224 : : HV_CUSTOM, OS_CUSTOM,
225 : : -1, -1, -1,
226 : : "debug-facilities", },
227 : :
228 : : /*
229 : : * ISAv2.07B Branch tracing (optional in ISA)
230 : : */
231 : : { "branch-tracing",
232 : : CPU_ALL,
233 : : ISA_BASE, USABLE_HV|USABLE_OS,
234 : : HV_CUSTOM, OS_CUSTOM,
235 : : -1, -1, -1,
236 : : "debug-facilities", },
237 : :
238 : : /*
239 : : * ISAv2.07B Floating-point Facility
240 : : */
241 : : { "floating-point",
242 : : CPU_ALL,
243 : : ISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,
244 : : HV_CUSTOM, OS_CUSTOM,
245 : : PPC_BITLSHIFT(63), -1, 27,
246 : : NULL, },
247 : :
248 : : /*
249 : : * ISAv2.07B Vector Facility (VMX)
250 : : */
251 : : { "vector",
252 : : CPU_ALL,
253 : : ISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,
254 : : HV_CUSTOM, OS_CUSTOM,
255 : : PPC_BITLSHIFT(62), -1, 28,
256 : : "floating-point", },
257 : :
258 : : /*
259 : : * ISAv2.07B Vector-scalar Facility (VSX)
260 : : */
261 : : { "vector-scalar",
262 : : CPU_ALL,
263 : : ISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,
264 : : HV_CUSTOM, OS_CUSTOM,
265 : : -1, -1, 7,
266 : : "vector", },
267 : :
268 : : { "vector-crypto",
269 : : CPU_ALL,
270 : : ISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,
271 : : HV_NONE, OS_NONE,
272 : : -1, -1, 57,
273 : : "vector", },
274 : :
275 : : /*
276 : : * ISAv2.07B Quadword Load and Store instructions
277 : : * including lqarx/stdqcx. instructions.
278 : : */
279 : : { "quadword-load-store",
280 : : CPU_ALL,
281 : : ISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,
282 : : HV_NONE, OS_NONE,
283 : : -1, -1, -1,
284 : : NULL, },
285 : :
286 : : /*
287 : : * ISAv2.07B Binary Coded Decimal (BCD)
288 : : * BCD fixed point instructions
289 : : */
290 : : { "decimal-integer",
291 : : CPU_ALL,
292 : : ISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,
293 : : HV_NONE, OS_NONE,
294 : : -1, -1, -1,
295 : : NULL, },
296 : :
297 : : /*
298 : : * ISAv2.07B Decimal floating-point Facility (DFP)
299 : : */
300 : : { "decimal-floating-point",
301 : : CPU_ALL,
302 : : ISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,
303 : : HV_NONE, OS_NONE,
304 : : -1, -1, 10,
305 : : "floating-point", },
306 : :
307 : : /*
308 : : * ISAv2.07B
309 : : * DSCR, default data prefetch LPCR, etc
310 : : */
311 : : { "data-stream-control-register",
312 : : CPU_ALL,
313 : : ISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,
314 : : HV_CUSTOM, OS_CUSTOM,
315 : : PPC_BITLSHIFT(61), PPC_BITLSHIFT(61), 61,
316 : : NULL, },
317 : :
318 : : /*
319 : : * ISAv2.07B Branch History Rolling Buffer (BHRB)
320 : : */
321 : : { "branch-history-rolling-buffer",
322 : : CPU_ALL,
323 : : ISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,
324 : : HV_CUSTOM, OS_CUSTOM,
325 : : PPC_BITLSHIFT(59), -1, -1,
326 : : NULL, },
327 : :
328 : : /*
329 : : * ISAv2.07B Transactional Memory Facility (TM or HTM)
330 : : */
331 : : { "transactional-memory",
332 : : CPU_P8, /* P9 support is not enabled yet */
333 : : ISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,
334 : : HV_CUSTOM, OS_CUSTOM,
335 : : PPC_BITLSHIFT(58), -1, 62,
336 : : NULL, },
337 : :
338 : : /*
339 : : * ISAv3.0B TM additions
340 : : * TEXASR bit 17, self-induced vs external footprint overflow
341 : : */
342 : : { "transactional-memory-v3",
343 : : 0,
344 : : ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR,
345 : : HV_NONE, OS_NONE,
346 : : -1, -1, -1,
347 : : "transactional-memory", },
348 : :
349 : : /*
350 : : * ISAv2.07B Event-Based Branch Facility (EBB)
351 : : */
352 : : { "event-based-branch",
353 : : CPU_ALL,
354 : : ISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,
355 : : HV_CUSTOM, OS_CUSTOM,
356 : : PPC_BITLSHIFT(56), PPC_BITLSHIFT(56), 60,
357 : : NULL, },
358 : :
359 : : /*
360 : : * ISAv2.07B Target Address Register (TAR)
361 : : */
362 : : { "target-address-register",
363 : : CPU_ALL,
364 : : ISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,
365 : : HV_CUSTOM, OS_CUSTOM,
366 : : PPC_BITLSHIFT(55), PPC_BITLSHIFT(55), 58,
367 : : NULL, },
368 : :
369 : : /*
370 : : * ISAv2.07B Control Register (CTRL)
371 : : */
372 : : { "control-register",
373 : : CPU_ALL,
374 : : ISA_BASE, USABLE_HV|USABLE_OS,
375 : : HV_CUSTOM, OS_CUSTOM,
376 : : -1, -1, -1,
377 : : NULL, },
378 : :
379 : : /*
380 : : * ISAv2.07B Book3S Chapter 11. Processor Control.
381 : : * msgsnd, msgsndp, doorbell, etc.
382 : : *
383 : : * ISAv3.0B is not compatible (different addressing, HFSCR required
384 : : * for msgsndp).
385 : : */
386 : : { "processor-control-facility",
387 : : CPU_P8_DD2, /* P8 DD1 has no dbell */
388 : : ISA_BASE, USABLE_HV|USABLE_OS,
389 : : HV_CUSTOM, OS_CUSTOM,
390 : : -1, -1, -1,
391 : : NULL, },
392 : :
393 : : /*
394 : : * ISAv2.07B PURR, SPURR registers
395 : : */
396 : : { "processor-utilization-of-resources-register",
397 : : CPU_ALL,
398 : : ISA_BASE, USABLE_HV|USABLE_OS,
399 : : HV_CUSTOM, OS_CUSTOM,
400 : : -1, -1, -1,
401 : : NULL, },
402 : :
403 : : /*
404 : : * POWER8 initiate coprocessor store word indexed (icswx) instruction
405 : : */
406 : : { "coprocessor-icswx",
407 : : CPU_P8,
408 : : ISA_BASE, USABLE_HV|USABLE_OS,
409 : : HV_CUSTOM, OS_CUSTOM,
410 : : -1, -1, -1,
411 : : NULL, },
412 : :
413 : : /*
414 : : * ISAv2.07B hash based MMU and all instructions, registers,
415 : : * data structures, exceptions, etc.
416 : : */
417 : : { "mmu-hash",
418 : : CPU_P8,
419 : : ISA_BASE, USABLE_HV|USABLE_OS,
420 : : HV_CUSTOM, OS_CUSTOM,
421 : : -1, -1, -1,
422 : : NULL, },
423 : :
424 : : /*
425 : : * POWER8 MCE / machine check exception.
426 : : */
427 : : { "machine-check-power8",
428 : : CPU_P8,
429 : : ISA_BASE, USABLE_HV|USABLE_OS,
430 : : HV_CUSTOM, OS_CUSTOM,
431 : : -1, -1, -1,
432 : : NULL, },
433 : :
434 : : /*
435 : : * POWER8 PMU / performance monitor unit.
436 : : */
437 : : { "performance-monitor-power8",
438 : : CPU_P8,
439 : : ISA_BASE, USABLE_HV|USABLE_OS,
440 : : HV_CUSTOM, OS_CUSTOM,
441 : : -1, -1, -1,
442 : : NULL, },
443 : :
444 : : /*
445 : : * ISAv2.07B alignment interrupts set DSISR register
446 : : *
447 : : * POWER CPUs do not used this, and it's removed from ISAv3.0B.
448 : : */
449 : : { "alignment-interrupt-dsisr",
450 : : 0,
451 : : ISA_BASE, USABLE_HV|USABLE_OS,
452 : : HV_NONE, OS_NONE,
453 : : -1, -1, -1,
454 : : NULL, },
455 : :
456 : : /*
457 : : * ISAv2.07B / POWER8 doze, nap, sleep, winkle instructions
458 : : * XXX: is Linux we using some BookIV specific implementation details
459 : : * in nap handling? We have no POWER8 specific key here.
460 : : */
461 : : { "idle-nap",
462 : : CPU_P8,
463 : : ISA_BASE, USABLE_HV,
464 : : HV_CUSTOM, OS_NONE,
465 : : -1, -1, -1,
466 : : NULL, },
467 : :
468 : : /*
469 : : * ISAv2.07B wait instruction
470 : : */
471 : : { "wait",
472 : : CPU_P8,
473 : : ISA_BASE, USABLE_HV|USABLE_OS|USABLE_PR,
474 : : HV_NONE, OS_NONE,
475 : : -1, -1, -1,
476 : : NULL, },
477 : :
478 : : { "subcore",
479 : : CPU_P8,
480 : : ISA_BASE, USABLE_HV|USABLE_OS,
481 : : HV_CUSTOM, OS_CUSTOM,
482 : : -1, -1, -1,
483 : : "smt", },
484 : :
485 : : /*
486 : : * ISAv3.0B radix based MMU
487 : : */
488 : : { "mmu-radix",
489 : : CPU_P9|CPU_P10|CPU_P11,
490 : : ISA_V3_0B, USABLE_HV|USABLE_OS,
491 : : HV_CUSTOM, OS_CUSTOM,
492 : : -1, -1, -1,
493 : : NULL, },
494 : :
495 : : /*
496 : : * ISAv3.0B hash based MMU, new hash pte format, PCTR, etc
497 : : */
498 : : { "mmu-hash-v3",
499 : : CPU_P9|CPU_P10|CPU_P11,
500 : : ISA_V3_0B, USABLE_HV|USABLE_OS,
501 : : HV_CUSTOM, OS_CUSTOM,
502 : : -1, -1, -1,
503 : : NULL, },
504 : :
505 : : /*
506 : : * ISAv3.0B wait instruction
507 : : */
508 : : { "wait-v3",
509 : : CPU_P9|CPU_P10|CPU_P11,
510 : : ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR,
511 : : HV_NONE, OS_NONE,
512 : : -1, -1, -1,
513 : : NULL, },
514 : :
515 : : /*
516 : : * ISAv3.0B stop idle instructions and registers
517 : : * XXX: Same question as for idle-nap
518 : : */
519 : : { "idle-stop",
520 : : CPU_P9|CPU_P10|CPU_P11,
521 : : ISA_V3_0B, USABLE_HV|USABLE_OS,
522 : : HV_CUSTOM, OS_CUSTOM,
523 : : -1, -1, -1,
524 : : NULL, },
525 : :
526 : : /*
527 : : * ISAv3.0B Hypervisor Virtualization Interrupt
528 : : * Also associated system registers, LPCR EE, HEIC, HVICE,
529 : : * system reset SRR1 reason, etc.
530 : : */
531 : : { "hypervisor-virtualization-interrupt",
532 : : CPU_P9|CPU_P10|CPU_P11,
533 : : ISA_V3_0B, USABLE_HV,
534 : : HV_CUSTOM, OS_NONE,
535 : : -1, -1, -1,
536 : : NULL, },
537 : :
538 : : /*
539 : : * POWER9 MCE / machine check exception.
540 : : */
541 : : { "machine-check-power9",
542 : : CPU_P9,
543 : : ISA_V3_0B, USABLE_HV|USABLE_OS,
544 : : HV_CUSTOM, OS_CUSTOM,
545 : : -1, -1, -1,
546 : : NULL, },
547 : :
548 : : /*
549 : : * POWER10 MCE / machine check exception.
550 : : */
551 : : { "machine-check-power10",
552 : : CPU_P10|CPU_P11,
553 : : ISA_V3_0B, USABLE_HV|USABLE_OS,
554 : : HV_CUSTOM, OS_CUSTOM,
555 : : -1, -1, -1,
556 : : NULL, },
557 : :
558 : : /*
559 : : * POWER9 PMU / performance monitor unit.
560 : : */
561 : : { "performance-monitor-power9",
562 : : CPU_P9,
563 : : ISA_V3_0B, USABLE_HV|USABLE_OS,
564 : : HV_CUSTOM, OS_CUSTOM,
565 : : -1, -1, -1,
566 : : NULL, },
567 : :
568 : : /*
569 : : * POWER10 PMU / performance monitor unit.
570 : : */
571 : : { "performance-monitor-power10",
572 : : CPU_P10|CPU_P11,
573 : : ISA_V3_1, USABLE_HV|USABLE_OS,
574 : : HV_CUSTOM, OS_CUSTOM,
575 : : -1, -1, -1,
576 : : NULL, },
577 : :
578 : : /*
579 : : * ISAv3.0B scv/rfscv system call instructions and exceptions, fscr bit
580 : : * etc.
581 : : */
582 : : { "system-call-vectored",
583 : : CPU_P9|CPU_P10|CPU_P11,
584 : : ISA_V3_0B, USABLE_OS|USABLE_PR,
585 : : HV_NONE, OS_CUSTOM,
586 : : -1, PPC_BITLSHIFT(51), 52,
587 : : NULL, },
588 : :
589 : : /*
590 : : * ISAv3.0B Book3S Chapter 10. Processor Control.
591 : : * global msgsnd, msgsndp, msgsync, doorbell, etc.
592 : : */
593 : : { "processor-control-facility-v3",
594 : : CPU_P9|CPU_P10|CPU_P11,
595 : : ISA_V3_0B, USABLE_HV|USABLE_OS,
596 : : HV_CUSTOM, OS_NONE,
597 : : PPC_BITLSHIFT(53), -1, -1,
598 : : NULL, },
599 : :
600 : : /*
601 : : * ISAv3.0B addpcis instruction
602 : : */
603 : : { "pc-relative-addressing",
604 : : CPU_P9|CPU_P10|CPU_P11,
605 : : ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR,
606 : : HV_NONE, OS_NONE,
607 : : -1, -1, -1,
608 : : NULL, },
609 : :
610 : : /*
611 : : * ISAv2.07B Book3S Chapter 7. Timer Facilities
612 : : * TB, VTB, DEC, HDEC, IC, etc registers and exceptions.
613 : : * Not including PURR or SPURR registers.
614 : : */
615 : : { "timer-facilities",
616 : : CPU_ALL,
617 : : ISA_BASE, USABLE_HV|USABLE_OS,
618 : : HV_NONE, OS_NONE,
619 : : -1, -1, -1,
620 : : NULL, },
621 : :
622 : : /*
623 : : * ISAv3.0B Book3S Chapter 7. Timer Facilities
624 : : * Large decrementer and hypervisor decrementer
625 : : */
626 : : { "timer-facilities-v3",
627 : : CPU_P9|CPU_P10|CPU_P11,
628 : : ISA_V3_0B, USABLE_HV|USABLE_OS,
629 : : HV_NONE, OS_NONE,
630 : : -1, -1, -1,
631 : : "timer-facilities", },
632 : :
633 : : /*
634 : : * ISAv3.0B deliver a random number instruction (darn)
635 : : */
636 : : { "random-number-generator",
637 : : CPU_P9|CPU_P10|CPU_P11,
638 : : ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR,
639 : : HV_NONE, OS_NONE,
640 : : -1, -1, 53,
641 : : NULL, },
642 : :
643 : : /*
644 : : * ISAv3.0B fixed point instructions and registers
645 : : * multiply-add, modulo, count trailing zeroes, cmprb, cmpeqb,
646 : : * extswsli, mfvsrld, mtvsrdd, mtvsrws, addex, CA32, OV32,
647 : : * mcrxrx, setb
648 : : */
649 : : { "fixed-point-v3",
650 : : CPU_P9|CPU_P10|CPU_P11,
651 : : ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR,
652 : : HV_NONE, OS_NONE,
653 : : -1, -1, -1,
654 : : NULL, },
655 : :
656 : : { "decimal-integer-v3",
657 : : CPU_P9|CPU_P10|CPU_P11,
658 : : ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR,
659 : : HV_NONE, OS_NONE,
660 : : -1, -1, -1,
661 : : "fixed-point-v3 decimal-integer", },
662 : :
663 : : /*
664 : : * ISAv3.0B lightweight mffs
665 : : */
666 : : { "floating-point-v3",
667 : : CPU_P9|CPU_P10|CPU_P11,
668 : : ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR,
669 : : HV_NONE, OS_NONE,
670 : : -1, -1, -1,
671 : : "floating-point", },
672 : :
673 : : { "decimal-floating-point-v3",
674 : : CPU_P9|CPU_P10|CPU_P11,
675 : : ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR,
676 : : HV_NONE, OS_NONE,
677 : : -1, -1, -1,
678 : : "floating-point-v3 decimal-floating-point", },
679 : :
680 : : { "vector-v3",
681 : : CPU_P9|CPU_P10|CPU_P11,
682 : : ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR,
683 : : HV_NONE, OS_NONE,
684 : : -1, -1, -1,
685 : : "vector", },
686 : :
687 : : { "vector-scalar-v3",
688 : : CPU_P9|CPU_P10|CPU_P11,
689 : : ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR,
690 : : HV_NONE, OS_NONE,
691 : : -1, -1, -1,
692 : : "vector-v3 vector-scalar" },
693 : :
694 : : { "vector-binary128",
695 : : CPU_P9|CPU_P10|CPU_P11,
696 : : ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR,
697 : : HV_NONE, OS_NONE,
698 : : -1, -1, 54,
699 : : "vector-scalar-v3", },
700 : :
701 : : { "vector-binary16",
702 : : CPU_P9|CPU_P10|CPU_P11,
703 : : ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR,
704 : : HV_NONE, OS_NONE,
705 : : -1, -1, -1,
706 : : "vector-v3", },
707 : :
708 : : /*
709 : : * ISAv3.0B external exception for EBB
710 : : */
711 : : { "event-based-branch-v3",
712 : : CPU_P9|CPU_P10|CPU_P11,
713 : : ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR,
714 : : HV_NONE, OS_NONE,
715 : : -1, -1, -1,
716 : : "event-based-branch", },
717 : :
718 : : /*
719 : : * ISAv3.0B Atomic Memory Operations (AMO)
720 : : */
721 : : { "atomic-memory-operations",
722 : : CPU_P9|CPU_P10|CPU_P11,
723 : : ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR,
724 : : HV_NONE, OS_NONE,
725 : : -1, -1, -1,
726 : : NULL, },
727 : :
728 : : /*
729 : : * ISAv3.0B Copy-Paste Facility
730 : : */
731 : : { "copy-paste",
732 : : CPU_P9|CPU_P10|CPU_P11,
733 : : ISA_V3_0B, USABLE_HV|USABLE_OS|USABLE_PR,
734 : : HV_NONE, OS_NONE,
735 : : -1, -1, -1,
736 : : NULL, },
737 : :
738 : : /*
739 : : * ISAv3.0B GSR SPR register
740 : : * POWER9 does not implement it
741 : : */
742 : : { "group-start-register",
743 : : 0,
744 : : ISA_V3_0B, USABLE_HV|USABLE_OS,
745 : : HV_NONE, OS_NONE,
746 : : -1, -1, -1,
747 : : NULL, },
748 : :
749 : : /*
750 : : * Enable matrix multiply accumulate.
751 : : */
752 : : { "matrix-multiply-accumulate",
753 : : CPU_P10|CPU_P11,
754 : : ISA_V3_1, USABLE_PR,
755 : : HV_CUSTOM, OS_CUSTOM,
756 : : -1, -1, 49,
757 : : NULL, },
758 : :
759 : : /*
760 : : * Enable prefix instructions. Toolchains assume this is
761 : : * enabled for when compiling for ISA 3.1.
762 : : */
763 : : { "prefix-instructions",
764 : : CPU_P10|CPU_P11,
765 : : ISA_V3_1, USABLE_HV|USABLE_OS|USABLE_PR,
766 : : HV_HFSCR, OS_FSCR,
767 : : 13, 13, -1,
768 : : NULL, },
769 : :
770 : : /*
771 : : * Due to hardware bugs in POWER9, the hypervisor needs to assist
772 : : * guests.
773 : : *
774 : : * Presence of this feature indicates presence of the bug.
775 : : *
776 : : * See linux kernel commit 4bb3c7a0208f
777 : : * and linux Documentation/powerpc/transactional_memory.txt
778 : : */
779 : : { "tm-suspend-hypervisor-assist",
780 : : CPU_P9_DD2_2|CPU_P9_DD2_3|CPU_P9P,
781 : : ISA_V3_0B, USABLE_HV,
782 : : HV_CUSTOM, OS_NONE,
783 : : -1, -1, -1,
784 : : NULL, },
785 : :
786 : : /*
787 : : * Due to hardware bugs in POWER9, the hypervisor can hit
788 : : * CPU bugs in the operations it needs to do for
789 : : * tm-suspend-hypervisor-assist.
790 : : *
791 : : * Presence of this "feature" means processor is affected by the bug.
792 : : *
793 : : * See linux kernel commit 4bb3c7a0208f
794 : : * and linux Documentation/powerpc/transactional_memory.txt
795 : : */
796 : : { "tm-suspend-xer-so-bug",
797 : : CPU_P9_DD2_2,
798 : : ISA_V3_0B, USABLE_HV,
799 : : HV_CUSTOM, OS_NONE,
800 : : -1, -1, -1,
801 : : NULL, },
802 : : };
803 : :
804 : 432 : static void add_cpu_feature_nodeps(struct dt_node *features,
805 : : const struct cpu_feature *f)
806 : : {
807 : : struct dt_node *feature;
808 : :
809 : 432 : feature = dt_new(features, f->name);
810 : 432 : assert(feature);
811 : :
812 : 432 : dt_add_property_cells(feature, "isa", f->isa);
813 : 432 : dt_add_property_cells(feature, "usable-privilege", f->usable_privilege);
814 : :
815 : 432 : if (f->usable_privilege & USABLE_HV) {
816 : 427 : if (f->hv_support != HV_NONE) {
817 : 287 : uint32_t s = 0;
818 : 287 : if (f->hv_support == HV_HFSCR)
819 : 0 : s |= HV_SUPPORT_HFSCR;
820 : :
821 : 287 : dt_add_property_cells(feature, "hv-support", s);
822 : 287 : if (f->hfscr_bit_nr != -1)
823 : 70 : dt_add_property_cells(feature, "hfscr-bit-nr", f->hfscr_bit_nr);
824 : : } else {
825 : 140 : assert(f->hfscr_bit_nr == -1);
826 : : }
827 : : }
828 : :
829 : 432 : if (f->usable_privilege & USABLE_OS) {
830 : 408 : if (f->os_support != OS_NONE) {
831 : 263 : uint32_t s = 0;
832 : 263 : if (f->os_support == OS_FSCR)
833 : 0 : s |= OS_SUPPORT_FSCR;
834 : 263 : dt_add_property_cells(feature, "os-support", s);
835 : 263 : if (f->fscr_bit_nr != -1)
836 : 35 : dt_add_property_cells(feature, "fscr-bit-nr", f->fscr_bit_nr);
837 : : } else {
838 : 145 : assert(f->fscr_bit_nr == -1);
839 : : }
840 : : }
841 : :
842 : 432 : if (f->usable_privilege & USABLE_PR) {
843 : 255 : if (f->hwcap_bit_nr != -1)
844 : 110 : dt_add_property_cells(feature, "hwcap-bit-nr", f->hwcap_bit_nr);
845 : : }
846 : :
847 : 432 : if (f->dependencies_names)
848 : 110 : dt_add_property(feature, "dependencies", NULL, 0);
849 : 432 : }
850 : :
851 : 10 : static void add_cpufeatures_dependencies(struct dt_node *features)
852 : : {
853 : : struct dt_node *feature;
854 : :
855 : 442 : dt_for_each_node(features, feature) {
856 : 432 : const struct cpu_feature *f = NULL;
857 : : const char *deps_names;
858 : : struct dt_property *deps;
859 : : int nr_deps;
860 : : int i;
861 : :
862 : : /* Find features with dependencies */
863 : :
864 : 432 : deps = __dt_find_property(feature, "dependencies");
865 : 432 : if (!deps)
866 : 322 : continue;
867 : :
868 : : /* Find the matching cpu table */
869 : 3780 : for (i = 0; i < ARRAY_SIZE(cpu_features_table); i++) {
870 : 3780 : f = &cpu_features_table[i];
871 : 3780 : if (!strcmp(f->name, feature->name))
872 : 110 : break;
873 : : }
874 : 110 : assert(f);
875 : 110 : assert(f->dependencies_names);
876 : :
877 : : /*
878 : : * Count number of depended features and allocate space
879 : : * for phandles in the property.
880 : : */
881 : 110 : deps_names = f->dependencies_names;
882 : 110 : nr_deps = strcount(deps_names, " ") + 1;
883 : 110 : dt_resize_property(&deps, nr_deps * sizeof(u32));
884 : :
885 : 110 : DBG("feature %s has %d dependencies (%s)\n", f->name, nr_deps, deps_names);
886 : : /*
887 : : * For each one, find the depended feature then advance to
888 : : * next name.
889 : : */
890 : 235 : for (i = 0; i < nr_deps; i++) {
891 : : struct dt_node *dep;
892 : : int len;
893 : :
894 : 125 : if (nr_deps - i == 1)
895 : 110 : len = strlen(deps_names);
896 : : else
897 : 15 : len = strchr(deps_names, ' ') - deps_names;
898 : :
899 : 3212 : dt_for_each_node(features, dep) {
900 : 3212 : if (!strncmp(deps_names, dep->name, len))
901 : 125 : goto found_dep;
902 : : }
903 : :
904 : 0 : prlog(PR_ERR, "CPUFT: feature %s dependencies not found\n", f->name);
905 : 0 : break;
906 : 125 : found_dep:
907 : 125 : DBG(" %s found dep (%s)\n", f->name, dep->name);
908 : 125 : dt_property_set_cell(deps, i, dep->phandle);
909 : :
910 : : /* Advance over the name + delimiter */
911 : 125 : deps_names += len + 1;
912 : : }
913 : : }
914 : 10 : }
915 : :
916 : 10 : static void add_cpufeatures(struct dt_node *cpus,
917 : : uint32_t cpu_feature_isa, uint32_t cpu_feature_cpu,
918 : : const char *cpu_name)
919 : : {
920 : : struct dt_node *features;
921 : : int i;
922 : :
923 : 10 : DBG("creating cpufeatures for cpu:%d isa:%d\n", cpu_feature_cpu, cpu_feature_isa);
924 : :
925 : 10 : features = dt_new(cpus, "ibm,powerpc-cpu-features");
926 : 10 : assert(features);
927 : :
928 : 10 : dt_add_property_cells(features, "isa", cpu_feature_isa);
929 : :
930 : 10 : dt_add_property_string(features, "device_type", "cpu-features");
931 : 10 : dt_add_property_string(features, "compatible", "ibm,powerpc-cpu-features");
932 : 10 : dt_add_property_string(features, "display-name", cpu_name);
933 : :
934 : : /* add without dependencies */
935 : 700 : for (i = 0; i < ARRAY_SIZE(cpu_features_table); i++) {
936 : 690 : const struct cpu_feature *f = &cpu_features_table[i];
937 : :
938 : 690 : if (f->cpus_supported & cpu_feature_cpu) {
939 : 432 : DBG(" '%s'\n", f->name);
940 : 432 : add_cpu_feature_nodeps(features, f);
941 : : }
942 : : }
943 : :
944 : : /* dependency construction pass */
945 : 10 : add_cpufeatures_dependencies(features);
946 : 10 : }
947 : :
948 : 11 : void dt_add_cpufeatures(struct dt_node *root)
949 : : {
950 : : int version;
951 : 11 : uint32_t cpu_feature_isa = 0;
952 : 11 : uint32_t cpu_feature_cpu = 0;
953 : : struct dt_node *cpus;
954 : 11 : const char *cpu_name = NULL;
955 : :
956 : 11 : version = mfspr(SPR_PVR);
957 : 11 : switch(PVR_TYPE(version)) {
958 : 2 : case PVR_TYPE_P8:
959 : 2 : if (!cpu_name)
960 : 2 : cpu_name = "POWER8";
961 : : /* fallthrough */
962 : : case PVR_TYPE_P8E:
963 : 4 : if (!cpu_name)
964 : 2 : cpu_name = "POWER8E";
965 : : /* fallthrough */
966 : 4 : cpu_feature_isa = ISA_V2_07B;
967 : 4 : if (PVR_VERS_MAJ(version) == 1)
968 : 2 : cpu_feature_cpu = CPU_P8_DD1;
969 : : else
970 : 2 : cpu_feature_cpu = CPU_P8_DD2;
971 : 4 : break;
972 : 1 : case PVR_TYPE_P8NVL:
973 : 1 : cpu_name = "POWER8NVL";
974 : 1 : cpu_feature_isa = ISA_V2_07B;
975 : 1 : cpu_feature_cpu = CPU_P8_DD2;
976 : 1 : break;
977 : 4 : case PVR_TYPE_P9:
978 : 4 : if (!cpu_name)
979 : 4 : cpu_name = "POWER9";
980 : :
981 : 4 : cpu_feature_isa = ISA_V3_0B;
982 : 4 : if (is_power9n(version) &&
983 : 4 : (PVR_VERS_MAJ(version) == 2)) {
984 : : /* P9N DD2.x */
985 : 4 : switch (PVR_VERS_MIN(version)) {
986 : 2 : case 0:
987 : : case 1:
988 : 2 : cpu_feature_cpu = CPU_P9_DD2_0_1;
989 : 2 : break;
990 : 1 : case 2:
991 : 1 : cpu_feature_cpu = CPU_P9_DD2_2;
992 : 1 : break;
993 : 1 : case 3:
994 : 1 : cpu_feature_cpu = CPU_P9_DD2_3;
995 : 1 : break;
996 : 0 : default:
997 : 0 : assert(0);
998 : : }
999 : 0 : } else if (is_power9c(version) &&
1000 : 0 : (PVR_VERS_MAJ(version) == 1)) {
1001 : : /* P9C DD1.x */
1002 : 0 : switch (PVR_VERS_MIN(version)) {
1003 : 0 : case 1:
1004 : : /* Cumulus DD1.1 => Nimbus DD2.1 */
1005 : 0 : cpu_feature_cpu = CPU_P9_DD2_0_1;
1006 : 0 : break;
1007 : 0 : case 2:
1008 : : /* Cumulus DD1.2 */
1009 : 0 : cpu_feature_cpu = CPU_P9_DD2_2;
1010 : 0 : break;
1011 : 0 : case 3:
1012 : : /* Cumulus DD1.3 */
1013 : 0 : cpu_feature_cpu = CPU_P9_DD2_3;
1014 : 0 : break;
1015 : 0 : default:
1016 : 0 : assert(0);
1017 : : }
1018 : : } else {
1019 : 0 : assert(0);
1020 : : }
1021 : :
1022 : 4 : break;
1023 : 1 : case PVR_TYPE_P9P:
1024 : 1 : if (!cpu_name)
1025 : 1 : cpu_name = "POWER9P";
1026 : :
1027 : 1 : cpu_feature_isa = ISA_V3_0B;
1028 : 1 : cpu_feature_cpu = CPU_P9P;
1029 : 1 : break;
1030 : 0 : case PVR_TYPE_P10:
1031 : 0 : if (!cpu_name)
1032 : 0 : cpu_name = "POWER10";
1033 : :
1034 : 0 : cpu_feature_isa = ISA_V3_1;
1035 : 0 : cpu_feature_cpu = CPU_P10;
1036 : 0 : break;
1037 : 0 : case PVR_TYPE_P11:
1038 : 0 : if (!cpu_name)
1039 : 0 : cpu_name = "Power11";
1040 : :
1041 : 0 : cpu_feature_isa = ISA_V3_1;
1042 : 0 : cpu_feature_cpu = CPU_P11;
1043 : 0 : break;
1044 : 1 : default:
1045 : 1 : return;
1046 : : }
1047 : :
1048 : 10 : cpus = dt_new_check(root, "cpus");
1049 : :
1050 : 10 : add_cpufeatures(cpus, cpu_feature_isa, cpu_feature_cpu, cpu_name);
1051 : : }
|