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 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
19 ***************************************************************************/
28 #include "breakpoints.h"
29 #include "target_type.h"
30 #include "algorithm.h"
33 #include "dsp563xx_once.h"
35 #define ASM_REG_W_R0 0x60F400
36 #define ASM_REG_W_R1 0x61F400
37 #define ASM_REG_W_R2 0x62F400
38 #define ASM_REG_W_R3 0x63F400
39 #define ASM_REG_W_R4 0x64F400
40 #define ASM_REG_W_R5 0x65F400
41 #define ASM_REG_W_R6 0x66F400
42 #define ASM_REG_W_R7 0x67F400
44 #define ASM_REG_W_N0 0x70F400
45 #define ASM_REG_W_N1 0x71F400
46 #define ASM_REG_W_N2 0x72F400
47 #define ASM_REG_W_N3 0x73F400
48 #define ASM_REG_W_N4 0x74F400
49 #define ASM_REG_W_N5 0x75F400
50 #define ASM_REG_W_N6 0x76F400
51 #define ASM_REG_W_N7 0x77F400
53 #define ASM_REG_W_M0 0x05F420
54 #define ASM_REG_W_M1 0x05F421
55 #define ASM_REG_W_M2 0x05F422
56 #define ASM_REG_W_M3 0x05F423
57 #define ASM_REG_W_M4 0x05F424
58 #define ASM_REG_W_M5 0x05F425
59 #define ASM_REG_W_M6 0x05F426
60 #define ASM_REG_W_M7 0x05F427
62 #define ASM_REG_W_X0 0x44F400
63 #define ASM_REG_W_X1 0x45F400
65 #define ASM_REG_W_Y0 0x46F400
66 #define ASM_REG_W_Y1 0x47F400
68 #define ASM_REG_W_A0 0x50F400
69 #define ASM_REG_W_A1 0x54F400
70 #define ASM_REG_W_A2 0x52F400
72 #define ASM_REG_W_B0 0x51F400
73 #define ASM_REG_W_B1 0x55F400
74 #define ASM_REG_W_B2 0x53F400
76 #define ASM_REG_W_VBA 0x05F430
77 #define ASM_REG_W_OMR 0x05F43A
78 #define ASM_REG_W_EP 0x05F42A
79 #define ASM_REG_W_SC 0x05F431
80 #define ASM_REG_W_SZ 0x05F438
81 #define ASM_REG_W_SR 0x05F439
82 #define ASM_REG_W_SP 0x05F43B
83 #define ASM_REG_W_SSH 0x05F43C
84 #define ASM_REG_W_SSL 0x05F43D
85 #define ASM_REG_W_LA 0x05F43E
86 #define ASM_REG_W_LC 0x05F43F
87 #define ASM_REG_W_PC 0x000000
88 #define ASM_REG_W_IPRC 0xFFFFFF
89 #define ASM_REG_W_IPRP 0xFFFFFE
91 #define ASM_REG_W_BCR 0xFFFFFB
92 #define ASM_REG_W_DCR 0xFFFFFA
93 #define ASM_REG_W_AAR0 0xFFFFF9
94 #define ASM_REG_W_AAR1 0xFFFFF8
95 #define ASM_REG_W_AAR2 0xFFFFF7
96 #define ASM_REG_W_AAR3 0xFFFFF6
99 * OBCR Register bit definitions
101 #define OBCR_b0_and_b1 ((0x0) << 10)
102 #define OBCR_b0_or_b1 ((0x1) << 10)
103 #define OBCR_b1_after_b0 ((0x2) << 10)
104 #define OBCR_b0_after_b1 ((0x3) << 10)
106 #define OBCR_BP_DISABLED (0x0)
107 #define OBCR_BP_MEM_P (0x1)
108 #define OBCR_BP_MEM_X (0x2)
109 #define OBCR_BP_MEM_Y (0x3)
110 #define OBCR_BP_ON_READ ((0x2) << 0)
111 #define OBCR_BP_ON_WRITE ((0x1) << 0)
112 #define OBCR_BP_CC_NOT_EQUAL ((0x0) << 2)
113 #define OBCR_BP_CC_EQUAL ((0x1) << 2)
114 #define OBCR_BP_CC_LESS_THAN ((0x2) << 2)
115 #define OBCR_BP_CC_GREATER_THAN ((0x3) << 2)
117 #define OBCR_BP_0(x) ((x)<<2)
118 #define OBCR_BP_1(x) ((x)<<6)
122 ONCE_REG_IDX_OSCR
= 0,
123 ONCE_REG_IDX_OMBC
= 1,
124 ONCE_REG_IDX_OBCR
= 2,
125 ONCE_REG_IDX_OMLR0
= 3,
126 ONCE_REG_IDX_OMLR1
= 4,
127 ONCE_REG_IDX_OGDBR
= 5,
128 ONCE_REG_IDX_OPDBR
= 6,
129 ONCE_REG_IDX_OPILR
= 7,
130 ONCE_REG_IDX_PDB
= 8,
131 ONCE_REG_IDX_OTC
= 9,
132 ONCE_REG_IDX_OPABFR
= 10,
133 ONCE_REG_IDX_OPABDR
= 11,
134 ONCE_REG_IDX_OPABEX
= 12,
135 ONCE_REG_IDX_OPABF0
= 13,
136 ONCE_REG_IDX_OPABF1
= 14,
137 ONCE_REG_IDX_OPABF2
= 15,
138 ONCE_REG_IDX_OPABF3
= 16,
139 ONCE_REG_IDX_OPABF4
= 17,
140 ONCE_REG_IDX_OPABF5
= 18,
141 ONCE_REG_IDX_OPABF6
= 19,
142 ONCE_REG_IDX_OPABF7
= 20,
143 ONCE_REG_IDX_OPABF8
= 21,
144 ONCE_REG_IDX_OPABF9
= 22,
145 ONCE_REG_IDX_OPABF10
= 23,
146 ONCE_REG_IDX_OPABF11
= 24,
149 static struct once_reg once_regs
[] = {
150 {ONCE_REG_IDX_OSCR
, DSP563XX_ONCE_OSCR
, 24, "OSCR", 0},
151 {ONCE_REG_IDX_OMBC
, DSP563XX_ONCE_OMBC
, 24, "OMBC", 0},
152 {ONCE_REG_IDX_OBCR
, DSP563XX_ONCE_OBCR
, 24, "OBCR", 0},
153 {ONCE_REG_IDX_OMLR0
, DSP563XX_ONCE_OMLR0
, 24, "OMLR0", 0},
154 {ONCE_REG_IDX_OMLR1
, DSP563XX_ONCE_OMLR1
, 24, "OMLR1", 0},
155 {ONCE_REG_IDX_OGDBR
, DSP563XX_ONCE_OGDBR
, 24, "OGDBR", 0},
156 {ONCE_REG_IDX_OPDBR
, DSP563XX_ONCE_OPDBR
, 24, "OPDBR", 0},
157 {ONCE_REG_IDX_OPILR
, DSP563XX_ONCE_OPILR
, 24, "OPILR", 0},
158 {ONCE_REG_IDX_PDB
, DSP563XX_ONCE_PDBGOTO
, 24, "PDB", 0},
159 {ONCE_REG_IDX_OTC
, DSP563XX_ONCE_OTC
, 24, "OTC", 0},
160 {ONCE_REG_IDX_OPABFR
, DSP563XX_ONCE_OPABFR
, 24, "OPABFR", 0},
161 {ONCE_REG_IDX_OPABDR
, DSP563XX_ONCE_OPABDR
, 24, "OPABDR", 0},
162 {ONCE_REG_IDX_OPABEX
, DSP563XX_ONCE_OPABEX
, 24, "OPABEX", 0},
163 {ONCE_REG_IDX_OPABF0
, DSP563XX_ONCE_OPABF11
, 25, "OPABF0", 0},
164 {ONCE_REG_IDX_OPABF1
, DSP563XX_ONCE_OPABF11
, 25, "OPABF1", 0},
165 {ONCE_REG_IDX_OPABF2
, DSP563XX_ONCE_OPABF11
, 25, "OPABF2", 0},
166 {ONCE_REG_IDX_OPABF3
, DSP563XX_ONCE_OPABF11
, 25, "OPABF3", 0},
167 {ONCE_REG_IDX_OPABF4
, DSP563XX_ONCE_OPABF11
, 25, "OPABF4", 0},
168 {ONCE_REG_IDX_OPABF5
, DSP563XX_ONCE_OPABF11
, 25, "OPABF5", 0},
169 {ONCE_REG_IDX_OPABF6
, DSP563XX_ONCE_OPABF11
, 25, "OPABF6", 0},
170 {ONCE_REG_IDX_OPABF7
, DSP563XX_ONCE_OPABF11
, 25, "OPABF7", 0},
171 {ONCE_REG_IDX_OPABF8
, DSP563XX_ONCE_OPABF11
, 25, "OPABF8", 0},
172 {ONCE_REG_IDX_OPABF9
, DSP563XX_ONCE_OPABF11
, 25, "OPABF9", 0},
173 {ONCE_REG_IDX_OPABF10
, DSP563XX_ONCE_OPABF11
, 25, "OPABF10", 0},
174 {ONCE_REG_IDX_OPABF11
, DSP563XX_ONCE_OPABF11
, 25, "OPABF11", 0},
175 /* {25,0x1f,24,"NRSEL",0}, */
178 enum dsp563xx_reg_idx
{
179 DSP563XX_REG_IDX_R0
= 0,
180 DSP563XX_REG_IDX_R1
= 1,
181 DSP563XX_REG_IDX_R2
= 2,
182 DSP563XX_REG_IDX_R3
= 3,
183 DSP563XX_REG_IDX_R4
= 4,
184 DSP563XX_REG_IDX_R5
= 5,
185 DSP563XX_REG_IDX_R6
= 6,
186 DSP563XX_REG_IDX_R7
= 7,
187 DSP563XX_REG_IDX_N0
= 8,
188 DSP563XX_REG_IDX_N1
= 9,
189 DSP563XX_REG_IDX_N2
= 10,
190 DSP563XX_REG_IDX_N3
= 11,
191 DSP563XX_REG_IDX_N4
= 12,
192 DSP563XX_REG_IDX_N5
= 13,
193 DSP563XX_REG_IDX_N6
= 14,
194 DSP563XX_REG_IDX_N7
= 15,
195 DSP563XX_REG_IDX_M0
= 16,
196 DSP563XX_REG_IDX_M1
= 17,
197 DSP563XX_REG_IDX_M2
= 18,
198 DSP563XX_REG_IDX_M3
= 19,
199 DSP563XX_REG_IDX_M4
= 20,
200 DSP563XX_REG_IDX_M5
= 21,
201 DSP563XX_REG_IDX_M6
= 22,
202 DSP563XX_REG_IDX_M7
= 23,
203 DSP563XX_REG_IDX_X0
= 24,
204 DSP563XX_REG_IDX_X1
= 25,
205 DSP563XX_REG_IDX_Y0
= 26,
206 DSP563XX_REG_IDX_Y1
= 27,
207 DSP563XX_REG_IDX_A0
= 28,
208 DSP563XX_REG_IDX_A1
= 29,
209 DSP563XX_REG_IDX_A2
= 30,
210 DSP563XX_REG_IDX_B0
= 31,
211 DSP563XX_REG_IDX_B1
= 32,
212 DSP563XX_REG_IDX_B2
= 33,
213 DSP563XX_REG_IDX_SSH
= 34,
214 DSP563XX_REG_IDX_SSL
= 35,
215 DSP563XX_REG_IDX_SP
= 36,
216 DSP563XX_REG_IDX_EP
= 37,
217 DSP563XX_REG_IDX_SZ
= 38,
218 DSP563XX_REG_IDX_SC
= 39,
219 DSP563XX_REG_IDX_PC
= 40,
220 DSP563XX_REG_IDX_SR
= 41,
221 DSP563XX_REG_IDX_OMR
= 42,
222 DSP563XX_REG_IDX_LA
= 43,
223 DSP563XX_REG_IDX_LC
= 44,
224 DSP563XX_REG_IDX_VBA
= 45,
225 DSP563XX_REG_IDX_IPRC
= 46,
226 DSP563XX_REG_IDX_IPRP
= 47,
227 DSP563XX_REG_IDX_BCR
= 48,
228 DSP563XX_REG_IDX_DCR
= 49,
229 DSP563XX_REG_IDX_AAR0
= 50,
230 DSP563XX_REG_IDX_AAR1
= 51,
231 DSP563XX_REG_IDX_AAR2
= 52,
232 DSP563XX_REG_IDX_AAR3
= 53,
235 static const struct {
239 /* effective addressing mode encoding */
242 } dsp563xx_regs
[] = {
244 /* address registers */
245 {DSP563XX_REG_IDX_R0
, "r0", 24, 0x10, ASM_REG_W_R0
},
246 {DSP563XX_REG_IDX_R1
, "r1", 24, 0x11, ASM_REG_W_R1
},
247 {DSP563XX_REG_IDX_R2
, "r2", 24, 0x12, ASM_REG_W_R2
},
248 {DSP563XX_REG_IDX_R3
, "r3", 24, 0x13, ASM_REG_W_R3
},
249 {DSP563XX_REG_IDX_R4
, "r4", 24, 0x14, ASM_REG_W_R4
},
250 {DSP563XX_REG_IDX_R5
, "r5", 24, 0x15, ASM_REG_W_R5
},
251 {DSP563XX_REG_IDX_R6
, "r6", 24, 0x16, ASM_REG_W_R6
},
252 {DSP563XX_REG_IDX_R7
, "r7", 24, 0x17, ASM_REG_W_R7
},
253 /* offset registers */
254 {DSP563XX_REG_IDX_N0
, "n0", 24, 0x18, ASM_REG_W_N0
},
255 {DSP563XX_REG_IDX_N1
, "n1", 24, 0x19, ASM_REG_W_N1
},
256 {DSP563XX_REG_IDX_N2
, "n2", 24, 0x1a, ASM_REG_W_N2
},
257 {DSP563XX_REG_IDX_N3
, "n3", 24, 0x1b, ASM_REG_W_N3
},
258 {DSP563XX_REG_IDX_N4
, "n4", 24, 0x1c, ASM_REG_W_N4
},
259 {DSP563XX_REG_IDX_N5
, "n5", 24, 0x1d, ASM_REG_W_N5
},
260 {DSP563XX_REG_IDX_N6
, "n6", 24, 0x1e, ASM_REG_W_N6
},
261 {DSP563XX_REG_IDX_N7
, "n7", 24, 0x1f, ASM_REG_W_N7
},
262 /* modifier registers */
263 {DSP563XX_REG_IDX_M0
, "m0", 24, 0x20, ASM_REG_W_M0
},
264 {DSP563XX_REG_IDX_M1
, "m1", 24, 0x21, ASM_REG_W_M1
},
265 {DSP563XX_REG_IDX_M2
, "m2", 24, 0x22, ASM_REG_W_M2
},
266 {DSP563XX_REG_IDX_M3
, "m3", 24, 0x23, ASM_REG_W_M3
},
267 {DSP563XX_REG_IDX_M4
, "m4", 24, 0x24, ASM_REG_W_M4
},
268 {DSP563XX_REG_IDX_M5
, "m5", 24, 0x25, ASM_REG_W_M5
},
269 {DSP563XX_REG_IDX_M6
, "m6", 24, 0x26, ASM_REG_W_M6
},
270 {DSP563XX_REG_IDX_M7
, "m7", 24, 0x27, ASM_REG_W_M7
},
271 /* data alu input register */
272 {DSP563XX_REG_IDX_X0
, "x0", 24, 0x04, ASM_REG_W_X0
},
273 {DSP563XX_REG_IDX_X1
, "x1", 24, 0x05, ASM_REG_W_X1
},
274 {DSP563XX_REG_IDX_Y0
, "y0", 24, 0x06, ASM_REG_W_Y0
},
275 {DSP563XX_REG_IDX_Y1
, "y1", 24, 0x07, ASM_REG_W_Y1
},
276 /* data alu accumulator register */
277 {DSP563XX_REG_IDX_A0
, "a0", 24, 0x08, ASM_REG_W_A0
},
278 {DSP563XX_REG_IDX_A1
, "a1", 24, 0x0c, ASM_REG_W_A1
},
279 {DSP563XX_REG_IDX_A2
, "a2", 8, 0x0a, ASM_REG_W_A2
},
280 {DSP563XX_REG_IDX_B0
, "b0", 24, 0x09, ASM_REG_W_B0
},
281 {DSP563XX_REG_IDX_B1
, "b1", 24, 0x0d, ASM_REG_W_B1
},
282 {DSP563XX_REG_IDX_B2
, "b2", 8, 0x0b, ASM_REG_W_B2
},
284 {DSP563XX_REG_IDX_SSH
, "ssh", 24, 0x3c, ASM_REG_W_SSH
},
285 {DSP563XX_REG_IDX_SSL
, "ssl", 24, 0x3d, ASM_REG_W_SSL
},
286 {DSP563XX_REG_IDX_SP
, "sp", 24, 0x3b, ASM_REG_W_SP
},
287 {DSP563XX_REG_IDX_EP
, "ep", 24, 0x2a, ASM_REG_W_EP
},
288 {DSP563XX_REG_IDX_SZ
, "sz", 24, 0x38, ASM_REG_W_SZ
},
289 {DSP563XX_REG_IDX_SC
, "sc", 24, 0x31, ASM_REG_W_SC
},
291 {DSP563XX_REG_IDX_PC
, "pc", 24, 0x00, ASM_REG_W_PC
},
292 {DSP563XX_REG_IDX_SR
, "sr", 24, 0x39, ASM_REG_W_SR
},
293 {DSP563XX_REG_IDX_OMR
, "omr", 24, 0x3a, ASM_REG_W_OMR
},
294 {DSP563XX_REG_IDX_LA
, "la", 24, 0x3e, ASM_REG_W_LA
},
295 {DSP563XX_REG_IDX_LC
, "lc", 24, 0x3f, ASM_REG_W_LC
},
297 {DSP563XX_REG_IDX_VBA
, "vba", 24, 0x30, ASM_REG_W_VBA
},
298 {DSP563XX_REG_IDX_IPRC
, "iprc", 24, 0x00, ASM_REG_W_IPRC
},
299 {DSP563XX_REG_IDX_IPRP
, "iprp", 24, 0x00, ASM_REG_W_IPRP
},
301 {DSP563XX_REG_IDX_BCR
, "bcr", 24, 0x00, ASM_REG_W_BCR
},
302 {DSP563XX_REG_IDX_DCR
, "dcr", 24, 0x00, ASM_REG_W_DCR
},
303 {DSP563XX_REG_IDX_AAR0
, "aar0", 24, 0x00, ASM_REG_W_AAR0
},
304 {DSP563XX_REG_IDX_AAR1
, "aar1", 24, 0x00, ASM_REG_W_AAR1
},
305 {DSP563XX_REG_IDX_AAR2
, "aar2", 24, 0x00, ASM_REG_W_AAR2
},
306 {DSP563XX_REG_IDX_AAR3
, "aar3", 24, 0x00, ASM_REG_W_AAR3
},
317 enum watchpoint_condition
{
324 #define INSTR_JUMP 0x0AF080
325 /* Effective Addressing Mode Encoding */
327 /* instrcution encoder */
329 * s - peripheral space X/Y (X=0,Y=1)
331 * d - source/destination register
332 * p - IO short address
334 #define INSTR_MOVEP_REG_HIO(s, w, d, p) (0x084000 | \
335 ((s & 1) << 16) | ((w & 1) << 15) | ((d & 0x3f) << 8) | (p & 0x3f))
337 /* the gdb register list is send in this order */
338 static uint8_t gdb_reg_list_idx
[] = {
339 DSP563XX_REG_IDX_X1
, DSP563XX_REG_IDX_X0
, DSP563XX_REG_IDX_Y1
, DSP563XX_REG_IDX_Y0
,
340 DSP563XX_REG_IDX_A2
, DSP563XX_REG_IDX_A1
, DSP563XX_REG_IDX_A0
, DSP563XX_REG_IDX_B2
,
341 DSP563XX_REG_IDX_B1
, DSP563XX_REG_IDX_B0
, DSP563XX_REG_IDX_PC
, DSP563XX_REG_IDX_SR
,
342 DSP563XX_REG_IDX_OMR
, DSP563XX_REG_IDX_LA
, DSP563XX_REG_IDX_LC
, DSP563XX_REG_IDX_SSH
,
343 DSP563XX_REG_IDX_SSL
, DSP563XX_REG_IDX_SP
, DSP563XX_REG_IDX_EP
, DSP563XX_REG_IDX_SZ
,
344 DSP563XX_REG_IDX_SC
, DSP563XX_REG_IDX_VBA
, DSP563XX_REG_IDX_IPRC
, DSP563XX_REG_IDX_IPRP
,
345 DSP563XX_REG_IDX_BCR
, DSP563XX_REG_IDX_DCR
, DSP563XX_REG_IDX_AAR0
, DSP563XX_REG_IDX_AAR1
,
346 DSP563XX_REG_IDX_AAR2
, DSP563XX_REG_IDX_AAR3
, DSP563XX_REG_IDX_R0
, DSP563XX_REG_IDX_R1
,
347 DSP563XX_REG_IDX_R2
, DSP563XX_REG_IDX_R3
, DSP563XX_REG_IDX_R4
, DSP563XX_REG_IDX_R5
,
348 DSP563XX_REG_IDX_R6
, DSP563XX_REG_IDX_R7
, DSP563XX_REG_IDX_N0
, DSP563XX_REG_IDX_N1
,
349 DSP563XX_REG_IDX_N2
, DSP563XX_REG_IDX_N3
, DSP563XX_REG_IDX_N4
, DSP563XX_REG_IDX_N5
,
350 DSP563XX_REG_IDX_N6
, DSP563XX_REG_IDX_N7
, DSP563XX_REG_IDX_M0
, DSP563XX_REG_IDX_M1
,
351 DSP563XX_REG_IDX_M2
, DSP563XX_REG_IDX_M3
, DSP563XX_REG_IDX_M4
, DSP563XX_REG_IDX_M5
,
352 DSP563XX_REG_IDX_M6
, DSP563XX_REG_IDX_M7
,
355 static int dsp563xx_get_gdb_reg_list(struct target
*target
,
356 struct reg
**reg_list
[],
358 enum target_register_class reg_class
)
361 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
363 if (target
->state
!= TARGET_HALTED
)
364 return ERROR_TARGET_NOT_HALTED
;
366 *reg_list_size
= DSP563XX_NUMCOREREGS
;
367 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
370 return ERROR_COMMAND_SYNTAX_ERROR
;
372 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++)
373 (*reg_list
)[i
] = &dsp563xx
->core_cache
->reg_list
[gdb_reg_list_idx
[i
]];
379 static int dsp563xx_read_core_reg(struct target
*target
, int num
)
382 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
384 if ((num
< 0) || (num
>= DSP563XX_NUMCOREREGS
))
385 return ERROR_COMMAND_SYNTAX_ERROR
;
387 reg_value
= dsp563xx
->core_regs
[num
];
388 buf_set_u32(dsp563xx
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
389 dsp563xx
->core_cache
->reg_list
[num
].valid
= 1;
390 dsp563xx
->core_cache
->reg_list
[num
].dirty
= 0;
395 static int dsp563xx_write_core_reg(struct target
*target
, int num
)
398 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
400 if ((num
< 0) || (num
>= DSP563XX_NUMCOREREGS
))
401 return ERROR_COMMAND_SYNTAX_ERROR
;
403 reg_value
= buf_get_u32(dsp563xx
->core_cache
->reg_list
[num
].value
, 0, 32);
404 dsp563xx
->core_regs
[num
] = reg_value
;
405 dsp563xx
->core_cache
->reg_list
[num
].valid
= 1;
406 dsp563xx
->core_cache
->reg_list
[num
].dirty
= 0;
411 static int dsp563xx_get_core_reg(struct reg
*reg
)
413 struct dsp563xx_core_reg
*dsp563xx_reg
= reg
->arch_info
;
414 struct target
*target
= dsp563xx_reg
->target
;
415 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
417 LOG_DEBUG("%s", __func__
);
419 if (target
->state
!= TARGET_HALTED
)
420 return ERROR_TARGET_NOT_HALTED
;
422 return dsp563xx
->read_core_reg(target
, dsp563xx_reg
->num
);
425 static int dsp563xx_set_core_reg(struct reg
*reg
, uint8_t *buf
)
427 LOG_DEBUG("%s", __func__
);
429 struct dsp563xx_core_reg
*dsp563xx_reg
= reg
->arch_info
;
430 struct target
*target
= dsp563xx_reg
->target
;
431 uint32_t value
= buf_get_u32(buf
, 0, 32);
433 if (target
->state
!= TARGET_HALTED
)
434 return ERROR_TARGET_NOT_HALTED
;
436 buf_set_u32(reg
->value
, 0, reg
->size
, value
);
443 static const struct reg_arch_type dsp563xx_reg_type
= {
444 .get
= dsp563xx_get_core_reg
,
445 .set
= dsp563xx_set_core_reg
,
448 static void dsp563xx_build_reg_cache(struct target
*target
)
450 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
452 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
453 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
454 struct reg
*reg_list
= calloc(DSP563XX_NUMCOREREGS
, sizeof(struct reg
));
455 struct dsp563xx_core_reg
*arch_info
= malloc(
456 sizeof(struct dsp563xx_core_reg
) * DSP563XX_NUMCOREREGS
);
459 /* Build the process context cache */
460 cache
->name
= "dsp563xx registers";
462 cache
->reg_list
= reg_list
;
463 cache
->num_regs
= DSP563XX_NUMCOREREGS
;
465 dsp563xx
->core_cache
= cache
;
467 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++) {
468 arch_info
[i
].num
= dsp563xx_regs
[i
].id
;
469 arch_info
[i
].name
= dsp563xx_regs
[i
].name
;
470 arch_info
[i
].size
= dsp563xx_regs
[i
].bits
;
471 arch_info
[i
].eame
= dsp563xx_regs
[i
].eame
;
472 arch_info
[i
].instr_mask
= dsp563xx_regs
[i
].instr_mask
;
473 arch_info
[i
].target
= target
;
474 arch_info
[i
].dsp563xx_common
= dsp563xx
;
475 reg_list
[i
].name
= dsp563xx_regs
[i
].name
;
476 reg_list
[i
].size
= 32; /* dsp563xx_regs[i].bits; */
477 reg_list
[i
].value
= calloc(1, 4);
478 reg_list
[i
].dirty
= 0;
479 reg_list
[i
].valid
= 0;
480 reg_list
[i
].type
= &dsp563xx_reg_type
;
481 reg_list
[i
].arch_info
= &arch_info
[i
];
485 static int dsp563xx_read_register(struct target
*target
, int num
, int force
);
486 static int dsp563xx_write_register(struct target
*target
, int num
, int force
);
488 static int dsp563xx_reg_read_high_io(struct target
*target
, uint32_t instr_mask
, uint32_t *data
)
492 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
494 /* we use r0 to store temporary data */
495 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
496 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
498 /* move source memory to r0 */
499 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 0, EAME_R0
, instr_mask
);
500 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, instr
);
503 /* move r0 to debug register */
504 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 1, EAME_R0
, 0xfffffc);
505 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 1, instr
);
508 /* read debug register */
509 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OGDBR
, data
);
512 /* r0 is no longer valid on target */
513 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= 1;
518 static int dsp563xx_reg_write_high_io(struct target
*target
, uint32_t instr_mask
, uint32_t data
)
522 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
524 /* we use r0 to store temporary data */
525 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
526 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
528 /* move data to r0 */
529 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 0, 0x60F400, data
);
532 /* move r0 to destination memory */
533 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 1, EAME_R0
, instr_mask
);
534 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 1, instr
);
538 /* r0 is no longer valid on target */
539 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= 1;
544 static int dsp563xx_reg_read(struct target
*target
, uint32_t eame
, uint32_t *data
)
549 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 1, eame
, 0xfffffc);
550 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, instr
);
554 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 1, 0x000000);
557 /* read debug register */
558 return dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OGDBR
, data
);
561 static int dsp563xx_reg_write(struct target
*target
, uint32_t instr_mask
, uint32_t data
)
565 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 0, instr_mask
, data
);
569 return dsp563xx_once_execute_sw_ir(target
->tap
, 1, 0x000000);
572 static int dsp563xx_reg_pc_read(struct target
*target
)
574 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
576 /* pc was changed, nothing todo */
577 if (dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].dirty
)
580 /* conditional branch check */
581 if (once_regs
[ONCE_REG_IDX_OPABDR
].reg
== once_regs
[ONCE_REG_IDX_OPABEX
].reg
) {
582 if ((once_regs
[ONCE_REG_IDX_OPABF11
].reg
& 1) == 0) {
583 LOG_DEBUG("%s conditional branch not supported yet (0x%" PRIx32
" 0x%" PRIx32
" 0x%" PRIx32
")",
585 (once_regs
[ONCE_REG_IDX_OPABF11
].reg
>> 1),
586 once_regs
[ONCE_REG_IDX_OPABDR
].reg
,
587 once_regs
[ONCE_REG_IDX_OPABEX
].reg
);
589 /* TODO: use disassembly to set correct pc offset
590 * read 2 words from OPABF11 and disasm the instruction
592 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] =
593 (once_regs
[ONCE_REG_IDX_OPABF11
].reg
>> 1) & 0x00FFFFFF;
595 if (once_regs
[ONCE_REG_IDX_OPABEX
].reg
==
596 once_regs
[ONCE_REG_IDX_OPABFR
].reg
)
597 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] =
598 once_regs
[ONCE_REG_IDX_OPABEX
].reg
;
600 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] =
601 once_regs
[ONCE_REG_IDX_OPABEX
].reg
- 1;
604 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] = once_regs
[ONCE_REG_IDX_OPABEX
].reg
;
606 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_PC
);
611 static int dsp563xx_reg_ssh_read(struct target
*target
)
615 struct dsp563xx_core_reg
*arch_info
;
616 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
618 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSH
].arch_info
;
620 /* get a valid stack pointer */
621 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 0);
624 sp
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
];
625 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SP
, 0);
629 /* get a valid stack count */
630 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SC
, 0);
634 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SC
, 0);
638 /* get a valid extended pointer */
639 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_EP
, 0);
643 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_EP
, 0);
650 err
= dsp563xx_reg_read(target
, arch_info
->eame
, &sp
);
654 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SC
, 1);
657 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SP
, 1);
660 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_EP
, 1);
665 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SSH
] = sp
;
666 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_SSH
);
671 static int dsp563xx_reg_ssh_write(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_SSH
].arch_info
;
680 /* get a valid stack pointer */
681 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 0);
684 sp
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
];
688 /* write new stackpointer */
689 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
] = sp
;
690 err
= dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_SP
);
693 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SP
, 1);
697 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
,
698 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SSH
]);
702 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 1);
705 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SSH
, 1);
713 static int dsp563xx_reg_ssl_read(struct target
*target
)
717 struct dsp563xx_core_reg
*arch_info
;
718 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
720 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSL
].arch_info
;
722 /* get a valid stack pointer */
723 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 0);
726 sp
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
];
731 err
= dsp563xx_reg_read(target
, arch_info
->eame
, &sp
);
736 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SSL
] = sp
;
737 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_SSL
);
742 static int dsp563xx_read_register(struct target
*target
, int num
, int force
)
746 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
747 struct dsp563xx_core_reg
*arch_info
;
750 dsp563xx
->core_cache
->reg_list
[num
].valid
= 0;
752 if (!dsp563xx
->core_cache
->reg_list
[num
].valid
) {
753 arch_info
= dsp563xx
->core_cache
->reg_list
[num
].arch_info
;
755 switch (arch_info
->num
) {
756 case DSP563XX_REG_IDX_SSH
:
757 err
= dsp563xx_reg_ssh_read(target
);
759 case DSP563XX_REG_IDX_SSL
:
760 err
= dsp563xx_reg_ssl_read(target
);
762 case DSP563XX_REG_IDX_PC
:
763 err
= dsp563xx_reg_pc_read(target
);
765 case DSP563XX_REG_IDX_IPRC
:
766 case DSP563XX_REG_IDX_IPRP
:
767 case DSP563XX_REG_IDX_BCR
:
768 case DSP563XX_REG_IDX_DCR
:
769 case DSP563XX_REG_IDX_AAR0
:
770 case DSP563XX_REG_IDX_AAR1
:
771 case DSP563XX_REG_IDX_AAR2
:
772 case DSP563XX_REG_IDX_AAR3
:
773 err
= dsp563xx_reg_read_high_io(target
,
774 arch_info
->instr_mask
, &data
);
775 if (err
== ERROR_OK
) {
776 dsp563xx
->core_regs
[num
] = data
;
777 dsp563xx
->read_core_reg(target
, num
);
781 err
= dsp563xx_reg_read(target
, arch_info
->eame
, &data
);
782 if (err
== ERROR_OK
) {
783 dsp563xx
->core_regs
[num
] = data
;
784 dsp563xx
->read_core_reg(target
, num
);
793 static int dsp563xx_write_register(struct target
*target
, int num
, int force
)
796 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
797 struct dsp563xx_core_reg
*arch_info
;
800 dsp563xx
->core_cache
->reg_list
[num
].dirty
= 1;
802 if (dsp563xx
->core_cache
->reg_list
[num
].dirty
) {
803 arch_info
= dsp563xx
->core_cache
->reg_list
[num
].arch_info
;
805 dsp563xx
->write_core_reg(target
, num
);
807 switch (arch_info
->num
) {
808 case DSP563XX_REG_IDX_SSH
:
809 err
= dsp563xx_reg_ssh_write(target
);
811 case DSP563XX_REG_IDX_PC
:
812 /* pc is updated on resume, no need to write it here */
814 case DSP563XX_REG_IDX_IPRC
:
815 case DSP563XX_REG_IDX_IPRP
:
816 case DSP563XX_REG_IDX_BCR
:
817 case DSP563XX_REG_IDX_DCR
:
818 case DSP563XX_REG_IDX_AAR0
:
819 case DSP563XX_REG_IDX_AAR1
:
820 case DSP563XX_REG_IDX_AAR2
:
821 case DSP563XX_REG_IDX_AAR3
:
822 err
= dsp563xx_reg_write_high_io(target
,
823 arch_info
->instr_mask
,
824 dsp563xx
->core_regs
[num
]);
827 err
= dsp563xx_reg_write(target
,
828 arch_info
->instr_mask
,
829 dsp563xx
->core_regs
[num
]);
831 if ((err
== ERROR_OK
) && (arch_info
->num
== DSP563XX_REG_IDX_SP
)) {
832 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSH
].valid
=
834 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSL
].valid
=
845 static int dsp563xx_save_context(struct target
*target
)
847 int i
, err
= ERROR_OK
;
849 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++) {
850 err
= dsp563xx_read_register(target
, i
, 0);
858 static int dsp563xx_restore_context(struct target
*target
)
860 int i
, err
= ERROR_OK
;
862 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++) {
863 err
= dsp563xx_write_register(target
, i
, 0);
871 static void dsp563xx_invalidate_x_context(struct target
*target
,
876 struct dsp563xx_core_reg
*arch_info
;
877 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
879 if (addr_start
> ASM_REG_W_IPRC
)
881 if (addr_start
< ASM_REG_W_AAR3
)
884 for (i
= DSP563XX_REG_IDX_IPRC
; i
< DSP563XX_NUMCOREREGS
; i
++) {
885 arch_info
= dsp563xx
->core_cache
->reg_list
[i
].arch_info
;
887 if ((arch_info
->instr_mask
>= addr_start
) &&
888 (arch_info
->instr_mask
<= addr_end
)) {
889 dsp563xx
->core_cache
->reg_list
[i
].valid
= 0;
890 dsp563xx
->core_cache
->reg_list
[i
].dirty
= 0;
895 static int dsp563xx_target_create(struct target
*target
, Jim_Interp
*interp
)
897 struct dsp563xx_common
*dsp563xx
= calloc(1, sizeof(struct dsp563xx_common
));
900 return ERROR_COMMAND_SYNTAX_ERROR
;
902 dsp563xx
->jtag_info
.tap
= target
->tap
;
903 target
->arch_info
= dsp563xx
;
904 dsp563xx
->read_core_reg
= dsp563xx_read_core_reg
;
905 dsp563xx
->write_core_reg
= dsp563xx_write_core_reg
;
910 static int dsp563xx_init_target(struct command_context
*cmd_ctx
, struct target
*target
)
912 LOG_DEBUG("%s", __func__
);
914 dsp563xx_build_reg_cache(target
);
915 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
917 dsp563xx
->hardware_breakpoints_cleared
= 0;
918 dsp563xx
->hardware_breakpoint
[0].used
= BPU_NONE
;
923 static int dsp563xx_examine(struct target
*target
)
927 if (target
->tap
->hasidcode
== false) {
928 LOG_ERROR("no IDCODE present on device");
929 return ERROR_COMMAND_SYNTAX_ERROR
;
932 if (!target_was_examined(target
)) {
933 target_set_examined(target
);
935 /* examine core and chip derivate number */
936 chip
= (target
->tap
->idcode
>>12) & 0x3ff;
937 /* core number 0 means DSP563XX */
938 if (((chip
>>5)&0x1f) == 0)
941 LOG_INFO("DSP56%03" PRId32
" device found", chip
);
943 /* Clear all breakpoints */
944 dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OBCR
, 0);
950 static int dsp563xx_arch_state(struct target
*target
)
952 LOG_DEBUG("%s", __func__
);
956 #define DSP563XX_SR_SA (1<<17)
957 #define DSP563XX_SR_SC (1<<13)
959 static int dsp563xx_debug_once_init(struct target
*target
)
961 return dsp563xx_once_read_register(target
->tap
, 1, once_regs
, DSP563XX_NUMONCEREGS
);
964 static int dsp563xx_debug_init(struct target
*target
)
968 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
969 struct dsp563xx_core_reg
*arch_info
;
971 err
= dsp563xx_debug_once_init(target
);
975 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SR
].arch_info
;
977 /* check 24bit mode */
978 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SR
, 0);
982 sr
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SR
];
984 if (sr
& (DSP563XX_SR_SA
| DSP563XX_SR_SC
)) {
985 sr
&= ~(DSP563XX_SR_SA
| DSP563XX_SR_SC
);
987 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, arch_info
->instr_mask
, sr
);
990 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SR
].dirty
= 1;
993 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_N0
, 0);
996 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_N1
, 0);
999 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_M0
, 0);
1000 if (err
!= ERROR_OK
)
1002 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_M1
, 0);
1003 if (err
!= ERROR_OK
)
1006 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_N0
] != 0x000000) {
1007 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N0
].arch_info
;
1008 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0x000000);
1009 if (err
!= ERROR_OK
)
1012 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N0
].dirty
= 1;
1014 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_N1
] != 0x000000) {
1015 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N1
].arch_info
;
1016 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0x000000);
1017 if (err
!= ERROR_OK
)
1020 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N1
].dirty
= 1;
1022 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_M0
] != 0xffffff) {
1023 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M0
].arch_info
;
1024 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0xffffff);
1025 if (err
!= ERROR_OK
)
1028 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M0
].dirty
= 1;
1030 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_M1
] != 0xffffff) {
1031 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M1
].arch_info
;
1032 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0xffffff);
1033 if (err
!= ERROR_OK
)
1036 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M1
].dirty
= 1;
1038 err
= dsp563xx_save_context(target
);
1039 if (err
!= ERROR_OK
)
1045 static int dsp563xx_jtag_debug_request(struct target
*target
)
1047 return dsp563xx_once_request_debug(target
->tap
, target
->state
== TARGET_RESET
);
1050 static int dsp563xx_poll(struct target
*target
)
1053 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1054 uint32_t once_status
= 0;
1057 state
= dsp563xx_once_target_status(target
->tap
);
1059 if (state
== TARGET_UNKNOWN
) {
1060 target
->state
= state
;
1061 LOG_ERROR("jtag status contains invalid mode value - communication failure");
1062 return ERROR_TARGET_FAILURE
;
1065 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OSCR
, &once_status
);
1066 if (err
!= ERROR_OK
)
1069 if ((once_status
& DSP563XX_ONCE_OSCR_DEBUG_M
) == DSP563XX_ONCE_OSCR_DEBUG_M
) {
1070 if (target
->state
!= TARGET_HALTED
) {
1071 target
->state
= TARGET_HALTED
;
1073 err
= dsp563xx_debug_init(target
);
1074 if (err
!= ERROR_OK
)
1077 if (once_status
& (DSP563XX_ONCE_OSCR_MBO
|DSP563XX_ONCE_OSCR_SWO
))
1078 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
1080 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1082 LOG_DEBUG("target->state: %s (%" PRIx32
")", target_state_name(target
), once_status
);
1083 LOG_INFO("halted: PC: 0x%" PRIx32
, dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
]);
1087 if (!dsp563xx
->hardware_breakpoints_cleared
) {
1088 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OBCR
, 0);
1089 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR0
, 0);
1090 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR1
, 0);
1091 dsp563xx
->hardware_breakpoints_cleared
= 1;
1097 static int dsp563xx_halt(struct target
*target
)
1101 LOG_DEBUG("%s", __func__
);
1103 if (target
->state
== TARGET_HALTED
) {
1104 LOG_DEBUG("target was already halted");
1108 if (target
->state
== TARGET_UNKNOWN
)
1109 LOG_WARNING("target was in unknown state when halt was requested");
1111 err
= dsp563xx_jtag_debug_request(target
);
1112 if (err
!= ERROR_OK
)
1115 target
->debug_reason
= DBG_REASON_DBGRQ
;
1120 static int dsp563xx_resume(struct target
*target
,
1123 int handle_breakpoints
,
1124 int debug_execution
)
1127 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1129 /* check if pc was changed and resume want to execute the next address
1130 * if pc was changed from gdb or other interface we will
1131 * jump to this address and don't execute the next address
1132 * this will not affect the resume command with an address argument
1133 * because current is set to zero then
1135 if (current
&& dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].dirty
) {
1136 dsp563xx_write_core_reg(target
, DSP563XX_REG_IDX_PC
);
1137 address
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
];
1141 LOG_DEBUG("%s %08X %08X", __func__
, current
, (unsigned) address
);
1143 err
= dsp563xx_restore_context(target
);
1144 if (err
!= ERROR_OK
)
1146 register_cache_invalidate(dsp563xx
->core_cache
);
1149 /* restore pipeline registers and go */
1150 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
,
1151 once_regs
[ONCE_REG_IDX_OPILR
].reg
);
1152 if (err
!= ERROR_OK
)
1154 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
|
1155 DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
,
1156 once_regs
[ONCE_REG_IDX_OPDBR
].reg
);
1157 if (err
!= ERROR_OK
)
1160 /* set to go register and jump */
1161 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
, INSTR_JUMP
);
1162 if (err
!= ERROR_OK
)
1164 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_PDBGOTO
|
1165 DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
, address
);
1166 if (err
!= ERROR_OK
)
1170 target
->state
= TARGET_RUNNING
;
1172 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1177 static int dsp563xx_step_ex(struct target
*target
,
1180 int handle_breakpoints
,
1184 uint32_t once_status
;
1185 uint32_t dr_in
, cnt
;
1186 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1188 if (target
->state
!= TARGET_HALTED
) {
1189 LOG_DEBUG("target was not halted");
1193 /* check if pc was changed and step want to execute the next address
1194 * if pc was changed from gdb or other interface we will
1195 * jump to this address and don't execute the next address
1196 * this will not affect the step command with an address argument
1197 * because current is set to zero then
1199 if (current
&& dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].dirty
) {
1200 dsp563xx_write_core_reg(target
, DSP563XX_REG_IDX_PC
);
1201 address
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
];
1205 LOG_DEBUG("%s %08X %08X", __func__
, current
, (unsigned) address
);
1207 err
= dsp563xx_jtag_debug_request(target
);
1208 if (err
!= ERROR_OK
)
1210 err
= dsp563xx_restore_context(target
);
1211 if (err
!= ERROR_OK
)
1214 /* reset trace mode */
1215 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OSCR
, 0x000000);
1216 if (err
!= ERROR_OK
)
1218 /* enable trace mode */
1219 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OSCR
, DSP563XX_ONCE_OSCR_TME
);
1220 if (err
!= ERROR_OK
)
1225 /* on JUMP we need one extra cycle */
1229 /* load step counter with N-1 */
1230 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OTC
, cnt
);
1231 if (err
!= ERROR_OK
)
1235 /* restore pipeline registers and go */
1236 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
,
1237 once_regs
[ONCE_REG_IDX_OPILR
].reg
);
1238 if (err
!= ERROR_OK
)
1240 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
|
1241 DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
,
1242 once_regs
[ONCE_REG_IDX_OPDBR
].reg
);
1243 if (err
!= ERROR_OK
)
1246 /* set to go register and jump */
1247 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
, INSTR_JUMP
);
1248 if (err
!= ERROR_OK
)
1250 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_PDBGOTO
|
1251 DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
,
1253 if (err
!= ERROR_OK
)
1258 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OSCR
, &once_status
);
1259 if (err
!= ERROR_OK
)
1262 if (once_status
& DSP563XX_ONCE_OSCR_TO
) {
1263 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OPABFR
, &dr_in
);
1264 if (err
!= ERROR_OK
)
1266 LOG_DEBUG("fetch: %08X", (unsigned) dr_in
&0x00ffffff);
1267 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OPABDR
, &dr_in
);
1268 if (err
!= ERROR_OK
)
1270 LOG_DEBUG("decode: %08X", (unsigned) dr_in
&0x00ffffff);
1271 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OPABEX
, &dr_in
);
1272 if (err
!= ERROR_OK
)
1274 LOG_DEBUG("execute: %08X", (unsigned) dr_in
&0x00ffffff);
1276 /* reset trace mode */
1277 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OSCR
, 0x000000);
1278 if (err
!= ERROR_OK
)
1281 register_cache_invalidate(dsp563xx
->core_cache
);
1282 err
= dsp563xx_debug_init(target
);
1283 if (err
!= ERROR_OK
)
1293 static int dsp563xx_step(struct target
*target
,
1296 int handle_breakpoints
)
1299 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1301 if (target
->state
!= TARGET_HALTED
) {
1302 LOG_WARNING("target not halted");
1303 return ERROR_TARGET_NOT_HALTED
;
1306 err
= dsp563xx_step_ex(target
, current
, address
, handle_breakpoints
, 0);
1307 if (err
!= ERROR_OK
)
1310 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1311 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1313 LOG_INFO("halted: PC: 0x%" PRIx32
, dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
]);
1318 static int dsp563xx_assert_reset(struct target
*target
)
1321 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1322 enum reset_types jtag_reset_config
= jtag_get_reset_config();
1324 if (jtag_reset_config
& RESET_HAS_SRST
) {
1325 /* default to asserting srst */
1326 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
1327 jtag_add_reset(1, 1);
1329 jtag_add_reset(0, 1);
1332 target
->state
= TARGET_RESET
;
1333 jtag_add_sleep(5000);
1335 /* registers are now invalid */
1336 register_cache_invalidate(dsp563xx
->core_cache
);
1338 if (target
->reset_halt
) {
1339 retval
= target_halt(target
);
1340 if (retval
!= ERROR_OK
)
1344 LOG_DEBUG("%s", __func__
);
1348 static int dsp563xx_deassert_reset(struct target
*target
)
1352 /* deassert reset lines */
1353 jtag_add_reset(0, 0);
1355 err
= dsp563xx_poll(target
);
1356 if (err
!= ERROR_OK
)
1359 if (target
->reset_halt
) {
1360 if (target
->state
== TARGET_HALTED
) {
1361 /* after a reset the cpu jmp to the
1362 * reset vector and need 2 cycles to fill
1363 * the cache (fetch,decode,excecute)
1365 err
= dsp563xx_step_ex(target
, 1, 0, 1, 1);
1366 if (err
!= ERROR_OK
)
1370 target
->state
= TARGET_RUNNING
;
1372 LOG_DEBUG("%s", __func__
);
1376 static int dsp563xx_run_algorithm(struct target
*target
,
1377 int num_mem_params
, struct mem_param
*mem_params
,
1378 int num_reg_params
, struct reg_param
*reg_params
,
1379 uint32_t entry_point
, uint32_t exit_point
,
1380 int timeout_ms
, void *arch_info
)
1383 int retval
= ERROR_OK
;
1384 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1386 if (target
->state
!= TARGET_HALTED
) {
1387 LOG_WARNING("target not halted");
1388 return ERROR_TARGET_NOT_HALTED
;
1391 for (i
= 0; i
< num_mem_params
; i
++) {
1392 retval
= target_write_buffer(target
, mem_params
[i
].address
,
1393 mem_params
[i
].size
, mem_params
[i
].value
);
1394 if (retval
!= ERROR_OK
)
1398 for (i
= 0; i
< num_reg_params
; i
++) {
1399 struct reg
*reg
= register_get_by_name(dsp563xx
->core_cache
,
1400 reg_params
[i
].reg_name
,
1404 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
1408 if (reg
->size
!= reg_params
[i
].size
) {
1409 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1410 reg_params
[i
].reg_name
);
1414 retval
= dsp563xx_set_core_reg(reg
, reg_params
[i
].value
);
1415 if (retval
!= ERROR_OK
)
1420 retval
= target_resume(target
, 0, entry_point
, 1, 1);
1421 if (retval
!= ERROR_OK
)
1424 retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
);
1425 if (retval
!= ERROR_OK
)
1428 for (i
= 0; i
< num_mem_params
; i
++) {
1429 if (mem_params
[i
].direction
!= PARAM_OUT
)
1430 retval
= target_read_buffer(target
,
1431 mem_params
[i
].address
,
1433 mem_params
[i
].value
);
1434 if (retval
!= ERROR_OK
)
1438 for (i
= 0; i
< num_reg_params
; i
++) {
1439 if (reg_params
[i
].direction
!= PARAM_OUT
) {
1441 struct reg
*reg
= register_get_by_name(dsp563xx
->core_cache
,
1442 reg_params
[i
].reg_name
,
1445 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
1449 if (reg
->size
!= reg_params
[i
].size
) {
1451 "BUG: register '%s' size doesn't match reg_params[i].size",
1452 reg_params
[i
].reg_name
);
1456 buf_set_u32(reg_params
[i
].value
, 0, 32, buf_get_u32(reg
->value
, 0, 32));
1463 /* global command context from openocd.c */
1464 extern struct command_context
*global_cmd_ctx
;
1466 static int dsp563xx_get_default_memory(void)
1472 if (!global_cmd_ctx
)
1475 interp
= global_cmd_ctx
->interp
;
1480 memspace
= Jim_GetGlobalVariableStr(interp
, "memspace", JIM_NONE
);
1485 c
= (char *)Jim_GetString(memspace
, NULL
);
1504 static int dsp563xx_read_memory_core(struct target
*target
,
1512 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1514 uint32_t data
, move_cmd
= 0;
1518 "memtype: %d address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
1524 if (target
->state
!= TARGET_HALTED
) {
1525 LOG_WARNING("target not halted");
1526 return ERROR_TARGET_NOT_HALTED
;
1531 /* TODO: mark effected queued registers */
1532 move_cmd
= 0x61d800;
1535 move_cmd
= 0x69d800;
1538 move_cmd
= 0x07d891;
1541 return ERROR_COMMAND_SYNTAX_ERROR
;
1544 /* we use r0 to store temporary data */
1545 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
1546 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
1547 /* we use r1 to store temporary data */
1548 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].valid
)
1549 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R1
);
1551 /* r0 is no longer valid on target */
1552 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= 1;
1553 /* r1 is no longer valid on target */
1554 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].dirty
= 1;
1559 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, 0x60F400, address
);
1560 if (err
!= ERROR_OK
)
1563 for (i
= 0; i
< x
; i
++) {
1564 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, move_cmd
);
1565 if (err
!= ERROR_OK
)
1567 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, 0x08D13C);
1568 if (err
!= ERROR_OK
)
1570 err
= dsp563xx_once_reg_read(target
->tap
, 0,
1571 DSP563XX_ONCE_OGDBR
, (uint32_t *)(void *)b
);
1572 if (err
!= ERROR_OK
)
1577 /* flush the jtag queue */
1578 err
= jtag_execute_queue();
1579 if (err
!= ERROR_OK
)
1582 /* walk over the buffer and fix target endianness */
1585 for (i
= 0; i
< x
; i
++) {
1586 data
= buf_get_u32(b
, 0, 32) & 0x00FFFFFF;
1587 /* LOG_DEBUG("R: %08X", *((uint32_t*)b)); */
1588 target_buffer_set_u32(target
, b
, data
);
1595 static int dsp563xx_read_memory(struct target
*target
,
1604 uint8_t *buffer_y
, *buffer_x
;
1606 /* if size equals zero we are called from target read memory
1607 * and have to handle the parameter here */
1608 if ((size
== 0) && (count
!= 0)) {
1612 LOG_DEBUG("size is not aligned to 4 byte");
1614 count
= (count
- size
) / 4;
1618 /* we only support 4 byte aligned data */
1619 if ((size
!= 4) || (!count
))
1620 return ERROR_COMMAND_SYNTAX_ERROR
;
1622 if (mem_type
!= MEM_L
)
1623 return dsp563xx_read_memory_core(target
, mem_type
, address
, size
, count
, buffer
);
1625 buffer_y
= malloc(size
* count
);
1627 return ERROR_COMMAND_SYNTAX_ERROR
;
1629 buffer_x
= malloc(size
* count
);
1632 return ERROR_COMMAND_SYNTAX_ERROR
;
1635 err
= dsp563xx_read_memory_core(target
, MEM_Y
, address
, size
, count
/ 2, buffer_y
);
1637 if (err
!= ERROR_OK
) {
1643 err
= dsp563xx_read_memory_core(target
, MEM_X
, address
, size
, count
/ 2, buffer_x
);
1645 if (err
!= ERROR_OK
) {
1651 for (i
= 0, i1
= 0; i
< count
; i
+= 2, i1
++) {
1652 buf_set_u32(buffer
+ i
*sizeof(uint32_t), 0, 32,
1653 buf_get_u32(buffer_y
+ i1
* sizeof(uint32_t), 0, 32));
1654 buf_set_u32(buffer
+ (i
+ 1) * sizeof(uint32_t), 0, 32,
1655 buf_get_u32(buffer_x
+ i1
* sizeof(uint32_t), 0, 32));
1664 static int dsp563xx_read_memory_default(struct target
*target
,
1671 return dsp563xx_read_memory(target
,
1672 dsp563xx_get_default_memory(), address
, size
, count
, buffer
);
1675 static int dsp563xx_read_buffer_default(struct target
*target
,
1681 return dsp563xx_read_memory(target
, dsp563xx_get_default_memory(), address
, size
, 0,
1685 static int dsp563xx_write_memory_core(struct target
*target
,
1690 const uint8_t *buffer
)
1693 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1695 uint32_t data
, move_cmd
= 0;
1699 "memtype: %d address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
1705 if (target
->state
!= TARGET_HALTED
) {
1706 LOG_WARNING("target not halted");
1707 return ERROR_TARGET_NOT_HALTED
;
1712 /* invalidate affected x registers */
1713 dsp563xx_invalidate_x_context(target
, address
, address
+ count
- 1);
1714 move_cmd
= 0x615800;
1717 move_cmd
= 0x695800;
1720 move_cmd
= 0x075891;
1723 return ERROR_COMMAND_SYNTAX_ERROR
;
1726 /* we use r0 to store temporary data */
1727 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
1728 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
1729 /* we use r1 to store temporary data */
1730 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].valid
)
1731 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R1
);
1733 /* r0 is no longer valid on target */
1734 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= 1;
1735 /* r1 is no longer valid on target */
1736 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].dirty
= 1;
1741 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, 0x60F400, address
);
1742 if (err
!= ERROR_OK
)
1745 for (i
= 0; i
< x
; i
++) {
1746 data
= target_buffer_get_u32(target
, b
);
1748 /* LOG_DEBUG("W: %08X", data); */
1752 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 0, 0x61F400, data
);
1753 if (err
!= ERROR_OK
)
1755 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, move_cmd
);
1756 if (err
!= ERROR_OK
)
1761 /* flush the jtag queue */
1762 err
= jtag_execute_queue();
1763 if (err
!= ERROR_OK
)
1769 static int dsp563xx_write_memory(struct target
*target
,
1774 const uint8_t *buffer
)
1778 uint8_t *buffer_y
, *buffer_x
;
1780 /* if size equals zero we are called from target write memory
1781 * and have to handle the parameter here */
1782 if ((size
== 0) && (count
!= 0)) {
1786 LOG_DEBUG("size is not aligned to 4 byte");
1788 count
= (count
- size
) / 4;
1792 /* we only support 4 byte aligned data */
1793 if ((size
!= 4) || (!count
))
1794 return ERROR_COMMAND_SYNTAX_ERROR
;
1796 if (mem_type
!= MEM_L
)
1797 return dsp563xx_write_memory_core(target
, mem_type
, address
, size
, count
, buffer
);
1799 buffer_y
= malloc(size
* count
);
1801 return ERROR_COMMAND_SYNTAX_ERROR
;
1803 buffer_x
= malloc(size
* count
);
1806 return ERROR_COMMAND_SYNTAX_ERROR
;
1809 for (i
= 0, i1
= 0; i
< count
; i
+= 2, i1
++) {
1810 buf_set_u32(buffer_y
+ i1
* sizeof(uint32_t), 0, 32,
1811 buf_get_u32(buffer
+ i
* sizeof(uint32_t), 0, 32));
1812 buf_set_u32(buffer_x
+ i1
* sizeof(uint32_t), 0, 32,
1813 buf_get_u32(buffer
+ (i
+ 1) * sizeof(uint32_t), 0, 32));
1816 err
= dsp563xx_write_memory_core(target
, MEM_Y
, address
, size
, count
/ 2, buffer_y
);
1818 if (err
!= ERROR_OK
) {
1824 err
= dsp563xx_write_memory_core(target
, MEM_X
, address
, size
, count
/ 2, buffer_x
);
1826 if (err
!= ERROR_OK
) {
1838 static int dsp563xx_write_memory_default(struct target
*target
,
1842 const uint8_t *buffer
)
1844 return dsp563xx_write_memory(target
,
1845 dsp563xx_get_default_memory(), address
, size
, count
, buffer
);
1848 static int dsp563xx_write_buffer_default(struct target
*target
,
1851 const uint8_t *buffer
)
1853 return dsp563xx_write_memory(target
, dsp563xx_get_default_memory(), address
, size
, 0,
1858 * Exit with error here, because we support watchpoints over a custom command.
1859 * This is because the DSP has separate X,Y,P memspace which is not compatible to the
1860 * traditional watchpoint logic.
1862 static int dsp563xx_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1864 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1868 * @see dsp563xx_add_watchpoint
1870 static int dsp563xx_remove_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1872 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1875 static void handle_md_output(struct command_context
*cmd_ctx
,
1876 struct target
*target
,
1880 const uint8_t *buffer
)
1882 const unsigned line_bytecnt
= 32;
1883 unsigned line_modulo
= line_bytecnt
/ size
;
1885 char output
[line_bytecnt
* 4 + 1];
1886 unsigned output_len
= 0;
1888 const char *value_fmt
;
1891 value_fmt
= "%8.8x ";
1894 value_fmt
= "%4.4x ";
1897 value_fmt
= "%2.2x ";
1900 /* "can't happen", caller checked */
1901 LOG_ERROR("invalid memory read size: %u", size
);
1905 for (unsigned i
= 0; i
< count
; i
++) {
1906 if (i
% line_modulo
== 0)
1907 output_len
+= snprintf(output
+ output_len
,
1908 sizeof(output
) - output_len
,
1910 (unsigned) (address
+ i
));
1913 const uint8_t *value_ptr
= buffer
+ i
* size
;
1916 value
= target_buffer_get_u32(target
, value_ptr
);
1919 value
= target_buffer_get_u16(target
, value_ptr
);
1924 output_len
+= snprintf(output
+ output_len
,
1925 sizeof(output
) - output_len
,
1929 if ((i
% line_modulo
== line_modulo
- 1) || (i
== count
- 1)) {
1930 command_print(cmd_ctx
, "%s", output
);
1936 static int dsp563xx_add_custom_watchpoint(struct target
*target
, uint32_t address
, uint32_t memType
,
1937 enum watchpoint_rw rw
, enum watchpoint_condition cond
)
1940 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1942 bool wasRunning
= false;
1943 /* Only set breakpoint when halted */
1944 if (target
->state
!= TARGET_HALTED
) {
1945 dsp563xx_halt(target
);
1949 if (dsp563xx
->hardware_breakpoint
[0].used
) {
1950 LOG_ERROR("Cannot add watchpoint. Hardware resource already used.");
1951 err
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1954 uint32_t obcr_value
= 0;
1955 if (err
== ERROR_OK
) {
1956 obcr_value
|= OBCR_b0_or_b1
;
1959 obcr_value
|= OBCR_BP_MEM_X
;
1962 obcr_value
|= OBCR_BP_MEM_Y
;
1965 obcr_value
|= OBCR_BP_MEM_P
;
1968 LOG_ERROR("Unknown memType parameter (%" PRIu32
")", memType
);
1969 err
= ERROR_TARGET_INVALID
;
1973 if (err
== ERROR_OK
) {
1976 obcr_value
|= OBCR_BP_0(OBCR_BP_ON_READ
);
1979 obcr_value
|= OBCR_BP_0(OBCR_BP_ON_WRITE
);
1982 obcr_value
|= OBCR_BP_0(OBCR_BP_ON_READ
|OBCR_BP_ON_WRITE
);
1985 LOG_ERROR("Unsupported write mode (%d)", rw
);
1986 err
= ERROR_TARGET_INVALID
;
1990 if (err
== ERROR_OK
) {
1993 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_EQUAL
);
1996 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_NOT_EQUAL
);
1999 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_LESS_THAN
);
2002 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_GREATER_THAN
);
2005 LOG_ERROR("Unsupported condition code (%d)", cond
);
2006 err
= ERROR_TARGET_INVALID
;
2010 if (err
== ERROR_OK
)
2011 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR0
, address
);
2013 if (err
== ERROR_OK
)
2014 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR1
, 0x0);
2016 if (err
== ERROR_OK
)
2017 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OBCR
, obcr_value
);
2019 if (err
== ERROR_OK
) {
2020 /* You should write the memory breakpoint counter to 0 */
2021 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMBC
, 0);
2024 if (err
== ERROR_OK
) {
2025 /* You should write the memory breakpoint counter to 0 */
2026 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OTC
, 0);
2029 if (err
== ERROR_OK
)
2030 dsp563xx
->hardware_breakpoint
[0].used
= BPU_WATCHPOINT
;
2032 if (err
== ERROR_OK
&& wasRunning
) {
2033 /* Resume from current PC */
2034 err
= dsp563xx_resume(target
, 1, 0x0, 0, 0);
2040 static int dsp563xx_remove_custom_watchpoint(struct target
*target
)
2043 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
2045 if (dsp563xx
->hardware_breakpoint
[0].used
!= BPU_WATCHPOINT
) {
2046 LOG_ERROR("Cannot remove watchpoint, as no watchpoint is currently configured!");
2047 err
= ERROR_TARGET_INVALID
;
2050 if (err
== ERROR_OK
) {
2051 /* Clear watchpoint by clearing OBCR. */
2052 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OBCR
, 0);
2055 if (err
== ERROR_OK
)
2056 dsp563xx
->hardware_breakpoint
[0].used
= BPU_NONE
;
2061 COMMAND_HANDLER(dsp563xx_add_watchpoint_command
)
2064 struct target
*target
= get_current_target(CMD_CTX
);
2066 uint32_t mem_type
= 0;
2067 switch (CMD_NAME
[2]) {
2078 return ERROR_COMMAND_SYNTAX_ERROR
;
2082 return ERROR_COMMAND_SYNTAX_ERROR
;
2084 uint32_t address
= 0;
2086 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], address
);
2088 enum watchpoint_condition cond
;
2089 switch (CMD_ARGV
[0][0]) {
2103 return ERROR_COMMAND_SYNTAX_ERROR
;
2106 enum watchpoint_rw rw
;
2107 switch (CMD_ARGV
[1][0]) {
2118 return ERROR_COMMAND_SYNTAX_ERROR
;
2121 err
= dsp563xx_add_custom_watchpoint(target
, address
, mem_type
, rw
, cond
);
2126 /* Adding a breakpoint using the once breakpoint logic.
2127 * Note that this mechanism is a true hw breakpoint and is share between the watchpoint logic.
2128 * This means, you can only have one breakpoint/watchpoint at any time.
2130 static int dsp563xx_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
2132 return dsp563xx_add_custom_watchpoint(target
, breakpoint
->address
, MEM_P
, WPT_READ
, EQUAL
);
2135 static int dsp563xx_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
2137 return dsp563xx_remove_custom_watchpoint(target
);
2140 COMMAND_HANDLER(dsp563xx_remove_watchpoint_command
)
2142 struct target
*target
= get_current_target(CMD_CTX
);
2144 return dsp563xx_remove_custom_watchpoint(target
);
2147 COMMAND_HANDLER(dsp563xx_mem_command
)
2149 struct target
*target
= get_current_target(CMD_CTX
);
2152 uint32_t address
= 0;
2153 uint32_t count
= 1, i
;
2154 uint32_t pattern
= 0;
2156 uint8_t *buffer
, *b
;
2158 switch (CMD_NAME
[1]) {
2166 return ERROR_COMMAND_SYNTAX_ERROR
;
2169 switch (CMD_NAME
[3]) {
2180 return ERROR_COMMAND_SYNTAX_ERROR
;
2184 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
2186 if (read_mem
== 0) {
2188 return ERROR_COMMAND_SYNTAX_ERROR
;
2190 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], pattern
);
2192 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], count
);
2195 if (read_mem
== 1) {
2197 return ERROR_COMMAND_SYNTAX_ERROR
;
2199 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], count
);
2202 buffer
= calloc(count
, sizeof(uint32_t));
2204 if (read_mem
== 1) {
2205 err
= dsp563xx_read_memory(target
, mem_type
, address
, sizeof(uint32_t),
2207 if (err
== ERROR_OK
)
2208 handle_md_output(CMD_CTX
, target
, address
, sizeof(uint32_t), count
, buffer
);
2213 for (i
= 0; i
< count
; i
++) {
2214 target_buffer_set_u32(target
, b
, pattern
);
2218 err
= dsp563xx_write_memory(target
,
2231 static const struct command_registration dsp563xx_command_handlers
[] = {
2234 .handler
= dsp563xx_mem_command
,
2235 .mode
= COMMAND_EXEC
,
2236 .help
= "write x memory words",
2237 .usage
= "address value [count]",
2241 .handler
= dsp563xx_mem_command
,
2242 .mode
= COMMAND_EXEC
,
2243 .help
= "write y memory words",
2244 .usage
= "address value [count]",
2248 .handler
= dsp563xx_mem_command
,
2249 .mode
= COMMAND_EXEC
,
2250 .help
= "write p memory words",
2251 .usage
= "address value [count]",
2255 .handler
= dsp563xx_mem_command
,
2256 .mode
= COMMAND_EXEC
,
2257 .help
= "display x memory words",
2258 .usage
= "address [count]",
2262 .handler
= dsp563xx_mem_command
,
2263 .mode
= COMMAND_EXEC
,
2264 .help
= "display y memory words",
2265 .usage
= "address [count]",
2269 .handler
= dsp563xx_mem_command
,
2270 .mode
= COMMAND_EXEC
,
2271 .help
= "display p memory words",
2272 .usage
= "address [count]",
2275 * Watchpoint commands
2279 .handler
= dsp563xx_add_watchpoint_command
,
2280 .mode
= COMMAND_EXEC
,
2281 .help
= "Create p memspace watchpoint",
2282 .usage
= "(>|<|=|!) (r|w|a) address",
2286 .handler
= dsp563xx_add_watchpoint_command
,
2287 .mode
= COMMAND_EXEC
,
2288 .help
= "Create x memspace watchpoint",
2289 .usage
= "(>|<|=|!) (r|w|a) address",
2293 .handler
= dsp563xx_add_watchpoint_command
,
2294 .mode
= COMMAND_EXEC
,
2295 .help
= "Create y memspace watchpoint",
2296 .usage
= "(>|<|=|!) (r|w|a) address",
2300 .handler
= dsp563xx_remove_watchpoint_command
,
2301 .mode
= COMMAND_EXEC
,
2302 .help
= "remove watchpoint custom",
2305 COMMAND_REGISTRATION_DONE
2308 /** Holds methods for DSP563XX targets. */
2309 struct target_type dsp563xx_target
= {
2312 .poll
= dsp563xx_poll
,
2313 .arch_state
= dsp563xx_arch_state
,
2315 .get_gdb_reg_list
= dsp563xx_get_gdb_reg_list
,
2317 .halt
= dsp563xx_halt
,
2318 .resume
= dsp563xx_resume
,
2319 .step
= dsp563xx_step
,
2321 .assert_reset
= dsp563xx_assert_reset
,
2322 .deassert_reset
= dsp563xx_deassert_reset
,
2324 .read_memory
= dsp563xx_read_memory_default
,
2325 .write_memory
= dsp563xx_write_memory_default
,
2327 .read_buffer
= dsp563xx_read_buffer_default
,
2328 .write_buffer
= dsp563xx_write_buffer_default
,
2330 .run_algorithm
= dsp563xx_run_algorithm
,
2332 .add_breakpoint
= dsp563xx_add_breakpoint
,
2333 .remove_breakpoint
= dsp563xx_remove_breakpoint
,
2334 .add_watchpoint
= dsp563xx_add_watchpoint
,
2335 .remove_watchpoint
= dsp563xx_remove_watchpoint
,
2337 .commands
= dsp563xx_command_handlers
,
2338 .target_create
= dsp563xx_target_create
,
2339 .init_target
= dsp563xx_init_target
,
2340 .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)