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 /* instruction 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
= true;
388 dsp563xx
->core_cache
->reg_list
[num
].dirty
= false;
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
= true;
404 dsp563xx
->core_cache
->reg_list
[num
].dirty
= false;
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
= false;
477 reg_list
[i
].valid
= false;
478 reg_list
[i
].exist
= true;
479 reg_list
[i
].type
= &dsp563xx_reg_type
;
480 reg_list
[i
].arch_info
= &arch_info
[i
];
484 static int dsp563xx_read_register(struct target
*target
, int num
, int force
);
485 static int dsp563xx_write_register(struct target
*target
, int num
, int force
);
487 static int dsp563xx_reg_read_high_io(struct target
*target
, uint32_t instr_mask
, uint32_t *data
)
491 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
493 /* we use r0 to store temporary data */
494 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
495 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
497 /* move source memory to r0 */
498 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 0, EAME_R0
, instr_mask
);
499 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, instr
);
502 /* move r0 to debug register */
503 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 1, EAME_R0
, 0xfffffc);
504 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 1, instr
);
507 /* read debug register */
508 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OGDBR
, data
);
511 /* r0 is no longer valid on target */
512 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= true;
517 static int dsp563xx_reg_write_high_io(struct target
*target
, uint32_t instr_mask
, uint32_t data
)
521 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
523 /* we use r0 to store temporary data */
524 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
525 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
527 /* move data to r0 */
528 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 0, 0x60F400, data
);
531 /* move r0 to destination memory */
532 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 1, EAME_R0
, instr_mask
);
533 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 1, instr
);
537 /* r0 is no longer valid on target */
538 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= true;
543 static int dsp563xx_reg_read(struct target
*target
, uint32_t eame
, uint32_t *data
)
548 instr
= INSTR_MOVEP_REG_HIO(MEM_X
, 1, eame
, 0xfffffc);
549 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, instr
);
553 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 1, 0x000000);
556 /* read debug register */
557 return dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OGDBR
, data
);
560 static int dsp563xx_reg_write(struct target
*target
, uint32_t instr_mask
, uint32_t data
)
564 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 0, instr_mask
, data
);
568 return dsp563xx_once_execute_sw_ir(target
->tap
, 1, 0x000000);
571 static int dsp563xx_reg_pc_read(struct target
*target
)
573 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
575 /* pc was changed, nothing todo */
576 if (dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].dirty
)
579 /* conditional branch check */
580 if (once_regs
[ONCE_REG_IDX_OPABDR
].reg
== once_regs
[ONCE_REG_IDX_OPABEX
].reg
) {
581 if ((once_regs
[ONCE_REG_IDX_OPABF11
].reg
& 1) == 0) {
582 LOG_DEBUG("%s conditional branch not supported yet (0x%" PRIx32
" 0x%" PRIx32
" 0x%" PRIx32
")",
584 (once_regs
[ONCE_REG_IDX_OPABF11
].reg
>> 1),
585 once_regs
[ONCE_REG_IDX_OPABDR
].reg
,
586 once_regs
[ONCE_REG_IDX_OPABEX
].reg
);
588 /* TODO: use disassembly to set correct pc offset
589 * read 2 words from OPABF11 and disasm the instruction
591 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] =
592 (once_regs
[ONCE_REG_IDX_OPABF11
].reg
>> 1) & 0x00FFFFFF;
594 if (once_regs
[ONCE_REG_IDX_OPABEX
].reg
==
595 once_regs
[ONCE_REG_IDX_OPABFR
].reg
)
596 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] =
597 once_regs
[ONCE_REG_IDX_OPABEX
].reg
;
599 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] =
600 once_regs
[ONCE_REG_IDX_OPABEX
].reg
- 1;
603 dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
] = once_regs
[ONCE_REG_IDX_OPABEX
].reg
;
605 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_PC
);
610 static int dsp563xx_reg_ssh_read(struct target
*target
)
614 struct dsp563xx_core_reg
*arch_info
;
615 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
617 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSH
].arch_info
;
619 /* get a valid stack pointer */
620 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 0);
623 sp
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
];
624 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SP
, 0);
628 /* get a valid stack count */
629 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SC
, 0);
633 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SC
, 0);
637 /* get a valid extended pointer */
638 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_EP
, 0);
642 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_EP
, 0);
649 err
= dsp563xx_reg_read(target
, arch_info
->eame
, &sp
);
653 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SC
, 1);
656 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SP
, 1);
659 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_EP
, 1);
664 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SSH
] = sp
;
665 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_SSH
);
670 static int dsp563xx_reg_ssh_write(struct target
*target
)
674 struct dsp563xx_core_reg
*arch_info
;
675 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
677 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSH
].arch_info
;
679 /* get a valid stack pointer */
680 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 0);
683 sp
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
];
687 /* write new stackpointer */
688 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
] = sp
;
689 err
= dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_SP
);
692 err
= dsp563xx_write_register(target
, DSP563XX_REG_IDX_SP
, 1);
696 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
,
697 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SSH
]);
701 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 1);
704 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SSH
, 1);
712 static int dsp563xx_reg_ssl_read(struct target
*target
)
716 struct dsp563xx_core_reg
*arch_info
;
717 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
719 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSL
].arch_info
;
721 /* get a valid stack pointer */
722 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SP
, 0);
725 sp
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SP
];
730 err
= dsp563xx_reg_read(target
, arch_info
->eame
, &sp
);
735 dsp563xx
->core_regs
[DSP563XX_REG_IDX_SSL
] = sp
;
736 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_SSL
);
741 static int dsp563xx_read_register(struct target
*target
, int num
, int force
)
745 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
746 struct dsp563xx_core_reg
*arch_info
;
749 dsp563xx
->core_cache
->reg_list
[num
].valid
= false;
751 if (!dsp563xx
->core_cache
->reg_list
[num
].valid
) {
752 arch_info
= dsp563xx
->core_cache
->reg_list
[num
].arch_info
;
754 switch (arch_info
->num
) {
755 case DSP563XX_REG_IDX_SSH
:
756 err
= dsp563xx_reg_ssh_read(target
);
758 case DSP563XX_REG_IDX_SSL
:
759 err
= dsp563xx_reg_ssl_read(target
);
761 case DSP563XX_REG_IDX_PC
:
762 err
= dsp563xx_reg_pc_read(target
);
764 case DSP563XX_REG_IDX_IPRC
:
765 case DSP563XX_REG_IDX_IPRP
:
766 case DSP563XX_REG_IDX_BCR
:
767 case DSP563XX_REG_IDX_DCR
:
768 case DSP563XX_REG_IDX_AAR0
:
769 case DSP563XX_REG_IDX_AAR1
:
770 case DSP563XX_REG_IDX_AAR2
:
771 case DSP563XX_REG_IDX_AAR3
:
772 err
= dsp563xx_reg_read_high_io(target
,
773 arch_info
->instr_mask
, &data
);
774 if (err
== ERROR_OK
) {
775 dsp563xx
->core_regs
[num
] = data
;
776 dsp563xx
->read_core_reg(target
, num
);
780 err
= dsp563xx_reg_read(target
, arch_info
->eame
, &data
);
781 if (err
== ERROR_OK
) {
782 dsp563xx
->core_regs
[num
] = data
;
783 dsp563xx
->read_core_reg(target
, num
);
792 static int dsp563xx_write_register(struct target
*target
, int num
, int force
)
795 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
796 struct dsp563xx_core_reg
*arch_info
;
799 dsp563xx
->core_cache
->reg_list
[num
].dirty
= true;
801 if (dsp563xx
->core_cache
->reg_list
[num
].dirty
) {
802 arch_info
= dsp563xx
->core_cache
->reg_list
[num
].arch_info
;
804 dsp563xx
->write_core_reg(target
, num
);
806 switch (arch_info
->num
) {
807 case DSP563XX_REG_IDX_SSH
:
808 err
= dsp563xx_reg_ssh_write(target
);
810 case DSP563XX_REG_IDX_PC
:
811 /* pc is updated on resume, no need to write it here */
813 case DSP563XX_REG_IDX_IPRC
:
814 case DSP563XX_REG_IDX_IPRP
:
815 case DSP563XX_REG_IDX_BCR
:
816 case DSP563XX_REG_IDX_DCR
:
817 case DSP563XX_REG_IDX_AAR0
:
818 case DSP563XX_REG_IDX_AAR1
:
819 case DSP563XX_REG_IDX_AAR2
:
820 case DSP563XX_REG_IDX_AAR3
:
821 err
= dsp563xx_reg_write_high_io(target
,
822 arch_info
->instr_mask
,
823 dsp563xx
->core_regs
[num
]);
826 err
= dsp563xx_reg_write(target
,
827 arch_info
->instr_mask
,
828 dsp563xx
->core_regs
[num
]);
830 if ((err
== ERROR_OK
) && (arch_info
->num
== DSP563XX_REG_IDX_SP
)) {
831 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSH
].valid
=
833 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SSL
].valid
=
844 static int dsp563xx_save_context(struct target
*target
)
846 int i
, err
= ERROR_OK
;
848 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++) {
849 err
= dsp563xx_read_register(target
, i
, 0);
857 static int dsp563xx_restore_context(struct target
*target
)
859 int i
, err
= ERROR_OK
;
861 for (i
= 0; i
< DSP563XX_NUMCOREREGS
; i
++) {
862 err
= dsp563xx_write_register(target
, i
, 0);
870 static void dsp563xx_invalidate_x_context(struct target
*target
,
875 struct dsp563xx_core_reg
*arch_info
;
876 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
878 if (addr_start
> ASM_REG_W_IPRC
)
880 if (addr_start
< ASM_REG_W_AAR3
)
883 for (i
= DSP563XX_REG_IDX_IPRC
; i
< DSP563XX_NUMCOREREGS
; i
++) {
884 arch_info
= dsp563xx
->core_cache
->reg_list
[i
].arch_info
;
886 if ((arch_info
->instr_mask
>= addr_start
) &&
887 (arch_info
->instr_mask
<= addr_end
)) {
888 dsp563xx
->core_cache
->reg_list
[i
].valid
= false;
889 dsp563xx
->core_cache
->reg_list
[i
].dirty
= false;
894 static int dsp563xx_target_create(struct target
*target
, Jim_Interp
*interp
)
896 struct dsp563xx_common
*dsp563xx
= calloc(1, sizeof(struct dsp563xx_common
));
899 return ERROR_COMMAND_SYNTAX_ERROR
;
901 dsp563xx
->jtag_info
.tap
= target
->tap
;
902 target
->arch_info
= dsp563xx
;
903 dsp563xx
->read_core_reg
= dsp563xx_read_core_reg
;
904 dsp563xx
->write_core_reg
= dsp563xx_write_core_reg
;
909 static int dsp563xx_init_target(struct command_context
*cmd_ctx
, struct target
*target
)
911 LOG_DEBUG("%s", __func__
);
913 dsp563xx_build_reg_cache(target
);
914 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
916 dsp563xx
->hardware_breakpoints_cleared
= false;
917 dsp563xx
->hardware_breakpoint
[0].used
= BPU_NONE
;
922 static int dsp563xx_examine(struct target
*target
)
926 if (target
->tap
->hasidcode
== false) {
927 LOG_ERROR("no IDCODE present on device");
928 return ERROR_COMMAND_SYNTAX_ERROR
;
931 if (!target_was_examined(target
)) {
932 target_set_examined(target
);
934 /* examine core and chip derivate number */
935 chip
= (target
->tap
->idcode
>>12) & 0x3ff;
936 /* core number 0 means DSP563XX */
937 if (((chip
>>5)&0x1f) == 0)
940 LOG_INFO("DSP56%03" PRIu32
" device found", chip
);
942 /* Clear all breakpoints */
943 dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OBCR
, 0);
949 static int dsp563xx_arch_state(struct target
*target
)
951 LOG_DEBUG("%s", __func__
);
955 #define DSP563XX_SR_SA (1<<17)
956 #define DSP563XX_SR_SC (1<<13)
958 static int dsp563xx_debug_once_init(struct target
*target
)
960 return dsp563xx_once_read_register(target
->tap
, 1, once_regs
, DSP563XX_NUMONCEREGS
);
963 static int dsp563xx_debug_init(struct target
*target
)
967 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
968 struct dsp563xx_core_reg
*arch_info
;
970 err
= dsp563xx_debug_once_init(target
);
974 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SR
].arch_info
;
976 /* check 24bit mode */
977 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_SR
, 0);
981 sr
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_SR
];
983 if (sr
& (DSP563XX_SR_SA
| DSP563XX_SR_SC
)) {
984 sr
&= ~(DSP563XX_SR_SA
| DSP563XX_SR_SC
);
986 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, arch_info
->instr_mask
, sr
);
989 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_SR
].dirty
= true;
992 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_N0
, 0);
995 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_N1
, 0);
998 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_M0
, 0);
1001 err
= dsp563xx_read_register(target
, DSP563XX_REG_IDX_M1
, 0);
1002 if (err
!= ERROR_OK
)
1005 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_N0
] != 0x000000) {
1006 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N0
].arch_info
;
1007 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0x000000);
1008 if (err
!= ERROR_OK
)
1011 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N0
].dirty
= true;
1013 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_N1
] != 0x000000) {
1014 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N1
].arch_info
;
1015 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0x000000);
1016 if (err
!= ERROR_OK
)
1019 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_N1
].dirty
= true;
1021 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_M0
] != 0xffffff) {
1022 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M0
].arch_info
;
1023 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0xffffff);
1024 if (err
!= ERROR_OK
)
1027 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M0
].dirty
= true;
1029 if (dsp563xx
->core_regs
[DSP563XX_REG_IDX_M1
] != 0xffffff) {
1030 arch_info
= dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M1
].arch_info
;
1031 err
= dsp563xx_reg_write(target
, arch_info
->instr_mask
, 0xffffff);
1032 if (err
!= ERROR_OK
)
1035 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_M1
].dirty
= true;
1037 err
= dsp563xx_save_context(target
);
1038 if (err
!= ERROR_OK
)
1044 static int dsp563xx_jtag_debug_request(struct target
*target
)
1046 return dsp563xx_once_request_debug(target
->tap
, target
->state
== TARGET_RESET
);
1049 static int dsp563xx_poll(struct target
*target
)
1052 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1053 uint32_t once_status
= 0;
1056 state
= dsp563xx_once_target_status(target
->tap
);
1058 if (state
== TARGET_UNKNOWN
) {
1059 target
->state
= state
;
1060 LOG_ERROR("jtag status contains invalid mode value - communication failure");
1061 return ERROR_TARGET_FAILURE
;
1064 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OSCR
, &once_status
);
1065 if (err
!= ERROR_OK
)
1068 if ((once_status
& DSP563XX_ONCE_OSCR_DEBUG_M
) == DSP563XX_ONCE_OSCR_DEBUG_M
) {
1069 if (target
->state
!= TARGET_HALTED
) {
1070 target
->state
= TARGET_HALTED
;
1072 err
= dsp563xx_debug_init(target
);
1073 if (err
!= ERROR_OK
)
1076 if (once_status
& (DSP563XX_ONCE_OSCR_MBO
|DSP563XX_ONCE_OSCR_SWO
))
1077 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
1079 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1081 LOG_DEBUG("target->state: %s (%" PRIx32
")", target_state_name(target
), once_status
);
1082 LOG_INFO("halted: PC: 0x%" PRIx32
, dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
]);
1086 if (!dsp563xx
->hardware_breakpoints_cleared
) {
1087 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OBCR
, 0);
1088 if (err
!= ERROR_OK
)
1091 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR0
, 0);
1092 if (err
!= ERROR_OK
)
1095 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR1
, 0);
1096 if (err
!= ERROR_OK
)
1099 dsp563xx
->hardware_breakpoints_cleared
= true;
1105 static int dsp563xx_halt(struct target
*target
)
1109 LOG_DEBUG("%s", __func__
);
1111 if (target
->state
== TARGET_HALTED
) {
1112 LOG_DEBUG("target was already halted");
1116 if (target
->state
== TARGET_UNKNOWN
)
1117 LOG_WARNING("target was in unknown state when halt was requested");
1119 err
= dsp563xx_jtag_debug_request(target
);
1120 if (err
!= ERROR_OK
)
1123 target
->debug_reason
= DBG_REASON_DBGRQ
;
1128 static int dsp563xx_resume(struct target
*target
,
1130 target_addr_t address
,
1131 int handle_breakpoints
,
1132 int debug_execution
)
1135 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1137 /* check if pc was changed and resume want to execute the next address
1138 * if pc was changed from gdb or other interface we will
1139 * jump to this address and don't execute the next address
1140 * this will not affect the resume command with an address argument
1141 * because current is set to zero then
1143 if (current
&& dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].dirty
) {
1144 dsp563xx_write_core_reg(target
, DSP563XX_REG_IDX_PC
);
1145 address
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
];
1149 LOG_DEBUG("%s %08X %08X", __func__
, current
, (unsigned) address
);
1151 err
= dsp563xx_restore_context(target
);
1152 if (err
!= ERROR_OK
)
1154 register_cache_invalidate(dsp563xx
->core_cache
);
1157 /* restore pipeline registers and go */
1158 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
,
1159 once_regs
[ONCE_REG_IDX_OPILR
].reg
);
1160 if (err
!= ERROR_OK
)
1162 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
|
1163 DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
,
1164 once_regs
[ONCE_REG_IDX_OPDBR
].reg
);
1165 if (err
!= ERROR_OK
)
1168 /* set to go register and jump */
1169 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
, INSTR_JUMP
);
1170 if (err
!= ERROR_OK
)
1172 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_PDBGOTO
|
1173 DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
, address
);
1174 if (err
!= ERROR_OK
)
1178 target
->state
= TARGET_RUNNING
;
1180 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1185 static int dsp563xx_step_ex(struct target
*target
,
1188 int handle_breakpoints
,
1192 uint32_t once_status
;
1193 uint32_t dr_in
, cnt
;
1194 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1196 if (target
->state
!= TARGET_HALTED
) {
1197 LOG_DEBUG("target was not halted");
1201 /* check if pc was changed and step want to execute the next address
1202 * if pc was changed from gdb or other interface we will
1203 * jump to this address and don't execute the next address
1204 * this will not affect the step command with an address argument
1205 * because current is set to zero then
1207 if (current
&& dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].dirty
) {
1208 dsp563xx_write_core_reg(target
, DSP563XX_REG_IDX_PC
);
1209 address
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
];
1213 LOG_DEBUG("%s %08X %08X", __func__
, current
, (unsigned) address
);
1215 err
= dsp563xx_jtag_debug_request(target
);
1216 if (err
!= ERROR_OK
)
1218 err
= dsp563xx_restore_context(target
);
1219 if (err
!= ERROR_OK
)
1222 /* reset trace mode */
1223 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OSCR
, 0x000000);
1224 if (err
!= ERROR_OK
)
1226 /* enable trace mode */
1227 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OSCR
, DSP563XX_ONCE_OSCR_TME
);
1228 if (err
!= ERROR_OK
)
1233 /* on JUMP we need one extra cycle */
1237 /* load step counter with N-1 */
1238 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OTC
, cnt
);
1239 if (err
!= ERROR_OK
)
1243 /* restore pipeline registers and go */
1244 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
,
1245 once_regs
[ONCE_REG_IDX_OPILR
].reg
);
1246 if (err
!= ERROR_OK
)
1248 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
|
1249 DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
,
1250 once_regs
[ONCE_REG_IDX_OPDBR
].reg
);
1251 if (err
!= ERROR_OK
)
1254 /* set to go register and jump */
1255 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
, INSTR_JUMP
);
1256 if (err
!= ERROR_OK
)
1258 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_PDBGOTO
|
1259 DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
,
1261 if (err
!= ERROR_OK
)
1266 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OSCR
, &once_status
);
1267 if (err
!= ERROR_OK
)
1270 if (once_status
& DSP563XX_ONCE_OSCR_TO
) {
1271 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OPABFR
, &dr_in
);
1272 if (err
!= ERROR_OK
)
1274 LOG_DEBUG("fetch: %08X", (unsigned) dr_in
&0x00ffffff);
1275 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OPABDR
, &dr_in
);
1276 if (err
!= ERROR_OK
)
1278 LOG_DEBUG("decode: %08X", (unsigned) dr_in
&0x00ffffff);
1279 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OPABEX
, &dr_in
);
1280 if (err
!= ERROR_OK
)
1282 LOG_DEBUG("execute: %08X", (unsigned) dr_in
&0x00ffffff);
1284 /* reset trace mode */
1285 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OSCR
, 0x000000);
1286 if (err
!= ERROR_OK
)
1289 register_cache_invalidate(dsp563xx
->core_cache
);
1290 err
= dsp563xx_debug_init(target
);
1291 if (err
!= ERROR_OK
)
1301 static int dsp563xx_step(struct target
*target
,
1303 target_addr_t address
,
1304 int handle_breakpoints
)
1307 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1309 if (target
->state
!= TARGET_HALTED
) {
1310 LOG_WARNING("target not halted");
1311 return ERROR_TARGET_NOT_HALTED
;
1314 err
= dsp563xx_step_ex(target
, current
, address
, handle_breakpoints
, 0);
1315 if (err
!= ERROR_OK
)
1318 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1319 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1321 LOG_INFO("halted: PC: 0x%" PRIx32
, dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
]);
1326 static int dsp563xx_assert_reset(struct target
*target
)
1329 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1330 enum reset_types jtag_reset_config
= jtag_get_reset_config();
1332 if (jtag_reset_config
& RESET_HAS_SRST
) {
1333 /* default to asserting srst */
1334 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
1335 jtag_add_reset(1, 1);
1337 jtag_add_reset(0, 1);
1340 target
->state
= TARGET_RESET
;
1341 jtag_add_sleep(5000);
1343 /* registers are now invalid */
1344 register_cache_invalidate(dsp563xx
->core_cache
);
1346 if (target
->reset_halt
) {
1347 retval
= target_halt(target
);
1348 if (retval
!= ERROR_OK
)
1352 LOG_DEBUG("%s", __func__
);
1356 static int dsp563xx_deassert_reset(struct target
*target
)
1360 /* deassert reset lines */
1361 jtag_add_reset(0, 0);
1363 err
= dsp563xx_poll(target
);
1364 if (err
!= ERROR_OK
)
1367 if (target
->reset_halt
) {
1368 if (target
->state
== TARGET_HALTED
) {
1369 /* after a reset the cpu jmp to the
1370 * reset vector and need 2 cycles to fill
1371 * the cache (fetch,decode,execute)
1373 err
= dsp563xx_step_ex(target
, 1, 0, 1, 1);
1374 if (err
!= ERROR_OK
)
1378 target
->state
= TARGET_RUNNING
;
1380 LOG_DEBUG("%s", __func__
);
1384 static int dsp563xx_run_algorithm(struct target
*target
,
1385 int num_mem_params
, struct mem_param
*mem_params
,
1386 int num_reg_params
, struct reg_param
*reg_params
,
1387 target_addr_t entry_point
, target_addr_t exit_point
,
1388 int timeout_ms
, void *arch_info
)
1391 int retval
= ERROR_OK
;
1392 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1394 if (target
->state
!= TARGET_HALTED
) {
1395 LOG_WARNING("target not halted");
1396 return ERROR_TARGET_NOT_HALTED
;
1399 for (i
= 0; i
< num_mem_params
; i
++) {
1400 if (mem_params
[i
].direction
== PARAM_IN
)
1402 retval
= target_write_buffer(target
, mem_params
[i
].address
,
1403 mem_params
[i
].size
, mem_params
[i
].value
);
1404 if (retval
!= ERROR_OK
)
1408 for (i
= 0; i
< num_reg_params
; i
++) {
1409 if (reg_params
[i
].direction
== PARAM_IN
)
1412 struct reg
*reg
= register_get_by_name(dsp563xx
->core_cache
,
1413 reg_params
[i
].reg_name
,
1417 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
1421 if (reg
->size
!= reg_params
[i
].size
) {
1422 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1423 reg_params
[i
].reg_name
);
1427 retval
= dsp563xx_set_core_reg(reg
, reg_params
[i
].value
);
1428 if (retval
!= ERROR_OK
)
1433 retval
= target_resume(target
, 0, entry_point
, 1, 1);
1434 if (retval
!= ERROR_OK
)
1437 retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
);
1438 if (retval
!= ERROR_OK
)
1441 for (i
= 0; i
< num_mem_params
; i
++) {
1442 if (mem_params
[i
].direction
!= PARAM_OUT
)
1443 retval
= target_read_buffer(target
,
1444 mem_params
[i
].address
,
1446 mem_params
[i
].value
);
1447 if (retval
!= ERROR_OK
)
1451 for (i
= 0; i
< num_reg_params
; i
++) {
1452 if (reg_params
[i
].direction
!= PARAM_OUT
) {
1454 struct reg
*reg
= register_get_by_name(dsp563xx
->core_cache
,
1455 reg_params
[i
].reg_name
,
1458 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
1462 if (reg
->size
!= reg_params
[i
].size
) {
1464 "BUG: register '%s' size doesn't match reg_params[i].size",
1465 reg_params
[i
].reg_name
);
1469 buf_set_u32(reg_params
[i
].value
, 0, 32, buf_get_u32(reg
->value
, 0, 32));
1476 /* global command context from openocd.c */
1477 extern struct command_context
*global_cmd_ctx
;
1479 static int dsp563xx_get_default_memory(void)
1485 if (!global_cmd_ctx
)
1488 interp
= global_cmd_ctx
->interp
;
1493 memspace
= Jim_GetGlobalVariableStr(interp
, "memspace", JIM_NONE
);
1498 c
= (char *)Jim_GetString(memspace
, NULL
);
1517 static int dsp563xx_read_memory_core(struct target
*target
,
1525 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1527 uint32_t data
, move_cmd
= 0;
1531 "memtype: %d address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
1537 if (target
->state
!= TARGET_HALTED
) {
1538 LOG_WARNING("target not halted");
1539 return ERROR_TARGET_NOT_HALTED
;
1544 /* TODO: mark effected queued registers */
1545 move_cmd
= 0x61d800;
1548 move_cmd
= 0x69d800;
1551 move_cmd
= 0x07d891;
1554 return ERROR_COMMAND_SYNTAX_ERROR
;
1557 /* we use r0 to store temporary data */
1558 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
1559 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
1560 /* we use r1 to store temporary data */
1561 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].valid
)
1562 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R1
);
1564 /* r0 is no longer valid on target */
1565 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= true;
1566 /* r1 is no longer valid on target */
1567 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].dirty
= true;
1572 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, 0x60F400, address
);
1573 if (err
!= ERROR_OK
)
1576 for (i
= 0; i
< x
; i
++) {
1577 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, move_cmd
);
1578 if (err
!= ERROR_OK
)
1580 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, 0x08D13C);
1581 if (err
!= ERROR_OK
)
1583 err
= dsp563xx_once_reg_read(target
->tap
, 0,
1584 DSP563XX_ONCE_OGDBR
, (uint32_t *)(void *)b
);
1585 if (err
!= ERROR_OK
)
1590 /* flush the jtag queue */
1591 err
= jtag_execute_queue();
1592 if (err
!= ERROR_OK
)
1595 /* walk over the buffer and fix target endianness */
1598 for (i
= 0; i
< x
; i
++) {
1599 data
= buf_get_u32(b
, 0, 32) & 0x00FFFFFF;
1600 /* LOG_DEBUG("R: %08X", *((uint32_t*)b)); */
1601 target_buffer_set_u32(target
, b
, data
);
1608 static int dsp563xx_read_memory(struct target
*target
,
1610 target_addr_t address
,
1617 uint8_t *buffer_y
, *buffer_x
;
1619 /* if size equals zero we are called from target read memory
1620 * and have to handle the parameter here */
1621 if ((size
== 0) && (count
!= 0)) {
1625 LOG_DEBUG("size is not aligned to 4 byte");
1627 count
= (count
- size
) / 4;
1631 /* we only support 4 byte aligned data */
1632 if ((size
!= 4) || (!count
))
1633 return ERROR_COMMAND_SYNTAX_ERROR
;
1635 if (mem_type
!= MEM_L
)
1636 return dsp563xx_read_memory_core(target
, mem_type
, address
, size
, count
, buffer
);
1638 buffer_y
= malloc(size
* count
);
1640 return ERROR_COMMAND_SYNTAX_ERROR
;
1642 buffer_x
= malloc(size
* count
);
1645 return ERROR_COMMAND_SYNTAX_ERROR
;
1648 err
= dsp563xx_read_memory_core(target
, MEM_Y
, address
, size
, count
/ 2, buffer_y
);
1650 if (err
!= ERROR_OK
) {
1656 err
= dsp563xx_read_memory_core(target
, MEM_X
, address
, size
, count
/ 2, buffer_x
);
1658 if (err
!= ERROR_OK
) {
1664 for (i
= 0, i1
= 0; i
< count
; i
+= 2, i1
++) {
1665 buf_set_u32(buffer
+ i
*sizeof(uint32_t), 0, 32,
1666 buf_get_u32(buffer_y
+ i1
* sizeof(uint32_t), 0, 32));
1667 buf_set_u32(buffer
+ (i
+ 1) * sizeof(uint32_t), 0, 32,
1668 buf_get_u32(buffer_x
+ i1
* sizeof(uint32_t), 0, 32));
1677 static int dsp563xx_read_memory_default(struct target
*target
,
1678 target_addr_t address
,
1684 return dsp563xx_read_memory(target
,
1685 dsp563xx_get_default_memory(), address
, size
, count
, buffer
);
1688 static int dsp563xx_read_buffer_default(struct target
*target
,
1689 target_addr_t address
,
1694 return dsp563xx_read_memory(target
, dsp563xx_get_default_memory(), address
, size
, 0,
1698 static int dsp563xx_write_memory_core(struct target
*target
,
1700 target_addr_t address
,
1703 const uint8_t *buffer
)
1706 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1708 uint32_t data
, move_cmd
= 0;
1712 "memtype: %d address: 0x%8.8" TARGET_PRIxADDR
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
1718 if (target
->state
!= TARGET_HALTED
) {
1719 LOG_WARNING("target not halted");
1720 return ERROR_TARGET_NOT_HALTED
;
1725 /* invalidate affected x registers */
1726 dsp563xx_invalidate_x_context(target
, address
, address
+ count
- 1);
1727 move_cmd
= 0x615800;
1730 move_cmd
= 0x695800;
1733 move_cmd
= 0x075891;
1736 return ERROR_COMMAND_SYNTAX_ERROR
;
1739 /* we use r0 to store temporary data */
1740 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
1741 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
1742 /* we use r1 to store temporary data */
1743 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].valid
)
1744 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R1
);
1746 /* r0 is no longer valid on target */
1747 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= true;
1748 /* r1 is no longer valid on target */
1749 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].dirty
= true;
1754 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, 0x60F400, address
);
1755 if (err
!= ERROR_OK
)
1758 for (i
= 0; i
< x
; i
++) {
1759 data
= target_buffer_get_u32(target
, b
);
1761 /* LOG_DEBUG("W: %08X", data); */
1765 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 0, 0x61F400, data
);
1766 if (err
!= ERROR_OK
)
1768 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, move_cmd
);
1769 if (err
!= ERROR_OK
)
1774 /* flush the jtag queue */
1775 err
= jtag_execute_queue();
1776 if (err
!= ERROR_OK
)
1782 static int dsp563xx_write_memory(struct target
*target
,
1784 target_addr_t address
,
1787 const uint8_t *buffer
)
1791 uint8_t *buffer_y
, *buffer_x
;
1793 /* if size equals zero we are called from target write memory
1794 * and have to handle the parameter here */
1795 if ((size
== 0) && (count
!= 0)) {
1799 LOG_DEBUG("size is not aligned to 4 byte");
1801 count
= (count
- size
) / 4;
1805 /* we only support 4 byte aligned data */
1806 if ((size
!= 4) || (!count
))
1807 return ERROR_COMMAND_SYNTAX_ERROR
;
1809 if (mem_type
!= MEM_L
)
1810 return dsp563xx_write_memory_core(target
, mem_type
, address
, size
, count
, buffer
);
1812 buffer_y
= malloc(size
* count
);
1814 return ERROR_COMMAND_SYNTAX_ERROR
;
1816 buffer_x
= malloc(size
* count
);
1819 return ERROR_COMMAND_SYNTAX_ERROR
;
1822 for (i
= 0, i1
= 0; i
< count
; i
+= 2, i1
++) {
1823 buf_set_u32(buffer_y
+ i1
* sizeof(uint32_t), 0, 32,
1824 buf_get_u32(buffer
+ i
* sizeof(uint32_t), 0, 32));
1825 buf_set_u32(buffer_x
+ i1
* sizeof(uint32_t), 0, 32,
1826 buf_get_u32(buffer
+ (i
+ 1) * sizeof(uint32_t), 0, 32));
1829 err
= dsp563xx_write_memory_core(target
, MEM_Y
, address
, size
, count
/ 2, buffer_y
);
1831 if (err
!= ERROR_OK
) {
1837 err
= dsp563xx_write_memory_core(target
, MEM_X
, address
, size
, count
/ 2, buffer_x
);
1839 if (err
!= ERROR_OK
) {
1851 static int dsp563xx_write_memory_default(struct target
*target
,
1852 target_addr_t address
,
1855 const uint8_t *buffer
)
1857 return dsp563xx_write_memory(target
,
1858 dsp563xx_get_default_memory(), address
, size
, count
, buffer
);
1861 static int dsp563xx_write_buffer_default(struct target
*target
,
1862 target_addr_t address
,
1864 const uint8_t *buffer
)
1866 return dsp563xx_write_memory(target
, dsp563xx_get_default_memory(), address
, size
, 0,
1871 * Exit with error here, because we support watchpoints over a custom command.
1872 * This is because the DSP has separate X,Y,P memspace which is not compatible to the
1873 * traditional watchpoint logic.
1875 static int dsp563xx_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1877 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1881 * @see dsp563xx_add_watchpoint
1883 static int dsp563xx_remove_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1885 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1888 static int dsp563xx_add_custom_watchpoint(struct target
*target
, uint32_t address
, uint32_t mem_type
,
1889 enum watchpoint_rw rw
, enum watchpoint_condition cond
)
1892 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1894 bool was_running
= false;
1895 /* Only set breakpoint when halted */
1896 if (target
->state
!= TARGET_HALTED
) {
1897 dsp563xx_halt(target
);
1901 if (dsp563xx
->hardware_breakpoint
[0].used
) {
1902 LOG_ERROR("Cannot add watchpoint. Hardware resource already used.");
1903 err
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1906 uint32_t obcr_value
= 0;
1907 if (err
== ERROR_OK
) {
1908 obcr_value
|= OBCR_B0_OR_B1
;
1911 obcr_value
|= OBCR_BP_MEM_X
;
1914 obcr_value
|= OBCR_BP_MEM_Y
;
1917 obcr_value
|= OBCR_BP_MEM_P
;
1920 LOG_ERROR("Unknown mem_type parameter (%" PRIu32
")", mem_type
);
1921 err
= ERROR_TARGET_INVALID
;
1925 if (err
== ERROR_OK
) {
1928 obcr_value
|= OBCR_BP_0(OBCR_BP_ON_READ
);
1931 obcr_value
|= OBCR_BP_0(OBCR_BP_ON_WRITE
);
1934 obcr_value
|= OBCR_BP_0(OBCR_BP_ON_READ
|OBCR_BP_ON_WRITE
);
1937 LOG_ERROR("Unsupported write mode (%d)", rw
);
1938 err
= ERROR_TARGET_INVALID
;
1942 if (err
== ERROR_OK
) {
1945 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_EQUAL
);
1948 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_NOT_EQUAL
);
1951 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_LESS_THAN
);
1954 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_GREATER_THAN
);
1957 LOG_ERROR("Unsupported condition code (%d)", cond
);
1958 err
= ERROR_TARGET_INVALID
;
1962 if (err
== ERROR_OK
)
1963 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR0
, address
);
1965 if (err
== ERROR_OK
)
1966 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR1
, 0x0);
1968 if (err
== ERROR_OK
)
1969 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OBCR
, obcr_value
);
1971 if (err
== ERROR_OK
) {
1972 /* You should write the memory breakpoint counter to 0 */
1973 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMBC
, 0);
1976 if (err
== ERROR_OK
) {
1977 /* You should write the memory breakpoint counter to 0 */
1978 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OTC
, 0);
1981 if (err
== ERROR_OK
)
1982 dsp563xx
->hardware_breakpoint
[0].used
= BPU_WATCHPOINT
;
1984 if (err
== ERROR_OK
&& was_running
) {
1985 /* Resume from current PC */
1986 err
= dsp563xx_resume(target
, 1, 0x0, 0, 0);
1992 static int dsp563xx_remove_custom_watchpoint(struct target
*target
)
1995 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1997 if (dsp563xx
->hardware_breakpoint
[0].used
!= BPU_WATCHPOINT
) {
1998 LOG_ERROR("Cannot remove watchpoint, as no watchpoint is currently configured!");
1999 err
= ERROR_TARGET_INVALID
;
2002 if (err
== ERROR_OK
) {
2003 /* Clear watchpoint by clearing OBCR. */
2004 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OBCR
, 0);
2007 if (err
== ERROR_OK
)
2008 dsp563xx
->hardware_breakpoint
[0].used
= BPU_NONE
;
2013 COMMAND_HANDLER(dsp563xx_add_watchpoint_command
)
2016 struct target
*target
= get_current_target(CMD_CTX
);
2018 uint32_t mem_type
= 0;
2019 switch (CMD_NAME
[2]) {
2030 return ERROR_COMMAND_SYNTAX_ERROR
;
2034 return ERROR_COMMAND_SYNTAX_ERROR
;
2036 uint32_t address
= 0;
2038 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], address
);
2040 enum watchpoint_condition cond
;
2041 switch (CMD_ARGV
[0][0]) {
2055 return ERROR_COMMAND_SYNTAX_ERROR
;
2058 enum watchpoint_rw rw
;
2059 switch (CMD_ARGV
[1][0]) {
2070 return ERROR_COMMAND_SYNTAX_ERROR
;
2073 err
= dsp563xx_add_custom_watchpoint(target
, address
, mem_type
, rw
, cond
);
2078 /* Adding a breakpoint using the once breakpoint logic.
2079 * Note that this mechanism is a true hw breakpoint and is share between the watchpoint logic.
2080 * This means, you can only have one breakpoint/watchpoint at any time.
2082 static int dsp563xx_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
2084 return dsp563xx_add_custom_watchpoint(target
, breakpoint
->address
, MEM_P
, WPT_READ
, EQUAL
);
2087 static int dsp563xx_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
2089 return dsp563xx_remove_custom_watchpoint(target
);
2092 COMMAND_HANDLER(dsp563xx_remove_watchpoint_command
)
2094 struct target
*target
= get_current_target(CMD_CTX
);
2096 return dsp563xx_remove_custom_watchpoint(target
);
2099 COMMAND_HANDLER(dsp563xx_mem_command
)
2101 struct target
*target
= get_current_target(CMD_CTX
);
2104 uint32_t address
= 0;
2105 uint32_t count
= 1, i
;
2106 uint32_t pattern
= 0;
2108 uint8_t *buffer
, *b
;
2110 switch (CMD_NAME
[1]) {
2118 return ERROR_COMMAND_SYNTAX_ERROR
;
2121 switch (CMD_NAME
[3]) {
2132 return ERROR_COMMAND_SYNTAX_ERROR
;
2136 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
2138 if (read_mem
== 0) {
2140 return ERROR_COMMAND_SYNTAX_ERROR
;
2142 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], pattern
);
2144 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], count
);
2147 if (read_mem
== 1) {
2149 return ERROR_COMMAND_SYNTAX_ERROR
;
2151 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], count
);
2154 buffer
= calloc(count
, sizeof(uint32_t));
2156 if (read_mem
== 1) {
2157 err
= dsp563xx_read_memory(target
, mem_type
, address
, sizeof(uint32_t),
2159 if (err
== ERROR_OK
)
2160 target_handle_md_output(CMD
, target
, address
, sizeof(uint32_t), count
, buffer
);
2165 for (i
= 0; i
< count
; i
++) {
2166 target_buffer_set_u32(target
, b
, pattern
);
2170 err
= dsp563xx_write_memory(target
,
2183 static const struct command_registration dsp563xx_command_handlers
[] = {
2186 .handler
= dsp563xx_mem_command
,
2187 .mode
= COMMAND_EXEC
,
2188 .help
= "write x memory words",
2189 .usage
= "address value [count]",
2193 .handler
= dsp563xx_mem_command
,
2194 .mode
= COMMAND_EXEC
,
2195 .help
= "write y memory words",
2196 .usage
= "address value [count]",
2200 .handler
= dsp563xx_mem_command
,
2201 .mode
= COMMAND_EXEC
,
2202 .help
= "write p memory words",
2203 .usage
= "address value [count]",
2207 .handler
= dsp563xx_mem_command
,
2208 .mode
= COMMAND_EXEC
,
2209 .help
= "display x memory words",
2210 .usage
= "address [count]",
2214 .handler
= dsp563xx_mem_command
,
2215 .mode
= COMMAND_EXEC
,
2216 .help
= "display y memory words",
2217 .usage
= "address [count]",
2221 .handler
= dsp563xx_mem_command
,
2222 .mode
= COMMAND_EXEC
,
2223 .help
= "display p memory words",
2224 .usage
= "address [count]",
2227 * Watchpoint commands
2231 .handler
= dsp563xx_add_watchpoint_command
,
2232 .mode
= COMMAND_EXEC
,
2233 .help
= "Create p memspace watchpoint",
2234 .usage
= "(>|<|=|!) (r|w|a) address",
2238 .handler
= dsp563xx_add_watchpoint_command
,
2239 .mode
= COMMAND_EXEC
,
2240 .help
= "Create x memspace watchpoint",
2241 .usage
= "(>|<|=|!) (r|w|a) address",
2245 .handler
= dsp563xx_add_watchpoint_command
,
2246 .mode
= COMMAND_EXEC
,
2247 .help
= "Create y memspace watchpoint",
2248 .usage
= "(>|<|=|!) (r|w|a) address",
2252 .handler
= dsp563xx_remove_watchpoint_command
,
2253 .mode
= COMMAND_EXEC
,
2254 .help
= "remove watchpoint custom",
2257 COMMAND_REGISTRATION_DONE
2260 /** Holds methods for DSP563XX targets. */
2261 struct target_type dsp563xx_target
= {
2264 .poll
= dsp563xx_poll
,
2265 .arch_state
= dsp563xx_arch_state
,
2267 .get_gdb_reg_list
= dsp563xx_get_gdb_reg_list
,
2269 .halt
= dsp563xx_halt
,
2270 .resume
= dsp563xx_resume
,
2271 .step
= dsp563xx_step
,
2273 .assert_reset
= dsp563xx_assert_reset
,
2274 .deassert_reset
= dsp563xx_deassert_reset
,
2276 .read_memory
= dsp563xx_read_memory_default
,
2277 .write_memory
= dsp563xx_write_memory_default
,
2279 .read_buffer
= dsp563xx_read_buffer_default
,
2280 .write_buffer
= dsp563xx_write_buffer_default
,
2282 .run_algorithm
= dsp563xx_run_algorithm
,
2284 .add_breakpoint
= dsp563xx_add_breakpoint
,
2285 .remove_breakpoint
= dsp563xx_remove_breakpoint
,
2286 .add_watchpoint
= dsp563xx_add_watchpoint
,
2287 .remove_watchpoint
= dsp563xx_remove_watchpoint
,
2289 .commands
= dsp563xx_command_handlers
,
2290 .target_create
= dsp563xx_target_create
,
2291 .init_target
= dsp563xx_init_target
,
2292 .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)