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