1 /* The fake debug assert instructions
3 * Copyright 2010 Analog Devices Inc.
5 * Licensed under the GPL-2 or later
8 #include <linux/types.h>
9 #include <linux/kernel.h>
10 #include <linux/ptrace.h>
12 const char * const greg_names
[] = {
13 "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7",
14 "P0", "P1", "P2", "P3", "P4", "P5", "SP", "FP",
15 "I0", "I1", "I2", "I3", "M0", "M1", "M2", "M3",
16 "B0", "B1", "B2", "B3", "L0", "L1", "L2", "L3",
17 "A0.X", "A0.W", "A1.X", "A1.W", "<res>", "<res>", "ASTAT", "RETS",
18 "<res>", "<res>", "<res>", "<res>", "<res>", "<res>", "<res>", "<res>",
19 "LC0", "LT0", "LB0", "LC1", "LT1", "LB1", "CYCLES", "CYCLES2",
20 "USP", "SEQSTAT", "SYSCFG", "RETI", "RETX", "RETN", "RETE", "EMUDAT",
23 static const char *get_allreg_name(int grp
, int reg
)
25 return greg_names
[(grp
<< 3) | reg
];
29 * Unfortunately, the pt_regs structure is not laid out the same way as the
30 * hardware register file, so we need to do some fix ups.
32 * CYCLES is not stored in the pt_regs structure - so, we just read it from
36 * - All reserved registers
37 * - All in group 7 are (supervisors only)
40 static bool fix_up_reg(struct pt_regs
*fp
, long *value
, int grp
, int reg
)
45 /* Only do Dregs and Pregs for now */
47 (grp
== 4 && (reg
== 4 || reg
== 5)) ||
51 if (grp
== 0 || (grp
== 1 && reg
< 6))
52 val
-= (reg
+ 8 * grp
);
53 else if (grp
== 1 && reg
== 6)
55 else if (grp
== 1 && reg
== 7)
60 } else if (grp
== 3 && reg
>= 4) {
63 } else if (grp
== 3 && reg
< 4) {
66 } else if (grp
== 4 && reg
< 4) {
69 } else if (grp
== 4 && reg
== 6)
71 else if (grp
== 4 && reg
== 7)
73 else if (grp
== 6 && reg
< 6) {
76 } else if (grp
== 6 && reg
== 6) {
77 __asm__
__volatile__("%0 = cycles;\n" : "=d"(tmp
));
79 } else if (grp
== 6 && reg
== 7) {
80 __asm__
__volatile__("%0 = cycles2;\n" : "=d"(tmp
));
89 #define PseudoDbg_Assert_opcode 0xf0000000
90 #define PseudoDbg_Assert_expected_bits 0
91 #define PseudoDbg_Assert_expected_mask 0xffff
92 #define PseudoDbg_Assert_regtest_bits 16
93 #define PseudoDbg_Assert_regtest_mask 0x7
94 #define PseudoDbg_Assert_grp_bits 19
95 #define PseudoDbg_Assert_grp_mask 0x7
96 #define PseudoDbg_Assert_dbgop_bits 22
97 #define PseudoDbg_Assert_dbgop_mask 0x3
98 #define PseudoDbg_Assert_dontcare_bits 24
99 #define PseudoDbg_Assert_dontcare_mask 0x7
100 #define PseudoDbg_Assert_code_bits 27
101 #define PseudoDbg_Assert_code_mask 0x1f
104 * DBGA - debug assert
106 bool execute_pseudodbg_assert(struct pt_regs
*fp
, unsigned int opcode
)
108 int expected
= ((opcode
>> PseudoDbg_Assert_expected_bits
) & PseudoDbg_Assert_expected_mask
);
109 int dbgop
= ((opcode
>> (PseudoDbg_Assert_dbgop_bits
)) & PseudoDbg_Assert_dbgop_mask
);
110 int grp
= ((opcode
>> (PseudoDbg_Assert_grp_bits
)) & PseudoDbg_Assert_grp_mask
);
111 int regtest
= ((opcode
>> (PseudoDbg_Assert_regtest_bits
)) & PseudoDbg_Assert_regtest_mask
);
114 if ((opcode
& 0xFF000000) != PseudoDbg_Assert_opcode
)
117 if (!fix_up_reg(fp
, &value
, grp
, regtest
))
120 if (dbgop
== 0 || dbgop
== 2) {
121 /* DBGA ( regs_lo , uimm16 ) */
122 /* DBGAL ( regs , uimm16 ) */
123 if (expected
!= (value
& 0xFFFF)) {
124 pr_notice("DBGA (%s.L,0x%x) failure, got 0x%x\n",
125 get_allreg_name(grp
, regtest
),
126 expected
, (unsigned int)(value
& 0xFFFF));
130 } else if (dbgop
== 1 || dbgop
== 3) {
131 /* DBGA ( regs_hi , uimm16 ) */
132 /* DBGAH ( regs , uimm16 ) */
133 if (expected
!= ((value
>> 16) & 0xFFFF)) {
134 pr_notice("DBGA (%s.H,0x%x) failure, got 0x%x\n",
135 get_allreg_name(grp
, regtest
),
136 expected
, (unsigned int)((value
>> 16) & 0xFFFF));
145 #define PseudoDbg_opcode 0xf8000000
146 #define PseudoDbg_reg_bits 0
147 #define PseudoDbg_reg_mask 0x7
148 #define PseudoDbg_grp_bits 3
149 #define PseudoDbg_grp_mask 0x7
150 #define PseudoDbg_fn_bits 6
151 #define PseudoDbg_fn_mask 0x3
152 #define PseudoDbg_code_bits 8
153 #define PseudoDbg_code_mask 0xff
156 * DBG - debug (dump a register value out)
158 bool execute_pseudodbg(struct pt_regs
*fp
, unsigned int opcode
)
163 if ((opcode
& 0xFF000000) != PseudoDbg_opcode
)
167 grp
= ((opcode
>> PseudoDbg_grp_bits
) & PseudoDbg_reg_mask
);
168 fn
= ((opcode
>> PseudoDbg_fn_bits
) & PseudoDbg_fn_mask
);
169 reg
= ((opcode
>> PseudoDbg_reg_bits
) & PseudoDbg_reg_mask
);
171 if (fn
== 3 && (reg
== 0 || reg
== 1)) {
172 if (!fix_up_reg(fp
, &value
, 4, 2 * reg
))
174 if (!fix_up_reg(fp
, &value1
, 4, 2 * reg
+ 1))
177 pr_notice("DBG A%i = %02lx%08lx\n", reg
, value
& 0xFF, value1
);
181 } else if (fn
== 0) {
182 if (!fix_up_reg(fp
, &value
, grp
, reg
))
185 pr_notice("DBG %s = %08lx\n", get_allreg_name(grp
, reg
), value
);