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
= malloc(sizeof(struct reg
) * DSP563XX_NUMCOREREGS
);
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%x 0x%x 0x%x)",
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%03d 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 (%x)", target_state_name(target
), once_status
);
1083 LOG_INFO("halted: PC: 0x%x", 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%x", 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_soft_reset_halt(struct target
*target
)
1378 LOG_DEBUG("%s", __func__
);
1382 static int dsp563xx_run_algorithm(struct target
*target
,
1383 int num_mem_params
, struct mem_param
*mem_params
,
1384 int num_reg_params
, struct reg_param
*reg_params
,
1385 uint32_t entry_point
, uint32_t exit_point
,
1386 int timeout_ms
, void *arch_info
)
1389 int retval
= ERROR_OK
;
1390 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1392 if (target
->state
!= TARGET_HALTED
) {
1393 LOG_WARNING("target not halted");
1394 return ERROR_TARGET_NOT_HALTED
;
1397 for (i
= 0; i
< num_mem_params
; i
++) {
1398 retval
= target_write_buffer(target
, mem_params
[i
].address
,
1399 mem_params
[i
].size
, mem_params
[i
].value
);
1400 if (retval
!= ERROR_OK
)
1404 for (i
= 0; i
< num_reg_params
; i
++) {
1405 struct reg
*reg
= register_get_by_name(dsp563xx
->core_cache
,
1406 reg_params
[i
].reg_name
,
1410 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
1414 if (reg
->size
!= reg_params
[i
].size
) {
1415 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1416 reg_params
[i
].reg_name
);
1420 retval
= dsp563xx_set_core_reg(reg
, reg_params
[i
].value
);
1421 if (retval
!= ERROR_OK
)
1426 retval
= target_resume(target
, 0, entry_point
, 1, 1);
1427 if (retval
!= ERROR_OK
)
1430 retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
);
1431 if (retval
!= ERROR_OK
)
1434 for (i
= 0; i
< num_mem_params
; i
++) {
1435 if (mem_params
[i
].direction
!= PARAM_OUT
)
1436 retval
= target_read_buffer(target
,
1437 mem_params
[i
].address
,
1439 mem_params
[i
].value
);
1440 if (retval
!= ERROR_OK
)
1444 for (i
= 0; i
< num_reg_params
; i
++) {
1445 if (reg_params
[i
].direction
!= PARAM_OUT
) {
1447 struct reg
*reg
= register_get_by_name(dsp563xx
->core_cache
,
1448 reg_params
[i
].reg_name
,
1451 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
1455 if (reg
->size
!= reg_params
[i
].size
) {
1457 "BUG: register '%s' size doesn't match reg_params[i].size",
1458 reg_params
[i
].reg_name
);
1462 buf_set_u32(reg_params
[i
].value
, 0, 32, buf_get_u32(reg
->value
, 0, 32));
1469 /* global command context from openocd.c */
1470 extern struct command_context
*global_cmd_ctx
;
1472 static int dsp563xx_get_default_memory(void)
1478 if (!global_cmd_ctx
)
1481 interp
= global_cmd_ctx
->interp
;
1486 memspace
= Jim_GetGlobalVariableStr(interp
, "memspace", JIM_NONE
);
1491 c
= (char *)Jim_GetString(memspace
, NULL
);
1510 static int dsp563xx_read_memory_core(struct target
*target
,
1518 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1520 uint32_t data
, move_cmd
= 0;
1524 "memtype: %d address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
1530 if (target
->state
!= TARGET_HALTED
) {
1531 LOG_WARNING("target not halted");
1532 return ERROR_TARGET_NOT_HALTED
;
1537 /* TODO: mark effected queued registers */
1538 move_cmd
= 0x61d800;
1541 move_cmd
= 0x69d800;
1544 move_cmd
= 0x07d891;
1547 return ERROR_COMMAND_SYNTAX_ERROR
;
1550 /* we use r0 to store temporary data */
1551 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
1552 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
1553 /* we use r1 to store temporary data */
1554 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].valid
)
1555 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R1
);
1557 /* r0 is no longer valid on target */
1558 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= 1;
1559 /* r1 is no longer valid on target */
1560 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].dirty
= 1;
1565 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, 0x60F400, address
);
1566 if (err
!= ERROR_OK
)
1569 for (i
= 0; i
< x
; i
++) {
1570 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, move_cmd
);
1571 if (err
!= ERROR_OK
)
1573 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, 0x08D13C);
1574 if (err
!= ERROR_OK
)
1576 err
= dsp563xx_once_reg_read(target
->tap
, 0,
1577 DSP563XX_ONCE_OGDBR
, (uint32_t *)(void *)b
);
1578 if (err
!= ERROR_OK
)
1583 /* flush the jtag queue */
1584 err
= jtag_execute_queue();
1585 if (err
!= ERROR_OK
)
1588 /* walk over the buffer and fix target endianness */
1591 for (i
= 0; i
< x
; i
++) {
1592 data
= buf_get_u32(b
, 0, 32) & 0x00FFFFFF;
1593 /* LOG_DEBUG("R: %08X", *((uint32_t*)b)); */
1594 target_buffer_set_u32(target
, b
, data
);
1601 static int dsp563xx_read_memory(struct target
*target
,
1610 uint8_t *buffer_y
, *buffer_x
;
1612 /* if size equals zero we are called from target read memory
1613 * and have to handle the parameter here */
1614 if ((size
== 0) && (count
!= 0)) {
1618 LOG_DEBUG("size is not aligned to 4 byte");
1620 count
= (count
- size
) / 4;
1624 /* we only support 4 byte aligned data */
1625 if ((size
!= 4) || (!count
))
1626 return ERROR_COMMAND_SYNTAX_ERROR
;
1628 if (mem_type
!= MEM_L
)
1629 return dsp563xx_read_memory_core(target
, mem_type
, address
, size
, count
, buffer
);
1631 buffer_y
= malloc(size
* count
);
1633 return ERROR_COMMAND_SYNTAX_ERROR
;
1635 buffer_x
= malloc(size
* count
);
1638 return ERROR_COMMAND_SYNTAX_ERROR
;
1641 err
= dsp563xx_read_memory_core(target
, MEM_Y
, address
, size
, count
/ 2, buffer_y
);
1643 if (err
!= ERROR_OK
) {
1649 err
= dsp563xx_read_memory_core(target
, MEM_X
, address
, size
, count
/ 2, buffer_x
);
1651 if (err
!= ERROR_OK
) {
1657 for (i
= 0, i1
= 0; i
< count
; i
+= 2, i1
++) {
1658 buf_set_u32(buffer
+ i
*sizeof(uint32_t), 0, 32,
1659 buf_get_u32(buffer_y
+ i1
* sizeof(uint32_t), 0, 32));
1660 buf_set_u32(buffer
+ (i
+ 1) * sizeof(uint32_t), 0, 32,
1661 buf_get_u32(buffer_x
+ i1
* sizeof(uint32_t), 0, 32));
1670 static int dsp563xx_read_memory_default(struct target
*target
,
1677 return dsp563xx_read_memory(target
,
1678 dsp563xx_get_default_memory(), address
, size
, count
, buffer
);
1681 static int dsp563xx_read_buffer_default(struct target
*target
,
1687 return dsp563xx_read_memory(target
, dsp563xx_get_default_memory(), address
, size
, 0,
1691 static int dsp563xx_write_memory_core(struct target
*target
,
1696 const uint8_t *buffer
)
1699 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1701 uint32_t data
, move_cmd
= 0;
1705 "memtype: %d address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
1711 if (target
->state
!= TARGET_HALTED
) {
1712 LOG_WARNING("target not halted");
1713 return ERROR_TARGET_NOT_HALTED
;
1718 /* invalidate affected x registers */
1719 dsp563xx_invalidate_x_context(target
, address
, address
+ count
- 1);
1720 move_cmd
= 0x615800;
1723 move_cmd
= 0x695800;
1726 move_cmd
= 0x075891;
1729 return ERROR_COMMAND_SYNTAX_ERROR
;
1732 /* we use r0 to store temporary data */
1733 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
1734 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
1735 /* we use r1 to store temporary data */
1736 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].valid
)
1737 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R1
);
1739 /* r0 is no longer valid on target */
1740 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= 1;
1741 /* r1 is no longer valid on target */
1742 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].dirty
= 1;
1747 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, 0x60F400, address
);
1748 if (err
!= ERROR_OK
)
1751 for (i
= 0; i
< x
; i
++) {
1752 data
= target_buffer_get_u32(target
, b
);
1754 /* LOG_DEBUG("W: %08X", data); */
1758 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 0, 0x61F400, data
);
1759 if (err
!= ERROR_OK
)
1761 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, move_cmd
);
1762 if (err
!= ERROR_OK
)
1767 /* flush the jtag queue */
1768 err
= jtag_execute_queue();
1769 if (err
!= ERROR_OK
)
1775 static int dsp563xx_write_memory(struct target
*target
,
1780 const uint8_t *buffer
)
1784 uint8_t *buffer_y
, *buffer_x
;
1786 /* if size equals zero we are called from target write memory
1787 * and have to handle the parameter here */
1788 if ((size
== 0) && (count
!= 0)) {
1792 LOG_DEBUG("size is not aligned to 4 byte");
1794 count
= (count
- size
) / 4;
1798 /* we only support 4 byte aligned data */
1799 if ((size
!= 4) || (!count
))
1800 return ERROR_COMMAND_SYNTAX_ERROR
;
1802 if (mem_type
!= MEM_L
)
1803 return dsp563xx_write_memory_core(target
, mem_type
, address
, size
, count
, buffer
);
1805 buffer_y
= malloc(size
* count
);
1807 return ERROR_COMMAND_SYNTAX_ERROR
;
1809 buffer_x
= malloc(size
* count
);
1812 return ERROR_COMMAND_SYNTAX_ERROR
;
1815 for (i
= 0, i1
= 0; i
< count
; i
+= 2, i1
++) {
1816 buf_set_u32(buffer_y
+ i1
* sizeof(uint32_t), 0, 32,
1817 buf_get_u32(buffer
+ i
* sizeof(uint32_t), 0, 32));
1818 buf_set_u32(buffer_x
+ i1
* sizeof(uint32_t), 0, 32,
1819 buf_get_u32(buffer
+ (i
+ 1) * sizeof(uint32_t), 0, 32));
1822 err
= dsp563xx_write_memory_core(target
, MEM_Y
, address
, size
, count
/ 2, buffer_y
);
1824 if (err
!= ERROR_OK
) {
1830 err
= dsp563xx_write_memory_core(target
, MEM_X
, address
, size
, count
/ 2, buffer_x
);
1832 if (err
!= ERROR_OK
) {
1844 static int dsp563xx_write_memory_default(struct target
*target
,
1848 const uint8_t *buffer
)
1850 return dsp563xx_write_memory(target
,
1851 dsp563xx_get_default_memory(), address
, size
, count
, buffer
);
1854 static int dsp563xx_write_buffer_default(struct target
*target
,
1857 const uint8_t *buffer
)
1859 return dsp563xx_write_memory(target
, dsp563xx_get_default_memory(), address
, size
, 0,
1864 * Exit with error here, because we support watchpoints over a custom command.
1865 * This is because the DSP has separate X,Y,P memspace which is not compatible to the
1866 * traditional watchpoint logic.
1868 static int dsp563xx_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1870 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1874 * @see dsp563xx_add_watchpoint
1876 static int dsp563xx_remove_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1878 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1881 static void handle_md_output(struct command_context
*cmd_ctx
,
1882 struct target
*target
,
1886 const uint8_t *buffer
)
1888 const unsigned line_bytecnt
= 32;
1889 unsigned line_modulo
= line_bytecnt
/ size
;
1891 char output
[line_bytecnt
* 4 + 1];
1892 unsigned output_len
= 0;
1894 const char *value_fmt
;
1897 value_fmt
= "%8.8x ";
1900 value_fmt
= "%4.4x ";
1903 value_fmt
= "%2.2x ";
1906 /* "can't happen", caller checked */
1907 LOG_ERROR("invalid memory read size: %u", size
);
1911 for (unsigned i
= 0; i
< count
; i
++) {
1912 if (i
% line_modulo
== 0)
1913 output_len
+= snprintf(output
+ output_len
,
1914 sizeof(output
) - output_len
,
1916 (unsigned) (address
+ i
));
1919 const uint8_t *value_ptr
= buffer
+ i
* size
;
1922 value
= target_buffer_get_u32(target
, value_ptr
);
1925 value
= target_buffer_get_u16(target
, value_ptr
);
1930 output_len
+= snprintf(output
+ output_len
,
1931 sizeof(output
) - output_len
,
1935 if ((i
% line_modulo
== line_modulo
- 1) || (i
== count
- 1)) {
1936 command_print(cmd_ctx
, "%s", output
);
1942 static int dsp563xx_add_custom_watchpoint(struct target
*target
, uint32_t address
, uint32_t memType
,
1943 enum watchpoint_rw rw
, enum watchpoint_condition cond
)
1946 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1948 bool wasRunning
= false;
1949 /* Only set breakpoint when halted */
1950 if (target
->state
!= TARGET_HALTED
) {
1951 dsp563xx_halt(target
);
1955 if (dsp563xx
->hardware_breakpoint
[0].used
) {
1956 LOG_ERROR("Cannot add watchpoint. Hardware resource already used.");
1957 err
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1960 uint32_t obcr_value
= 0;
1961 if (err
== ERROR_OK
) {
1962 obcr_value
|= OBCR_b0_or_b1
;
1965 obcr_value
|= OBCR_BP_MEM_X
;
1968 obcr_value
|= OBCR_BP_MEM_Y
;
1971 obcr_value
|= OBCR_BP_MEM_P
;
1974 LOG_ERROR("Unknown memType parameter (%d)", memType
);
1975 err
= ERROR_TARGET_INVALID
;
1979 if (err
== ERROR_OK
) {
1982 obcr_value
|= OBCR_BP_0(OBCR_BP_ON_READ
);
1985 obcr_value
|= OBCR_BP_0(OBCR_BP_ON_WRITE
);
1988 obcr_value
|= OBCR_BP_0(OBCR_BP_ON_READ
|OBCR_BP_ON_WRITE
);
1991 LOG_ERROR("Unsupported write mode (%d)", rw
);
1992 err
= ERROR_TARGET_INVALID
;
1996 if (err
== ERROR_OK
) {
1999 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_EQUAL
);
2002 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_NOT_EQUAL
);
2005 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_LESS_THAN
);
2008 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_GREATER_THAN
);
2011 LOG_ERROR("Unsupported condition code (%d)", cond
);
2012 err
= ERROR_TARGET_INVALID
;
2016 if (err
== ERROR_OK
)
2017 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR0
, address
);
2019 if (err
== ERROR_OK
)
2020 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR1
, 0x0);
2022 if (err
== ERROR_OK
)
2023 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OBCR
, obcr_value
);
2025 if (err
== ERROR_OK
) {
2026 /* You should write the memory breakpoint counter to 0 */
2027 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMBC
, 0);
2030 if (err
== ERROR_OK
) {
2031 /* You should write the memory breakpoint counter to 0 */
2032 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OTC
, 0);
2035 if (err
== ERROR_OK
)
2036 dsp563xx
->hardware_breakpoint
[0].used
= BPU_WATCHPOINT
;
2038 if (err
== ERROR_OK
&& wasRunning
) {
2039 /* Resume from current PC */
2040 err
= dsp563xx_resume(target
, 1, 0x0, 0, 0);
2046 static int dsp563xx_remove_custom_watchpoint(struct target
*target
)
2049 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
2051 if (dsp563xx
->hardware_breakpoint
[0].used
!= BPU_WATCHPOINT
) {
2052 LOG_ERROR("Cannot remove watchpoint, as no watchpoint is currently configured!");
2053 err
= ERROR_TARGET_INVALID
;
2056 if (err
== ERROR_OK
) {
2057 /* Clear watchpoint by clearing OBCR. */
2058 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OBCR
, 0);
2061 if (err
== ERROR_OK
)
2062 dsp563xx
->hardware_breakpoint
[0].used
= BPU_NONE
;
2067 COMMAND_HANDLER(dsp563xx_add_watchpoint_command
)
2070 struct target
*target
= get_current_target(CMD_CTX
);
2072 uint32_t mem_type
= 0;
2073 switch (CMD_NAME
[2]) {
2084 return ERROR_COMMAND_SYNTAX_ERROR
;
2088 return ERROR_COMMAND_SYNTAX_ERROR
;
2090 uint32_t address
= 0;
2092 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], address
);
2094 enum watchpoint_condition cond
;
2095 switch (CMD_ARGV
[0][0]) {
2109 return ERROR_COMMAND_SYNTAX_ERROR
;
2112 enum watchpoint_rw rw
;
2113 switch (CMD_ARGV
[1][0]) {
2124 return ERROR_COMMAND_SYNTAX_ERROR
;
2127 err
= dsp563xx_add_custom_watchpoint(target
, address
, mem_type
, rw
, cond
);
2132 /* Adding a breakpoint using the once breakpoint logic.
2133 * Note that this mechanism is a true hw breakpoint and is share between the watchpoint logic.
2134 * This means, you can only have one breakpoint/watchpoint at any time.
2136 static int dsp563xx_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
2138 return dsp563xx_add_custom_watchpoint(target
, breakpoint
->address
, MEM_P
, WPT_READ
, EQUAL
);
2141 static int dsp563xx_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
2143 return dsp563xx_remove_custom_watchpoint(target
);
2146 COMMAND_HANDLER(dsp563xx_remove_watchpoint_command
)
2148 struct target
*target
= get_current_target(CMD_CTX
);
2150 return dsp563xx_remove_custom_watchpoint(target
);
2153 COMMAND_HANDLER(dsp563xx_mem_command
)
2155 struct target
*target
= get_current_target(CMD_CTX
);
2158 uint32_t address
= 0;
2159 uint32_t count
= 1, i
;
2160 uint32_t pattern
= 0;
2162 uint8_t *buffer
, *b
;
2164 switch (CMD_NAME
[1]) {
2172 return ERROR_COMMAND_SYNTAX_ERROR
;
2175 switch (CMD_NAME
[3]) {
2186 return ERROR_COMMAND_SYNTAX_ERROR
;
2190 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
2192 if (read_mem
== 0) {
2194 return ERROR_COMMAND_SYNTAX_ERROR
;
2196 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], pattern
);
2198 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], count
);
2201 if (read_mem
== 1) {
2203 return ERROR_COMMAND_SYNTAX_ERROR
;
2205 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], count
);
2208 buffer
= calloc(count
, sizeof(uint32_t));
2210 if (read_mem
== 1) {
2211 err
= dsp563xx_read_memory(target
, mem_type
, address
, sizeof(uint32_t),
2213 if (err
== ERROR_OK
)
2214 handle_md_output(CMD_CTX
, target
, address
, sizeof(uint32_t), count
, buffer
);
2219 for (i
= 0; i
< count
; i
++) {
2220 target_buffer_set_u32(target
, b
, pattern
);
2224 err
= dsp563xx_write_memory(target
,
2237 static const struct command_registration dsp563xx_command_handlers
[] = {
2240 .handler
= dsp563xx_mem_command
,
2241 .mode
= COMMAND_EXEC
,
2242 .help
= "write x memory words",
2243 .usage
= "address value [count]",
2247 .handler
= dsp563xx_mem_command
,
2248 .mode
= COMMAND_EXEC
,
2249 .help
= "write y memory words",
2250 .usage
= "address value [count]",
2254 .handler
= dsp563xx_mem_command
,
2255 .mode
= COMMAND_EXEC
,
2256 .help
= "write p memory words",
2257 .usage
= "address value [count]",
2261 .handler
= dsp563xx_mem_command
,
2262 .mode
= COMMAND_EXEC
,
2263 .help
= "display x memory words",
2264 .usage
= "address [count]",
2268 .handler
= dsp563xx_mem_command
,
2269 .mode
= COMMAND_EXEC
,
2270 .help
= "display y memory words",
2271 .usage
= "address [count]",
2275 .handler
= dsp563xx_mem_command
,
2276 .mode
= COMMAND_EXEC
,
2277 .help
= "display p memory words",
2278 .usage
= "address [count]",
2281 * Watchpoint commands
2285 .handler
= dsp563xx_add_watchpoint_command
,
2286 .mode
= COMMAND_EXEC
,
2287 .help
= "Create p memspace watchpoint",
2288 .usage
= "(>|<|=|!) (r|w|a) address",
2292 .handler
= dsp563xx_add_watchpoint_command
,
2293 .mode
= COMMAND_EXEC
,
2294 .help
= "Create x memspace watchpoint",
2295 .usage
= "(>|<|=|!) (r|w|a) address",
2299 .handler
= dsp563xx_add_watchpoint_command
,
2300 .mode
= COMMAND_EXEC
,
2301 .help
= "Create y memspace watchpoint",
2302 .usage
= "(>|<|=|!) (r|w|a) address",
2306 .handler
= dsp563xx_remove_watchpoint_command
,
2307 .mode
= COMMAND_EXEC
,
2308 .help
= "remove watchpoint custom",
2311 COMMAND_REGISTRATION_DONE
2314 /** Holds methods for DSP563XX targets. */
2315 struct target_type dsp563xx_target
= {
2318 .poll
= dsp563xx_poll
,
2319 .arch_state
= dsp563xx_arch_state
,
2321 .target_request_data
= NULL
,
2323 .get_gdb_reg_list
= dsp563xx_get_gdb_reg_list
,
2325 .halt
= dsp563xx_halt
,
2326 .resume
= dsp563xx_resume
,
2327 .step
= dsp563xx_step
,
2329 .assert_reset
= dsp563xx_assert_reset
,
2330 .deassert_reset
= dsp563xx_deassert_reset
,
2331 .soft_reset_halt
= dsp563xx_soft_reset_halt
,
2333 .read_memory
= dsp563xx_read_memory_default
,
2334 .write_memory
= dsp563xx_write_memory_default
,
2336 .read_buffer
= dsp563xx_read_buffer_default
,
2337 .write_buffer
= dsp563xx_write_buffer_default
,
2339 .run_algorithm
= dsp563xx_run_algorithm
,
2341 .add_breakpoint
= dsp563xx_add_breakpoint
,
2342 .remove_breakpoint
= dsp563xx_remove_breakpoint
,
2343 .add_watchpoint
= dsp563xx_add_watchpoint
,
2344 .remove_watchpoint
= dsp563xx_remove_watchpoint
,
2346 .commands
= dsp563xx_command_handlers
,
2347 .target_create
= dsp563xx_target_create
,
2348 .init_target
= dsp563xx_init_target
,
2349 .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)