jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / target / dsp563xx.c
1 /***************************************************************************
2 * Copyright (C) 2009-2011 by Mathias Kuester *
3 * mkdorg@users.sourceforge.net *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include <jim.h>
24
25 #include "target.h"
26 #include "breakpoints.h"
27 #include "target_type.h"
28 #include "algorithm.h"
29 #include "register.h"
30 #include "dsp563xx.h"
31 #include "dsp563xx_once.h"
32
33 #define ASM_REG_W_R0 0x60F400
34 #define ASM_REG_W_R1 0x61F400
35 #define ASM_REG_W_R2 0x62F400
36 #define ASM_REG_W_R3 0x63F400
37 #define ASM_REG_W_R4 0x64F400
38 #define ASM_REG_W_R5 0x65F400
39 #define ASM_REG_W_R6 0x66F400
40 #define ASM_REG_W_R7 0x67F400
41
42 #define ASM_REG_W_N0 0x70F400
43 #define ASM_REG_W_N1 0x71F400
44 #define ASM_REG_W_N2 0x72F400
45 #define ASM_REG_W_N3 0x73F400
46 #define ASM_REG_W_N4 0x74F400
47 #define ASM_REG_W_N5 0x75F400
48 #define ASM_REG_W_N6 0x76F400
49 #define ASM_REG_W_N7 0x77F400
50
51 #define ASM_REG_W_M0 0x05F420
52 #define ASM_REG_W_M1 0x05F421
53 #define ASM_REG_W_M2 0x05F422
54 #define ASM_REG_W_M3 0x05F423
55 #define ASM_REG_W_M4 0x05F424
56 #define ASM_REG_W_M5 0x05F425
57 #define ASM_REG_W_M6 0x05F426
58 #define ASM_REG_W_M7 0x05F427
59
60 #define ASM_REG_W_X0 0x44F400
61 #define ASM_REG_W_X1 0x45F400
62
63 #define ASM_REG_W_Y0 0x46F400
64 #define ASM_REG_W_Y1 0x47F400
65
66 #define ASM_REG_W_A0 0x50F400
67 #define ASM_REG_W_A1 0x54F400
68 #define ASM_REG_W_A2 0x52F400
69
70 #define ASM_REG_W_B0 0x51F400
71 #define ASM_REG_W_B1 0x55F400
72 #define ASM_REG_W_B2 0x53F400
73
74 #define ASM_REG_W_VBA 0x05F430
75 #define ASM_REG_W_OMR 0x05F43A
76 #define ASM_REG_W_EP 0x05F42A
77 #define ASM_REG_W_SC 0x05F431
78 #define ASM_REG_W_SZ 0x05F438
79 #define ASM_REG_W_SR 0x05F439
80 #define ASM_REG_W_SP 0x05F43B
81 #define ASM_REG_W_SSH 0x05F43C
82 #define ASM_REG_W_SSL 0x05F43D
83 #define ASM_REG_W_LA 0x05F43E
84 #define ASM_REG_W_LC 0x05F43F
85 #define ASM_REG_W_PC 0x000000
86 #define ASM_REG_W_IPRC 0xFFFFFF
87 #define ASM_REG_W_IPRP 0xFFFFFE
88
89 #define ASM_REG_W_BCR 0xFFFFFB
90 #define ASM_REG_W_DCR 0xFFFFFA
91 #define ASM_REG_W_AAR0 0xFFFFF9
92 #define ASM_REG_W_AAR1 0xFFFFF8
93 #define ASM_REG_W_AAR2 0xFFFFF7
94 #define ASM_REG_W_AAR3 0xFFFFF6
95
96 /*
97 * OBCR Register bit definitions
98 */
99 #define OBCR_b0_and_b1 ((0x0) << 10)
100 #define OBCR_b0_or_b1 ((0x1) << 10)
101 #define OBCR_b1_after_b0 ((0x2) << 10)
102 #define OBCR_b0_after_b1 ((0x3) << 10)
103
104 #define OBCR_BP_DISABLED (0x0)
105 #define OBCR_BP_MEM_P (0x1)
106 #define OBCR_BP_MEM_X (0x2)
107 #define OBCR_BP_MEM_Y (0x3)
108 #define OBCR_BP_ON_READ ((0x2) << 0)
109 #define OBCR_BP_ON_WRITE ((0x1) << 0)
110 #define OBCR_BP_CC_NOT_EQUAL ((0x0) << 2)
111 #define OBCR_BP_CC_EQUAL ((0x1) << 2)
112 #define OBCR_BP_CC_LESS_THAN ((0x2) << 2)
113 #define OBCR_BP_CC_GREATER_THAN ((0x3) << 2)
114
115 #define OBCR_BP_0(x) ((x)<<2)
116 #define OBCR_BP_1(x) ((x)<<6)
117
118
119 enum once_reg_idx {
120 ONCE_REG_IDX_OSCR = 0,
121 ONCE_REG_IDX_OMBC = 1,
122 ONCE_REG_IDX_OBCR = 2,
123 ONCE_REG_IDX_OMLR0 = 3,
124 ONCE_REG_IDX_OMLR1 = 4,
125 ONCE_REG_IDX_OGDBR = 5,
126 ONCE_REG_IDX_OPDBR = 6,
127 ONCE_REG_IDX_OPILR = 7,
128 ONCE_REG_IDX_PDB = 8,
129 ONCE_REG_IDX_OTC = 9,
130 ONCE_REG_IDX_OPABFR = 10,
131 ONCE_REG_IDX_OPABDR = 11,
132 ONCE_REG_IDX_OPABEX = 12,
133 ONCE_REG_IDX_OPABF0 = 13,
134 ONCE_REG_IDX_OPABF1 = 14,
135 ONCE_REG_IDX_OPABF2 = 15,
136 ONCE_REG_IDX_OPABF3 = 16,
137 ONCE_REG_IDX_OPABF4 = 17,
138 ONCE_REG_IDX_OPABF5 = 18,
139 ONCE_REG_IDX_OPABF6 = 19,
140 ONCE_REG_IDX_OPABF7 = 20,
141 ONCE_REG_IDX_OPABF8 = 21,
142 ONCE_REG_IDX_OPABF9 = 22,
143 ONCE_REG_IDX_OPABF10 = 23,
144 ONCE_REG_IDX_OPABF11 = 24,
145 };
146
147 static struct once_reg once_regs[] = {
148 {ONCE_REG_IDX_OSCR, DSP563XX_ONCE_OSCR, 24, "OSCR", 0},
149 {ONCE_REG_IDX_OMBC, DSP563XX_ONCE_OMBC, 24, "OMBC", 0},
150 {ONCE_REG_IDX_OBCR, DSP563XX_ONCE_OBCR, 24, "OBCR", 0},
151 {ONCE_REG_IDX_OMLR0, DSP563XX_ONCE_OMLR0, 24, "OMLR0", 0},
152 {ONCE_REG_IDX_OMLR1, DSP563XX_ONCE_OMLR1, 24, "OMLR1", 0},
153 {ONCE_REG_IDX_OGDBR, DSP563XX_ONCE_OGDBR, 24, "OGDBR", 0},
154 {ONCE_REG_IDX_OPDBR, DSP563XX_ONCE_OPDBR, 24, "OPDBR", 0},
155 {ONCE_REG_IDX_OPILR, DSP563XX_ONCE_OPILR, 24, "OPILR", 0},
156 {ONCE_REG_IDX_PDB, DSP563XX_ONCE_PDBGOTO, 24, "PDB", 0},
157 {ONCE_REG_IDX_OTC, DSP563XX_ONCE_OTC, 24, "OTC", 0},
158 {ONCE_REG_IDX_OPABFR, DSP563XX_ONCE_OPABFR, 24, "OPABFR", 0},
159 {ONCE_REG_IDX_OPABDR, DSP563XX_ONCE_OPABDR, 24, "OPABDR", 0},
160 {ONCE_REG_IDX_OPABEX, DSP563XX_ONCE_OPABEX, 24, "OPABEX", 0},
161 {ONCE_REG_IDX_OPABF0, DSP563XX_ONCE_OPABF11, 25, "OPABF0", 0},
162 {ONCE_REG_IDX_OPABF1, DSP563XX_ONCE_OPABF11, 25, "OPABF1", 0},
163 {ONCE_REG_IDX_OPABF2, DSP563XX_ONCE_OPABF11, 25, "OPABF2", 0},
164 {ONCE_REG_IDX_OPABF3, DSP563XX_ONCE_OPABF11, 25, "OPABF3", 0},
165 {ONCE_REG_IDX_OPABF4, DSP563XX_ONCE_OPABF11, 25, "OPABF4", 0},
166 {ONCE_REG_IDX_OPABF5, DSP563XX_ONCE_OPABF11, 25, "OPABF5", 0},
167 {ONCE_REG_IDX_OPABF6, DSP563XX_ONCE_OPABF11, 25, "OPABF6", 0},
168 {ONCE_REG_IDX_OPABF7, DSP563XX_ONCE_OPABF11, 25, "OPABF7", 0},
169 {ONCE_REG_IDX_OPABF8, DSP563XX_ONCE_OPABF11, 25, "OPABF8", 0},
170 {ONCE_REG_IDX_OPABF9, DSP563XX_ONCE_OPABF11, 25, "OPABF9", 0},
171 {ONCE_REG_IDX_OPABF10, DSP563XX_ONCE_OPABF11, 25, "OPABF10", 0},
172 {ONCE_REG_IDX_OPABF11, DSP563XX_ONCE_OPABF11, 25, "OPABF11", 0},
173 /* {25,0x1f,24,"NRSEL",0}, */
174 };
175
176 enum dsp563xx_reg_idx {
177 DSP563XX_REG_IDX_R0 = 0,
178 DSP563XX_REG_IDX_R1 = 1,
179 DSP563XX_REG_IDX_R2 = 2,
180 DSP563XX_REG_IDX_R3 = 3,
181 DSP563XX_REG_IDX_R4 = 4,
182 DSP563XX_REG_IDX_R5 = 5,
183 DSP563XX_REG_IDX_R6 = 6,
184 DSP563XX_REG_IDX_R7 = 7,
185 DSP563XX_REG_IDX_N0 = 8,
186 DSP563XX_REG_IDX_N1 = 9,
187 DSP563XX_REG_IDX_N2 = 10,
188 DSP563XX_REG_IDX_N3 = 11,
189 DSP563XX_REG_IDX_N4 = 12,
190 DSP563XX_REG_IDX_N5 = 13,
191 DSP563XX_REG_IDX_N6 = 14,
192 DSP563XX_REG_IDX_N7 = 15,
193 DSP563XX_REG_IDX_M0 = 16,
194 DSP563XX_REG_IDX_M1 = 17,
195 DSP563XX_REG_IDX_M2 = 18,
196 DSP563XX_REG_IDX_M3 = 19,
197 DSP563XX_REG_IDX_M4 = 20,
198 DSP563XX_REG_IDX_M5 = 21,
199 DSP563XX_REG_IDX_M6 = 22,
200 DSP563XX_REG_IDX_M7 = 23,
201 DSP563XX_REG_IDX_X0 = 24,
202 DSP563XX_REG_IDX_X1 = 25,
203 DSP563XX_REG_IDX_Y0 = 26,
204 DSP563XX_REG_IDX_Y1 = 27,
205 DSP563XX_REG_IDX_A0 = 28,
206 DSP563XX_REG_IDX_A1 = 29,
207 DSP563XX_REG_IDX_A2 = 30,
208 DSP563XX_REG_IDX_B0 = 31,
209 DSP563XX_REG_IDX_B1 = 32,
210 DSP563XX_REG_IDX_B2 = 33,
211 DSP563XX_REG_IDX_SSH = 34,
212 DSP563XX_REG_IDX_SSL = 35,
213 DSP563XX_REG_IDX_SP = 36,
214 DSP563XX_REG_IDX_EP = 37,
215 DSP563XX_REG_IDX_SZ = 38,
216 DSP563XX_REG_IDX_SC = 39,
217 DSP563XX_REG_IDX_PC = 40,
218 DSP563XX_REG_IDX_SR = 41,
219 DSP563XX_REG_IDX_OMR = 42,
220 DSP563XX_REG_IDX_LA = 43,
221 DSP563XX_REG_IDX_LC = 44,
222 DSP563XX_REG_IDX_VBA = 45,
223 DSP563XX_REG_IDX_IPRC = 46,
224 DSP563XX_REG_IDX_IPRP = 47,
225 DSP563XX_REG_IDX_BCR = 48,
226 DSP563XX_REG_IDX_DCR = 49,
227 DSP563XX_REG_IDX_AAR0 = 50,
228 DSP563XX_REG_IDX_AAR1 = 51,
229 DSP563XX_REG_IDX_AAR2 = 52,
230 DSP563XX_REG_IDX_AAR3 = 53,
231 };
232
233 static const struct {
234 unsigned id;
235 const char *name;
236 unsigned bits;
237 /* effective addressing mode encoding */
238 uint8_t eame;
239 uint32_t instr_mask;
240 } dsp563xx_regs[] = {
241 /* *INDENT-OFF* */
242 /* address registers */
243 {DSP563XX_REG_IDX_R0, "r0", 24, 0x10, ASM_REG_W_R0},
244 {DSP563XX_REG_IDX_R1, "r1", 24, 0x11, ASM_REG_W_R1},
245 {DSP563XX_REG_IDX_R2, "r2", 24, 0x12, ASM_REG_W_R2},
246 {DSP563XX_REG_IDX_R3, "r3", 24, 0x13, ASM_REG_W_R3},
247 {DSP563XX_REG_IDX_R4, "r4", 24, 0x14, ASM_REG_W_R4},
248 {DSP563XX_REG_IDX_R5, "r5", 24, 0x15, ASM_REG_W_R5},
249 {DSP563XX_REG_IDX_R6, "r6", 24, 0x16, ASM_REG_W_R6},
250 {DSP563XX_REG_IDX_R7, "r7", 24, 0x17, ASM_REG_W_R7},
251 /* offset registers */
252 {DSP563XX_REG_IDX_N0, "n0", 24, 0x18, ASM_REG_W_N0},
253 {DSP563XX_REG_IDX_N1, "n1", 24, 0x19, ASM_REG_W_N1},
254 {DSP563XX_REG_IDX_N2, "n2", 24, 0x1a, ASM_REG_W_N2},
255 {DSP563XX_REG_IDX_N3, "n3", 24, 0x1b, ASM_REG_W_N3},
256 {DSP563XX_REG_IDX_N4, "n4", 24, 0x1c, ASM_REG_W_N4},
257 {DSP563XX_REG_IDX_N5, "n5", 24, 0x1d, ASM_REG_W_N5},
258 {DSP563XX_REG_IDX_N6, "n6", 24, 0x1e, ASM_REG_W_N6},
259 {DSP563XX_REG_IDX_N7, "n7", 24, 0x1f, ASM_REG_W_N7},
260 /* modifier registers */
261 {DSP563XX_REG_IDX_M0, "m0", 24, 0x20, ASM_REG_W_M0},
262 {DSP563XX_REG_IDX_M1, "m1", 24, 0x21, ASM_REG_W_M1},
263 {DSP563XX_REG_IDX_M2, "m2", 24, 0x22, ASM_REG_W_M2},
264 {DSP563XX_REG_IDX_M3, "m3", 24, 0x23, ASM_REG_W_M3},
265 {DSP563XX_REG_IDX_M4, "m4", 24, 0x24, ASM_REG_W_M4},
266 {DSP563XX_REG_IDX_M5, "m5", 24, 0x25, ASM_REG_W_M5},
267 {DSP563XX_REG_IDX_M6, "m6", 24, 0x26, ASM_REG_W_M6},
268 {DSP563XX_REG_IDX_M7, "m7", 24, 0x27, ASM_REG_W_M7},
269 /* data alu input register */
270 {DSP563XX_REG_IDX_X0, "x0", 24, 0x04, ASM_REG_W_X0},
271 {DSP563XX_REG_IDX_X1, "x1", 24, 0x05, ASM_REG_W_X1},
272 {DSP563XX_REG_IDX_Y0, "y0", 24, 0x06, ASM_REG_W_Y0},
273 {DSP563XX_REG_IDX_Y1, "y1", 24, 0x07, ASM_REG_W_Y1},
274 /* data alu accumulator register */
275 {DSP563XX_REG_IDX_A0, "a0", 24, 0x08, ASM_REG_W_A0},
276 {DSP563XX_REG_IDX_A1, "a1", 24, 0x0c, ASM_REG_W_A1},
277 {DSP563XX_REG_IDX_A2, "a2", 8, 0x0a, ASM_REG_W_A2},
278 {DSP563XX_REG_IDX_B0, "b0", 24, 0x09, ASM_REG_W_B0},
279 {DSP563XX_REG_IDX_B1, "b1", 24, 0x0d, ASM_REG_W_B1},
280 {DSP563XX_REG_IDX_B2, "b2", 8, 0x0b, ASM_REG_W_B2},
281 /* stack */
282 {DSP563XX_REG_IDX_SSH, "ssh", 24, 0x3c, ASM_REG_W_SSH},
283 {DSP563XX_REG_IDX_SSL, "ssl", 24, 0x3d, ASM_REG_W_SSL},
284 {DSP563XX_REG_IDX_SP, "sp", 24, 0x3b, ASM_REG_W_SP},
285 {DSP563XX_REG_IDX_EP, "ep", 24, 0x2a, ASM_REG_W_EP},
286 {DSP563XX_REG_IDX_SZ, "sz", 24, 0x38, ASM_REG_W_SZ},
287 {DSP563XX_REG_IDX_SC, "sc", 24, 0x31, ASM_REG_W_SC},
288 /* system */
289 {DSP563XX_REG_IDX_PC, "pc", 24, 0x00, ASM_REG_W_PC},
290 {DSP563XX_REG_IDX_SR, "sr", 24, 0x39, ASM_REG_W_SR},
291 {DSP563XX_REG_IDX_OMR, "omr", 24, 0x3a, ASM_REG_W_OMR},
292 {DSP563XX_REG_IDX_LA, "la", 24, 0x3e, ASM_REG_W_LA},
293 {DSP563XX_REG_IDX_LC, "lc", 24, 0x3f, ASM_REG_W_LC},
294 /* interrupt */
295 {DSP563XX_REG_IDX_VBA, "vba", 24, 0x30, ASM_REG_W_VBA},
296 {DSP563XX_REG_IDX_IPRC, "iprc", 24, 0x00, ASM_REG_W_IPRC},
297 {DSP563XX_REG_IDX_IPRP, "iprp", 24, 0x00, ASM_REG_W_IPRP},
298 /* port a */
299 {DSP563XX_REG_IDX_BCR, "bcr", 24, 0x00, ASM_REG_W_BCR},
300 {DSP563XX_REG_IDX_DCR, "dcr", 24, 0x00, ASM_REG_W_DCR},
301 {DSP563XX_REG_IDX_AAR0, "aar0", 24, 0x00, ASM_REG_W_AAR0},
302 {DSP563XX_REG_IDX_AAR1, "aar1", 24, 0x00, ASM_REG_W_AAR1},
303 {DSP563XX_REG_IDX_AAR2, "aar2", 24, 0x00, ASM_REG_W_AAR2},
304 {DSP563XX_REG_IDX_AAR3, "aar3", 24, 0x00, ASM_REG_W_AAR3},
305 /* *INDENT-ON* */
306 };
307
308 enum memory_type {
309 MEM_X = 0,
310 MEM_Y = 1,
311 MEM_P = 2,
312 MEM_L = 3,
313 };
314
315 enum watchpoint_condition {
316 EQUAL,
317 NOT_EQUAL,
318 GREATER,
319 LESS_THAN
320 };
321
322 #define INSTR_JUMP 0x0AF080
323 /* Effective Addressing Mode Encoding */
324 #define EAME_R0 0x10
325 /* instrcution encoder */
326 /* movep
327 * s - peripheral space X/Y (X=0,Y=1)
328 * w - write/read
329 * d - source/destination register
330 * p - IO short address
331 */
332 #define INSTR_MOVEP_REG_HIO(s, w, d, p) (0x084000 | \
333 ((s & 1) << 16) | ((w & 1) << 15) | ((d & 0x3f) << 8) | (p & 0x3f))
334
335 /* the gdb register list is send in this order */
336 static const uint8_t gdb_reg_list_idx[] = {
337 DSP563XX_REG_IDX_X1, DSP563XX_REG_IDX_X0, DSP563XX_REG_IDX_Y1, DSP563XX_REG_IDX_Y0,
338 DSP563XX_REG_IDX_A2, DSP563XX_REG_IDX_A1, DSP563XX_REG_IDX_A0, DSP563XX_REG_IDX_B2,
339 DSP563XX_REG_IDX_B1, DSP563XX_REG_IDX_B0, DSP563XX_REG_IDX_PC, DSP563XX_REG_IDX_SR,
340 DSP563XX_REG_IDX_OMR, DSP563XX_REG_IDX_LA, DSP563XX_REG_IDX_LC, DSP563XX_REG_IDX_SSH,
341 DSP563XX_REG_IDX_SSL, DSP563XX_REG_IDX_SP, DSP563XX_REG_IDX_EP, DSP563XX_REG_IDX_SZ,
342 DSP563XX_REG_IDX_SC, DSP563XX_REG_IDX_VBA, DSP563XX_REG_IDX_IPRC, DSP563XX_REG_IDX_IPRP,
343 DSP563XX_REG_IDX_BCR, DSP563XX_REG_IDX_DCR, DSP563XX_REG_IDX_AAR0, DSP563XX_REG_IDX_AAR1,
344 DSP563XX_REG_IDX_AAR2, DSP563XX_REG_IDX_AAR3, DSP563XX_REG_IDX_R0, DSP563XX_REG_IDX_R1,
345 DSP563XX_REG_IDX_R2, DSP563XX_REG_IDX_R3, DSP563XX_REG_IDX_R4, DSP563XX_REG_IDX_R5,
346 DSP563XX_REG_IDX_R6, DSP563XX_REG_IDX_R7, DSP563XX_REG_IDX_N0, DSP563XX_REG_IDX_N1,
347 DSP563XX_REG_IDX_N2, DSP563XX_REG_IDX_N3, DSP563XX_REG_IDX_N4, DSP563XX_REG_IDX_N5,
348 DSP563XX_REG_IDX_N6, DSP563XX_REG_IDX_N7, DSP563XX_REG_IDX_M0, DSP563XX_REG_IDX_M1,
349 DSP563XX_REG_IDX_M2, DSP563XX_REG_IDX_M3, DSP563XX_REG_IDX_M4, DSP563XX_REG_IDX_M5,
350 DSP563XX_REG_IDX_M6, DSP563XX_REG_IDX_M7,
351 };
352
353 static int dsp563xx_get_gdb_reg_list(struct target *target,
354 struct reg **reg_list[],
355 int *reg_list_size,
356 enum target_register_class reg_class)
357 {
358 int i;
359 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
360
361 if (target->state != TARGET_HALTED)
362 return ERROR_TARGET_NOT_HALTED;
363
364 *reg_list_size = DSP563XX_NUMCOREREGS;
365 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
366
367 if (!*reg_list)
368 return ERROR_COMMAND_SYNTAX_ERROR;
369
370 for (i = 0; i < DSP563XX_NUMCOREREGS; i++)
371 (*reg_list)[i] = &dsp563xx->core_cache->reg_list[gdb_reg_list_idx[i]];
372
373 return ERROR_OK;
374
375 }
376
377 static int dsp563xx_read_core_reg(struct target *target, int num)
378 {
379 uint32_t reg_value;
380 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
381
382 if ((num < 0) || (num >= DSP563XX_NUMCOREREGS))
383 return ERROR_COMMAND_SYNTAX_ERROR;
384
385 reg_value = dsp563xx->core_regs[num];
386 buf_set_u32(dsp563xx->core_cache->reg_list[num].value, 0, 32, reg_value);
387 dsp563xx->core_cache->reg_list[num].valid = true;
388 dsp563xx->core_cache->reg_list[num].dirty = false;
389
390 return ERROR_OK;
391 }
392
393 static int dsp563xx_write_core_reg(struct target *target, int num)
394 {
395 uint32_t reg_value;
396 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
397
398 if ((num < 0) || (num >= DSP563XX_NUMCOREREGS))
399 return ERROR_COMMAND_SYNTAX_ERROR;
400
401 reg_value = buf_get_u32(dsp563xx->core_cache->reg_list[num].value, 0, 32);
402 dsp563xx->core_regs[num] = reg_value;
403 dsp563xx->core_cache->reg_list[num].valid = true;
404 dsp563xx->core_cache->reg_list[num].dirty = false;
405
406 return ERROR_OK;
407 }
408
409 static int dsp563xx_get_core_reg(struct reg *reg)
410 {
411 struct dsp563xx_core_reg *dsp563xx_reg = reg->arch_info;
412 struct target *target = dsp563xx_reg->target;
413 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
414
415 LOG_DEBUG("%s", __func__);
416
417 if (target->state != TARGET_HALTED)
418 return ERROR_TARGET_NOT_HALTED;
419
420 return dsp563xx->read_core_reg(target, dsp563xx_reg->num);
421 }
422
423 static int dsp563xx_set_core_reg(struct reg *reg, uint8_t *buf)
424 {
425 LOG_DEBUG("%s", __func__);
426
427 struct dsp563xx_core_reg *dsp563xx_reg = reg->arch_info;
428 struct target *target = dsp563xx_reg->target;
429 uint32_t value = buf_get_u32(buf, 0, 32);
430
431 if (target->state != TARGET_HALTED)
432 return ERROR_TARGET_NOT_HALTED;
433
434 buf_set_u32(reg->value, 0, reg->size, value);
435 reg->dirty = true;
436 reg->valid = true;
437
438 return ERROR_OK;
439 }
440
441 static const struct reg_arch_type dsp563xx_reg_type = {
442 .get = dsp563xx_get_core_reg,
443 .set = dsp563xx_set_core_reg,
444 };
445
446 static void dsp563xx_build_reg_cache(struct target *target)
447 {
448 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
449
450 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
451 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
452 struct reg *reg_list = calloc(DSP563XX_NUMCOREREGS, sizeof(struct reg));
453 struct dsp563xx_core_reg *arch_info = malloc(
454 sizeof(struct dsp563xx_core_reg) * DSP563XX_NUMCOREREGS);
455 int i;
456
457 /* Build the process context cache */
458 cache->name = "dsp563xx registers";
459 cache->next = NULL;
460 cache->reg_list = reg_list;
461 cache->num_regs = DSP563XX_NUMCOREREGS;
462 (*cache_p) = cache;
463 dsp563xx->core_cache = cache;
464
465 for (i = 0; i < DSP563XX_NUMCOREREGS; i++) {
466 arch_info[i].num = dsp563xx_regs[i].id;
467 arch_info[i].name = dsp563xx_regs[i].name;
468 arch_info[i].size = dsp563xx_regs[i].bits;
469 arch_info[i].eame = dsp563xx_regs[i].eame;
470 arch_info[i].instr_mask = dsp563xx_regs[i].instr_mask;
471 arch_info[i].target = target;
472 arch_info[i].dsp563xx_common = dsp563xx;
473 reg_list[i].name = dsp563xx_regs[i].name;
474 reg_list[i].size = 32; /* dsp563xx_regs[i].bits; */
475 reg_list[i].value = calloc(1, 4);
476 reg_list[i].dirty = false;
477 reg_list[i].valid = false;
478 reg_list[i].exist = true;
479 reg_list[i].type = &dsp563xx_reg_type;
480 reg_list[i].arch_info = &arch_info[i];
481 }
482 }
483
484 static int dsp563xx_read_register(struct target *target, int num, int force);
485 static int dsp563xx_write_register(struct target *target, int num, int force);
486
487 static int dsp563xx_reg_read_high_io(struct target *target, uint32_t instr_mask, uint32_t *data)
488 {
489 int err;
490 uint32_t instr;
491 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
492
493 /* we use r0 to store temporary data */
494 if (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].valid)
495 dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R0);
496
497 /* move source memory to r0 */
498 instr = INSTR_MOVEP_REG_HIO(MEM_X, 0, EAME_R0, instr_mask);
499 err = dsp563xx_once_execute_sw_ir(target->tap, 0, instr);
500 if (err != ERROR_OK)
501 return err;
502 /* move r0 to debug register */
503 instr = INSTR_MOVEP_REG_HIO(MEM_X, 1, EAME_R0, 0xfffffc);
504 err = dsp563xx_once_execute_sw_ir(target->tap, 1, instr);
505 if (err != ERROR_OK)
506 return err;
507 /* read debug register */
508 err = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OGDBR, data);
509 if (err != ERROR_OK)
510 return err;
511 /* r0 is no longer valid on target */
512 dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].dirty = true;
513
514 return ERROR_OK;
515 }
516
517 static int dsp563xx_reg_write_high_io(struct target *target, uint32_t instr_mask, uint32_t data)
518 {
519 int err;
520 uint32_t instr;
521 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
522
523 /* we use r0 to store temporary data */
524 if (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].valid)
525 dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R0);
526
527 /* move data to r0 */
528 err = dsp563xx_once_execute_dw_ir(target->tap, 0, 0x60F400, data);
529 if (err != ERROR_OK)
530 return err;
531 /* move r0 to destination memory */
532 instr = INSTR_MOVEP_REG_HIO(MEM_X, 1, EAME_R0, instr_mask);
533 err = dsp563xx_once_execute_sw_ir(target->tap, 1, instr);
534 if (err != ERROR_OK)
535 return err;
536
537 /* r0 is no longer valid on target */
538 dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].dirty = true;
539
540 return ERROR_OK;
541 }
542
543 static int dsp563xx_reg_read(struct target *target, uint32_t eame, uint32_t *data)
544 {
545 int err;
546 uint32_t instr;
547
548 instr = INSTR_MOVEP_REG_HIO(MEM_X, 1, eame, 0xfffffc);
549 err = dsp563xx_once_execute_sw_ir(target->tap, 0, instr);
550 if (err != ERROR_OK)
551 return err;
552 /* nop */
553 err = dsp563xx_once_execute_sw_ir(target->tap, 1, 0x000000);
554 if (err != ERROR_OK)
555 return err;
556 /* read debug register */
557 return dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OGDBR, data);
558 }
559
560 static int dsp563xx_reg_write(struct target *target, uint32_t instr_mask, uint32_t data)
561 {
562 int err;
563
564 err = dsp563xx_once_execute_dw_ir(target->tap, 0, instr_mask, data);
565 if (err != ERROR_OK)
566 return err;
567 /* nop */
568 return dsp563xx_once_execute_sw_ir(target->tap, 1, 0x000000);
569 }
570
571 static int dsp563xx_reg_pc_read(struct target *target)
572 {
573 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
574
575 /* pc was changed, nothing todo */
576 if (dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_PC].dirty)
577 return ERROR_OK;
578
579 /* conditional branch check */
580 if (once_regs[ONCE_REG_IDX_OPABDR].reg == once_regs[ONCE_REG_IDX_OPABEX].reg) {
581 if ((once_regs[ONCE_REG_IDX_OPABF11].reg & 1) == 0) {
582 LOG_DEBUG("%s conditional branch not supported yet (0x%" PRIx32 " 0x%" PRIx32 " 0x%" PRIx32 ")",
583 __func__,
584 (once_regs[ONCE_REG_IDX_OPABF11].reg >> 1),
585 once_regs[ONCE_REG_IDX_OPABDR].reg,
586 once_regs[ONCE_REG_IDX_OPABEX].reg);
587
588 /* TODO: use disassembly to set correct pc offset
589 * read 2 words from OPABF11 and disasm the instruction
590 */
591 dsp563xx->core_regs[DSP563XX_REG_IDX_PC] =
592 (once_regs[ONCE_REG_IDX_OPABF11].reg >> 1) & 0x00FFFFFF;
593 } else {
594 if (once_regs[ONCE_REG_IDX_OPABEX].reg ==
595 once_regs[ONCE_REG_IDX_OPABFR].reg)
596 dsp563xx->core_regs[DSP563XX_REG_IDX_PC] =
597 once_regs[ONCE_REG_IDX_OPABEX].reg;
598 else
599 dsp563xx->core_regs[DSP563XX_REG_IDX_PC] =
600 once_regs[ONCE_REG_IDX_OPABEX].reg - 1;
601 }
602 } else
603 dsp563xx->core_regs[DSP563XX_REG_IDX_PC] = once_regs[ONCE_REG_IDX_OPABEX].reg;
604
605 dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_PC);
606
607 return ERROR_OK;
608 }
609
610 static int dsp563xx_reg_ssh_read(struct target *target)
611 {
612 int err;
613 uint32_t sp;
614 struct dsp563xx_core_reg *arch_info;
615 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
616
617 arch_info = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_SSH].arch_info;
618
619 /* get a valid stack pointer */
620 err = dsp563xx_read_register(target, DSP563XX_REG_IDX_SP, 0);
621 if (err != ERROR_OK)
622 return err;
623 sp = dsp563xx->core_regs[DSP563XX_REG_IDX_SP];
624 err = dsp563xx_write_register(target, DSP563XX_REG_IDX_SP, 0);
625 if (err != ERROR_OK)
626 return err;
627
628 /* get a valid stack count */
629 err = dsp563xx_read_register(target, DSP563XX_REG_IDX_SC, 0);
630 if (err != ERROR_OK)
631 return err;
632
633 err = dsp563xx_write_register(target, DSP563XX_REG_IDX_SC, 0);
634 if (err != ERROR_OK)
635 return err;
636
637 /* get a valid extended pointer */
638 err = dsp563xx_read_register(target, DSP563XX_REG_IDX_EP, 0);
639 if (err != ERROR_OK)
640 return err;
641
642 err = dsp563xx_write_register(target, DSP563XX_REG_IDX_EP, 0);
643 if (err != ERROR_OK)
644 return err;
645
646 if (!sp)
647 sp = 0x00FFFFFF;
648 else {
649 err = dsp563xx_reg_read(target, arch_info->eame, &sp);
650 if (err != ERROR_OK)
651 return err;
652
653 err = dsp563xx_write_register(target, DSP563XX_REG_IDX_SC, 1);
654 if (err != ERROR_OK)
655 return err;
656 err = dsp563xx_write_register(target, DSP563XX_REG_IDX_SP, 1);
657 if (err != ERROR_OK)
658 return err;
659 err = dsp563xx_write_register(target, DSP563XX_REG_IDX_EP, 1);
660 if (err != ERROR_OK)
661 return err;
662 }
663
664 dsp563xx->core_regs[DSP563XX_REG_IDX_SSH] = sp;
665 dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_SSH);
666
667 return ERROR_OK;
668 }
669
670 static int dsp563xx_reg_ssh_write(struct target *target)
671 {
672 int err;
673 uint32_t sp;
674 struct dsp563xx_core_reg *arch_info;
675 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
676
677 arch_info = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_SSH].arch_info;
678
679 /* get a valid stack pointer */
680 err = dsp563xx_read_register(target, DSP563XX_REG_IDX_SP, 0);
681 if (err != ERROR_OK)
682 return err;
683 sp = dsp563xx->core_regs[DSP563XX_REG_IDX_SP];
684
685 if (sp) {
686 sp--;
687 /* write new stackpointer */
688 dsp563xx->core_regs[DSP563XX_REG_IDX_SP] = sp;
689 err = dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_SP);
690 if (err != ERROR_OK)
691 return err;
692 err = dsp563xx_write_register(target, DSP563XX_REG_IDX_SP, 1);
693 if (err != ERROR_OK)
694 return err;
695
696 err = dsp563xx_reg_write(target, arch_info->instr_mask,
697 dsp563xx->core_regs[DSP563XX_REG_IDX_SSH]);
698 if (err != ERROR_OK)
699 return err;
700
701 err = dsp563xx_read_register(target, DSP563XX_REG_IDX_SP, 1);
702 if (err != ERROR_OK)
703 return err;
704 err = dsp563xx_read_register(target, DSP563XX_REG_IDX_SSH, 1);
705 if (err != ERROR_OK)
706 return err;
707 }
708
709 return ERROR_OK;
710 }
711
712 static int dsp563xx_reg_ssl_read(struct target *target)
713 {
714 int err;
715 uint32_t sp;
716 struct dsp563xx_core_reg *arch_info;
717 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
718
719 arch_info = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_SSL].arch_info;
720
721 /* get a valid stack pointer */
722 err = dsp563xx_read_register(target, DSP563XX_REG_IDX_SP, 0);
723 if (err != ERROR_OK)
724 return err;
725 sp = dsp563xx->core_regs[DSP563XX_REG_IDX_SP];
726
727 if (!sp)
728 sp = 0x00FFFFFF;
729 else {
730 err = dsp563xx_reg_read(target, arch_info->eame, &sp);
731 if (err != ERROR_OK)
732 return err;
733 }
734
735 dsp563xx->core_regs[DSP563XX_REG_IDX_SSL] = sp;
736 dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_SSL);
737
738 return ERROR_OK;
739 }
740
741 static int dsp563xx_read_register(struct target *target, int num, int force)
742 {
743 int err = ERROR_OK;
744 uint32_t data = 0;
745 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
746 struct dsp563xx_core_reg *arch_info;
747
748 if (force)
749 dsp563xx->core_cache->reg_list[num].valid = false;
750
751 if (!dsp563xx->core_cache->reg_list[num].valid) {
752 arch_info = dsp563xx->core_cache->reg_list[num].arch_info;
753
754 switch (arch_info->num) {
755 case DSP563XX_REG_IDX_SSH:
756 err = dsp563xx_reg_ssh_read(target);
757 break;
758 case DSP563XX_REG_IDX_SSL:
759 err = dsp563xx_reg_ssl_read(target);
760 break;
761 case DSP563XX_REG_IDX_PC:
762 err = dsp563xx_reg_pc_read(target);
763 break;
764 case DSP563XX_REG_IDX_IPRC:
765 case DSP563XX_REG_IDX_IPRP:
766 case DSP563XX_REG_IDX_BCR:
767 case DSP563XX_REG_IDX_DCR:
768 case DSP563XX_REG_IDX_AAR0:
769 case DSP563XX_REG_IDX_AAR1:
770 case DSP563XX_REG_IDX_AAR2:
771 case DSP563XX_REG_IDX_AAR3:
772 err = dsp563xx_reg_read_high_io(target,
773 arch_info->instr_mask, &data);
774 if (err == ERROR_OK) {
775 dsp563xx->core_regs[num] = data;
776 dsp563xx->read_core_reg(target, num);
777 }
778 break;
779 default:
780 err = dsp563xx_reg_read(target, arch_info->eame, &data);
781 if (err == ERROR_OK) {
782 dsp563xx->core_regs[num] = data;
783 dsp563xx->read_core_reg(target, num);
784 }
785 break;
786 }
787 }
788
789 return err;
790 }
791
792 static int dsp563xx_write_register(struct target *target, int num, int force)
793 {
794 int err = ERROR_OK;
795 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
796 struct dsp563xx_core_reg *arch_info;
797
798 if (force)
799 dsp563xx->core_cache->reg_list[num].dirty = true;
800
801 if (dsp563xx->core_cache->reg_list[num].dirty) {
802 arch_info = dsp563xx->core_cache->reg_list[num].arch_info;
803
804 dsp563xx->write_core_reg(target, num);
805
806 switch (arch_info->num) {
807 case DSP563XX_REG_IDX_SSH:
808 err = dsp563xx_reg_ssh_write(target);
809 break;
810 case DSP563XX_REG_IDX_PC:
811 /* pc is updated on resume, no need to write it here */
812 break;
813 case DSP563XX_REG_IDX_IPRC:
814 case DSP563XX_REG_IDX_IPRP:
815 case DSP563XX_REG_IDX_BCR:
816 case DSP563XX_REG_IDX_DCR:
817 case DSP563XX_REG_IDX_AAR0:
818 case DSP563XX_REG_IDX_AAR1:
819 case DSP563XX_REG_IDX_AAR2:
820 case DSP563XX_REG_IDX_AAR3:
821 err = dsp563xx_reg_write_high_io(target,
822 arch_info->instr_mask,
823 dsp563xx->core_regs[num]);
824 break;
825 default:
826 err = dsp563xx_reg_write(target,
827 arch_info->instr_mask,
828 dsp563xx->core_regs[num]);
829
830 if ((err == ERROR_OK) && (arch_info->num == DSP563XX_REG_IDX_SP)) {
831 dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_SSH].valid =
832 0;
833 dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_SSL].valid =
834 0;
835 }
836
837 break;
838 }
839 }
840
841 return err;
842 }
843
844 static int dsp563xx_save_context(struct target *target)
845 {
846 int i, err = ERROR_OK;
847
848 for (i = 0; i < DSP563XX_NUMCOREREGS; i++) {
849 err = dsp563xx_read_register(target, i, 0);
850 if (err != ERROR_OK)
851 break;
852 }
853
854 return err;
855 }
856
857 static int dsp563xx_restore_context(struct target *target)
858 {
859 int i, err = ERROR_OK;
860
861 for (i = 0; i < DSP563XX_NUMCOREREGS; i++) {
862 err = dsp563xx_write_register(target, i, 0);
863 if (err != ERROR_OK)
864 break;
865 }
866
867 return err;
868 }
869
870 static void dsp563xx_invalidate_x_context(struct target *target,
871 uint32_t addr_start,
872 uint32_t addr_end)
873 {
874 int i;
875 struct dsp563xx_core_reg *arch_info;
876 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
877
878 if (addr_start > ASM_REG_W_IPRC)
879 return;
880 if (addr_start < ASM_REG_W_AAR3)
881 return;
882
883 for (i = DSP563XX_REG_IDX_IPRC; i < DSP563XX_NUMCOREREGS; i++) {
884 arch_info = dsp563xx->core_cache->reg_list[i].arch_info;
885
886 if ((arch_info->instr_mask >= addr_start) &&
887 (arch_info->instr_mask <= addr_end)) {
888 dsp563xx->core_cache->reg_list[i].valid = false;
889 dsp563xx->core_cache->reg_list[i].dirty = false;
890 }
891 }
892 }
893
894 static int dsp563xx_target_create(struct target *target, Jim_Interp *interp)
895 {
896 struct dsp563xx_common *dsp563xx = calloc(1, sizeof(struct dsp563xx_common));
897
898 if (!dsp563xx)
899 return ERROR_COMMAND_SYNTAX_ERROR;
900
901 dsp563xx->jtag_info.tap = target->tap;
902 target->arch_info = dsp563xx;
903 dsp563xx->read_core_reg = dsp563xx_read_core_reg;
904 dsp563xx->write_core_reg = dsp563xx_write_core_reg;
905
906 return ERROR_OK;
907 }
908
909 static int dsp563xx_init_target(struct command_context *cmd_ctx, struct target *target)
910 {
911 LOG_DEBUG("%s", __func__);
912
913 dsp563xx_build_reg_cache(target);
914 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
915
916 dsp563xx->hardware_breakpoints_cleared = 0;
917 dsp563xx->hardware_breakpoint[0].used = BPU_NONE;
918
919 return ERROR_OK;
920 }
921
922 static int dsp563xx_examine(struct target *target)
923 {
924 uint32_t chip;
925
926 if (target->tap->hasidcode == false) {
927 LOG_ERROR("no IDCODE present on device");
928 return ERROR_COMMAND_SYNTAX_ERROR;
929 }
930
931 if (!target_was_examined(target)) {
932 target_set_examined(target);
933
934 /* examine core and chip derivate number */
935 chip = (target->tap->idcode>>12) & 0x3ff;
936 /* core number 0 means DSP563XX */
937 if (((chip>>5)&0x1f) == 0)
938 chip += 300;
939
940 LOG_INFO("DSP56%03" PRId32 " device found", chip);
941
942 /* Clear all breakpoints */
943 dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OBCR, 0);
944 }
945
946 return ERROR_OK;
947 }
948
949 static int dsp563xx_arch_state(struct target *target)
950 {
951 LOG_DEBUG("%s", __func__);
952 return ERROR_OK;
953 }
954
955 #define DSP563XX_SR_SA (1<<17)
956 #define DSP563XX_SR_SC (1<<13)
957
958 static int dsp563xx_debug_once_init(struct target *target)
959 {
960 return dsp563xx_once_read_register(target->tap, 1, once_regs, DSP563XX_NUMONCEREGS);
961 }
962
963 static int dsp563xx_debug_init(struct target *target)
964 {
965 int err;
966 uint32_t sr;
967 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
968 struct dsp563xx_core_reg *arch_info;
969
970 err = dsp563xx_debug_once_init(target);
971 if (err != ERROR_OK)
972 return err;
973
974 arch_info = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_SR].arch_info;
975
976 /* check 24bit mode */
977 err = dsp563xx_read_register(target, DSP563XX_REG_IDX_SR, 0);
978 if (err != ERROR_OK)
979 return err;
980
981 sr = dsp563xx->core_regs[DSP563XX_REG_IDX_SR];
982
983 if (sr & (DSP563XX_SR_SA | DSP563XX_SR_SC)) {
984 sr &= ~(DSP563XX_SR_SA | DSP563XX_SR_SC);
985
986 err = dsp563xx_once_execute_dw_ir(target->tap, 1, arch_info->instr_mask, sr);
987 if (err != ERROR_OK)
988 return err;
989 dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_SR].dirty = true;
990 }
991
992 err = dsp563xx_read_register(target, DSP563XX_REG_IDX_N0, 0);
993 if (err != ERROR_OK)
994 return err;
995 err = dsp563xx_read_register(target, DSP563XX_REG_IDX_N1, 0);
996 if (err != ERROR_OK)
997 return err;
998 err = dsp563xx_read_register(target, DSP563XX_REG_IDX_M0, 0);
999 if (err != ERROR_OK)
1000 return err;
1001 err = dsp563xx_read_register(target, DSP563XX_REG_IDX_M1, 0);
1002 if (err != ERROR_OK)
1003 return err;
1004
1005 if (dsp563xx->core_regs[DSP563XX_REG_IDX_N0] != 0x000000) {
1006 arch_info = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_N0].arch_info;
1007 err = dsp563xx_reg_write(target, arch_info->instr_mask, 0x000000);
1008 if (err != ERROR_OK)
1009 return err;
1010 }
1011 dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_N0].dirty = true;
1012
1013 if (dsp563xx->core_regs[DSP563XX_REG_IDX_N1] != 0x000000) {
1014 arch_info = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_N1].arch_info;
1015 err = dsp563xx_reg_write(target, arch_info->instr_mask, 0x000000);
1016 if (err != ERROR_OK)
1017 return err;
1018 }
1019 dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_N1].dirty = true;
1020
1021 if (dsp563xx->core_regs[DSP563XX_REG_IDX_M0] != 0xffffff) {
1022 arch_info = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_M0].arch_info;
1023 err = dsp563xx_reg_write(target, arch_info->instr_mask, 0xffffff);
1024 if (err != ERROR_OK)
1025 return err;
1026 }
1027 dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_M0].dirty = true;
1028
1029 if (dsp563xx->core_regs[DSP563XX_REG_IDX_M1] != 0xffffff) {
1030 arch_info = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_M1].arch_info;
1031 err = dsp563xx_reg_write(target, arch_info->instr_mask, 0xffffff);
1032 if (err != ERROR_OK)
1033 return err;
1034 }
1035 dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_M1].dirty = true;
1036
1037 err = dsp563xx_save_context(target);
1038 if (err != ERROR_OK)
1039 return err;
1040
1041 return ERROR_OK;
1042 }
1043
1044 static int dsp563xx_jtag_debug_request(struct target *target)
1045 {
1046 return dsp563xx_once_request_debug(target->tap, target->state == TARGET_RESET);
1047 }
1048
1049 static int dsp563xx_poll(struct target *target)
1050 {
1051 int err;
1052 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
1053 uint32_t once_status = 0;
1054 int state;
1055
1056 state = dsp563xx_once_target_status(target->tap);
1057
1058 if (state == TARGET_UNKNOWN) {
1059 target->state = state;
1060 LOG_ERROR("jtag status contains invalid mode value - communication failure");
1061 return ERROR_TARGET_FAILURE;
1062 }
1063
1064 err = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OSCR, &once_status);
1065 if (err != ERROR_OK)
1066 return err;
1067
1068 if ((once_status & DSP563XX_ONCE_OSCR_DEBUG_M) == DSP563XX_ONCE_OSCR_DEBUG_M) {
1069 if (target->state != TARGET_HALTED) {
1070 target->state = TARGET_HALTED;
1071
1072 err = dsp563xx_debug_init(target);
1073 if (err != ERROR_OK)
1074 return err;
1075
1076 if (once_status & (DSP563XX_ONCE_OSCR_MBO|DSP563XX_ONCE_OSCR_SWO))
1077 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
1078 else
1079 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1080
1081 LOG_DEBUG("target->state: %s (%" PRIx32 ")", target_state_name(target), once_status);
1082 LOG_INFO("halted: PC: 0x%" PRIx32, dsp563xx->core_regs[DSP563XX_REG_IDX_PC]);
1083 }
1084 }
1085
1086 if (!dsp563xx->hardware_breakpoints_cleared) {
1087 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OBCR, 0);
1088 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMLR0, 0);
1089 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMLR1, 0);
1090 dsp563xx->hardware_breakpoints_cleared = 1;
1091 }
1092
1093 return ERROR_OK;
1094 }
1095
1096 static int dsp563xx_halt(struct target *target)
1097 {
1098 int err;
1099
1100 LOG_DEBUG("%s", __func__);
1101
1102 if (target->state == TARGET_HALTED) {
1103 LOG_DEBUG("target was already halted");
1104 return ERROR_OK;
1105 }
1106
1107 if (target->state == TARGET_UNKNOWN)
1108 LOG_WARNING("target was in unknown state when halt was requested");
1109
1110 err = dsp563xx_jtag_debug_request(target);
1111 if (err != ERROR_OK)
1112 return err;
1113
1114 target->debug_reason = DBG_REASON_DBGRQ;
1115
1116 return ERROR_OK;
1117 }
1118
1119 static int dsp563xx_resume(struct target *target,
1120 int current,
1121 target_addr_t address,
1122 int handle_breakpoints,
1123 int debug_execution)
1124 {
1125 int err;
1126 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
1127
1128 /* check if pc was changed and resume want to execute the next address
1129 * if pc was changed from gdb or other interface we will
1130 * jump to this address and don't execute the next address
1131 * this will not affect the resume command with an address argument
1132 * because current is set to zero then
1133 */
1134 if (current && dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_PC].dirty) {
1135 dsp563xx_write_core_reg(target, DSP563XX_REG_IDX_PC);
1136 address = dsp563xx->core_regs[DSP563XX_REG_IDX_PC];
1137 current = 0;
1138 }
1139
1140 LOG_DEBUG("%s %08X %08X", __func__, current, (unsigned) address);
1141
1142 err = dsp563xx_restore_context(target);
1143 if (err != ERROR_OK)
1144 return err;
1145 register_cache_invalidate(dsp563xx->core_cache);
1146
1147 if (current) {
1148 /* restore pipeline registers and go */
1149 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR,
1150 once_regs[ONCE_REG_IDX_OPILR].reg);
1151 if (err != ERROR_OK)
1152 return err;
1153 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR |
1154 DSP563XX_ONCE_OCR_EX | DSP563XX_ONCE_OCR_GO,
1155 once_regs[ONCE_REG_IDX_OPDBR].reg);
1156 if (err != ERROR_OK)
1157 return err;
1158 } else {
1159 /* set to go register and jump */
1160 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR, INSTR_JUMP);
1161 if (err != ERROR_OK)
1162 return err;
1163 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_PDBGOTO |
1164 DSP563XX_ONCE_OCR_EX | DSP563XX_ONCE_OCR_GO, address);
1165 if (err != ERROR_OK)
1166 return err;
1167 }
1168
1169 target->state = TARGET_RUNNING;
1170
1171 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
1172
1173 return ERROR_OK;
1174 }
1175
1176 static int dsp563xx_step_ex(struct target *target,
1177 int current,
1178 uint32_t address,
1179 int handle_breakpoints,
1180 int steps)
1181 {
1182 int err;
1183 uint32_t once_status;
1184 uint32_t dr_in, cnt;
1185 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
1186
1187 if (target->state != TARGET_HALTED) {
1188 LOG_DEBUG("target was not halted");
1189 return ERROR_OK;
1190 }
1191
1192 /* check if pc was changed and step want to execute the next address
1193 * if pc was changed from gdb or other interface we will
1194 * jump to this address and don't execute the next address
1195 * this will not affect the step command with an address argument
1196 * because current is set to zero then
1197 */
1198 if (current && dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_PC].dirty) {
1199 dsp563xx_write_core_reg(target, DSP563XX_REG_IDX_PC);
1200 address = dsp563xx->core_regs[DSP563XX_REG_IDX_PC];
1201 current = 0;
1202 }
1203
1204 LOG_DEBUG("%s %08X %08X", __func__, current, (unsigned) address);
1205
1206 err = dsp563xx_jtag_debug_request(target);
1207 if (err != ERROR_OK)
1208 return err;
1209 err = dsp563xx_restore_context(target);
1210 if (err != ERROR_OK)
1211 return err;
1212
1213 /* reset trace mode */
1214 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OSCR, 0x000000);
1215 if (err != ERROR_OK)
1216 return err;
1217 /* enable trace mode */
1218 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OSCR, DSP563XX_ONCE_OSCR_TME);
1219 if (err != ERROR_OK)
1220 return err;
1221
1222 cnt = steps;
1223
1224 /* on JUMP we need one extra cycle */
1225 if (!current)
1226 cnt++;
1227
1228 /* load step counter with N-1 */
1229 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OTC, cnt);
1230 if (err != ERROR_OK)
1231 return err;
1232
1233 if (current) {
1234 /* restore pipeline registers and go */
1235 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR,
1236 once_regs[ONCE_REG_IDX_OPILR].reg);
1237 if (err != ERROR_OK)
1238 return err;
1239 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR |
1240 DSP563XX_ONCE_OCR_EX | DSP563XX_ONCE_OCR_GO,
1241 once_regs[ONCE_REG_IDX_OPDBR].reg);
1242 if (err != ERROR_OK)
1243 return err;
1244 } else {
1245 /* set to go register and jump */
1246 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR, INSTR_JUMP);
1247 if (err != ERROR_OK)
1248 return err;
1249 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_PDBGOTO |
1250 DSP563XX_ONCE_OCR_EX | DSP563XX_ONCE_OCR_GO,
1251 address);
1252 if (err != ERROR_OK)
1253 return err;
1254 }
1255
1256 while (1) {
1257 err = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OSCR, &once_status);
1258 if (err != ERROR_OK)
1259 return err;
1260
1261 if (once_status & DSP563XX_ONCE_OSCR_TO) {
1262 err = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OPABFR, &dr_in);
1263 if (err != ERROR_OK)
1264 return err;
1265 LOG_DEBUG("fetch: %08X", (unsigned) dr_in&0x00ffffff);
1266 err = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OPABDR, &dr_in);
1267 if (err != ERROR_OK)
1268 return err;
1269 LOG_DEBUG("decode: %08X", (unsigned) dr_in&0x00ffffff);
1270 err = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OPABEX, &dr_in);
1271 if (err != ERROR_OK)
1272 return err;
1273 LOG_DEBUG("execute: %08X", (unsigned) dr_in&0x00ffffff);
1274
1275 /* reset trace mode */
1276 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OSCR, 0x000000);
1277 if (err != ERROR_OK)
1278 return err;
1279
1280 register_cache_invalidate(dsp563xx->core_cache);
1281 err = dsp563xx_debug_init(target);
1282 if (err != ERROR_OK)
1283 return err;
1284
1285 break;
1286 }
1287 }
1288
1289 return ERROR_OK;
1290 }
1291
1292 static int dsp563xx_step(struct target *target,
1293 int current,
1294 target_addr_t address,
1295 int handle_breakpoints)
1296 {
1297 int err;
1298 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
1299
1300 if (target->state != TARGET_HALTED) {
1301 LOG_WARNING("target not halted");
1302 return ERROR_TARGET_NOT_HALTED;
1303 }
1304
1305 err = dsp563xx_step_ex(target, current, address, handle_breakpoints, 0);
1306 if (err != ERROR_OK)
1307 return err;
1308
1309 target->debug_reason = DBG_REASON_SINGLESTEP;
1310 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1311
1312 LOG_INFO("halted: PC: 0x%" PRIx32, dsp563xx->core_regs[DSP563XX_REG_IDX_PC]);
1313
1314 return err;
1315 }
1316
1317 static int dsp563xx_assert_reset(struct target *target)
1318 {
1319 int retval = 0;
1320 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
1321 enum reset_types jtag_reset_config = jtag_get_reset_config();
1322
1323 if (jtag_reset_config & RESET_HAS_SRST) {
1324 /* default to asserting srst */
1325 if (jtag_reset_config & RESET_SRST_PULLS_TRST)
1326 jtag_add_reset(1, 1);
1327 else
1328 jtag_add_reset(0, 1);
1329 }
1330
1331 target->state = TARGET_RESET;
1332 jtag_add_sleep(5000);
1333
1334 /* registers are now invalid */
1335 register_cache_invalidate(dsp563xx->core_cache);
1336
1337 if (target->reset_halt) {
1338 retval = target_halt(target);
1339 if (retval != ERROR_OK)
1340 return retval;
1341 }
1342
1343 LOG_DEBUG("%s", __func__);
1344 return ERROR_OK;
1345 }
1346
1347 static int dsp563xx_deassert_reset(struct target *target)
1348 {
1349 int err;
1350
1351 /* deassert reset lines */
1352 jtag_add_reset(0, 0);
1353
1354 err = dsp563xx_poll(target);
1355 if (err != ERROR_OK)
1356 return err;
1357
1358 if (target->reset_halt) {
1359 if (target->state == TARGET_HALTED) {
1360 /* after a reset the cpu jmp to the
1361 * reset vector and need 2 cycles to fill
1362 * the cache (fetch,decode,excecute)
1363 */
1364 err = dsp563xx_step_ex(target, 1, 0, 1, 1);
1365 if (err != ERROR_OK)
1366 return err;
1367 }
1368 } else
1369 target->state = TARGET_RUNNING;
1370
1371 LOG_DEBUG("%s", __func__);
1372 return ERROR_OK;
1373 }
1374
1375 static int dsp563xx_run_algorithm(struct target *target,
1376 int num_mem_params, struct mem_param *mem_params,
1377 int num_reg_params, struct reg_param *reg_params,
1378 target_addr_t entry_point, target_addr_t exit_point,
1379 int timeout_ms, void *arch_info)
1380 {
1381 int i;
1382 int retval = ERROR_OK;
1383 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
1384
1385 if (target->state != TARGET_HALTED) {
1386 LOG_WARNING("target not halted");
1387 return ERROR_TARGET_NOT_HALTED;
1388 }
1389
1390 for (i = 0; i < num_mem_params; i++) {
1391 if (mem_params[i].direction == PARAM_IN)
1392 continue;
1393 retval = target_write_buffer(target, mem_params[i].address,
1394 mem_params[i].size, mem_params[i].value);
1395 if (retval != ERROR_OK)
1396 return retval;
1397 }
1398
1399 for (i = 0; i < num_reg_params; i++) {
1400 if (reg_params[i].direction == PARAM_IN)
1401 continue;
1402
1403 struct reg *reg = register_get_by_name(dsp563xx->core_cache,
1404 reg_params[i].reg_name,
1405 0);
1406
1407 if (!reg) {
1408 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
1409 continue;
1410 }
1411
1412 if (reg->size != reg_params[i].size) {
1413 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1414 reg_params[i].reg_name);
1415 continue;
1416 }
1417
1418 retval = dsp563xx_set_core_reg(reg, reg_params[i].value);
1419 if (retval != ERROR_OK)
1420 return retval;
1421 }
1422
1423 /* exec */
1424 retval = target_resume(target, 0, entry_point, 1, 1);
1425 if (retval != ERROR_OK)
1426 return retval;
1427
1428 retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
1429 if (retval != ERROR_OK)
1430 return retval;
1431
1432 for (i = 0; i < num_mem_params; i++) {
1433 if (mem_params[i].direction != PARAM_OUT)
1434 retval = target_read_buffer(target,
1435 mem_params[i].address,
1436 mem_params[i].size,
1437 mem_params[i].value);
1438 if (retval != ERROR_OK)
1439 return retval;
1440 }
1441
1442 for (i = 0; i < num_reg_params; i++) {
1443 if (reg_params[i].direction != PARAM_OUT) {
1444
1445 struct reg *reg = register_get_by_name(dsp563xx->core_cache,
1446 reg_params[i].reg_name,
1447 0);
1448 if (!reg) {
1449 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
1450 continue;
1451 }
1452
1453 if (reg->size != reg_params[i].size) {
1454 LOG_ERROR(
1455 "BUG: register '%s' size doesn't match reg_params[i].size",
1456 reg_params[i].reg_name);
1457 continue;
1458 }
1459
1460 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
1461 }
1462 }
1463
1464 return ERROR_OK;
1465 }
1466
1467 /* global command context from openocd.c */
1468 extern struct command_context *global_cmd_ctx;
1469
1470 static int dsp563xx_get_default_memory(void)
1471 {
1472 Jim_Interp *interp;
1473 Jim_Obj *memspace;
1474 char *c;
1475
1476 if (!global_cmd_ctx)
1477 return MEM_P;
1478
1479 interp = global_cmd_ctx->interp;
1480
1481 if (!interp)
1482 return MEM_P;
1483
1484 memspace = Jim_GetGlobalVariableStr(interp, "memspace", JIM_NONE);
1485
1486 if (!memspace)
1487 return MEM_P;
1488
1489 c = (char *)Jim_GetString(memspace, NULL);
1490
1491 if (!c)
1492 return MEM_P;
1493
1494 switch (c[0]) {
1495 case '1':
1496 return MEM_X;
1497 case '2':
1498 return MEM_Y;
1499 case '3':
1500 return MEM_L;
1501 default:
1502 break;
1503 }
1504
1505 return MEM_P;
1506 }
1507
1508 static int dsp563xx_read_memory_core(struct target *target,
1509 int mem_type,
1510 uint32_t address,
1511 uint32_t size,
1512 uint32_t count,
1513 uint8_t *buffer)
1514 {
1515 int err;
1516 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
1517 uint32_t i, x;
1518 uint32_t data, move_cmd = 0;
1519 uint8_t *b;
1520
1521 LOG_DEBUG(
1522 "memtype: %d address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
1523 mem_type,
1524 address,
1525 size,
1526 count);
1527
1528 if (target->state != TARGET_HALTED) {
1529 LOG_WARNING("target not halted");
1530 return ERROR_TARGET_NOT_HALTED;
1531 }
1532
1533 switch (mem_type) {
1534 case MEM_X:
1535 /* TODO: mark effected queued registers */
1536 move_cmd = 0x61d800;
1537 break;
1538 case MEM_Y:
1539 move_cmd = 0x69d800;
1540 break;
1541 case MEM_P:
1542 move_cmd = 0x07d891;
1543 break;
1544 default:
1545 return ERROR_COMMAND_SYNTAX_ERROR;
1546 }
1547
1548 /* we use r0 to store temporary data */
1549 if (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].valid)
1550 dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R0);
1551 /* we use r1 to store temporary data */
1552 if (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R1].valid)
1553 dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R1);
1554
1555 /* r0 is no longer valid on target */
1556 dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].dirty = true;
1557 /* r1 is no longer valid on target */
1558 dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R1].dirty = true;
1559
1560 x = count;
1561 b = buffer;
1562
1563 err = dsp563xx_once_execute_dw_ir(target->tap, 1, 0x60F400, address);
1564 if (err != ERROR_OK)
1565 return err;
1566
1567 for (i = 0; i < x; i++) {
1568 err = dsp563xx_once_execute_sw_ir(target->tap, 0, move_cmd);
1569 if (err != ERROR_OK)
1570 return err;
1571 err = dsp563xx_once_execute_sw_ir(target->tap, 0, 0x08D13C);
1572 if (err != ERROR_OK)
1573 return err;
1574 err = dsp563xx_once_reg_read(target->tap, 0,
1575 DSP563XX_ONCE_OGDBR, (uint32_t *)(void *)b);
1576 if (err != ERROR_OK)
1577 return err;
1578 b += 4;
1579 }
1580
1581 /* flush the jtag queue */
1582 err = jtag_execute_queue();
1583 if (err != ERROR_OK)
1584 return err;
1585
1586 /* walk over the buffer and fix target endianness */
1587 b = buffer;
1588
1589 for (i = 0; i < x; i++) {
1590 data = buf_get_u32(b, 0, 32) & 0x00FFFFFF;
1591 /* LOG_DEBUG("R: %08X", *((uint32_t*)b)); */
1592 target_buffer_set_u32(target, b, data);
1593 b += 4;
1594 }
1595
1596 return ERROR_OK;
1597 }
1598
1599 static int dsp563xx_read_memory(struct target *target,
1600 int mem_type,
1601 target_addr_t address,
1602 uint32_t size,
1603 uint32_t count,
1604 uint8_t *buffer)
1605 {
1606 int err;
1607 uint32_t i, i1;
1608 uint8_t *buffer_y, *buffer_x;
1609
1610 /* if size equals zero we are called from target read memory
1611 * and have to handle the parameter here */
1612 if ((size == 0) && (count != 0)) {
1613 size = count % 4;
1614
1615 if (size)
1616 LOG_DEBUG("size is not aligned to 4 byte");
1617
1618 count = (count - size) / 4;
1619 size = 4;
1620 }
1621
1622 /* we only support 4 byte aligned data */
1623 if ((size != 4) || (!count))
1624 return ERROR_COMMAND_SYNTAX_ERROR;
1625
1626 if (mem_type != MEM_L)
1627 return dsp563xx_read_memory_core(target, mem_type, address, size, count, buffer);
1628
1629 buffer_y = malloc(size * count);
1630 if (!buffer_y)
1631 return ERROR_COMMAND_SYNTAX_ERROR;
1632
1633 buffer_x = malloc(size * count);
1634 if (!buffer_x) {
1635 free(buffer_y);
1636 return ERROR_COMMAND_SYNTAX_ERROR;
1637 }
1638
1639 err = dsp563xx_read_memory_core(target, MEM_Y, address, size, count / 2, buffer_y);
1640
1641 if (err != ERROR_OK) {
1642 free(buffer_y);
1643 free(buffer_x);
1644 return err;
1645 }
1646
1647 err = dsp563xx_read_memory_core(target, MEM_X, address, size, count / 2, buffer_x);
1648
1649 if (err != ERROR_OK) {
1650 free(buffer_y);
1651 free(buffer_x);
1652 return err;
1653 }
1654
1655 for (i = 0, i1 = 0; i < count; i += 2, i1++) {
1656 buf_set_u32(buffer + i*sizeof(uint32_t), 0, 32,
1657 buf_get_u32(buffer_y + i1 * sizeof(uint32_t), 0, 32));
1658 buf_set_u32(buffer + (i + 1) * sizeof(uint32_t), 0, 32,
1659 buf_get_u32(buffer_x + i1 * sizeof(uint32_t), 0, 32));
1660 }
1661
1662 free(buffer_y);
1663 free(buffer_x);
1664
1665 return ERROR_OK;
1666 }
1667
1668 static int dsp563xx_read_memory_default(struct target *target,
1669 target_addr_t address,
1670 uint32_t size,
1671 uint32_t count,
1672 uint8_t *buffer)
1673 {
1674
1675 return dsp563xx_read_memory(target,
1676 dsp563xx_get_default_memory(), address, size, count, buffer);
1677 }
1678
1679 static int dsp563xx_read_buffer_default(struct target *target,
1680 target_addr_t address,
1681 uint32_t size,
1682 uint8_t *buffer)
1683 {
1684
1685 return dsp563xx_read_memory(target, dsp563xx_get_default_memory(), address, size, 0,
1686 buffer);
1687 }
1688
1689 static int dsp563xx_write_memory_core(struct target *target,
1690 int mem_type,
1691 target_addr_t address,
1692 uint32_t size,
1693 uint32_t count,
1694 const uint8_t *buffer)
1695 {
1696 int err;
1697 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
1698 uint32_t i, x;
1699 uint32_t data, move_cmd = 0;
1700 const uint8_t *b;
1701
1702 LOG_DEBUG(
1703 "memtype: %d address: 0x%8.8" TARGET_PRIxADDR ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
1704 mem_type,
1705 address,
1706 size,
1707 count);
1708
1709 if (target->state != TARGET_HALTED) {
1710 LOG_WARNING("target not halted");
1711 return ERROR_TARGET_NOT_HALTED;
1712 }
1713
1714 switch (mem_type) {
1715 case MEM_X:
1716 /* invalidate affected x registers */
1717 dsp563xx_invalidate_x_context(target, address, address + count - 1);
1718 move_cmd = 0x615800;
1719 break;
1720 case MEM_Y:
1721 move_cmd = 0x695800;
1722 break;
1723 case MEM_P:
1724 move_cmd = 0x075891;
1725 break;
1726 default:
1727 return ERROR_COMMAND_SYNTAX_ERROR;
1728 }
1729
1730 /* we use r0 to store temporary data */
1731 if (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].valid)
1732 dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R0);
1733 /* we use r1 to store temporary data */
1734 if (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R1].valid)
1735 dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R1);
1736
1737 /* r0 is no longer valid on target */
1738 dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].dirty = true;
1739 /* r1 is no longer valid on target */
1740 dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R1].dirty = true;
1741
1742 x = count;
1743 b = buffer;
1744
1745 err = dsp563xx_once_execute_dw_ir(target->tap, 1, 0x60F400, address);
1746 if (err != ERROR_OK)
1747 return err;
1748
1749 for (i = 0; i < x; i++) {
1750 data = target_buffer_get_u32(target, b);
1751
1752 /* LOG_DEBUG("W: %08X", data); */
1753
1754 data &= 0x00ffffff;
1755
1756 err = dsp563xx_once_execute_dw_ir(target->tap, 0, 0x61F400, data);
1757 if (err != ERROR_OK)
1758 return err;
1759 err = dsp563xx_once_execute_sw_ir(target->tap, 0, move_cmd);
1760 if (err != ERROR_OK)
1761 return err;
1762 b += 4;
1763 }
1764
1765 /* flush the jtag queue */
1766 err = jtag_execute_queue();
1767 if (err != ERROR_OK)
1768 return err;
1769
1770 return ERROR_OK;
1771 }
1772
1773 static int dsp563xx_write_memory(struct target *target,
1774 int mem_type,
1775 target_addr_t address,
1776 uint32_t size,
1777 uint32_t count,
1778 const uint8_t *buffer)
1779 {
1780 int err;
1781 uint32_t i, i1;
1782 uint8_t *buffer_y, *buffer_x;
1783
1784 /* if size equals zero we are called from target write memory
1785 * and have to handle the parameter here */
1786 if ((size == 0) && (count != 0)) {
1787 size = count % 4;
1788
1789 if (size)
1790 LOG_DEBUG("size is not aligned to 4 byte");
1791
1792 count = (count - size) / 4;
1793 size = 4;
1794 }
1795
1796 /* we only support 4 byte aligned data */
1797 if ((size != 4) || (!count))
1798 return ERROR_COMMAND_SYNTAX_ERROR;
1799
1800 if (mem_type != MEM_L)
1801 return dsp563xx_write_memory_core(target, mem_type, address, size, count, buffer);
1802
1803 buffer_y = malloc(size * count);
1804 if (!buffer_y)
1805 return ERROR_COMMAND_SYNTAX_ERROR;
1806
1807 buffer_x = malloc(size * count);
1808 if (!buffer_x) {
1809 free(buffer_y);
1810 return ERROR_COMMAND_SYNTAX_ERROR;
1811 }
1812
1813 for (i = 0, i1 = 0; i < count; i += 2, i1++) {
1814 buf_set_u32(buffer_y + i1 * sizeof(uint32_t), 0, 32,
1815 buf_get_u32(buffer + i * sizeof(uint32_t), 0, 32));
1816 buf_set_u32(buffer_x + i1 * sizeof(uint32_t), 0, 32,
1817 buf_get_u32(buffer + (i + 1) * sizeof(uint32_t), 0, 32));
1818 }
1819
1820 err = dsp563xx_write_memory_core(target, MEM_Y, address, size, count / 2, buffer_y);
1821
1822 if (err != ERROR_OK) {
1823 free(buffer_y);
1824 free(buffer_x);
1825 return err;
1826 }
1827
1828 err = dsp563xx_write_memory_core(target, MEM_X, address, size, count / 2, buffer_x);
1829
1830 if (err != ERROR_OK) {
1831 free(buffer_y);
1832 free(buffer_x);
1833 return err;
1834 }
1835
1836 free(buffer_y);
1837 free(buffer_x);
1838
1839 return ERROR_OK;
1840 }
1841
1842 static int dsp563xx_write_memory_default(struct target *target,
1843 target_addr_t address,
1844 uint32_t size,
1845 uint32_t count,
1846 const uint8_t *buffer)
1847 {
1848 return dsp563xx_write_memory(target,
1849 dsp563xx_get_default_memory(), address, size, count, buffer);
1850 }
1851
1852 static int dsp563xx_write_buffer_default(struct target *target,
1853 target_addr_t address,
1854 uint32_t size,
1855 const uint8_t *buffer)
1856 {
1857 return dsp563xx_write_memory(target, dsp563xx_get_default_memory(), address, size, 0,
1858 buffer);
1859 }
1860
1861 /*
1862 * Exit with error here, because we support watchpoints over a custom command.
1863 * This is because the DSP has separate X,Y,P memspace which is not compatible to the
1864 * traditional watchpoint logic.
1865 */
1866 static int dsp563xx_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
1867 {
1868 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1869 }
1870
1871 /*
1872 * @see dsp563xx_add_watchpoint
1873 */
1874 static int dsp563xx_remove_watchpoint(struct target *target, struct watchpoint *watchpoint)
1875 {
1876 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1877 }
1878
1879 static int dsp563xx_add_custom_watchpoint(struct target *target, uint32_t address, uint32_t memType,
1880 enum watchpoint_rw rw, enum watchpoint_condition cond)
1881 {
1882 int err = ERROR_OK;
1883 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
1884
1885 bool wasRunning = false;
1886 /* Only set breakpoint when halted */
1887 if (target->state != TARGET_HALTED) {
1888 dsp563xx_halt(target);
1889 wasRunning = true;
1890 }
1891
1892 if (dsp563xx->hardware_breakpoint[0].used) {
1893 LOG_ERROR("Cannot add watchpoint. Hardware resource already used.");
1894 err = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1895 }
1896
1897 uint32_t obcr_value = 0;
1898 if (err == ERROR_OK) {
1899 obcr_value |= OBCR_b0_or_b1;
1900 switch (memType) {
1901 case MEM_X:
1902 obcr_value |= OBCR_BP_MEM_X;
1903 break;
1904 case MEM_Y:
1905 obcr_value |= OBCR_BP_MEM_Y;
1906 break;
1907 case MEM_P:
1908 obcr_value |= OBCR_BP_MEM_P;
1909 break;
1910 default:
1911 LOG_ERROR("Unknown memType parameter (%" PRIu32 ")", memType);
1912 err = ERROR_TARGET_INVALID;
1913 }
1914 }
1915
1916 if (err == ERROR_OK) {
1917 switch (rw) {
1918 case WPT_READ:
1919 obcr_value |= OBCR_BP_0(OBCR_BP_ON_READ);
1920 break;
1921 case WPT_WRITE:
1922 obcr_value |= OBCR_BP_0(OBCR_BP_ON_WRITE);
1923 break;
1924 case WPT_ACCESS:
1925 obcr_value |= OBCR_BP_0(OBCR_BP_ON_READ|OBCR_BP_ON_WRITE);
1926 break;
1927 default:
1928 LOG_ERROR("Unsupported write mode (%d)", rw);
1929 err = ERROR_TARGET_INVALID;
1930 }
1931 }
1932
1933 if (err == ERROR_OK) {
1934 switch (cond) {
1935 case EQUAL:
1936 obcr_value |= OBCR_BP_0(OBCR_BP_CC_EQUAL);
1937 break;
1938 case NOT_EQUAL:
1939 obcr_value |= OBCR_BP_0(OBCR_BP_CC_NOT_EQUAL);
1940 break;
1941 case LESS_THAN:
1942 obcr_value |= OBCR_BP_0(OBCR_BP_CC_LESS_THAN);
1943 break;
1944 case GREATER:
1945 obcr_value |= OBCR_BP_0(OBCR_BP_CC_GREATER_THAN);
1946 break;
1947 default:
1948 LOG_ERROR("Unsupported condition code (%d)", cond);
1949 err = ERROR_TARGET_INVALID;
1950 }
1951 }
1952
1953 if (err == ERROR_OK)
1954 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMLR0, address);
1955
1956 if (err == ERROR_OK)
1957 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMLR1, 0x0);
1958
1959 if (err == ERROR_OK)
1960 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OBCR, obcr_value);
1961
1962 if (err == ERROR_OK) {
1963 /* You should write the memory breakpoint counter to 0 */
1964 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMBC, 0);
1965 }
1966
1967 if (err == ERROR_OK) {
1968 /* You should write the memory breakpoint counter to 0 */
1969 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OTC, 0);
1970 }
1971
1972 if (err == ERROR_OK)
1973 dsp563xx->hardware_breakpoint[0].used = BPU_WATCHPOINT;
1974
1975 if (err == ERROR_OK && wasRunning) {
1976 /* Resume from current PC */
1977 err = dsp563xx_resume(target, 1, 0x0, 0, 0);
1978 }
1979
1980 return err;
1981 }
1982
1983 static int dsp563xx_remove_custom_watchpoint(struct target *target)
1984 {
1985 int err = ERROR_OK;
1986 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
1987
1988 if (dsp563xx->hardware_breakpoint[0].used != BPU_WATCHPOINT) {
1989 LOG_ERROR("Cannot remove watchpoint, as no watchpoint is currently configured!");
1990 err = ERROR_TARGET_INVALID;
1991 }
1992
1993 if (err == ERROR_OK) {
1994 /* Clear watchpoint by clearing OBCR. */
1995 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OBCR, 0);
1996 }
1997
1998 if (err == ERROR_OK)
1999 dsp563xx->hardware_breakpoint[0].used = BPU_NONE;
2000
2001 return err;
2002 }
2003
2004 COMMAND_HANDLER(dsp563xx_add_watchpoint_command)
2005 {
2006 int err = ERROR_OK;
2007 struct target *target = get_current_target(CMD_CTX);
2008
2009 uint32_t mem_type = 0;
2010 switch (CMD_NAME[2]) {
2011 case 'x':
2012 mem_type = MEM_X;
2013 break;
2014 case 'y':
2015 mem_type = MEM_Y;
2016 break;
2017 case 'p':
2018 mem_type = MEM_P;
2019 break;
2020 default:
2021 return ERROR_COMMAND_SYNTAX_ERROR;
2022 }
2023
2024 if (CMD_ARGC < 2)
2025 return ERROR_COMMAND_SYNTAX_ERROR;
2026
2027 uint32_t address = 0;
2028 if (CMD_ARGC > 2)
2029 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], address);
2030
2031 enum watchpoint_condition cond;
2032 switch (CMD_ARGV[0][0]) {
2033 case '>':
2034 cond = GREATER;
2035 break;
2036 case '<':
2037 cond = LESS_THAN;
2038 break;
2039 case '=':
2040 cond = EQUAL;
2041 break;
2042 case '!':
2043 cond = NOT_EQUAL;
2044 break;
2045 default:
2046 return ERROR_COMMAND_SYNTAX_ERROR;
2047 }
2048
2049 enum watchpoint_rw rw;
2050 switch (CMD_ARGV[1][0]) {
2051 case 'r':
2052 rw = WPT_READ;
2053 break;
2054 case 'w':
2055 rw = WPT_WRITE;
2056 break;
2057 case 'a':
2058 rw = WPT_ACCESS;
2059 break;
2060 default:
2061 return ERROR_COMMAND_SYNTAX_ERROR;
2062 }
2063
2064 err = dsp563xx_add_custom_watchpoint(target, address, mem_type, rw, cond);
2065
2066 return err;
2067 }
2068
2069 /* Adding a breakpoint using the once breakpoint logic.
2070 * Note that this mechanism is a true hw breakpoint and is share between the watchpoint logic.
2071 * This means, you can only have one breakpoint/watchpoint at any time.
2072 */
2073 static int dsp563xx_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
2074 {
2075 return dsp563xx_add_custom_watchpoint(target, breakpoint->address, MEM_P, WPT_READ, EQUAL);
2076 }
2077
2078 static int dsp563xx_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)
2079 {
2080 return dsp563xx_remove_custom_watchpoint(target);
2081 }
2082
2083 COMMAND_HANDLER(dsp563xx_remove_watchpoint_command)
2084 {
2085 struct target *target = get_current_target(CMD_CTX);
2086
2087 return dsp563xx_remove_custom_watchpoint(target);
2088 }
2089
2090 COMMAND_HANDLER(dsp563xx_mem_command)
2091 {
2092 struct target *target = get_current_target(CMD_CTX);
2093 int err = ERROR_OK;
2094 int read_mem;
2095 uint32_t address = 0;
2096 uint32_t count = 1, i;
2097 uint32_t pattern = 0;
2098 uint32_t mem_type;
2099 uint8_t *buffer, *b;
2100
2101 switch (CMD_NAME[1]) {
2102 case 'w':
2103 read_mem = 0;
2104 break;
2105 case 'd':
2106 read_mem = 1;
2107 break;
2108 default:
2109 return ERROR_COMMAND_SYNTAX_ERROR;
2110 }
2111
2112 switch (CMD_NAME[3]) {
2113 case 'x':
2114 mem_type = MEM_X;
2115 break;
2116 case 'y':
2117 mem_type = MEM_Y;
2118 break;
2119 case 'p':
2120 mem_type = MEM_P;
2121 break;
2122 default:
2123 return ERROR_COMMAND_SYNTAX_ERROR;
2124 }
2125
2126 if (CMD_ARGC > 0)
2127 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
2128
2129 if (read_mem == 0) {
2130 if (CMD_ARGC < 2)
2131 return ERROR_COMMAND_SYNTAX_ERROR;
2132 if (CMD_ARGC > 1)
2133 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], pattern);
2134 if (CMD_ARGC > 2)
2135 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], count);
2136 }
2137
2138 if (read_mem == 1) {
2139 if (CMD_ARGC < 1)
2140 return ERROR_COMMAND_SYNTAX_ERROR;
2141 if (CMD_ARGC > 1)
2142 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], count);
2143 }
2144
2145 buffer = calloc(count, sizeof(uint32_t));
2146
2147 if (read_mem == 1) {
2148 err = dsp563xx_read_memory(target, mem_type, address, sizeof(uint32_t),
2149 count, buffer);
2150 if (err == ERROR_OK)
2151 target_handle_md_output(CMD, target, address, sizeof(uint32_t), count, buffer);
2152
2153 } else {
2154 b = buffer;
2155
2156 for (i = 0; i < count; i++) {
2157 target_buffer_set_u32(target, b, pattern);
2158 b += 4;
2159 }
2160
2161 err = dsp563xx_write_memory(target,
2162 mem_type,
2163 address,
2164 sizeof(uint32_t),
2165 count,
2166 buffer);
2167 }
2168
2169 free(buffer);
2170
2171 return err;
2172 }
2173
2174 static const struct command_registration dsp563xx_command_handlers[] = {
2175 {
2176 .name = "mwwx",
2177 .handler = dsp563xx_mem_command,
2178 .mode = COMMAND_EXEC,
2179 .help = "write x memory words",
2180 .usage = "address value [count]",
2181 },
2182 {
2183 .name = "mwwy",
2184 .handler = dsp563xx_mem_command,
2185 .mode = COMMAND_EXEC,
2186 .help = "write y memory words",
2187 .usage = "address value [count]",
2188 },
2189 {
2190 .name = "mwwp",
2191 .handler = dsp563xx_mem_command,
2192 .mode = COMMAND_EXEC,
2193 .help = "write p memory words",
2194 .usage = "address value [count]",
2195 },
2196 {
2197 .name = "mdwx",
2198 .handler = dsp563xx_mem_command,
2199 .mode = COMMAND_EXEC,
2200 .help = "display x memory words",
2201 .usage = "address [count]",
2202 },
2203 {
2204 .name = "mdwy",
2205 .handler = dsp563xx_mem_command,
2206 .mode = COMMAND_EXEC,
2207 .help = "display y memory words",
2208 .usage = "address [count]",
2209 },
2210 {
2211 .name = "mdwp",
2212 .handler = dsp563xx_mem_command,
2213 .mode = COMMAND_EXEC,
2214 .help = "display p memory words",
2215 .usage = "address [count]",
2216 },
2217 /*
2218 * Watchpoint commands
2219 */
2220 {
2221 .name = "wpp",
2222 .handler = dsp563xx_add_watchpoint_command,
2223 .mode = COMMAND_EXEC,
2224 .help = "Create p memspace watchpoint",
2225 .usage = "(>|<|=|!) (r|w|a) address",
2226 },
2227 {
2228 .name = "wpx",
2229 .handler = dsp563xx_add_watchpoint_command,
2230 .mode = COMMAND_EXEC,
2231 .help = "Create x memspace watchpoint",
2232 .usage = "(>|<|=|!) (r|w|a) address",
2233 },
2234 {
2235 .name = "wpy",
2236 .handler = dsp563xx_add_watchpoint_command,
2237 .mode = COMMAND_EXEC,
2238 .help = "Create y memspace watchpoint",
2239 .usage = "(>|<|=|!) (r|w|a) address",
2240 },
2241 {
2242 .name = "rwpc",
2243 .handler = dsp563xx_remove_watchpoint_command,
2244 .mode = COMMAND_EXEC,
2245 .help = "remove watchpoint custom",
2246 .usage = " ",
2247 },
2248 COMMAND_REGISTRATION_DONE
2249 };
2250
2251 /** Holds methods for DSP563XX targets. */
2252 struct target_type dsp563xx_target = {
2253 .name = "dsp563xx",
2254
2255 .poll = dsp563xx_poll,
2256 .arch_state = dsp563xx_arch_state,
2257
2258 .get_gdb_reg_list = dsp563xx_get_gdb_reg_list,
2259
2260 .halt = dsp563xx_halt,
2261 .resume = dsp563xx_resume,
2262 .step = dsp563xx_step,
2263
2264 .assert_reset = dsp563xx_assert_reset,
2265 .deassert_reset = dsp563xx_deassert_reset,
2266
2267 .read_memory = dsp563xx_read_memory_default,
2268 .write_memory = dsp563xx_write_memory_default,
2269
2270 .read_buffer = dsp563xx_read_buffer_default,
2271 .write_buffer = dsp563xx_write_buffer_default,
2272
2273 .run_algorithm = dsp563xx_run_algorithm,
2274
2275 .add_breakpoint = dsp563xx_add_breakpoint,
2276 .remove_breakpoint = dsp563xx_remove_breakpoint,
2277 .add_watchpoint = dsp563xx_add_watchpoint,
2278 .remove_watchpoint = dsp563xx_remove_watchpoint,
2279
2280 .commands = dsp563xx_command_handlers,
2281 .target_create = dsp563xx_target_create,
2282 .init_target = dsp563xx_init_target,
2283 .examine = dsp563xx_examine,
2284 };

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)