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 /* instruction 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 = false;
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" PRIu32 " 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 if (err != ERROR_OK)
1089 return err;
1090
1091 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMLR0, 0);
1092 if (err != ERROR_OK)
1093 return err;
1094
1095 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMLR1, 0);
1096 if (err != ERROR_OK)
1097 return err;
1098
1099 dsp563xx->hardware_breakpoints_cleared = true;
1100 }
1101
1102 return ERROR_OK;
1103 }
1104
1105 static int dsp563xx_halt(struct target *target)
1106 {
1107 int err;
1108
1109 LOG_DEBUG("%s", __func__);
1110
1111 if (target->state == TARGET_HALTED) {
1112 LOG_DEBUG("target was already halted");
1113 return ERROR_OK;
1114 }
1115
1116 if (target->state == TARGET_UNKNOWN)
1117 LOG_WARNING("target was in unknown state when halt was requested");
1118
1119 err = dsp563xx_jtag_debug_request(target);
1120 if (err != ERROR_OK)
1121 return err;
1122
1123 target->debug_reason = DBG_REASON_DBGRQ;
1124
1125 return ERROR_OK;
1126 }
1127
1128 static int dsp563xx_resume(struct target *target,
1129 int current,
1130 target_addr_t address,
1131 int handle_breakpoints,
1132 int debug_execution)
1133 {
1134 int err;
1135 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
1136
1137 /* check if pc was changed and resume want to execute the next address
1138 * if pc was changed from gdb or other interface we will
1139 * jump to this address and don't execute the next address
1140 * this will not affect the resume command with an address argument
1141 * because current is set to zero then
1142 */
1143 if (current && dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_PC].dirty) {
1144 dsp563xx_write_core_reg(target, DSP563XX_REG_IDX_PC);
1145 address = dsp563xx->core_regs[DSP563XX_REG_IDX_PC];
1146 current = 0;
1147 }
1148
1149 LOG_DEBUG("%s %08X %08X", __func__, current, (unsigned) address);
1150
1151 err = dsp563xx_restore_context(target);
1152 if (err != ERROR_OK)
1153 return err;
1154 register_cache_invalidate(dsp563xx->core_cache);
1155
1156 if (current) {
1157 /* restore pipeline registers and go */
1158 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR,
1159 once_regs[ONCE_REG_IDX_OPILR].reg);
1160 if (err != ERROR_OK)
1161 return err;
1162 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR |
1163 DSP563XX_ONCE_OCR_EX | DSP563XX_ONCE_OCR_GO,
1164 once_regs[ONCE_REG_IDX_OPDBR].reg);
1165 if (err != ERROR_OK)
1166 return err;
1167 } else {
1168 /* set to go register and jump */
1169 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR, INSTR_JUMP);
1170 if (err != ERROR_OK)
1171 return err;
1172 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_PDBGOTO |
1173 DSP563XX_ONCE_OCR_EX | DSP563XX_ONCE_OCR_GO, address);
1174 if (err != ERROR_OK)
1175 return err;
1176 }
1177
1178 target->state = TARGET_RUNNING;
1179
1180 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
1181
1182 return ERROR_OK;
1183 }
1184
1185 static int dsp563xx_step_ex(struct target *target,
1186 int current,
1187 uint32_t address,
1188 int handle_breakpoints,
1189 int steps)
1190 {
1191 int err;
1192 uint32_t once_status;
1193 uint32_t dr_in, cnt;
1194 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
1195
1196 if (target->state != TARGET_HALTED) {
1197 LOG_DEBUG("target was not halted");
1198 return ERROR_OK;
1199 }
1200
1201 /* check if pc was changed and step want to execute the next address
1202 * if pc was changed from gdb or other interface we will
1203 * jump to this address and don't execute the next address
1204 * this will not affect the step command with an address argument
1205 * because current is set to zero then
1206 */
1207 if (current && dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_PC].dirty) {
1208 dsp563xx_write_core_reg(target, DSP563XX_REG_IDX_PC);
1209 address = dsp563xx->core_regs[DSP563XX_REG_IDX_PC];
1210 current = 0;
1211 }
1212
1213 LOG_DEBUG("%s %08X %08X", __func__, current, (unsigned) address);
1214
1215 err = dsp563xx_jtag_debug_request(target);
1216 if (err != ERROR_OK)
1217 return err;
1218 err = dsp563xx_restore_context(target);
1219 if (err != ERROR_OK)
1220 return err;
1221
1222 /* reset trace mode */
1223 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OSCR, 0x000000);
1224 if (err != ERROR_OK)
1225 return err;
1226 /* enable trace mode */
1227 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OSCR, DSP563XX_ONCE_OSCR_TME);
1228 if (err != ERROR_OK)
1229 return err;
1230
1231 cnt = steps;
1232
1233 /* on JUMP we need one extra cycle */
1234 if (!current)
1235 cnt++;
1236
1237 /* load step counter with N-1 */
1238 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OTC, cnt);
1239 if (err != ERROR_OK)
1240 return err;
1241
1242 if (current) {
1243 /* restore pipeline registers and go */
1244 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR,
1245 once_regs[ONCE_REG_IDX_OPILR].reg);
1246 if (err != ERROR_OK)
1247 return err;
1248 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR |
1249 DSP563XX_ONCE_OCR_EX | DSP563XX_ONCE_OCR_GO,
1250 once_regs[ONCE_REG_IDX_OPDBR].reg);
1251 if (err != ERROR_OK)
1252 return err;
1253 } else {
1254 /* set to go register and jump */
1255 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR, INSTR_JUMP);
1256 if (err != ERROR_OK)
1257 return err;
1258 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_PDBGOTO |
1259 DSP563XX_ONCE_OCR_EX | DSP563XX_ONCE_OCR_GO,
1260 address);
1261 if (err != ERROR_OK)
1262 return err;
1263 }
1264
1265 while (1) {
1266 err = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OSCR, &once_status);
1267 if (err != ERROR_OK)
1268 return err;
1269
1270 if (once_status & DSP563XX_ONCE_OSCR_TO) {
1271 err = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OPABFR, &dr_in);
1272 if (err != ERROR_OK)
1273 return err;
1274 LOG_DEBUG("fetch: %08X", (unsigned) dr_in&0x00ffffff);
1275 err = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OPABDR, &dr_in);
1276 if (err != ERROR_OK)
1277 return err;
1278 LOG_DEBUG("decode: %08X", (unsigned) dr_in&0x00ffffff);
1279 err = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OPABEX, &dr_in);
1280 if (err != ERROR_OK)
1281 return err;
1282 LOG_DEBUG("execute: %08X", (unsigned) dr_in&0x00ffffff);
1283
1284 /* reset trace mode */
1285 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OSCR, 0x000000);
1286 if (err != ERROR_OK)
1287 return err;
1288
1289 register_cache_invalidate(dsp563xx->core_cache);
1290 err = dsp563xx_debug_init(target);
1291 if (err != ERROR_OK)
1292 return err;
1293
1294 break;
1295 }
1296 }
1297
1298 return ERROR_OK;
1299 }
1300
1301 static int dsp563xx_step(struct target *target,
1302 int current,
1303 target_addr_t address,
1304 int handle_breakpoints)
1305 {
1306 int err;
1307 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
1308
1309 if (target->state != TARGET_HALTED) {
1310 LOG_WARNING("target not halted");
1311 return ERROR_TARGET_NOT_HALTED;
1312 }
1313
1314 err = dsp563xx_step_ex(target, current, address, handle_breakpoints, 0);
1315 if (err != ERROR_OK)
1316 return err;
1317
1318 target->debug_reason = DBG_REASON_SINGLESTEP;
1319 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1320
1321 LOG_INFO("halted: PC: 0x%" PRIx32, dsp563xx->core_regs[DSP563XX_REG_IDX_PC]);
1322
1323 return err;
1324 }
1325
1326 static int dsp563xx_assert_reset(struct target *target)
1327 {
1328 int retval = 0;
1329 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
1330 enum reset_types jtag_reset_config = jtag_get_reset_config();
1331
1332 if (jtag_reset_config & RESET_HAS_SRST) {
1333 /* default to asserting srst */
1334 if (jtag_reset_config & RESET_SRST_PULLS_TRST)
1335 jtag_add_reset(1, 1);
1336 else
1337 jtag_add_reset(0, 1);
1338 }
1339
1340 target->state = TARGET_RESET;
1341 jtag_add_sleep(5000);
1342
1343 /* registers are now invalid */
1344 register_cache_invalidate(dsp563xx->core_cache);
1345
1346 if (target->reset_halt) {
1347 retval = target_halt(target);
1348 if (retval != ERROR_OK)
1349 return retval;
1350 }
1351
1352 LOG_DEBUG("%s", __func__);
1353 return ERROR_OK;
1354 }
1355
1356 static int dsp563xx_deassert_reset(struct target *target)
1357 {
1358 int err;
1359
1360 /* deassert reset lines */
1361 jtag_add_reset(0, 0);
1362
1363 err = dsp563xx_poll(target);
1364 if (err != ERROR_OK)
1365 return err;
1366
1367 if (target->reset_halt) {
1368 if (target->state == TARGET_HALTED) {
1369 /* after a reset the cpu jmp to the
1370 * reset vector and need 2 cycles to fill
1371 * the cache (fetch,decode,execute)
1372 */
1373 err = dsp563xx_step_ex(target, 1, 0, 1, 1);
1374 if (err != ERROR_OK)
1375 return err;
1376 }
1377 } else
1378 target->state = TARGET_RUNNING;
1379
1380 LOG_DEBUG("%s", __func__);
1381 return ERROR_OK;
1382 }
1383
1384 static int dsp563xx_run_algorithm(struct target *target,
1385 int num_mem_params, struct mem_param *mem_params,
1386 int num_reg_params, struct reg_param *reg_params,
1387 target_addr_t entry_point, target_addr_t exit_point,
1388 int timeout_ms, void *arch_info)
1389 {
1390 int i;
1391 int retval = ERROR_OK;
1392 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
1393
1394 if (target->state != TARGET_HALTED) {
1395 LOG_WARNING("target not halted");
1396 return ERROR_TARGET_NOT_HALTED;
1397 }
1398
1399 for (i = 0; i < num_mem_params; i++) {
1400 if (mem_params[i].direction == PARAM_IN)
1401 continue;
1402 retval = target_write_buffer(target, mem_params[i].address,
1403 mem_params[i].size, mem_params[i].value);
1404 if (retval != ERROR_OK)
1405 return retval;
1406 }
1407
1408 for (i = 0; i < num_reg_params; i++) {
1409 if (reg_params[i].direction == PARAM_IN)
1410 continue;
1411
1412 struct reg *reg = register_get_by_name(dsp563xx->core_cache,
1413 reg_params[i].reg_name,
1414 false);
1415
1416 if (!reg) {
1417 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
1418 continue;
1419 }
1420
1421 if (reg->size != reg_params[i].size) {
1422 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1423 reg_params[i].reg_name);
1424 continue;
1425 }
1426
1427 retval = dsp563xx_set_core_reg(reg, reg_params[i].value);
1428 if (retval != ERROR_OK)
1429 return retval;
1430 }
1431
1432 /* exec */
1433 retval = target_resume(target, 0, entry_point, 1, 1);
1434 if (retval != ERROR_OK)
1435 return retval;
1436
1437 retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
1438 if (retval != ERROR_OK)
1439 return retval;
1440
1441 for (i = 0; i < num_mem_params; i++) {
1442 if (mem_params[i].direction != PARAM_OUT)
1443 retval = target_read_buffer(target,
1444 mem_params[i].address,
1445 mem_params[i].size,
1446 mem_params[i].value);
1447 if (retval != ERROR_OK)
1448 return retval;
1449 }
1450
1451 for (i = 0; i < num_reg_params; i++) {
1452 if (reg_params[i].direction != PARAM_OUT) {
1453
1454 struct reg *reg = register_get_by_name(dsp563xx->core_cache,
1455 reg_params[i].reg_name,
1456 false);
1457 if (!reg) {
1458 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
1459 continue;
1460 }
1461
1462 if (reg->size != reg_params[i].size) {
1463 LOG_ERROR(
1464 "BUG: register '%s' size doesn't match reg_params[i].size",
1465 reg_params[i].reg_name);
1466 continue;
1467 }
1468
1469 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
1470 }
1471 }
1472
1473 return ERROR_OK;
1474 }
1475
1476 /* global command context from openocd.c */
1477 extern struct command_context *global_cmd_ctx;
1478
1479 static int dsp563xx_get_default_memory(void)
1480 {
1481 Jim_Interp *interp;
1482 Jim_Obj *memspace;
1483 char *c;
1484
1485 if (!global_cmd_ctx)
1486 return MEM_P;
1487
1488 interp = global_cmd_ctx->interp;
1489
1490 if (!interp)
1491 return MEM_P;
1492
1493 memspace = Jim_GetGlobalVariableStr(interp, "memspace", JIM_NONE);
1494
1495 if (!memspace)
1496 return MEM_P;
1497
1498 c = (char *)Jim_GetString(memspace, NULL);
1499
1500 if (!c)
1501 return MEM_P;
1502
1503 switch (c[0]) {
1504 case '1':
1505 return MEM_X;
1506 case '2':
1507 return MEM_Y;
1508 case '3':
1509 return MEM_L;
1510 default:
1511 break;
1512 }
1513
1514 return MEM_P;
1515 }
1516
1517 static int dsp563xx_read_memory_core(struct target *target,
1518 int mem_type,
1519 uint32_t address,
1520 uint32_t size,
1521 uint32_t count,
1522 uint8_t *buffer)
1523 {
1524 int err;
1525 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
1526 uint32_t i, x;
1527 uint32_t data, move_cmd = 0;
1528 uint8_t *b;
1529
1530 LOG_DEBUG(
1531 "memtype: %d address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
1532 mem_type,
1533 address,
1534 size,
1535 count);
1536
1537 if (target->state != TARGET_HALTED) {
1538 LOG_WARNING("target not halted");
1539 return ERROR_TARGET_NOT_HALTED;
1540 }
1541
1542 switch (mem_type) {
1543 case MEM_X:
1544 /* TODO: mark effected queued registers */
1545 move_cmd = 0x61d800;
1546 break;
1547 case MEM_Y:
1548 move_cmd = 0x69d800;
1549 break;
1550 case MEM_P:
1551 move_cmd = 0x07d891;
1552 break;
1553 default:
1554 return ERROR_COMMAND_SYNTAX_ERROR;
1555 }
1556
1557 /* we use r0 to store temporary data */
1558 if (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].valid)
1559 dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R0);
1560 /* we use r1 to store temporary data */
1561 if (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R1].valid)
1562 dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R1);
1563
1564 /* r0 is no longer valid on target */
1565 dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].dirty = true;
1566 /* r1 is no longer valid on target */
1567 dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R1].dirty = true;
1568
1569 x = count;
1570 b = buffer;
1571
1572 err = dsp563xx_once_execute_dw_ir(target->tap, 1, 0x60F400, address);
1573 if (err != ERROR_OK)
1574 return err;
1575
1576 for (i = 0; i < x; i++) {
1577 err = dsp563xx_once_execute_sw_ir(target->tap, 0, move_cmd);
1578 if (err != ERROR_OK)
1579 return err;
1580 err = dsp563xx_once_execute_sw_ir(target->tap, 0, 0x08D13C);
1581 if (err != ERROR_OK)
1582 return err;
1583 err = dsp563xx_once_reg_read(target->tap, 0,
1584 DSP563XX_ONCE_OGDBR, (uint32_t *)(void *)b);
1585 if (err != ERROR_OK)
1586 return err;
1587 b += 4;
1588 }
1589
1590 /* flush the jtag queue */
1591 err = jtag_execute_queue();
1592 if (err != ERROR_OK)
1593 return err;
1594
1595 /* walk over the buffer and fix target endianness */
1596 b = buffer;
1597
1598 for (i = 0; i < x; i++) {
1599 data = buf_get_u32(b, 0, 32) & 0x00FFFFFF;
1600 /* LOG_DEBUG("R: %08X", *((uint32_t*)b)); */
1601 target_buffer_set_u32(target, b, data);
1602 b += 4;
1603 }
1604
1605 return ERROR_OK;
1606 }
1607
1608 static int dsp563xx_read_memory(struct target *target,
1609 int mem_type,
1610 target_addr_t address,
1611 uint32_t size,
1612 uint32_t count,
1613 uint8_t *buffer)
1614 {
1615 int err;
1616 uint32_t i, i1;
1617 uint8_t *buffer_y, *buffer_x;
1618
1619 /* if size equals zero we are called from target read memory
1620 * and have to handle the parameter here */
1621 if ((size == 0) && (count != 0)) {
1622 size = count % 4;
1623
1624 if (size)
1625 LOG_DEBUG("size is not aligned to 4 byte");
1626
1627 count = (count - size) / 4;
1628 size = 4;
1629 }
1630
1631 /* we only support 4 byte aligned data */
1632 if ((size != 4) || (!count))
1633 return ERROR_COMMAND_SYNTAX_ERROR;
1634
1635 if (mem_type != MEM_L)
1636 return dsp563xx_read_memory_core(target, mem_type, address, size, count, buffer);
1637
1638 buffer_y = malloc(size * count);
1639 if (!buffer_y)
1640 return ERROR_COMMAND_SYNTAX_ERROR;
1641
1642 buffer_x = malloc(size * count);
1643 if (!buffer_x) {
1644 free(buffer_y);
1645 return ERROR_COMMAND_SYNTAX_ERROR;
1646 }
1647
1648 err = dsp563xx_read_memory_core(target, MEM_Y, address, size, count / 2, buffer_y);
1649
1650 if (err != ERROR_OK) {
1651 free(buffer_y);
1652 free(buffer_x);
1653 return err;
1654 }
1655
1656 err = dsp563xx_read_memory_core(target, MEM_X, address, size, count / 2, buffer_x);
1657
1658 if (err != ERROR_OK) {
1659 free(buffer_y);
1660 free(buffer_x);
1661 return err;
1662 }
1663
1664 for (i = 0, i1 = 0; i < count; i += 2, i1++) {
1665 buf_set_u32(buffer + i*sizeof(uint32_t), 0, 32,
1666 buf_get_u32(buffer_y + i1 * sizeof(uint32_t), 0, 32));
1667 buf_set_u32(buffer + (i + 1) * sizeof(uint32_t), 0, 32,
1668 buf_get_u32(buffer_x + i1 * sizeof(uint32_t), 0, 32));
1669 }
1670
1671 free(buffer_y);
1672 free(buffer_x);
1673
1674 return ERROR_OK;
1675 }
1676
1677 static int dsp563xx_read_memory_default(struct target *target,
1678 target_addr_t address,
1679 uint32_t size,
1680 uint32_t count,
1681 uint8_t *buffer)
1682 {
1683
1684 return dsp563xx_read_memory(target,
1685 dsp563xx_get_default_memory(), address, size, count, buffer);
1686 }
1687
1688 static int dsp563xx_read_buffer_default(struct target *target,
1689 target_addr_t address,
1690 uint32_t size,
1691 uint8_t *buffer)
1692 {
1693
1694 return dsp563xx_read_memory(target, dsp563xx_get_default_memory(), address, size, 0,
1695 buffer);
1696 }
1697
1698 static int dsp563xx_write_memory_core(struct target *target,
1699 int mem_type,
1700 target_addr_t address,
1701 uint32_t size,
1702 uint32_t count,
1703 const uint8_t *buffer)
1704 {
1705 int err;
1706 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
1707 uint32_t i, x;
1708 uint32_t data, move_cmd = 0;
1709 const uint8_t *b;
1710
1711 LOG_DEBUG(
1712 "memtype: %d address: 0x%8.8" TARGET_PRIxADDR ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
1713 mem_type,
1714 address,
1715 size,
1716 count);
1717
1718 if (target->state != TARGET_HALTED) {
1719 LOG_WARNING("target not halted");
1720 return ERROR_TARGET_NOT_HALTED;
1721 }
1722
1723 switch (mem_type) {
1724 case MEM_X:
1725 /* invalidate affected x registers */
1726 dsp563xx_invalidate_x_context(target, address, address + count - 1);
1727 move_cmd = 0x615800;
1728 break;
1729 case MEM_Y:
1730 move_cmd = 0x695800;
1731 break;
1732 case MEM_P:
1733 move_cmd = 0x075891;
1734 break;
1735 default:
1736 return ERROR_COMMAND_SYNTAX_ERROR;
1737 }
1738
1739 /* we use r0 to store temporary data */
1740 if (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].valid)
1741 dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R0);
1742 /* we use r1 to store temporary data */
1743 if (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R1].valid)
1744 dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R1);
1745
1746 /* r0 is no longer valid on target */
1747 dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].dirty = true;
1748 /* r1 is no longer valid on target */
1749 dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R1].dirty = true;
1750
1751 x = count;
1752 b = buffer;
1753
1754 err = dsp563xx_once_execute_dw_ir(target->tap, 1, 0x60F400, address);
1755 if (err != ERROR_OK)
1756 return err;
1757
1758 for (i = 0; i < x; i++) {
1759 data = target_buffer_get_u32(target, b);
1760
1761 /* LOG_DEBUG("W: %08X", data); */
1762
1763 data &= 0x00ffffff;
1764
1765 err = dsp563xx_once_execute_dw_ir(target->tap, 0, 0x61F400, data);
1766 if (err != ERROR_OK)
1767 return err;
1768 err = dsp563xx_once_execute_sw_ir(target->tap, 0, move_cmd);
1769 if (err != ERROR_OK)
1770 return err;
1771 b += 4;
1772 }
1773
1774 /* flush the jtag queue */
1775 err = jtag_execute_queue();
1776 if (err != ERROR_OK)
1777 return err;
1778
1779 return ERROR_OK;
1780 }
1781
1782 static int dsp563xx_write_memory(struct target *target,
1783 int mem_type,
1784 target_addr_t address,
1785 uint32_t size,
1786 uint32_t count,
1787 const uint8_t *buffer)
1788 {
1789 int err;
1790 uint32_t i, i1;
1791 uint8_t *buffer_y, *buffer_x;
1792
1793 /* if size equals zero we are called from target write memory
1794 * and have to handle the parameter here */
1795 if ((size == 0) && (count != 0)) {
1796 size = count % 4;
1797
1798 if (size)
1799 LOG_DEBUG("size is not aligned to 4 byte");
1800
1801 count = (count - size) / 4;
1802 size = 4;
1803 }
1804
1805 /* we only support 4 byte aligned data */
1806 if ((size != 4) || (!count))
1807 return ERROR_COMMAND_SYNTAX_ERROR;
1808
1809 if (mem_type != MEM_L)
1810 return dsp563xx_write_memory_core(target, mem_type, address, size, count, buffer);
1811
1812 buffer_y = malloc(size * count);
1813 if (!buffer_y)
1814 return ERROR_COMMAND_SYNTAX_ERROR;
1815
1816 buffer_x = malloc(size * count);
1817 if (!buffer_x) {
1818 free(buffer_y);
1819 return ERROR_COMMAND_SYNTAX_ERROR;
1820 }
1821
1822 for (i = 0, i1 = 0; i < count; i += 2, i1++) {
1823 buf_set_u32(buffer_y + i1 * sizeof(uint32_t), 0, 32,
1824 buf_get_u32(buffer + i * sizeof(uint32_t), 0, 32));
1825 buf_set_u32(buffer_x + i1 * sizeof(uint32_t), 0, 32,
1826 buf_get_u32(buffer + (i + 1) * sizeof(uint32_t), 0, 32));
1827 }
1828
1829 err = dsp563xx_write_memory_core(target, MEM_Y, address, size, count / 2, buffer_y);
1830
1831 if (err != ERROR_OK) {
1832 free(buffer_y);
1833 free(buffer_x);
1834 return err;
1835 }
1836
1837 err = dsp563xx_write_memory_core(target, MEM_X, address, size, count / 2, buffer_x);
1838
1839 if (err != ERROR_OK) {
1840 free(buffer_y);
1841 free(buffer_x);
1842 return err;
1843 }
1844
1845 free(buffer_y);
1846 free(buffer_x);
1847
1848 return ERROR_OK;
1849 }
1850
1851 static int dsp563xx_write_memory_default(struct target *target,
1852 target_addr_t address,
1853 uint32_t size,
1854 uint32_t count,
1855 const uint8_t *buffer)
1856 {
1857 return dsp563xx_write_memory(target,
1858 dsp563xx_get_default_memory(), address, size, count, buffer);
1859 }
1860
1861 static int dsp563xx_write_buffer_default(struct target *target,
1862 target_addr_t address,
1863 uint32_t size,
1864 const uint8_t *buffer)
1865 {
1866 return dsp563xx_write_memory(target, dsp563xx_get_default_memory(), address, size, 0,
1867 buffer);
1868 }
1869
1870 /*
1871 * Exit with error here, because we support watchpoints over a custom command.
1872 * This is because the DSP has separate X,Y,P memspace which is not compatible to the
1873 * traditional watchpoint logic.
1874 */
1875 static int dsp563xx_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
1876 {
1877 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1878 }
1879
1880 /*
1881 * @see dsp563xx_add_watchpoint
1882 */
1883 static int dsp563xx_remove_watchpoint(struct target *target, struct watchpoint *watchpoint)
1884 {
1885 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1886 }
1887
1888 static int dsp563xx_add_custom_watchpoint(struct target *target, uint32_t address, uint32_t mem_type,
1889 enum watchpoint_rw rw, enum watchpoint_condition cond)
1890 {
1891 int err = ERROR_OK;
1892 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
1893
1894 bool was_running = false;
1895 /* Only set breakpoint when halted */
1896 if (target->state != TARGET_HALTED) {
1897 dsp563xx_halt(target);
1898 was_running = true;
1899 }
1900
1901 if (dsp563xx->hardware_breakpoint[0].used) {
1902 LOG_ERROR("Cannot add watchpoint. Hardware resource already used.");
1903 err = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1904 }
1905
1906 uint32_t obcr_value = 0;
1907 if (err == ERROR_OK) {
1908 obcr_value |= OBCR_B0_OR_B1;
1909 switch (mem_type) {
1910 case MEM_X:
1911 obcr_value |= OBCR_BP_MEM_X;
1912 break;
1913 case MEM_Y:
1914 obcr_value |= OBCR_BP_MEM_Y;
1915 break;
1916 case MEM_P:
1917 obcr_value |= OBCR_BP_MEM_P;
1918 break;
1919 default:
1920 LOG_ERROR("Unknown mem_type parameter (%" PRIu32 ")", mem_type);
1921 err = ERROR_TARGET_INVALID;
1922 }
1923 }
1924
1925 if (err == ERROR_OK) {
1926 switch (rw) {
1927 case WPT_READ:
1928 obcr_value |= OBCR_BP_0(OBCR_BP_ON_READ);
1929 break;
1930 case WPT_WRITE:
1931 obcr_value |= OBCR_BP_0(OBCR_BP_ON_WRITE);
1932 break;
1933 case WPT_ACCESS:
1934 obcr_value |= OBCR_BP_0(OBCR_BP_ON_READ|OBCR_BP_ON_WRITE);
1935 break;
1936 default:
1937 LOG_ERROR("Unsupported write mode (%d)", rw);
1938 err = ERROR_TARGET_INVALID;
1939 }
1940 }
1941
1942 if (err == ERROR_OK) {
1943 switch (cond) {
1944 case EQUAL:
1945 obcr_value |= OBCR_BP_0(OBCR_BP_CC_EQUAL);
1946 break;
1947 case NOT_EQUAL:
1948 obcr_value |= OBCR_BP_0(OBCR_BP_CC_NOT_EQUAL);
1949 break;
1950 case LESS_THAN:
1951 obcr_value |= OBCR_BP_0(OBCR_BP_CC_LESS_THAN);
1952 break;
1953 case GREATER:
1954 obcr_value |= OBCR_BP_0(OBCR_BP_CC_GREATER_THAN);
1955 break;
1956 default:
1957 LOG_ERROR("Unsupported condition code (%d)", cond);
1958 err = ERROR_TARGET_INVALID;
1959 }
1960 }
1961
1962 if (err == ERROR_OK)
1963 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMLR0, address);
1964
1965 if (err == ERROR_OK)
1966 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMLR1, 0x0);
1967
1968 if (err == ERROR_OK)
1969 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OBCR, obcr_value);
1970
1971 if (err == ERROR_OK) {
1972 /* You should write the memory breakpoint counter to 0 */
1973 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMBC, 0);
1974 }
1975
1976 if (err == ERROR_OK) {
1977 /* You should write the memory breakpoint counter to 0 */
1978 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OTC, 0);
1979 }
1980
1981 if (err == ERROR_OK)
1982 dsp563xx->hardware_breakpoint[0].used = BPU_WATCHPOINT;
1983
1984 if (err == ERROR_OK && was_running) {
1985 /* Resume from current PC */
1986 err = dsp563xx_resume(target, 1, 0x0, 0, 0);
1987 }
1988
1989 return err;
1990 }
1991
1992 static int dsp563xx_remove_custom_watchpoint(struct target *target)
1993 {
1994 int err = ERROR_OK;
1995 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
1996
1997 if (dsp563xx->hardware_breakpoint[0].used != BPU_WATCHPOINT) {
1998 LOG_ERROR("Cannot remove watchpoint, as no watchpoint is currently configured!");
1999 err = ERROR_TARGET_INVALID;
2000 }
2001
2002 if (err == ERROR_OK) {
2003 /* Clear watchpoint by clearing OBCR. */
2004 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OBCR, 0);
2005 }
2006
2007 if (err == ERROR_OK)
2008 dsp563xx->hardware_breakpoint[0].used = BPU_NONE;
2009
2010 return err;
2011 }
2012
2013 COMMAND_HANDLER(dsp563xx_add_watchpoint_command)
2014 {
2015 int err = ERROR_OK;
2016 struct target *target = get_current_target(CMD_CTX);
2017
2018 uint32_t mem_type = 0;
2019 switch (CMD_NAME[2]) {
2020 case 'x':
2021 mem_type = MEM_X;
2022 break;
2023 case 'y':
2024 mem_type = MEM_Y;
2025 break;
2026 case 'p':
2027 mem_type = MEM_P;
2028 break;
2029 default:
2030 return ERROR_COMMAND_SYNTAX_ERROR;
2031 }
2032
2033 if (CMD_ARGC < 2)
2034 return ERROR_COMMAND_SYNTAX_ERROR;
2035
2036 uint32_t address = 0;
2037 if (CMD_ARGC > 2)
2038 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], address);
2039
2040 enum watchpoint_condition cond;
2041 switch (CMD_ARGV[0][0]) {
2042 case '>':
2043 cond = GREATER;
2044 break;
2045 case '<':
2046 cond = LESS_THAN;
2047 break;
2048 case '=':
2049 cond = EQUAL;
2050 break;
2051 case '!':
2052 cond = NOT_EQUAL;
2053 break;
2054 default:
2055 return ERROR_COMMAND_SYNTAX_ERROR;
2056 }
2057
2058 enum watchpoint_rw rw;
2059 switch (CMD_ARGV[1][0]) {
2060 case 'r':
2061 rw = WPT_READ;
2062 break;
2063 case 'w':
2064 rw = WPT_WRITE;
2065 break;
2066 case 'a':
2067 rw = WPT_ACCESS;
2068 break;
2069 default:
2070 return ERROR_COMMAND_SYNTAX_ERROR;
2071 }
2072
2073 err = dsp563xx_add_custom_watchpoint(target, address, mem_type, rw, cond);
2074
2075 return err;
2076 }
2077
2078 /* Adding a breakpoint using the once breakpoint logic.
2079 * Note that this mechanism is a true hw breakpoint and is share between the watchpoint logic.
2080 * This means, you can only have one breakpoint/watchpoint at any time.
2081 */
2082 static int dsp563xx_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
2083 {
2084 return dsp563xx_add_custom_watchpoint(target, breakpoint->address, MEM_P, WPT_READ, EQUAL);
2085 }
2086
2087 static int dsp563xx_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)
2088 {
2089 return dsp563xx_remove_custom_watchpoint(target);
2090 }
2091
2092 COMMAND_HANDLER(dsp563xx_remove_watchpoint_command)
2093 {
2094 struct target *target = get_current_target(CMD_CTX);
2095
2096 return dsp563xx_remove_custom_watchpoint(target);
2097 }
2098
2099 COMMAND_HANDLER(dsp563xx_mem_command)
2100 {
2101 struct target *target = get_current_target(CMD_CTX);
2102 int err = ERROR_OK;
2103 int read_mem;
2104 uint32_t address = 0;
2105 uint32_t count = 1, i;
2106 uint32_t pattern = 0;
2107 uint32_t mem_type;
2108 uint8_t *buffer, *b;
2109
2110 switch (CMD_NAME[1]) {
2111 case 'w':
2112 read_mem = 0;
2113 break;
2114 case 'd':
2115 read_mem = 1;
2116 break;
2117 default:
2118 return ERROR_COMMAND_SYNTAX_ERROR;
2119 }
2120
2121 switch (CMD_NAME[3]) {
2122 case 'x':
2123 mem_type = MEM_X;
2124 break;
2125 case 'y':
2126 mem_type = MEM_Y;
2127 break;
2128 case 'p':
2129 mem_type = MEM_P;
2130 break;
2131 default:
2132 return ERROR_COMMAND_SYNTAX_ERROR;
2133 }
2134
2135 if (CMD_ARGC > 0)
2136 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
2137
2138 if (read_mem == 0) {
2139 if (CMD_ARGC < 2)
2140 return ERROR_COMMAND_SYNTAX_ERROR;
2141 if (CMD_ARGC > 1)
2142 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], pattern);
2143 if (CMD_ARGC > 2)
2144 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], count);
2145 }
2146
2147 if (read_mem == 1) {
2148 if (CMD_ARGC < 1)
2149 return ERROR_COMMAND_SYNTAX_ERROR;
2150 if (CMD_ARGC > 1)
2151 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], count);
2152 }
2153
2154 buffer = calloc(count, sizeof(uint32_t));
2155
2156 if (read_mem == 1) {
2157 err = dsp563xx_read_memory(target, mem_type, address, sizeof(uint32_t),
2158 count, buffer);
2159 if (err == ERROR_OK)
2160 target_handle_md_output(CMD, target, address, sizeof(uint32_t), count, buffer);
2161
2162 } else {
2163 b = buffer;
2164
2165 for (i = 0; i < count; i++) {
2166 target_buffer_set_u32(target, b, pattern);
2167 b += 4;
2168 }
2169
2170 err = dsp563xx_write_memory(target,
2171 mem_type,
2172 address,
2173 sizeof(uint32_t),
2174 count,
2175 buffer);
2176 }
2177
2178 free(buffer);
2179
2180 return err;
2181 }
2182
2183 static const struct command_registration dsp563xx_command_handlers[] = {
2184 {
2185 .name = "mwwx",
2186 .handler = dsp563xx_mem_command,
2187 .mode = COMMAND_EXEC,
2188 .help = "write x memory words",
2189 .usage = "address value [count]",
2190 },
2191 {
2192 .name = "mwwy",
2193 .handler = dsp563xx_mem_command,
2194 .mode = COMMAND_EXEC,
2195 .help = "write y memory words",
2196 .usage = "address value [count]",
2197 },
2198 {
2199 .name = "mwwp",
2200 .handler = dsp563xx_mem_command,
2201 .mode = COMMAND_EXEC,
2202 .help = "write p memory words",
2203 .usage = "address value [count]",
2204 },
2205 {
2206 .name = "mdwx",
2207 .handler = dsp563xx_mem_command,
2208 .mode = COMMAND_EXEC,
2209 .help = "display x memory words",
2210 .usage = "address [count]",
2211 },
2212 {
2213 .name = "mdwy",
2214 .handler = dsp563xx_mem_command,
2215 .mode = COMMAND_EXEC,
2216 .help = "display y memory words",
2217 .usage = "address [count]",
2218 },
2219 {
2220 .name = "mdwp",
2221 .handler = dsp563xx_mem_command,
2222 .mode = COMMAND_EXEC,
2223 .help = "display p memory words",
2224 .usage = "address [count]",
2225 },
2226 /*
2227 * Watchpoint commands
2228 */
2229 {
2230 .name = "wpp",
2231 .handler = dsp563xx_add_watchpoint_command,
2232 .mode = COMMAND_EXEC,
2233 .help = "Create p memspace watchpoint",
2234 .usage = "(>|<|=|!) (r|w|a) address",
2235 },
2236 {
2237 .name = "wpx",
2238 .handler = dsp563xx_add_watchpoint_command,
2239 .mode = COMMAND_EXEC,
2240 .help = "Create x memspace watchpoint",
2241 .usage = "(>|<|=|!) (r|w|a) address",
2242 },
2243 {
2244 .name = "wpy",
2245 .handler = dsp563xx_add_watchpoint_command,
2246 .mode = COMMAND_EXEC,
2247 .help = "Create y memspace watchpoint",
2248 .usage = "(>|<|=|!) (r|w|a) address",
2249 },
2250 {
2251 .name = "rwpc",
2252 .handler = dsp563xx_remove_watchpoint_command,
2253 .mode = COMMAND_EXEC,
2254 .help = "remove watchpoint custom",
2255 .usage = "",
2256 },
2257 COMMAND_REGISTRATION_DONE
2258 };
2259
2260 /** Holds methods for DSP563XX targets. */
2261 struct target_type dsp563xx_target = {
2262 .name = "dsp563xx",
2263
2264 .poll = dsp563xx_poll,
2265 .arch_state = dsp563xx_arch_state,
2266
2267 .get_gdb_reg_list = dsp563xx_get_gdb_reg_list,
2268
2269 .halt = dsp563xx_halt,
2270 .resume = dsp563xx_resume,
2271 .step = dsp563xx_step,
2272
2273 .assert_reset = dsp563xx_assert_reset,
2274 .deassert_reset = dsp563xx_deassert_reset,
2275
2276 .read_memory = dsp563xx_read_memory_default,
2277 .write_memory = dsp563xx_write_memory_default,
2278
2279 .read_buffer = dsp563xx_read_buffer_default,
2280 .write_buffer = dsp563xx_write_buffer_default,
2281
2282 .run_algorithm = dsp563xx_run_algorithm,
2283
2284 .add_breakpoint = dsp563xx_add_breakpoint,
2285 .remove_breakpoint = dsp563xx_remove_breakpoint,
2286 .add_watchpoint = dsp563xx_add_watchpoint,
2287 .remove_watchpoint = dsp563xx_remove_watchpoint,
2288
2289 .commands = dsp563xx_command_handlers,
2290 .target_create = dsp563xx_target_create,
2291 .init_target = dsp563xx_init_target,
2292 .examine = dsp563xx_examine,
2293 };

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)