1 /***************************************************************************
2 * Copyright (C) 2009-2011 by Mathias Kuester *
3 * mkdorg@users.sourceforge.net *
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. *
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. *
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 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
27 #include "target_type.h"
30 #include "dsp563xx_once.h"
32 #define ASM_REG_W_R0 0x60F400
33 #define ASM_REG_W_R1 0x61F400
34 #define ASM_REG_W_R2 0x62F400
35 #define ASM_REG_W_R3 0x63F400
36 #define ASM_REG_W_R4 0x64F400
37 #define ASM_REG_W_R5 0x65F400
38 #define ASM_REG_W_R6 0x66F400
39 #define ASM_REG_W_R7 0x67F400
41 #define ASM_REG_W_N0 0x70F400
42 #define ASM_REG_W_N1 0x71F400
43 #define ASM_REG_W_N2 0x72F400
44 #define ASM_REG_W_N3 0x73F400
45 #define ASM_REG_W_N4 0x74F400
46 #define ASM_REG_W_N5 0x75F400
47 #define ASM_REG_W_N6 0x76F400
48 #define ASM_REG_W_N7 0x77F400
50 #define ASM_REG_W_M0 0x05F420
51 #define ASM_REG_W_M1 0x05F421
52 #define ASM_REG_W_M2 0x05F422
53 #define ASM_REG_W_M3 0x05F423
54 #define ASM_REG_W_M4 0x05F424
55 #define ASM_REG_W_M5 0x05F425
56 #define ASM_REG_W_M6 0x05F426
57 #define ASM_REG_W_M7 0x05F427
59 #define ASM_REG_W_X0 0x44F400
60 #define ASM_REG_W_X1 0x45F400
62 #define ASM_REG_W_Y0 0x46F400
63 #define ASM_REG_W_Y1 0x47F400
65 #define ASM_REG_W_A0 0x50F400
66 #define ASM_REG_W_A1 0x54F400
67 #define ASM_REG_W_A2 0x52F400
69 #define ASM_REG_W_B0 0x51F400
70 #define ASM_REG_W_B1 0x55F400
71 #define ASM_REG_W_B2 0x53F400
73 #define ASM_REG_W_VBA 0x05F430
74 #define ASM_REG_W_OMR 0x05F43A
75 #define ASM_REG_W_EP 0x05F42A
76 #define ASM_REG_W_SC 0x05F431
77 #define ASM_REG_W_SZ 0x05F438
78 #define ASM_REG_W_SR 0x05F439
79 #define ASM_REG_W_SP 0x05F43B
80 #define ASM_REG_W_SSH 0x05F43C
81 #define ASM_REG_W_SSL 0x05F43D
82 #define ASM_REG_W_LA 0x05F43E
83 #define ASM_REG_W_LC 0x05F43F
84 #define ASM_REG_W_PC 0x000000
85 #define ASM_REG_W_IPRC 0xFFFFFF
86 #define ASM_REG_W_IPRP 0xFFFFFE
88 #define ASM_REG_W_BCR 0xFFFFFB
89 #define ASM_REG_W_DCR 0xFFFFFA
90 #define ASM_REG_W_AAR0 0xFFFFF9
91 #define ASM_REG_W_AAR1 0xFFFFF8
92 #define ASM_REG_W_AAR2 0xFFFFF7
93 #define ASM_REG_W_AAR3 0xFFFFF6
100 ONCE_REG_IDX_OMLR1
=4,
101 ONCE_REG_IDX_OGDBR
=5,
102 ONCE_REG_IDX_OPDBR
=6,
103 ONCE_REG_IDX_OPILR
=7,
106 ONCE_REG_IDX_OPABFR
=10,
107 ONCE_REG_IDX_OPABDR
=11,
108 ONCE_REG_IDX_OPABEX
=12,
109 ONCE_REG_IDX_OPABF0
=13,
110 ONCE_REG_IDX_OPABF1
=14,
111 ONCE_REG_IDX_OPABF2
=15,
112 ONCE_REG_IDX_OPABF3
=16,
113 ONCE_REG_IDX_OPABF4
=17,
114 ONCE_REG_IDX_OPABF5
=18,
115 ONCE_REG_IDX_OPABF6
=19,
116 ONCE_REG_IDX_OPABF7
=20,
117 ONCE_REG_IDX_OPABF8
=21,
118 ONCE_REG_IDX_OPABF9
=22,
119 ONCE_REG_IDX_OPABF10
=23,
120 ONCE_REG_IDX_OPABF11
=24,
123 static struct once_reg once_regs
[] = {
124 {ONCE_REG_IDX_OSCR
, DSP563XX_ONCE_OSCR
, 24, "OSCR", 0},
125 {ONCE_REG_IDX_OMBC
, DSP563XX_ONCE_OMBC
, 24, "OMBC", 0},
126 {ONCE_REG_IDX_OBCR
, DSP563XX_ONCE_OBCR
, 24, "OBCR", 0},
127 {ONCE_REG_IDX_OMLR0
, DSP563XX_ONCE_OMLR0
, 24, "OMLR0", 0},
128 {ONCE_REG_IDX_OMLR1
, DSP563XX_ONCE_OMLR1
, 24, "OMLR1", 0},
129 {ONCE_REG_IDX_OGDBR
, DSP563XX_ONCE_OGDBR
, 24, "OGDBR", 0},
130 {ONCE_REG_IDX_OPDBR
, DSP563XX_ONCE_OPDBR
, 24, "OPDBR", 0},
131 {ONCE_REG_IDX_OPILR
, DSP563XX_ONCE_OPILR
, 24, "OPILR", 0},
132 {ONCE_REG_IDX_PDB
, DSP563XX_ONCE_PDBGOTO
, 24, "PDB", 0},
133 {ONCE_REG_IDX_OTC
, DSP563XX_ONCE_OTC
, 24, "OTC", 0},
134 {ONCE_REG_IDX_OPABFR
, DSP563XX_ONCE_OPABFR
, 24, "OPABFR", 0},
135 {ONCE_REG_IDX_OPABDR
, DSP563XX_ONCE_OPABDR
, 24, "OPABDR", 0},
136 {ONCE_REG_IDX_OPABEX
, DSP563XX_ONCE_OPABEX
, 24, "OPABEX", 0},
137 {ONCE_REG_IDX_OPABF0
, DSP563XX_ONCE_OPABF11
, 25, "OPABF0", 0},
138 {ONCE_REG_IDX_OPABF1
, DSP563XX_ONCE_OPABF11
, 25, "OPABF1", 0},
139 {ONCE_REG_IDX_OPABF2
, DSP563XX_ONCE_OPABF11
, 25, "OPABF2", 0},
140 {ONCE_REG_IDX_OPABF3
, DSP563XX_ONCE_OPABF11
, 25, "OPABF3", 0},
141 {ONCE_REG_IDX_OPABF4
, DSP563XX_ONCE_OPABF11
, 25, "OPABF4", 0},
142 {ONCE_REG_IDX_OPABF5
, DSP563XX_ONCE_OPABF11
, 25, "OPABF5", 0},
143 {ONCE_REG_IDX_OPABF6
, DSP563XX_ONCE_OPABF11
, 25, "OPABF6", 0},
144 {ONCE_REG_IDX_OPABF7
, DSP563XX_ONCE_OPABF11
, 25, "OPABF7", 0},
145 {ONCE_REG_IDX_OPABF8
, DSP563XX_ONCE_OPABF11
, 25, "OPABF8", 0},
146 {ONCE_REG_IDX_OPABF9
, DSP563XX_ONCE_OPABF11
, 25, "OPABF9", 0},
147 {ONCE_REG_IDX_OPABF10
, DSP563XX_ONCE_OPABF11
, 25, "OPABF10", 0},
148 {ONCE_REG_IDX_OPABF11
, DSP563XX_ONCE_OPABF11
, 25, "OPABF11", 0},
149 // {25,0x1f,24,"NRSEL",0},
152 enum dsp563xx_reg_idx
{
153 DSP563XX_REG_IDX_R0
=0,
154 DSP563XX_REG_IDX_R1
=1,
155 DSP563XX_REG_IDX_R2
=2,
156 DSP563XX_REG_IDX_R3
=3,
157 DSP563XX_REG_IDX_R4
=4,
158 DSP563XX_REG_IDX_R5
=5,
159 DSP563XX_REG_IDX_R6
=6,
160 DSP563XX_REG_IDX_R7
=7,
161 DSP563XX_REG_IDX_N0
=8,
162 DSP563XX_REG_IDX_N1
=9,
163 DSP563XX_REG_IDX_N2
=10,
164 DSP563XX_REG_IDX_N3
=11,
165 DSP563XX_REG_IDX_N4
=12,
166 DSP563XX_REG_IDX_N5
=13,
167 DSP563XX_REG_IDX_N6
=14,
168 DSP563XX_REG_IDX_N7
=15,
169 DSP563XX_REG_IDX_M0
=16,
170 DSP563XX_REG_IDX_M1
=17,
171 DSP563XX_REG_IDX_M2
=18,
172 DSP563XX_REG_IDX_M3
=19,
173 DSP563XX_REG_IDX_M4
=20,
174 DSP563XX_REG_IDX_M5
=21,
175 DSP563XX_REG_IDX_M6
=22,
176 DSP563XX_REG_IDX_M7
=23,
177 DSP563XX_REG_IDX_X0
=24,
178 DSP563XX_REG_IDX_X1
=25,
179 DSP563XX_REG_IDX_Y0
=26,
180 DSP563XX_REG_IDX_Y1
=27,
181 DSP563XX_REG_IDX_A0
=28,
182 DSP563XX_REG_IDX_A1
=29,
183 DSP563XX_REG_IDX_A2
=30,
184 DSP563XX_REG_IDX_B0
=31,
185 DSP563XX_REG_IDX_B1
=32,
186 DSP563XX_REG_IDX_B2
=33,
187 DSP563XX_REG_IDX_SSH
=34,
188 DSP563XX_REG_IDX_SSL
=35,
189 DSP563XX_REG_IDX_SP
=36,
190 DSP563XX_REG_IDX_EP
=37,
191 DSP563XX_REG_IDX_SZ
=38,
192 DSP563XX_REG_IDX_SC
=39,
193 DSP563XX_REG_IDX_PC
=40,
194 DSP563XX_REG_IDX_SR
=41,
195 DSP563XX_REG_IDX_OMR
=42,
196 DSP563XX_REG_IDX_LA
=43,
197 DSP563XX_REG_IDX_LC
=44,
198 DSP563XX_REG_IDX_VBA
=45,
199 DSP563XX_REG_IDX_IPRC
=46,
200 DSP563XX_REG_IDX_IPRP
=47,
201 DSP563XX_REG_IDX_BCR
=48,
202 DSP563XX_REG_IDX_DCR
=49,
203 DSP563XX_REG_IDX_AAR0
=50,
204 DSP563XX_REG_IDX_AAR1
=51,
205 DSP563XX_REG_IDX_AAR2
=52,
206 DSP563XX_REG_IDX_AAR3
=53,
214 /* effective addressing mode encoding */
220 /* address registers */
221 {DSP563XX_REG_IDX_R0
, "r0", 24, 0x10, ASM_REG_W_R0
},
222 {DSP563XX_REG_IDX_R1
, "r1", 24, 0x11, ASM_REG_W_R1
},
223 {DSP563XX_REG_IDX_R2
, "r2", 24, 0x12, ASM_REG_W_R2
},
224 {DSP563XX_REG_IDX_R3
, "r3", 24, 0x13, ASM_REG_W_R3
},
225 {DSP563XX_REG_IDX_R4
, "r4", 24, 0x14, ASM_REG_W_R4
},
226 {DSP563XX_REG_IDX_R5
, "r5", 24, 0x15, ASM_REG_W_R5
},
227 {DSP563XX_REG_IDX_R6
, "r6", 24, 0x16, ASM_REG_W_R6
},
228 {DSP563XX_REG_IDX_R7
, "r7", 24, 0x17, ASM_REG_W_R7
},
229 /* offset registers */
230 {DSP563XX_REG_IDX_N0
, "n0", 24, 0x18, ASM_REG_W_N0
},
231 {DSP563XX_REG_IDX_N1
, "n1", 24, 0x19, ASM_REG_W_N1
},
232 {DSP563XX_REG_IDX_N2
, "n2", 24, 0x1a, ASM_REG_W_N2
},
233 {DSP563XX_REG_IDX_N3
, "n3", 24, 0x1b, ASM_REG_W_N3
},
234 {DSP563XX_REG_IDX_N4
, "n4", 24, 0x1c, ASM_REG_W_N4
},
235 {DSP563XX_REG_IDX_N5
, "n5", 24, 0x1d, ASM_REG_W_N5
},
236 {DSP563XX_REG_IDX_N6
, "n6", 24, 0x1e, ASM_REG_W_N6
},
237 {DSP563XX_REG_IDX_N7
, "n7", 24, 0x1f, ASM_REG_W_N7
},
238 /* modifier registers */
239 {DSP563XX_REG_IDX_M0
, "m0", 24, 0x20, ASM_REG_W_M0
},
240 {DSP563XX_REG_IDX_M1
, "m1", 24, 0x21, ASM_REG_W_M1
},
241 {DSP563XX_REG_IDX_M2
, "m2", 24, 0x22, ASM_REG_W_M2
},
242 {DSP563XX_REG_IDX_M3
, "m3", 24, 0x23, ASM_REG_W_M3
},
243 {DSP563XX_REG_IDX_M4
, "m4", 24, 0x24, ASM_REG_W_M4
},
244 {DSP563XX_REG_IDX_M5
, "m5", 24, 0x25, ASM_REG_W_M5
},
245 {DSP563XX_REG_IDX_M6
, "m6", 24, 0x26, ASM_REG_W_M6
},
246 {DSP563XX_REG_IDX_M7
, "m7", 24, 0x27, ASM_REG_W_M7
},
247 /* data alu input register */
248 {DSP563XX_REG_IDX_X0
, "x0", 24, 0x04, ASM_REG_W_X0
},
249 {DSP563XX_REG_IDX_X1
, "x1", 24, 0x05, ASM_REG_W_X1
},
250 {DSP563XX_REG_IDX_Y0
, "y0", 24, 0x06, ASM_REG_W_Y0
},
251 {DSP563XX_REG_IDX_Y1
, "y1", 24, 0x07, ASM_REG_W_Y1
},
252 /* data alu accumulator register */
253 {DSP563XX_REG_IDX_A0
, "a0", 24, 0x08, ASM_REG_W_A0
},
254 {DSP563XX_REG_IDX_A1
, "a1", 24, 0x0c, ASM_REG_W_A1
},
255 {DSP563XX_REG_IDX_A2
, "a2", 8, 0x0a, ASM_REG_W_A2
},
256 {DSP563XX_REG_IDX_B0
, "b0", 24, 0x09, ASM_REG_W_B0
},
257 {DSP563XX_REG_IDX_B1
, "b1", 24, 0x0d, ASM_REG_W_B1
},
258 {DSP563XX_REG_IDX_B2
, "b2", 8, 0x0b, ASM_REG_W_B2
},
260 {DSP563XX_REG_IDX_SSH
, "ssh",24, 0x3c, ASM_REG_W_SSH
},
261 {DSP563XX_REG_IDX_SSL
, "ssl",24, 0x3d, ASM_REG_W_SSL
},
262 {DSP563XX_REG_IDX_SP
, "sp", 24, 0x3b, ASM_REG_W_SP
},
263 {DSP563XX_REG_IDX_EP
, "ep", 24, 0x2a, ASM_REG_W_EP
},
264 {DSP563XX_REG_IDX_SZ
, "sz", 24, 0x38, ASM_REG_W_SZ
},
265 {DSP563XX_REG_IDX_SC
, "sc", 24, 0x31, ASM_REG_W_SC
},
267 {DSP563XX_REG_IDX_PC
, "pc", 24, 0x00, ASM_REG_W_PC
},
268 {DSP563XX_REG_IDX_SR
, "sr", 24, 0x39, ASM_REG_W_SR
},
269 {DSP563XX_REG_IDX_OMR
, "omr",24, 0x3a, ASM_REG_W_OMR
},
270 {DSP563XX_REG_IDX_LA
, "la", 24, 0x3e, ASM_REG_W_LA
},
271 {DSP563XX_REG_IDX_LC
, "lc", 24, 0x3f, ASM_REG_W_LC
},
273 {DSP563XX_REG_IDX_VBA
, "vba", 24, 0x30, ASM_REG_W_VBA
},
274 {DSP563XX_REG_IDX_IPRC
, "iprc",24, 0x00, ASM_REG_W_IPRC
},
275 {DSP563XX_REG_IDX_IPRP
, "iprp",24, 0x00, ASM_REG_W_IPRP
},
277 {DSP563XX_REG_IDX_BCR
, "bcr", 24, 0x00, ASM_REG_W_BCR
},
278 {DSP563XX_REG_IDX_DCR
, "dcr", 24, 0x00, ASM_REG_W_DCR
},
279 {DSP563XX_REG_IDX_AAR0
, "aar0",24, 0x00, ASM_REG_W_AAR0
},
280 {DSP563XX_REG_IDX_AAR1
, "aar1",24, 0x00, ASM_REG_W_AAR1
},
281 {DSP563XX_REG_IDX_AAR2
, "aar2",24, 0x00, ASM_REG_W_AAR2
},
282 {DSP563XX_REG_IDX_AAR3
, "aar3",24, 0x00, ASM_REG_W_AAR3
},
294 #define INSTR_JUMP 0x0AF080
295 /* Effective Addressing Mode Encoding */
297 /* instrcution encoder */
299 * s - peripheral space X/Y (X=0,Y=1)
301 * d - source/destination register
302 * p - IO short address
304 #define INSTR_MOVEP_REG_HIO(s,w,d,p) (0x084000 | ((s & 1)<<16) | ((w&1)<<15) | ((d & 0x3f)<<8) | (p & 0x3f))
306 /* the gdb register list is send in this order */
307 uint8_t gdb_reg_list_idx
[] = {
308 DSP563XX_REG_IDX_X1
, DSP563XX_REG_IDX_X0
, DSP563XX_REG_IDX_Y1
, DSP563XX_REG_IDX_Y0
,
309 DSP563XX_REG_IDX_A2
, DSP563XX_REG_IDX_A1
, DSP563XX_REG_IDX_A0
, DSP563XX_REG_IDX_B2
,
310 DSP563XX_REG_IDX_B1
, DSP563XX_REG_IDX_B0
, DSP563XX_REG_IDX_PC
, DSP563XX_REG_IDX_SR
,
311 DSP563XX_REG_IDX_OMR
,DSP563XX_REG_IDX_LA
, DSP563XX_REG_IDX_LC
, DSP563XX_REG_IDX_SSH
,
312 DSP563XX_REG_IDX_SSL
,DSP563XX_REG_IDX_SP
, DSP563XX_REG_IDX_EP
, DSP563XX_REG_IDX_SZ
,
313 DSP563XX_REG_IDX_SC
, DSP563XX_REG_IDX_VBA
,DSP563XX_REG_IDX_IPRC
, DSP563XX_REG_IDX_IPRP
,
314 DSP563XX_REG_IDX_BCR
,DSP563XX_REG_IDX_DCR
,DSP563XX_REG_IDX_AAR0
,DSP563XX_REG_IDX_AAR1
,
315 DSP563XX_REG_IDX_AAR2
,DSP563XX_REG_IDX_AAR3
,DSP563XX_REG_IDX_R0
,DSP563XX_REG_IDX_R1
,
316 DSP563XX_REG_IDX_R2
, DSP563XX_REG_IDX_R3
, DSP563XX_REG_IDX_R4
, DSP563XX_REG_IDX_R5
,
317 DSP563XX_REG_IDX_R6
, DSP563XX_REG_IDX_R7
, DSP563XX_REG_IDX_N0
, DSP563XX_REG_IDX_N1
,
318 DSP563XX_REG_IDX_N2
, DSP563XX_REG_IDX_N3
, DSP563XX_REG_IDX_N4
, DSP563XX_REG_IDX_N5
,
319 DSP563XX_REG_IDX_N6
, DSP563XX_REG_IDX_N7
, DSP563XX_REG_IDX_M0
, DSP563XX_REG_IDX_M1
,
320 DSP563XX_REG_IDX_M2
, DSP563XX_REG_IDX_M3
, DSP563XX_REG_IDX_M4
, DSP563XX_REG_IDX_M5
,
321 DSP563XX_REG_IDX_M6
, DSP563XX_REG_IDX_M7
,
324 static int dsp563xx_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[], int *reg_list_size
)
327 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
329 if (target
->state
!= TARGET_HALTED
)
331 return ERROR_TARGET_NOT_HALTED
;
334 *reg_list_size
= DSP563XX_NUMCOREREGS
;
335 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
338 return ERROR_INVALID_ARGUMENTS
;
340 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++)
342 (*reg_list
)[i
] = &dsp563xx
->core_cache
->reg_list
[gdb_reg_list_idx
[i
]];
349 static int dsp563xx_read_core_reg(struct target
*target
, int num
)
352 struct dsp563xx_core_reg
*dsp563xx_core_reg
;
353 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
355 if ((num
< 0) || (num
>= DSP563XX_NUMCOREREGS
))
356 return ERROR_INVALID_ARGUMENTS
;
358 dsp563xx_core_reg
= dsp563xx
->core_cache
->reg_list
[num
].arch_info
;
359 reg_value
= dsp563xx
->core_regs
[num
];
360 buf_set_u32(dsp563xx
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
361 dsp563xx
->core_cache
->reg_list
[num
].valid
= 1;
362 dsp563xx
->core_cache
->reg_list
[num
].dirty
= 0;
367 static int dsp563xx_write_core_reg(struct target
*target
, int num
)
370 struct dsp563xx_core_reg
*dsp563xx_core_reg
;
371 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
373 if ((num
< 0) || (num
>= DSP563XX_NUMCOREREGS
))
374 return ERROR_INVALID_ARGUMENTS
;
376 reg_value
= buf_get_u32(dsp563xx
->core_cache
->reg_list
[num
].value
, 0, 32);
377 dsp563xx_core_reg
= dsp563xx
->core_cache
->reg_list
[num
].arch_info
;
378 dsp563xx
->core_regs
[num
] = reg_value
;
379 dsp563xx
->core_cache
->reg_list
[num
].valid
= 1;
380 dsp563xx
->core_cache
->reg_list
[num
].dirty
= 0;
385 static int dsp563xx_get_core_reg(struct reg
*reg
)
387 struct dsp563xx_core_reg
*dsp563xx_reg
= reg
->arch_info
;
388 struct target
*target
= dsp563xx_reg
->target
;
389 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
391 LOG_DEBUG("%s", __FUNCTION__
);
393 if (target
->state
!= TARGET_HALTED
)
395 return ERROR_TARGET_NOT_HALTED
;
398 return dsp563xx
->read_core_reg(target
, dsp563xx_reg
->num
);
401 static int dsp563xx_set_core_reg(struct reg
*reg
, uint8_t * buf
)
403 LOG_DEBUG("%s", __FUNCTION__
);
405 struct dsp563xx_core_reg
*dsp563xx_reg
= reg
->arch_info
;
406 struct target
*target
= dsp563xx_reg
->target
;
407 uint32_t value
= buf_get_u32(buf
, 0, 32);
409 if (target
->state
!= TARGET_HALTED
)
411 return ERROR_TARGET_NOT_HALTED
;
414 buf_set_u32(reg
->value
, 0, reg
->size
, value
);
421 static const struct reg_arch_type dsp563xx_reg_type
= {
422 .get
= dsp563xx_get_core_reg
,
423 .set
= dsp563xx_set_core_reg
,
426 static void dsp563xx_build_reg_cache(struct target
*target
)
428 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
430 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
431 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
432 struct reg
*reg_list
= malloc(sizeof(struct reg
) * DSP563XX_NUMCOREREGS
);
433 struct dsp563xx_core_reg
*arch_info
= malloc(sizeof(struct dsp563xx_core_reg
) * DSP563XX_NUMCOREREGS
);
436 /* Build the process context cache */
437 cache
->name
= "dsp563xx registers";
439 cache
->reg_list
= reg_list
;
440 cache
->num_regs
= DSP563XX_NUMCOREREGS
;
442 dsp563xx
->core_cache
= cache
;
444 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++)
446 arch_info
[i
].num
= dsp563xx_regs
[i
].id
;
447 arch_info
[i
].name
= dsp563xx_regs
[i
].name
;
448 arch_info
[i
].size
= dsp563xx_regs
[i
].bits
;
449 arch_info
[i
].eame
= dsp563xx_regs
[i
].eame
;
450 arch_info
[i
].instr_mask
= dsp563xx_regs
[i
].instr_mask
;
451 arch_info
[i
].target
= target
;
452 arch_info
[i
].dsp563xx_common
= dsp563xx
;
453 reg_list
[i
].name
= dsp563xx_regs
[i
].name
;
454 reg_list
[i
].size
= 32; //dsp563xx_regs[i].bits;
455 reg_list
[i
].value
= calloc(1, 4);
456 reg_list
[i
].dirty
= 0;
457 reg_list
[i
].valid
= 0;
458 reg_list
[i
].type
= &dsp563xx_reg_type
;
459 reg_list
[i
].arch_info
= &arch_info
[i
];
463 static int dsp563xx_read_register(struct target
*target
, int num
, int force
);
464 static int dsp563xx_write_register(struct target
*target
, int num
, int force
);
466 static int dsp563xx_reg_read_high_io(struct target
*target
, uint32_t instr_mask
, uint32_t * data
)
470 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
472 /* we use r0 to store temporary data */
473 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
474 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
476 /* move source memory to r0 */
477 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 0, EAME_R0
, instr_mask
);
478 if ((err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, instr
)) != ERROR_OK
)
480 /* move r0 to debug register */
481 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 1, EAME_R0
, 0xfffffc);
482 if ((err
= dsp563xx_once_execute_sw_ir(target
->tap
, 1, instr
)) != ERROR_OK
)
484 /* read debug register */
485 if ((err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OGDBR
, data
)) != ERROR_OK
)
487 /* r0 is no longer valid on target */
488 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= 1;
493 static int dsp563xx_reg_write_high_io(struct target
*target
, uint32_t instr_mask
, uint32_t data
)
497 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
499 /* we use r0 to store temporary data */
500 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
501 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
503 /* move data to r0 */
504 if ((err
= dsp563xx_once_execute_dw_ir(target
->tap
, 0, 0x60F400, data
)) != ERROR_OK
)
506 /* move r0 to destination memory */
507 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 1, EAME_R0
, instr_mask
);
508 if ((err
= dsp563xx_once_execute_sw_ir(target
->tap
, 1, instr
)) != ERROR_OK
)
511 /* r0 is no longer valid on target */
512 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= 1;
517 static int dsp563xx_reg_read(struct target
*target
, uint32_t eame
, uint32_t * data
)
522 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 1, eame
, 0xfffffc);
523 if ((err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, instr
)) != ERROR_OK
)
526 if ((err
= dsp563xx_once_execute_sw_ir(target
->tap
, 1, 0x000000)) != ERROR_OK
)
528 /* read debug register */
529 return dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OGDBR
, data
);
532 static int dsp563xx_reg_write(struct target
*target
, uint32_t instr_mask
, uint32_t data
)
536 if ((err
= dsp563xx_once_execute_dw_ir(target
->tap
, 0, instr_mask
, data
)) != ERROR_OK
)
539 return dsp563xx_once_execute_sw_ir(target
->tap
, 1, 0x000000);
542 static int dsp563xx_reg_pc_read(struct target
*target
)
544 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
546 /* pc was changed, nothing todo */
547 if (dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].dirty
)
550 /* conditional branch check */
551 if ( once_regs
[ONCE_REG_IDX_OPABDR
].reg
== once_regs
[ONCE_REG_IDX_OPABEX
].reg
)
553 if ( (once_regs
[ONCE_REG_IDX_OPABF11
].reg
& 1) == 0 )
555 LOG_DEBUG("%s conditional branch not supported yet", __FUNCTION__
);
557 /* TODO: use disassembly to set correct pc offset */
558 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] = (once_regs
[ONCE_REG_IDX_OPABF11
].reg
>> 1) & 0x00FFFFFF;
562 if ( once_regs
[ONCE_REG_IDX_OPABEX
].reg
== once_regs
[ONCE_REG_IDX_OPABFR
].reg
)
564 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] = once_regs
[ONCE_REG_IDX_OPABEX
].reg
;
568 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] = once_regs
[ONCE_REG_IDX_OPABEX
].reg
- 1;
574 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] = once_regs
[ONCE_REG_IDX_OPABEX
].reg
;
577 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_PC
);
582 static int dsp563xx_reg_ssh_read(struct target
*target
)
586 struct dsp563xx_core_reg
*arch_info
;
587 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
589 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSH
].arch_info
;
591 /* get a valid stack pointer */
592 if ((err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 0)) != ERROR_OK
)
594 sp
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
];
595 if ((err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SP
, 0)) != ERROR_OK
)
598 /* get a valid stack count */
599 if ((err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SC
, 0)) != ERROR_OK
)
601 sc
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SC
];
602 if ((err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SC
, 0)) != ERROR_OK
)
605 /* get a valid extended pointer */
606 if ((err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_EP
, 0)) != ERROR_OK
)
608 ep
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_EP
];
609 if ((err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_EP
, 0)) != ERROR_OK
)
618 if ((err
= dsp563xx_reg_read(target
, arch_info
->eame
, &sp
)) != ERROR_OK
)
621 if ((err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SC
, 1)) != ERROR_OK
)
623 if ((err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SP
, 1)) != ERROR_OK
)
625 if ((err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_EP
, 1)) != ERROR_OK
)
629 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SSH
] = sp
;
630 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_SSH
);
635 static int dsp563xx_reg_ssh_write(struct target
*target
)
639 struct dsp563xx_core_reg
*arch_info
;
640 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
642 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSH
].arch_info
;
644 /* get a valid stack pointer */
645 if ((err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 0)) != ERROR_OK
)
647 sp
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
];
652 /* write new stackpointer */
653 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
] = sp
;
654 if ((err
= dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_SP
)) != ERROR_OK
)
656 if ((err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SP
, 1)) != ERROR_OK
)
659 if ((err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, dsp563xx
->core_regs
[DSP563XX_REG_IDX_SSH
])) != ERROR_OK
)
662 if ((err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 1)) != ERROR_OK
)
664 if ((err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SSH
, 1)) != ERROR_OK
)
671 static int dsp563xx_reg_ssl_read(struct target
*target
)
675 struct dsp563xx_core_reg
*arch_info
;
676 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
678 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSL
].arch_info
;
680 /* get a valid stack pointer */
681 if ((err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 0)) != ERROR_OK
)
683 sp
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
];
691 if ((err
= dsp563xx_reg_read(target
, arch_info
->eame
, &sp
)) != ERROR_OK
)
695 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SSL
] = sp
;
696 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_SSL
);
701 static int dsp563xx_read_register(struct target
*target
, int num
, int force
)
705 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
706 struct dsp563xx_core_reg
*arch_info
;
709 dsp563xx
->core_cache
->reg_list
[num
].valid
= 0;
711 if (!dsp563xx
->core_cache
->reg_list
[num
].valid
)
713 arch_info
= dsp563xx
->core_cache
->reg_list
[num
].arch_info
;
715 switch (arch_info
->num
)
717 case DSP563XX_REG_IDX_SSH
:
718 err
= dsp563xx_reg_ssh_read(target
);
720 case DSP563XX_REG_IDX_SSL
:
721 err
= dsp563xx_reg_ssl_read(target
);
723 case DSP563XX_REG_IDX_PC
:
724 err
= dsp563xx_reg_pc_read(target
);
726 case DSP563XX_REG_IDX_IPRC
:
727 case DSP563XX_REG_IDX_IPRP
:
728 case DSP563XX_REG_IDX_BCR
:
729 case DSP563XX_REG_IDX_DCR
:
730 case DSP563XX_REG_IDX_AAR0
:
731 case DSP563XX_REG_IDX_AAR1
:
732 case DSP563XX_REG_IDX_AAR2
:
733 case DSP563XX_REG_IDX_AAR3
:
734 err
= dsp563xx_reg_read_high_io(target
, arch_info
->instr_mask
, &data
);
737 dsp563xx
->core_regs
[num
] = data
;
738 dsp563xx
->read_core_reg(target
, num
);
742 err
= dsp563xx_reg_read(target
, arch_info
->eame
, &data
);
745 dsp563xx
->core_regs
[num
] = data
;
746 dsp563xx
->read_core_reg(target
, num
);
756 static int dsp563xx_write_register(struct target
*target
, int num
, int force
)
759 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
760 struct dsp563xx_core_reg
*arch_info
;
763 dsp563xx
->core_cache
->reg_list
[num
].dirty
= 1;
765 if (dsp563xx
->core_cache
->reg_list
[num
].dirty
)
767 arch_info
= dsp563xx
->core_cache
->reg_list
[num
].arch_info
;
769 dsp563xx
->write_core_reg(target
, num
);
771 switch (arch_info
->num
)
773 case DSP563XX_REG_IDX_SSH
:
774 err
= dsp563xx_reg_ssh_write(target
);
776 case DSP563XX_REG_IDX_PC
:
777 /* pc is updated on resume, no need to write it here */
779 case DSP563XX_REG_IDX_IPRC
:
780 case DSP563XX_REG_IDX_IPRP
:
781 case DSP563XX_REG_IDX_BCR
:
782 case DSP563XX_REG_IDX_DCR
:
783 case DSP563XX_REG_IDX_AAR0
:
784 case DSP563XX_REG_IDX_AAR1
:
785 case DSP563XX_REG_IDX_AAR2
:
786 case DSP563XX_REG_IDX_AAR3
:
787 err
= dsp563xx_reg_write_high_io(target
, arch_info
->instr_mask
, dsp563xx
->core_regs
[num
]);
790 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, dsp563xx
->core_regs
[num
]);
792 if ((err
== ERROR_OK
) && (arch_info
->num
== DSP563XX_REG_IDX_SP
))
794 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSH
].valid
= 0;
795 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSL
].valid
= 0;
805 static int dsp563xx_save_context(struct target
*target
)
807 int i
, err
= ERROR_OK
;
809 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++)
811 if ((err
= dsp563xx_read_register(target
, i
, 0)) != ERROR_OK
)
818 static int dsp563xx_restore_context(struct target
*target
)
820 int i
, err
= ERROR_OK
;
822 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++)
824 if ((err
= dsp563xx_write_register(target
, i
, 0)) != ERROR_OK
)
831 static void dsp563xx_invalidate_x_context(struct target
*target
, uint32_t addr_start
, uint32_t addr_end
)
834 struct dsp563xx_core_reg
*arch_info
;
835 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
837 if ( addr_start
> ASM_REG_W_IPRC
)
839 if ( addr_start
< ASM_REG_W_AAR3
)
842 for (i
= DSP563XX_REG_IDX_IPRC
; i
< DSP563XX_NUMCOREREGS
; i
++)
844 arch_info
= dsp563xx
->core_cache
->reg_list
[i
].arch_info
;
846 if ( (arch_info
->instr_mask
>= addr_start
) &&
847 (arch_info
->instr_mask
<= addr_end
))
849 dsp563xx
->core_cache
->reg_list
[i
].valid
= 0;
850 dsp563xx
->core_cache
->reg_list
[i
].dirty
= 0;
855 static int dsp563xx_target_create(struct target
*target
, Jim_Interp
* interp
)
857 struct dsp563xx_common
*dsp563xx
= calloc(1, sizeof(struct dsp563xx_common
));
860 return ERROR_INVALID_ARGUMENTS
;
862 dsp563xx
->jtag_info
.tap
= target
->tap
;
863 target
->arch_info
= dsp563xx
;
864 dsp563xx
->read_core_reg
= dsp563xx_read_core_reg
;
865 dsp563xx
->write_core_reg
= dsp563xx_write_core_reg
;
870 static int dsp563xx_init_target(struct command_context
*cmd_ctx
, struct target
*target
)
872 LOG_DEBUG("%s", __FUNCTION__
);
874 dsp563xx_build_reg_cache(target
);
879 static int dsp563xx_examine(struct target
*target
)
883 if (target
->tap
->hasidcode
== false)
885 LOG_ERROR("no IDCODE present on device");
887 return ERROR_INVALID_ARGUMENTS
;
890 if (!target_was_examined(target
))
892 target_set_examined(target
);
894 /* examine core and chip derivate number */
895 chip
= (target
->tap
->idcode
>>12)&0x3ff;
896 /* core number 0 means DSP563XX */
897 if ( ((chip
>>5)&0x1f) == 0 )
900 LOG_INFO("DSP56%03d device found",chip
);
906 static int dsp563xx_arch_state(struct target
*target
)
908 LOG_DEBUG("%s", __FUNCTION__
);
912 #define DSP563XX_SR_SA (1<<17)
913 #define DSP563XX_SR_SC (1<<13)
915 static int dsp563xx_debug_once_init(struct target
*target
)
917 return dsp563xx_once_read_register(target
->tap
, 1, once_regs
, DSP563XX_NUMONCEREGS
);
920 static int dsp563xx_debug_init(struct target
*target
)
924 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
925 struct dsp563xx_core_reg
*arch_info
;
927 if ((err
= dsp563xx_debug_once_init(target
)) != ERROR_OK
)
930 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SR
].arch_info
;
932 /* check 24bit mode */
933 if ((err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SR
, 0)) != ERROR_OK
)
936 sr
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SR
];
938 if (sr
& (DSP563XX_SR_SA
| DSP563XX_SR_SC
))
940 sr
&= ~(DSP563XX_SR_SA
| DSP563XX_SR_SC
);
942 if ((err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, arch_info
->instr_mask
, sr
)) != ERROR_OK
)
944 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SR
].dirty
= 1;
947 if ((err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_N0
, 0)) != ERROR_OK
)
949 if ((err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_N1
, 0)) != ERROR_OK
)
951 if ((err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_M0
, 0)) != ERROR_OK
)
953 if ((err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_M1
, 0)) != ERROR_OK
)
956 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_N0
] != 0x000000)
958 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N0
].arch_info
;
959 if ((err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0x000000)) != ERROR_OK
)
962 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N0
].dirty
= 1;
964 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_N1
] != 0x000000)
966 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N1
].arch_info
;
967 if ((err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0x000000)) != ERROR_OK
)
970 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N1
].dirty
= 1;
972 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_M0
] != 0xffffff)
974 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M0
].arch_info
;
975 if ((err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0xffffff)) != ERROR_OK
)
978 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M0
].dirty
= 1;
980 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_M1
] != 0xffffff)
982 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M1
].arch_info
;
983 if ((err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0xffffff)) != ERROR_OK
)
986 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M1
].dirty
= 1;
988 if ((err
= dsp563xx_save_context(target
)) != ERROR_OK
)
994 static int dsp563xx_jtag_debug_request(struct target
*target
)
996 return dsp563xx_once_request_debug(target
->tap
, target
->state
== TARGET_RESET
);
999 static int dsp563xx_poll(struct target
*target
)
1002 uint32_t once_status
;
1005 state
= dsp563xx_once_target_status(target
->tap
);
1007 if (state
== TARGET_UNKNOWN
)
1009 target
->state
= state
;
1010 LOG_ERROR("jtag status contains invalid mode value - communication failure");
1011 return ERROR_TARGET_FAILURE
;
1014 if ((err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OSCR
, &once_status
)) != ERROR_OK
)
1017 if ((once_status
& DSP563XX_ONCE_OSCR_DEBUG_M
) == DSP563XX_ONCE_OSCR_DEBUG_M
)
1019 if (target
->state
!= TARGET_HALTED
)
1021 target
->state
= TARGET_HALTED
;
1023 if ((err
= dsp563xx_debug_init(target
)) != ERROR_OK
)
1026 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1028 LOG_DEBUG("target->state: %s (%x)", target_state_name(target
),once_status
);
1035 static int dsp563xx_halt(struct target
*target
)
1039 LOG_DEBUG("%s", __FUNCTION__
);
1041 if (target
->state
== TARGET_HALTED
)
1043 LOG_DEBUG("target was already halted");
1047 if (target
->state
== TARGET_UNKNOWN
)
1049 LOG_WARNING("target was in unknown state when halt was requested");
1052 if ((err
= dsp563xx_jtag_debug_request(target
)) != ERROR_OK
)
1055 target
->debug_reason
= DBG_REASON_DBGRQ
;
1060 static int dsp563xx_resume(struct target
*target
, int current
, uint32_t address
, int handle_breakpoints
, int debug_execution
)
1063 struct dsp563xx_core_reg
*dsp563xx_core_reg
;
1064 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1066 /* check if pc was changed and resume want to execute the next address
1067 * if pc was changed from gdb or other interface we will
1068 * jump to this address and don't execute the next address
1069 * this will not affect the resume command with an address argument
1070 * because current is set to zero then
1072 if ( current
&& dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].dirty
)
1074 dsp563xx_write_core_reg(target
,DSP563XX_REG_IDX_PC
);
1075 dsp563xx_core_reg
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].arch_info
;
1076 address
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
];
1080 LOG_DEBUG("%s %08X %08X", __FUNCTION__
, current
, (unsigned) address
);
1082 if ((err
= dsp563xx_restore_context(target
)) != ERROR_OK
)
1084 register_cache_invalidate(dsp563xx
->core_cache
);
1088 /* restore pipeline registers and go */
1089 if ((err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
, once_regs
[ONCE_REG_IDX_OPILR
].reg
)) != ERROR_OK
)
1092 dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
| DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
,
1093 once_regs
[ONCE_REG_IDX_OPDBR
].reg
)) != ERROR_OK
)
1098 /* set to go register and jump */
1099 if ((err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
, INSTR_JUMP
)) != ERROR_OK
)
1101 if ((err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_PDBGOTO
| DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
, address
)) != ERROR_OK
)
1105 target
->state
= TARGET_RUNNING
;
1110 static int dsp563xx_step_ex(struct target
*target
, int current
, uint32_t address
, int handle_breakpoints
, int steps
)
1113 uint32_t once_status
;
1114 uint32_t dr_in
, cnt
;
1115 struct dsp563xx_core_reg
*dsp563xx_core_reg
;
1116 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1118 if (target
->state
!= TARGET_HALTED
)
1120 LOG_DEBUG("target was not halted");
1124 /* check if pc was changed and step want to execute the next address
1125 * if pc was changed from gdb or other interface we will
1126 * jump to this address and don't execute the next address
1127 * this will not affect the step command with an address argument
1128 * because current is set to zero then
1130 if ( current
&& dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].dirty
)
1132 dsp563xx_write_core_reg(target
,DSP563XX_REG_IDX_PC
);
1133 dsp563xx_core_reg
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].arch_info
;
1134 address
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
];
1138 LOG_DEBUG("%s %08X %08X", __FUNCTION__
, current
, (unsigned) address
);
1140 if ((err
= dsp563xx_jtag_debug_request(target
)) != ERROR_OK
)
1142 if ((err
= dsp563xx_restore_context(target
)) != ERROR_OK
)
1145 /* reset trace mode */
1146 if ((err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OSCR
, 0x000000)) != ERROR_OK
)
1148 /* enable trace mode */
1149 if ((err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OSCR
, DSP563XX_ONCE_OSCR_TME
)) != ERROR_OK
)
1154 /* on JUMP we need one extra cycle */
1158 /* load step counter with N-1 */
1159 if ((err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OTC
, cnt
)) != ERROR_OK
)
1164 /* restore pipeline registers and go */
1165 if ((err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
, once_regs
[ONCE_REG_IDX_OPILR
].reg
)) != ERROR_OK
)
1168 dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
| DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
,
1169 once_regs
[ONCE_REG_IDX_OPDBR
].reg
)) != ERROR_OK
)
1174 /* set to go register and jump */
1175 if ((err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
, INSTR_JUMP
)) != ERROR_OK
)
1177 if ((err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_PDBGOTO
| DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
, address
)) != ERROR_OK
)
1183 if ((err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OSCR
, &once_status
)) != ERROR_OK
)
1186 if (once_status
& DSP563XX_ONCE_OSCR_TO
)
1188 if ((err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OPABFR
, &dr_in
)) != ERROR_OK
)
1190 LOG_DEBUG("fetch: %08X", (unsigned) dr_in
&0x00ffffff);
1191 if ((err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OPABDR
, &dr_in
)) != ERROR_OK
)
1193 LOG_DEBUG("decode: %08X", (unsigned) dr_in
&0x00ffffff);
1194 if ((err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OPABEX
, &dr_in
)) != ERROR_OK
)
1196 LOG_DEBUG("execute: %08X", (unsigned) dr_in
&0x00ffffff);
1198 /* reset trace mode */
1199 if ((err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OSCR
, 0x000000)) != ERROR_OK
)
1202 register_cache_invalidate(dsp563xx
->core_cache
);
1203 if ((err
= dsp563xx_debug_init(target
)) != ERROR_OK
)
1213 static int dsp563xx_step(struct target
*target
, int current
, uint32_t address
, int handle_breakpoints
)
1217 if ( (err
=dsp563xx_step_ex(target
, current
, address
, handle_breakpoints
, 0)) != ERROR_OK
)
1222 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1223 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1228 static int dsp563xx_assert_reset(struct target
*target
)
1231 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1232 enum reset_types jtag_reset_config
= jtag_get_reset_config();
1234 if (jtag_reset_config
& RESET_HAS_SRST
)
1236 /* default to asserting srst */
1237 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
1239 jtag_add_reset(1, 1);
1243 jtag_add_reset(0, 1);
1247 target
->state
= TARGET_RESET
;
1248 jtag_add_sleep(5000);
1250 /* registers are now invalid */
1251 register_cache_invalidate(dsp563xx
->core_cache
);
1253 if (target
->reset_halt
)
1255 if ((retval
= target_halt(target
)) != ERROR_OK
)
1259 LOG_DEBUG("%s", __FUNCTION__
);
1263 static int dsp563xx_deassert_reset(struct target
*target
)
1267 /* deassert reset lines */
1268 jtag_add_reset(0, 0);
1270 if ((err
= dsp563xx_poll(target
)) != ERROR_OK
)
1273 if (target
->reset_halt
)
1275 if (target
->state
== TARGET_HALTED
)
1277 /* after a reset the cpu jmp to the
1278 * reset vector and need 2 cycles to fill
1279 * the cache (fetch,decode,excecute)
1281 if ((err
= dsp563xx_step_ex(target
, 1, 0, 1, 1)) != ERROR_OK
)
1286 // target->state = TARGET_RUNNING;
1288 LOG_DEBUG("%s", __FUNCTION__
);
1292 static int dsp563xx_soft_reset_halt(struct target
*target
)
1294 LOG_DEBUG("%s", __FUNCTION__
);
1298 /* global command context from openocd.c */
1299 extern struct command_context
*global_cmd_ctx
;
1301 static int dsp563xx_get_default_memory(void)
1307 if ( !global_cmd_ctx
)
1310 interp
= global_cmd_ctx
->interp
;
1315 memspace
= Jim_GetGlobalVariableStr(interp
,"memspace", JIM_NONE
);
1320 c
= (char*)Jim_GetString(memspace
,NULL
);
1340 static int dsp563xx_read_memory_core(struct target
*target
, int mem_type
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t * buffer
)
1343 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1345 uint32_t data
, move_cmd
= 0;
1348 LOG_DEBUG("memtype: %d address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"", mem_type
,address
, size
, count
);
1350 if (target
->state
!= TARGET_HALTED
)
1352 LOG_WARNING("target not halted");
1353 return ERROR_TARGET_NOT_HALTED
;
1359 /* TODO: mark effected queued registers */
1360 move_cmd
= 0x61d800;
1363 move_cmd
= 0x69d800;
1366 move_cmd
= 0x07d891;
1369 return ERROR_INVALID_ARGUMENTS
;
1372 /* we use r0 to store temporary data */
1373 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
1374 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
1375 /* we use r1 to store temporary data */
1376 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].valid
)
1377 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R1
);
1379 /* r0 is no longer valid on target */
1380 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= 1;
1381 /* r1 is no longer valid on target */
1382 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].dirty
= 1;
1387 if ((err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, 0x60F400, address
)) != ERROR_OK
)
1390 for (i
= 0; i
< x
; i
++)
1392 if ((err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, move_cmd
)) != ERROR_OK
)
1394 if ((err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, 0x08D13C)) != ERROR_OK
)
1396 if ((err
= dsp563xx_once_reg_read(target
->tap
, 0, DSP563XX_ONCE_OGDBR
, (uint32_t*)(void *)b
)) != ERROR_OK
)
1401 /* flush the jtag queue */
1402 if ((err
= jtag_execute_queue()) != ERROR_OK
)
1407 /* walk over the buffer and fix target endianness */
1410 for (i
= 0; i
< x
; i
++)
1412 data
= buf_get_u32(b
, 0, 32) & 0x00FFFFFF;
1413 // LOG_DEBUG("R: %08X", *((uint32_t*)b));
1414 target_buffer_set_u32(target
, b
, data
);
1421 static int dsp563xx_read_memory(struct target
*target
, int mem_type
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t * buffer
)
1425 uint8_t *buffer_y
,*buffer_x
;
1427 /* we only support 4 byte aligned data */
1428 if ( (size
!= 4) || (!count
) )
1430 return ERROR_INVALID_ARGUMENTS
;
1433 if ( mem_type
!= MEM_L
)
1435 return dsp563xx_read_memory_core(target
,mem_type
,address
,size
,count
,buffer
);
1438 if ( !(buffer_y
= malloc(size
*count
)) )
1440 return ERROR_INVALID_ARGUMENTS
;
1443 if ( !(buffer_x
= malloc(size
*count
)) )
1446 return ERROR_INVALID_ARGUMENTS
;
1449 err
= dsp563xx_read_memory_core(target
,MEM_Y
,address
,size
,count
/2,buffer_y
);
1451 if ( err
!= ERROR_OK
)
1458 err
= dsp563xx_read_memory_core(target
,MEM_X
,address
,size
,count
/2,buffer_x
);
1460 if ( err
!= ERROR_OK
)
1467 for(i
=0,i1
=0;i
<count
;i
+=2,i1
++)
1469 buf_set_u32(buffer
+ i
*sizeof(uint32_t), 0, 32, buf_get_u32(buffer_y
+i1
*sizeof(uint32_t), 0, 32));
1470 buf_set_u32(buffer
+ (i
+ 1) *sizeof(uint32_t), 0, 32, buf_get_u32(buffer_x
+i1
*sizeof(uint32_t), 0, 32));
1479 static int dsp563xx_read_memory_default(struct target
*target
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t * buffer
)
1482 return dsp563xx_read_memory(target
, dsp563xx_get_default_memory(), address
, size
, count
, buffer
);
1485 static int dsp563xx_write_memory_core(struct target
*target
, int mem_type
, uint32_t address
, uint32_t size
, uint32_t count
, const uint8_t * buffer
)
1488 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1490 uint32_t data
, move_cmd
= 0;
1493 LOG_DEBUG("memtype: %d address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"", mem_type
,address
, size
, count
);
1495 if (target
->state
!= TARGET_HALTED
)
1497 LOG_WARNING("target not halted");
1498 return ERROR_TARGET_NOT_HALTED
;
1504 /* invalidate affected x registers */
1505 dsp563xx_invalidate_x_context(target
,address
,address
+count
-1);
1506 move_cmd
= 0x615800;
1509 move_cmd
= 0x695800;
1512 move_cmd
= 0x075891;
1515 return ERROR_INVALID_ARGUMENTS
;
1518 /* we use r0 to store temporary data */
1519 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
1520 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
1521 /* we use r1 to store temporary data */
1522 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].valid
)
1523 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R1
);
1525 /* r0 is no longer valid on target */
1526 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= 1;
1527 /* r1 is no longer valid on target */
1528 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].dirty
= 1;
1533 if ((err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, 0x60F400, address
)) != ERROR_OK
)
1536 for (i
= 0; i
< x
; i
++)
1538 data
= target_buffer_get_u32(target
, b
);
1540 // LOG_DEBUG("W: %08X", data);
1544 if ((err
= dsp563xx_once_execute_dw_ir(target
->tap
, 0, 0x61F400, data
)) != ERROR_OK
)
1546 if ((err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, move_cmd
)) != ERROR_OK
)
1551 /* flush the jtag queue */
1552 if ((err
= jtag_execute_queue()) != ERROR_OK
)
1560 static int dsp563xx_write_memory(struct target
*target
, int mem_type
, uint32_t address
, uint32_t size
, uint32_t count
, const uint8_t * buffer
)
1564 uint8_t *buffer_y
,*buffer_x
;
1566 /* we only support 4 byte aligned data */
1567 if ( (size
!= 4) || (!count
) )
1569 return ERROR_INVALID_ARGUMENTS
;
1572 if ( mem_type
!= MEM_L
)
1574 return dsp563xx_write_memory_core(target
,mem_type
,address
,size
,count
,buffer
);
1577 if ( !(buffer_y
= malloc(size
*count
)) )
1579 return ERROR_INVALID_ARGUMENTS
;
1582 if ( !(buffer_x
= malloc(size
*count
)) )
1585 return ERROR_INVALID_ARGUMENTS
;
1588 for(i
=0,i1
=0;i
<count
;i
+=2,i1
++)
1590 buf_set_u32(buffer_y
+ i1
*sizeof(uint32_t), 0, 32, buf_get_u32(buffer
+i
*sizeof(uint32_t), 0, 32));
1591 buf_set_u32(buffer_x
+ i1
*sizeof(uint32_t), 0, 32, buf_get_u32(buffer
+(i
+1)*sizeof(uint32_t), 0, 32));
1594 err
= dsp563xx_write_memory_core(target
,MEM_Y
,address
,size
,count
/2,buffer_y
);
1596 if ( err
!= ERROR_OK
)
1603 err
= dsp563xx_write_memory_core(target
,MEM_X
,address
,size
,count
/2,buffer_x
);
1605 if ( err
!= ERROR_OK
)
1618 static int dsp563xx_write_memory_default(struct target
*target
, uint32_t address
, uint32_t size
, uint32_t count
, const uint8_t * buffer
)
1620 return dsp563xx_write_memory(target
, dsp563xx_get_default_memory(), address
, size
, count
, buffer
);
1623 static int dsp563xx_bulk_write_memory_default(struct target
*target
, uint32_t address
, uint32_t count
, const uint8_t *buffer
)
1625 return dsp563xx_write_memory(target
, dsp563xx_get_default_memory(), address
, 4, count
, buffer
);
1628 static int dsp563xx_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1633 static int dsp563xx_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1638 static int dsp563xx_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1643 static int dsp563xx_remove_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1648 static void handle_md_output(struct command_context
*cmd_ctx
, struct target
*target
, uint32_t address
, unsigned size
, unsigned count
, const uint8_t * buffer
)
1650 const unsigned line_bytecnt
= 32;
1651 unsigned line_modulo
= line_bytecnt
/ size
;
1653 char output
[line_bytecnt
* 4 + 1];
1654 unsigned output_len
= 0;
1656 const char *value_fmt
;
1660 value_fmt
= "%8.8x ";
1663 value_fmt
= "%4.4x ";
1666 value_fmt
= "%2.2x ";
1669 /* "can't happen", caller checked */
1670 LOG_ERROR("invalid memory read size: %u", size
);
1674 for (unsigned i
= 0; i
< count
; i
++)
1676 if (i
% line_modulo
== 0)
1678 output_len
+= snprintf(output
+ output_len
, sizeof(output
) - output_len
, "0x%8.8x: ", (unsigned) (address
+ (i
* size
)));
1682 const uint8_t *value_ptr
= buffer
+ i
* size
;
1686 value
= target_buffer_get_u32(target
, value_ptr
);
1689 value
= target_buffer_get_u16(target
, value_ptr
);
1694 output_len
+= snprintf(output
+ output_len
, sizeof(output
) - output_len
, value_fmt
, value
);
1696 if ((i
% line_modulo
== line_modulo
- 1) || (i
== count
- 1))
1698 command_print(cmd_ctx
, "%s", output
);
1704 COMMAND_HANDLER(dsp563xx_mem_command
)
1706 struct target
*target
= get_current_target(CMD_CTX
);
1709 uint32_t address
= 0;
1710 uint32_t count
= 1, i
;
1711 uint32_t pattern
= 0;
1713 uint8_t *buffer
, *b
;
1715 switch (CMD_NAME
[1])
1724 return ERROR_COMMAND_SYNTAX_ERROR
;
1727 switch (CMD_NAME
[3])
1739 return ERROR_COMMAND_SYNTAX_ERROR
;
1744 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
1751 return ERROR_COMMAND_SYNTAX_ERROR
;
1755 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], pattern
);
1759 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], count
);
1767 return ERROR_COMMAND_SYNTAX_ERROR
;
1771 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], count
);
1775 buffer
= calloc(count
, sizeof(uint32_t));
1779 if ((err
= dsp563xx_read_memory(target
, mem_type
, address
, sizeof(uint32_t), count
, buffer
)) == ERROR_OK
)
1780 handle_md_output(CMD_CTX
, target
, address
, sizeof(uint32_t), count
, buffer
);
1786 for (i
= 0; i
< count
; i
++)
1788 target_buffer_set_u32(target
, b
, pattern
);
1792 err
= dsp563xx_write_memory(target
, mem_type
, address
, sizeof(uint32_t), count
, buffer
);
1800 static const struct command_registration dsp563xx_command_handlers
[] = {
1803 .handler
= dsp563xx_mem_command
,
1804 .mode
= COMMAND_EXEC
,
1805 .help
= "write x memory words",
1806 .usage
= "mwwx address value [count]",
1810 .handler
= dsp563xx_mem_command
,
1811 .mode
= COMMAND_EXEC
,
1812 .help
= "write y memory words",
1813 .usage
= "mwwy address value [count]",
1817 .handler
= dsp563xx_mem_command
,
1818 .mode
= COMMAND_EXEC
,
1819 .help
= "write p memory words",
1820 .usage
= "mwwp address value [count]",
1824 .handler
= dsp563xx_mem_command
,
1825 .mode
= COMMAND_EXEC
,
1826 .help
= "display x memory words",
1827 .usage
= "mdwx address [count]",
1831 .handler
= dsp563xx_mem_command
,
1832 .mode
= COMMAND_EXEC
,
1833 .help
= "display y memory words",
1834 .usage
= "mdwy address [count]",
1838 .handler
= dsp563xx_mem_command
,
1839 .mode
= COMMAND_EXEC
,
1840 .help
= "display p memory words",
1841 .usage
= "mdwp address [count]",
1843 COMMAND_REGISTRATION_DONE
1846 /** Holds methods for DSP563XX targets. */
1847 struct target_type dsp563xx_target
= {
1850 .poll
= dsp563xx_poll
,
1851 .arch_state
= dsp563xx_arch_state
,
1853 .target_request_data
= NULL
,
1855 .get_gdb_reg_list
= dsp563xx_get_gdb_reg_list
,
1857 .halt
= dsp563xx_halt
,
1858 .resume
= dsp563xx_resume
,
1859 .step
= dsp563xx_step
,
1861 .assert_reset
= dsp563xx_assert_reset
,
1862 .deassert_reset
= dsp563xx_deassert_reset
,
1863 .soft_reset_halt
= dsp563xx_soft_reset_halt
,
1865 .read_memory
= dsp563xx_read_memory_default
,
1866 .write_memory
= dsp563xx_write_memory_default
,
1867 .bulk_write_memory
= dsp563xx_bulk_write_memory_default
,
1869 .add_breakpoint
= dsp563xx_add_breakpoint
,
1870 .remove_breakpoint
= dsp563xx_remove_breakpoint
,
1871 .add_watchpoint
= dsp563xx_add_watchpoint
,
1872 .remove_watchpoint
= dsp563xx_remove_watchpoint
,
1874 .commands
= dsp563xx_command_handlers
,
1875 .target_create
= dsp563xx_target_create
,
1876 .init_target
= dsp563xx_init_target
,
1877 .examine
= dsp563xx_examine
,
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)