1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 /***************************************************************************
4 * Copyright (C) 2009-2011 by Mathias Kuester *
5 * mkdorg@users.sourceforge.net *
6 ***************************************************************************/
15 #include "breakpoints.h"
16 #include "target_type.h"
17 #include "algorithm.h"
20 #include "dsp563xx_once.h"
22 #define ASM_REG_W_R0 0x60F400
23 #define ASM_REG_W_R1 0x61F400
24 #define ASM_REG_W_R2 0x62F400
25 #define ASM_REG_W_R3 0x63F400
26 #define ASM_REG_W_R4 0x64F400
27 #define ASM_REG_W_R5 0x65F400
28 #define ASM_REG_W_R6 0x66F400
29 #define ASM_REG_W_R7 0x67F400
31 #define ASM_REG_W_N0 0x70F400
32 #define ASM_REG_W_N1 0x71F400
33 #define ASM_REG_W_N2 0x72F400
34 #define ASM_REG_W_N3 0x73F400
35 #define ASM_REG_W_N4 0x74F400
36 #define ASM_REG_W_N5 0x75F400
37 #define ASM_REG_W_N6 0x76F400
38 #define ASM_REG_W_N7 0x77F400
40 #define ASM_REG_W_M0 0x05F420
41 #define ASM_REG_W_M1 0x05F421
42 #define ASM_REG_W_M2 0x05F422
43 #define ASM_REG_W_M3 0x05F423
44 #define ASM_REG_W_M4 0x05F424
45 #define ASM_REG_W_M5 0x05F425
46 #define ASM_REG_W_M6 0x05F426
47 #define ASM_REG_W_M7 0x05F427
49 #define ASM_REG_W_X0 0x44F400
50 #define ASM_REG_W_X1 0x45F400
52 #define ASM_REG_W_Y0 0x46F400
53 #define ASM_REG_W_Y1 0x47F400
55 #define ASM_REG_W_A0 0x50F400
56 #define ASM_REG_W_A1 0x54F400
57 #define ASM_REG_W_A2 0x52F400
59 #define ASM_REG_W_B0 0x51F400
60 #define ASM_REG_W_B1 0x55F400
61 #define ASM_REG_W_B2 0x53F400
63 #define ASM_REG_W_VBA 0x05F430
64 #define ASM_REG_W_OMR 0x05F43A
65 #define ASM_REG_W_EP 0x05F42A
66 #define ASM_REG_W_SC 0x05F431
67 #define ASM_REG_W_SZ 0x05F438
68 #define ASM_REG_W_SR 0x05F439
69 #define ASM_REG_W_SP 0x05F43B
70 #define ASM_REG_W_SSH 0x05F43C
71 #define ASM_REG_W_SSL 0x05F43D
72 #define ASM_REG_W_LA 0x05F43E
73 #define ASM_REG_W_LC 0x05F43F
74 #define ASM_REG_W_PC 0x000000
75 #define ASM_REG_W_IPRC 0xFFFFFF
76 #define ASM_REG_W_IPRP 0xFFFFFE
78 #define ASM_REG_W_BCR 0xFFFFFB
79 #define ASM_REG_W_DCR 0xFFFFFA
80 #define ASM_REG_W_AAR0 0xFFFFF9
81 #define ASM_REG_W_AAR1 0xFFFFF8
82 #define ASM_REG_W_AAR2 0xFFFFF7
83 #define ASM_REG_W_AAR3 0xFFFFF6
86 * OBCR Register bit definitions
88 #define OBCR_B0_AND_B1 ((0x0) << 10)
89 #define OBCR_B0_OR_B1 ((0x1) << 10)
90 #define OBCR_B1_AFTER_B0 ((0x2) << 10)
91 #define OBCR_B0_AFTER_B1 ((0x3) << 10)
93 #define OBCR_BP_DISABLED (0x0)
94 #define OBCR_BP_MEM_P (0x1)
95 #define OBCR_BP_MEM_X (0x2)
96 #define OBCR_BP_MEM_Y (0x3)
97 #define OBCR_BP_ON_READ ((0x2) << 0)
98 #define OBCR_BP_ON_WRITE ((0x1) << 0)
99 #define OBCR_BP_CC_NOT_EQUAL ((0x0) << 2)
100 #define OBCR_BP_CC_EQUAL ((0x1) << 2)
101 #define OBCR_BP_CC_LESS_THAN ((0x2) << 2)
102 #define OBCR_BP_CC_GREATER_THAN ((0x3) << 2)
104 #define OBCR_BP_0(x) ((x)<<2)
105 #define OBCR_BP_1(x) ((x)<<6)
109 ONCE_REG_IDX_OSCR
= 0,
110 ONCE_REG_IDX_OMBC
= 1,
111 ONCE_REG_IDX_OBCR
= 2,
112 ONCE_REG_IDX_OMLR0
= 3,
113 ONCE_REG_IDX_OMLR1
= 4,
114 ONCE_REG_IDX_OGDBR
= 5,
115 ONCE_REG_IDX_OPDBR
= 6,
116 ONCE_REG_IDX_OPILR
= 7,
117 ONCE_REG_IDX_PDB
= 8,
118 ONCE_REG_IDX_OTC
= 9,
119 ONCE_REG_IDX_OPABFR
= 10,
120 ONCE_REG_IDX_OPABDR
= 11,
121 ONCE_REG_IDX_OPABEX
= 12,
122 ONCE_REG_IDX_OPABF0
= 13,
123 ONCE_REG_IDX_OPABF1
= 14,
124 ONCE_REG_IDX_OPABF2
= 15,
125 ONCE_REG_IDX_OPABF3
= 16,
126 ONCE_REG_IDX_OPABF4
= 17,
127 ONCE_REG_IDX_OPABF5
= 18,
128 ONCE_REG_IDX_OPABF6
= 19,
129 ONCE_REG_IDX_OPABF7
= 20,
130 ONCE_REG_IDX_OPABF8
= 21,
131 ONCE_REG_IDX_OPABF9
= 22,
132 ONCE_REG_IDX_OPABF10
= 23,
133 ONCE_REG_IDX_OPABF11
= 24,
136 static struct once_reg once_regs
[] = {
137 {ONCE_REG_IDX_OSCR
, DSP563XX_ONCE_OSCR
, 24, "OSCR", 0},
138 {ONCE_REG_IDX_OMBC
, DSP563XX_ONCE_OMBC
, 24, "OMBC", 0},
139 {ONCE_REG_IDX_OBCR
, DSP563XX_ONCE_OBCR
, 24, "OBCR", 0},
140 {ONCE_REG_IDX_OMLR0
, DSP563XX_ONCE_OMLR0
, 24, "OMLR0", 0},
141 {ONCE_REG_IDX_OMLR1
, DSP563XX_ONCE_OMLR1
, 24, "OMLR1", 0},
142 {ONCE_REG_IDX_OGDBR
, DSP563XX_ONCE_OGDBR
, 24, "OGDBR", 0},
143 {ONCE_REG_IDX_OPDBR
, DSP563XX_ONCE_OPDBR
, 24, "OPDBR", 0},
144 {ONCE_REG_IDX_OPILR
, DSP563XX_ONCE_OPILR
, 24, "OPILR", 0},
145 {ONCE_REG_IDX_PDB
, DSP563XX_ONCE_PDBGOTO
, 24, "PDB", 0},
146 {ONCE_REG_IDX_OTC
, DSP563XX_ONCE_OTC
, 24, "OTC", 0},
147 {ONCE_REG_IDX_OPABFR
, DSP563XX_ONCE_OPABFR
, 24, "OPABFR", 0},
148 {ONCE_REG_IDX_OPABDR
, DSP563XX_ONCE_OPABDR
, 24, "OPABDR", 0},
149 {ONCE_REG_IDX_OPABEX
, DSP563XX_ONCE_OPABEX
, 24, "OPABEX", 0},
150 {ONCE_REG_IDX_OPABF0
, DSP563XX_ONCE_OPABF11
, 25, "OPABF0", 0},
151 {ONCE_REG_IDX_OPABF1
, DSP563XX_ONCE_OPABF11
, 25, "OPABF1", 0},
152 {ONCE_REG_IDX_OPABF2
, DSP563XX_ONCE_OPABF11
, 25, "OPABF2", 0},
153 {ONCE_REG_IDX_OPABF3
, DSP563XX_ONCE_OPABF11
, 25, "OPABF3", 0},
154 {ONCE_REG_IDX_OPABF4
, DSP563XX_ONCE_OPABF11
, 25, "OPABF4", 0},
155 {ONCE_REG_IDX_OPABF5
, DSP563XX_ONCE_OPABF11
, 25, "OPABF5", 0},
156 {ONCE_REG_IDX_OPABF6
, DSP563XX_ONCE_OPABF11
, 25, "OPABF6", 0},
157 {ONCE_REG_IDX_OPABF7
, DSP563XX_ONCE_OPABF11
, 25, "OPABF7", 0},
158 {ONCE_REG_IDX_OPABF8
, DSP563XX_ONCE_OPABF11
, 25, "OPABF8", 0},
159 {ONCE_REG_IDX_OPABF9
, DSP563XX_ONCE_OPABF11
, 25, "OPABF9", 0},
160 {ONCE_REG_IDX_OPABF10
, DSP563XX_ONCE_OPABF11
, 25, "OPABF10", 0},
161 {ONCE_REG_IDX_OPABF11
, DSP563XX_ONCE_OPABF11
, 25, "OPABF11", 0},
162 /* {25,0x1f,24,"NRSEL",0}, */
165 enum dsp563xx_reg_idx
{
166 DSP563XX_REG_IDX_R0
= 0,
167 DSP563XX_REG_IDX_R1
= 1,
168 DSP563XX_REG_IDX_R2
= 2,
169 DSP563XX_REG_IDX_R3
= 3,
170 DSP563XX_REG_IDX_R4
= 4,
171 DSP563XX_REG_IDX_R5
= 5,
172 DSP563XX_REG_IDX_R6
= 6,
173 DSP563XX_REG_IDX_R7
= 7,
174 DSP563XX_REG_IDX_N0
= 8,
175 DSP563XX_REG_IDX_N1
= 9,
176 DSP563XX_REG_IDX_N2
= 10,
177 DSP563XX_REG_IDX_N3
= 11,
178 DSP563XX_REG_IDX_N4
= 12,
179 DSP563XX_REG_IDX_N5
= 13,
180 DSP563XX_REG_IDX_N6
= 14,
181 DSP563XX_REG_IDX_N7
= 15,
182 DSP563XX_REG_IDX_M0
= 16,
183 DSP563XX_REG_IDX_M1
= 17,
184 DSP563XX_REG_IDX_M2
= 18,
185 DSP563XX_REG_IDX_M3
= 19,
186 DSP563XX_REG_IDX_M4
= 20,
187 DSP563XX_REG_IDX_M5
= 21,
188 DSP563XX_REG_IDX_M6
= 22,
189 DSP563XX_REG_IDX_M7
= 23,
190 DSP563XX_REG_IDX_X0
= 24,
191 DSP563XX_REG_IDX_X1
= 25,
192 DSP563XX_REG_IDX_Y0
= 26,
193 DSP563XX_REG_IDX_Y1
= 27,
194 DSP563XX_REG_IDX_A0
= 28,
195 DSP563XX_REG_IDX_A1
= 29,
196 DSP563XX_REG_IDX_A2
= 30,
197 DSP563XX_REG_IDX_B0
= 31,
198 DSP563XX_REG_IDX_B1
= 32,
199 DSP563XX_REG_IDX_B2
= 33,
200 DSP563XX_REG_IDX_SSH
= 34,
201 DSP563XX_REG_IDX_SSL
= 35,
202 DSP563XX_REG_IDX_SP
= 36,
203 DSP563XX_REG_IDX_EP
= 37,
204 DSP563XX_REG_IDX_SZ
= 38,
205 DSP563XX_REG_IDX_SC
= 39,
206 DSP563XX_REG_IDX_PC
= 40,
207 DSP563XX_REG_IDX_SR
= 41,
208 DSP563XX_REG_IDX_OMR
= 42,
209 DSP563XX_REG_IDX_LA
= 43,
210 DSP563XX_REG_IDX_LC
= 44,
211 DSP563XX_REG_IDX_VBA
= 45,
212 DSP563XX_REG_IDX_IPRC
= 46,
213 DSP563XX_REG_IDX_IPRP
= 47,
214 DSP563XX_REG_IDX_BCR
= 48,
215 DSP563XX_REG_IDX_DCR
= 49,
216 DSP563XX_REG_IDX_AAR0
= 50,
217 DSP563XX_REG_IDX_AAR1
= 51,
218 DSP563XX_REG_IDX_AAR2
= 52,
219 DSP563XX_REG_IDX_AAR3
= 53,
222 static const struct {
226 /* effective addressing mode encoding */
229 } dsp563xx_regs
[] = {
231 /* address registers */
232 {DSP563XX_REG_IDX_R0
, "r0", 24, 0x10, ASM_REG_W_R0
},
233 {DSP563XX_REG_IDX_R1
, "r1", 24, 0x11, ASM_REG_W_R1
},
234 {DSP563XX_REG_IDX_R2
, "r2", 24, 0x12, ASM_REG_W_R2
},
235 {DSP563XX_REG_IDX_R3
, "r3", 24, 0x13, ASM_REG_W_R3
},
236 {DSP563XX_REG_IDX_R4
, "r4", 24, 0x14, ASM_REG_W_R4
},
237 {DSP563XX_REG_IDX_R5
, "r5", 24, 0x15, ASM_REG_W_R5
},
238 {DSP563XX_REG_IDX_R6
, "r6", 24, 0x16, ASM_REG_W_R6
},
239 {DSP563XX_REG_IDX_R7
, "r7", 24, 0x17, ASM_REG_W_R7
},
240 /* offset registers */
241 {DSP563XX_REG_IDX_N0
, "n0", 24, 0x18, ASM_REG_W_N0
},
242 {DSP563XX_REG_IDX_N1
, "n1", 24, 0x19, ASM_REG_W_N1
},
243 {DSP563XX_REG_IDX_N2
, "n2", 24, 0x1a, ASM_REG_W_N2
},
244 {DSP563XX_REG_IDX_N3
, "n3", 24, 0x1b, ASM_REG_W_N3
},
245 {DSP563XX_REG_IDX_N4
, "n4", 24, 0x1c, ASM_REG_W_N4
},
246 {DSP563XX_REG_IDX_N5
, "n5", 24, 0x1d, ASM_REG_W_N5
},
247 {DSP563XX_REG_IDX_N6
, "n6", 24, 0x1e, ASM_REG_W_N6
},
248 {DSP563XX_REG_IDX_N7
, "n7", 24, 0x1f, ASM_REG_W_N7
},
249 /* modifier registers */
250 {DSP563XX_REG_IDX_M0
, "m0", 24, 0x20, ASM_REG_W_M0
},
251 {DSP563XX_REG_IDX_M1
, "m1", 24, 0x21, ASM_REG_W_M1
},
252 {DSP563XX_REG_IDX_M2
, "m2", 24, 0x22, ASM_REG_W_M2
},
253 {DSP563XX_REG_IDX_M3
, "m3", 24, 0x23, ASM_REG_W_M3
},
254 {DSP563XX_REG_IDX_M4
, "m4", 24, 0x24, ASM_REG_W_M4
},
255 {DSP563XX_REG_IDX_M5
, "m5", 24, 0x25, ASM_REG_W_M5
},
256 {DSP563XX_REG_IDX_M6
, "m6", 24, 0x26, ASM_REG_W_M6
},
257 {DSP563XX_REG_IDX_M7
, "m7", 24, 0x27, ASM_REG_W_M7
},
258 /* data alu input register */
259 {DSP563XX_REG_IDX_X0
, "x0", 24, 0x04, ASM_REG_W_X0
},
260 {DSP563XX_REG_IDX_X1
, "x1", 24, 0x05, ASM_REG_W_X1
},
261 {DSP563XX_REG_IDX_Y0
, "y0", 24, 0x06, ASM_REG_W_Y0
},
262 {DSP563XX_REG_IDX_Y1
, "y1", 24, 0x07, ASM_REG_W_Y1
},
263 /* data alu accumulator register */
264 {DSP563XX_REG_IDX_A0
, "a0", 24, 0x08, ASM_REG_W_A0
},
265 {DSP563XX_REG_IDX_A1
, "a1", 24, 0x0c, ASM_REG_W_A1
},
266 {DSP563XX_REG_IDX_A2
, "a2", 8, 0x0a, ASM_REG_W_A2
},
267 {DSP563XX_REG_IDX_B0
, "b0", 24, 0x09, ASM_REG_W_B0
},
268 {DSP563XX_REG_IDX_B1
, "b1", 24, 0x0d, ASM_REG_W_B1
},
269 {DSP563XX_REG_IDX_B2
, "b2", 8, 0x0b, ASM_REG_W_B2
},
271 {DSP563XX_REG_IDX_SSH
, "ssh", 24, 0x3c, ASM_REG_W_SSH
},
272 {DSP563XX_REG_IDX_SSL
, "ssl", 24, 0x3d, ASM_REG_W_SSL
},
273 {DSP563XX_REG_IDX_SP
, "sp", 24, 0x3b, ASM_REG_W_SP
},
274 {DSP563XX_REG_IDX_EP
, "ep", 24, 0x2a, ASM_REG_W_EP
},
275 {DSP563XX_REG_IDX_SZ
, "sz", 24, 0x38, ASM_REG_W_SZ
},
276 {DSP563XX_REG_IDX_SC
, "sc", 24, 0x31, ASM_REG_W_SC
},
278 {DSP563XX_REG_IDX_PC
, "pc", 24, 0x00, ASM_REG_W_PC
},
279 {DSP563XX_REG_IDX_SR
, "sr", 24, 0x39, ASM_REG_W_SR
},
280 {DSP563XX_REG_IDX_OMR
, "omr", 24, 0x3a, ASM_REG_W_OMR
},
281 {DSP563XX_REG_IDX_LA
, "la", 24, 0x3e, ASM_REG_W_LA
},
282 {DSP563XX_REG_IDX_LC
, "lc", 24, 0x3f, ASM_REG_W_LC
},
284 {DSP563XX_REG_IDX_VBA
, "vba", 24, 0x30, ASM_REG_W_VBA
},
285 {DSP563XX_REG_IDX_IPRC
, "iprc", 24, 0x00, ASM_REG_W_IPRC
},
286 {DSP563XX_REG_IDX_IPRP
, "iprp", 24, 0x00, ASM_REG_W_IPRP
},
288 {DSP563XX_REG_IDX_BCR
, "bcr", 24, 0x00, ASM_REG_W_BCR
},
289 {DSP563XX_REG_IDX_DCR
, "dcr", 24, 0x00, ASM_REG_W_DCR
},
290 {DSP563XX_REG_IDX_AAR0
, "aar0", 24, 0x00, ASM_REG_W_AAR0
},
291 {DSP563XX_REG_IDX_AAR1
, "aar1", 24, 0x00, ASM_REG_W_AAR1
},
292 {DSP563XX_REG_IDX_AAR2
, "aar2", 24, 0x00, ASM_REG_W_AAR2
},
293 {DSP563XX_REG_IDX_AAR3
, "aar3", 24, 0x00, ASM_REG_W_AAR3
},
304 enum watchpoint_condition
{
311 #define INSTR_JUMP 0x0AF080
312 /* Effective Addressing Mode Encoding */
314 /* instruction encoder */
316 * s - peripheral space X/Y (X=0,Y=1)
318 * d - source/destination register
319 * p - IO short address
321 #define INSTR_MOVEP_REG_HIO(s, w, d, p) (0x084000 | \
322 ((s & 1) << 16) | ((w & 1) << 15) | ((d & 0x3f) << 8) | (p & 0x3f))
324 /* the gdb register list is send in this order */
325 static const uint8_t gdb_reg_list_idx
[] = {
326 DSP563XX_REG_IDX_X1
, DSP563XX_REG_IDX_X0
, DSP563XX_REG_IDX_Y1
, DSP563XX_REG_IDX_Y0
,
327 DSP563XX_REG_IDX_A2
, DSP563XX_REG_IDX_A1
, DSP563XX_REG_IDX_A0
, DSP563XX_REG_IDX_B2
,
328 DSP563XX_REG_IDX_B1
, DSP563XX_REG_IDX_B0
, DSP563XX_REG_IDX_PC
, DSP563XX_REG_IDX_SR
,
329 DSP563XX_REG_IDX_OMR
, DSP563XX_REG_IDX_LA
, DSP563XX_REG_IDX_LC
, DSP563XX_REG_IDX_SSH
,
330 DSP563XX_REG_IDX_SSL
, DSP563XX_REG_IDX_SP
, DSP563XX_REG_IDX_EP
, DSP563XX_REG_IDX_SZ
,
331 DSP563XX_REG_IDX_SC
, DSP563XX_REG_IDX_VBA
, DSP563XX_REG_IDX_IPRC
, DSP563XX_REG_IDX_IPRP
,
332 DSP563XX_REG_IDX_BCR
, DSP563XX_REG_IDX_DCR
, DSP563XX_REG_IDX_AAR0
, DSP563XX_REG_IDX_AAR1
,
333 DSP563XX_REG_IDX_AAR2
, DSP563XX_REG_IDX_AAR3
, DSP563XX_REG_IDX_R0
, DSP563XX_REG_IDX_R1
,
334 DSP563XX_REG_IDX_R2
, DSP563XX_REG_IDX_R3
, DSP563XX_REG_IDX_R4
, DSP563XX_REG_IDX_R5
,
335 DSP563XX_REG_IDX_R6
, DSP563XX_REG_IDX_R7
, DSP563XX_REG_IDX_N0
, DSP563XX_REG_IDX_N1
,
336 DSP563XX_REG_IDX_N2
, DSP563XX_REG_IDX_N3
, DSP563XX_REG_IDX_N4
, DSP563XX_REG_IDX_N5
,
337 DSP563XX_REG_IDX_N6
, DSP563XX_REG_IDX_N7
, DSP563XX_REG_IDX_M0
, DSP563XX_REG_IDX_M1
,
338 DSP563XX_REG_IDX_M2
, DSP563XX_REG_IDX_M3
, DSP563XX_REG_IDX_M4
, DSP563XX_REG_IDX_M5
,
339 DSP563XX_REG_IDX_M6
, DSP563XX_REG_IDX_M7
,
342 static int dsp563xx_get_gdb_reg_list(struct target
*target
,
343 struct reg
**reg_list
[],
345 enum target_register_class reg_class
)
348 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
350 if (target
->state
!= TARGET_HALTED
)
351 return ERROR_TARGET_NOT_HALTED
;
353 *reg_list_size
= DSP563XX_NUMCOREREGS
;
354 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
357 return ERROR_COMMAND_SYNTAX_ERROR
;
359 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++)
360 (*reg_list
)[i
] = &dsp563xx
->core_cache
->reg_list
[gdb_reg_list_idx
[i
]];
366 static int dsp563xx_read_core_reg(struct target
*target
, int num
)
369 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
371 if ((num
< 0) || (num
>= DSP563XX_NUMCOREREGS
))
372 return ERROR_COMMAND_SYNTAX_ERROR
;
374 reg_value
= dsp563xx
->core_regs
[num
];
375 buf_set_u32(dsp563xx
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
376 dsp563xx
->core_cache
->reg_list
[num
].valid
= true;
377 dsp563xx
->core_cache
->reg_list
[num
].dirty
= false;
382 static int dsp563xx_write_core_reg(struct target
*target
, int num
)
385 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
387 if ((num
< 0) || (num
>= DSP563XX_NUMCOREREGS
))
388 return ERROR_COMMAND_SYNTAX_ERROR
;
390 reg_value
= buf_get_u32(dsp563xx
->core_cache
->reg_list
[num
].value
, 0, 32);
391 dsp563xx
->core_regs
[num
] = reg_value
;
392 dsp563xx
->core_cache
->reg_list
[num
].valid
= true;
393 dsp563xx
->core_cache
->reg_list
[num
].dirty
= false;
398 static int dsp563xx_get_core_reg(struct reg
*reg
)
400 struct dsp563xx_core_reg
*dsp563xx_reg
= reg
->arch_info
;
401 struct target
*target
= dsp563xx_reg
->target
;
402 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
404 LOG_DEBUG("%s", __func__
);
406 if (target
->state
!= TARGET_HALTED
)
407 return ERROR_TARGET_NOT_HALTED
;
409 return dsp563xx
->read_core_reg(target
, dsp563xx_reg
->num
);
412 static int dsp563xx_set_core_reg(struct reg
*reg
, uint8_t *buf
)
414 LOG_DEBUG("%s", __func__
);
416 struct dsp563xx_core_reg
*dsp563xx_reg
= reg
->arch_info
;
417 struct target
*target
= dsp563xx_reg
->target
;
418 uint32_t value
= buf_get_u32(buf
, 0, 32);
420 if (target
->state
!= TARGET_HALTED
)
421 return ERROR_TARGET_NOT_HALTED
;
423 buf_set_u32(reg
->value
, 0, reg
->size
, value
);
430 static const struct reg_arch_type dsp563xx_reg_type
= {
431 .get
= dsp563xx_get_core_reg
,
432 .set
= dsp563xx_set_core_reg
,
435 static void dsp563xx_build_reg_cache(struct target
*target
)
437 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
439 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
440 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
441 struct reg
*reg_list
= calloc(DSP563XX_NUMCOREREGS
, sizeof(struct reg
));
442 struct dsp563xx_core_reg
*arch_info
= malloc(
443 sizeof(struct dsp563xx_core_reg
) * DSP563XX_NUMCOREREGS
);
446 /* Build the process context cache */
447 cache
->name
= "dsp563xx registers";
449 cache
->reg_list
= reg_list
;
450 cache
->num_regs
= DSP563XX_NUMCOREREGS
;
452 dsp563xx
->core_cache
= cache
;
454 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++) {
455 arch_info
[i
].num
= dsp563xx_regs
[i
].id
;
456 arch_info
[i
].name
= dsp563xx_regs
[i
].name
;
457 arch_info
[i
].size
= dsp563xx_regs
[i
].bits
;
458 arch_info
[i
].eame
= dsp563xx_regs
[i
].eame
;
459 arch_info
[i
].instr_mask
= dsp563xx_regs
[i
].instr_mask
;
460 arch_info
[i
].target
= target
;
461 arch_info
[i
].dsp563xx_common
= dsp563xx
;
462 reg_list
[i
].name
= dsp563xx_regs
[i
].name
;
463 reg_list
[i
].size
= 32; /* dsp563xx_regs[i].bits; */
464 reg_list
[i
].value
= calloc(1, 4);
465 reg_list
[i
].dirty
= false;
466 reg_list
[i
].valid
= false;
467 reg_list
[i
].exist
= true;
468 reg_list
[i
].type
= &dsp563xx_reg_type
;
469 reg_list
[i
].arch_info
= &arch_info
[i
];
473 static int dsp563xx_read_register(struct target
*target
, int num
, int force
);
474 static int dsp563xx_write_register(struct target
*target
, int num
, int force
);
476 static int dsp563xx_reg_read_high_io(struct target
*target
, uint32_t instr_mask
, uint32_t *data
)
480 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
482 /* we use r0 to store temporary data */
483 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
484 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
486 /* move source memory to r0 */
487 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 0, EAME_R0
, instr_mask
);
488 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, instr
);
491 /* move r0 to debug register */
492 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 1, EAME_R0
, 0xfffffc);
493 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 1, instr
);
496 /* read debug register */
497 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OGDBR
, data
);
500 /* r0 is no longer valid on target */
501 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= true;
506 static int dsp563xx_reg_write_high_io(struct target
*target
, uint32_t instr_mask
, uint32_t data
)
510 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
512 /* we use r0 to store temporary data */
513 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
514 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
516 /* move data to r0 */
517 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 0, 0x60F400, data
);
520 /* move r0 to destination memory */
521 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 1, EAME_R0
, instr_mask
);
522 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 1, instr
);
526 /* r0 is no longer valid on target */
527 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= true;
532 static int dsp563xx_reg_read(struct target
*target
, uint32_t eame
, uint32_t *data
)
537 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 1, eame
, 0xfffffc);
538 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, instr
);
542 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 1, 0x000000);
545 /* read debug register */
546 return dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OGDBR
, data
);
549 static int dsp563xx_reg_write(struct target
*target
, uint32_t instr_mask
, uint32_t data
)
553 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 0, instr_mask
, data
);
557 return dsp563xx_once_execute_sw_ir(target
->tap
, 1, 0x000000);
560 static int dsp563xx_reg_pc_read(struct target
*target
)
562 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
564 /* pc was changed, nothing todo */
565 if (dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].dirty
)
568 /* conditional branch check */
569 if (once_regs
[ONCE_REG_IDX_OPABDR
].reg
== once_regs
[ONCE_REG_IDX_OPABEX
].reg
) {
570 if ((once_regs
[ONCE_REG_IDX_OPABF11
].reg
& 1) == 0) {
571 LOG_DEBUG("%s conditional branch not supported yet (0x%" PRIx32
" 0x%" PRIx32
" 0x%" PRIx32
")",
573 (once_regs
[ONCE_REG_IDX_OPABF11
].reg
>> 1),
574 once_regs
[ONCE_REG_IDX_OPABDR
].reg
,
575 once_regs
[ONCE_REG_IDX_OPABEX
].reg
);
577 /* TODO: use disassembly to set correct pc offset
578 * read 2 words from OPABF11 and disasm the instruction
580 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] =
581 (once_regs
[ONCE_REG_IDX_OPABF11
].reg
>> 1) & 0x00FFFFFF;
583 if (once_regs
[ONCE_REG_IDX_OPABEX
].reg
==
584 once_regs
[ONCE_REG_IDX_OPABFR
].reg
)
585 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] =
586 once_regs
[ONCE_REG_IDX_OPABEX
].reg
;
588 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] =
589 once_regs
[ONCE_REG_IDX_OPABEX
].reg
- 1;
592 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] = once_regs
[ONCE_REG_IDX_OPABEX
].reg
;
594 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_PC
);
599 static int dsp563xx_reg_ssh_read(struct target
*target
)
603 struct dsp563xx_core_reg
*arch_info
;
604 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
606 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSH
].arch_info
;
608 /* get a valid stack pointer */
609 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 0);
612 sp
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
];
613 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SP
, 0);
617 /* get a valid stack count */
618 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SC
, 0);
622 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SC
, 0);
626 /* get a valid extended pointer */
627 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_EP
, 0);
631 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_EP
, 0);
638 err
= dsp563xx_reg_read(target
, arch_info
->eame
, &sp
);
642 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SC
, 1);
645 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SP
, 1);
648 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_EP
, 1);
653 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SSH
] = sp
;
654 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_SSH
);
659 static int dsp563xx_reg_ssh_write(struct target
*target
)
663 struct dsp563xx_core_reg
*arch_info
;
664 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
666 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSH
].arch_info
;
668 /* get a valid stack pointer */
669 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 0);
672 sp
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
];
676 /* write new stackpointer */
677 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
] = sp
;
678 err
= dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_SP
);
681 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SP
, 1);
685 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
,
686 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SSH
]);
690 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 1);
693 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SSH
, 1);
701 static int dsp563xx_reg_ssl_read(struct target
*target
)
705 struct dsp563xx_core_reg
*arch_info
;
706 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
708 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSL
].arch_info
;
710 /* get a valid stack pointer */
711 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 0);
714 sp
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
];
719 err
= dsp563xx_reg_read(target
, arch_info
->eame
, &sp
);
724 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SSL
] = sp
;
725 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_SSL
);
730 static int dsp563xx_read_register(struct target
*target
, int num
, int force
)
734 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
735 struct dsp563xx_core_reg
*arch_info
;
738 dsp563xx
->core_cache
->reg_list
[num
].valid
= false;
740 if (!dsp563xx
->core_cache
->reg_list
[num
].valid
) {
741 arch_info
= dsp563xx
->core_cache
->reg_list
[num
].arch_info
;
743 switch (arch_info
->num
) {
744 case DSP563XX_REG_IDX_SSH
:
745 err
= dsp563xx_reg_ssh_read(target
);
747 case DSP563XX_REG_IDX_SSL
:
748 err
= dsp563xx_reg_ssl_read(target
);
750 case DSP563XX_REG_IDX_PC
:
751 err
= dsp563xx_reg_pc_read(target
);
753 case DSP563XX_REG_IDX_IPRC
:
754 case DSP563XX_REG_IDX_IPRP
:
755 case DSP563XX_REG_IDX_BCR
:
756 case DSP563XX_REG_IDX_DCR
:
757 case DSP563XX_REG_IDX_AAR0
:
758 case DSP563XX_REG_IDX_AAR1
:
759 case DSP563XX_REG_IDX_AAR2
:
760 case DSP563XX_REG_IDX_AAR3
:
761 err
= dsp563xx_reg_read_high_io(target
,
762 arch_info
->instr_mask
, &data
);
763 if (err
== ERROR_OK
) {
764 dsp563xx
->core_regs
[num
] = data
;
765 dsp563xx
->read_core_reg(target
, num
);
769 err
= dsp563xx_reg_read(target
, arch_info
->eame
, &data
);
770 if (err
== ERROR_OK
) {
771 dsp563xx
->core_regs
[num
] = data
;
772 dsp563xx
->read_core_reg(target
, num
);
781 static int dsp563xx_write_register(struct target
*target
, int num
, int force
)
784 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
785 struct dsp563xx_core_reg
*arch_info
;
788 dsp563xx
->core_cache
->reg_list
[num
].dirty
= true;
790 if (dsp563xx
->core_cache
->reg_list
[num
].dirty
) {
791 arch_info
= dsp563xx
->core_cache
->reg_list
[num
].arch_info
;
793 dsp563xx
->write_core_reg(target
, num
);
795 switch (arch_info
->num
) {
796 case DSP563XX_REG_IDX_SSH
:
797 err
= dsp563xx_reg_ssh_write(target
);
799 case DSP563XX_REG_IDX_PC
:
800 /* pc is updated on resume, no need to write it here */
802 case DSP563XX_REG_IDX_IPRC
:
803 case DSP563XX_REG_IDX_IPRP
:
804 case DSP563XX_REG_IDX_BCR
:
805 case DSP563XX_REG_IDX_DCR
:
806 case DSP563XX_REG_IDX_AAR0
:
807 case DSP563XX_REG_IDX_AAR1
:
808 case DSP563XX_REG_IDX_AAR2
:
809 case DSP563XX_REG_IDX_AAR3
:
810 err
= dsp563xx_reg_write_high_io(target
,
811 arch_info
->instr_mask
,
812 dsp563xx
->core_regs
[num
]);
815 err
= dsp563xx_reg_write(target
,
816 arch_info
->instr_mask
,
817 dsp563xx
->core_regs
[num
]);
819 if ((err
== ERROR_OK
) && (arch_info
->num
== DSP563XX_REG_IDX_SP
)) {
820 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSH
].valid
=
822 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSL
].valid
=
833 static int dsp563xx_save_context(struct target
*target
)
835 int i
, err
= ERROR_OK
;
837 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++) {
838 err
= dsp563xx_read_register(target
, i
, 0);
846 static int dsp563xx_restore_context(struct target
*target
)
848 int i
, err
= ERROR_OK
;
850 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++) {
851 err
= dsp563xx_write_register(target
, i
, 0);
859 static void dsp563xx_invalidate_x_context(struct target
*target
,
864 struct dsp563xx_core_reg
*arch_info
;
865 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
867 if (addr_start
> ASM_REG_W_IPRC
)
869 if (addr_start
< ASM_REG_W_AAR3
)
872 for (i
= DSP563XX_REG_IDX_IPRC
; i
< DSP563XX_NUMCOREREGS
; i
++) {
873 arch_info
= dsp563xx
->core_cache
->reg_list
[i
].arch_info
;
875 if ((arch_info
->instr_mask
>= addr_start
) &&
876 (arch_info
->instr_mask
<= addr_end
)) {
877 dsp563xx
->core_cache
->reg_list
[i
].valid
= false;
878 dsp563xx
->core_cache
->reg_list
[i
].dirty
= false;
883 static int dsp563xx_target_create(struct target
*target
, Jim_Interp
*interp
)
885 struct dsp563xx_common
*dsp563xx
= calloc(1, sizeof(struct dsp563xx_common
));
888 return ERROR_COMMAND_SYNTAX_ERROR
;
890 dsp563xx
->jtag_info
.tap
= target
->tap
;
891 target
->arch_info
= dsp563xx
;
892 dsp563xx
->read_core_reg
= dsp563xx_read_core_reg
;
893 dsp563xx
->write_core_reg
= dsp563xx_write_core_reg
;
898 static int dsp563xx_init_target(struct command_context
*cmd_ctx
, struct target
*target
)
900 LOG_DEBUG("%s", __func__
);
902 dsp563xx_build_reg_cache(target
);
903 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
905 dsp563xx
->hardware_breakpoints_cleared
= false;
906 dsp563xx
->hardware_breakpoint
[0].used
= BPU_NONE
;
911 static int dsp563xx_examine(struct target
*target
)
915 if (target
->tap
->hasidcode
== false) {
916 LOG_ERROR("no IDCODE present on device");
917 return ERROR_COMMAND_SYNTAX_ERROR
;
920 if (!target_was_examined(target
)) {
921 target_set_examined(target
);
923 /* examine core and chip derivate number */
924 chip
= (target
->tap
->idcode
>>12) & 0x3ff;
925 /* core number 0 means DSP563XX */
926 if (((chip
>>5)&0x1f) == 0)
929 LOG_INFO("DSP56%03" PRIu32
" device found", chip
);
931 /* Clear all breakpoints */
932 dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OBCR
, 0);
938 static int dsp563xx_arch_state(struct target
*target
)
940 LOG_DEBUG("%s", __func__
);
944 #define DSP563XX_SR_SA (1<<17)
945 #define DSP563XX_SR_SC (1<<13)
947 static int dsp563xx_debug_once_init(struct target
*target
)
949 return dsp563xx_once_read_register(target
->tap
, 1, once_regs
, DSP563XX_NUMONCEREGS
);
952 static int dsp563xx_debug_init(struct target
*target
)
956 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
957 struct dsp563xx_core_reg
*arch_info
;
959 err
= dsp563xx_debug_once_init(target
);
963 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SR
].arch_info
;
965 /* check 24bit mode */
966 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SR
, 0);
970 sr
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SR
];
972 if (sr
& (DSP563XX_SR_SA
| DSP563XX_SR_SC
)) {
973 sr
&= ~(DSP563XX_SR_SA
| DSP563XX_SR_SC
);
975 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, arch_info
->instr_mask
, sr
);
978 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SR
].dirty
= true;
981 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_N0
, 0);
984 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_N1
, 0);
987 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_M0
, 0);
990 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_M1
, 0);
994 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_N0
] != 0x000000) {
995 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N0
].arch_info
;
996 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0x000000);
1000 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N0
].dirty
= true;
1002 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_N1
] != 0x000000) {
1003 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N1
].arch_info
;
1004 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0x000000);
1005 if (err
!= ERROR_OK
)
1008 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N1
].dirty
= true;
1010 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_M0
] != 0xffffff) {
1011 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M0
].arch_info
;
1012 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0xffffff);
1013 if (err
!= ERROR_OK
)
1016 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M0
].dirty
= true;
1018 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_M1
] != 0xffffff) {
1019 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M1
].arch_info
;
1020 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0xffffff);
1021 if (err
!= ERROR_OK
)
1024 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M1
].dirty
= true;
1026 err
= dsp563xx_save_context(target
);
1027 if (err
!= ERROR_OK
)
1033 static int dsp563xx_jtag_debug_request(struct target
*target
)
1035 return dsp563xx_once_request_debug(target
->tap
, target
->state
== TARGET_RESET
);
1038 static int dsp563xx_poll(struct target
*target
)
1041 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1042 uint32_t once_status
= 0;
1045 state
= dsp563xx_once_target_status(target
->tap
);
1047 if (state
== TARGET_UNKNOWN
) {
1048 target
->state
= state
;
1049 LOG_ERROR("jtag status contains invalid mode value - communication failure");
1050 return ERROR_TARGET_FAILURE
;
1053 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OSCR
, &once_status
);
1054 if (err
!= ERROR_OK
)
1057 if ((once_status
& DSP563XX_ONCE_OSCR_DEBUG_M
) == DSP563XX_ONCE_OSCR_DEBUG_M
) {
1058 if (target
->state
!= TARGET_HALTED
) {
1059 target
->state
= TARGET_HALTED
;
1061 err
= dsp563xx_debug_init(target
);
1062 if (err
!= ERROR_OK
)
1065 if (once_status
& (DSP563XX_ONCE_OSCR_MBO
|DSP563XX_ONCE_OSCR_SWO
))
1066 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
1068 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1070 LOG_DEBUG("target->state: %s (%" PRIx32
")", target_state_name(target
), once_status
);
1071 LOG_INFO("halted: PC: 0x%" PRIx32
, dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
]);
1075 if (!dsp563xx
->hardware_breakpoints_cleared
) {
1076 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OBCR
, 0);
1077 if (err
!= ERROR_OK
)
1080 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR0
, 0);
1081 if (err
!= ERROR_OK
)
1084 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR1
, 0);
1085 if (err
!= ERROR_OK
)
1088 dsp563xx
->hardware_breakpoints_cleared
= true;
1094 static int dsp563xx_halt(struct target
*target
)
1098 LOG_DEBUG("%s", __func__
);
1100 if (target
->state
== TARGET_HALTED
) {
1101 LOG_DEBUG("target was already halted");
1105 if (target
->state
== TARGET_UNKNOWN
)
1106 LOG_WARNING("target was in unknown state when halt was requested");
1108 err
= dsp563xx_jtag_debug_request(target
);
1109 if (err
!= ERROR_OK
)
1112 target
->debug_reason
= DBG_REASON_DBGRQ
;
1117 static int dsp563xx_resume(struct target
*target
,
1119 target_addr_t address
,
1120 int handle_breakpoints
,
1121 int debug_execution
)
1124 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1126 /* check if pc was changed and resume want to execute the next address
1127 * if pc was changed from gdb or other interface we will
1128 * jump to this address and don't execute the next address
1129 * this will not affect the resume command with an address argument
1130 * because current is set to zero then
1132 if (current
&& dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].dirty
) {
1133 dsp563xx_write_core_reg(target
, DSP563XX_REG_IDX_PC
);
1134 address
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
];
1138 LOG_DEBUG("%s %08X %08X", __func__
, current
, (unsigned) address
);
1140 err
= dsp563xx_restore_context(target
);
1141 if (err
!= ERROR_OK
)
1143 register_cache_invalidate(dsp563xx
->core_cache
);
1146 /* restore pipeline registers and go */
1147 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
,
1148 once_regs
[ONCE_REG_IDX_OPILR
].reg
);
1149 if (err
!= ERROR_OK
)
1151 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
|
1152 DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
,
1153 once_regs
[ONCE_REG_IDX_OPDBR
].reg
);
1154 if (err
!= ERROR_OK
)
1157 /* set to go register and jump */
1158 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
, INSTR_JUMP
);
1159 if (err
!= ERROR_OK
)
1161 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_PDBGOTO
|
1162 DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
, address
);
1163 if (err
!= ERROR_OK
)
1167 target
->state
= TARGET_RUNNING
;
1169 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1174 static int dsp563xx_step_ex(struct target
*target
,
1177 int handle_breakpoints
,
1181 uint32_t once_status
;
1182 uint32_t dr_in
, cnt
;
1183 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1185 if (target
->state
!= TARGET_HALTED
) {
1186 LOG_DEBUG("target was not halted");
1190 /* check if pc was changed and step want to execute the next address
1191 * if pc was changed from gdb or other interface we will
1192 * jump to this address and don't execute the next address
1193 * this will not affect the step command with an address argument
1194 * because current is set to zero then
1196 if (current
&& dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].dirty
) {
1197 dsp563xx_write_core_reg(target
, DSP563XX_REG_IDX_PC
);
1198 address
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
];
1202 LOG_DEBUG("%s %08X %08X", __func__
, current
, (unsigned) address
);
1204 err
= dsp563xx_jtag_debug_request(target
);
1205 if (err
!= ERROR_OK
)
1207 err
= dsp563xx_restore_context(target
);
1208 if (err
!= ERROR_OK
)
1211 /* reset trace mode */
1212 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OSCR
, 0x000000);
1213 if (err
!= ERROR_OK
)
1215 /* enable trace mode */
1216 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OSCR
, DSP563XX_ONCE_OSCR_TME
);
1217 if (err
!= ERROR_OK
)
1222 /* on JUMP we need one extra cycle */
1226 /* load step counter with N-1 */
1227 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OTC
, cnt
);
1228 if (err
!= ERROR_OK
)
1232 /* restore pipeline registers and go */
1233 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
,
1234 once_regs
[ONCE_REG_IDX_OPILR
].reg
);
1235 if (err
!= ERROR_OK
)
1237 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
|
1238 DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
,
1239 once_regs
[ONCE_REG_IDX_OPDBR
].reg
);
1240 if (err
!= ERROR_OK
)
1243 /* set to go register and jump */
1244 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
, INSTR_JUMP
);
1245 if (err
!= ERROR_OK
)
1247 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_PDBGOTO
|
1248 DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
,
1250 if (err
!= ERROR_OK
)
1255 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OSCR
, &once_status
);
1256 if (err
!= ERROR_OK
)
1259 if (once_status
& DSP563XX_ONCE_OSCR_TO
) {
1260 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OPABFR
, &dr_in
);
1261 if (err
!= ERROR_OK
)
1263 LOG_DEBUG("fetch: %08X", (unsigned) dr_in
&0x00ffffff);
1264 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OPABDR
, &dr_in
);
1265 if (err
!= ERROR_OK
)
1267 LOG_DEBUG("decode: %08X", (unsigned) dr_in
&0x00ffffff);
1268 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OPABEX
, &dr_in
);
1269 if (err
!= ERROR_OK
)
1271 LOG_DEBUG("execute: %08X", (unsigned) dr_in
&0x00ffffff);
1273 /* reset trace mode */
1274 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OSCR
, 0x000000);
1275 if (err
!= ERROR_OK
)
1278 register_cache_invalidate(dsp563xx
->core_cache
);
1279 err
= dsp563xx_debug_init(target
);
1280 if (err
!= ERROR_OK
)
1290 static int dsp563xx_step(struct target
*target
,
1292 target_addr_t address
,
1293 int handle_breakpoints
)
1296 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1298 if (target
->state
!= TARGET_HALTED
) {
1299 LOG_WARNING("target not halted");
1300 return ERROR_TARGET_NOT_HALTED
;
1303 err
= dsp563xx_step_ex(target
, current
, address
, handle_breakpoints
, 0);
1304 if (err
!= ERROR_OK
)
1307 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1308 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1310 LOG_INFO("halted: PC: 0x%" PRIx32
, dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
]);
1315 static int dsp563xx_assert_reset(struct target
*target
)
1318 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1319 enum reset_types jtag_reset_config
= jtag_get_reset_config();
1321 if (jtag_reset_config
& RESET_HAS_SRST
) {
1322 /* default to asserting srst */
1323 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
1324 jtag_add_reset(1, 1);
1326 jtag_add_reset(0, 1);
1329 target
->state
= TARGET_RESET
;
1330 jtag_add_sleep(5000);
1332 /* registers are now invalid */
1333 register_cache_invalidate(dsp563xx
->core_cache
);
1335 if (target
->reset_halt
) {
1336 retval
= target_halt(target
);
1337 if (retval
!= ERROR_OK
)
1341 LOG_DEBUG("%s", __func__
);
1345 static int dsp563xx_deassert_reset(struct target
*target
)
1349 /* deassert reset lines */
1350 jtag_add_reset(0, 0);
1352 err
= dsp563xx_poll(target
);
1353 if (err
!= ERROR_OK
)
1356 if (target
->reset_halt
) {
1357 if (target
->state
== TARGET_HALTED
) {
1358 /* after a reset the cpu jmp to the
1359 * reset vector and need 2 cycles to fill
1360 * the cache (fetch,decode,execute)
1362 err
= dsp563xx_step_ex(target
, 1, 0, 1, 1);
1363 if (err
!= ERROR_OK
)
1367 target
->state
= TARGET_RUNNING
;
1369 LOG_DEBUG("%s", __func__
);
1373 static int dsp563xx_run_algorithm(struct target
*target
,
1374 int num_mem_params
, struct mem_param
*mem_params
,
1375 int num_reg_params
, struct reg_param
*reg_params
,
1376 target_addr_t entry_point
, target_addr_t exit_point
,
1377 int timeout_ms
, void *arch_info
)
1380 int retval
= ERROR_OK
;
1381 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1383 if (target
->state
!= TARGET_HALTED
) {
1384 LOG_WARNING("target not halted");
1385 return ERROR_TARGET_NOT_HALTED
;
1388 for (i
= 0; i
< num_mem_params
; i
++) {
1389 if (mem_params
[i
].direction
== PARAM_IN
)
1391 retval
= target_write_buffer(target
, mem_params
[i
].address
,
1392 mem_params
[i
].size
, mem_params
[i
].value
);
1393 if (retval
!= ERROR_OK
)
1397 for (i
= 0; i
< num_reg_params
; i
++) {
1398 if (reg_params
[i
].direction
== PARAM_IN
)
1401 struct reg
*reg
= register_get_by_name(dsp563xx
->core_cache
,
1402 reg_params
[i
].reg_name
,
1406 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
1410 if (reg
->size
!= reg_params
[i
].size
) {
1411 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1412 reg_params
[i
].reg_name
);
1416 retval
= dsp563xx_set_core_reg(reg
, reg_params
[i
].value
);
1417 if (retval
!= ERROR_OK
)
1422 retval
= target_resume(target
, 0, entry_point
, 1, 1);
1423 if (retval
!= ERROR_OK
)
1426 retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
);
1427 if (retval
!= ERROR_OK
)
1430 for (i
= 0; i
< num_mem_params
; i
++) {
1431 if (mem_params
[i
].direction
!= PARAM_OUT
)
1432 retval
= target_read_buffer(target
,
1433 mem_params
[i
].address
,
1435 mem_params
[i
].value
);
1436 if (retval
!= ERROR_OK
)
1440 for (i
= 0; i
< num_reg_params
; i
++) {
1441 if (reg_params
[i
].direction
!= PARAM_OUT
) {
1443 struct reg
*reg
= register_get_by_name(dsp563xx
->core_cache
,
1444 reg_params
[i
].reg_name
,
1447 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
1451 if (reg
->size
!= reg_params
[i
].size
) {
1453 "BUG: register '%s' size doesn't match reg_params[i].size",
1454 reg_params
[i
].reg_name
);
1458 buf_set_u32(reg_params
[i
].value
, 0, 32, buf_get_u32(reg
->value
, 0, 32));
1465 /* global command context from openocd.c */
1466 extern struct command_context
*global_cmd_ctx
;
1468 static int dsp563xx_get_default_memory(void)
1474 if (!global_cmd_ctx
)
1477 interp
= global_cmd_ctx
->interp
;
1482 memspace
= Jim_GetGlobalVariableStr(interp
, "memspace", JIM_NONE
);
1487 c
= (char *)Jim_GetString(memspace
, NULL
);
1506 static int dsp563xx_read_memory_core(struct target
*target
,
1514 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1516 uint32_t data
, move_cmd
= 0;
1520 "memtype: %d address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
1526 if (target
->state
!= TARGET_HALTED
) {
1527 LOG_WARNING("target not halted");
1528 return ERROR_TARGET_NOT_HALTED
;
1533 /* TODO: mark effected queued registers */
1534 move_cmd
= 0x61d800;
1537 move_cmd
= 0x69d800;
1540 move_cmd
= 0x07d891;
1543 return ERROR_COMMAND_SYNTAX_ERROR
;
1546 /* we use r0 to store temporary data */
1547 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
1548 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
1549 /* we use r1 to store temporary data */
1550 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].valid
)
1551 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R1
);
1553 /* r0 is no longer valid on target */
1554 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= true;
1555 /* r1 is no longer valid on target */
1556 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].dirty
= true;
1561 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, 0x60F400, address
);
1562 if (err
!= ERROR_OK
)
1565 for (i
= 0; i
< x
; i
++) {
1566 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, move_cmd
);
1567 if (err
!= ERROR_OK
)
1569 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, 0x08D13C);
1570 if (err
!= ERROR_OK
)
1572 err
= dsp563xx_once_reg_read(target
->tap
, 0,
1573 DSP563XX_ONCE_OGDBR
, (uint32_t *)(void *)b
);
1574 if (err
!= ERROR_OK
)
1579 /* flush the jtag queue */
1580 err
= jtag_execute_queue();
1581 if (err
!= ERROR_OK
)
1584 /* walk over the buffer and fix target endianness */
1587 for (i
= 0; i
< x
; i
++) {
1588 data
= buf_get_u32(b
, 0, 32) & 0x00FFFFFF;
1589 /* LOG_DEBUG("R: %08X", *((uint32_t*)b)); */
1590 target_buffer_set_u32(target
, b
, data
);
1597 static int dsp563xx_read_memory(struct target
*target
,
1599 target_addr_t address
,
1606 uint8_t *buffer_y
, *buffer_x
;
1608 /* if size equals zero we are called from target read memory
1609 * and have to handle the parameter here */
1610 if ((size
== 0) && (count
!= 0)) {
1614 LOG_DEBUG("size is not aligned to 4 byte");
1616 count
= (count
- size
) / 4;
1620 /* we only support 4 byte aligned data */
1621 if ((size
!= 4) || (!count
))
1622 return ERROR_COMMAND_SYNTAX_ERROR
;
1624 if (mem_type
!= MEM_L
)
1625 return dsp563xx_read_memory_core(target
, mem_type
, address
, size
, count
, buffer
);
1627 buffer_y
= malloc(size
* count
);
1629 return ERROR_COMMAND_SYNTAX_ERROR
;
1631 buffer_x
= malloc(size
* count
);
1634 return ERROR_COMMAND_SYNTAX_ERROR
;
1637 err
= dsp563xx_read_memory_core(target
, MEM_Y
, address
, size
, count
/ 2, buffer_y
);
1639 if (err
!= ERROR_OK
) {
1645 err
= dsp563xx_read_memory_core(target
, MEM_X
, address
, size
, count
/ 2, buffer_x
);
1647 if (err
!= ERROR_OK
) {
1653 for (i
= 0, i1
= 0; i
< count
; i
+= 2, i1
++) {
1654 buf_set_u32(buffer
+ i
*sizeof(uint32_t), 0, 32,
1655 buf_get_u32(buffer_y
+ i1
* sizeof(uint32_t), 0, 32));
1656 buf_set_u32(buffer
+ (i
+ 1) * sizeof(uint32_t), 0, 32,
1657 buf_get_u32(buffer_x
+ i1
* sizeof(uint32_t), 0, 32));
1666 static int dsp563xx_read_memory_default(struct target
*target
,
1667 target_addr_t address
,
1673 return dsp563xx_read_memory(target
,
1674 dsp563xx_get_default_memory(), address
, size
, count
, buffer
);
1677 static int dsp563xx_read_buffer_default(struct target
*target
,
1678 target_addr_t address
,
1683 return dsp563xx_read_memory(target
, dsp563xx_get_default_memory(), address
, size
, 0,
1687 static int dsp563xx_write_memory_core(struct target
*target
,
1689 target_addr_t address
,
1692 const uint8_t *buffer
)
1695 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1697 uint32_t data
, move_cmd
= 0;
1701 "memtype: %d address: 0x%8.8" TARGET_PRIxADDR
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
1707 if (target
->state
!= TARGET_HALTED
) {
1708 LOG_WARNING("target not halted");
1709 return ERROR_TARGET_NOT_HALTED
;
1714 /* invalidate affected x registers */
1715 dsp563xx_invalidate_x_context(target
, address
, address
+ count
- 1);
1716 move_cmd
= 0x615800;
1719 move_cmd
= 0x695800;
1722 move_cmd
= 0x075891;
1725 return ERROR_COMMAND_SYNTAX_ERROR
;
1728 /* we use r0 to store temporary data */
1729 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
1730 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
1731 /* we use r1 to store temporary data */
1732 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].valid
)
1733 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R1
);
1735 /* r0 is no longer valid on target */
1736 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= true;
1737 /* r1 is no longer valid on target */
1738 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].dirty
= true;
1743 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, 0x60F400, address
);
1744 if (err
!= ERROR_OK
)
1747 for (i
= 0; i
< x
; i
++) {
1748 data
= target_buffer_get_u32(target
, b
);
1750 /* LOG_DEBUG("W: %08X", data); */
1754 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 0, 0x61F400, data
);
1755 if (err
!= ERROR_OK
)
1757 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, move_cmd
);
1758 if (err
!= ERROR_OK
)
1763 /* flush the jtag queue */
1764 err
= jtag_execute_queue();
1765 if (err
!= ERROR_OK
)
1771 static int dsp563xx_write_memory(struct target
*target
,
1773 target_addr_t address
,
1776 const uint8_t *buffer
)
1780 uint8_t *buffer_y
, *buffer_x
;
1782 /* if size equals zero we are called from target write memory
1783 * and have to handle the parameter here */
1784 if ((size
== 0) && (count
!= 0)) {
1788 LOG_DEBUG("size is not aligned to 4 byte");
1790 count
= (count
- size
) / 4;
1794 /* we only support 4 byte aligned data */
1795 if ((size
!= 4) || (!count
))
1796 return ERROR_COMMAND_SYNTAX_ERROR
;
1798 if (mem_type
!= MEM_L
)
1799 return dsp563xx_write_memory_core(target
, mem_type
, address
, size
, count
, buffer
);
1801 buffer_y
= malloc(size
* count
);
1803 return ERROR_COMMAND_SYNTAX_ERROR
;
1805 buffer_x
= malloc(size
* count
);
1808 return ERROR_COMMAND_SYNTAX_ERROR
;
1811 for (i
= 0, i1
= 0; i
< count
; i
+= 2, i1
++) {
1812 buf_set_u32(buffer_y
+ i1
* sizeof(uint32_t), 0, 32,
1813 buf_get_u32(buffer
+ i
* sizeof(uint32_t), 0, 32));
1814 buf_set_u32(buffer_x
+ i1
* sizeof(uint32_t), 0, 32,
1815 buf_get_u32(buffer
+ (i
+ 1) * sizeof(uint32_t), 0, 32));
1818 err
= dsp563xx_write_memory_core(target
, MEM_Y
, address
, size
, count
/ 2, buffer_y
);
1820 if (err
!= ERROR_OK
) {
1826 err
= dsp563xx_write_memory_core(target
, MEM_X
, address
, size
, count
/ 2, buffer_x
);
1828 if (err
!= ERROR_OK
) {
1840 static int dsp563xx_write_memory_default(struct target
*target
,
1841 target_addr_t address
,
1844 const uint8_t *buffer
)
1846 return dsp563xx_write_memory(target
,
1847 dsp563xx_get_default_memory(), address
, size
, count
, buffer
);
1850 static int dsp563xx_write_buffer_default(struct target
*target
,
1851 target_addr_t address
,
1853 const uint8_t *buffer
)
1855 return dsp563xx_write_memory(target
, dsp563xx_get_default_memory(), address
, size
, 0,
1860 * Exit with error here, because we support watchpoints over a custom command.
1861 * This is because the DSP has separate X,Y,P memspace which is not compatible to the
1862 * traditional watchpoint logic.
1864 static int dsp563xx_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1866 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1870 * @see dsp563xx_add_watchpoint
1872 static int dsp563xx_remove_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1874 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1877 static int dsp563xx_add_custom_watchpoint(struct target
*target
, uint32_t address
, uint32_t mem_type
,
1878 enum watchpoint_rw rw
, enum watchpoint_condition cond
)
1881 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1883 bool was_running
= false;
1884 /* Only set breakpoint when halted */
1885 if (target
->state
!= TARGET_HALTED
) {
1886 dsp563xx_halt(target
);
1890 if (dsp563xx
->hardware_breakpoint
[0].used
) {
1891 LOG_ERROR("Cannot add watchpoint. Hardware resource already used.");
1892 err
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1895 uint32_t obcr_value
= 0;
1896 if (err
== ERROR_OK
) {
1897 obcr_value
|= OBCR_B0_OR_B1
;
1900 obcr_value
|= OBCR_BP_MEM_X
;
1903 obcr_value
|= OBCR_BP_MEM_Y
;
1906 obcr_value
|= OBCR_BP_MEM_P
;
1909 LOG_ERROR("Unknown mem_type parameter (%" PRIu32
")", mem_type
);
1910 err
= ERROR_TARGET_INVALID
;
1914 if (err
== ERROR_OK
) {
1917 obcr_value
|= OBCR_BP_0(OBCR_BP_ON_READ
);
1920 obcr_value
|= OBCR_BP_0(OBCR_BP_ON_WRITE
);
1923 obcr_value
|= OBCR_BP_0(OBCR_BP_ON_READ
|OBCR_BP_ON_WRITE
);
1926 LOG_ERROR("Unsupported write mode (%d)", rw
);
1927 err
= ERROR_TARGET_INVALID
;
1931 if (err
== ERROR_OK
) {
1934 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_EQUAL
);
1937 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_NOT_EQUAL
);
1940 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_LESS_THAN
);
1943 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_GREATER_THAN
);
1946 LOG_ERROR("Unsupported condition code (%d)", cond
);
1947 err
= ERROR_TARGET_INVALID
;
1951 if (err
== ERROR_OK
)
1952 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR0
, address
);
1954 if (err
== ERROR_OK
)
1955 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR1
, 0x0);
1957 if (err
== ERROR_OK
)
1958 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OBCR
, obcr_value
);
1960 if (err
== ERROR_OK
) {
1961 /* You should write the memory breakpoint counter to 0 */
1962 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMBC
, 0);
1965 if (err
== ERROR_OK
) {
1966 /* You should write the memory breakpoint counter to 0 */
1967 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OTC
, 0);
1970 if (err
== ERROR_OK
)
1971 dsp563xx
->hardware_breakpoint
[0].used
= BPU_WATCHPOINT
;
1973 if (err
== ERROR_OK
&& was_running
) {
1974 /* Resume from current PC */
1975 err
= dsp563xx_resume(target
, 1, 0x0, 0, 0);
1981 static int dsp563xx_remove_custom_watchpoint(struct target
*target
)
1984 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1986 if (dsp563xx
->hardware_breakpoint
[0].used
!= BPU_WATCHPOINT
) {
1987 LOG_ERROR("Cannot remove watchpoint, as no watchpoint is currently configured!");
1988 err
= ERROR_TARGET_INVALID
;
1991 if (err
== ERROR_OK
) {
1992 /* Clear watchpoint by clearing OBCR. */
1993 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OBCR
, 0);
1996 if (err
== ERROR_OK
)
1997 dsp563xx
->hardware_breakpoint
[0].used
= BPU_NONE
;
2002 COMMAND_HANDLER(dsp563xx_add_watchpoint_command
)
2005 struct target
*target
= get_current_target(CMD_CTX
);
2007 uint32_t mem_type
= 0;
2008 switch (CMD_NAME
[2]) {
2019 return ERROR_COMMAND_SYNTAX_ERROR
;
2023 return ERROR_COMMAND_SYNTAX_ERROR
;
2025 uint32_t address
= 0;
2027 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], address
);
2029 enum watchpoint_condition cond
;
2030 switch (CMD_ARGV
[0][0]) {
2044 return ERROR_COMMAND_SYNTAX_ERROR
;
2047 enum watchpoint_rw rw
;
2048 switch (CMD_ARGV
[1][0]) {
2059 return ERROR_COMMAND_SYNTAX_ERROR
;
2062 err
= dsp563xx_add_custom_watchpoint(target
, address
, mem_type
, rw
, cond
);
2067 /* Adding a breakpoint using the once breakpoint logic.
2068 * Note that this mechanism is a true hw breakpoint and is share between the watchpoint logic.
2069 * This means, you can only have one breakpoint/watchpoint at any time.
2071 static int dsp563xx_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
2073 return dsp563xx_add_custom_watchpoint(target
, breakpoint
->address
, MEM_P
, WPT_READ
, EQUAL
);
2076 static int dsp563xx_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
2078 return dsp563xx_remove_custom_watchpoint(target
);
2081 COMMAND_HANDLER(dsp563xx_remove_watchpoint_command
)
2083 struct target
*target
= get_current_target(CMD_CTX
);
2085 return dsp563xx_remove_custom_watchpoint(target
);
2088 COMMAND_HANDLER(dsp563xx_mem_command
)
2090 struct target
*target
= get_current_target(CMD_CTX
);
2093 uint32_t address
= 0;
2094 uint32_t count
= 1, i
;
2095 uint32_t pattern
= 0;
2097 uint8_t *buffer
, *b
;
2099 switch (CMD_NAME
[1]) {
2107 return ERROR_COMMAND_SYNTAX_ERROR
;
2110 switch (CMD_NAME
[3]) {
2121 return ERROR_COMMAND_SYNTAX_ERROR
;
2125 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
2127 if (read_mem
== 0) {
2129 return ERROR_COMMAND_SYNTAX_ERROR
;
2131 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], pattern
);
2133 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], count
);
2136 if (read_mem
== 1) {
2138 return ERROR_COMMAND_SYNTAX_ERROR
;
2140 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], count
);
2143 buffer
= calloc(count
, sizeof(uint32_t));
2145 if (read_mem
== 1) {
2146 err
= dsp563xx_read_memory(target
, mem_type
, address
, sizeof(uint32_t),
2148 if (err
== ERROR_OK
)
2149 target_handle_md_output(CMD
, target
, address
, sizeof(uint32_t), count
, buffer
);
2154 for (i
= 0; i
< count
; i
++) {
2155 target_buffer_set_u32(target
, b
, pattern
);
2159 err
= dsp563xx_write_memory(target
,
2172 static const struct command_registration dsp563xx_command_handlers
[] = {
2175 .handler
= dsp563xx_mem_command
,
2176 .mode
= COMMAND_EXEC
,
2177 .help
= "write x memory words",
2178 .usage
= "address value [count]",
2182 .handler
= dsp563xx_mem_command
,
2183 .mode
= COMMAND_EXEC
,
2184 .help
= "write y memory words",
2185 .usage
= "address value [count]",
2189 .handler
= dsp563xx_mem_command
,
2190 .mode
= COMMAND_EXEC
,
2191 .help
= "write p memory words",
2192 .usage
= "address value [count]",
2196 .handler
= dsp563xx_mem_command
,
2197 .mode
= COMMAND_EXEC
,
2198 .help
= "display x memory words",
2199 .usage
= "address [count]",
2203 .handler
= dsp563xx_mem_command
,
2204 .mode
= COMMAND_EXEC
,
2205 .help
= "display y memory words",
2206 .usage
= "address [count]",
2210 .handler
= dsp563xx_mem_command
,
2211 .mode
= COMMAND_EXEC
,
2212 .help
= "display p memory words",
2213 .usage
= "address [count]",
2216 * Watchpoint commands
2220 .handler
= dsp563xx_add_watchpoint_command
,
2221 .mode
= COMMAND_EXEC
,
2222 .help
= "Create p memspace watchpoint",
2223 .usage
= "(>|<|=|!) (r|w|a) address",
2227 .handler
= dsp563xx_add_watchpoint_command
,
2228 .mode
= COMMAND_EXEC
,
2229 .help
= "Create x memspace watchpoint",
2230 .usage
= "(>|<|=|!) (r|w|a) address",
2234 .handler
= dsp563xx_add_watchpoint_command
,
2235 .mode
= COMMAND_EXEC
,
2236 .help
= "Create y memspace watchpoint",
2237 .usage
= "(>|<|=|!) (r|w|a) address",
2241 .handler
= dsp563xx_remove_watchpoint_command
,
2242 .mode
= COMMAND_EXEC
,
2243 .help
= "remove watchpoint custom",
2246 COMMAND_REGISTRATION_DONE
2249 /** Holds methods for DSP563XX targets. */
2250 struct target_type dsp563xx_target
= {
2253 .poll
= dsp563xx_poll
,
2254 .arch_state
= dsp563xx_arch_state
,
2256 .get_gdb_reg_list
= dsp563xx_get_gdb_reg_list
,
2258 .halt
= dsp563xx_halt
,
2259 .resume
= dsp563xx_resume
,
2260 .step
= dsp563xx_step
,
2262 .assert_reset
= dsp563xx_assert_reset
,
2263 .deassert_reset
= dsp563xx_deassert_reset
,
2265 .read_memory
= dsp563xx_read_memory_default
,
2266 .write_memory
= dsp563xx_write_memory_default
,
2268 .read_buffer
= dsp563xx_read_buffer_default
,
2269 .write_buffer
= dsp563xx_write_buffer_default
,
2271 .run_algorithm
= dsp563xx_run_algorithm
,
2273 .add_breakpoint
= dsp563xx_add_breakpoint
,
2274 .remove_breakpoint
= dsp563xx_remove_breakpoint
,
2275 .add_watchpoint
= dsp563xx_add_watchpoint
,
2276 .remove_watchpoint
= dsp563xx_remove_watchpoint
,
2278 .commands
= dsp563xx_command_handlers
,
2279 .target_create
= dsp563xx_target_create
,
2280 .init_target
= dsp563xx_init_target
,
2281 .examine
= dsp563xx_examine
,
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)