1 // SPDX-License-Identifier: GPL-2.0
2 #include <errno.h>
3 #include <string.h>
4 #include "perf_regs.h"
5 #include "event.h"
6
arch_sdt_arg_parse_op(char * old_op __maybe_unused,char ** new_op __maybe_unused)7 int __weak arch_sdt_arg_parse_op(char *old_op __maybe_unused,
8 char **new_op __maybe_unused)
9 {
10 return SDT_ARG_SKIP;
11 }
12
arch__intr_reg_mask(void)13 uint64_t __weak arch__intr_reg_mask(void)
14 {
15 return PERF_REGS_MASK;
16 }
17
arch__user_reg_mask(void)18 uint64_t __weak arch__user_reg_mask(void)
19 {
20 return PERF_REGS_MASK;
21 }
22
23 #ifdef HAVE_PERF_REGS_SUPPORT
24
25 #define perf_event_arm_regs perf_event_arm64_regs
26 #include "../../arch/arm64/include/uapi/asm/perf_regs.h"
27 #undef perf_event_arm_regs
28
29 #include "../../arch/arm/include/uapi/asm/perf_regs.h"
30 #include "../../arch/csky/include/uapi/asm/perf_regs.h"
31 #include "../../arch/mips/include/uapi/asm/perf_regs.h"
32 #include "../../arch/powerpc/include/uapi/asm/perf_regs.h"
33 #include "../../arch/riscv/include/uapi/asm/perf_regs.h"
34 #include "../../arch/s390/include/uapi/asm/perf_regs.h"
35 #include "../../arch/x86/include/uapi/asm/perf_regs.h"
36
__perf_reg_name_arm64(int id)37 static const char *__perf_reg_name_arm64(int id)
38 {
39 switch (id) {
40 case PERF_REG_ARM64_X0:
41 return "x0";
42 case PERF_REG_ARM64_X1:
43 return "x1";
44 case PERF_REG_ARM64_X2:
45 return "x2";
46 case PERF_REG_ARM64_X3:
47 return "x3";
48 case PERF_REG_ARM64_X4:
49 return "x4";
50 case PERF_REG_ARM64_X5:
51 return "x5";
52 case PERF_REG_ARM64_X6:
53 return "x6";
54 case PERF_REG_ARM64_X7:
55 return "x7";
56 case PERF_REG_ARM64_X8:
57 return "x8";
58 case PERF_REG_ARM64_X9:
59 return "x9";
60 case PERF_REG_ARM64_X10:
61 return "x10";
62 case PERF_REG_ARM64_X11:
63 return "x11";
64 case PERF_REG_ARM64_X12:
65 return "x12";
66 case PERF_REG_ARM64_X13:
67 return "x13";
68 case PERF_REG_ARM64_X14:
69 return "x14";
70 case PERF_REG_ARM64_X15:
71 return "x15";
72 case PERF_REG_ARM64_X16:
73 return "x16";
74 case PERF_REG_ARM64_X17:
75 return "x17";
76 case PERF_REG_ARM64_X18:
77 return "x18";
78 case PERF_REG_ARM64_X19:
79 return "x19";
80 case PERF_REG_ARM64_X20:
81 return "x20";
82 case PERF_REG_ARM64_X21:
83 return "x21";
84 case PERF_REG_ARM64_X22:
85 return "x22";
86 case PERF_REG_ARM64_X23:
87 return "x23";
88 case PERF_REG_ARM64_X24:
89 return "x24";
90 case PERF_REG_ARM64_X25:
91 return "x25";
92 case PERF_REG_ARM64_X26:
93 return "x26";
94 case PERF_REG_ARM64_X27:
95 return "x27";
96 case PERF_REG_ARM64_X28:
97 return "x28";
98 case PERF_REG_ARM64_X29:
99 return "x29";
100 case PERF_REG_ARM64_SP:
101 return "sp";
102 case PERF_REG_ARM64_LR:
103 return "lr";
104 case PERF_REG_ARM64_PC:
105 return "pc";
106 case PERF_REG_ARM64_VG:
107 return "vg";
108 default:
109 return NULL;
110 }
111
112 return NULL;
113 }
114
__perf_reg_name_arm(int id)115 static const char *__perf_reg_name_arm(int id)
116 {
117 switch (id) {
118 case PERF_REG_ARM_R0:
119 return "r0";
120 case PERF_REG_ARM_R1:
121 return "r1";
122 case PERF_REG_ARM_R2:
123 return "r2";
124 case PERF_REG_ARM_R3:
125 return "r3";
126 case PERF_REG_ARM_R4:
127 return "r4";
128 case PERF_REG_ARM_R5:
129 return "r5";
130 case PERF_REG_ARM_R6:
131 return "r6";
132 case PERF_REG_ARM_R7:
133 return "r7";
134 case PERF_REG_ARM_R8:
135 return "r8";
136 case PERF_REG_ARM_R9:
137 return "r9";
138 case PERF_REG_ARM_R10:
139 return "r10";
140 case PERF_REG_ARM_FP:
141 return "fp";
142 case PERF_REG_ARM_IP:
143 return "ip";
144 case PERF_REG_ARM_SP:
145 return "sp";
146 case PERF_REG_ARM_LR:
147 return "lr";
148 case PERF_REG_ARM_PC:
149 return "pc";
150 default:
151 return NULL;
152 }
153
154 return NULL;
155 }
156
__perf_reg_name_csky(int id)157 static const char *__perf_reg_name_csky(int id)
158 {
159 switch (id) {
160 case PERF_REG_CSKY_A0:
161 return "a0";
162 case PERF_REG_CSKY_A1:
163 return "a1";
164 case PERF_REG_CSKY_A2:
165 return "a2";
166 case PERF_REG_CSKY_A3:
167 return "a3";
168 case PERF_REG_CSKY_REGS0:
169 return "regs0";
170 case PERF_REG_CSKY_REGS1:
171 return "regs1";
172 case PERF_REG_CSKY_REGS2:
173 return "regs2";
174 case PERF_REG_CSKY_REGS3:
175 return "regs3";
176 case PERF_REG_CSKY_REGS4:
177 return "regs4";
178 case PERF_REG_CSKY_REGS5:
179 return "regs5";
180 case PERF_REG_CSKY_REGS6:
181 return "regs6";
182 case PERF_REG_CSKY_REGS7:
183 return "regs7";
184 case PERF_REG_CSKY_REGS8:
185 return "regs8";
186 case PERF_REG_CSKY_REGS9:
187 return "regs9";
188 case PERF_REG_CSKY_SP:
189 return "sp";
190 case PERF_REG_CSKY_LR:
191 return "lr";
192 case PERF_REG_CSKY_PC:
193 return "pc";
194 #if defined(__CSKYABIV2__)
195 case PERF_REG_CSKY_EXREGS0:
196 return "exregs0";
197 case PERF_REG_CSKY_EXREGS1:
198 return "exregs1";
199 case PERF_REG_CSKY_EXREGS2:
200 return "exregs2";
201 case PERF_REG_CSKY_EXREGS3:
202 return "exregs3";
203 case PERF_REG_CSKY_EXREGS4:
204 return "exregs4";
205 case PERF_REG_CSKY_EXREGS5:
206 return "exregs5";
207 case PERF_REG_CSKY_EXREGS6:
208 return "exregs6";
209 case PERF_REG_CSKY_EXREGS7:
210 return "exregs7";
211 case PERF_REG_CSKY_EXREGS8:
212 return "exregs8";
213 case PERF_REG_CSKY_EXREGS9:
214 return "exregs9";
215 case PERF_REG_CSKY_EXREGS10:
216 return "exregs10";
217 case PERF_REG_CSKY_EXREGS11:
218 return "exregs11";
219 case PERF_REG_CSKY_EXREGS12:
220 return "exregs12";
221 case PERF_REG_CSKY_EXREGS13:
222 return "exregs13";
223 case PERF_REG_CSKY_EXREGS14:
224 return "exregs14";
225 case PERF_REG_CSKY_TLS:
226 return "tls";
227 case PERF_REG_CSKY_HI:
228 return "hi";
229 case PERF_REG_CSKY_LO:
230 return "lo";
231 #endif
232 default:
233 return NULL;
234 }
235
236 return NULL;
237 }
238
__perf_reg_name_mips(int id)239 static const char *__perf_reg_name_mips(int id)
240 {
241 switch (id) {
242 case PERF_REG_MIPS_PC:
243 return "PC";
244 case PERF_REG_MIPS_R1:
245 return "$1";
246 case PERF_REG_MIPS_R2:
247 return "$2";
248 case PERF_REG_MIPS_R3:
249 return "$3";
250 case PERF_REG_MIPS_R4:
251 return "$4";
252 case PERF_REG_MIPS_R5:
253 return "$5";
254 case PERF_REG_MIPS_R6:
255 return "$6";
256 case PERF_REG_MIPS_R7:
257 return "$7";
258 case PERF_REG_MIPS_R8:
259 return "$8";
260 case PERF_REG_MIPS_R9:
261 return "$9";
262 case PERF_REG_MIPS_R10:
263 return "$10";
264 case PERF_REG_MIPS_R11:
265 return "$11";
266 case PERF_REG_MIPS_R12:
267 return "$12";
268 case PERF_REG_MIPS_R13:
269 return "$13";
270 case PERF_REG_MIPS_R14:
271 return "$14";
272 case PERF_REG_MIPS_R15:
273 return "$15";
274 case PERF_REG_MIPS_R16:
275 return "$16";
276 case PERF_REG_MIPS_R17:
277 return "$17";
278 case PERF_REG_MIPS_R18:
279 return "$18";
280 case PERF_REG_MIPS_R19:
281 return "$19";
282 case PERF_REG_MIPS_R20:
283 return "$20";
284 case PERF_REG_MIPS_R21:
285 return "$21";
286 case PERF_REG_MIPS_R22:
287 return "$22";
288 case PERF_REG_MIPS_R23:
289 return "$23";
290 case PERF_REG_MIPS_R24:
291 return "$24";
292 case PERF_REG_MIPS_R25:
293 return "$25";
294 case PERF_REG_MIPS_R28:
295 return "$28";
296 case PERF_REG_MIPS_R29:
297 return "$29";
298 case PERF_REG_MIPS_R30:
299 return "$30";
300 case PERF_REG_MIPS_R31:
301 return "$31";
302 default:
303 break;
304 }
305 return NULL;
306 }
307
__perf_reg_name_powerpc(int id)308 static const char *__perf_reg_name_powerpc(int id)
309 {
310 switch (id) {
311 case PERF_REG_POWERPC_R0:
312 return "r0";
313 case PERF_REG_POWERPC_R1:
314 return "r1";
315 case PERF_REG_POWERPC_R2:
316 return "r2";
317 case PERF_REG_POWERPC_R3:
318 return "r3";
319 case PERF_REG_POWERPC_R4:
320 return "r4";
321 case PERF_REG_POWERPC_R5:
322 return "r5";
323 case PERF_REG_POWERPC_R6:
324 return "r6";
325 case PERF_REG_POWERPC_R7:
326 return "r7";
327 case PERF_REG_POWERPC_R8:
328 return "r8";
329 case PERF_REG_POWERPC_R9:
330 return "r9";
331 case PERF_REG_POWERPC_R10:
332 return "r10";
333 case PERF_REG_POWERPC_R11:
334 return "r11";
335 case PERF_REG_POWERPC_R12:
336 return "r12";
337 case PERF_REG_POWERPC_R13:
338 return "r13";
339 case PERF_REG_POWERPC_R14:
340 return "r14";
341 case PERF_REG_POWERPC_R15:
342 return "r15";
343 case PERF_REG_POWERPC_R16:
344 return "r16";
345 case PERF_REG_POWERPC_R17:
346 return "r17";
347 case PERF_REG_POWERPC_R18:
348 return "r18";
349 case PERF_REG_POWERPC_R19:
350 return "r19";
351 case PERF_REG_POWERPC_R20:
352 return "r20";
353 case PERF_REG_POWERPC_R21:
354 return "r21";
355 case PERF_REG_POWERPC_R22:
356 return "r22";
357 case PERF_REG_POWERPC_R23:
358 return "r23";
359 case PERF_REG_POWERPC_R24:
360 return "r24";
361 case PERF_REG_POWERPC_R25:
362 return "r25";
363 case PERF_REG_POWERPC_R26:
364 return "r26";
365 case PERF_REG_POWERPC_R27:
366 return "r27";
367 case PERF_REG_POWERPC_R28:
368 return "r28";
369 case PERF_REG_POWERPC_R29:
370 return "r29";
371 case PERF_REG_POWERPC_R30:
372 return "r30";
373 case PERF_REG_POWERPC_R31:
374 return "r31";
375 case PERF_REG_POWERPC_NIP:
376 return "nip";
377 case PERF_REG_POWERPC_MSR:
378 return "msr";
379 case PERF_REG_POWERPC_ORIG_R3:
380 return "orig_r3";
381 case PERF_REG_POWERPC_CTR:
382 return "ctr";
383 case PERF_REG_POWERPC_LINK:
384 return "link";
385 case PERF_REG_POWERPC_XER:
386 return "xer";
387 case PERF_REG_POWERPC_CCR:
388 return "ccr";
389 case PERF_REG_POWERPC_SOFTE:
390 return "softe";
391 case PERF_REG_POWERPC_TRAP:
392 return "trap";
393 case PERF_REG_POWERPC_DAR:
394 return "dar";
395 case PERF_REG_POWERPC_DSISR:
396 return "dsisr";
397 case PERF_REG_POWERPC_SIER:
398 return "sier";
399 case PERF_REG_POWERPC_MMCRA:
400 return "mmcra";
401 case PERF_REG_POWERPC_MMCR0:
402 return "mmcr0";
403 case PERF_REG_POWERPC_MMCR1:
404 return "mmcr1";
405 case PERF_REG_POWERPC_MMCR2:
406 return "mmcr2";
407 case PERF_REG_POWERPC_MMCR3:
408 return "mmcr3";
409 case PERF_REG_POWERPC_SIER2:
410 return "sier2";
411 case PERF_REG_POWERPC_SIER3:
412 return "sier3";
413 case PERF_REG_POWERPC_PMC1:
414 return "pmc1";
415 case PERF_REG_POWERPC_PMC2:
416 return "pmc2";
417 case PERF_REG_POWERPC_PMC3:
418 return "pmc3";
419 case PERF_REG_POWERPC_PMC4:
420 return "pmc4";
421 case PERF_REG_POWERPC_PMC5:
422 return "pmc5";
423 case PERF_REG_POWERPC_PMC6:
424 return "pmc6";
425 case PERF_REG_POWERPC_SDAR:
426 return "sdar";
427 case PERF_REG_POWERPC_SIAR:
428 return "siar";
429 default:
430 break;
431 }
432 return NULL;
433 }
434
__perf_reg_name_riscv(int id)435 static const char *__perf_reg_name_riscv(int id)
436 {
437 switch (id) {
438 case PERF_REG_RISCV_PC:
439 return "pc";
440 case PERF_REG_RISCV_RA:
441 return "ra";
442 case PERF_REG_RISCV_SP:
443 return "sp";
444 case PERF_REG_RISCV_GP:
445 return "gp";
446 case PERF_REG_RISCV_TP:
447 return "tp";
448 case PERF_REG_RISCV_T0:
449 return "t0";
450 case PERF_REG_RISCV_T1:
451 return "t1";
452 case PERF_REG_RISCV_T2:
453 return "t2";
454 case PERF_REG_RISCV_S0:
455 return "s0";
456 case PERF_REG_RISCV_S1:
457 return "s1";
458 case PERF_REG_RISCV_A0:
459 return "a0";
460 case PERF_REG_RISCV_A1:
461 return "a1";
462 case PERF_REG_RISCV_A2:
463 return "a2";
464 case PERF_REG_RISCV_A3:
465 return "a3";
466 case PERF_REG_RISCV_A4:
467 return "a4";
468 case PERF_REG_RISCV_A5:
469 return "a5";
470 case PERF_REG_RISCV_A6:
471 return "a6";
472 case PERF_REG_RISCV_A7:
473 return "a7";
474 case PERF_REG_RISCV_S2:
475 return "s2";
476 case PERF_REG_RISCV_S3:
477 return "s3";
478 case PERF_REG_RISCV_S4:
479 return "s4";
480 case PERF_REG_RISCV_S5:
481 return "s5";
482 case PERF_REG_RISCV_S6:
483 return "s6";
484 case PERF_REG_RISCV_S7:
485 return "s7";
486 case PERF_REG_RISCV_S8:
487 return "s8";
488 case PERF_REG_RISCV_S9:
489 return "s9";
490 case PERF_REG_RISCV_S10:
491 return "s10";
492 case PERF_REG_RISCV_S11:
493 return "s11";
494 case PERF_REG_RISCV_T3:
495 return "t3";
496 case PERF_REG_RISCV_T4:
497 return "t4";
498 case PERF_REG_RISCV_T5:
499 return "t5";
500 case PERF_REG_RISCV_T6:
501 return "t6";
502 default:
503 return NULL;
504 }
505
506 return NULL;
507 }
508
__perf_reg_name_s390(int id)509 static const char *__perf_reg_name_s390(int id)
510 {
511 switch (id) {
512 case PERF_REG_S390_R0:
513 return "R0";
514 case PERF_REG_S390_R1:
515 return "R1";
516 case PERF_REG_S390_R2:
517 return "R2";
518 case PERF_REG_S390_R3:
519 return "R3";
520 case PERF_REG_S390_R4:
521 return "R4";
522 case PERF_REG_S390_R5:
523 return "R5";
524 case PERF_REG_S390_R6:
525 return "R6";
526 case PERF_REG_S390_R7:
527 return "R7";
528 case PERF_REG_S390_R8:
529 return "R8";
530 case PERF_REG_S390_R9:
531 return "R9";
532 case PERF_REG_S390_R10:
533 return "R10";
534 case PERF_REG_S390_R11:
535 return "R11";
536 case PERF_REG_S390_R12:
537 return "R12";
538 case PERF_REG_S390_R13:
539 return "R13";
540 case PERF_REG_S390_R14:
541 return "R14";
542 case PERF_REG_S390_R15:
543 return "R15";
544 case PERF_REG_S390_FP0:
545 return "FP0";
546 case PERF_REG_S390_FP1:
547 return "FP1";
548 case PERF_REG_S390_FP2:
549 return "FP2";
550 case PERF_REG_S390_FP3:
551 return "FP3";
552 case PERF_REG_S390_FP4:
553 return "FP4";
554 case PERF_REG_S390_FP5:
555 return "FP5";
556 case PERF_REG_S390_FP6:
557 return "FP6";
558 case PERF_REG_S390_FP7:
559 return "FP7";
560 case PERF_REG_S390_FP8:
561 return "FP8";
562 case PERF_REG_S390_FP9:
563 return "FP9";
564 case PERF_REG_S390_FP10:
565 return "FP10";
566 case PERF_REG_S390_FP11:
567 return "FP11";
568 case PERF_REG_S390_FP12:
569 return "FP12";
570 case PERF_REG_S390_FP13:
571 return "FP13";
572 case PERF_REG_S390_FP14:
573 return "FP14";
574 case PERF_REG_S390_FP15:
575 return "FP15";
576 case PERF_REG_S390_MASK:
577 return "MASK";
578 case PERF_REG_S390_PC:
579 return "PC";
580 default:
581 return NULL;
582 }
583
584 return NULL;
585 }
586
__perf_reg_name_x86(int id)587 static const char *__perf_reg_name_x86(int id)
588 {
589 switch (id) {
590 case PERF_REG_X86_AX:
591 return "AX";
592 case PERF_REG_X86_BX:
593 return "BX";
594 case PERF_REG_X86_CX:
595 return "CX";
596 case PERF_REG_X86_DX:
597 return "DX";
598 case PERF_REG_X86_SI:
599 return "SI";
600 case PERF_REG_X86_DI:
601 return "DI";
602 case PERF_REG_X86_BP:
603 return "BP";
604 case PERF_REG_X86_SP:
605 return "SP";
606 case PERF_REG_X86_IP:
607 return "IP";
608 case PERF_REG_X86_FLAGS:
609 return "FLAGS";
610 case PERF_REG_X86_CS:
611 return "CS";
612 case PERF_REG_X86_SS:
613 return "SS";
614 case PERF_REG_X86_DS:
615 return "DS";
616 case PERF_REG_X86_ES:
617 return "ES";
618 case PERF_REG_X86_FS:
619 return "FS";
620 case PERF_REG_X86_GS:
621 return "GS";
622 case PERF_REG_X86_R8:
623 return "R8";
624 case PERF_REG_X86_R9:
625 return "R9";
626 case PERF_REG_X86_R10:
627 return "R10";
628 case PERF_REG_X86_R11:
629 return "R11";
630 case PERF_REG_X86_R12:
631 return "R12";
632 case PERF_REG_X86_R13:
633 return "R13";
634 case PERF_REG_X86_R14:
635 return "R14";
636 case PERF_REG_X86_R15:
637 return "R15";
638
639 #define XMM(x) \
640 case PERF_REG_X86_XMM ## x: \
641 case PERF_REG_X86_XMM ## x + 1: \
642 return "XMM" #x;
643 XMM(0)
644 XMM(1)
645 XMM(2)
646 XMM(3)
647 XMM(4)
648 XMM(5)
649 XMM(6)
650 XMM(7)
651 XMM(8)
652 XMM(9)
653 XMM(10)
654 XMM(11)
655 XMM(12)
656 XMM(13)
657 XMM(14)
658 XMM(15)
659 #undef XMM
660 default:
661 return NULL;
662 }
663
664 return NULL;
665 }
666
perf_reg_name(int id,const char * arch)667 const char *perf_reg_name(int id, const char *arch)
668 {
669 const char *reg_name = NULL;
670
671 if (!strcmp(arch, "csky"))
672 reg_name = __perf_reg_name_csky(id);
673 else if (!strcmp(arch, "mips"))
674 reg_name = __perf_reg_name_mips(id);
675 else if (!strcmp(arch, "powerpc"))
676 reg_name = __perf_reg_name_powerpc(id);
677 else if (!strcmp(arch, "riscv"))
678 reg_name = __perf_reg_name_riscv(id);
679 else if (!strcmp(arch, "s390"))
680 reg_name = __perf_reg_name_s390(id);
681 else if (!strcmp(arch, "x86"))
682 reg_name = __perf_reg_name_x86(id);
683 else if (!strcmp(arch, "arm"))
684 reg_name = __perf_reg_name_arm(id);
685 else if (!strcmp(arch, "arm64"))
686 reg_name = __perf_reg_name_arm64(id);
687
688 return reg_name ?: "unknown";
689 }
690
perf_reg_value(u64 * valp,struct regs_dump * regs,int id)691 int perf_reg_value(u64 *valp, struct regs_dump *regs, int id)
692 {
693 int i, idx = 0;
694 u64 mask = regs->mask;
695
696 if ((u64)id >= PERF_SAMPLE_REGS_CACHE_SIZE)
697 return -EINVAL;
698
699 if (regs->cache_mask & (1ULL << id))
700 goto out;
701
702 if (!(mask & (1ULL << id)))
703 return -EINVAL;
704
705 for (i = 0; i < id; i++) {
706 if (mask & (1ULL << i))
707 idx++;
708 }
709
710 regs->cache_mask |= (1ULL << id);
711 regs->cache_regs[id] = regs->regs[idx];
712
713 out:
714 *valp = regs->cache_regs[id];
715 return 0;
716 }
717 #endif
718