target: constify structures
[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 const 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 = calloc(DSP563XX_NUMCOREREGS, sizeof(struct reg));
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%" PRIx32 " 0x%" PRIx32 " 0x%" PRIx32 ")",
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%03" PRId32 " 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 (%" PRIx32 ")", target_state_name(target), once_status);
1083 LOG_INFO("halted: PC: 0x%" PRIx32, 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%" PRIx32, 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_run_algorithm(struct target *target,
1377 int num_mem_params, struct mem_param *mem_params,
1378 int num_reg_params, struct reg_param *reg_params,
1379 uint32_t entry_point, uint32_t exit_point,
1380 int timeout_ms, void *arch_info)
1381 {
1382 int i;
1383 int retval = ERROR_OK;
1384 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
1385
1386 if (target->state != TARGET_HALTED) {
1387 LOG_WARNING("target not halted");
1388 return ERROR_TARGET_NOT_HALTED;
1389 }
1390
1391 for (i = 0; i < num_mem_params; i++) {
1392 retval = target_write_buffer(target, mem_params[i].address,
1393 mem_params[i].size, mem_params[i].value);
1394 if (retval != ERROR_OK)
1395 return retval;
1396 }
1397
1398 for (i = 0; i < num_reg_params; i++) {
1399 struct reg *reg = register_get_by_name(dsp563xx->core_cache,
1400 reg_params[i].reg_name,
1401 0);
1402
1403 if (!reg) {
1404 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
1405 continue;
1406 }
1407
1408 if (reg->size != reg_params[i].size) {
1409 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1410 reg_params[i].reg_name);
1411 continue;
1412 }
1413
1414 retval = dsp563xx_set_core_reg(reg, reg_params[i].value);
1415 if (retval != ERROR_OK)
1416 return retval;
1417 }
1418
1419 /* exec */
1420 retval = target_resume(target, 0, entry_point, 1, 1);
1421 if (retval != ERROR_OK)
1422 return retval;
1423
1424 retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
1425 if (retval != ERROR_OK)
1426 return retval;
1427
1428 for (i = 0; i < num_mem_params; i++) {
1429 if (mem_params[i].direction != PARAM_OUT)
1430 retval = target_read_buffer(target,
1431 mem_params[i].address,
1432 mem_params[i].size,
1433 mem_params[i].value);
1434 if (retval != ERROR_OK)
1435 return retval;
1436 }
1437
1438 for (i = 0; i < num_reg_params; i++) {
1439 if (reg_params[i].direction != PARAM_OUT) {
1440
1441 struct reg *reg = register_get_by_name(dsp563xx->core_cache,
1442 reg_params[i].reg_name,
1443 0);
1444 if (!reg) {
1445 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
1446 continue;
1447 }
1448
1449 if (reg->size != reg_params[i].size) {
1450 LOG_ERROR(
1451 "BUG: register '%s' size doesn't match reg_params[i].size",
1452 reg_params[i].reg_name);
1453 continue;
1454 }
1455
1456 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
1457 }
1458 }
1459
1460 return ERROR_OK;
1461 }
1462
1463 /* global command context from openocd.c */
1464 extern struct command_context *global_cmd_ctx;
1465
1466 static int dsp563xx_get_default_memory(void)
1467 {
1468 Jim_Interp *interp;
1469 Jim_Obj *memspace;
1470 char *c;
1471
1472 if (!global_cmd_ctx)
1473 return MEM_P;
1474
1475 interp = global_cmd_ctx->interp;
1476
1477 if (!interp)
1478 return MEM_P;
1479
1480 memspace = Jim_GetGlobalVariableStr(interp, "memspace", JIM_NONE);
1481
1482 if (!memspace)
1483 return MEM_P;
1484
1485 c = (char *)Jim_GetString(memspace, NULL);
1486
1487 if (!c)
1488 return MEM_P;
1489
1490 switch (c[0]) {
1491 case '1':
1492 return MEM_X;
1493 case '2':
1494 return MEM_Y;
1495 case '3':
1496 return MEM_L;
1497 default:
1498 break;
1499 }
1500
1501 return MEM_P;
1502 }
1503
1504 static int dsp563xx_read_memory_core(struct target *target,
1505 int mem_type,
1506 uint32_t address,
1507 uint32_t size,
1508 uint32_t count,
1509 uint8_t *buffer)
1510 {
1511 int err;
1512 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
1513 uint32_t i, x;
1514 uint32_t data, move_cmd = 0;
1515 uint8_t *b;
1516
1517 LOG_DEBUG(
1518 "memtype: %d address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
1519 mem_type,
1520 address,
1521 size,
1522 count);
1523
1524 if (target->state != TARGET_HALTED) {
1525 LOG_WARNING("target not halted");
1526 return ERROR_TARGET_NOT_HALTED;
1527 }
1528
1529 switch (mem_type) {
1530 case MEM_X:
1531 /* TODO: mark effected queued registers */
1532 move_cmd = 0x61d800;
1533 break;
1534 case MEM_Y:
1535 move_cmd = 0x69d800;
1536 break;
1537 case MEM_P:
1538 move_cmd = 0x07d891;
1539 break;
1540 default:
1541 return ERROR_COMMAND_SYNTAX_ERROR;
1542 }
1543
1544 /* we use r0 to store temporary data */
1545 if (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].valid)
1546 dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R0);
1547 /* we use r1 to store temporary data */
1548 if (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R1].valid)
1549 dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R1);
1550
1551 /* r0 is no longer valid on target */
1552 dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].dirty = 1;
1553 /* r1 is no longer valid on target */
1554 dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R1].dirty = 1;
1555
1556 x = count;
1557 b = buffer;
1558
1559 err = dsp563xx_once_execute_dw_ir(target->tap, 1, 0x60F400, address);
1560 if (err != ERROR_OK)
1561 return err;
1562
1563 for (i = 0; i < x; i++) {
1564 err = dsp563xx_once_execute_sw_ir(target->tap, 0, move_cmd);
1565 if (err != ERROR_OK)
1566 return err;
1567 err = dsp563xx_once_execute_sw_ir(target->tap, 0, 0x08D13C);
1568 if (err != ERROR_OK)
1569 return err;
1570 err = dsp563xx_once_reg_read(target->tap, 0,
1571 DSP563XX_ONCE_OGDBR, (uint32_t *)(void *)b);
1572 if (err != ERROR_OK)
1573 return err;
1574 b += 4;
1575 }
1576
1577 /* flush the jtag queue */
1578 err = jtag_execute_queue();
1579 if (err != ERROR_OK)
1580 return err;
1581
1582 /* walk over the buffer and fix target endianness */
1583 b = buffer;
1584
1585 for (i = 0; i < x; i++) {
1586 data = buf_get_u32(b, 0, 32) & 0x00FFFFFF;
1587 /* LOG_DEBUG("R: %08X", *((uint32_t*)b)); */
1588 target_buffer_set_u32(target, b, data);
1589 b += 4;
1590 }
1591
1592 return ERROR_OK;
1593 }
1594
1595 static int dsp563xx_read_memory(struct target *target,
1596 int mem_type,
1597 uint32_t address,
1598 uint32_t size,
1599 uint32_t count,
1600 uint8_t *buffer)
1601 {
1602 int err;
1603 uint32_t i, i1;
1604 uint8_t *buffer_y, *buffer_x;
1605
1606 /* if size equals zero we are called from target read memory
1607 * and have to handle the parameter here */
1608 if ((size == 0) && (count != 0)) {
1609 size = count % 4;
1610
1611 if (size)
1612 LOG_DEBUG("size is not aligned to 4 byte");
1613
1614 count = (count - size) / 4;
1615 size = 4;
1616 }
1617
1618 /* we only support 4 byte aligned data */
1619 if ((size != 4) || (!count))
1620 return ERROR_COMMAND_SYNTAX_ERROR;
1621
1622 if (mem_type != MEM_L)
1623 return dsp563xx_read_memory_core(target, mem_type, address, size, count, buffer);
1624
1625 buffer_y = malloc(size * count);
1626 if (!buffer_y)
1627 return ERROR_COMMAND_SYNTAX_ERROR;
1628
1629 buffer_x = malloc(size * count);
1630 if (!buffer_x) {
1631 free(buffer_y);
1632 return ERROR_COMMAND_SYNTAX_ERROR;
1633 }
1634
1635 err = dsp563xx_read_memory_core(target, MEM_Y, address, size, count / 2, buffer_y);
1636
1637 if (err != ERROR_OK) {
1638 free(buffer_y);
1639 free(buffer_x);
1640 return err;
1641 }
1642
1643 err = dsp563xx_read_memory_core(target, MEM_X, address, size, count / 2, buffer_x);
1644
1645 if (err != ERROR_OK) {
1646 free(buffer_y);
1647 free(buffer_x);
1648 return err;
1649 }
1650
1651 for (i = 0, i1 = 0; i < count; i += 2, i1++) {
1652 buf_set_u32(buffer + i*sizeof(uint32_t), 0, 32,
1653 buf_get_u32(buffer_y + i1 * sizeof(uint32_t), 0, 32));
1654 buf_set_u32(buffer + (i + 1) * sizeof(uint32_t), 0, 32,
1655 buf_get_u32(buffer_x + i1 * sizeof(uint32_t), 0, 32));
1656 }
1657
1658 free(buffer_y);
1659 free(buffer_x);
1660
1661 return ERROR_OK;
1662 }
1663
1664 static int dsp563xx_read_memory_default(struct target *target,
1665 uint32_t address,
1666 uint32_t size,
1667 uint32_t count,
1668 uint8_t *buffer)
1669 {
1670
1671 return dsp563xx_read_memory(target,
1672 dsp563xx_get_default_memory(), address, size, count, buffer);
1673 }
1674
1675 static int dsp563xx_read_buffer_default(struct target *target,
1676 uint32_t address,
1677 uint32_t size,
1678 uint8_t *buffer)
1679 {
1680
1681 return dsp563xx_read_memory(target, dsp563xx_get_default_memory(), address, size, 0,
1682 buffer);
1683 }
1684
1685 static int dsp563xx_write_memory_core(struct target *target,
1686 int mem_type,
1687 uint32_t address,
1688 uint32_t size,
1689 uint32_t count,
1690 const uint8_t *buffer)
1691 {
1692 int err;
1693 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
1694 uint32_t i, x;
1695 uint32_t data, move_cmd = 0;
1696 const uint8_t *b;
1697
1698 LOG_DEBUG(
1699 "memtype: %d address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
1700 mem_type,
1701 address,
1702 size,
1703 count);
1704
1705 if (target->state != TARGET_HALTED) {
1706 LOG_WARNING("target not halted");
1707 return ERROR_TARGET_NOT_HALTED;
1708 }
1709
1710 switch (mem_type) {
1711 case MEM_X:
1712 /* invalidate affected x registers */
1713 dsp563xx_invalidate_x_context(target, address, address + count - 1);
1714 move_cmd = 0x615800;
1715 break;
1716 case MEM_Y:
1717 move_cmd = 0x695800;
1718 break;
1719 case MEM_P:
1720 move_cmd = 0x075891;
1721 break;
1722 default:
1723 return ERROR_COMMAND_SYNTAX_ERROR;
1724 }
1725
1726 /* we use r0 to store temporary data */
1727 if (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].valid)
1728 dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R0);
1729 /* we use r1 to store temporary data */
1730 if (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R1].valid)
1731 dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R1);
1732
1733 /* r0 is no longer valid on target */
1734 dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].dirty = 1;
1735 /* r1 is no longer valid on target */
1736 dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R1].dirty = 1;
1737
1738 x = count;
1739 b = buffer;
1740
1741 err = dsp563xx_once_execute_dw_ir(target->tap, 1, 0x60F400, address);
1742 if (err != ERROR_OK)
1743 return err;
1744
1745 for (i = 0; i < x; i++) {
1746 data = target_buffer_get_u32(target, b);
1747
1748 /* LOG_DEBUG("W: %08X", data); */
1749
1750 data &= 0x00ffffff;
1751
1752 err = dsp563xx_once_execute_dw_ir(target->tap, 0, 0x61F400, data);
1753 if (err != ERROR_OK)
1754 return err;
1755 err = dsp563xx_once_execute_sw_ir(target->tap, 0, move_cmd);
1756 if (err != ERROR_OK)
1757 return err;
1758 b += 4;
1759 }
1760
1761 /* flush the jtag queue */
1762 err = jtag_execute_queue();
1763 if (err != ERROR_OK)
1764 return err;
1765
1766 return ERROR_OK;
1767 }
1768
1769 static int dsp563xx_write_memory(struct target *target,
1770 int mem_type,
1771 uint32_t address,
1772 uint32_t size,
1773 uint32_t count,
1774 const uint8_t *buffer)
1775 {
1776 int err;
1777 uint32_t i, i1;
1778 uint8_t *buffer_y, *buffer_x;
1779
1780 /* if size equals zero we are called from target write memory
1781 * and have to handle the parameter here */
1782 if ((size == 0) && (count != 0)) {
1783 size = count % 4;
1784
1785 if (size)
1786 LOG_DEBUG("size is not aligned to 4 byte");
1787
1788 count = (count - size) / 4;
1789 size = 4;
1790 }
1791
1792 /* we only support 4 byte aligned data */
1793 if ((size != 4) || (!count))
1794 return ERROR_COMMAND_SYNTAX_ERROR;
1795
1796 if (mem_type != MEM_L)
1797 return dsp563xx_write_memory_core(target, mem_type, address, size, count, buffer);
1798
1799 buffer_y = malloc(size * count);
1800 if (!buffer_y)
1801 return ERROR_COMMAND_SYNTAX_ERROR;
1802
1803 buffer_x = malloc(size * count);
1804 if (!buffer_x) {
1805 free(buffer_y);
1806 return ERROR_COMMAND_SYNTAX_ERROR;
1807 }
1808
1809 for (i = 0, i1 = 0; i < count; i += 2, i1++) {
1810 buf_set_u32(buffer_y + i1 * sizeof(uint32_t), 0, 32,
1811 buf_get_u32(buffer + i * sizeof(uint32_t), 0, 32));
1812 buf_set_u32(buffer_x + i1 * sizeof(uint32_t), 0, 32,
1813 buf_get_u32(buffer + (i + 1) * sizeof(uint32_t), 0, 32));
1814 }
1815
1816 err = dsp563xx_write_memory_core(target, MEM_Y, address, size, count / 2, buffer_y);
1817
1818 if (err != ERROR_OK) {
1819 free(buffer_y);
1820 free(buffer_x);
1821 return err;
1822 }
1823
1824 err = dsp563xx_write_memory_core(target, MEM_X, address, size, count / 2, buffer_x);
1825
1826 if (err != ERROR_OK) {
1827 free(buffer_y);
1828 free(buffer_x);
1829 return err;
1830 }
1831
1832 free(buffer_y);
1833 free(buffer_x);
1834
1835 return ERROR_OK;
1836 }
1837
1838 static int dsp563xx_write_memory_default(struct target *target,
1839 uint32_t address,
1840 uint32_t size,
1841 uint32_t count,
1842 const uint8_t *buffer)
1843 {
1844 return dsp563xx_write_memory(target,
1845 dsp563xx_get_default_memory(), address, size, count, buffer);
1846 }
1847
1848 static int dsp563xx_write_buffer_default(struct target *target,
1849 uint32_t address,
1850 uint32_t size,
1851 const uint8_t *buffer)
1852 {
1853 return dsp563xx_write_memory(target, dsp563xx_get_default_memory(), address, size, 0,
1854 buffer);
1855 }
1856
1857 /*
1858 * Exit with error here, because we support watchpoints over a custom command.
1859 * This is because the DSP has separate X,Y,P memspace which is not compatible to the
1860 * traditional watchpoint logic.
1861 */
1862 static int dsp563xx_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
1863 {
1864 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1865 }
1866
1867 /*
1868 * @see dsp563xx_add_watchpoint
1869 */
1870 static int dsp563xx_remove_watchpoint(struct target *target, struct watchpoint *watchpoint)
1871 {
1872 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1873 }
1874
1875 static void handle_md_output(struct command_context *cmd_ctx,
1876 struct target *target,
1877 uint32_t address,
1878 unsigned size,
1879 unsigned count,
1880 const uint8_t *buffer)
1881 {
1882 const unsigned line_bytecnt = 32;
1883 unsigned line_modulo = line_bytecnt / size;
1884
1885 char output[line_bytecnt * 4 + 1];
1886 unsigned output_len = 0;
1887
1888 const char *value_fmt;
1889 switch (size) {
1890 case 4:
1891 value_fmt = "%8.8x ";
1892 break;
1893 case 2:
1894 value_fmt = "%4.4x ";
1895 break;
1896 case 1:
1897 value_fmt = "%2.2x ";
1898 break;
1899 default:
1900 /* "can't happen", caller checked */
1901 LOG_ERROR("invalid memory read size: %u", size);
1902 return;
1903 }
1904
1905 for (unsigned i = 0; i < count; i++) {
1906 if (i % line_modulo == 0)
1907 output_len += snprintf(output + output_len,
1908 sizeof(output) - output_len,
1909 "0x%8.8x: ",
1910 (unsigned) (address + i));
1911
1912 uint32_t value = 0;
1913 const uint8_t *value_ptr = buffer + i * size;
1914 switch (size) {
1915 case 4:
1916 value = target_buffer_get_u32(target, value_ptr);
1917 break;
1918 case 2:
1919 value = target_buffer_get_u16(target, value_ptr);
1920 break;
1921 case 1:
1922 value = *value_ptr;
1923 }
1924 output_len += snprintf(output + output_len,
1925 sizeof(output) - output_len,
1926 value_fmt,
1927 value);
1928
1929 if ((i % line_modulo == line_modulo - 1) || (i == count - 1)) {
1930 command_print(cmd_ctx, "%s", output);
1931 output_len = 0;
1932 }
1933 }
1934 }
1935
1936 static int dsp563xx_add_custom_watchpoint(struct target *target, uint32_t address, uint32_t memType,
1937 enum watchpoint_rw rw, enum watchpoint_condition cond)
1938 {
1939 int err = ERROR_OK;
1940 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
1941
1942 bool wasRunning = false;
1943 /* Only set breakpoint when halted */
1944 if (target->state != TARGET_HALTED) {
1945 dsp563xx_halt(target);
1946 wasRunning = true;
1947 }
1948
1949 if (dsp563xx->hardware_breakpoint[0].used) {
1950 LOG_ERROR("Cannot add watchpoint. Hardware resource already used.");
1951 err = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1952 }
1953
1954 uint32_t obcr_value = 0;
1955 if (err == ERROR_OK) {
1956 obcr_value |= OBCR_b0_or_b1;
1957 switch (memType) {
1958 case MEM_X:
1959 obcr_value |= OBCR_BP_MEM_X;
1960 break;
1961 case MEM_Y:
1962 obcr_value |= OBCR_BP_MEM_Y;
1963 break;
1964 case MEM_P:
1965 obcr_value |= OBCR_BP_MEM_P;
1966 break;
1967 default:
1968 LOG_ERROR("Unknown memType parameter (%" PRIu32 ")", memType);
1969 err = ERROR_TARGET_INVALID;
1970 }
1971 }
1972
1973 if (err == ERROR_OK) {
1974 switch (rw) {
1975 case WPT_READ:
1976 obcr_value |= OBCR_BP_0(OBCR_BP_ON_READ);
1977 break;
1978 case WPT_WRITE:
1979 obcr_value |= OBCR_BP_0(OBCR_BP_ON_WRITE);
1980 break;
1981 case WPT_ACCESS:
1982 obcr_value |= OBCR_BP_0(OBCR_BP_ON_READ|OBCR_BP_ON_WRITE);
1983 break;
1984 default:
1985 LOG_ERROR("Unsupported write mode (%d)", rw);
1986 err = ERROR_TARGET_INVALID;
1987 }
1988 }
1989
1990 if (err == ERROR_OK) {
1991 switch (cond) {
1992 case EQUAL:
1993 obcr_value |= OBCR_BP_0(OBCR_BP_CC_EQUAL);
1994 break;
1995 case NOT_EQUAL:
1996 obcr_value |= OBCR_BP_0(OBCR_BP_CC_NOT_EQUAL);
1997 break;
1998 case LESS_THAN:
1999 obcr_value |= OBCR_BP_0(OBCR_BP_CC_LESS_THAN);
2000 break;
2001 case GREATER:
2002 obcr_value |= OBCR_BP_0(OBCR_BP_CC_GREATER_THAN);
2003 break;
2004 default:
2005 LOG_ERROR("Unsupported condition code (%d)", cond);
2006 err = ERROR_TARGET_INVALID;
2007 }
2008 }
2009
2010 if (err == ERROR_OK)
2011 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMLR0, address);
2012
2013 if (err == ERROR_OK)
2014 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMLR1, 0x0);
2015
2016 if (err == ERROR_OK)
2017 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OBCR, obcr_value);
2018
2019 if (err == ERROR_OK) {
2020 /* You should write the memory breakpoint counter to 0 */
2021 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMBC, 0);
2022 }
2023
2024 if (err == ERROR_OK) {
2025 /* You should write the memory breakpoint counter to 0 */
2026 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OTC, 0);
2027 }
2028
2029 if (err == ERROR_OK)
2030 dsp563xx->hardware_breakpoint[0].used = BPU_WATCHPOINT;
2031
2032 if (err == ERROR_OK && wasRunning) {
2033 /* Resume from current PC */
2034 err = dsp563xx_resume(target, 1, 0x0, 0, 0);
2035 }
2036
2037 return err;
2038 }
2039
2040 static int dsp563xx_remove_custom_watchpoint(struct target *target)
2041 {
2042 int err = ERROR_OK;
2043 struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
2044
2045 if (dsp563xx->hardware_breakpoint[0].used != BPU_WATCHPOINT) {
2046 LOG_ERROR("Cannot remove watchpoint, as no watchpoint is currently configured!");
2047 err = ERROR_TARGET_INVALID;
2048 }
2049
2050 if (err == ERROR_OK) {
2051 /* Clear watchpoint by clearing OBCR. */
2052 err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OBCR, 0);
2053 }
2054
2055 if (err == ERROR_OK)
2056 dsp563xx->hardware_breakpoint[0].used = BPU_NONE;
2057
2058 return err;
2059 }
2060
2061 COMMAND_HANDLER(dsp563xx_add_watchpoint_command)
2062 {
2063 int err = ERROR_OK;
2064 struct target *target = get_current_target(CMD_CTX);
2065
2066 uint32_t mem_type = 0;
2067 switch (CMD_NAME[2]) {
2068 case 'x':
2069 mem_type = MEM_X;
2070 break;
2071 case 'y':
2072 mem_type = MEM_Y;
2073 break;
2074 case 'p':
2075 mem_type = MEM_P;
2076 break;
2077 default:
2078 return ERROR_COMMAND_SYNTAX_ERROR;
2079 }
2080
2081 if (CMD_ARGC < 2)
2082 return ERROR_COMMAND_SYNTAX_ERROR;
2083
2084 uint32_t address = 0;
2085 if (CMD_ARGC > 2)
2086 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], address);
2087
2088 enum watchpoint_condition cond;
2089 switch (CMD_ARGV[0][0]) {
2090 case '>':
2091 cond = GREATER;
2092 break;
2093 case '<':
2094 cond = LESS_THAN;
2095 break;
2096 case '=':
2097 cond = EQUAL;
2098 break;
2099 case '!':
2100 cond = NOT_EQUAL;
2101 break;
2102 default:
2103 return ERROR_COMMAND_SYNTAX_ERROR;
2104 }
2105
2106 enum watchpoint_rw rw;
2107 switch (CMD_ARGV[1][0]) {
2108 case 'r':
2109 rw = WPT_READ;
2110 break;
2111 case 'w':
2112 rw = WPT_WRITE;
2113 break;
2114 case 'a':
2115 rw = WPT_ACCESS;
2116 break;
2117 default:
2118 return ERROR_COMMAND_SYNTAX_ERROR;
2119 }
2120
2121 err = dsp563xx_add_custom_watchpoint(target, address, mem_type, rw, cond);
2122
2123 return err;
2124 }
2125
2126 /* Adding a breakpoint using the once breakpoint logic.
2127 * Note that this mechanism is a true hw breakpoint and is share between the watchpoint logic.
2128 * This means, you can only have one breakpoint/watchpoint at any time.
2129 */
2130 static int dsp563xx_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
2131 {
2132 return dsp563xx_add_custom_watchpoint(target, breakpoint->address, MEM_P, WPT_READ, EQUAL);
2133 }
2134
2135 static int dsp563xx_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)
2136 {
2137 return dsp563xx_remove_custom_watchpoint(target);
2138 }
2139
2140 COMMAND_HANDLER(dsp563xx_remove_watchpoint_command)
2141 {
2142 struct target *target = get_current_target(CMD_CTX);
2143
2144 return dsp563xx_remove_custom_watchpoint(target);
2145 }
2146
2147 COMMAND_HANDLER(dsp563xx_mem_command)
2148 {
2149 struct target *target = get_current_target(CMD_CTX);
2150 int err = ERROR_OK;
2151 int read_mem;
2152 uint32_t address = 0;
2153 uint32_t count = 1, i;
2154 uint32_t pattern = 0;
2155 uint32_t mem_type;
2156 uint8_t *buffer, *b;
2157
2158 switch (CMD_NAME[1]) {
2159 case 'w':
2160 read_mem = 0;
2161 break;
2162 case 'd':
2163 read_mem = 1;
2164 break;
2165 default:
2166 return ERROR_COMMAND_SYNTAX_ERROR;
2167 }
2168
2169 switch (CMD_NAME[3]) {
2170 case 'x':
2171 mem_type = MEM_X;
2172 break;
2173 case 'y':
2174 mem_type = MEM_Y;
2175 break;
2176 case 'p':
2177 mem_type = MEM_P;
2178 break;
2179 default:
2180 return ERROR_COMMAND_SYNTAX_ERROR;
2181 }
2182
2183 if (CMD_ARGC > 0)
2184 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
2185
2186 if (read_mem == 0) {
2187 if (CMD_ARGC < 2)
2188 return ERROR_COMMAND_SYNTAX_ERROR;
2189 if (CMD_ARGC > 1)
2190 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], pattern);
2191 if (CMD_ARGC > 2)
2192 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], count);
2193 }
2194
2195 if (read_mem == 1) {
2196 if (CMD_ARGC < 1)
2197 return ERROR_COMMAND_SYNTAX_ERROR;
2198 if (CMD_ARGC > 1)
2199 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], count);
2200 }
2201
2202 buffer = calloc(count, sizeof(uint32_t));
2203
2204 if (read_mem == 1) {
2205 err = dsp563xx_read_memory(target, mem_type, address, sizeof(uint32_t),
2206 count, buffer);
2207 if (err == ERROR_OK)
2208 handle_md_output(CMD_CTX, target, address, sizeof(uint32_t), count, buffer);
2209
2210 } else {
2211 b = buffer;
2212
2213 for (i = 0; i < count; i++) {
2214 target_buffer_set_u32(target, b, pattern);
2215 b += 4;
2216 }
2217
2218 err = dsp563xx_write_memory(target,
2219 mem_type,
2220 address,
2221 sizeof(uint32_t),
2222 count,
2223 buffer);
2224 }
2225
2226 free(buffer);
2227
2228 return err;
2229 }
2230
2231 static const struct command_registration dsp563xx_command_handlers[] = {
2232 {
2233 .name = "mwwx",
2234 .handler = dsp563xx_mem_command,
2235 .mode = COMMAND_EXEC,
2236 .help = "write x memory words",
2237 .usage = "address value [count]",
2238 },
2239 {
2240 .name = "mwwy",
2241 .handler = dsp563xx_mem_command,
2242 .mode = COMMAND_EXEC,
2243 .help = "write y memory words",
2244 .usage = "address value [count]",
2245 },
2246 {
2247 .name = "mwwp",
2248 .handler = dsp563xx_mem_command,
2249 .mode = COMMAND_EXEC,
2250 .help = "write p memory words",
2251 .usage = "address value [count]",
2252 },
2253 {
2254 .name = "mdwx",
2255 .handler = dsp563xx_mem_command,
2256 .mode = COMMAND_EXEC,
2257 .help = "display x memory words",
2258 .usage = "address [count]",
2259 },
2260 {
2261 .name = "mdwy",
2262 .handler = dsp563xx_mem_command,
2263 .mode = COMMAND_EXEC,
2264 .help = "display y memory words",
2265 .usage = "address [count]",
2266 },
2267 {
2268 .name = "mdwp",
2269 .handler = dsp563xx_mem_command,
2270 .mode = COMMAND_EXEC,
2271 .help = "display p memory words",
2272 .usage = "address [count]",
2273 },
2274 /*
2275 * Watchpoint commands
2276 */
2277 {
2278 .name = "wpp",
2279 .handler = dsp563xx_add_watchpoint_command,
2280 .mode = COMMAND_EXEC,
2281 .help = "Create p memspace watchpoint",
2282 .usage = "(>|<|=|!) (r|w|a) address",
2283 },
2284 {
2285 .name = "wpx",
2286 .handler = dsp563xx_add_watchpoint_command,
2287 .mode = COMMAND_EXEC,
2288 .help = "Create x memspace watchpoint",
2289 .usage = "(>|<|=|!) (r|w|a) address",
2290 },
2291 {
2292 .name = "wpy",
2293 .handler = dsp563xx_add_watchpoint_command,
2294 .mode = COMMAND_EXEC,
2295 .help = "Create y memspace watchpoint",
2296 .usage = "(>|<|=|!) (r|w|a) address",
2297 },
2298 {
2299 .name = "rwpc",
2300 .handler = dsp563xx_remove_watchpoint_command,
2301 .mode = COMMAND_EXEC,
2302 .help = "remove watchpoint custom",
2303 .usage = " ",
2304 },
2305 COMMAND_REGISTRATION_DONE
2306 };
2307
2308 /** Holds methods for DSP563XX targets. */
2309 struct target_type dsp563xx_target = {
2310 .name = "dsp563xx",
2311
2312 .poll = dsp563xx_poll,
2313 .arch_state = dsp563xx_arch_state,
2314
2315 .get_gdb_reg_list = dsp563xx_get_gdb_reg_list,
2316
2317 .halt = dsp563xx_halt,
2318 .resume = dsp563xx_resume,
2319 .step = dsp563xx_step,
2320
2321 .assert_reset = dsp563xx_assert_reset,
2322 .deassert_reset = dsp563xx_deassert_reset,
2323
2324 .read_memory = dsp563xx_read_memory_default,
2325 .write_memory = dsp563xx_write_memory_default,
2326
2327 .read_buffer = dsp563xx_read_buffer_default,
2328 .write_buffer = dsp563xx_write_buffer_default,
2329
2330 .run_algorithm = dsp563xx_run_algorithm,
2331
2332 .add_breakpoint = dsp563xx_add_breakpoint,
2333 .remove_breakpoint = dsp563xx_remove_breakpoint,
2334 .add_watchpoint = dsp563xx_add_watchpoint,
2335 .remove_watchpoint = dsp563xx_remove_watchpoint,
2336
2337 .commands = dsp563xx_command_handlers,
2338 .target_create = dsp563xx_target_create,
2339 .init_target = dsp563xx_init_target,
2340 .examine = dsp563xx_examine,
2341 };

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)