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, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
26 #include "breakpoints.h"
27 #include "target_type.h"
28 #include "algorithm.h"
31 #include "dsp563xx_once.h"
33 #define ASM_REG_W_R0 0x60F400
34 #define ASM_REG_W_R1 0x61F400
35 #define ASM_REG_W_R2 0x62F400
36 #define ASM_REG_W_R3 0x63F400
37 #define ASM_REG_W_R4 0x64F400
38 #define ASM_REG_W_R5 0x65F400
39 #define ASM_REG_W_R6 0x66F400
40 #define ASM_REG_W_R7 0x67F400
42 #define ASM_REG_W_N0 0x70F400
43 #define ASM_REG_W_N1 0x71F400
44 #define ASM_REG_W_N2 0x72F400
45 #define ASM_REG_W_N3 0x73F400
46 #define ASM_REG_W_N4 0x74F400
47 #define ASM_REG_W_N5 0x75F400
48 #define ASM_REG_W_N6 0x76F400
49 #define ASM_REG_W_N7 0x77F400
51 #define ASM_REG_W_M0 0x05F420
52 #define ASM_REG_W_M1 0x05F421
53 #define ASM_REG_W_M2 0x05F422
54 #define ASM_REG_W_M3 0x05F423
55 #define ASM_REG_W_M4 0x05F424
56 #define ASM_REG_W_M5 0x05F425
57 #define ASM_REG_W_M6 0x05F426
58 #define ASM_REG_W_M7 0x05F427
60 #define ASM_REG_W_X0 0x44F400
61 #define ASM_REG_W_X1 0x45F400
63 #define ASM_REG_W_Y0 0x46F400
64 #define ASM_REG_W_Y1 0x47F400
66 #define ASM_REG_W_A0 0x50F400
67 #define ASM_REG_W_A1 0x54F400
68 #define ASM_REG_W_A2 0x52F400
70 #define ASM_REG_W_B0 0x51F400
71 #define ASM_REG_W_B1 0x55F400
72 #define ASM_REG_W_B2 0x53F400
74 #define ASM_REG_W_VBA 0x05F430
75 #define ASM_REG_W_OMR 0x05F43A
76 #define ASM_REG_W_EP 0x05F42A
77 #define ASM_REG_W_SC 0x05F431
78 #define ASM_REG_W_SZ 0x05F438
79 #define ASM_REG_W_SR 0x05F439
80 #define ASM_REG_W_SP 0x05F43B
81 #define ASM_REG_W_SSH 0x05F43C
82 #define ASM_REG_W_SSL 0x05F43D
83 #define ASM_REG_W_LA 0x05F43E
84 #define ASM_REG_W_LC 0x05F43F
85 #define ASM_REG_W_PC 0x000000
86 #define ASM_REG_W_IPRC 0xFFFFFF
87 #define ASM_REG_W_IPRP 0xFFFFFE
89 #define ASM_REG_W_BCR 0xFFFFFB
90 #define ASM_REG_W_DCR 0xFFFFFA
91 #define ASM_REG_W_AAR0 0xFFFFF9
92 #define ASM_REG_W_AAR1 0xFFFFF8
93 #define ASM_REG_W_AAR2 0xFFFFF7
94 #define ASM_REG_W_AAR3 0xFFFFF6
97 * OBCR Register bit definitions
99 #define OBCR_b0_and_b1 ((0x0) << 10)
100 #define OBCR_b0_or_b1 ((0x1) << 10)
101 #define OBCR_b1_after_b0 ((0x2) << 10)
102 #define OBCR_b0_after_b1 ((0x3) << 10)
104 #define OBCR_BP_DISABLED (0x0)
105 #define OBCR_BP_MEM_P (0x1)
106 #define OBCR_BP_MEM_X (0x2)
107 #define OBCR_BP_MEM_Y (0x3)
108 #define OBCR_BP_ON_READ ((0x2) << 0)
109 #define OBCR_BP_ON_WRITE ((0x1) << 0)
110 #define OBCR_BP_CC_NOT_EQUAL ((0x0) << 2)
111 #define OBCR_BP_CC_EQUAL ((0x1) << 2)
112 #define OBCR_BP_CC_LESS_THAN ((0x2) << 2)
113 #define OBCR_BP_CC_GREATER_THAN ((0x3) << 2)
115 #define OBCR_BP_0(x) ((x)<<2)
116 #define OBCR_BP_1(x) ((x)<<6)
120 ONCE_REG_IDX_OSCR
= 0,
121 ONCE_REG_IDX_OMBC
= 1,
122 ONCE_REG_IDX_OBCR
= 2,
123 ONCE_REG_IDX_OMLR0
= 3,
124 ONCE_REG_IDX_OMLR1
= 4,
125 ONCE_REG_IDX_OGDBR
= 5,
126 ONCE_REG_IDX_OPDBR
= 6,
127 ONCE_REG_IDX_OPILR
= 7,
128 ONCE_REG_IDX_PDB
= 8,
129 ONCE_REG_IDX_OTC
= 9,
130 ONCE_REG_IDX_OPABFR
= 10,
131 ONCE_REG_IDX_OPABDR
= 11,
132 ONCE_REG_IDX_OPABEX
= 12,
133 ONCE_REG_IDX_OPABF0
= 13,
134 ONCE_REG_IDX_OPABF1
= 14,
135 ONCE_REG_IDX_OPABF2
= 15,
136 ONCE_REG_IDX_OPABF3
= 16,
137 ONCE_REG_IDX_OPABF4
= 17,
138 ONCE_REG_IDX_OPABF5
= 18,
139 ONCE_REG_IDX_OPABF6
= 19,
140 ONCE_REG_IDX_OPABF7
= 20,
141 ONCE_REG_IDX_OPABF8
= 21,
142 ONCE_REG_IDX_OPABF9
= 22,
143 ONCE_REG_IDX_OPABF10
= 23,
144 ONCE_REG_IDX_OPABF11
= 24,
147 static struct once_reg once_regs
[] = {
148 {ONCE_REG_IDX_OSCR
, DSP563XX_ONCE_OSCR
, 24, "OSCR", 0},
149 {ONCE_REG_IDX_OMBC
, DSP563XX_ONCE_OMBC
, 24, "OMBC", 0},
150 {ONCE_REG_IDX_OBCR
, DSP563XX_ONCE_OBCR
, 24, "OBCR", 0},
151 {ONCE_REG_IDX_OMLR0
, DSP563XX_ONCE_OMLR0
, 24, "OMLR0", 0},
152 {ONCE_REG_IDX_OMLR1
, DSP563XX_ONCE_OMLR1
, 24, "OMLR1", 0},
153 {ONCE_REG_IDX_OGDBR
, DSP563XX_ONCE_OGDBR
, 24, "OGDBR", 0},
154 {ONCE_REG_IDX_OPDBR
, DSP563XX_ONCE_OPDBR
, 24, "OPDBR", 0},
155 {ONCE_REG_IDX_OPILR
, DSP563XX_ONCE_OPILR
, 24, "OPILR", 0},
156 {ONCE_REG_IDX_PDB
, DSP563XX_ONCE_PDBGOTO
, 24, "PDB", 0},
157 {ONCE_REG_IDX_OTC
, DSP563XX_ONCE_OTC
, 24, "OTC", 0},
158 {ONCE_REG_IDX_OPABFR
, DSP563XX_ONCE_OPABFR
, 24, "OPABFR", 0},
159 {ONCE_REG_IDX_OPABDR
, DSP563XX_ONCE_OPABDR
, 24, "OPABDR", 0},
160 {ONCE_REG_IDX_OPABEX
, DSP563XX_ONCE_OPABEX
, 24, "OPABEX", 0},
161 {ONCE_REG_IDX_OPABF0
, DSP563XX_ONCE_OPABF11
, 25, "OPABF0", 0},
162 {ONCE_REG_IDX_OPABF1
, DSP563XX_ONCE_OPABF11
, 25, "OPABF1", 0},
163 {ONCE_REG_IDX_OPABF2
, DSP563XX_ONCE_OPABF11
, 25, "OPABF2", 0},
164 {ONCE_REG_IDX_OPABF3
, DSP563XX_ONCE_OPABF11
, 25, "OPABF3", 0},
165 {ONCE_REG_IDX_OPABF4
, DSP563XX_ONCE_OPABF11
, 25, "OPABF4", 0},
166 {ONCE_REG_IDX_OPABF5
, DSP563XX_ONCE_OPABF11
, 25, "OPABF5", 0},
167 {ONCE_REG_IDX_OPABF6
, DSP563XX_ONCE_OPABF11
, 25, "OPABF6", 0},
168 {ONCE_REG_IDX_OPABF7
, DSP563XX_ONCE_OPABF11
, 25, "OPABF7", 0},
169 {ONCE_REG_IDX_OPABF8
, DSP563XX_ONCE_OPABF11
, 25, "OPABF8", 0},
170 {ONCE_REG_IDX_OPABF9
, DSP563XX_ONCE_OPABF11
, 25, "OPABF9", 0},
171 {ONCE_REG_IDX_OPABF10
, DSP563XX_ONCE_OPABF11
, 25, "OPABF10", 0},
172 {ONCE_REG_IDX_OPABF11
, DSP563XX_ONCE_OPABF11
, 25, "OPABF11", 0},
173 /* {25,0x1f,24,"NRSEL",0}, */
176 enum dsp563xx_reg_idx
{
177 DSP563XX_REG_IDX_R0
= 0,
178 DSP563XX_REG_IDX_R1
= 1,
179 DSP563XX_REG_IDX_R2
= 2,
180 DSP563XX_REG_IDX_R3
= 3,
181 DSP563XX_REG_IDX_R4
= 4,
182 DSP563XX_REG_IDX_R5
= 5,
183 DSP563XX_REG_IDX_R6
= 6,
184 DSP563XX_REG_IDX_R7
= 7,
185 DSP563XX_REG_IDX_N0
= 8,
186 DSP563XX_REG_IDX_N1
= 9,
187 DSP563XX_REG_IDX_N2
= 10,
188 DSP563XX_REG_IDX_N3
= 11,
189 DSP563XX_REG_IDX_N4
= 12,
190 DSP563XX_REG_IDX_N5
= 13,
191 DSP563XX_REG_IDX_N6
= 14,
192 DSP563XX_REG_IDX_N7
= 15,
193 DSP563XX_REG_IDX_M0
= 16,
194 DSP563XX_REG_IDX_M1
= 17,
195 DSP563XX_REG_IDX_M2
= 18,
196 DSP563XX_REG_IDX_M3
= 19,
197 DSP563XX_REG_IDX_M4
= 20,
198 DSP563XX_REG_IDX_M5
= 21,
199 DSP563XX_REG_IDX_M6
= 22,
200 DSP563XX_REG_IDX_M7
= 23,
201 DSP563XX_REG_IDX_X0
= 24,
202 DSP563XX_REG_IDX_X1
= 25,
203 DSP563XX_REG_IDX_Y0
= 26,
204 DSP563XX_REG_IDX_Y1
= 27,
205 DSP563XX_REG_IDX_A0
= 28,
206 DSP563XX_REG_IDX_A1
= 29,
207 DSP563XX_REG_IDX_A2
= 30,
208 DSP563XX_REG_IDX_B0
= 31,
209 DSP563XX_REG_IDX_B1
= 32,
210 DSP563XX_REG_IDX_B2
= 33,
211 DSP563XX_REG_IDX_SSH
= 34,
212 DSP563XX_REG_IDX_SSL
= 35,
213 DSP563XX_REG_IDX_SP
= 36,
214 DSP563XX_REG_IDX_EP
= 37,
215 DSP563XX_REG_IDX_SZ
= 38,
216 DSP563XX_REG_IDX_SC
= 39,
217 DSP563XX_REG_IDX_PC
= 40,
218 DSP563XX_REG_IDX_SR
= 41,
219 DSP563XX_REG_IDX_OMR
= 42,
220 DSP563XX_REG_IDX_LA
= 43,
221 DSP563XX_REG_IDX_LC
= 44,
222 DSP563XX_REG_IDX_VBA
= 45,
223 DSP563XX_REG_IDX_IPRC
= 46,
224 DSP563XX_REG_IDX_IPRP
= 47,
225 DSP563XX_REG_IDX_BCR
= 48,
226 DSP563XX_REG_IDX_DCR
= 49,
227 DSP563XX_REG_IDX_AAR0
= 50,
228 DSP563XX_REG_IDX_AAR1
= 51,
229 DSP563XX_REG_IDX_AAR2
= 52,
230 DSP563XX_REG_IDX_AAR3
= 53,
233 static const struct {
237 /* effective addressing mode encoding */
240 } dsp563xx_regs
[] = {
242 /* address registers */
243 {DSP563XX_REG_IDX_R0
, "r0", 24, 0x10, ASM_REG_W_R0
},
244 {DSP563XX_REG_IDX_R1
, "r1", 24, 0x11, ASM_REG_W_R1
},
245 {DSP563XX_REG_IDX_R2
, "r2", 24, 0x12, ASM_REG_W_R2
},
246 {DSP563XX_REG_IDX_R3
, "r3", 24, 0x13, ASM_REG_W_R3
},
247 {DSP563XX_REG_IDX_R4
, "r4", 24, 0x14, ASM_REG_W_R4
},
248 {DSP563XX_REG_IDX_R5
, "r5", 24, 0x15, ASM_REG_W_R5
},
249 {DSP563XX_REG_IDX_R6
, "r6", 24, 0x16, ASM_REG_W_R6
},
250 {DSP563XX_REG_IDX_R7
, "r7", 24, 0x17, ASM_REG_W_R7
},
251 /* offset registers */
252 {DSP563XX_REG_IDX_N0
, "n0", 24, 0x18, ASM_REG_W_N0
},
253 {DSP563XX_REG_IDX_N1
, "n1", 24, 0x19, ASM_REG_W_N1
},
254 {DSP563XX_REG_IDX_N2
, "n2", 24, 0x1a, ASM_REG_W_N2
},
255 {DSP563XX_REG_IDX_N3
, "n3", 24, 0x1b, ASM_REG_W_N3
},
256 {DSP563XX_REG_IDX_N4
, "n4", 24, 0x1c, ASM_REG_W_N4
},
257 {DSP563XX_REG_IDX_N5
, "n5", 24, 0x1d, ASM_REG_W_N5
},
258 {DSP563XX_REG_IDX_N6
, "n6", 24, 0x1e, ASM_REG_W_N6
},
259 {DSP563XX_REG_IDX_N7
, "n7", 24, 0x1f, ASM_REG_W_N7
},
260 /* modifier registers */
261 {DSP563XX_REG_IDX_M0
, "m0", 24, 0x20, ASM_REG_W_M0
},
262 {DSP563XX_REG_IDX_M1
, "m1", 24, 0x21, ASM_REG_W_M1
},
263 {DSP563XX_REG_IDX_M2
, "m2", 24, 0x22, ASM_REG_W_M2
},
264 {DSP563XX_REG_IDX_M3
, "m3", 24, 0x23, ASM_REG_W_M3
},
265 {DSP563XX_REG_IDX_M4
, "m4", 24, 0x24, ASM_REG_W_M4
},
266 {DSP563XX_REG_IDX_M5
, "m5", 24, 0x25, ASM_REG_W_M5
},
267 {DSP563XX_REG_IDX_M6
, "m6", 24, 0x26, ASM_REG_W_M6
},
268 {DSP563XX_REG_IDX_M7
, "m7", 24, 0x27, ASM_REG_W_M7
},
269 /* data alu input register */
270 {DSP563XX_REG_IDX_X0
, "x0", 24, 0x04, ASM_REG_W_X0
},
271 {DSP563XX_REG_IDX_X1
, "x1", 24, 0x05, ASM_REG_W_X1
},
272 {DSP563XX_REG_IDX_Y0
, "y0", 24, 0x06, ASM_REG_W_Y0
},
273 {DSP563XX_REG_IDX_Y1
, "y1", 24, 0x07, ASM_REG_W_Y1
},
274 /* data alu accumulator register */
275 {DSP563XX_REG_IDX_A0
, "a0", 24, 0x08, ASM_REG_W_A0
},
276 {DSP563XX_REG_IDX_A1
, "a1", 24, 0x0c, ASM_REG_W_A1
},
277 {DSP563XX_REG_IDX_A2
, "a2", 8, 0x0a, ASM_REG_W_A2
},
278 {DSP563XX_REG_IDX_B0
, "b0", 24, 0x09, ASM_REG_W_B0
},
279 {DSP563XX_REG_IDX_B1
, "b1", 24, 0x0d, ASM_REG_W_B1
},
280 {DSP563XX_REG_IDX_B2
, "b2", 8, 0x0b, ASM_REG_W_B2
},
282 {DSP563XX_REG_IDX_SSH
, "ssh", 24, 0x3c, ASM_REG_W_SSH
},
283 {DSP563XX_REG_IDX_SSL
, "ssl", 24, 0x3d, ASM_REG_W_SSL
},
284 {DSP563XX_REG_IDX_SP
, "sp", 24, 0x3b, ASM_REG_W_SP
},
285 {DSP563XX_REG_IDX_EP
, "ep", 24, 0x2a, ASM_REG_W_EP
},
286 {DSP563XX_REG_IDX_SZ
, "sz", 24, 0x38, ASM_REG_W_SZ
},
287 {DSP563XX_REG_IDX_SC
, "sc", 24, 0x31, ASM_REG_W_SC
},
289 {DSP563XX_REG_IDX_PC
, "pc", 24, 0x00, ASM_REG_W_PC
},
290 {DSP563XX_REG_IDX_SR
, "sr", 24, 0x39, ASM_REG_W_SR
},
291 {DSP563XX_REG_IDX_OMR
, "omr", 24, 0x3a, ASM_REG_W_OMR
},
292 {DSP563XX_REG_IDX_LA
, "la", 24, 0x3e, ASM_REG_W_LA
},
293 {DSP563XX_REG_IDX_LC
, "lc", 24, 0x3f, ASM_REG_W_LC
},
295 {DSP563XX_REG_IDX_VBA
, "vba", 24, 0x30, ASM_REG_W_VBA
},
296 {DSP563XX_REG_IDX_IPRC
, "iprc", 24, 0x00, ASM_REG_W_IPRC
},
297 {DSP563XX_REG_IDX_IPRP
, "iprp", 24, 0x00, ASM_REG_W_IPRP
},
299 {DSP563XX_REG_IDX_BCR
, "bcr", 24, 0x00, ASM_REG_W_BCR
},
300 {DSP563XX_REG_IDX_DCR
, "dcr", 24, 0x00, ASM_REG_W_DCR
},
301 {DSP563XX_REG_IDX_AAR0
, "aar0", 24, 0x00, ASM_REG_W_AAR0
},
302 {DSP563XX_REG_IDX_AAR1
, "aar1", 24, 0x00, ASM_REG_W_AAR1
},
303 {DSP563XX_REG_IDX_AAR2
, "aar2", 24, 0x00, ASM_REG_W_AAR2
},
304 {DSP563XX_REG_IDX_AAR3
, "aar3", 24, 0x00, ASM_REG_W_AAR3
},
315 enum watchpoint_condition
{
322 #define INSTR_JUMP 0x0AF080
323 /* Effective Addressing Mode Encoding */
325 /* instrcution encoder */
327 * s - peripheral space X/Y (X=0,Y=1)
329 * d - source/destination register
330 * p - IO short address
332 #define INSTR_MOVEP_REG_HIO(s, w, d, p) (0x084000 | \
333 ((s & 1) << 16) | ((w & 1) << 15) | ((d & 0x3f) << 8) | (p & 0x3f))
335 /* the gdb register list is send in this order */
336 static const uint8_t gdb_reg_list_idx
[] = {
337 DSP563XX_REG_IDX_X1
, DSP563XX_REG_IDX_X0
, DSP563XX_REG_IDX_Y1
, DSP563XX_REG_IDX_Y0
,
338 DSP563XX_REG_IDX_A2
, DSP563XX_REG_IDX_A1
, DSP563XX_REG_IDX_A0
, DSP563XX_REG_IDX_B2
,
339 DSP563XX_REG_IDX_B1
, DSP563XX_REG_IDX_B0
, DSP563XX_REG_IDX_PC
, DSP563XX_REG_IDX_SR
,
340 DSP563XX_REG_IDX_OMR
, DSP563XX_REG_IDX_LA
, DSP563XX_REG_IDX_LC
, DSP563XX_REG_IDX_SSH
,
341 DSP563XX_REG_IDX_SSL
, DSP563XX_REG_IDX_SP
, DSP563XX_REG_IDX_EP
, DSP563XX_REG_IDX_SZ
,
342 DSP563XX_REG_IDX_SC
, DSP563XX_REG_IDX_VBA
, DSP563XX_REG_IDX_IPRC
, DSP563XX_REG_IDX_IPRP
,
343 DSP563XX_REG_IDX_BCR
, DSP563XX_REG_IDX_DCR
, DSP563XX_REG_IDX_AAR0
, DSP563XX_REG_IDX_AAR1
,
344 DSP563XX_REG_IDX_AAR2
, DSP563XX_REG_IDX_AAR3
, DSP563XX_REG_IDX_R0
, DSP563XX_REG_IDX_R1
,
345 DSP563XX_REG_IDX_R2
, DSP563XX_REG_IDX_R3
, DSP563XX_REG_IDX_R4
, DSP563XX_REG_IDX_R5
,
346 DSP563XX_REG_IDX_R6
, DSP563XX_REG_IDX_R7
, DSP563XX_REG_IDX_N0
, DSP563XX_REG_IDX_N1
,
347 DSP563XX_REG_IDX_N2
, DSP563XX_REG_IDX_N3
, DSP563XX_REG_IDX_N4
, DSP563XX_REG_IDX_N5
,
348 DSP563XX_REG_IDX_N6
, DSP563XX_REG_IDX_N7
, DSP563XX_REG_IDX_M0
, DSP563XX_REG_IDX_M1
,
349 DSP563XX_REG_IDX_M2
, DSP563XX_REG_IDX_M3
, DSP563XX_REG_IDX_M4
, DSP563XX_REG_IDX_M5
,
350 DSP563XX_REG_IDX_M6
, DSP563XX_REG_IDX_M7
,
353 static int dsp563xx_get_gdb_reg_list(struct target
*target
,
354 struct reg
**reg_list
[],
356 enum target_register_class reg_class
)
359 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
361 if (target
->state
!= TARGET_HALTED
)
362 return ERROR_TARGET_NOT_HALTED
;
364 *reg_list_size
= DSP563XX_NUMCOREREGS
;
365 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
368 return ERROR_COMMAND_SYNTAX_ERROR
;
370 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++)
371 (*reg_list
)[i
] = &dsp563xx
->core_cache
->reg_list
[gdb_reg_list_idx
[i
]];
377 static int dsp563xx_read_core_reg(struct target
*target
, int num
)
380 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
382 if ((num
< 0) || (num
>= DSP563XX_NUMCOREREGS
))
383 return ERROR_COMMAND_SYNTAX_ERROR
;
385 reg_value
= dsp563xx
->core_regs
[num
];
386 buf_set_u32(dsp563xx
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
387 dsp563xx
->core_cache
->reg_list
[num
].valid
= 1;
388 dsp563xx
->core_cache
->reg_list
[num
].dirty
= 0;
393 static int dsp563xx_write_core_reg(struct target
*target
, int num
)
396 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
398 if ((num
< 0) || (num
>= DSP563XX_NUMCOREREGS
))
399 return ERROR_COMMAND_SYNTAX_ERROR
;
401 reg_value
= buf_get_u32(dsp563xx
->core_cache
->reg_list
[num
].value
, 0, 32);
402 dsp563xx
->core_regs
[num
] = reg_value
;
403 dsp563xx
->core_cache
->reg_list
[num
].valid
= 1;
404 dsp563xx
->core_cache
->reg_list
[num
].dirty
= 0;
409 static int dsp563xx_get_core_reg(struct reg
*reg
)
411 struct dsp563xx_core_reg
*dsp563xx_reg
= reg
->arch_info
;
412 struct target
*target
= dsp563xx_reg
->target
;
413 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
415 LOG_DEBUG("%s", __func__
);
417 if (target
->state
!= TARGET_HALTED
)
418 return ERROR_TARGET_NOT_HALTED
;
420 return dsp563xx
->read_core_reg(target
, dsp563xx_reg
->num
);
423 static int dsp563xx_set_core_reg(struct reg
*reg
, uint8_t *buf
)
425 LOG_DEBUG("%s", __func__
);
427 struct dsp563xx_core_reg
*dsp563xx_reg
= reg
->arch_info
;
428 struct target
*target
= dsp563xx_reg
->target
;
429 uint32_t value
= buf_get_u32(buf
, 0, 32);
431 if (target
->state
!= TARGET_HALTED
)
432 return ERROR_TARGET_NOT_HALTED
;
434 buf_set_u32(reg
->value
, 0, reg
->size
, value
);
441 static const struct reg_arch_type dsp563xx_reg_type
= {
442 .get
= dsp563xx_get_core_reg
,
443 .set
= dsp563xx_set_core_reg
,
446 static void dsp563xx_build_reg_cache(struct target
*target
)
448 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
450 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
451 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
452 struct reg
*reg_list
= calloc(DSP563XX_NUMCOREREGS
, sizeof(struct reg
));
453 struct dsp563xx_core_reg
*arch_info
= malloc(
454 sizeof(struct dsp563xx_core_reg
) * DSP563XX_NUMCOREREGS
);
457 /* Build the process context cache */
458 cache
->name
= "dsp563xx registers";
460 cache
->reg_list
= reg_list
;
461 cache
->num_regs
= DSP563XX_NUMCOREREGS
;
463 dsp563xx
->core_cache
= cache
;
465 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++) {
466 arch_info
[i
].num
= dsp563xx_regs
[i
].id
;
467 arch_info
[i
].name
= dsp563xx_regs
[i
].name
;
468 arch_info
[i
].size
= dsp563xx_regs
[i
].bits
;
469 arch_info
[i
].eame
= dsp563xx_regs
[i
].eame
;
470 arch_info
[i
].instr_mask
= dsp563xx_regs
[i
].instr_mask
;
471 arch_info
[i
].target
= target
;
472 arch_info
[i
].dsp563xx_common
= dsp563xx
;
473 reg_list
[i
].name
= dsp563xx_regs
[i
].name
;
474 reg_list
[i
].size
= 32; /* dsp563xx_regs[i].bits; */
475 reg_list
[i
].value
= calloc(1, 4);
476 reg_list
[i
].dirty
= 0;
477 reg_list
[i
].valid
= 0;
478 reg_list
[i
].type
= &dsp563xx_reg_type
;
479 reg_list
[i
].arch_info
= &arch_info
[i
];
483 static int dsp563xx_read_register(struct target
*target
, int num
, int force
);
484 static int dsp563xx_write_register(struct target
*target
, int num
, int force
);
486 static int dsp563xx_reg_read_high_io(struct target
*target
, uint32_t instr_mask
, uint32_t *data
)
490 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
492 /* we use r0 to store temporary data */
493 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
494 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
496 /* move source memory to r0 */
497 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 0, EAME_R0
, instr_mask
);
498 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, instr
);
501 /* move r0 to debug register */
502 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 1, EAME_R0
, 0xfffffc);
503 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 1, instr
);
506 /* read debug register */
507 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OGDBR
, data
);
510 /* r0 is no longer valid on target */
511 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= 1;
516 static int dsp563xx_reg_write_high_io(struct target
*target
, uint32_t instr_mask
, uint32_t data
)
520 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
522 /* we use r0 to store temporary data */
523 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
524 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
526 /* move data to r0 */
527 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 0, 0x60F400, data
);
530 /* move r0 to destination memory */
531 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 1, EAME_R0
, instr_mask
);
532 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 1, instr
);
536 /* r0 is no longer valid on target */
537 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= 1;
542 static int dsp563xx_reg_read(struct target
*target
, uint32_t eame
, uint32_t *data
)
547 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 1, eame
, 0xfffffc);
548 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, instr
);
552 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 1, 0x000000);
555 /* read debug register */
556 return dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OGDBR
, data
);
559 static int dsp563xx_reg_write(struct target
*target
, uint32_t instr_mask
, uint32_t data
)
563 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 0, instr_mask
, data
);
567 return dsp563xx_once_execute_sw_ir(target
->tap
, 1, 0x000000);
570 static int dsp563xx_reg_pc_read(struct target
*target
)
572 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
574 /* pc was changed, nothing todo */
575 if (dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].dirty
)
578 /* conditional branch check */
579 if (once_regs
[ONCE_REG_IDX_OPABDR
].reg
== once_regs
[ONCE_REG_IDX_OPABEX
].reg
) {
580 if ((once_regs
[ONCE_REG_IDX_OPABF11
].reg
& 1) == 0) {
581 LOG_DEBUG("%s conditional branch not supported yet (0x%" PRIx32
" 0x%" PRIx32
" 0x%" PRIx32
")",
583 (once_regs
[ONCE_REG_IDX_OPABF11
].reg
>> 1),
584 once_regs
[ONCE_REG_IDX_OPABDR
].reg
,
585 once_regs
[ONCE_REG_IDX_OPABEX
].reg
);
587 /* TODO: use disassembly to set correct pc offset
588 * read 2 words from OPABF11 and disasm the instruction
590 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] =
591 (once_regs
[ONCE_REG_IDX_OPABF11
].reg
>> 1) & 0x00FFFFFF;
593 if (once_regs
[ONCE_REG_IDX_OPABEX
].reg
==
594 once_regs
[ONCE_REG_IDX_OPABFR
].reg
)
595 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] =
596 once_regs
[ONCE_REG_IDX_OPABEX
].reg
;
598 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] =
599 once_regs
[ONCE_REG_IDX_OPABEX
].reg
- 1;
602 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] = once_regs
[ONCE_REG_IDX_OPABEX
].reg
;
604 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_PC
);
609 static int dsp563xx_reg_ssh_read(struct target
*target
)
613 struct dsp563xx_core_reg
*arch_info
;
614 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
616 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSH
].arch_info
;
618 /* get a valid stack pointer */
619 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 0);
622 sp
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
];
623 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SP
, 0);
627 /* get a valid stack count */
628 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SC
, 0);
632 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SC
, 0);
636 /* get a valid extended pointer */
637 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_EP
, 0);
641 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_EP
, 0);
648 err
= dsp563xx_reg_read(target
, arch_info
->eame
, &sp
);
652 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SC
, 1);
655 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SP
, 1);
658 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_EP
, 1);
663 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SSH
] = sp
;
664 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_SSH
);
669 static int dsp563xx_reg_ssh_write(struct target
*target
)
673 struct dsp563xx_core_reg
*arch_info
;
674 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
676 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSH
].arch_info
;
678 /* get a valid stack pointer */
679 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 0);
682 sp
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
];
686 /* write new stackpointer */
687 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
] = sp
;
688 err
= dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_SP
);
691 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SP
, 1);
695 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
,
696 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SSH
]);
700 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 1);
703 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SSH
, 1);
711 static int dsp563xx_reg_ssl_read(struct target
*target
)
715 struct dsp563xx_core_reg
*arch_info
;
716 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
718 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSL
].arch_info
;
720 /* get a valid stack pointer */
721 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 0);
724 sp
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
];
729 err
= dsp563xx_reg_read(target
, arch_info
->eame
, &sp
);
734 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SSL
] = sp
;
735 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_SSL
);
740 static int dsp563xx_read_register(struct target
*target
, int num
, int force
)
744 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
745 struct dsp563xx_core_reg
*arch_info
;
748 dsp563xx
->core_cache
->reg_list
[num
].valid
= 0;
750 if (!dsp563xx
->core_cache
->reg_list
[num
].valid
) {
751 arch_info
= dsp563xx
->core_cache
->reg_list
[num
].arch_info
;
753 switch (arch_info
->num
) {
754 case DSP563XX_REG_IDX_SSH
:
755 err
= dsp563xx_reg_ssh_read(target
);
757 case DSP563XX_REG_IDX_SSL
:
758 err
= dsp563xx_reg_ssl_read(target
);
760 case DSP563XX_REG_IDX_PC
:
761 err
= dsp563xx_reg_pc_read(target
);
763 case DSP563XX_REG_IDX_IPRC
:
764 case DSP563XX_REG_IDX_IPRP
:
765 case DSP563XX_REG_IDX_BCR
:
766 case DSP563XX_REG_IDX_DCR
:
767 case DSP563XX_REG_IDX_AAR0
:
768 case DSP563XX_REG_IDX_AAR1
:
769 case DSP563XX_REG_IDX_AAR2
:
770 case DSP563XX_REG_IDX_AAR3
:
771 err
= dsp563xx_reg_read_high_io(target
,
772 arch_info
->instr_mask
, &data
);
773 if (err
== ERROR_OK
) {
774 dsp563xx
->core_regs
[num
] = data
;
775 dsp563xx
->read_core_reg(target
, num
);
779 err
= dsp563xx_reg_read(target
, arch_info
->eame
, &data
);
780 if (err
== ERROR_OK
) {
781 dsp563xx
->core_regs
[num
] = data
;
782 dsp563xx
->read_core_reg(target
, num
);
791 static int dsp563xx_write_register(struct target
*target
, int num
, int force
)
794 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
795 struct dsp563xx_core_reg
*arch_info
;
798 dsp563xx
->core_cache
->reg_list
[num
].dirty
= 1;
800 if (dsp563xx
->core_cache
->reg_list
[num
].dirty
) {
801 arch_info
= dsp563xx
->core_cache
->reg_list
[num
].arch_info
;
803 dsp563xx
->write_core_reg(target
, num
);
805 switch (arch_info
->num
) {
806 case DSP563XX_REG_IDX_SSH
:
807 err
= dsp563xx_reg_ssh_write(target
);
809 case DSP563XX_REG_IDX_PC
:
810 /* pc is updated on resume, no need to write it here */
812 case DSP563XX_REG_IDX_IPRC
:
813 case DSP563XX_REG_IDX_IPRP
:
814 case DSP563XX_REG_IDX_BCR
:
815 case DSP563XX_REG_IDX_DCR
:
816 case DSP563XX_REG_IDX_AAR0
:
817 case DSP563XX_REG_IDX_AAR1
:
818 case DSP563XX_REG_IDX_AAR2
:
819 case DSP563XX_REG_IDX_AAR3
:
820 err
= dsp563xx_reg_write_high_io(target
,
821 arch_info
->instr_mask
,
822 dsp563xx
->core_regs
[num
]);
825 err
= dsp563xx_reg_write(target
,
826 arch_info
->instr_mask
,
827 dsp563xx
->core_regs
[num
]);
829 if ((err
== ERROR_OK
) && (arch_info
->num
== DSP563XX_REG_IDX_SP
)) {
830 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSH
].valid
=
832 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSL
].valid
=
843 static int dsp563xx_save_context(struct target
*target
)
845 int i
, err
= ERROR_OK
;
847 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++) {
848 err
= dsp563xx_read_register(target
, i
, 0);
856 static int dsp563xx_restore_context(struct target
*target
)
858 int i
, err
= ERROR_OK
;
860 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++) {
861 err
= dsp563xx_write_register(target
, i
, 0);
869 static void dsp563xx_invalidate_x_context(struct target
*target
,
874 struct dsp563xx_core_reg
*arch_info
;
875 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
877 if (addr_start
> ASM_REG_W_IPRC
)
879 if (addr_start
< ASM_REG_W_AAR3
)
882 for (i
= DSP563XX_REG_IDX_IPRC
; i
< DSP563XX_NUMCOREREGS
; i
++) {
883 arch_info
= dsp563xx
->core_cache
->reg_list
[i
].arch_info
;
885 if ((arch_info
->instr_mask
>= addr_start
) &&
886 (arch_info
->instr_mask
<= addr_end
)) {
887 dsp563xx
->core_cache
->reg_list
[i
].valid
= 0;
888 dsp563xx
->core_cache
->reg_list
[i
].dirty
= 0;
893 static int dsp563xx_target_create(struct target
*target
, Jim_Interp
*interp
)
895 struct dsp563xx_common
*dsp563xx
= calloc(1, sizeof(struct dsp563xx_common
));
898 return ERROR_COMMAND_SYNTAX_ERROR
;
900 dsp563xx
->jtag_info
.tap
= target
->tap
;
901 target
->arch_info
= dsp563xx
;
902 dsp563xx
->read_core_reg
= dsp563xx_read_core_reg
;
903 dsp563xx
->write_core_reg
= dsp563xx_write_core_reg
;
908 static int dsp563xx_init_target(struct command_context
*cmd_ctx
, struct target
*target
)
910 LOG_DEBUG("%s", __func__
);
912 dsp563xx_build_reg_cache(target
);
913 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
915 dsp563xx
->hardware_breakpoints_cleared
= 0;
916 dsp563xx
->hardware_breakpoint
[0].used
= BPU_NONE
;
921 static int dsp563xx_examine(struct target
*target
)
925 if (target
->tap
->hasidcode
== false) {
926 LOG_ERROR("no IDCODE present on device");
927 return ERROR_COMMAND_SYNTAX_ERROR
;
930 if (!target_was_examined(target
)) {
931 target_set_examined(target
);
933 /* examine core and chip derivate number */
934 chip
= (target
->tap
->idcode
>>12) & 0x3ff;
935 /* core number 0 means DSP563XX */
936 if (((chip
>>5)&0x1f) == 0)
939 LOG_INFO("DSP56%03" PRId32
" device found", chip
);
941 /* Clear all breakpoints */
942 dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OBCR
, 0);
948 static int dsp563xx_arch_state(struct target
*target
)
950 LOG_DEBUG("%s", __func__
);
954 #define DSP563XX_SR_SA (1<<17)
955 #define DSP563XX_SR_SC (1<<13)
957 static int dsp563xx_debug_once_init(struct target
*target
)
959 return dsp563xx_once_read_register(target
->tap
, 1, once_regs
, DSP563XX_NUMONCEREGS
);
962 static int dsp563xx_debug_init(struct target
*target
)
966 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
967 struct dsp563xx_core_reg
*arch_info
;
969 err
= dsp563xx_debug_once_init(target
);
973 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SR
].arch_info
;
975 /* check 24bit mode */
976 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SR
, 0);
980 sr
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SR
];
982 if (sr
& (DSP563XX_SR_SA
| DSP563XX_SR_SC
)) {
983 sr
&= ~(DSP563XX_SR_SA
| DSP563XX_SR_SC
);
985 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, arch_info
->instr_mask
, sr
);
988 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SR
].dirty
= 1;
991 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_N0
, 0);
994 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_N1
, 0);
997 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_M0
, 0);
1000 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_M1
, 0);
1001 if (err
!= ERROR_OK
)
1004 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_N0
] != 0x000000) {
1005 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N0
].arch_info
;
1006 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0x000000);
1007 if (err
!= ERROR_OK
)
1010 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N0
].dirty
= 1;
1012 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_N1
] != 0x000000) {
1013 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N1
].arch_info
;
1014 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0x000000);
1015 if (err
!= ERROR_OK
)
1018 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N1
].dirty
= 1;
1020 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_M0
] != 0xffffff) {
1021 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M0
].arch_info
;
1022 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0xffffff);
1023 if (err
!= ERROR_OK
)
1026 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M0
].dirty
= 1;
1028 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_M1
] != 0xffffff) {
1029 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M1
].arch_info
;
1030 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0xffffff);
1031 if (err
!= ERROR_OK
)
1034 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M1
].dirty
= 1;
1036 err
= dsp563xx_save_context(target
);
1037 if (err
!= ERROR_OK
)
1043 static int dsp563xx_jtag_debug_request(struct target
*target
)
1045 return dsp563xx_once_request_debug(target
->tap
, target
->state
== TARGET_RESET
);
1048 static int dsp563xx_poll(struct target
*target
)
1051 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1052 uint32_t once_status
= 0;
1055 state
= dsp563xx_once_target_status(target
->tap
);
1057 if (state
== TARGET_UNKNOWN
) {
1058 target
->state
= state
;
1059 LOG_ERROR("jtag status contains invalid mode value - communication failure");
1060 return ERROR_TARGET_FAILURE
;
1063 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OSCR
, &once_status
);
1064 if (err
!= ERROR_OK
)
1067 if ((once_status
& DSP563XX_ONCE_OSCR_DEBUG_M
) == DSP563XX_ONCE_OSCR_DEBUG_M
) {
1068 if (target
->state
!= TARGET_HALTED
) {
1069 target
->state
= TARGET_HALTED
;
1071 err
= dsp563xx_debug_init(target
);
1072 if (err
!= ERROR_OK
)
1075 if (once_status
& (DSP563XX_ONCE_OSCR_MBO
|DSP563XX_ONCE_OSCR_SWO
))
1076 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
1078 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1080 LOG_DEBUG("target->state: %s (%" PRIx32
")", target_state_name(target
), once_status
);
1081 LOG_INFO("halted: PC: 0x%" PRIx32
, dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
]);
1085 if (!dsp563xx
->hardware_breakpoints_cleared
) {
1086 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OBCR
, 0);
1087 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR0
, 0);
1088 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR1
, 0);
1089 dsp563xx
->hardware_breakpoints_cleared
= 1;
1095 static int dsp563xx_halt(struct target
*target
)
1099 LOG_DEBUG("%s", __func__
);
1101 if (target
->state
== TARGET_HALTED
) {
1102 LOG_DEBUG("target was already halted");
1106 if (target
->state
== TARGET_UNKNOWN
)
1107 LOG_WARNING("target was in unknown state when halt was requested");
1109 err
= dsp563xx_jtag_debug_request(target
);
1110 if (err
!= ERROR_OK
)
1113 target
->debug_reason
= DBG_REASON_DBGRQ
;
1118 static int dsp563xx_resume(struct target
*target
,
1120 target_addr_t address
,
1121 int handle_breakpoints
,
1122 int debug_execution
)
1125 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1127 /* check if pc was changed and resume want to execute the next address
1128 * if pc was changed from gdb or other interface we will
1129 * jump to this address and don't execute the next address
1130 * this will not affect the resume command with an address argument
1131 * because current is set to zero then
1133 if (current
&& dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].dirty
) {
1134 dsp563xx_write_core_reg(target
, DSP563XX_REG_IDX_PC
);
1135 address
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
];
1139 LOG_DEBUG("%s %08X %08X", __func__
, current
, (unsigned) address
);
1141 err
= dsp563xx_restore_context(target
);
1142 if (err
!= ERROR_OK
)
1144 register_cache_invalidate(dsp563xx
->core_cache
);
1147 /* restore pipeline registers and go */
1148 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
,
1149 once_regs
[ONCE_REG_IDX_OPILR
].reg
);
1150 if (err
!= ERROR_OK
)
1152 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
|
1153 DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
,
1154 once_regs
[ONCE_REG_IDX_OPDBR
].reg
);
1155 if (err
!= ERROR_OK
)
1158 /* set to go register and jump */
1159 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
, INSTR_JUMP
);
1160 if (err
!= ERROR_OK
)
1162 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_PDBGOTO
|
1163 DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
, address
);
1164 if (err
!= ERROR_OK
)
1168 target
->state
= TARGET_RUNNING
;
1170 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1175 static int dsp563xx_step_ex(struct target
*target
,
1178 int handle_breakpoints
,
1182 uint32_t once_status
;
1183 uint32_t dr_in
, cnt
;
1184 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1186 if (target
->state
!= TARGET_HALTED
) {
1187 LOG_DEBUG("target was not halted");
1191 /* check if pc was changed and step want to execute the next address
1192 * if pc was changed from gdb or other interface we will
1193 * jump to this address and don't execute the next address
1194 * this will not affect the step command with an address argument
1195 * because current is set to zero then
1197 if (current
&& dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].dirty
) {
1198 dsp563xx_write_core_reg(target
, DSP563XX_REG_IDX_PC
);
1199 address
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
];
1203 LOG_DEBUG("%s %08X %08X", __func__
, current
, (unsigned) address
);
1205 err
= dsp563xx_jtag_debug_request(target
);
1206 if (err
!= ERROR_OK
)
1208 err
= dsp563xx_restore_context(target
);
1209 if (err
!= ERROR_OK
)
1212 /* reset trace mode */
1213 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OSCR
, 0x000000);
1214 if (err
!= ERROR_OK
)
1216 /* enable trace mode */
1217 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OSCR
, DSP563XX_ONCE_OSCR_TME
);
1218 if (err
!= ERROR_OK
)
1223 /* on JUMP we need one extra cycle */
1227 /* load step counter with N-1 */
1228 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OTC
, cnt
);
1229 if (err
!= ERROR_OK
)
1233 /* restore pipeline registers and go */
1234 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
,
1235 once_regs
[ONCE_REG_IDX_OPILR
].reg
);
1236 if (err
!= ERROR_OK
)
1238 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
|
1239 DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
,
1240 once_regs
[ONCE_REG_IDX_OPDBR
].reg
);
1241 if (err
!= ERROR_OK
)
1244 /* set to go register and jump */
1245 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
, INSTR_JUMP
);
1246 if (err
!= ERROR_OK
)
1248 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_PDBGOTO
|
1249 DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
,
1251 if (err
!= ERROR_OK
)
1256 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OSCR
, &once_status
);
1257 if (err
!= ERROR_OK
)
1260 if (once_status
& DSP563XX_ONCE_OSCR_TO
) {
1261 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OPABFR
, &dr_in
);
1262 if (err
!= ERROR_OK
)
1264 LOG_DEBUG("fetch: %08X", (unsigned) dr_in
&0x00ffffff);
1265 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OPABDR
, &dr_in
);
1266 if (err
!= ERROR_OK
)
1268 LOG_DEBUG("decode: %08X", (unsigned) dr_in
&0x00ffffff);
1269 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OPABEX
, &dr_in
);
1270 if (err
!= ERROR_OK
)
1272 LOG_DEBUG("execute: %08X", (unsigned) dr_in
&0x00ffffff);
1274 /* reset trace mode */
1275 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OSCR
, 0x000000);
1276 if (err
!= ERROR_OK
)
1279 register_cache_invalidate(dsp563xx
->core_cache
);
1280 err
= dsp563xx_debug_init(target
);
1281 if (err
!= ERROR_OK
)
1291 static int dsp563xx_step(struct target
*target
,
1293 target_addr_t address
,
1294 int handle_breakpoints
)
1297 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1299 if (target
->state
!= TARGET_HALTED
) {
1300 LOG_WARNING("target not halted");
1301 return ERROR_TARGET_NOT_HALTED
;
1304 err
= dsp563xx_step_ex(target
, current
, address
, handle_breakpoints
, 0);
1305 if (err
!= ERROR_OK
)
1308 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1309 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1311 LOG_INFO("halted: PC: 0x%" PRIx32
, dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
]);
1316 static int dsp563xx_assert_reset(struct target
*target
)
1319 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1320 enum reset_types jtag_reset_config
= jtag_get_reset_config();
1322 if (jtag_reset_config
& RESET_HAS_SRST
) {
1323 /* default to asserting srst */
1324 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
1325 jtag_add_reset(1, 1);
1327 jtag_add_reset(0, 1);
1330 target
->state
= TARGET_RESET
;
1331 jtag_add_sleep(5000);
1333 /* registers are now invalid */
1334 register_cache_invalidate(dsp563xx
->core_cache
);
1336 if (target
->reset_halt
) {
1337 retval
= target_halt(target
);
1338 if (retval
!= ERROR_OK
)
1342 LOG_DEBUG("%s", __func__
);
1346 static int dsp563xx_deassert_reset(struct target
*target
)
1350 /* deassert reset lines */
1351 jtag_add_reset(0, 0);
1353 err
= dsp563xx_poll(target
);
1354 if (err
!= ERROR_OK
)
1357 if (target
->reset_halt
) {
1358 if (target
->state
== TARGET_HALTED
) {
1359 /* after a reset the cpu jmp to the
1360 * reset vector and need 2 cycles to fill
1361 * the cache (fetch,decode,excecute)
1363 err
= dsp563xx_step_ex(target
, 1, 0, 1, 1);
1364 if (err
!= ERROR_OK
)
1368 target
->state
= TARGET_RUNNING
;
1370 LOG_DEBUG("%s", __func__
);
1374 static int dsp563xx_run_algorithm(struct target
*target
,
1375 int num_mem_params
, struct mem_param
*mem_params
,
1376 int num_reg_params
, struct reg_param
*reg_params
,
1377 target_addr_t entry_point
, target_addr_t exit_point
,
1378 int timeout_ms
, void *arch_info
)
1381 int retval
= ERROR_OK
;
1382 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1384 if (target
->state
!= TARGET_HALTED
) {
1385 LOG_WARNING("target not halted");
1386 return ERROR_TARGET_NOT_HALTED
;
1389 for (i
= 0; i
< num_mem_params
; i
++) {
1390 if (mem_params
[i
].direction
== PARAM_IN
)
1392 retval
= target_write_buffer(target
, mem_params
[i
].address
,
1393 mem_params
[i
].size
, mem_params
[i
].value
);
1394 if (retval
!= ERROR_OK
)
1398 for (i
= 0; i
< num_reg_params
; i
++) {
1399 if (reg_params
[i
].direction
== PARAM_IN
)
1402 struct reg
*reg
= register_get_by_name(dsp563xx
->core_cache
,
1403 reg_params
[i
].reg_name
,
1407 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
1411 if (reg
->size
!= reg_params
[i
].size
) {
1412 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1413 reg_params
[i
].reg_name
);
1417 retval
= dsp563xx_set_core_reg(reg
, reg_params
[i
].value
);
1418 if (retval
!= ERROR_OK
)
1423 retval
= target_resume(target
, 0, entry_point
, 1, 1);
1424 if (retval
!= ERROR_OK
)
1427 retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
);
1428 if (retval
!= ERROR_OK
)
1431 for (i
= 0; i
< num_mem_params
; i
++) {
1432 if (mem_params
[i
].direction
!= PARAM_OUT
)
1433 retval
= target_read_buffer(target
,
1434 mem_params
[i
].address
,
1436 mem_params
[i
].value
);
1437 if (retval
!= ERROR_OK
)
1441 for (i
= 0; i
< num_reg_params
; i
++) {
1442 if (reg_params
[i
].direction
!= PARAM_OUT
) {
1444 struct reg
*reg
= register_get_by_name(dsp563xx
->core_cache
,
1445 reg_params
[i
].reg_name
,
1448 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
1452 if (reg
->size
!= reg_params
[i
].size
) {
1454 "BUG: register '%s' size doesn't match reg_params[i].size",
1455 reg_params
[i
].reg_name
);
1459 buf_set_u32(reg_params
[i
].value
, 0, 32, buf_get_u32(reg
->value
, 0, 32));
1466 /* global command context from openocd.c */
1467 extern struct command_context
*global_cmd_ctx
;
1469 static int dsp563xx_get_default_memory(void)
1475 if (!global_cmd_ctx
)
1478 interp
= global_cmd_ctx
->interp
;
1483 memspace
= Jim_GetGlobalVariableStr(interp
, "memspace", JIM_NONE
);
1488 c
= (char *)Jim_GetString(memspace
, NULL
);
1507 static int dsp563xx_read_memory_core(struct target
*target
,
1515 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1517 uint32_t data
, move_cmd
= 0;
1521 "memtype: %d address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
1527 if (target
->state
!= TARGET_HALTED
) {
1528 LOG_WARNING("target not halted");
1529 return ERROR_TARGET_NOT_HALTED
;
1534 /* TODO: mark effected queued registers */
1535 move_cmd
= 0x61d800;
1538 move_cmd
= 0x69d800;
1541 move_cmd
= 0x07d891;
1544 return ERROR_COMMAND_SYNTAX_ERROR
;
1547 /* we use r0 to store temporary data */
1548 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
1549 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
1550 /* we use r1 to store temporary data */
1551 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].valid
)
1552 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R1
);
1554 /* r0 is no longer valid on target */
1555 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= 1;
1556 /* r1 is no longer valid on target */
1557 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].dirty
= 1;
1562 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, 0x60F400, address
);
1563 if (err
!= ERROR_OK
)
1566 for (i
= 0; i
< x
; i
++) {
1567 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, move_cmd
);
1568 if (err
!= ERROR_OK
)
1570 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, 0x08D13C);
1571 if (err
!= ERROR_OK
)
1573 err
= dsp563xx_once_reg_read(target
->tap
, 0,
1574 DSP563XX_ONCE_OGDBR
, (uint32_t *)(void *)b
);
1575 if (err
!= ERROR_OK
)
1580 /* flush the jtag queue */
1581 err
= jtag_execute_queue();
1582 if (err
!= ERROR_OK
)
1585 /* walk over the buffer and fix target endianness */
1588 for (i
= 0; i
< x
; i
++) {
1589 data
= buf_get_u32(b
, 0, 32) & 0x00FFFFFF;
1590 /* LOG_DEBUG("R: %08X", *((uint32_t*)b)); */
1591 target_buffer_set_u32(target
, b
, data
);
1598 static int dsp563xx_read_memory(struct target
*target
,
1600 target_addr_t address
,
1607 uint8_t *buffer_y
, *buffer_x
;
1609 /* if size equals zero we are called from target read memory
1610 * and have to handle the parameter here */
1611 if ((size
== 0) && (count
!= 0)) {
1615 LOG_DEBUG("size is not aligned to 4 byte");
1617 count
= (count
- size
) / 4;
1621 /* we only support 4 byte aligned data */
1622 if ((size
!= 4) || (!count
))
1623 return ERROR_COMMAND_SYNTAX_ERROR
;
1625 if (mem_type
!= MEM_L
)
1626 return dsp563xx_read_memory_core(target
, mem_type
, address
, size
, count
, buffer
);
1628 buffer_y
= malloc(size
* count
);
1630 return ERROR_COMMAND_SYNTAX_ERROR
;
1632 buffer_x
= malloc(size
* count
);
1635 return ERROR_COMMAND_SYNTAX_ERROR
;
1638 err
= dsp563xx_read_memory_core(target
, MEM_Y
, address
, size
, count
/ 2, buffer_y
);
1640 if (err
!= ERROR_OK
) {
1646 err
= dsp563xx_read_memory_core(target
, MEM_X
, address
, size
, count
/ 2, buffer_x
);
1648 if (err
!= ERROR_OK
) {
1654 for (i
= 0, i1
= 0; i
< count
; i
+= 2, i1
++) {
1655 buf_set_u32(buffer
+ i
*sizeof(uint32_t), 0, 32,
1656 buf_get_u32(buffer_y
+ i1
* sizeof(uint32_t), 0, 32));
1657 buf_set_u32(buffer
+ (i
+ 1) * sizeof(uint32_t), 0, 32,
1658 buf_get_u32(buffer_x
+ i1
* sizeof(uint32_t), 0, 32));
1667 static int dsp563xx_read_memory_default(struct target
*target
,
1668 target_addr_t address
,
1674 return dsp563xx_read_memory(target
,
1675 dsp563xx_get_default_memory(), address
, size
, count
, buffer
);
1678 static int dsp563xx_read_buffer_default(struct target
*target
,
1679 target_addr_t address
,
1684 return dsp563xx_read_memory(target
, dsp563xx_get_default_memory(), address
, size
, 0,
1688 static int dsp563xx_write_memory_core(struct target
*target
,
1690 target_addr_t address
,
1693 const uint8_t *buffer
)
1696 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1698 uint32_t data
, move_cmd
= 0;
1702 "memtype: %d address: 0x%8.8" TARGET_PRIxADDR
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
1708 if (target
->state
!= TARGET_HALTED
) {
1709 LOG_WARNING("target not halted");
1710 return ERROR_TARGET_NOT_HALTED
;
1715 /* invalidate affected x registers */
1716 dsp563xx_invalidate_x_context(target
, address
, address
+ count
- 1);
1717 move_cmd
= 0x615800;
1720 move_cmd
= 0x695800;
1723 move_cmd
= 0x075891;
1726 return ERROR_COMMAND_SYNTAX_ERROR
;
1729 /* we use r0 to store temporary data */
1730 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
1731 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
1732 /* we use r1 to store temporary data */
1733 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].valid
)
1734 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R1
);
1736 /* r0 is no longer valid on target */
1737 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= 1;
1738 /* r1 is no longer valid on target */
1739 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].dirty
= 1;
1744 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, 0x60F400, address
);
1745 if (err
!= ERROR_OK
)
1748 for (i
= 0; i
< x
; i
++) {
1749 data
= target_buffer_get_u32(target
, b
);
1751 /* LOG_DEBUG("W: %08X", data); */
1755 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 0, 0x61F400, data
);
1756 if (err
!= ERROR_OK
)
1758 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, move_cmd
);
1759 if (err
!= ERROR_OK
)
1764 /* flush the jtag queue */
1765 err
= jtag_execute_queue();
1766 if (err
!= ERROR_OK
)
1772 static int dsp563xx_write_memory(struct target
*target
,
1774 target_addr_t address
,
1777 const uint8_t *buffer
)
1781 uint8_t *buffer_y
, *buffer_x
;
1783 /* if size equals zero we are called from target write memory
1784 * and have to handle the parameter here */
1785 if ((size
== 0) && (count
!= 0)) {
1789 LOG_DEBUG("size is not aligned to 4 byte");
1791 count
= (count
- size
) / 4;
1795 /* we only support 4 byte aligned data */
1796 if ((size
!= 4) || (!count
))
1797 return ERROR_COMMAND_SYNTAX_ERROR
;
1799 if (mem_type
!= MEM_L
)
1800 return dsp563xx_write_memory_core(target
, mem_type
, address
, size
, count
, buffer
);
1802 buffer_y
= malloc(size
* count
);
1804 return ERROR_COMMAND_SYNTAX_ERROR
;
1806 buffer_x
= malloc(size
* count
);
1809 return ERROR_COMMAND_SYNTAX_ERROR
;
1812 for (i
= 0, i1
= 0; i
< count
; i
+= 2, i1
++) {
1813 buf_set_u32(buffer_y
+ i1
* sizeof(uint32_t), 0, 32,
1814 buf_get_u32(buffer
+ i
* sizeof(uint32_t), 0, 32));
1815 buf_set_u32(buffer_x
+ i1
* sizeof(uint32_t), 0, 32,
1816 buf_get_u32(buffer
+ (i
+ 1) * sizeof(uint32_t), 0, 32));
1819 err
= dsp563xx_write_memory_core(target
, MEM_Y
, address
, size
, count
/ 2, buffer_y
);
1821 if (err
!= ERROR_OK
) {
1827 err
= dsp563xx_write_memory_core(target
, MEM_X
, address
, size
, count
/ 2, buffer_x
);
1829 if (err
!= ERROR_OK
) {
1841 static int dsp563xx_write_memory_default(struct target
*target
,
1842 target_addr_t address
,
1845 const uint8_t *buffer
)
1847 return dsp563xx_write_memory(target
,
1848 dsp563xx_get_default_memory(), address
, size
, count
, buffer
);
1851 static int dsp563xx_write_buffer_default(struct target
*target
,
1852 target_addr_t address
,
1854 const uint8_t *buffer
)
1856 return dsp563xx_write_memory(target
, dsp563xx_get_default_memory(), address
, size
, 0,
1861 * Exit with error here, because we support watchpoints over a custom command.
1862 * This is because the DSP has separate X,Y,P memspace which is not compatible to the
1863 * traditional watchpoint logic.
1865 static int dsp563xx_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1867 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1871 * @see dsp563xx_add_watchpoint
1873 static int dsp563xx_remove_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1875 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1878 static void handle_md_output(struct command_context
*cmd_ctx
,
1879 struct target
*target
,
1883 const uint8_t *buffer
)
1885 const unsigned line_bytecnt
= 32;
1886 unsigned line_modulo
= line_bytecnt
/ size
;
1888 char output
[line_bytecnt
* 4 + 1];
1889 unsigned output_len
= 0;
1891 const char *value_fmt
;
1894 value_fmt
= "%8.8x ";
1897 value_fmt
= "%4.4x ";
1900 value_fmt
= "%2.2x ";
1903 /* "can't happen", caller checked */
1904 LOG_ERROR("invalid memory read size: %u", size
);
1908 for (unsigned i
= 0; i
< count
; i
++) {
1909 if (i
% line_modulo
== 0)
1910 output_len
+= snprintf(output
+ output_len
,
1911 sizeof(output
) - output_len
,
1913 (unsigned) (address
+ i
));
1916 const uint8_t *value_ptr
= buffer
+ i
* size
;
1919 value
= target_buffer_get_u32(target
, value_ptr
);
1922 value
= target_buffer_get_u16(target
, value_ptr
);
1927 output_len
+= snprintf(output
+ output_len
,
1928 sizeof(output
) - output_len
,
1932 if ((i
% line_modulo
== line_modulo
- 1) || (i
== count
- 1)) {
1933 command_print(cmd_ctx
, "%s", output
);
1939 static int dsp563xx_add_custom_watchpoint(struct target
*target
, uint32_t address
, uint32_t memType
,
1940 enum watchpoint_rw rw
, enum watchpoint_condition cond
)
1943 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1945 bool wasRunning
= false;
1946 /* Only set breakpoint when halted */
1947 if (target
->state
!= TARGET_HALTED
) {
1948 dsp563xx_halt(target
);
1952 if (dsp563xx
->hardware_breakpoint
[0].used
) {
1953 LOG_ERROR("Cannot add watchpoint. Hardware resource already used.");
1954 err
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1957 uint32_t obcr_value
= 0;
1958 if (err
== ERROR_OK
) {
1959 obcr_value
|= OBCR_b0_or_b1
;
1962 obcr_value
|= OBCR_BP_MEM_X
;
1965 obcr_value
|= OBCR_BP_MEM_Y
;
1968 obcr_value
|= OBCR_BP_MEM_P
;
1971 LOG_ERROR("Unknown memType parameter (%" PRIu32
")", memType
);
1972 err
= ERROR_TARGET_INVALID
;
1976 if (err
== ERROR_OK
) {
1979 obcr_value
|= OBCR_BP_0(OBCR_BP_ON_READ
);
1982 obcr_value
|= OBCR_BP_0(OBCR_BP_ON_WRITE
);
1985 obcr_value
|= OBCR_BP_0(OBCR_BP_ON_READ
|OBCR_BP_ON_WRITE
);
1988 LOG_ERROR("Unsupported write mode (%d)", rw
);
1989 err
= ERROR_TARGET_INVALID
;
1993 if (err
== ERROR_OK
) {
1996 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_EQUAL
);
1999 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_NOT_EQUAL
);
2002 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_LESS_THAN
);
2005 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_GREATER_THAN
);
2008 LOG_ERROR("Unsupported condition code (%d)", cond
);
2009 err
= ERROR_TARGET_INVALID
;
2013 if (err
== ERROR_OK
)
2014 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR0
, address
);
2016 if (err
== ERROR_OK
)
2017 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR1
, 0x0);
2019 if (err
== ERROR_OK
)
2020 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OBCR
, obcr_value
);
2022 if (err
== ERROR_OK
) {
2023 /* You should write the memory breakpoint counter to 0 */
2024 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMBC
, 0);
2027 if (err
== ERROR_OK
) {
2028 /* You should write the memory breakpoint counter to 0 */
2029 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OTC
, 0);
2032 if (err
== ERROR_OK
)
2033 dsp563xx
->hardware_breakpoint
[0].used
= BPU_WATCHPOINT
;
2035 if (err
== ERROR_OK
&& wasRunning
) {
2036 /* Resume from current PC */
2037 err
= dsp563xx_resume(target
, 1, 0x0, 0, 0);
2043 static int dsp563xx_remove_custom_watchpoint(struct target
*target
)
2046 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
2048 if (dsp563xx
->hardware_breakpoint
[0].used
!= BPU_WATCHPOINT
) {
2049 LOG_ERROR("Cannot remove watchpoint, as no watchpoint is currently configured!");
2050 err
= ERROR_TARGET_INVALID
;
2053 if (err
== ERROR_OK
) {
2054 /* Clear watchpoint by clearing OBCR. */
2055 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OBCR
, 0);
2058 if (err
== ERROR_OK
)
2059 dsp563xx
->hardware_breakpoint
[0].used
= BPU_NONE
;
2064 COMMAND_HANDLER(dsp563xx_add_watchpoint_command
)
2067 struct target
*target
= get_current_target(CMD_CTX
);
2069 uint32_t mem_type
= 0;
2070 switch (CMD_NAME
[2]) {
2081 return ERROR_COMMAND_SYNTAX_ERROR
;
2085 return ERROR_COMMAND_SYNTAX_ERROR
;
2087 uint32_t address
= 0;
2089 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], address
);
2091 enum watchpoint_condition cond
;
2092 switch (CMD_ARGV
[0][0]) {
2106 return ERROR_COMMAND_SYNTAX_ERROR
;
2109 enum watchpoint_rw rw
;
2110 switch (CMD_ARGV
[1][0]) {
2121 return ERROR_COMMAND_SYNTAX_ERROR
;
2124 err
= dsp563xx_add_custom_watchpoint(target
, address
, mem_type
, rw
, cond
);
2129 /* Adding a breakpoint using the once breakpoint logic.
2130 * Note that this mechanism is a true hw breakpoint and is share between the watchpoint logic.
2131 * This means, you can only have one breakpoint/watchpoint at any time.
2133 static int dsp563xx_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
2135 return dsp563xx_add_custom_watchpoint(target
, breakpoint
->address
, MEM_P
, WPT_READ
, EQUAL
);
2138 static int dsp563xx_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
2140 return dsp563xx_remove_custom_watchpoint(target
);
2143 COMMAND_HANDLER(dsp563xx_remove_watchpoint_command
)
2145 struct target
*target
= get_current_target(CMD_CTX
);
2147 return dsp563xx_remove_custom_watchpoint(target
);
2150 COMMAND_HANDLER(dsp563xx_mem_command
)
2152 struct target
*target
= get_current_target(CMD_CTX
);
2155 uint32_t address
= 0;
2156 uint32_t count
= 1, i
;
2157 uint32_t pattern
= 0;
2159 uint8_t *buffer
, *b
;
2161 switch (CMD_NAME
[1]) {
2169 return ERROR_COMMAND_SYNTAX_ERROR
;
2172 switch (CMD_NAME
[3]) {
2183 return ERROR_COMMAND_SYNTAX_ERROR
;
2187 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
2189 if (read_mem
== 0) {
2191 return ERROR_COMMAND_SYNTAX_ERROR
;
2193 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], pattern
);
2195 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], count
);
2198 if (read_mem
== 1) {
2200 return ERROR_COMMAND_SYNTAX_ERROR
;
2202 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], count
);
2205 buffer
= calloc(count
, sizeof(uint32_t));
2207 if (read_mem
== 1) {
2208 err
= dsp563xx_read_memory(target
, mem_type
, address
, sizeof(uint32_t),
2210 if (err
== ERROR_OK
)
2211 handle_md_output(CMD_CTX
, target
, address
, sizeof(uint32_t), count
, buffer
);
2216 for (i
= 0; i
< count
; i
++) {
2217 target_buffer_set_u32(target
, b
, pattern
);
2221 err
= dsp563xx_write_memory(target
,
2234 static const struct command_registration dsp563xx_command_handlers
[] = {
2237 .handler
= dsp563xx_mem_command
,
2238 .mode
= COMMAND_EXEC
,
2239 .help
= "write x memory words",
2240 .usage
= "address value [count]",
2244 .handler
= dsp563xx_mem_command
,
2245 .mode
= COMMAND_EXEC
,
2246 .help
= "write y memory words",
2247 .usage
= "address value [count]",
2251 .handler
= dsp563xx_mem_command
,
2252 .mode
= COMMAND_EXEC
,
2253 .help
= "write p memory words",
2254 .usage
= "address value [count]",
2258 .handler
= dsp563xx_mem_command
,
2259 .mode
= COMMAND_EXEC
,
2260 .help
= "display x memory words",
2261 .usage
= "address [count]",
2265 .handler
= dsp563xx_mem_command
,
2266 .mode
= COMMAND_EXEC
,
2267 .help
= "display y memory words",
2268 .usage
= "address [count]",
2272 .handler
= dsp563xx_mem_command
,
2273 .mode
= COMMAND_EXEC
,
2274 .help
= "display p memory words",
2275 .usage
= "address [count]",
2278 * Watchpoint commands
2282 .handler
= dsp563xx_add_watchpoint_command
,
2283 .mode
= COMMAND_EXEC
,
2284 .help
= "Create p memspace watchpoint",
2285 .usage
= "(>|<|=|!) (r|w|a) address",
2289 .handler
= dsp563xx_add_watchpoint_command
,
2290 .mode
= COMMAND_EXEC
,
2291 .help
= "Create x memspace watchpoint",
2292 .usage
= "(>|<|=|!) (r|w|a) address",
2296 .handler
= dsp563xx_add_watchpoint_command
,
2297 .mode
= COMMAND_EXEC
,
2298 .help
= "Create y memspace watchpoint",
2299 .usage
= "(>|<|=|!) (r|w|a) address",
2303 .handler
= dsp563xx_remove_watchpoint_command
,
2304 .mode
= COMMAND_EXEC
,
2305 .help
= "remove watchpoint custom",
2308 COMMAND_REGISTRATION_DONE
2311 /** Holds methods for DSP563XX targets. */
2312 struct target_type dsp563xx_target
= {
2315 .poll
= dsp563xx_poll
,
2316 .arch_state
= dsp563xx_arch_state
,
2318 .get_gdb_reg_list
= dsp563xx_get_gdb_reg_list
,
2320 .halt
= dsp563xx_halt
,
2321 .resume
= dsp563xx_resume
,
2322 .step
= dsp563xx_step
,
2324 .assert_reset
= dsp563xx_assert_reset
,
2325 .deassert_reset
= dsp563xx_deassert_reset
,
2327 .read_memory
= dsp563xx_read_memory_default
,
2328 .write_memory
= dsp563xx_write_memory_default
,
2330 .read_buffer
= dsp563xx_read_buffer_default
,
2331 .write_buffer
= dsp563xx_write_buffer_default
,
2333 .run_algorithm
= dsp563xx_run_algorithm
,
2335 .add_breakpoint
= dsp563xx_add_breakpoint
,
2336 .remove_breakpoint
= dsp563xx_remove_breakpoint
,
2337 .add_watchpoint
= dsp563xx_add_watchpoint
,
2338 .remove_watchpoint
= dsp563xx_remove_watchpoint
,
2340 .commands
= dsp563xx_command_handlers
,
2341 .target_create
= dsp563xx_target_create
,
2342 .init_target
= dsp563xx_init_target
,
2343 .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)