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

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)