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_common
*dsp563xx
= target_to_dsp563xx(target
);
354 if ((num
< 0) || (num
>= DSP563XX_NUMCOREREGS
))
355 return ERROR_INVALID_ARGUMENTS
;
357 reg_value
= dsp563xx
->core_regs
[num
];
358 buf_set_u32(dsp563xx
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
359 dsp563xx
->core_cache
->reg_list
[num
].valid
= 1;
360 dsp563xx
->core_cache
->reg_list
[num
].dirty
= 0;
365 static int dsp563xx_write_core_reg(struct target
*target
, int num
)
368 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
370 if ((num
< 0) || (num
>= DSP563XX_NUMCOREREGS
))
371 return ERROR_INVALID_ARGUMENTS
;
373 reg_value
= buf_get_u32(dsp563xx
->core_cache
->reg_list
[num
].value
, 0, 32);
374 dsp563xx
->core_regs
[num
] = reg_value
;
375 dsp563xx
->core_cache
->reg_list
[num
].valid
= 1;
376 dsp563xx
->core_cache
->reg_list
[num
].dirty
= 0;
381 static int dsp563xx_get_core_reg(struct reg
*reg
)
383 struct dsp563xx_core_reg
*dsp563xx_reg
= reg
->arch_info
;
384 struct target
*target
= dsp563xx_reg
->target
;
385 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
387 LOG_DEBUG("%s", __FUNCTION__
);
389 if (target
->state
!= TARGET_HALTED
)
391 return ERROR_TARGET_NOT_HALTED
;
394 return dsp563xx
->read_core_reg(target
, dsp563xx_reg
->num
);
397 static int dsp563xx_set_core_reg(struct reg
*reg
, uint8_t * buf
)
399 LOG_DEBUG("%s", __FUNCTION__
);
401 struct dsp563xx_core_reg
*dsp563xx_reg
= reg
->arch_info
;
402 struct target
*target
= dsp563xx_reg
->target
;
403 uint32_t value
= buf_get_u32(buf
, 0, 32);
405 if (target
->state
!= TARGET_HALTED
)
407 return ERROR_TARGET_NOT_HALTED
;
410 buf_set_u32(reg
->value
, 0, reg
->size
, value
);
417 static const struct reg_arch_type dsp563xx_reg_type
= {
418 .get
= dsp563xx_get_core_reg
,
419 .set
= dsp563xx_set_core_reg
,
422 static void dsp563xx_build_reg_cache(struct target
*target
)
424 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
426 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
427 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
428 struct reg
*reg_list
= malloc(sizeof(struct reg
) * DSP563XX_NUMCOREREGS
);
429 struct dsp563xx_core_reg
*arch_info
= malloc(sizeof(struct dsp563xx_core_reg
) * DSP563XX_NUMCOREREGS
);
432 /* Build the process context cache */
433 cache
->name
= "dsp563xx registers";
435 cache
->reg_list
= reg_list
;
436 cache
->num_regs
= DSP563XX_NUMCOREREGS
;
438 dsp563xx
->core_cache
= cache
;
440 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++)
442 arch_info
[i
].num
= dsp563xx_regs
[i
].id
;
443 arch_info
[i
].name
= dsp563xx_regs
[i
].name
;
444 arch_info
[i
].size
= dsp563xx_regs
[i
].bits
;
445 arch_info
[i
].eame
= dsp563xx_regs
[i
].eame
;
446 arch_info
[i
].instr_mask
= dsp563xx_regs
[i
].instr_mask
;
447 arch_info
[i
].target
= target
;
448 arch_info
[i
].dsp563xx_common
= dsp563xx
;
449 reg_list
[i
].name
= dsp563xx_regs
[i
].name
;
450 reg_list
[i
].size
= 32; //dsp563xx_regs[i].bits;
451 reg_list
[i
].value
= calloc(1, 4);
452 reg_list
[i
].dirty
= 0;
453 reg_list
[i
].valid
= 0;
454 reg_list
[i
].type
= &dsp563xx_reg_type
;
455 reg_list
[i
].arch_info
= &arch_info
[i
];
459 static int dsp563xx_read_register(struct target
*target
, int num
, int force
);
460 static int dsp563xx_write_register(struct target
*target
, int num
, int force
);
462 static int dsp563xx_reg_read_high_io(struct target
*target
, uint32_t instr_mask
, uint32_t * data
)
466 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
468 /* we use r0 to store temporary data */
469 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
470 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
472 /* move source memory to r0 */
473 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 0, EAME_R0
, instr_mask
);
474 if ((err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, instr
)) != ERROR_OK
)
476 /* move r0 to debug register */
477 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 1, EAME_R0
, 0xfffffc);
478 if ((err
= dsp563xx_once_execute_sw_ir(target
->tap
, 1, instr
)) != ERROR_OK
)
480 /* read debug register */
481 if ((err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OGDBR
, data
)) != ERROR_OK
)
483 /* r0 is no longer valid on target */
484 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= 1;
489 static int dsp563xx_reg_write_high_io(struct target
*target
, uint32_t instr_mask
, uint32_t data
)
493 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
495 /* we use r0 to store temporary data */
496 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
497 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
499 /* move data to r0 */
500 if ((err
= dsp563xx_once_execute_dw_ir(target
->tap
, 0, 0x60F400, data
)) != ERROR_OK
)
502 /* move r0 to destination memory */
503 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 1, EAME_R0
, instr_mask
);
504 if ((err
= dsp563xx_once_execute_sw_ir(target
->tap
, 1, instr
)) != ERROR_OK
)
507 /* r0 is no longer valid on target */
508 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= 1;
513 static int dsp563xx_reg_read(struct target
*target
, uint32_t eame
, uint32_t * data
)
518 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 1, eame
, 0xfffffc);
519 if ((err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, instr
)) != ERROR_OK
)
522 if ((err
= dsp563xx_once_execute_sw_ir(target
->tap
, 1, 0x000000)) != ERROR_OK
)
524 /* read debug register */
525 return dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OGDBR
, data
);
528 static int dsp563xx_reg_write(struct target
*target
, uint32_t instr_mask
, uint32_t data
)
532 if ((err
= dsp563xx_once_execute_dw_ir(target
->tap
, 0, instr_mask
, data
)) != ERROR_OK
)
535 return dsp563xx_once_execute_sw_ir(target
->tap
, 1, 0x000000);
538 static int dsp563xx_reg_pc_read(struct target
*target
)
540 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
542 /* pc was changed, nothing todo */
543 if (dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].dirty
)
546 /* conditional branch check */
547 if ( once_regs
[ONCE_REG_IDX_OPABDR
].reg
== once_regs
[ONCE_REG_IDX_OPABEX
].reg
)
549 if ( (once_regs
[ONCE_REG_IDX_OPABF11
].reg
& 1) == 0 )
551 LOG_DEBUG("%s conditional branch not supported yet", __FUNCTION__
);
553 /* TODO: use disassembly to set correct pc offset */
554 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] = (once_regs
[ONCE_REG_IDX_OPABF11
].reg
>> 1) & 0x00FFFFFF;
558 if ( once_regs
[ONCE_REG_IDX_OPABEX
].reg
== once_regs
[ONCE_REG_IDX_OPABFR
].reg
)
560 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] = once_regs
[ONCE_REG_IDX_OPABEX
].reg
;
564 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] = once_regs
[ONCE_REG_IDX_OPABEX
].reg
- 1;
570 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] = once_regs
[ONCE_REG_IDX_OPABEX
].reg
;
573 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_PC
);
578 static int dsp563xx_reg_ssh_read(struct target
*target
)
582 struct dsp563xx_core_reg
*arch_info
;
583 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
585 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSH
].arch_info
;
587 /* get a valid stack pointer */
588 if ((err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 0)) != ERROR_OK
)
590 sp
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
];
591 if ((err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SP
, 0)) != ERROR_OK
)
594 /* get a valid stack count */
595 if ((err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SC
, 0)) != ERROR_OK
)
598 if ((err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SC
, 0)) != ERROR_OK
)
601 /* get a valid extended pointer */
602 if ((err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_EP
, 0)) != ERROR_OK
)
605 if ((err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_EP
, 0)) != ERROR_OK
)
614 if ((err
= dsp563xx_reg_read(target
, arch_info
->eame
, &sp
)) != ERROR_OK
)
617 if ((err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SC
, 1)) != ERROR_OK
)
619 if ((err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SP
, 1)) != ERROR_OK
)
621 if ((err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_EP
, 1)) != ERROR_OK
)
625 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SSH
] = sp
;
626 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_SSH
);
631 static int dsp563xx_reg_ssh_write(struct target
*target
)
635 struct dsp563xx_core_reg
*arch_info
;
636 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
638 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSH
].arch_info
;
640 /* get a valid stack pointer */
641 if ((err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 0)) != ERROR_OK
)
643 sp
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
];
648 /* write new stackpointer */
649 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
] = sp
;
650 if ((err
= dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_SP
)) != ERROR_OK
)
652 if ((err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SP
, 1)) != ERROR_OK
)
655 if ((err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, dsp563xx
->core_regs
[DSP563XX_REG_IDX_SSH
])) != ERROR_OK
)
658 if ((err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 1)) != ERROR_OK
)
660 if ((err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SSH
, 1)) != ERROR_OK
)
667 static int dsp563xx_reg_ssl_read(struct target
*target
)
671 struct dsp563xx_core_reg
*arch_info
;
672 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
674 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSL
].arch_info
;
676 /* get a valid stack pointer */
677 if ((err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 0)) != ERROR_OK
)
679 sp
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
];
687 if ((err
= dsp563xx_reg_read(target
, arch_info
->eame
, &sp
)) != ERROR_OK
)
691 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SSL
] = sp
;
692 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_SSL
);
697 static int dsp563xx_read_register(struct target
*target
, int num
, int force
)
701 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
702 struct dsp563xx_core_reg
*arch_info
;
705 dsp563xx
->core_cache
->reg_list
[num
].valid
= 0;
707 if (!dsp563xx
->core_cache
->reg_list
[num
].valid
)
709 arch_info
= dsp563xx
->core_cache
->reg_list
[num
].arch_info
;
711 switch (arch_info
->num
)
713 case DSP563XX_REG_IDX_SSH
:
714 err
= dsp563xx_reg_ssh_read(target
);
716 case DSP563XX_REG_IDX_SSL
:
717 err
= dsp563xx_reg_ssl_read(target
);
719 case DSP563XX_REG_IDX_PC
:
720 err
= dsp563xx_reg_pc_read(target
);
722 case DSP563XX_REG_IDX_IPRC
:
723 case DSP563XX_REG_IDX_IPRP
:
724 case DSP563XX_REG_IDX_BCR
:
725 case DSP563XX_REG_IDX_DCR
:
726 case DSP563XX_REG_IDX_AAR0
:
727 case DSP563XX_REG_IDX_AAR1
:
728 case DSP563XX_REG_IDX_AAR2
:
729 case DSP563XX_REG_IDX_AAR3
:
730 err
= dsp563xx_reg_read_high_io(target
, arch_info
->instr_mask
, &data
);
733 dsp563xx
->core_regs
[num
] = data
;
734 dsp563xx
->read_core_reg(target
, num
);
738 err
= dsp563xx_reg_read(target
, arch_info
->eame
, &data
);
741 dsp563xx
->core_regs
[num
] = data
;
742 dsp563xx
->read_core_reg(target
, num
);
752 static int dsp563xx_write_register(struct target
*target
, int num
, int force
)
755 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
756 struct dsp563xx_core_reg
*arch_info
;
759 dsp563xx
->core_cache
->reg_list
[num
].dirty
= 1;
761 if (dsp563xx
->core_cache
->reg_list
[num
].dirty
)
763 arch_info
= dsp563xx
->core_cache
->reg_list
[num
].arch_info
;
765 dsp563xx
->write_core_reg(target
, num
);
767 switch (arch_info
->num
)
769 case DSP563XX_REG_IDX_SSH
:
770 err
= dsp563xx_reg_ssh_write(target
);
772 case DSP563XX_REG_IDX_PC
:
773 /* pc is updated on resume, no need to write it here */
775 case DSP563XX_REG_IDX_IPRC
:
776 case DSP563XX_REG_IDX_IPRP
:
777 case DSP563XX_REG_IDX_BCR
:
778 case DSP563XX_REG_IDX_DCR
:
779 case DSP563XX_REG_IDX_AAR0
:
780 case DSP563XX_REG_IDX_AAR1
:
781 case DSP563XX_REG_IDX_AAR2
:
782 case DSP563XX_REG_IDX_AAR3
:
783 err
= dsp563xx_reg_write_high_io(target
, arch_info
->instr_mask
, dsp563xx
->core_regs
[num
]);
786 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, dsp563xx
->core_regs
[num
]);
788 if ((err
== ERROR_OK
) && (arch_info
->num
== DSP563XX_REG_IDX_SP
))
790 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSH
].valid
= 0;
791 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSL
].valid
= 0;
801 static int dsp563xx_save_context(struct target
*target
)
803 int i
, err
= ERROR_OK
;
805 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++)
807 if ((err
= dsp563xx_read_register(target
, i
, 0)) != ERROR_OK
)
814 static int dsp563xx_restore_context(struct target
*target
)
816 int i
, err
= ERROR_OK
;
818 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++)
820 if ((err
= dsp563xx_write_register(target
, i
, 0)) != ERROR_OK
)
827 static void dsp563xx_invalidate_x_context(struct target
*target
, uint32_t addr_start
, uint32_t addr_end
)
830 struct dsp563xx_core_reg
*arch_info
;
831 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
833 if ( addr_start
> ASM_REG_W_IPRC
)
835 if ( addr_start
< ASM_REG_W_AAR3
)
838 for (i
= DSP563XX_REG_IDX_IPRC
; i
< DSP563XX_NUMCOREREGS
; i
++)
840 arch_info
= dsp563xx
->core_cache
->reg_list
[i
].arch_info
;
842 if ( (arch_info
->instr_mask
>= addr_start
) &&
843 (arch_info
->instr_mask
<= addr_end
))
845 dsp563xx
->core_cache
->reg_list
[i
].valid
= 0;
846 dsp563xx
->core_cache
->reg_list
[i
].dirty
= 0;
851 static int dsp563xx_target_create(struct target
*target
, Jim_Interp
* interp
)
853 struct dsp563xx_common
*dsp563xx
= calloc(1, sizeof(struct dsp563xx_common
));
856 return ERROR_INVALID_ARGUMENTS
;
858 dsp563xx
->jtag_info
.tap
= target
->tap
;
859 target
->arch_info
= dsp563xx
;
860 dsp563xx
->read_core_reg
= dsp563xx_read_core_reg
;
861 dsp563xx
->write_core_reg
= dsp563xx_write_core_reg
;
866 static int dsp563xx_init_target(struct command_context
*cmd_ctx
, struct target
*target
)
868 LOG_DEBUG("%s", __FUNCTION__
);
870 dsp563xx_build_reg_cache(target
);
875 static int dsp563xx_examine(struct target
*target
)
879 if (target
->tap
->hasidcode
== false)
881 LOG_ERROR("no IDCODE present on device");
883 return ERROR_INVALID_ARGUMENTS
;
886 if (!target_was_examined(target
))
888 target_set_examined(target
);
890 /* examine core and chip derivate number */
891 chip
= (target
->tap
->idcode
>>12)&0x3ff;
892 /* core number 0 means DSP563XX */
893 if ( ((chip
>>5)&0x1f) == 0 )
896 LOG_INFO("DSP56%03d device found",chip
);
902 static int dsp563xx_arch_state(struct target
*target
)
904 LOG_DEBUG("%s", __FUNCTION__
);
908 #define DSP563XX_SR_SA (1<<17)
909 #define DSP563XX_SR_SC (1<<13)
911 static int dsp563xx_debug_once_init(struct target
*target
)
913 return dsp563xx_once_read_register(target
->tap
, 1, once_regs
, DSP563XX_NUMONCEREGS
);
916 static int dsp563xx_debug_init(struct target
*target
)
920 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
921 struct dsp563xx_core_reg
*arch_info
;
923 if ((err
= dsp563xx_debug_once_init(target
)) != ERROR_OK
)
926 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SR
].arch_info
;
928 /* check 24bit mode */
929 if ((err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SR
, 0)) != ERROR_OK
)
932 sr
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SR
];
934 if (sr
& (DSP563XX_SR_SA
| DSP563XX_SR_SC
))
936 sr
&= ~(DSP563XX_SR_SA
| DSP563XX_SR_SC
);
938 if ((err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, arch_info
->instr_mask
, sr
)) != ERROR_OK
)
940 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SR
].dirty
= 1;
943 if ((err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_N0
, 0)) != ERROR_OK
)
945 if ((err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_N1
, 0)) != ERROR_OK
)
947 if ((err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_M0
, 0)) != ERROR_OK
)
949 if ((err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_M1
, 0)) != ERROR_OK
)
952 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_N0
] != 0x000000)
954 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N0
].arch_info
;
955 if ((err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0x000000)) != ERROR_OK
)
958 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N0
].dirty
= 1;
960 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_N1
] != 0x000000)
962 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N1
].arch_info
;
963 if ((err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0x000000)) != ERROR_OK
)
966 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N1
].dirty
= 1;
968 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_M0
] != 0xffffff)
970 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M0
].arch_info
;
971 if ((err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0xffffff)) != ERROR_OK
)
974 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M0
].dirty
= 1;
976 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_M1
] != 0xffffff)
978 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M1
].arch_info
;
979 if ((err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0xffffff)) != ERROR_OK
)
982 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M1
].dirty
= 1;
984 if ((err
= dsp563xx_save_context(target
)) != ERROR_OK
)
990 static int dsp563xx_jtag_debug_request(struct target
*target
)
992 return dsp563xx_once_request_debug(target
->tap
, target
->state
== TARGET_RESET
);
995 static int dsp563xx_poll(struct target
*target
)
998 uint32_t once_status
;
1001 state
= dsp563xx_once_target_status(target
->tap
);
1003 if (state
== TARGET_UNKNOWN
)
1005 target
->state
= state
;
1006 LOG_ERROR("jtag status contains invalid mode value - communication failure");
1007 return ERROR_TARGET_FAILURE
;
1010 if ((err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OSCR
, &once_status
)) != ERROR_OK
)
1013 if ((once_status
& DSP563XX_ONCE_OSCR_DEBUG_M
) == DSP563XX_ONCE_OSCR_DEBUG_M
)
1015 if (target
->state
!= TARGET_HALTED
)
1017 target
->state
= TARGET_HALTED
;
1019 if ((err
= dsp563xx_debug_init(target
)) != ERROR_OK
)
1022 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1024 LOG_DEBUG("target->state: %s (%x)", target_state_name(target
),once_status
);
1031 static int dsp563xx_halt(struct target
*target
)
1035 LOG_DEBUG("%s", __FUNCTION__
);
1037 if (target
->state
== TARGET_HALTED
)
1039 LOG_DEBUG("target was already halted");
1043 if (target
->state
== TARGET_UNKNOWN
)
1045 LOG_WARNING("target was in unknown state when halt was requested");
1048 if ((err
= dsp563xx_jtag_debug_request(target
)) != ERROR_OK
)
1051 target
->debug_reason
= DBG_REASON_DBGRQ
;
1056 static int dsp563xx_resume(struct target
*target
, int current
, uint32_t address
, int handle_breakpoints
, int debug_execution
)
1059 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1061 /* check if pc was changed and resume want to execute the next address
1062 * if pc was changed from gdb or other interface we will
1063 * jump to this address and don't execute the next address
1064 * this will not affect the resume command with an address argument
1065 * because current is set to zero then
1067 if ( current
&& dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].dirty
)
1069 dsp563xx_write_core_reg(target
,DSP563XX_REG_IDX_PC
);
1070 address
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
];
1074 LOG_DEBUG("%s %08X %08X", __FUNCTION__
, current
, (unsigned) address
);
1076 if ((err
= dsp563xx_restore_context(target
)) != ERROR_OK
)
1078 register_cache_invalidate(dsp563xx
->core_cache
);
1082 /* restore pipeline registers and go */
1083 if ((err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
, once_regs
[ONCE_REG_IDX_OPILR
].reg
)) != ERROR_OK
)
1086 dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
| DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
,
1087 once_regs
[ONCE_REG_IDX_OPDBR
].reg
)) != ERROR_OK
)
1092 /* set to go register and jump */
1093 if ((err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
, INSTR_JUMP
)) != ERROR_OK
)
1095 if ((err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_PDBGOTO
| DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
, address
)) != ERROR_OK
)
1099 target
->state
= TARGET_RUNNING
;
1104 static int dsp563xx_step_ex(struct target
*target
, int current
, uint32_t address
, int handle_breakpoints
, int steps
)
1107 uint32_t once_status
;
1108 uint32_t dr_in
, cnt
;
1109 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1111 if (target
->state
!= TARGET_HALTED
)
1113 LOG_DEBUG("target was not halted");
1117 /* check if pc was changed and step want to execute the next address
1118 * if pc was changed from gdb or other interface we will
1119 * jump to this address and don't execute the next address
1120 * this will not affect the step command with an address argument
1121 * because current is set to zero then
1123 if ( current
&& dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].dirty
)
1125 dsp563xx_write_core_reg(target
,DSP563XX_REG_IDX_PC
);
1126 address
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
];
1130 LOG_DEBUG("%s %08X %08X", __FUNCTION__
, current
, (unsigned) address
);
1132 if ((err
= dsp563xx_jtag_debug_request(target
)) != ERROR_OK
)
1134 if ((err
= dsp563xx_restore_context(target
)) != ERROR_OK
)
1137 /* reset trace mode */
1138 if ((err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OSCR
, 0x000000)) != ERROR_OK
)
1140 /* enable trace mode */
1141 if ((err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OSCR
, DSP563XX_ONCE_OSCR_TME
)) != ERROR_OK
)
1146 /* on JUMP we need one extra cycle */
1150 /* load step counter with N-1 */
1151 if ((err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OTC
, cnt
)) != ERROR_OK
)
1156 /* restore pipeline registers and go */
1157 if ((err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
, once_regs
[ONCE_REG_IDX_OPILR
].reg
)) != ERROR_OK
)
1160 dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
| DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
,
1161 once_regs
[ONCE_REG_IDX_OPDBR
].reg
)) != ERROR_OK
)
1166 /* set to go register and jump */
1167 if ((err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
, INSTR_JUMP
)) != ERROR_OK
)
1169 if ((err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_PDBGOTO
| DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
, address
)) != ERROR_OK
)
1175 if ((err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OSCR
, &once_status
)) != ERROR_OK
)
1178 if (once_status
& DSP563XX_ONCE_OSCR_TO
)
1180 if ((err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OPABFR
, &dr_in
)) != ERROR_OK
)
1182 LOG_DEBUG("fetch: %08X", (unsigned) dr_in
&0x00ffffff);
1183 if ((err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OPABDR
, &dr_in
)) != ERROR_OK
)
1185 LOG_DEBUG("decode: %08X", (unsigned) dr_in
&0x00ffffff);
1186 if ((err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OPABEX
, &dr_in
)) != ERROR_OK
)
1188 LOG_DEBUG("execute: %08X", (unsigned) dr_in
&0x00ffffff);
1190 /* reset trace mode */
1191 if ((err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OSCR
, 0x000000)) != ERROR_OK
)
1194 register_cache_invalidate(dsp563xx
->core_cache
);
1195 if ((err
= dsp563xx_debug_init(target
)) != ERROR_OK
)
1205 static int dsp563xx_step(struct target
*target
, int current
, uint32_t address
, int handle_breakpoints
)
1209 if ( (err
=dsp563xx_step_ex(target
, current
, address
, handle_breakpoints
, 0)) != ERROR_OK
)
1214 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1215 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1220 static int dsp563xx_assert_reset(struct target
*target
)
1223 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1224 enum reset_types jtag_reset_config
= jtag_get_reset_config();
1226 if (jtag_reset_config
& RESET_HAS_SRST
)
1228 /* default to asserting srst */
1229 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
1231 jtag_add_reset(1, 1);
1235 jtag_add_reset(0, 1);
1239 target
->state
= TARGET_RESET
;
1240 jtag_add_sleep(5000);
1242 /* registers are now invalid */
1243 register_cache_invalidate(dsp563xx
->core_cache
);
1245 if (target
->reset_halt
)
1247 if ((retval
= target_halt(target
)) != ERROR_OK
)
1251 LOG_DEBUG("%s", __FUNCTION__
);
1255 static int dsp563xx_deassert_reset(struct target
*target
)
1259 /* deassert reset lines */
1260 jtag_add_reset(0, 0);
1262 if ((err
= dsp563xx_poll(target
)) != ERROR_OK
)
1265 if (target
->reset_halt
)
1267 if (target
->state
== TARGET_HALTED
)
1269 /* after a reset the cpu jmp to the
1270 * reset vector and need 2 cycles to fill
1271 * the cache (fetch,decode,excecute)
1273 if ((err
= dsp563xx_step_ex(target
, 1, 0, 1, 1)) != ERROR_OK
)
1278 // target->state = TARGET_RUNNING;
1280 LOG_DEBUG("%s", __FUNCTION__
);
1284 static int dsp563xx_soft_reset_halt(struct target
*target
)
1286 LOG_DEBUG("%s", __FUNCTION__
);
1290 /* global command context from openocd.c */
1291 extern struct command_context
*global_cmd_ctx
;
1293 static int dsp563xx_get_default_memory(void)
1299 if ( !global_cmd_ctx
)
1302 interp
= global_cmd_ctx
->interp
;
1307 memspace
= Jim_GetGlobalVariableStr(interp
,"memspace", JIM_NONE
);
1312 c
= (char*)Jim_GetString(memspace
,NULL
);
1332 static int dsp563xx_read_memory_core(struct target
*target
, int mem_type
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t * buffer
)
1335 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1337 uint32_t data
, move_cmd
= 0;
1340 LOG_DEBUG("memtype: %d address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"", mem_type
,address
, size
, count
);
1342 if (target
->state
!= TARGET_HALTED
)
1344 LOG_WARNING("target not halted");
1345 return ERROR_TARGET_NOT_HALTED
;
1351 /* TODO: mark effected queued registers */
1352 move_cmd
= 0x61d800;
1355 move_cmd
= 0x69d800;
1358 move_cmd
= 0x07d891;
1361 return ERROR_INVALID_ARGUMENTS
;
1364 /* we use r0 to store temporary data */
1365 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
1366 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
1367 /* we use r1 to store temporary data */
1368 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].valid
)
1369 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R1
);
1371 /* r0 is no longer valid on target */
1372 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= 1;
1373 /* r1 is no longer valid on target */
1374 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].dirty
= 1;
1379 if ((err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, 0x60F400, address
)) != ERROR_OK
)
1382 for (i
= 0; i
< x
; i
++)
1384 if ((err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, move_cmd
)) != ERROR_OK
)
1386 if ((err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, 0x08D13C)) != ERROR_OK
)
1388 if ((err
= dsp563xx_once_reg_read(target
->tap
, 0, DSP563XX_ONCE_OGDBR
, (uint32_t*)(void *)b
)) != ERROR_OK
)
1393 /* flush the jtag queue */
1394 if ((err
= jtag_execute_queue()) != ERROR_OK
)
1399 /* walk over the buffer and fix target endianness */
1402 for (i
= 0; i
< x
; i
++)
1404 data
= buf_get_u32(b
, 0, 32) & 0x00FFFFFF;
1405 // LOG_DEBUG("R: %08X", *((uint32_t*)b));
1406 target_buffer_set_u32(target
, b
, data
);
1413 static int dsp563xx_read_memory(struct target
*target
, int mem_type
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t * buffer
)
1417 uint8_t *buffer_y
,*buffer_x
;
1419 /* we only support 4 byte aligned data */
1420 if ( (size
!= 4) || (!count
) )
1422 return ERROR_INVALID_ARGUMENTS
;
1425 if ( mem_type
!= MEM_L
)
1427 return dsp563xx_read_memory_core(target
,mem_type
,address
,size
,count
,buffer
);
1430 if ( !(buffer_y
= malloc(size
*count
)) )
1432 return ERROR_INVALID_ARGUMENTS
;
1435 if ( !(buffer_x
= malloc(size
*count
)) )
1438 return ERROR_INVALID_ARGUMENTS
;
1441 err
= dsp563xx_read_memory_core(target
,MEM_Y
,address
,size
,count
/2,buffer_y
);
1443 if ( err
!= ERROR_OK
)
1450 err
= dsp563xx_read_memory_core(target
,MEM_X
,address
,size
,count
/2,buffer_x
);
1452 if ( err
!= ERROR_OK
)
1459 for(i
=0,i1
=0;i
<count
;i
+=2,i1
++)
1461 buf_set_u32(buffer
+ i
*sizeof(uint32_t), 0, 32, buf_get_u32(buffer_y
+i1
*sizeof(uint32_t), 0, 32));
1462 buf_set_u32(buffer
+ (i
+ 1) *sizeof(uint32_t), 0, 32, buf_get_u32(buffer_x
+i1
*sizeof(uint32_t), 0, 32));
1471 static int dsp563xx_read_memory_default(struct target
*target
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t * buffer
)
1474 return dsp563xx_read_memory(target
, dsp563xx_get_default_memory(), address
, size
, count
, buffer
);
1477 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
)
1480 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1482 uint32_t data
, move_cmd
= 0;
1485 LOG_DEBUG("memtype: %d address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"", mem_type
,address
, size
, count
);
1487 if (target
->state
!= TARGET_HALTED
)
1489 LOG_WARNING("target not halted");
1490 return ERROR_TARGET_NOT_HALTED
;
1496 /* invalidate affected x registers */
1497 dsp563xx_invalidate_x_context(target
,address
,address
+count
-1);
1498 move_cmd
= 0x615800;
1501 move_cmd
= 0x695800;
1504 move_cmd
= 0x075891;
1507 return ERROR_INVALID_ARGUMENTS
;
1510 /* we use r0 to store temporary data */
1511 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
1512 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
1513 /* we use r1 to store temporary data */
1514 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].valid
)
1515 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R1
);
1517 /* r0 is no longer valid on target */
1518 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= 1;
1519 /* r1 is no longer valid on target */
1520 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].dirty
= 1;
1525 if ((err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, 0x60F400, address
)) != ERROR_OK
)
1528 for (i
= 0; i
< x
; i
++)
1530 data
= target_buffer_get_u32(target
, b
);
1532 // LOG_DEBUG("W: %08X", data);
1536 if ((err
= dsp563xx_once_execute_dw_ir(target
->tap
, 0, 0x61F400, data
)) != ERROR_OK
)
1538 if ((err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, move_cmd
)) != ERROR_OK
)
1543 /* flush the jtag queue */
1544 if ((err
= jtag_execute_queue()) != ERROR_OK
)
1552 static int dsp563xx_write_memory(struct target
*target
, int mem_type
, uint32_t address
, uint32_t size
, uint32_t count
, const uint8_t * buffer
)
1556 uint8_t *buffer_y
,*buffer_x
;
1558 /* we only support 4 byte aligned data */
1559 if ( (size
!= 4) || (!count
) )
1561 return ERROR_INVALID_ARGUMENTS
;
1564 if ( mem_type
!= MEM_L
)
1566 return dsp563xx_write_memory_core(target
,mem_type
,address
,size
,count
,buffer
);
1569 if ( !(buffer_y
= malloc(size
*count
)) )
1571 return ERROR_INVALID_ARGUMENTS
;
1574 if ( !(buffer_x
= malloc(size
*count
)) )
1577 return ERROR_INVALID_ARGUMENTS
;
1580 for(i
=0,i1
=0;i
<count
;i
+=2,i1
++)
1582 buf_set_u32(buffer_y
+ i1
*sizeof(uint32_t), 0, 32, buf_get_u32(buffer
+i
*sizeof(uint32_t), 0, 32));
1583 buf_set_u32(buffer_x
+ i1
*sizeof(uint32_t), 0, 32, buf_get_u32(buffer
+(i
+1)*sizeof(uint32_t), 0, 32));
1586 err
= dsp563xx_write_memory_core(target
,MEM_Y
,address
,size
,count
/2,buffer_y
);
1588 if ( err
!= ERROR_OK
)
1595 err
= dsp563xx_write_memory_core(target
,MEM_X
,address
,size
,count
/2,buffer_x
);
1597 if ( err
!= ERROR_OK
)
1610 static int dsp563xx_write_memory_default(struct target
*target
, uint32_t address
, uint32_t size
, uint32_t count
, const uint8_t * buffer
)
1612 return dsp563xx_write_memory(target
, dsp563xx_get_default_memory(), address
, size
, count
, buffer
);
1615 static int dsp563xx_bulk_write_memory_default(struct target
*target
, uint32_t address
, uint32_t count
, const uint8_t *buffer
)
1617 return dsp563xx_write_memory(target
, dsp563xx_get_default_memory(), address
, 4, count
, buffer
);
1620 static int dsp563xx_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1625 static int dsp563xx_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1630 static int dsp563xx_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1635 static int dsp563xx_remove_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1640 static void handle_md_output(struct command_context
*cmd_ctx
, struct target
*target
, uint32_t address
, unsigned size
, unsigned count
, const uint8_t * buffer
)
1642 const unsigned line_bytecnt
= 32;
1643 unsigned line_modulo
= line_bytecnt
/ size
;
1645 char output
[line_bytecnt
* 4 + 1];
1646 unsigned output_len
= 0;
1648 const char *value_fmt
;
1652 value_fmt
= "%8.8x ";
1655 value_fmt
= "%4.4x ";
1658 value_fmt
= "%2.2x ";
1661 /* "can't happen", caller checked */
1662 LOG_ERROR("invalid memory read size: %u", size
);
1666 for (unsigned i
= 0; i
< count
; i
++)
1668 if (i
% line_modulo
== 0)
1670 output_len
+= snprintf(output
+ output_len
, sizeof(output
) - output_len
, "0x%8.8x: ", (unsigned) (address
+ (i
* size
)));
1674 const uint8_t *value_ptr
= buffer
+ i
* size
;
1678 value
= target_buffer_get_u32(target
, value_ptr
);
1681 value
= target_buffer_get_u16(target
, value_ptr
);
1686 output_len
+= snprintf(output
+ output_len
, sizeof(output
) - output_len
, value_fmt
, value
);
1688 if ((i
% line_modulo
== line_modulo
- 1) || (i
== count
- 1))
1690 command_print(cmd_ctx
, "%s", output
);
1696 COMMAND_HANDLER(dsp563xx_mem_command
)
1698 struct target
*target
= get_current_target(CMD_CTX
);
1701 uint32_t address
= 0;
1702 uint32_t count
= 1, i
;
1703 uint32_t pattern
= 0;
1705 uint8_t *buffer
, *b
;
1707 switch (CMD_NAME
[1])
1716 return ERROR_COMMAND_SYNTAX_ERROR
;
1719 switch (CMD_NAME
[3])
1731 return ERROR_COMMAND_SYNTAX_ERROR
;
1736 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
1743 return ERROR_COMMAND_SYNTAX_ERROR
;
1747 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], pattern
);
1751 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], count
);
1759 return ERROR_COMMAND_SYNTAX_ERROR
;
1763 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], count
);
1767 buffer
= calloc(count
, sizeof(uint32_t));
1771 if ((err
= dsp563xx_read_memory(target
, mem_type
, address
, sizeof(uint32_t), count
, buffer
)) == ERROR_OK
)
1772 handle_md_output(CMD_CTX
, target
, address
, sizeof(uint32_t), count
, buffer
);
1778 for (i
= 0; i
< count
; i
++)
1780 target_buffer_set_u32(target
, b
, pattern
);
1784 err
= dsp563xx_write_memory(target
, mem_type
, address
, sizeof(uint32_t), count
, buffer
);
1792 static const struct command_registration dsp563xx_command_handlers
[] = {
1795 .handler
= dsp563xx_mem_command
,
1796 .mode
= COMMAND_EXEC
,
1797 .help
= "write x memory words",
1798 .usage
= "mwwx address value [count]",
1802 .handler
= dsp563xx_mem_command
,
1803 .mode
= COMMAND_EXEC
,
1804 .help
= "write y memory words",
1805 .usage
= "mwwy address value [count]",
1809 .handler
= dsp563xx_mem_command
,
1810 .mode
= COMMAND_EXEC
,
1811 .help
= "write p memory words",
1812 .usage
= "mwwp address value [count]",
1816 .handler
= dsp563xx_mem_command
,
1817 .mode
= COMMAND_EXEC
,
1818 .help
= "display x memory words",
1819 .usage
= "mdwx address [count]",
1823 .handler
= dsp563xx_mem_command
,
1824 .mode
= COMMAND_EXEC
,
1825 .help
= "display y memory words",
1826 .usage
= "mdwy address [count]",
1830 .handler
= dsp563xx_mem_command
,
1831 .mode
= COMMAND_EXEC
,
1832 .help
= "display p memory words",
1833 .usage
= "mdwp address [count]",
1835 COMMAND_REGISTRATION_DONE
1838 /** Holds methods for DSP563XX targets. */
1839 struct target_type dsp563xx_target
= {
1842 .poll
= dsp563xx_poll
,
1843 .arch_state
= dsp563xx_arch_state
,
1845 .target_request_data
= NULL
,
1847 .get_gdb_reg_list
= dsp563xx_get_gdb_reg_list
,
1849 .halt
= dsp563xx_halt
,
1850 .resume
= dsp563xx_resume
,
1851 .step
= dsp563xx_step
,
1853 .assert_reset
= dsp563xx_assert_reset
,
1854 .deassert_reset
= dsp563xx_deassert_reset
,
1855 .soft_reset_halt
= dsp563xx_soft_reset_halt
,
1857 .read_memory
= dsp563xx_read_memory_default
,
1858 .write_memory
= dsp563xx_write_memory_default
,
1859 .bulk_write_memory
= dsp563xx_bulk_write_memory_default
,
1861 .add_breakpoint
= dsp563xx_add_breakpoint
,
1862 .remove_breakpoint
= dsp563xx_remove_breakpoint
,
1863 .add_watchpoint
= dsp563xx_add_watchpoint
,
1864 .remove_watchpoint
= dsp563xx_remove_watchpoint
,
1866 .commands
= dsp563xx_command_handlers
,
1867 .target_create
= dsp563xx_target_create
,
1868 .init_target
= dsp563xx_init_target
,
1869 .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)