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
= 0;
917 dsp563xx
->hardware_breakpoint
[0].used
= BPU_NONE
;
922 static int dsp563xx_examine(struct target
*target
)
926 if (target
->tap
->hasidcode
== false) {
927 LOG_ERROR("no IDCODE present on device");
928 return ERROR_COMMAND_SYNTAX_ERROR
;
931 if (!target_was_examined(target
)) {
932 target_set_examined(target
);
934 /* examine core and chip derivate number */
935 chip
= (target
->tap
->idcode
>>12) & 0x3ff;
936 /* core number 0 means DSP563XX */
937 if (((chip
>>5)&0x1f) == 0)
940 LOG_INFO("DSP56%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 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR0
, 0);
1089 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR1
, 0);
1090 dsp563xx
->hardware_breakpoints_cleared
= 1;
1096 static int dsp563xx_halt(struct target
*target
)
1100 LOG_DEBUG("%s", __func__
);
1102 if (target
->state
== TARGET_HALTED
) {
1103 LOG_DEBUG("target was already halted");
1107 if (target
->state
== TARGET_UNKNOWN
)
1108 LOG_WARNING("target was in unknown state when halt was requested");
1110 err
= dsp563xx_jtag_debug_request(target
);
1111 if (err
!= ERROR_OK
)
1114 target
->debug_reason
= DBG_REASON_DBGRQ
;
1119 static int dsp563xx_resume(struct target
*target
,
1121 target_addr_t address
,
1122 int handle_breakpoints
,
1123 int debug_execution
)
1126 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1128 /* check if pc was changed and resume want to execute the next address
1129 * if pc was changed from gdb or other interface we will
1130 * jump to this address and don't execute the next address
1131 * this will not affect the resume command with an address argument
1132 * because current is set to zero then
1134 if (current
&& dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].dirty
) {
1135 dsp563xx_write_core_reg(target
, DSP563XX_REG_IDX_PC
);
1136 address
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
];
1140 LOG_DEBUG("%s %08X %08X", __func__
, current
, (unsigned) address
);
1142 err
= dsp563xx_restore_context(target
);
1143 if (err
!= ERROR_OK
)
1145 register_cache_invalidate(dsp563xx
->core_cache
);
1148 /* restore pipeline registers and go */
1149 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
,
1150 once_regs
[ONCE_REG_IDX_OPILR
].reg
);
1151 if (err
!= ERROR_OK
)
1153 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
|
1154 DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
,
1155 once_regs
[ONCE_REG_IDX_OPDBR
].reg
);
1156 if (err
!= ERROR_OK
)
1159 /* set to go register and jump */
1160 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
, INSTR_JUMP
);
1161 if (err
!= ERROR_OK
)
1163 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_PDBGOTO
|
1164 DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
, address
);
1165 if (err
!= ERROR_OK
)
1169 target
->state
= TARGET_RUNNING
;
1171 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1176 static int dsp563xx_step_ex(struct target
*target
,
1179 int handle_breakpoints
,
1183 uint32_t once_status
;
1184 uint32_t dr_in
, cnt
;
1185 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1187 if (target
->state
!= TARGET_HALTED
) {
1188 LOG_DEBUG("target was not halted");
1192 /* check if pc was changed and step want to execute the next address
1193 * if pc was changed from gdb or other interface we will
1194 * jump to this address and don't execute the next address
1195 * this will not affect the step command with an address argument
1196 * because current is set to zero then
1198 if (current
&& dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_PC
].dirty
) {
1199 dsp563xx_write_core_reg(target
, DSP563XX_REG_IDX_PC
);
1200 address
= dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
];
1204 LOG_DEBUG("%s %08X %08X", __func__
, current
, (unsigned) address
);
1206 err
= dsp563xx_jtag_debug_request(target
);
1207 if (err
!= ERROR_OK
)
1209 err
= dsp563xx_restore_context(target
);
1210 if (err
!= ERROR_OK
)
1213 /* reset trace mode */
1214 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OSCR
, 0x000000);
1215 if (err
!= ERROR_OK
)
1217 /* enable trace mode */
1218 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OSCR
, DSP563XX_ONCE_OSCR_TME
);
1219 if (err
!= ERROR_OK
)
1224 /* on JUMP we need one extra cycle */
1228 /* load step counter with N-1 */
1229 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OTC
, cnt
);
1230 if (err
!= ERROR_OK
)
1234 /* restore pipeline registers and go */
1235 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
,
1236 once_regs
[ONCE_REG_IDX_OPILR
].reg
);
1237 if (err
!= ERROR_OK
)
1239 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
|
1240 DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
,
1241 once_regs
[ONCE_REG_IDX_OPDBR
].reg
);
1242 if (err
!= ERROR_OK
)
1245 /* set to go register and jump */
1246 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OPDBR
, INSTR_JUMP
);
1247 if (err
!= ERROR_OK
)
1249 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_PDBGOTO
|
1250 DSP563XX_ONCE_OCR_EX
| DSP563XX_ONCE_OCR_GO
,
1252 if (err
!= ERROR_OK
)
1257 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OSCR
, &once_status
);
1258 if (err
!= ERROR_OK
)
1261 if (once_status
& DSP563XX_ONCE_OSCR_TO
) {
1262 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OPABFR
, &dr_in
);
1263 if (err
!= ERROR_OK
)
1265 LOG_DEBUG("fetch: %08X", (unsigned) dr_in
&0x00ffffff);
1266 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OPABDR
, &dr_in
);
1267 if (err
!= ERROR_OK
)
1269 LOG_DEBUG("decode: %08X", (unsigned) dr_in
&0x00ffffff);
1270 err
= dsp563xx_once_reg_read(target
->tap
, 1, DSP563XX_ONCE_OPABEX
, &dr_in
);
1271 if (err
!= ERROR_OK
)
1273 LOG_DEBUG("execute: %08X", (unsigned) dr_in
&0x00ffffff);
1275 /* reset trace mode */
1276 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OSCR
, 0x000000);
1277 if (err
!= ERROR_OK
)
1280 register_cache_invalidate(dsp563xx
->core_cache
);
1281 err
= dsp563xx_debug_init(target
);
1282 if (err
!= ERROR_OK
)
1292 static int dsp563xx_step(struct target
*target
,
1294 target_addr_t address
,
1295 int handle_breakpoints
)
1298 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1300 if (target
->state
!= TARGET_HALTED
) {
1301 LOG_WARNING("target not halted");
1302 return ERROR_TARGET_NOT_HALTED
;
1305 err
= dsp563xx_step_ex(target
, current
, address
, handle_breakpoints
, 0);
1306 if (err
!= ERROR_OK
)
1309 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1310 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1312 LOG_INFO("halted: PC: 0x%" PRIx32
, dsp563xx
->core_regs
[DSP563XX_REG_IDX_PC
]);
1317 static int dsp563xx_assert_reset(struct target
*target
)
1320 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1321 enum reset_types jtag_reset_config
= jtag_get_reset_config();
1323 if (jtag_reset_config
& RESET_HAS_SRST
) {
1324 /* default to asserting srst */
1325 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
1326 jtag_add_reset(1, 1);
1328 jtag_add_reset(0, 1);
1331 target
->state
= TARGET_RESET
;
1332 jtag_add_sleep(5000);
1334 /* registers are now invalid */
1335 register_cache_invalidate(dsp563xx
->core_cache
);
1337 if (target
->reset_halt
) {
1338 retval
= target_halt(target
);
1339 if (retval
!= ERROR_OK
)
1343 LOG_DEBUG("%s", __func__
);
1347 static int dsp563xx_deassert_reset(struct target
*target
)
1351 /* deassert reset lines */
1352 jtag_add_reset(0, 0);
1354 err
= dsp563xx_poll(target
);
1355 if (err
!= ERROR_OK
)
1358 if (target
->reset_halt
) {
1359 if (target
->state
== TARGET_HALTED
) {
1360 /* after a reset the cpu jmp to the
1361 * reset vector and need 2 cycles to fill
1362 * the cache (fetch,decode,execute)
1364 err
= dsp563xx_step_ex(target
, 1, 0, 1, 1);
1365 if (err
!= ERROR_OK
)
1369 target
->state
= TARGET_RUNNING
;
1371 LOG_DEBUG("%s", __func__
);
1375 static int dsp563xx_run_algorithm(struct target
*target
,
1376 int num_mem_params
, struct mem_param
*mem_params
,
1377 int num_reg_params
, struct reg_param
*reg_params
,
1378 target_addr_t entry_point
, target_addr_t exit_point
,
1379 int timeout_ms
, void *arch_info
)
1382 int retval
= ERROR_OK
;
1383 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1385 if (target
->state
!= TARGET_HALTED
) {
1386 LOG_WARNING("target not halted");
1387 return ERROR_TARGET_NOT_HALTED
;
1390 for (i
= 0; i
< num_mem_params
; i
++) {
1391 if (mem_params
[i
].direction
== PARAM_IN
)
1393 retval
= target_write_buffer(target
, mem_params
[i
].address
,
1394 mem_params
[i
].size
, mem_params
[i
].value
);
1395 if (retval
!= ERROR_OK
)
1399 for (i
= 0; i
< num_reg_params
; i
++) {
1400 if (reg_params
[i
].direction
== PARAM_IN
)
1403 struct reg
*reg
= register_get_by_name(dsp563xx
->core_cache
,
1404 reg_params
[i
].reg_name
,
1408 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
1412 if (reg
->size
!= reg_params
[i
].size
) {
1413 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1414 reg_params
[i
].reg_name
);
1418 retval
= dsp563xx_set_core_reg(reg
, reg_params
[i
].value
);
1419 if (retval
!= ERROR_OK
)
1424 retval
= target_resume(target
, 0, entry_point
, 1, 1);
1425 if (retval
!= ERROR_OK
)
1428 retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
);
1429 if (retval
!= ERROR_OK
)
1432 for (i
= 0; i
< num_mem_params
; i
++) {
1433 if (mem_params
[i
].direction
!= PARAM_OUT
)
1434 retval
= target_read_buffer(target
,
1435 mem_params
[i
].address
,
1437 mem_params
[i
].value
);
1438 if (retval
!= ERROR_OK
)
1442 for (i
= 0; i
< num_reg_params
; i
++) {
1443 if (reg_params
[i
].direction
!= PARAM_OUT
) {
1445 struct reg
*reg
= register_get_by_name(dsp563xx
->core_cache
,
1446 reg_params
[i
].reg_name
,
1449 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
1453 if (reg
->size
!= reg_params
[i
].size
) {
1455 "BUG: register '%s' size doesn't match reg_params[i].size",
1456 reg_params
[i
].reg_name
);
1460 buf_set_u32(reg_params
[i
].value
, 0, 32, buf_get_u32(reg
->value
, 0, 32));
1467 /* global command context from openocd.c */
1468 extern struct command_context
*global_cmd_ctx
;
1470 static int dsp563xx_get_default_memory(void)
1476 if (!global_cmd_ctx
)
1479 interp
= global_cmd_ctx
->interp
;
1484 memspace
= Jim_GetGlobalVariableStr(interp
, "memspace", JIM_NONE
);
1489 c
= (char *)Jim_GetString(memspace
, NULL
);
1508 static int dsp563xx_read_memory_core(struct target
*target
,
1516 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1518 uint32_t data
, move_cmd
= 0;
1522 "memtype: %d address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
1528 if (target
->state
!= TARGET_HALTED
) {
1529 LOG_WARNING("target not halted");
1530 return ERROR_TARGET_NOT_HALTED
;
1535 /* TODO: mark effected queued registers */
1536 move_cmd
= 0x61d800;
1539 move_cmd
= 0x69d800;
1542 move_cmd
= 0x07d891;
1545 return ERROR_COMMAND_SYNTAX_ERROR
;
1548 /* we use r0 to store temporary data */
1549 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
1550 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
1551 /* we use r1 to store temporary data */
1552 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].valid
)
1553 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R1
);
1555 /* r0 is no longer valid on target */
1556 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= true;
1557 /* r1 is no longer valid on target */
1558 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].dirty
= true;
1563 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, 0x60F400, address
);
1564 if (err
!= ERROR_OK
)
1567 for (i
= 0; i
< x
; i
++) {
1568 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, move_cmd
);
1569 if (err
!= ERROR_OK
)
1571 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, 0x08D13C);
1572 if (err
!= ERROR_OK
)
1574 err
= dsp563xx_once_reg_read(target
->tap
, 0,
1575 DSP563XX_ONCE_OGDBR
, (uint32_t *)(void *)b
);
1576 if (err
!= ERROR_OK
)
1581 /* flush the jtag queue */
1582 err
= jtag_execute_queue();
1583 if (err
!= ERROR_OK
)
1586 /* walk over the buffer and fix target endianness */
1589 for (i
= 0; i
< x
; i
++) {
1590 data
= buf_get_u32(b
, 0, 32) & 0x00FFFFFF;
1591 /* LOG_DEBUG("R: %08X", *((uint32_t*)b)); */
1592 target_buffer_set_u32(target
, b
, data
);
1599 static int dsp563xx_read_memory(struct target
*target
,
1601 target_addr_t address
,
1608 uint8_t *buffer_y
, *buffer_x
;
1610 /* if size equals zero we are called from target read memory
1611 * and have to handle the parameter here */
1612 if ((size
== 0) && (count
!= 0)) {
1616 LOG_DEBUG("size is not aligned to 4 byte");
1618 count
= (count
- size
) / 4;
1622 /* we only support 4 byte aligned data */
1623 if ((size
!= 4) || (!count
))
1624 return ERROR_COMMAND_SYNTAX_ERROR
;
1626 if (mem_type
!= MEM_L
)
1627 return dsp563xx_read_memory_core(target
, mem_type
, address
, size
, count
, buffer
);
1629 buffer_y
= malloc(size
* count
);
1631 return ERROR_COMMAND_SYNTAX_ERROR
;
1633 buffer_x
= malloc(size
* count
);
1636 return ERROR_COMMAND_SYNTAX_ERROR
;
1639 err
= dsp563xx_read_memory_core(target
, MEM_Y
, address
, size
, count
/ 2, buffer_y
);
1641 if (err
!= ERROR_OK
) {
1647 err
= dsp563xx_read_memory_core(target
, MEM_X
, address
, size
, count
/ 2, buffer_x
);
1649 if (err
!= ERROR_OK
) {
1655 for (i
= 0, i1
= 0; i
< count
; i
+= 2, i1
++) {
1656 buf_set_u32(buffer
+ i
*sizeof(uint32_t), 0, 32,
1657 buf_get_u32(buffer_y
+ i1
* sizeof(uint32_t), 0, 32));
1658 buf_set_u32(buffer
+ (i
+ 1) * sizeof(uint32_t), 0, 32,
1659 buf_get_u32(buffer_x
+ i1
* sizeof(uint32_t), 0, 32));
1668 static int dsp563xx_read_memory_default(struct target
*target
,
1669 target_addr_t address
,
1675 return dsp563xx_read_memory(target
,
1676 dsp563xx_get_default_memory(), address
, size
, count
, buffer
);
1679 static int dsp563xx_read_buffer_default(struct target
*target
,
1680 target_addr_t address
,
1685 return dsp563xx_read_memory(target
, dsp563xx_get_default_memory(), address
, size
, 0,
1689 static int dsp563xx_write_memory_core(struct target
*target
,
1691 target_addr_t address
,
1694 const uint8_t *buffer
)
1697 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1699 uint32_t data
, move_cmd
= 0;
1703 "memtype: %d address: 0x%8.8" TARGET_PRIxADDR
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
1709 if (target
->state
!= TARGET_HALTED
) {
1710 LOG_WARNING("target not halted");
1711 return ERROR_TARGET_NOT_HALTED
;
1716 /* invalidate affected x registers */
1717 dsp563xx_invalidate_x_context(target
, address
, address
+ count
- 1);
1718 move_cmd
= 0x615800;
1721 move_cmd
= 0x695800;
1724 move_cmd
= 0x075891;
1727 return ERROR_COMMAND_SYNTAX_ERROR
;
1730 /* we use r0 to store temporary data */
1731 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].valid
)
1732 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R0
);
1733 /* we use r1 to store temporary data */
1734 if (!dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].valid
)
1735 dsp563xx
->read_core_reg(target
, DSP563XX_REG_IDX_R1
);
1737 /* r0 is no longer valid on target */
1738 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R0
].dirty
= true;
1739 /* r1 is no longer valid on target */
1740 dsp563xx
->core_cache
->reg_list
[DSP563XX_REG_IDX_R1
].dirty
= true;
1745 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 1, 0x60F400, address
);
1746 if (err
!= ERROR_OK
)
1749 for (i
= 0; i
< x
; i
++) {
1750 data
= target_buffer_get_u32(target
, b
);
1752 /* LOG_DEBUG("W: %08X", data); */
1756 err
= dsp563xx_once_execute_dw_ir(target
->tap
, 0, 0x61F400, data
);
1757 if (err
!= ERROR_OK
)
1759 err
= dsp563xx_once_execute_sw_ir(target
->tap
, 0, move_cmd
);
1760 if (err
!= ERROR_OK
)
1765 /* flush the jtag queue */
1766 err
= jtag_execute_queue();
1767 if (err
!= ERROR_OK
)
1773 static int dsp563xx_write_memory(struct target
*target
,
1775 target_addr_t address
,
1778 const uint8_t *buffer
)
1782 uint8_t *buffer_y
, *buffer_x
;
1784 /* if size equals zero we are called from target write memory
1785 * and have to handle the parameter here */
1786 if ((size
== 0) && (count
!= 0)) {
1790 LOG_DEBUG("size is not aligned to 4 byte");
1792 count
= (count
- size
) / 4;
1796 /* we only support 4 byte aligned data */
1797 if ((size
!= 4) || (!count
))
1798 return ERROR_COMMAND_SYNTAX_ERROR
;
1800 if (mem_type
!= MEM_L
)
1801 return dsp563xx_write_memory_core(target
, mem_type
, address
, size
, count
, buffer
);
1803 buffer_y
= malloc(size
* count
);
1805 return ERROR_COMMAND_SYNTAX_ERROR
;
1807 buffer_x
= malloc(size
* count
);
1810 return ERROR_COMMAND_SYNTAX_ERROR
;
1813 for (i
= 0, i1
= 0; i
< count
; i
+= 2, i1
++) {
1814 buf_set_u32(buffer_y
+ i1
* sizeof(uint32_t), 0, 32,
1815 buf_get_u32(buffer
+ i
* sizeof(uint32_t), 0, 32));
1816 buf_set_u32(buffer_x
+ i1
* sizeof(uint32_t), 0, 32,
1817 buf_get_u32(buffer
+ (i
+ 1) * sizeof(uint32_t), 0, 32));
1820 err
= dsp563xx_write_memory_core(target
, MEM_Y
, address
, size
, count
/ 2, buffer_y
);
1822 if (err
!= ERROR_OK
) {
1828 err
= dsp563xx_write_memory_core(target
, MEM_X
, address
, size
, count
/ 2, buffer_x
);
1830 if (err
!= ERROR_OK
) {
1842 static int dsp563xx_write_memory_default(struct target
*target
,
1843 target_addr_t address
,
1846 const uint8_t *buffer
)
1848 return dsp563xx_write_memory(target
,
1849 dsp563xx_get_default_memory(), address
, size
, count
, buffer
);
1852 static int dsp563xx_write_buffer_default(struct target
*target
,
1853 target_addr_t address
,
1855 const uint8_t *buffer
)
1857 return dsp563xx_write_memory(target
, dsp563xx_get_default_memory(), address
, size
, 0,
1862 * Exit with error here, because we support watchpoints over a custom command.
1863 * This is because the DSP has separate X,Y,P memspace which is not compatible to the
1864 * traditional watchpoint logic.
1866 static int dsp563xx_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1868 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1872 * @see dsp563xx_add_watchpoint
1874 static int dsp563xx_remove_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1876 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1879 static int dsp563xx_add_custom_watchpoint(struct target
*target
, uint32_t address
, uint32_t memType
,
1880 enum watchpoint_rw rw
, enum watchpoint_condition cond
)
1883 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1885 bool wasRunning
= false;
1886 /* Only set breakpoint when halted */
1887 if (target
->state
!= TARGET_HALTED
) {
1888 dsp563xx_halt(target
);
1892 if (dsp563xx
->hardware_breakpoint
[0].used
) {
1893 LOG_ERROR("Cannot add watchpoint. Hardware resource already used.");
1894 err
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1897 uint32_t obcr_value
= 0;
1898 if (err
== ERROR_OK
) {
1899 obcr_value
|= OBCR_b0_or_b1
;
1902 obcr_value
|= OBCR_BP_MEM_X
;
1905 obcr_value
|= OBCR_BP_MEM_Y
;
1908 obcr_value
|= OBCR_BP_MEM_P
;
1911 LOG_ERROR("Unknown memType parameter (%" PRIu32
")", memType
);
1912 err
= ERROR_TARGET_INVALID
;
1916 if (err
== ERROR_OK
) {
1919 obcr_value
|= OBCR_BP_0(OBCR_BP_ON_READ
);
1922 obcr_value
|= OBCR_BP_0(OBCR_BP_ON_WRITE
);
1925 obcr_value
|= OBCR_BP_0(OBCR_BP_ON_READ
|OBCR_BP_ON_WRITE
);
1928 LOG_ERROR("Unsupported write mode (%d)", rw
);
1929 err
= ERROR_TARGET_INVALID
;
1933 if (err
== ERROR_OK
) {
1936 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_EQUAL
);
1939 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_NOT_EQUAL
);
1942 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_LESS_THAN
);
1945 obcr_value
|= OBCR_BP_0(OBCR_BP_CC_GREATER_THAN
);
1948 LOG_ERROR("Unsupported condition code (%d)", cond
);
1949 err
= ERROR_TARGET_INVALID
;
1953 if (err
== ERROR_OK
)
1954 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR0
, address
);
1956 if (err
== ERROR_OK
)
1957 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMLR1
, 0x0);
1959 if (err
== ERROR_OK
)
1960 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OBCR
, obcr_value
);
1962 if (err
== ERROR_OK
) {
1963 /* You should write the memory breakpoint counter to 0 */
1964 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OMBC
, 0);
1967 if (err
== ERROR_OK
) {
1968 /* You should write the memory breakpoint counter to 0 */
1969 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OTC
, 0);
1972 if (err
== ERROR_OK
)
1973 dsp563xx
->hardware_breakpoint
[0].used
= BPU_WATCHPOINT
;
1975 if (err
== ERROR_OK
&& wasRunning
) {
1976 /* Resume from current PC */
1977 err
= dsp563xx_resume(target
, 1, 0x0, 0, 0);
1983 static int dsp563xx_remove_custom_watchpoint(struct target
*target
)
1986 struct dsp563xx_common
*dsp563xx
= target_to_dsp563xx(target
);
1988 if (dsp563xx
->hardware_breakpoint
[0].used
!= BPU_WATCHPOINT
) {
1989 LOG_ERROR("Cannot remove watchpoint, as no watchpoint is currently configured!");
1990 err
= ERROR_TARGET_INVALID
;
1993 if (err
== ERROR_OK
) {
1994 /* Clear watchpoint by clearing OBCR. */
1995 err
= dsp563xx_once_reg_write(target
->tap
, 1, DSP563XX_ONCE_OBCR
, 0);
1998 if (err
== ERROR_OK
)
1999 dsp563xx
->hardware_breakpoint
[0].used
= BPU_NONE
;
2004 COMMAND_HANDLER(dsp563xx_add_watchpoint_command
)
2007 struct target
*target
= get_current_target(CMD_CTX
);
2009 uint32_t mem_type
= 0;
2010 switch (CMD_NAME
[2]) {
2021 return ERROR_COMMAND_SYNTAX_ERROR
;
2025 return ERROR_COMMAND_SYNTAX_ERROR
;
2027 uint32_t address
= 0;
2029 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], address
);
2031 enum watchpoint_condition cond
;
2032 switch (CMD_ARGV
[0][0]) {
2046 return ERROR_COMMAND_SYNTAX_ERROR
;
2049 enum watchpoint_rw rw
;
2050 switch (CMD_ARGV
[1][0]) {
2061 return ERROR_COMMAND_SYNTAX_ERROR
;
2064 err
= dsp563xx_add_custom_watchpoint(target
, address
, mem_type
, rw
, cond
);
2069 /* Adding a breakpoint using the once breakpoint logic.
2070 * Note that this mechanism is a true hw breakpoint and is share between the watchpoint logic.
2071 * This means, you can only have one breakpoint/watchpoint at any time.
2073 static int dsp563xx_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
2075 return dsp563xx_add_custom_watchpoint(target
, breakpoint
->address
, MEM_P
, WPT_READ
, EQUAL
);
2078 static int dsp563xx_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
2080 return dsp563xx_remove_custom_watchpoint(target
);
2083 COMMAND_HANDLER(dsp563xx_remove_watchpoint_command
)
2085 struct target
*target
= get_current_target(CMD_CTX
);
2087 return dsp563xx_remove_custom_watchpoint(target
);
2090 COMMAND_HANDLER(dsp563xx_mem_command
)
2092 struct target
*target
= get_current_target(CMD_CTX
);
2095 uint32_t address
= 0;
2096 uint32_t count
= 1, i
;
2097 uint32_t pattern
= 0;
2099 uint8_t *buffer
, *b
;
2101 switch (CMD_NAME
[1]) {
2109 return ERROR_COMMAND_SYNTAX_ERROR
;
2112 switch (CMD_NAME
[3]) {
2123 return ERROR_COMMAND_SYNTAX_ERROR
;
2127 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
2129 if (read_mem
== 0) {
2131 return ERROR_COMMAND_SYNTAX_ERROR
;
2133 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], pattern
);
2135 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], count
);
2138 if (read_mem
== 1) {
2140 return ERROR_COMMAND_SYNTAX_ERROR
;
2142 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], count
);
2145 buffer
= calloc(count
, sizeof(uint32_t));
2147 if (read_mem
== 1) {
2148 err
= dsp563xx_read_memory(target
, mem_type
, address
, sizeof(uint32_t),
2150 if (err
== ERROR_OK
)
2151 target_handle_md_output(CMD
, target
, address
, sizeof(uint32_t), count
, buffer
);
2156 for (i
= 0; i
< count
; i
++) {
2157 target_buffer_set_u32(target
, b
, pattern
);
2161 err
= dsp563xx_write_memory(target
,
2174 static const struct command_registration dsp563xx_command_handlers
[] = {
2177 .handler
= dsp563xx_mem_command
,
2178 .mode
= COMMAND_EXEC
,
2179 .help
= "write x memory words",
2180 .usage
= "address value [count]",
2184 .handler
= dsp563xx_mem_command
,
2185 .mode
= COMMAND_EXEC
,
2186 .help
= "write y memory words",
2187 .usage
= "address value [count]",
2191 .handler
= dsp563xx_mem_command
,
2192 .mode
= COMMAND_EXEC
,
2193 .help
= "write p memory words",
2194 .usage
= "address value [count]",
2198 .handler
= dsp563xx_mem_command
,
2199 .mode
= COMMAND_EXEC
,
2200 .help
= "display x memory words",
2201 .usage
= "address [count]",
2205 .handler
= dsp563xx_mem_command
,
2206 .mode
= COMMAND_EXEC
,
2207 .help
= "display y memory words",
2208 .usage
= "address [count]",
2212 .handler
= dsp563xx_mem_command
,
2213 .mode
= COMMAND_EXEC
,
2214 .help
= "display p memory words",
2215 .usage
= "address [count]",
2218 * Watchpoint commands
2222 .handler
= dsp563xx_add_watchpoint_command
,
2223 .mode
= COMMAND_EXEC
,
2224 .help
= "Create p memspace watchpoint",
2225 .usage
= "(>|<|=|!) (r|w|a) address",
2229 .handler
= dsp563xx_add_watchpoint_command
,
2230 .mode
= COMMAND_EXEC
,
2231 .help
= "Create x memspace watchpoint",
2232 .usage
= "(>|<|=|!) (r|w|a) address",
2236 .handler
= dsp563xx_add_watchpoint_command
,
2237 .mode
= COMMAND_EXEC
,
2238 .help
= "Create y memspace watchpoint",
2239 .usage
= "(>|<|=|!) (r|w|a) address",
2243 .handler
= dsp563xx_remove_watchpoint_command
,
2244 .mode
= COMMAND_EXEC
,
2245 .help
= "remove watchpoint custom",
2248 COMMAND_REGISTRATION_DONE
2251 /** Holds methods for DSP563XX targets. */
2252 struct target_type dsp563xx_target
= {
2255 .poll
= dsp563xx_poll
,
2256 .arch_state
= dsp563xx_arch_state
,
2258 .get_gdb_reg_list
= dsp563xx_get_gdb_reg_list
,
2260 .halt
= dsp563xx_halt
,
2261 .resume
= dsp563xx_resume
,
2262 .step
= dsp563xx_step
,
2264 .assert_reset
= dsp563xx_assert_reset
,
2265 .deassert_reset
= dsp563xx_deassert_reset
,
2267 .read_memory
= dsp563xx_read_memory_default
,
2268 .write_memory
= dsp563xx_write_memory_default
,
2270 .read_buffer
= dsp563xx_read_buffer_default
,
2271 .write_buffer
= dsp563xx_write_buffer_default
,
2273 .run_algorithm
= dsp563xx_run_algorithm
,
2275 .add_breakpoint
= dsp563xx_add_breakpoint
,
2276 .remove_breakpoint
= dsp563xx_remove_breakpoint
,
2277 .add_watchpoint
= dsp563xx_add_watchpoint
,
2278 .remove_watchpoint
= dsp563xx_remove_watchpoint
,
2280 .commands
= dsp563xx_command_handlers
,
2281 .target_create
= dsp563xx_target_create
,
2282 .init_target
= dsp563xx_init_target
,
2283 .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)