Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tools/perf: Add basic support for LoongArch

Add basic support for LoongArch, which is very similar to the MIPS
version.

Signed-off-by: Ming Wang <wangming01@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>

+518 -3
+40
tools/arch/loongarch/include/uapi/asm/perf_regs.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 + #ifndef _ASM_LOONGARCH_PERF_REGS_H 3 + #define _ASM_LOONGARCH_PERF_REGS_H 4 + 5 + enum perf_event_loongarch_regs { 6 + PERF_REG_LOONGARCH_PC, 7 + PERF_REG_LOONGARCH_R1, 8 + PERF_REG_LOONGARCH_R2, 9 + PERF_REG_LOONGARCH_R3, 10 + PERF_REG_LOONGARCH_R4, 11 + PERF_REG_LOONGARCH_R5, 12 + PERF_REG_LOONGARCH_R6, 13 + PERF_REG_LOONGARCH_R7, 14 + PERF_REG_LOONGARCH_R8, 15 + PERF_REG_LOONGARCH_R9, 16 + PERF_REG_LOONGARCH_R10, 17 + PERF_REG_LOONGARCH_R11, 18 + PERF_REG_LOONGARCH_R12, 19 + PERF_REG_LOONGARCH_R13, 20 + PERF_REG_LOONGARCH_R14, 21 + PERF_REG_LOONGARCH_R15, 22 + PERF_REG_LOONGARCH_R16, 23 + PERF_REG_LOONGARCH_R17, 24 + PERF_REG_LOONGARCH_R18, 25 + PERF_REG_LOONGARCH_R19, 26 + PERF_REG_LOONGARCH_R20, 27 + PERF_REG_LOONGARCH_R21, 28 + PERF_REG_LOONGARCH_R22, 29 + PERF_REG_LOONGARCH_R23, 30 + PERF_REG_LOONGARCH_R24, 31 + PERF_REG_LOONGARCH_R25, 32 + PERF_REG_LOONGARCH_R26, 33 + PERF_REG_LOONGARCH_R27, 34 + PERF_REG_LOONGARCH_R28, 35 + PERF_REG_LOONGARCH_R29, 36 + PERF_REG_LOONGARCH_R30, 37 + PERF_REG_LOONGARCH_R31, 38 + PERF_REG_LOONGARCH_MAX, 39 + }; 40 + #endif /* _ASM_LOONGARCH_PERF_REGS_H */
+9
tools/arch/loongarch/include/uapi/asm/unistd.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 + /* 3 + * Copyright (C) 2020-2023 Loongson Technology Corporation Limited 4 + */ 5 + 6 + #define __ARCH_WANT_SYS_CLONE 7 + #define __ARCH_WANT_SYS_CLONE3 8 + 9 + #include <asm-generic/unistd.h>
+9 -3
tools/perf/Makefile.config
··· 38 38 NO_SYSCALL_TABLE := 0 39 39 endif 40 40 else 41 - ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc arm64 s390 mips)) 41 + ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc arm64 s390 mips loongarch)) 42 42 NO_SYSCALL_TABLE := 0 43 43 endif 44 44 endif ··· 80 80 LIBUNWIND_LIBS = -lunwind -lunwind-aarch64 81 81 endif 82 82 83 + ifeq ($(SRCARCH),loongarch) 84 + NO_PERF_REGS := 0 85 + CFLAGS += -I$(OUTPUT)arch/loongarch/include/generated 86 + LIBUNWIND_LIBS = -lunwind -lunwind-loongarch64 87 + endif 88 + 83 89 ifeq ($(SRCARCH),riscv) 84 90 NO_PERF_REGS := 0 85 91 endif ··· 113 107 # Disable it on all other architectures in case libdw unwind 114 108 # support is detected in system. Add supported architectures 115 109 # to the check. 116 - ifneq ($(SRCARCH),$(filter $(SRCARCH),x86 arm arm64 powerpc s390 csky riscv)) 110 + ifneq ($(SRCARCH),$(filter $(SRCARCH),x86 arm arm64 powerpc s390 csky riscv loongarch)) 117 111 NO_LIBDW_DWARF_UNWIND := 1 118 112 endif 119 113 ··· 135 129 ifdef LIBUNWIND_DIR 136 130 LIBUNWIND_CFLAGS = -I$(LIBUNWIND_DIR)/include 137 131 LIBUNWIND_LDFLAGS = -L$(LIBUNWIND_DIR)/lib 138 - LIBUNWIND_ARCHS = x86 x86_64 arm aarch64 debug-frame-arm debug-frame-aarch64 132 + LIBUNWIND_ARCHS = x86 x86_64 arm aarch64 debug-frame-arm debug-frame-aarch64 loongarch 139 133 $(foreach libunwind_arch,$(LIBUNWIND_ARCHS),$(call libunwind_arch_set_flags,$(libunwind_arch))) 140 134 endif 141 135
+1
tools/perf/arch/loongarch/Build
··· 1 + perf-y += util/
+28
tools/perf/arch/loongarch/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + ifndef NO_DWARF 3 + PERF_HAVE_DWARF_REGS := 1 4 + endif 5 + PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1 6 + PERF_HAVE_JITDUMP := 1 7 + 8 + # 9 + # Syscall table generation for perf 10 + # 11 + 12 + out := $(OUTPUT)arch/loongarch/include/generated/asm 13 + header := $(out)/syscalls.c 14 + incpath := $(srctree)/tools 15 + sysdef := $(srctree)/tools/arch/loongarch/include/uapi/asm/unistd.h 16 + sysprf := $(srctree)/tools/perf/arch/loongarch/entry/syscalls/ 17 + systbl := $(sysprf)/mksyscalltbl 18 + 19 + # Create output directory if not already present 20 + _dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)') 21 + 22 + $(header): $(sysdef) $(systbl) 23 + $(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(incpath) $(sysdef) > $@ 24 + 25 + clean:: 26 + $(call QUIET_CLEAN, loongarch) $(RM) $(header) 27 + 28 + archheaders: $(header)
+45
tools/perf/arch/loongarch/annotate/instructions.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Perf annotate functions. 4 + * 5 + * Copyright (C) 2020-2023 Loongson Technology Corporation Limited 6 + */ 7 + 8 + static 9 + struct ins_ops *loongarch__associate_ins_ops(struct arch *arch, const char *name) 10 + { 11 + struct ins_ops *ops = NULL; 12 + 13 + if (!strncmp(name, "beqz", 4) || 14 + !strncmp(name, "bnez", 4) || 15 + !strncmp(name, "beq", 3) || 16 + !strncmp(name, "bne", 3) || 17 + !strncmp(name, "blt", 3) || 18 + !strncmp(name, "bge", 3) || 19 + !strncmp(name, "bltu", 4) || 20 + !strncmp(name, "bgeu", 4) || 21 + !strncmp(name, "bl", 2)) 22 + ops = &call_ops; 23 + else if (!strncmp(name, "jirl", 4)) 24 + ops = &ret_ops; 25 + else if (name[0] == 'b') 26 + ops = &jump_ops; 27 + else 28 + return NULL; 29 + 30 + arch__associate_ins_ops(arch, name, ops); 31 + 32 + return ops; 33 + } 34 + 35 + static 36 + int loongarch__annotate_init(struct arch *arch, char *cpuid __maybe_unused) 37 + { 38 + if (!arch->initialized) { 39 + arch->associate_instruction_ops = loongarch__associate_ins_ops; 40 + arch->initialized = true; 41 + arch->objdump.comment_char = '#'; 42 + } 43 + 44 + return 0; 45 + }
+61
tools/perf/arch/loongarch/entry/syscalls/mksyscalltbl
··· 1 + #!/bin/sh 2 + # SPDX-License-Identifier: GPL-2.0 3 + # 4 + # Generate system call table for perf. Derived from 5 + # powerpc script. 6 + # 7 + # Author(s): Ming Wang <wangming01@loongson.cn> 8 + # Author(s): Huacai Chen <chenhuacai@loongson.cn> 9 + # Copyright (C) 2020-2023 Loongson Technology Corporation Limited 10 + 11 + gcc=$1 12 + hostcc=$2 13 + incpath=$3 14 + input=$4 15 + 16 + if ! test -r $input; then 17 + echo "Could not read input file" >&2 18 + exit 1 19 + fi 20 + 21 + create_table_from_c() 22 + { 23 + local sc nr last_sc 24 + 25 + create_table_exe=`mktemp ${TMPDIR:-/tmp}/create-table-XXXXXX` 26 + 27 + { 28 + 29 + cat <<-_EoHEADER 30 + #include <stdio.h> 31 + #include "$input" 32 + int main(int argc, char *argv[]) 33 + { 34 + _EoHEADER 35 + 36 + while read sc nr; do 37 + printf "%s\n" " printf(\"\\t[%d] = \\\"$sc\\\",\\n\", $nr);" 38 + last_sc=$nr 39 + done 40 + 41 + printf "%s\n" " printf(\"#define SYSCALLTBL_LOONGARCH_MAX_ID %d\\n\", $last_sc);" 42 + printf "}\n" 43 + 44 + } | $hostcc -I $incpath/include/uapi -o $create_table_exe -x c - 45 + 46 + $create_table_exe 47 + 48 + rm -f $create_table_exe 49 + } 50 + 51 + create_table() 52 + { 53 + echo "static const char *syscalltbl_loongarch[] = {" 54 + create_table_from_c 55 + echo "};" 56 + } 57 + 58 + $gcc -E -dM -x c -I $incpath/include/uapi $input \ 59 + |sed -ne 's/^#define __NR_//p' \ 60 + |sort -t' ' -k2 -n \ 61 + |create_table
+16
tools/perf/arch/loongarch/include/dwarf-regs-table.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * dwarf-regs-table.h : Mapping of DWARF debug register numbers into 4 + * register names. 5 + * 6 + * Copyright (C) 2020-2023 Loongson Technology Corporation Limited 7 + */ 8 + 9 + #ifdef DEFINE_DWARF_REGSTR_TABLE 10 + static const char * const loongarch_regstr_tbl[] = { 11 + "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", 12 + "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", 13 + "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23", 14 + "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31", 15 + }; 16 + #endif
+15
tools/perf/arch/loongarch/include/perf_regs.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef ARCH_PERF_REGS_H 3 + #define ARCH_PERF_REGS_H 4 + 5 + #include <stdlib.h> 6 + #include <linux/types.h> 7 + #include <asm/perf_regs.h> 8 + 9 + #define PERF_REGS_MAX PERF_REG_LOONGARCH_MAX 10 + #define PERF_REG_IP PERF_REG_LOONGARCH_PC 11 + #define PERF_REG_SP PERF_REG_LOONGARCH_R3 12 + 13 + #define PERF_REGS_MASK ((1ULL << PERF_REG_LOONGARCH_MAX) - 1) 14 + 15 + #endif /* ARCH_PERF_REGS_H */
+5
tools/perf/arch/loongarch/util/Build
··· 1 + perf-y += perf_regs.o 2 + 3 + perf-$(CONFIG_DWARF) += dwarf-regs.o 4 + perf-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o 5 + perf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
+44
tools/perf/arch/loongarch/util/dwarf-regs.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * dwarf-regs.c : Mapping of DWARF debug register numbers into register names. 4 + * 5 + * Copyright (C) 2020-2023 Loongson Technology Corporation Limited 6 + */ 7 + 8 + #include <stdio.h> 9 + #include <errno.h> /* for EINVAL */ 10 + #include <string.h> /* for strcmp */ 11 + #include <dwarf-regs.h> 12 + 13 + struct pt_regs_dwarfnum { 14 + const char *name; 15 + unsigned int dwarfnum; 16 + }; 17 + 18 + static struct pt_regs_dwarfnum loongarch_gpr_table[] = { 19 + {"%r0", 0}, {"%r1", 1}, {"%r2", 2}, {"%r3", 3}, 20 + {"%r4", 4}, {"%r5", 5}, {"%r6", 6}, {"%r7", 7}, 21 + {"%r8", 8}, {"%r9", 9}, {"%r10", 10}, {"%r11", 11}, 22 + {"%r12", 12}, {"%r13", 13}, {"%r14", 14}, {"%r15", 15}, 23 + {"%r16", 16}, {"%r17", 17}, {"%r18", 18}, {"%r19", 19}, 24 + {"%r20", 20}, {"%r21", 21}, {"%r22", 22}, {"%r23", 23}, 25 + {"%r24", 24}, {"%r25", 25}, {"%r26", 26}, {"%r27", 27}, 26 + {"%r28", 28}, {"%r29", 29}, {"%r30", 30}, {"%r31", 31}, 27 + {NULL, 0} 28 + }; 29 + 30 + const char *get_arch_regstr(unsigned int n) 31 + { 32 + n %= 32; 33 + return loongarch_gpr_table[n].name; 34 + } 35 + 36 + int regs_query_register_offset(const char *name) 37 + { 38 + const struct pt_regs_dwarfnum *roff; 39 + 40 + for (roff = loongarch_gpr_table; roff->name != NULL; roff++) 41 + if (!strcmp(roff->name, name)) 42 + return roff->dwarfnum; 43 + return -EINVAL; 44 + }
+6
tools/perf/arch/loongarch/util/perf_regs.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #include "../../../util/perf_regs.h" 3 + 4 + const struct sample_reg sample_reg_masks[] = { 5 + SMPL_REG_END 6 + };
+56
tools/perf/arch/loongarch/util/unwind-libdw.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (C) 2020-2023 Loongson Technology Corporation Limited */ 3 + 4 + #include <elfutils/libdwfl.h> 5 + #include "../../util/unwind-libdw.h" 6 + #include "../../util/perf_regs.h" 7 + #include "../../util/sample.h" 8 + 9 + bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) 10 + { 11 + struct unwind_info *ui = arg; 12 + struct regs_dump *user_regs = &ui->sample->user_regs; 13 + Dwarf_Word dwarf_regs[PERF_REG_LOONGARCH_MAX]; 14 + 15 + #define REG(r) ({ \ 16 + Dwarf_Word val = 0; \ 17 + perf_reg_value(&val, user_regs, PERF_REG_LOONGARCH_##r); \ 18 + val; \ 19 + }) 20 + 21 + dwarf_regs[0] = 0; 22 + dwarf_regs[1] = REG(R1); 23 + dwarf_regs[2] = REG(R2); 24 + dwarf_regs[3] = REG(R3); 25 + dwarf_regs[4] = REG(R4); 26 + dwarf_regs[5] = REG(R5); 27 + dwarf_regs[6] = REG(R6); 28 + dwarf_regs[7] = REG(R7); 29 + dwarf_regs[8] = REG(R8); 30 + dwarf_regs[9] = REG(R9); 31 + dwarf_regs[10] = REG(R10); 32 + dwarf_regs[11] = REG(R11); 33 + dwarf_regs[12] = REG(R12); 34 + dwarf_regs[13] = REG(R13); 35 + dwarf_regs[14] = REG(R14); 36 + dwarf_regs[15] = REG(R15); 37 + dwarf_regs[16] = REG(R16); 38 + dwarf_regs[17] = REG(R17); 39 + dwarf_regs[18] = REG(R18); 40 + dwarf_regs[19] = REG(R19); 41 + dwarf_regs[20] = REG(R20); 42 + dwarf_regs[21] = REG(R21); 43 + dwarf_regs[22] = REG(R22); 44 + dwarf_regs[23] = REG(R23); 45 + dwarf_regs[24] = REG(R24); 46 + dwarf_regs[25] = REG(R25); 47 + dwarf_regs[26] = REG(R26); 48 + dwarf_regs[27] = REG(R27); 49 + dwarf_regs[28] = REG(R28); 50 + dwarf_regs[29] = REG(R29); 51 + dwarf_regs[30] = REG(R30); 52 + dwarf_regs[31] = REG(R31); 53 + dwfl_thread_state_register_pc(thread, REG(PC)); 54 + 55 + return dwfl_thread_state_registers(thread, 0, PERF_REG_LOONGARCH_MAX, dwarf_regs); 56 + }
+82
tools/perf/arch/loongarch/util/unwind-libunwind.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <errno.h> 4 + #include <libunwind.h> 5 + #include "perf_regs.h" 6 + #include "../../util/unwind.h" 7 + #include "util/debug.h" 8 + 9 + int libunwind__arch_reg_id(int regnum) 10 + { 11 + switch (regnum) { 12 + case UNW_LOONGARCH64_R1: 13 + return PERF_REG_LOONGARCH_R1; 14 + case UNW_LOONGARCH64_R2: 15 + return PERF_REG_LOONGARCH_R2; 16 + case UNW_LOONGARCH64_R3: 17 + return PERF_REG_LOONGARCH_R3; 18 + case UNW_LOONGARCH64_R4: 19 + return PERF_REG_LOONGARCH_R4; 20 + case UNW_LOONGARCH64_R5: 21 + return PERF_REG_LOONGARCH_R5; 22 + case UNW_LOONGARCH64_R6: 23 + return PERF_REG_LOONGARCH_R6; 24 + case UNW_LOONGARCH64_R7: 25 + return PERF_REG_LOONGARCH_R7; 26 + case UNW_LOONGARCH64_R8: 27 + return PERF_REG_LOONGARCH_R8; 28 + case UNW_LOONGARCH64_R9: 29 + return PERF_REG_LOONGARCH_R9; 30 + case UNW_LOONGARCH64_R10: 31 + return PERF_REG_LOONGARCH_R10; 32 + case UNW_LOONGARCH64_R11: 33 + return PERF_REG_LOONGARCH_R11; 34 + case UNW_LOONGARCH64_R12: 35 + return PERF_REG_LOONGARCH_R12; 36 + case UNW_LOONGARCH64_R13: 37 + return PERF_REG_LOONGARCH_R13; 38 + case UNW_LOONGARCH64_R14: 39 + return PERF_REG_LOONGARCH_R14; 40 + case UNW_LOONGARCH64_R15: 41 + return PERF_REG_LOONGARCH_R15; 42 + case UNW_LOONGARCH64_R16: 43 + return PERF_REG_LOONGARCH_R16; 44 + case UNW_LOONGARCH64_R17: 45 + return PERF_REG_LOONGARCH_R17; 46 + case UNW_LOONGARCH64_R18: 47 + return PERF_REG_LOONGARCH_R18; 48 + case UNW_LOONGARCH64_R19: 49 + return PERF_REG_LOONGARCH_R19; 50 + case UNW_LOONGARCH64_R20: 51 + return PERF_REG_LOONGARCH_R20; 52 + case UNW_LOONGARCH64_R21: 53 + return PERF_REG_LOONGARCH_R21; 54 + case UNW_LOONGARCH64_R22: 55 + return PERF_REG_LOONGARCH_R22; 56 + case UNW_LOONGARCH64_R23: 57 + return PERF_REG_LOONGARCH_R23; 58 + case UNW_LOONGARCH64_R24: 59 + return PERF_REG_LOONGARCH_R24; 60 + case UNW_LOONGARCH64_R25: 61 + return PERF_REG_LOONGARCH_R25; 62 + case UNW_LOONGARCH64_R26: 63 + return PERF_REG_LOONGARCH_R26; 64 + case UNW_LOONGARCH64_R27: 65 + return PERF_REG_LOONGARCH_R27; 66 + case UNW_LOONGARCH64_R28: 67 + return PERF_REG_LOONGARCH_R28; 68 + case UNW_LOONGARCH64_R29: 69 + return PERF_REG_LOONGARCH_R29; 70 + case UNW_LOONGARCH64_R30: 71 + return PERF_REG_LOONGARCH_R30; 72 + case UNW_LOONGARCH64_R31: 73 + return PERF_REG_LOONGARCH_R31; 74 + case UNW_LOONGARCH64_PC: 75 + return PERF_REG_LOONGARCH_PC; 76 + default: 77 + pr_err("unwind: invalid reg id %d\n", regnum); 78 + return -EINVAL; 79 + } 80 + 81 + return -EINVAL; 82 + }
+1
tools/perf/check-headers.sh
··· 40 40 arch/x86/tools/gen-insn-attr-x86.awk 41 41 arch/arm/include/uapi/asm/perf_regs.h 42 42 arch/arm64/include/uapi/asm/perf_regs.h 43 + arch/loongarch/include/uapi/asm/perf_regs.h 43 44 arch/mips/include/uapi/asm/perf_regs.h 44 45 arch/powerpc/include/uapi/asm/perf_regs.h 45 46 arch/s390/include/uapi/asm/perf_regs.h
+8
tools/perf/util/annotate.c
··· 149 149 #include "arch/arm/annotate/instructions.c" 150 150 #include "arch/arm64/annotate/instructions.c" 151 151 #include "arch/csky/annotate/instructions.c" 152 + #include "arch/loongarch/annotate/instructions.c" 152 153 #include "arch/mips/annotate/instructions.c" 153 154 #include "arch/x86/annotate/instructions.c" 154 155 #include "arch/powerpc/annotate/instructions.c" ··· 208 207 { 209 208 .name = "sparc", 210 209 .init = sparc__annotate_init, 210 + .objdump = { 211 + .comment_char = '#', 212 + }, 213 + }, 214 + { 215 + .name = "loongarch", 216 + .init = loongarch__annotate_init, 211 217 .objdump = { 212 218 .comment_char = '#', 213 219 },
+7
tools/perf/util/dwarf-regs.c
··· 14 14 #define EM_AARCH64 183 /* ARM 64 bit */ 15 15 #endif 16 16 17 + #ifndef EM_LOONGARCH 18 + #define EM_LOONGARCH 258 /* LoongArch */ 19 + #endif 20 + 17 21 /* Define const char * {arch}_register_tbl[] */ 18 22 #define DEFINE_DWARF_REGSTR_TABLE 19 23 #include "../arch/x86/include/dwarf-regs-table.h" ··· 29 25 #include "../arch/sparc/include/dwarf-regs-table.h" 30 26 #include "../arch/xtensa/include/dwarf-regs-table.h" 31 27 #include "../arch/mips/include/dwarf-regs-table.h" 28 + #include "../arch/loongarch/include/dwarf-regs-table.h" 32 29 33 30 #define __get_dwarf_regstr(tbl, n) (((n) < ARRAY_SIZE(tbl)) ? (tbl)[(n)] : NULL) 34 31 ··· 61 56 return __get_dwarf_regstr(xtensa_regstr_tbl, n); 62 57 case EM_MIPS: 63 58 return __get_dwarf_regstr(mips_regstr_tbl, n); 59 + case EM_LOONGARCH: 60 + return __get_dwarf_regstr(loongarch_regstr_tbl, n); 64 61 default: 65 62 pr_err("ELF MACHINE %x is not supported.\n", machine); 66 63 }
+2
tools/perf/util/env.c
··· 435 435 return "mips"; 436 436 if (!strncmp(arch, "sh", 2) && isdigit(arch[2])) 437 437 return "sh"; 438 + if (!strncmp(arch, "loongarch", 9)) 439 + return "loongarch"; 438 440 439 441 return arch; 440 442 }
+3
tools/perf/util/genelf.h
··· 43 43 #elif defined(__riscv) && __riscv_xlen == 64 44 44 #define GEN_ELF_ARCH EM_RISCV 45 45 #define GEN_ELF_CLASS ELFCLASS64 46 + #elif defined(__loongarch__) 47 + #define GEN_ELF_ARCH EM_LOONGARCH 48 + #define GEN_ELF_CLASS ELFCLASS64 46 49 #else 47 50 #error "unsupported architecture" 48 51 #endif
+76
tools/perf/util/perf_regs.c
··· 28 28 29 29 #include "../../arch/arm/include/uapi/asm/perf_regs.h" 30 30 #include "../../arch/csky/include/uapi/asm/perf_regs.h" 31 + #include "../../arch/loongarch/include/uapi/asm/perf_regs.h" 31 32 #include "../../arch/mips/include/uapi/asm/perf_regs.h" 32 33 #include "../../arch/powerpc/include/uapi/asm/perf_regs.h" 33 34 #include "../../arch/riscv/include/uapi/asm/perf_regs.h" ··· 234 233 return NULL; 235 234 } 236 235 236 + return NULL; 237 + } 238 + 239 + static inline const char *__perf_reg_name_loongarch(int id) 240 + { 241 + switch (id) { 242 + case PERF_REG_LOONGARCH_PC: 243 + return "PC"; 244 + case PERF_REG_LOONGARCH_R1: 245 + return "%r1"; 246 + case PERF_REG_LOONGARCH_R2: 247 + return "%r2"; 248 + case PERF_REG_LOONGARCH_R3: 249 + return "%r3"; 250 + case PERF_REG_LOONGARCH_R4: 251 + return "%r4"; 252 + case PERF_REG_LOONGARCH_R5: 253 + return "%r5"; 254 + case PERF_REG_LOONGARCH_R6: 255 + return "%r6"; 256 + case PERF_REG_LOONGARCH_R7: 257 + return "%r7"; 258 + case PERF_REG_LOONGARCH_R8: 259 + return "%r8"; 260 + case PERF_REG_LOONGARCH_R9: 261 + return "%r9"; 262 + case PERF_REG_LOONGARCH_R10: 263 + return "%r10"; 264 + case PERF_REG_LOONGARCH_R11: 265 + return "%r11"; 266 + case PERF_REG_LOONGARCH_R12: 267 + return "%r12"; 268 + case PERF_REG_LOONGARCH_R13: 269 + return "%r13"; 270 + case PERF_REG_LOONGARCH_R14: 271 + return "%r14"; 272 + case PERF_REG_LOONGARCH_R15: 273 + return "%r15"; 274 + case PERF_REG_LOONGARCH_R16: 275 + return "%r16"; 276 + case PERF_REG_LOONGARCH_R17: 277 + return "%r17"; 278 + case PERF_REG_LOONGARCH_R18: 279 + return "%r18"; 280 + case PERF_REG_LOONGARCH_R19: 281 + return "%r19"; 282 + case PERF_REG_LOONGARCH_R20: 283 + return "%r20"; 284 + case PERF_REG_LOONGARCH_R21: 285 + return "%r21"; 286 + case PERF_REG_LOONGARCH_R22: 287 + return "%r22"; 288 + case PERF_REG_LOONGARCH_R23: 289 + return "%r23"; 290 + case PERF_REG_LOONGARCH_R24: 291 + return "%r24"; 292 + case PERF_REG_LOONGARCH_R25: 293 + return "%r25"; 294 + case PERF_REG_LOONGARCH_R26: 295 + return "%r26"; 296 + case PERF_REG_LOONGARCH_R27: 297 + return "%r27"; 298 + case PERF_REG_LOONGARCH_R28: 299 + return "%r28"; 300 + case PERF_REG_LOONGARCH_R29: 301 + return "%r29"; 302 + case PERF_REG_LOONGARCH_R30: 303 + return "%r30"; 304 + case PERF_REG_LOONGARCH_R31: 305 + return "%r31"; 306 + default: 307 + break; 308 + } 237 309 return NULL; 238 310 } 239 311 ··· 744 670 745 671 if (!strcmp(arch, "csky")) 746 672 reg_name = __perf_reg_name_csky(id); 673 + else if (!strcmp(arch, "loongarch")) 674 + reg_name = __perf_reg_name_loongarch(id); 747 675 else if (!strcmp(arch, "mips")) 748 676 reg_name = __perf_reg_name_mips(id); 749 677 else if (!strcmp(arch, "powerpc"))
+4
tools/perf/util/syscalltbl.c
··· 38 38 #include <asm/syscalls_n64.c> 39 39 const int syscalltbl_native_max_id = SYSCALLTBL_MIPS_N64_MAX_ID; 40 40 static const char **syscalltbl_native = syscalltbl_mips_n64; 41 + #elif defined(__loongarch__) 42 + #include <asm/syscalls.c> 43 + const int syscalltbl_native_max_id = SYSCALLTBL_LOONGARCH_MAX_ID; 44 + static const char **syscalltbl_native = syscalltbl_loongarch; 41 45 #endif 42 46 43 47 struct syscall {