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
[],
360 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
362 if (target
->state
!= TARGET_HALTED
)
363 return ERROR_TARGET_NOT_HALTED
;
365 *reg_list_size
= DSP563XX_NUMCOREREGS
;
366 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
369 return ERROR_COMMAND_SYNTAX_ERROR
;
371 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++)
372 (*reg_list
)[i
] = &dsp563xx
->core_cache
->reg_list
[gdb_reg_list_idx
[i
]];
378 static int dsp563xx_read_core_reg(struct target
*target
, int num
)
381 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
383 if ((num
< 0) || (num
>= DSP563XX_NUMCOREREGS
))
384 return ERROR_COMMAND_SYNTAX_ERROR
;
386 reg_value
= dsp563xx
->core_regs
[num
];
387 buf_set_u32(dsp563xx
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
388 dsp563xx
->core_cache
->reg_list
[num
].valid
= 1;
389 dsp563xx
->core_cache
->reg_list
[num
].dirty
= 0;
394 static int dsp563xx_write_core_reg(struct target
*target
, int num
)
397 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
399 if ((num
< 0) || (num
>= DSP563XX_NUMCOREREGS
))
400 return ERROR_COMMAND_SYNTAX_ERROR
;
402 reg_value
= buf_get_u32(dsp563xx
->core_cache
->reg_list
[num
].value
, 0, 32);
403 dsp563xx
->core_regs
[num
] = reg_value
;
404 dsp563xx
->core_cache
->reg_list
[num
].valid
= 1;
405 dsp563xx
->core_cache
->reg_list
[num
].dirty
= 0;
410 static int dsp563xx_get_core_reg(struct reg
*reg
)
412 struct dsp563xx_core_reg
*dsp563xx_reg
= reg
->arch_info
;
413 struct target
*target
= dsp563xx_reg
->target
;
414 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
416 LOG_DEBUG("%s", __func__
);
418 if (target
->state
!= TARGET_HALTED
)
419 return ERROR_TARGET_NOT_HALTED
;
421 return dsp563xx
->read_core_reg(target
, dsp563xx_reg
->num
);
424 static int dsp563xx_set_core_reg(struct reg
*reg
, uint8_t *buf
)
426 LOG_DEBUG("%s", __func__
);
428 struct dsp563xx_core_reg
*dsp563xx_reg
= reg
->arch_info
;
429 struct target
*target
= dsp563xx_reg
->target
;
430 uint32_t value
= buf_get_u32(buf
, 0, 32);
432 if (target
->state
!= TARGET_HALTED
)
433 return ERROR_TARGET_NOT_HALTED
;
435 buf_set_u32(reg
->value
, 0, reg
->size
, value
);
442 static const struct reg_arch_type dsp563xx_reg_type
= {
443 .get
= dsp563xx_get_core_reg
,
444 .set
= dsp563xx_set_core_reg
,
447 static void dsp563xx_build_reg_cache(struct target
*target
)
449 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
451 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
452 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
453 struct reg
*reg_list
= malloc(sizeof(struct reg
) * DSP563XX_NUMCOREREGS
);
454 struct dsp563xx_core_reg
*arch_info
= malloc(
455 sizeof(struct dsp563xx_core_reg
) * DSP563XX_NUMCOREREGS
);
458 /* Build the process context cache */
459 cache
->name
= "dsp563xx registers";
461 cache
->reg_list
= reg_list
;
462 cache
->num_regs
= DSP563XX_NUMCOREREGS
;
464 dsp563xx
->core_cache
= cache
;
466 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++) {
467 arch_info
[i
].num
= dsp563xx_regs
[i
].id
;
468 arch_info
[i
].name
= dsp563xx_regs
[i
].name
;
469 arch_info
[i
].size
= dsp563xx_regs
[i
].bits
;
470 arch_info
[i
].eame
= dsp563xx_regs
[i
].eame
;
471 arch_info
[i
].instr_mask
= dsp563xx_regs
[i
].instr_mask
;
472 arch_info
[i
].target
= target
;
473 arch_info
[i
].dsp563xx_common
= dsp563xx
;
474 reg_list
[i
].name
= dsp563xx_regs
[i
].name
;
475 reg_list
[i
].size
= 32; /* dsp563xx_regs[i].bits; */
476 reg_list
[i
].value
= calloc(1, 4);
477 reg_list
[i
].dirty
= 0;
478 reg_list
[i
].valid
= 0;
479 reg_list
[i
].type
= &dsp563xx_reg_type
;
480 reg_list
[i
].arch_info
= &arch_info
[i
];
484 static int dsp563xx_read_register(struct target
*target
, int num
, int force
);
485 static int dsp563xx_write_register(struct target
*target
, int num
, int force
);
487 static int dsp563xx_reg_read_high_io(struct target
*target
, uint32_t instr_mask
, uint32_t *data
)
491 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
493 /* we use r0 to store temporary data */
494 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
495 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
497 /* move source memory to r0 */
498 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 0, EAME_R0
, instr_mask
);
499 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, instr
);
502 /* move r0 to debug register */
503 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 1, EAME_R0
, 0xfffffc);
504 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 1, instr
);
507 /* read debug register */
508 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OGDBR
, data
);
511 /* r0 is no longer valid on target */
512 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= 1;
517 static int dsp563xx_reg_write_high_io(struct target
*target
, uint32_t instr_mask
, uint32_t data
)
521 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
523 /* we use r0 to store temporary data */
524 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
525 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
527 /* move data to r0 */
528 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 0, 0x60F400, data
);
531 /* move r0 to destination memory */
532 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 1, EAME_R0
, instr_mask
);
533 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 1, instr
);
537 /* r0 is no longer valid on target */
538 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= 1;
543 static int dsp563xx_reg_read(struct target
*target
, uint32_t eame
, uint32_t *data
)
548 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 1, eame
, 0xfffffc);
549 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, instr
);
553 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 1, 0x000000);
556 /* read debug register */
557 return dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OGDBR
, data
);
560 static int dsp563xx_reg_write(struct target
*target
, uint32_t instr_mask
, uint32_t data
)
564 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 0, instr_mask
, data
);
568 return dsp563xx_once_execute_sw_ir(target
->tap
, 1, 0x000000);
571 static int dsp563xx_reg_pc_read(struct target
*target
)
573 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
575 /* pc was changed, nothing todo */
576 if (dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].dirty
)
579 /* conditional branch check */
580 if (once_regs
[ONCE_REG_IDX_OPABDR
].reg
== once_regs
[ONCE_REG_IDX_OPABEX
].reg
) {
581 if ((once_regs
[ONCE_REG_IDX_OPABF11
].reg
& 1) == 0) {
582 LOG_DEBUG("%s conditional branch not supported yet (0x%x 0x%x 0x%x)",
584 (once_regs
[ONCE_REG_IDX_OPABF11
].reg
>> 1),
585 once_regs
[ONCE_REG_IDX_OPABDR
].reg
,
586 once_regs
[ONCE_REG_IDX_OPABEX
].reg
);
588 /* TODO: use disassembly to set correct pc offset
589 * read 2 words from OPABF11 and disasm the instruction
591 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] =
592 (once_regs
[ONCE_REG_IDX_OPABF11
].reg
>> 1) & 0x00FFFFFF;
594 if (once_regs
[ONCE_REG_IDX_OPABEX
].reg
==
595 once_regs
[ONCE_REG_IDX_OPABFR
].reg
)
596 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] =
597 once_regs
[ONCE_REG_IDX_OPABEX
].reg
;
599 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] =
600 once_regs
[ONCE_REG_IDX_OPABEX
].reg
- 1;
603 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] = once_regs
[ONCE_REG_IDX_OPABEX
].reg
;
605 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_PC
);
610 static int dsp563xx_reg_ssh_read(struct target
*target
)
614 struct dsp563xx_core_reg
*arch_info
;
615 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
617 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSH
].arch_info
;
619 /* get a valid stack pointer */
620 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 0);
623 sp
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
];
624 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SP
, 0);
628 /* get a valid stack count */
629 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SC
, 0);
633 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SC
, 0);
637 /* get a valid extended pointer */
638 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_EP
, 0);
642 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_EP
, 0);
649 err
= dsp563xx_reg_read(target
, arch_info
->eame
, &sp
);
653 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SC
, 1);
656 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SP
, 1);
659 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_EP
, 1);
664 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SSH
] = sp
;
665 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_SSH
);
670 static int dsp563xx_reg_ssh_write(struct target
*target
)
674 struct dsp563xx_core_reg
*arch_info
;
675 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
677 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSH
].arch_info
;
679 /* get a valid stack pointer */
680 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 0);
683 sp
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
];
687 /* write new stackpointer */
688 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
] = sp
;
689 err
= dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_SP
);
692 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SP
, 1);
696 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
,
697 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SSH
]);
701 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 1);
704 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SSH
, 1);
712 static int dsp563xx_reg_ssl_read(struct target
*target
)
716 struct dsp563xx_core_reg
*arch_info
;
717 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
719 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSL
].arch_info
;
721 /* get a valid stack pointer */
722 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 0);
725 sp
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
];
730 err
= dsp563xx_reg_read(target
, arch_info
->eame
, &sp
);
735 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SSL
] = sp
;
736 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_SSL
);
741 static int dsp563xx_read_register(struct target
*target
, int num
, int force
)
745 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
746 struct dsp563xx_core_reg
*arch_info
;
749 dsp563xx
->core_cache
->reg_list
[num
].valid
= 0;
751 if (!dsp563xx
->core_cache
->reg_list
[num
].valid
) {
752 arch_info
= dsp563xx
->core_cache
->reg_list
[num
].arch_info
;
754 switch (arch_info
->num
) {
755 case DSP563XX_REG_IDX_SSH
:
756 err
= dsp563xx_reg_ssh_read(target
);
758 case DSP563XX_REG_IDX_SSL
:
759 err
= dsp563xx_reg_ssl_read(target
);
761 case DSP563XX_REG_IDX_PC
:
762 err
= dsp563xx_reg_pc_read(target
);
764 case DSP563XX_REG_IDX_IPRC
:
765 case DSP563XX_REG_IDX_IPRP
:
766 case DSP563XX_REG_IDX_BCR
:
767 case DSP563XX_REG_IDX_DCR
:
768 case DSP563XX_REG_IDX_AAR0
:
769 case DSP563XX_REG_IDX_AAR1
:
770 case DSP563XX_REG_IDX_AAR2
:
771 case DSP563XX_REG_IDX_AAR3
:
772 err
= dsp563xx_reg_read_high_io(target
,
773 arch_info
->instr_mask
, &data
);
774 if (err
== ERROR_OK
) {
775 dsp563xx
->core_regs
[num
] = data
;
776 dsp563xx
->read_core_reg(target
, num
);
780 err
= dsp563xx_reg_read(target
, arch_info
->eame
, &data
);
781 if (err
== ERROR_OK
) {
782 dsp563xx
->core_regs
[num
] = data
;
783 dsp563xx
->read_core_reg(target
, num
);
792 static int dsp563xx_write_register(struct target
*target
, int num
, int force
)
795 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
796 struct dsp563xx_core_reg
*arch_info
;
799 dsp563xx
->core_cache
->reg_list
[num
].dirty
= 1;
801 if (dsp563xx
->core_cache
->reg_list
[num
].dirty
) {
802 arch_info
= dsp563xx
->core_cache
->reg_list
[num
].arch_info
;
804 dsp563xx
->write_core_reg(target
, num
);
806 switch (arch_info
->num
) {
807 case DSP563XX_REG_IDX_SSH
:
808 err
= dsp563xx_reg_ssh_write(target
);
810 case DSP563XX_REG_IDX_PC
:
811 /* pc is updated on resume, no need to write it here */
813 case DSP563XX_REG_IDX_IPRC
:
814 case DSP563XX_REG_IDX_IPRP
:
815 case DSP563XX_REG_IDX_BCR
:
816 case DSP563XX_REG_IDX_DCR
:
817 case DSP563XX_REG_IDX_AAR0
:
818 case DSP563XX_REG_IDX_AAR1
:
819 case DSP563XX_REG_IDX_AAR2
:
820 case DSP563XX_REG_IDX_AAR3
:
821 err
= dsp563xx_reg_write_high_io(target
,
822 arch_info
->instr_mask
,
823 dsp563xx
->core_regs
[num
]);
826 err
= dsp563xx_reg_write(target
,
827 arch_info
->instr_mask
,
828 dsp563xx
->core_regs
[num
]);
830 if ((err
== ERROR_OK
) && (arch_info
->num
== DSP563XX_REG_IDX_SP
)) {
831 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSH
].valid
=
833 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSL
].valid
=
844 static int dsp563xx_save_context(struct target
*target
)
846 int i
, err
= ERROR_OK
;
848 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++) {
849 err
= dsp563xx_read_register(target
, i
, 0);
857 static int dsp563xx_restore_context(struct target
*target
)
859 int i
, err
= ERROR_OK
;
861 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++) {
862 err
= dsp563xx_write_register(target
, i
, 0);
870 static void dsp563xx_invalidate_x_context(struct target
*target
,
875 struct dsp563xx_core_reg
*arch_info
;
876 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
878 if (addr_start
> ASM_REG_W_IPRC
)
880 if (addr_start
< ASM_REG_W_AAR3
)
883 for (i
= DSP563XX_REG_IDX_IPRC
; i
< DSP563XX_NUMCOREREGS
; i
++) {
884 arch_info
= dsp563xx
->core_cache
->reg_list
[i
].arch_info
;
886 if ((arch_info
->instr_mask
>= addr_start
) &&
887 (arch_info
->instr_mask
<= addr_end
)) {
888 dsp563xx
->core_cache
->reg_list
[i
].valid
= 0;
889 dsp563xx
->core_cache
->reg_list
[i
].dirty
= 0;
894 static int dsp563xx_target_create(struct target
*target
, Jim_Interp
*interp
)
896 struct dsp563xx_common
*dsp563xx
= calloc(1, sizeof(struct dsp563xx_common
));
899 return ERROR_COMMAND_SYNTAX_ERROR
;
901 dsp563xx
->jtag_info
.tap
= target
->tap
;
902 target
->arch_info
= dsp563xx
;
903 dsp563xx
->read_core_reg
= dsp563xx_read_core_reg
;
904 dsp563xx
->write_core_reg
= dsp563xx_write_core_reg
;
909 static int dsp563xx_init_target(struct command_context
*cmd_ctx
, struct target
*target
)
911 LOG_DEBUG("%s", __func__
);
913 dsp563xx_build_reg_cache(target
);
914 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
916 dsp563xx
->hardware_breakpoints_cleared
= 0;
917 dsp563xx
->hardware_breakpoint
[0].used
= BPU_NONE
;
922 static int dsp563xx_examine(struct target
*target
)
926 if (target
->tap
->hasidcode
== false) {
927 LOG_ERROR("no IDCODE present on device");
928 return ERROR_COMMAND_SYNTAX_ERROR
;
931 if (!target_was_examined(target
)) {
932 target_set_examined(target
);
934 /* examine core and chip derivate number */
935 chip
= (target
->tap
->idcode
>>12) & 0x3ff;
936 /* core number 0 means DSP563XX */
937 if (((chip
>>5)&0x1f) == 0)
940 LOG_INFO("DSP56%03d device found", chip
);
942 /* Clear all breakpoints */
943 dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OBCR
, 0);
949 static int dsp563xx_arch_state(struct target
*target
)
951 LOG_DEBUG("%s", __func__
);
955 #define DSP563XX_SR_SA (1<<17)
956 #define DSP563XX_SR_SC (1<<13)
958 static int dsp563xx_debug_once_init(struct target
*target
)
960 return dsp563xx_once_read_register(target
->tap
, 1, once_regs
, DSP563XX_NUMONCEREGS
);
963 static int dsp563xx_debug_init(struct target
*target
)
967 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
968 struct dsp563xx_core_reg
*arch_info
;
970 err
= dsp563xx_debug_once_init(target
);
974 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SR
].arch_info
;
976 /* check 24bit mode */
977 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SR
, 0);
981 sr
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SR
];
983 if (sr
& (DSP563XX_SR_SA
| DSP563XX_SR_SC
)) {
984 sr
&= ~(DSP563XX_SR_SA
| DSP563XX_SR_SC
);
986 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, arch_info
->instr_mask
, sr
);
989 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SR
].dirty
= 1;
992 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_N0
, 0);
995 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_N1
, 0);
998 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_M0
, 0);
1001 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_M1
, 0);
1002 if (err
!= ERROR_OK
)
1005 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_N0
] != 0x000000) {
1006 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N0
].arch_info
;
1007 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0x000000);
1008 if (err
!= ERROR_OK
)
1011 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N0
].dirty
= 1;
1013 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_N1
] != 0x000000) {
1014 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N1
].arch_info
;
1015 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0x000000);
1016 if (err
!= ERROR_OK
)
1019 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N1
].dirty
= 1;
1021 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_M0
] != 0xffffff) {
1022 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M0
].arch_info
;
1023 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0xffffff);
1024 if (err
!= ERROR_OK
)
1027 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M0
].dirty
= 1;
1029 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_M1
] != 0xffffff) {
1030 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M1
].arch_info
;
1031 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0xffffff);
1032 if (err
!= ERROR_OK
)
1035 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M1
].dirty
= 1;
1037 err
= dsp563xx_save_context(target
);
1038 if (err
!= ERROR_OK
)
1044 static int dsp563xx_jtag_debug_request(struct target
*target
)
1046 return dsp563xx_once_request_debug(target
->tap
, target
->state
== TARGET_RESET
);
1049 static int dsp563xx_poll(struct target
*target
)
1052 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1053 uint32_t once_status
= 0;
1056 state
= dsp563xx_once_target_status(target
->tap
);
1058 if (state
== TARGET_UNKNOWN
) {
1059 target
->state
= state
;
1060 LOG_ERROR("jtag status contains invalid mode value - communication failure");
1061 return ERROR_TARGET_FAILURE
;
1064 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OSCR
, &once_status
);
1065 if (err
!= ERROR_OK
)
1068 if ((once_status
& DSP563XX_ONCE_OSCR_DEBUG_M
) == DSP563XX_ONCE_OSCR_DEBUG_M
) {
1069 if (target
->state
!= TARGET_HALTED
) {
1070 target
->state
= TARGET_HALTED
;
1072 err
= dsp563xx_debug_init(target
);
1073 if (err
!= ERROR_OK
)
1076 if (once_status
& (DSP563XX_ONCE_OSCR_MBO
|DSP563XX_ONCE_OSCR_SWO
))
1077 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
1079 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1081 LOG_DEBUG("target->state: %s (%x)", target_state_name(target
), once_status
);
1082 LOG_INFO("halted: PC: 0x%x", dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
]);
1086 if (!dsp563xx
->hardware_breakpoints_cleared
) {
1087 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OBCR
, 0);
1088 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR0
, 0);
1089 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR1
, 0);
1090 dsp563xx
->hardware_breakpoints_cleared
= 1;
1096 static int dsp563xx_halt(struct target
*target
)
1100 LOG_DEBUG("%s", __func__
);
1102 if (target
->state
== TARGET_HALTED
) {
1103 LOG_DEBUG("target was already halted");
1107 if (target
->state
== TARGET_UNKNOWN
)
1108 LOG_WARNING("target was in unknown state when halt was requested");
1110 err
= dsp563xx_jtag_debug_request(target
);
1111 if (err
!= ERROR_OK
)
1114 target
->debug_reason
= DBG_REASON_DBGRQ
;
1119 static int dsp563xx_resume(struct target
*target
,
1122 int handle_breakpoints
,
1123 int debug_execution
)
1126 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1128 /* check if pc was changed and resume want to execute the next address
1129 * if pc was changed from gdb or other interface we will
1130 * jump to this address and don't execute the next address
1131 * this will not affect the resume command with an address argument
1132 * because current is set to zero then
1134 if (current
&& dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].dirty
) {
1135 dsp563xx_write_core_reg(target
, DSP563XX_REG_IDX_PC
);
1136 address
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
];
1140 LOG_DEBUG("%s %08X %08X", __func__
, current
, (unsigned) address
);
1142 err
= dsp563xx_restore_context(target
);
1143 if (err
!= ERROR_OK
)
1145 register_cache_invalidate(dsp563xx
->core_cache
);
1148 /* restore pipeline registers and go */
1149 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
,
1150 once_regs
[ONCE_REG_IDX_OPILR
].reg
);
1151 if (err
!= ERROR_OK
)
1153 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
|
1154 DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
,
1155 once_regs
[ONCE_REG_IDX_OPDBR
].reg
);
1156 if (err
!= ERROR_OK
)
1159 /* set to go register and jump */
1160 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
, INSTR_JUMP
);
1161 if (err
!= ERROR_OK
)
1163 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_PDBGOTO
|
1164 DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
, address
);
1165 if (err
!= ERROR_OK
)
1169 target
->state
= TARGET_RUNNING
;
1171 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1176 static int dsp563xx_step_ex(struct target
*target
,
1179 int handle_breakpoints
,
1183 uint32_t once_status
;
1184 uint32_t dr_in
, cnt
;
1185 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1187 if (target
->state
!= TARGET_HALTED
) {
1188 LOG_DEBUG("target was not halted");
1192 /* check if pc was changed and step want to execute the next address
1193 * if pc was changed from gdb or other interface we will
1194 * jump to this address and don't execute the next address
1195 * this will not affect the step command with an address argument
1196 * because current is set to zero then
1198 if (current
&& dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].dirty
) {
1199 dsp563xx_write_core_reg(target
, DSP563XX_REG_IDX_PC
);
1200 address
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
];
1204 LOG_DEBUG("%s %08X %08X", __func__
, current
, (unsigned) address
);
1206 err
= dsp563xx_jtag_debug_request(target
);
1207 if (err
!= ERROR_OK
)
1209 err
= dsp563xx_restore_context(target
);
1210 if (err
!= ERROR_OK
)
1213 /* reset trace mode */
1214 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OSCR
, 0x000000);
1215 if (err
!= ERROR_OK
)
1217 /* enable trace mode */
1218 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OSCR
, DSP563XX_ONCE_OSCR_TME
);
1219 if (err
!= ERROR_OK
)
1224 /* on JUMP we need one extra cycle */
1228 /* load step counter with N-1 */
1229 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OTC
, cnt
);
1230 if (err
!= ERROR_OK
)
1234 /* restore pipeline registers and go */
1235 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
,
1236 once_regs
[ONCE_REG_IDX_OPILR
].reg
);
1237 if (err
!= ERROR_OK
)
1239 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
|
1240 DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
,
1241 once_regs
[ONCE_REG_IDX_OPDBR
].reg
);
1242 if (err
!= ERROR_OK
)
1245 /* set to go register and jump */
1246 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
, INSTR_JUMP
);
1247 if (err
!= ERROR_OK
)
1249 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_PDBGOTO
|
1250 DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
,
1252 if (err
!= ERROR_OK
)
1257 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OSCR
, &once_status
);
1258 if (err
!= ERROR_OK
)
1261 if (once_status
& DSP563XX_ONCE_OSCR_TO
) {
1262 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OPABFR
, &dr_in
);
1263 if (err
!= ERROR_OK
)
1265 LOG_DEBUG("fetch: %08X", (unsigned) dr_in
&0x00ffffff);
1266 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OPABDR
, &dr_in
);
1267 if (err
!= ERROR_OK
)
1269 LOG_DEBUG("decode: %08X", (unsigned) dr_in
&0x00ffffff);
1270 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OPABEX
, &dr_in
);
1271 if (err
!= ERROR_OK
)
1273 LOG_DEBUG("execute: %08X", (unsigned) dr_in
&0x00ffffff);
1275 /* reset trace mode */
1276 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OSCR
, 0x000000);
1277 if (err
!= ERROR_OK
)
1280 register_cache_invalidate(dsp563xx
->core_cache
);
1281 err
= dsp563xx_debug_init(target
);
1282 if (err
!= ERROR_OK
)
1292 static int dsp563xx_step(struct target
*target
,
1295 int handle_breakpoints
)
1298 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1300 if (target
->state
!= TARGET_HALTED
) {
1301 LOG_WARNING("target not halted");
1302 return ERROR_TARGET_NOT_HALTED
;
1305 err
= dsp563xx_step_ex(target
, current
, address
, handle_breakpoints
, 0);
1306 if (err
!= ERROR_OK
)
1309 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1310 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1312 LOG_INFO("halted: PC: 0x%x", dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
]);
1317 static int dsp563xx_assert_reset(struct target
*target
)
1320 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1321 enum reset_types jtag_reset_config
= jtag_get_reset_config();
1323 if (jtag_reset_config
& RESET_HAS_SRST
) {
1324 /* default to asserting srst */
1325 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
1326 jtag_add_reset(1, 1);
1328 jtag_add_reset(0, 1);
1331 target
->state
= TARGET_RESET
;
1332 jtag_add_sleep(5000);
1334 /* registers are now invalid */
1335 register_cache_invalidate(dsp563xx
->core_cache
);
1337 if (target
->reset_halt
) {
1338 retval
= target_halt(target
);
1339 if (retval
!= ERROR_OK
)
1343 LOG_DEBUG("%s", __func__
);
1347 static int dsp563xx_deassert_reset(struct target
*target
)
1351 /* deassert reset lines */
1352 jtag_add_reset(0, 0);
1354 err
= dsp563xx_poll(target
);
1355 if (err
!= ERROR_OK
)
1358 if (target
->reset_halt
) {
1359 if (target
->state
== TARGET_HALTED
) {
1360 /* after a reset the cpu jmp to the
1361 * reset vector and need 2 cycles to fill
1362 * the cache (fetch,decode,excecute)
1364 err
= dsp563xx_step_ex(target
, 1, 0, 1, 1);
1365 if (err
!= ERROR_OK
)
1369 target
->state
= TARGET_RUNNING
;
1371 LOG_DEBUG("%s", __func__
);
1375 static int dsp563xx_soft_reset_halt(struct target
*target
)
1377 LOG_DEBUG("%s", __func__
);
1381 static int dsp563xx_run_algorithm(struct target
*target
,
1382 int num_mem_params
, struct mem_param
*mem_params
,
1383 int num_reg_params
, struct reg_param
*reg_params
,
1384 uint32_t entry_point
, uint32_t exit_point
,
1385 int timeout_ms
, void *arch_info
)
1388 int retval
= ERROR_OK
;
1389 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1391 if (target
->state
!= TARGET_HALTED
) {
1392 LOG_WARNING("target not halted");
1393 return ERROR_TARGET_NOT_HALTED
;
1396 for (i
= 0; i
< num_mem_params
; i
++) {
1397 retval
= target_write_buffer(target
, mem_params
[i
].address
,
1398 mem_params
[i
].size
, mem_params
[i
].value
);
1399 if (retval
!= ERROR_OK
)
1403 for (i
= 0; i
< num_reg_params
; i
++) {
1404 struct reg
*reg
= register_get_by_name(dsp563xx
->core_cache
,
1405 reg_params
[i
].reg_name
,
1409 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
1413 if (reg
->size
!= reg_params
[i
].size
) {
1414 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1415 reg_params
[i
].reg_name
);
1419 retval
= dsp563xx_set_core_reg(reg
, reg_params
[i
].value
);
1420 if (retval
!= ERROR_OK
)
1425 retval
= target_resume(target
, 0, entry_point
, 1, 1);
1426 if (retval
!= ERROR_OK
)
1429 retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
);
1430 if (retval
!= ERROR_OK
)
1433 for (i
= 0; i
< num_mem_params
; i
++) {
1434 if (mem_params
[i
].direction
!= PARAM_OUT
)
1435 retval
= target_read_buffer(target
,
1436 mem_params
[i
].address
,
1438 mem_params
[i
].value
);
1439 if (retval
!= ERROR_OK
)
1443 for (i
= 0; i
< num_reg_params
; i
++) {
1444 if (reg_params
[i
].direction
!= PARAM_OUT
) {
1446 struct reg
*reg
= register_get_by_name(dsp563xx
->core_cache
,
1447 reg_params
[i
].reg_name
,
1450 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
1454 if (reg
->size
!= reg_params
[i
].size
) {
1456 "BUG: register '%s' size doesn't match reg_params[i].size",
1457 reg_params
[i
].reg_name
);
1461 buf_set_u32(reg_params
[i
].value
, 0, 32, buf_get_u32(reg
->value
, 0, 32));
1468 /* global command context from openocd.c */
1469 extern struct command_context
*global_cmd_ctx
;
1471 static int dsp563xx_get_default_memory(void)
1477 if (!global_cmd_ctx
)
1480 interp
= global_cmd_ctx
->interp
;
1485 memspace
= Jim_GetGlobalVariableStr(interp
, "memspace", JIM_NONE
);
1490 c
= (char *)Jim_GetString(memspace
, NULL
);
1509 static int dsp563xx_read_memory_core(struct target
*target
,
1517 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1519 uint32_t data
, move_cmd
= 0;
1523 "memtype: %d address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
1529 if (target
->state
!= TARGET_HALTED
) {
1530 LOG_WARNING("target not halted");
1531 return ERROR_TARGET_NOT_HALTED
;
1536 /* TODO: mark effected queued registers */
1537 move_cmd
= 0x61d800;
1540 move_cmd
= 0x69d800;
1543 move_cmd
= 0x07d891;
1546 return ERROR_COMMAND_SYNTAX_ERROR
;
1549 /* we use r0 to store temporary data */
1550 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
1551 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
1552 /* we use r1 to store temporary data */
1553 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].valid
)
1554 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R1
);
1556 /* r0 is no longer valid on target */
1557 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= 1;
1558 /* r1 is no longer valid on target */
1559 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].dirty
= 1;
1564 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, 0x60F400, address
);
1565 if (err
!= ERROR_OK
)
1568 for (i
= 0; i
< x
; i
++) {
1569 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, move_cmd
);
1570 if (err
!= ERROR_OK
)
1572 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, 0x08D13C);
1573 if (err
!= ERROR_OK
)
1575 err
= dsp563xx_once_reg_read(target
->tap
, 0,
1576 DSP563XX_ONCE_OGDBR
, (uint32_t *)(void *)b
);
1577 if (err
!= ERROR_OK
)
1582 /* flush the jtag queue */
1583 err
= jtag_execute_queue();
1584 if (err
!= ERROR_OK
)
1587 /* walk over the buffer and fix target endianness */
1590 for (i
= 0; i
< x
; i
++) {
1591 data
= buf_get_u32(b
, 0, 32) & 0x00FFFFFF;
1592 /* LOG_DEBUG("R: %08X", *((uint32_t*)b)); */
1593 target_buffer_set_u32(target
, b
, data
);
1600 static int dsp563xx_read_memory(struct target
*target
,
1609 uint8_t *buffer_y
, *buffer_x
;
1611 /* if size equals zero we are called from target read memory
1612 * and have to handle the parameter here */
1613 if ((size
== 0) && (count
!= 0)) {
1617 LOG_DEBUG("size is not aligned to 4 byte");
1619 count
= (count
- size
) / 4;
1623 /* we only support 4 byte aligned data */
1624 if ((size
!= 4) || (!count
))
1625 return ERROR_COMMAND_SYNTAX_ERROR
;
1627 if (mem_type
!= MEM_L
)
1628 return dsp563xx_read_memory_core(target
, mem_type
, address
, size
, count
, buffer
);
1630 buffer_y
= malloc(size
* count
);
1632 return ERROR_COMMAND_SYNTAX_ERROR
;
1634 buffer_x
= malloc(size
* count
);
1637 return ERROR_COMMAND_SYNTAX_ERROR
;
1640 err
= dsp563xx_read_memory_core(target
, MEM_Y
, address
, size
, count
/ 2, buffer_y
);
1642 if (err
!= ERROR_OK
) {
1648 err
= dsp563xx_read_memory_core(target
, MEM_X
, address
, size
, count
/ 2, buffer_x
);
1650 if (err
!= ERROR_OK
) {
1656 for (i
= 0, i1
= 0; i
< count
; i
+= 2, i1
++) {
1657 buf_set_u32(buffer
+ i
*sizeof(uint32_t), 0, 32,
1658 buf_get_u32(buffer_y
+ i1
* sizeof(uint32_t), 0, 32));
1659 buf_set_u32(buffer
+ (i
+ 1) * sizeof(uint32_t), 0, 32,
1660 buf_get_u32(buffer_x
+ i1
* sizeof(uint32_t), 0, 32));
1669 static int dsp563xx_read_memory_default(struct target
*target
,
1676 return dsp563xx_read_memory(target
,
1677 dsp563xx_get_default_memory(), address
, size
, count
, buffer
);
1680 static int dsp563xx_read_buffer_default(struct target
*target
,
1686 return dsp563xx_read_memory(target
, dsp563xx_get_default_memory(), address
, size
, 0,
1690 static int dsp563xx_write_memory_core(struct target
*target
,
1695 const uint8_t *buffer
)
1698 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1700 uint32_t data
, move_cmd
= 0;
1704 "memtype: %d address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
1710 if (target
->state
!= TARGET_HALTED
) {
1711 LOG_WARNING("target not halted");
1712 return ERROR_TARGET_NOT_HALTED
;
1717 /* invalidate affected x registers */
1718 dsp563xx_invalidate_x_context(target
, address
, address
+ count
- 1);
1719 move_cmd
= 0x615800;
1722 move_cmd
= 0x695800;
1725 move_cmd
= 0x075891;
1728 return ERROR_COMMAND_SYNTAX_ERROR
;
1731 /* we use r0 to store temporary data */
1732 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
1733 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
1734 /* we use r1 to store temporary data */
1735 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].valid
)
1736 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R1
);
1738 /* r0 is no longer valid on target */
1739 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= 1;
1740 /* r1 is no longer valid on target */
1741 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].dirty
= 1;
1746 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, 0x60F400, address
);
1747 if (err
!= ERROR_OK
)
1750 for (i
= 0; i
< x
; i
++) {
1751 data
= target_buffer_get_u32(target
, b
);
1753 /* LOG_DEBUG("W: %08X", data); */
1757 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 0, 0x61F400, data
);
1758 if (err
!= ERROR_OK
)
1760 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, move_cmd
);
1761 if (err
!= ERROR_OK
)
1766 /* flush the jtag queue */
1767 err
= jtag_execute_queue();
1768 if (err
!= ERROR_OK
)
1774 static int dsp563xx_write_memory(struct target
*target
,
1779 const uint8_t *buffer
)
1783 uint8_t *buffer_y
, *buffer_x
;
1785 /* if size equals zero we are called from target write memory
1786 * and have to handle the parameter here */
1787 if ((size
== 0) && (count
!= 0)) {
1791 LOG_DEBUG("size is not aligned to 4 byte");
1793 count
= (count
- size
) / 4;
1797 /* we only support 4 byte aligned data */
1798 if ((size
!= 4) || (!count
))
1799 return ERROR_COMMAND_SYNTAX_ERROR
;
1801 if (mem_type
!= MEM_L
)
1802 return dsp563xx_write_memory_core(target
, mem_type
, address
, size
, count
, buffer
);
1804 buffer_y
= malloc(size
* count
);
1806 return ERROR_COMMAND_SYNTAX_ERROR
;
1808 buffer_x
= malloc(size
* count
);
1811 return ERROR_COMMAND_SYNTAX_ERROR
;
1814 for (i
= 0, i1
= 0; i
< count
; i
+= 2, i1
++) {
1815 buf_set_u32(buffer_y
+ i1
* sizeof(uint32_t), 0, 32,
1816 buf_get_u32(buffer
+ i
* sizeof(uint32_t), 0, 32));
1817 buf_set_u32(buffer_x
+ i1
* sizeof(uint32_t), 0, 32,
1818 buf_get_u32(buffer
+ (i
+ 1) * sizeof(uint32_t), 0, 32));
1821 err
= dsp563xx_write_memory_core(target
, MEM_Y
, address
, size
, count
/ 2, buffer_y
);
1823 if (err
!= ERROR_OK
) {
1829 err
= dsp563xx_write_memory_core(target
, MEM_X
, address
, size
, count
/ 2, buffer_x
);
1831 if (err
!= ERROR_OK
) {
1843 static int dsp563xx_write_memory_default(struct target
*target
,
1847 const uint8_t *buffer
)
1849 return dsp563xx_write_memory(target
,
1850 dsp563xx_get_default_memory(), address
, size
, count
, buffer
);
1853 static int dsp563xx_write_buffer_default(struct target
*target
,
1856 const uint8_t *buffer
)
1858 return dsp563xx_write_memory(target
, dsp563xx_get_default_memory(), address
, size
, 0,
1863 * Exit with error here, because we support watchpoints over a custom command.
1864 * This is because the DSP has separate X,Y,P memspace which is not compatible to the
1865 * traditional watchpoint logic.
1867 static int dsp563xx_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1869 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1873 * @see dsp563xx_add_watchpoint
1875 static int dsp563xx_remove_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1877 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1880 static void handle_md_output(struct command_context
*cmd_ctx
,
1881 struct target
*target
,
1885 const uint8_t *buffer
)
1887 const unsigned line_bytecnt
= 32;
1888 unsigned line_modulo
= line_bytecnt
/ size
;
1890 char output
[line_bytecnt
* 4 + 1];
1891 unsigned output_len
= 0;
1893 const char *value_fmt
;
1896 value_fmt
= "%8.8x ";
1899 value_fmt
= "%4.4x ";
1902 value_fmt
= "%2.2x ";
1905 /* "can't happen", caller checked */
1906 LOG_ERROR("invalid memory read size: %u", size
);
1910 for (unsigned i
= 0; i
< count
; i
++) {
1911 if (i
% line_modulo
== 0)
1912 output_len
+= snprintf(output
+ output_len
,
1913 sizeof(output
) - output_len
,
1915 (unsigned) (address
+ i
));
1918 const uint8_t *value_ptr
= buffer
+ i
* size
;
1921 value
= target_buffer_get_u32(target
, value_ptr
);
1924 value
= target_buffer_get_u16(target
, value_ptr
);
1929 output_len
+= snprintf(output
+ output_len
,
1930 sizeof(output
) - output_len
,
1934 if ((i
% line_modulo
== line_modulo
- 1) || (i
== count
- 1)) {
1935 command_print(cmd_ctx
, "%s", output
);
1941 static int dsp563xx_add_custom_watchpoint(struct target
*target
, uint32_t address
, uint32_t memType
,
1942 enum watchpoint_rw rw
, enum watchpoint_condition cond
)
1945 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1947 bool wasRunning
= false;
1948 /* Only set breakpoint when halted */
1949 if (target
->state
!= TARGET_HALTED
) {
1950 dsp563xx_halt(target
);
1954 if (dsp563xx
->hardware_breakpoint
[0].used
) {
1955 LOG_ERROR("Cannot add watchpoint. Hardware resource already used.");
1956 err
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1959 uint32_t obcr_value
= 0;
1960 if (err
== ERROR_OK
) {
1961 obcr_value
|= OBCR_b0_or_b1
;
1964 obcr_value
|= OBCR_BP_MEM_X
;
1967 obcr_value
|= OBCR_BP_MEM_Y
;
1970 obcr_value
|= OBCR_BP_MEM_P
;
1973 LOG_ERROR("Unknown memType parameter (%d)", memType
);
1974 err
= ERROR_TARGET_INVALID
;
1978 if (err
== ERROR_OK
) {
1981 obcr_value
|= OBCR_BP_0(OBCR_BP_ON_READ
);
1984 obcr_value
|= OBCR_BP_0(OBCR_BP_ON_WRITE
);
1987 obcr_value
|= OBCR_BP_0(OBCR_BP_ON_READ
|OBCR_BP_ON_WRITE
);
1990 LOG_ERROR("Unsupported write mode (%d)", rw
);
1991 err
= ERROR_TARGET_INVALID
;
1995 if (err
== ERROR_OK
) {
1998 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_EQUAL
);
2001 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_NOT_EQUAL
);
2004 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_LESS_THAN
);
2007 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_GREATER_THAN
);
2010 LOG_ERROR("Unsupported condition code (%d)", cond
);
2011 err
= ERROR_TARGET_INVALID
;
2015 if (err
== ERROR_OK
)
2016 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR0
, address
);
2018 if (err
== ERROR_OK
)
2019 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR1
, 0x0);
2021 if (err
== ERROR_OK
)
2022 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OBCR
, obcr_value
);
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_OMBC
, 0);
2029 if (err
== ERROR_OK
) {
2030 /* You should write the memory breakpoint counter to 0 */
2031 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OTC
, 0);
2034 if (err
== ERROR_OK
)
2035 dsp563xx
->hardware_breakpoint
[0].used
= BPU_WATCHPOINT
;
2037 if (err
== ERROR_OK
&& wasRunning
) {
2038 /* Resume from current PC */
2039 err
= dsp563xx_resume(target
, 1, 0x0, 0, 0);
2045 static int dsp563xx_remove_custom_watchpoint(struct target
*target
)
2048 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
2050 if (dsp563xx
->hardware_breakpoint
[0].used
!= BPU_WATCHPOINT
) {
2051 LOG_ERROR("Cannot remove watchpoint, as no watchpoint is currently configured!");
2052 err
= ERROR_TARGET_INVALID
;
2055 if (err
== ERROR_OK
) {
2056 /* Clear watchpoint by clearing OBCR. */
2057 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OBCR
, 0);
2060 if (err
== ERROR_OK
)
2061 dsp563xx
->hardware_breakpoint
[0].used
= BPU_NONE
;
2066 COMMAND_HANDLER(dsp563xx_add_watchpoint_command
)
2069 struct target
*target
= get_current_target(CMD_CTX
);
2071 uint32_t mem_type
= 0;
2072 switch (CMD_NAME
[2]) {
2083 return ERROR_COMMAND_SYNTAX_ERROR
;
2087 return ERROR_COMMAND_SYNTAX_ERROR
;
2089 uint32_t address
= 0;
2091 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], address
);
2093 enum watchpoint_condition cond
;
2094 switch (CMD_ARGV
[0][0]) {
2108 return ERROR_COMMAND_SYNTAX_ERROR
;
2111 enum watchpoint_rw rw
;
2112 switch (CMD_ARGV
[1][0]) {
2123 return ERROR_COMMAND_SYNTAX_ERROR
;
2126 err
= dsp563xx_add_custom_watchpoint(target
, address
, mem_type
, rw
, cond
);
2131 /* Adding a breakpoint using the once breakpoint logic.
2132 * Note that this mechanism is a true hw breakpoint and is share between the watchpoint logic.
2133 * This means, you can only have one breakpoint/watchpoint at any time.
2135 static int dsp563xx_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
2137 return dsp563xx_add_custom_watchpoint(target
, breakpoint
->address
, MEM_P
, WPT_READ
, EQUAL
);
2140 static int dsp563xx_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
2142 return dsp563xx_remove_custom_watchpoint(target
);
2145 COMMAND_HANDLER(dsp563xx_remove_watchpoint_command
)
2147 struct target
*target
= get_current_target(CMD_CTX
);
2149 return dsp563xx_remove_custom_watchpoint(target
);
2152 COMMAND_HANDLER(dsp563xx_mem_command
)
2154 struct target
*target
= get_current_target(CMD_CTX
);
2157 uint32_t address
= 0;
2158 uint32_t count
= 1, i
;
2159 uint32_t pattern
= 0;
2161 uint8_t *buffer
, *b
;
2163 switch (CMD_NAME
[1]) {
2171 return ERROR_COMMAND_SYNTAX_ERROR
;
2174 switch (CMD_NAME
[3]) {
2185 return ERROR_COMMAND_SYNTAX_ERROR
;
2189 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
2191 if (read_mem
== 0) {
2193 return ERROR_COMMAND_SYNTAX_ERROR
;
2195 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], pattern
);
2197 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], count
);
2200 if (read_mem
== 1) {
2202 return ERROR_COMMAND_SYNTAX_ERROR
;
2204 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], count
);
2207 buffer
= calloc(count
, sizeof(uint32_t));
2209 if (read_mem
== 1) {
2210 err
= dsp563xx_read_memory(target
, mem_type
, address
, sizeof(uint32_t),
2212 if (err
== ERROR_OK
)
2213 handle_md_output(CMD_CTX
, target
, address
, sizeof(uint32_t), count
, buffer
);
2218 for (i
= 0; i
< count
; i
++) {
2219 target_buffer_set_u32(target
, b
, pattern
);
2223 err
= dsp563xx_write_memory(target
,
2236 static const struct command_registration dsp563xx_command_handlers
[] = {
2239 .handler
= dsp563xx_mem_command
,
2240 .mode
= COMMAND_EXEC
,
2241 .help
= "write x memory words",
2242 .usage
= "address value [count]",
2246 .handler
= dsp563xx_mem_command
,
2247 .mode
= COMMAND_EXEC
,
2248 .help
= "write y memory words",
2249 .usage
= "address value [count]",
2253 .handler
= dsp563xx_mem_command
,
2254 .mode
= COMMAND_EXEC
,
2255 .help
= "write p memory words",
2256 .usage
= "address value [count]",
2260 .handler
= dsp563xx_mem_command
,
2261 .mode
= COMMAND_EXEC
,
2262 .help
= "display x memory words",
2263 .usage
= "address [count]",
2267 .handler
= dsp563xx_mem_command
,
2268 .mode
= COMMAND_EXEC
,
2269 .help
= "display y memory words",
2270 .usage
= "address [count]",
2274 .handler
= dsp563xx_mem_command
,
2275 .mode
= COMMAND_EXEC
,
2276 .help
= "display p memory words",
2277 .usage
= "address [count]",
2280 * Watchpoint commands
2284 .handler
= dsp563xx_add_watchpoint_command
,
2285 .mode
= COMMAND_EXEC
,
2286 .help
= "Create p memspace watchpoint",
2287 .usage
= "(>|<|=|!) (r|w|a) address",
2291 .handler
= dsp563xx_add_watchpoint_command
,
2292 .mode
= COMMAND_EXEC
,
2293 .help
= "Create x memspace watchpoint",
2294 .usage
= "(>|<|=|!) (r|w|a) address",
2298 .handler
= dsp563xx_add_watchpoint_command
,
2299 .mode
= COMMAND_EXEC
,
2300 .help
= "Create y memspace watchpoint",
2301 .usage
= "(>|<|=|!) (r|w|a) address",
2305 .handler
= dsp563xx_remove_watchpoint_command
,
2306 .mode
= COMMAND_EXEC
,
2307 .help
= "remove watchpoint custom",
2310 COMMAND_REGISTRATION_DONE
2313 /** Holds methods for DSP563XX targets. */
2314 struct target_type dsp563xx_target
= {
2317 .poll
= dsp563xx_poll
,
2318 .arch_state
= dsp563xx_arch_state
,
2320 .target_request_data
= NULL
,
2322 .get_gdb_reg_list
= dsp563xx_get_gdb_reg_list
,
2324 .halt
= dsp563xx_halt
,
2325 .resume
= dsp563xx_resume
,
2326 .step
= dsp563xx_step
,
2328 .assert_reset
= dsp563xx_assert_reset
,
2329 .deassert_reset
= dsp563xx_deassert_reset
,
2330 .soft_reset_halt
= dsp563xx_soft_reset_halt
,
2332 .read_memory
= dsp563xx_read_memory_default
,
2333 .write_memory
= dsp563xx_write_memory_default
,
2335 .read_buffer
= dsp563xx_read_buffer_default
,
2336 .write_buffer
= dsp563xx_write_buffer_default
,
2338 .run_algorithm
= dsp563xx_run_algorithm
,
2340 .add_breakpoint
= dsp563xx_add_breakpoint
,
2341 .remove_breakpoint
= dsp563xx_remove_breakpoint
,
2342 .add_watchpoint
= dsp563xx_add_watchpoint
,
2343 .remove_watchpoint
= dsp563xx_remove_watchpoint
,
2345 .commands
= dsp563xx_command_handlers
,
2346 .target_create
= dsp563xx_target_create
,
2347 .init_target
= dsp563xx_init_target
,
2348 .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)