dsp563xx: Adding breakpoint/watchpoint support.
[openocd.git] / src / target / dsp563xx_once.c
1 /***************************************************************************
2 * Copyright (C) 2009 by Mathias Kuester *
3 * mkdorg@users.sourceforge.net *
4 * *
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. *
9 * *
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. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
19 ***************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <jim.h>
26
27 #include "target.h"
28 #include "target_type.h"
29 #include "register.h"
30 #include "dsp563xx.h"
31 #include "dsp563xx_once.h"
32
33 #define JTAG_STATUS_STATIC_MASK 0x03
34 #define JTAG_STATUS_STATIC_VALUE 0x01
35
36 #define JTAG_STATUS_NORMAL 0x01
37 #define JTAG_STATUS_STOPWAIT 0x05
38 #define JTAG_STATUS_BUSY 0x09
39 #define JTAG_STATUS_DEBUG 0x0d
40
41 #define JTAG_INSTR_EXTEST 0x00
42 #define JTAG_INSTR_SAMPLE_PRELOAD 0x01
43 #define JTAG_INSTR_IDCODE 0x02
44 #define JTAG_INSTR_HIZ 0x04
45 #define JTAG_INSTR_CLAMP 0x05
46 #define JTAG_INSTR_ENABLE_ONCE 0x06
47 #define JTAG_INSTR_DEBUG_REQUEST 0x07
48 #define JTAG_INSTR_BYPASS 0x0F
49
50 /** */
51 static inline int dsp563xx_write_dr(struct jtag_tap *tap, uint8_t * dr_in, uint8_t * dr_out, int dr_len, int rti)
52 {
53 jtag_add_plain_dr_scan(dr_len, dr_out, dr_in, TAP_IDLE);
54
55 return ERROR_OK;
56 }
57
58 /** */
59 static inline int dsp563xx_write_dr_u8(struct jtag_tap *tap, uint8_t * dr_in, uint8_t dr_out, int dr_len, int rti)
60 {
61 return dsp563xx_write_dr(tap, dr_in, &dr_out, dr_len, rti);
62 }
63
64 /** */
65 static inline int dsp563xx_write_dr_u32(struct jtag_tap *tap, uint32_t * dr_in, uint32_t dr_out, int dr_len, int rti)
66 {
67 return dsp563xx_write_dr(tap, (uint8_t *) dr_in, (uint8_t *) &dr_out, dr_len, rti);
68 }
69
70 /** single word instruction */
71 static inline int dsp563xx_once_ir_exec(struct jtag_tap *tap, int flush, uint8_t instr, uint8_t rw, uint8_t go, uint8_t ex)
72 {
73 int err;
74
75 err = dsp563xx_write_dr_u8(tap, 0, instr | (ex << 5) | (go << 6) | (rw << 7), 8, 0);
76 if (err != ERROR_OK)
77 return err;
78 if (flush)
79 err = jtag_execute_queue();
80 return err;
81 }
82
83 /* IR and DR functions */
84 static inline int dsp563xx_write_ir(struct jtag_tap *tap, uint8_t * ir_in, uint8_t * ir_out, int ir_len, int rti)
85 {
86 jtag_add_plain_ir_scan(tap->ir_length, ir_out, ir_in, TAP_IDLE);
87
88 return ERROR_OK;
89 }
90
91 static inline int dsp563xx_write_ir_u8(struct jtag_tap *tap, uint8_t * ir_in, uint8_t ir_out, int ir_len, int rti)
92 {
93 return dsp563xx_write_ir(tap, ir_in, &ir_out, ir_len, rti);
94 }
95
96 static inline int dsp563xx_jtag_sendinstr(struct jtag_tap *tap, uint8_t * ir_in, uint8_t ir_out)
97 {
98 return dsp563xx_write_ir_u8(tap, ir_in, ir_out, tap->ir_length, 1);
99 }
100
101 /** */
102 int dsp563xx_once_target_status(struct jtag_tap *tap)
103 {
104 int err;
105 uint8_t jtag_status;
106
107 err = dsp563xx_jtag_sendinstr(tap, &jtag_status, JTAG_INSTR_ENABLE_ONCE);
108 if (err != ERROR_OK)
109 return TARGET_UNKNOWN;
110 err = jtag_execute_queue();
111 if (err != ERROR_OK)
112 return TARGET_UNKNOWN;
113
114 /* verify correct static status pattern */
115 if ((jtag_status & JTAG_STATUS_STATIC_MASK) != JTAG_STATUS_STATIC_VALUE)
116 return TARGET_UNKNOWN;
117
118 if (jtag_status != JTAG_STATUS_DEBUG)
119 return TARGET_RUNNING;
120
121 return TARGET_HALTED;
122 }
123
124 /** */
125 int dsp563xx_once_request_debug(struct jtag_tap *tap, int reset_state)
126 {
127 int err;
128 uint8_t ir_in = 0, pattern = 0;
129 uint32_t retry = 0;
130
131 /* in reset state we only get a ACK
132 * from the interface */
133 if (reset_state)
134 pattern = 1;
135 else
136 pattern = JTAG_STATUS_DEBUG;
137
138 /* wait until we get the ack */
139 while (ir_in != pattern) {
140 err = dsp563xx_jtag_sendinstr(tap, &ir_in, JTAG_INSTR_DEBUG_REQUEST);
141 if (err != ERROR_OK)
142 return err;
143 err = jtag_execute_queue();
144 if (err != ERROR_OK)
145 return err;
146
147 LOG_DEBUG("debug request: %02X", ir_in);
148
149 if (retry++ == 100)
150 return ERROR_TARGET_FAILURE;
151 }
152
153 /* we cant enable the once in reset state */
154 if (pattern == 1)
155 return ERROR_OK;
156
157 /* try to enable once */
158 retry = 0;
159 ir_in = 0;
160 while (ir_in != pattern) {
161 err = dsp563xx_jtag_sendinstr(tap, &ir_in, JTAG_INSTR_ENABLE_ONCE);
162 if (err != ERROR_OK)
163 return err;
164 err = jtag_execute_queue();
165 if (err != ERROR_OK)
166 return err;
167
168 LOG_DEBUG("enable once: %02X", ir_in);
169
170 if (retry++ == 100) {
171 LOG_DEBUG("error");
172 return ERROR_TARGET_FAILURE;
173 }
174 }
175
176 if (ir_in != JTAG_STATUS_DEBUG)
177 return ERROR_TARGET_FAILURE;
178
179 return ERROR_OK;
180 }
181
182 /** once read registers */
183 int dsp563xx_once_read_register(struct jtag_tap *tap, int flush, struct once_reg *regs, int len)
184 {
185 int i;
186 int err = ERROR_OK;
187
188 for (i = 0; i < len; i++) {
189 err = dsp563xx_once_reg_read_ex(tap, flush, regs[i].addr, regs[i].len, &regs[i].reg);
190 if (err != ERROR_OK)
191 return err;
192 }
193
194 if (flush)
195 err = jtag_execute_queue();
196 return err;
197 }
198
199 /** once read register with register len */
200 int dsp563xx_once_reg_read_ex(struct jtag_tap *tap, int flush, uint8_t reg, uint8_t len, uint32_t * data)
201 {
202 int err;
203
204 err = dsp563xx_once_ir_exec(tap, 1, reg, 1, 0, 0);
205 if (err != ERROR_OK)
206 return err;
207 err = dsp563xx_write_dr_u32(tap, data, 0x00, len, 0);
208 if (err != ERROR_OK)
209 return err;
210 if (flush)
211 err = jtag_execute_queue();
212
213 return err;
214 }
215
216 /** once read register */
217 int dsp563xx_once_reg_read(struct jtag_tap *tap, int flush, uint8_t reg, uint32_t * data)
218 {
219 int err;
220
221 err = dsp563xx_once_ir_exec(tap, flush, reg, 1, 0, 0);
222 if (err != ERROR_OK)
223 return err;
224 err = dsp563xx_write_dr_u32(tap, data, 0x00, 24, 0);
225 if (err != ERROR_OK)
226 return err;
227 if (flush)
228 err = jtag_execute_queue();
229
230 return err;
231 }
232
233 /** once write register */
234 int dsp563xx_once_reg_write(struct jtag_tap *tap, int flush, uint8_t reg, uint32_t data)
235 {
236 int err;
237
238 err = dsp563xx_once_ir_exec(tap, flush, reg, 0, 0, 0);
239 if (err != ERROR_OK)
240 return err;
241 err = dsp563xx_write_dr_u32(tap, 0x00, data, 24, 0);
242 if (err != ERROR_OK)
243 return err;
244 if (flush)
245 err = jtag_execute_queue();
246 return err;
247 }
248
249 /** single word instruction */
250 int dsp563xx_once_execute_sw_ir(struct jtag_tap *tap, int flush, uint32_t opcode)
251 {
252 int err;
253
254 err = dsp563xx_once_ir_exec(tap, flush, DSP563XX_ONCE_OPDBR, 0, 1, 0);
255 if (err != ERROR_OK)
256 return err;
257 err = dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0);
258 if (err != ERROR_OK)
259 return err;
260 if (flush)
261 err = jtag_execute_queue();
262 return err;
263 }
264
265 /** double word instruction */
266 int dsp563xx_once_execute_dw_ir(struct jtag_tap *tap, int flush, uint32_t opcode, uint32_t operand)
267 {
268 int err;
269
270 err = dsp563xx_once_ir_exec(tap, flush, DSP563XX_ONCE_OPDBR, 0, 0, 0);
271 if (err != ERROR_OK)
272 return err;
273 err = dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0);
274 if (err != ERROR_OK)
275 return err;
276 if (flush) {
277 err = jtag_execute_queue();
278 if (err != ERROR_OK)
279 return err;
280 }
281
282 err = dsp563xx_once_ir_exec(tap, flush, DSP563XX_ONCE_OPDBR, 0, 1, 0);
283 if (err != ERROR_OK)
284 return err;
285 err = dsp563xx_write_dr_u32(tap, 0, operand, 24, 0);
286 if (err != ERROR_OK)
287 return err;
288 if (flush) {
289 err = jtag_execute_queue();
290 if (err != ERROR_OK)
291 return err;
292 }
293
294 return ERROR_OK;
295 }

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)