1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd.
3 // Mapping of DWARF debug register numbers into register names.
4
5 #include <errno.h>
6 #include <stddef.h>
7 #include <dwarf-regs.h>
8 // Ensure the V2 perf reg definitions are included.
9 #undef __CSKYABIV2__
10 #define __CSKYABIV2__ 1
11 #include "../../../arch/csky/include/uapi/asm/perf_regs.h"
12
13 #define CSKY_ABIV2_MAX_REGS 73
14 static const char * const csky_dwarf_regs_table_abiv2[CSKY_ABIV2_MAX_REGS] = {
15 /* r0 ~ r8 */
16 "%a0", "%a1", "%a2", "%a3", "%regs0", "%regs1", "%regs2", "%regs3",
17 /* r9 ~ r15 */
18 "%regs4", "%regs5", "%regs6", "%regs7", "%regs8", "%regs9", "%sp",
19 "%lr",
20 /* r16 ~ r23 */
21 "%exregs0", "%exregs1", "%exregs2", "%exregs3", "%exregs4",
22 "%exregs5", "%exregs6", "%exregs7",
23 /* r24 ~ r31 */
24 "%exregs8", "%exregs9", "%exregs10", "%exregs11", "%exregs12",
25 "%exregs13", "%exregs14", "%tls",
26 "%pc", NULL, NULL, NULL, "%hi", "%lo", NULL, NULL,
27 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
28 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
29 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
30 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
31 "%epc",
32 };
33
34 #define CSKY_ABIV1_MAX_REGS 57
35 static const char * const csky_dwarf_regs_table_abiv1[CSKY_ABIV1_MAX_REGS] = {
36 /* r0 ~ r8 */
37 "%sp", "%regs9", "%a0", "%a1", "%a2", "%a3", "%regs0", "%regs1",
38 /* r9 ~ r15 */
39 "%regs2", "%regs3", "%regs4", "%regs5", "%regs6", "%regs7", "%regs8",
40 "%lr",
41 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
42 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
43 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
44 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
45 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
46 "%epc",
47 };
48
__get_csky_regstr(unsigned int n,unsigned int flags)49 const char *__get_csky_regstr(unsigned int n, unsigned int flags)
50 {
51 if (flags & EF_CSKY_ABIV2)
52 return (n < CSKY_ABIV2_MAX_REGS) ? csky_dwarf_regs_table_abiv2[n] : NULL;
53
54 return (n < CSKY_ABIV1_MAX_REGS) ? csky_dwarf_regs_table_abiv1[n] : NULL;
55 }
56
__get_dwarf_regnum(const char * const * regstr,size_t num_regstr,const char * name)57 static int __get_dwarf_regnum(const char *const *regstr, size_t num_regstr, const char *name)
58 {
59 for (size_t i = 0; i < num_regstr; i++) {
60 if (regstr[i] && !strcmp(regstr[i], name))
61 return i;
62 }
63 return -ENOENT;
64 }
65
__get_csky_regnum(const char * name,unsigned int flags)66 int __get_csky_regnum(const char *name, unsigned int flags)
67 {
68 if (flags & EF_CSKY_ABIV2)
69 return __get_dwarf_regnum(csky_dwarf_regs_table_abiv2, CSKY_ABIV2_MAX_REGS, name);
70
71 return __get_dwarf_regnum(csky_dwarf_regs_table_abiv1, CSKY_ABIV1_MAX_REGS, name);
72 }
73
__get_dwarf_regnum_for_perf_regnum_csky(int perf_regnum,unsigned int flags)74 int __get_dwarf_regnum_for_perf_regnum_csky(int perf_regnum, unsigned int flags)
75 {
76 static const int dwarf_csky_regnums[][2] = {
77 [PERF_REG_CSKY_TLS] = {-ENOENT, 31},
78 [PERF_REG_CSKY_LR] = {15, 15},
79 [PERF_REG_CSKY_PC] = {-ENOENT, 32},
80 /* TODO: PERF_REG_CSKY_SR */
81 [PERF_REG_CSKY_SP] = {0, 14},
82 /* TODO: PERF_REG_CSKY_ORIG_A0 */
83 [PERF_REG_CSKY_A0] = {2, 0},
84 [PERF_REG_CSKY_A1] = {3, 1},
85 [PERF_REG_CSKY_A2] = {4, 2},
86 [PERF_REG_CSKY_A3] = {5, 3},
87 [PERF_REG_CSKY_REGS0] = {6, 4},
88 [PERF_REG_CSKY_REGS1] = {7, 5},
89 [PERF_REG_CSKY_REGS2] = {8, 6},
90 [PERF_REG_CSKY_REGS3] = {9, 7},
91 [PERF_REG_CSKY_REGS4] = {10, 8},
92 [PERF_REG_CSKY_REGS5] = {11, 9},
93 [PERF_REG_CSKY_REGS6] = {12, 10},
94 [PERF_REG_CSKY_REGS7] = {13, 11},
95 [PERF_REG_CSKY_REGS8] = {14, 12},
96 [PERF_REG_CSKY_REGS9] = {1, 13},
97 [PERF_REG_CSKY_EXREGS0] = {-ENOENT, 16},
98 [PERF_REG_CSKY_EXREGS1] = {-ENOENT, 17},
99 [PERF_REG_CSKY_EXREGS2] = {-ENOENT, 18},
100 [PERF_REG_CSKY_EXREGS3] = {-ENOENT, 19},
101 [PERF_REG_CSKY_EXREGS4] = {-ENOENT, 20},
102 [PERF_REG_CSKY_EXREGS5] = {-ENOENT, 21},
103 [PERF_REG_CSKY_EXREGS6] = {-ENOENT, 22},
104 [PERF_REG_CSKY_EXREGS7] = {-ENOENT, 23},
105 [PERF_REG_CSKY_EXREGS8] = {-ENOENT, 24},
106 [PERF_REG_CSKY_EXREGS9] = {-ENOENT, 25},
107 [PERF_REG_CSKY_EXREGS10] = {-ENOENT, 26},
108 [PERF_REG_CSKY_EXREGS11] = {-ENOENT, 27},
109 [PERF_REG_CSKY_EXREGS12] = {-ENOENT, 28},
110 [PERF_REG_CSKY_EXREGS13] = {-ENOENT, 29},
111 [PERF_REG_CSKY_EXREGS14] = {-ENOENT, 30},
112 /* TODO: PERF_REG_CSKY_HI */
113 /* TODO: PERF_REG_CSKY_LO */
114 /* TODO: PERF_REG_CSKY_DCSR */
115 };
116 int idx = 0;
117
118 if (flags & EF_CSKY_ABIV2)
119 idx++;
120
121 if (perf_regnum < 0 || perf_regnum > (int)ARRAY_SIZE(dwarf_csky_regnums) ||
122 dwarf_csky_regnums[perf_regnum][idx] == 0)
123 return -ENOENT;
124
125 return dwarf_csky_regnums[perf_regnum][idx];
126 }
127