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