pic32mx: false pending at low core clock
[openocd.git] / src / target / mips_ejtag.c
1 /***************************************************************************
2 * Copyright (C) 2008 by Spencer Oliver *
3 * spen@spen-soft.co.uk *
4 * *
5 * Copyright (C) 2008 by David T.L. Wong *
6 * *
7 * Copyright (C) 2009 by David N. Claffey <dnclaffey@gmail.com> *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
18 * *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program; if not, write to the *
21 * Free Software Foundation, Inc., *
22 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
23 ***************************************************************************/
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include "mips32.h"
30 #include "mips_ejtag.h"
31
32 void mips_ejtag_set_instr(struct mips_ejtag *ejtag_info, int new_instr)
33 {
34 struct jtag_tap *tap;
35
36 tap = ejtag_info->tap;
37 assert(tap != NULL);
38
39 if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != (uint32_t)new_instr) {
40 struct scan_field field;
41 uint8_t t[4];
42
43 field.num_bits = tap->ir_length;
44 field.out_value = t;
45 buf_set_u32(t, 0, field.num_bits, new_instr);
46 field.in_value = NULL;
47
48 jtag_add_ir_scan(tap, &field, TAP_IDLE);
49 }
50 }
51
52 int mips_ejtag_get_idcode(struct mips_ejtag *ejtag_info, uint32_t *idcode)
53 {
54 struct scan_field field;
55 uint8_t r[4];
56
57 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_IDCODE);
58
59 field.num_bits = 32;
60 field.out_value = NULL;
61 field.in_value = r;
62
63 jtag_add_dr_scan(ejtag_info->tap, 1, &field, TAP_IDLE);
64
65 int retval;
66 retval = jtag_execute_queue();
67 if (retval != ERROR_OK) {
68 LOG_ERROR("register read failed");
69 return retval;
70 }
71
72 *idcode = buf_get_u32(field.in_value, 0, 32);
73
74 return ERROR_OK;
75 }
76
77 static int mips_ejtag_get_impcode(struct mips_ejtag *ejtag_info, uint32_t *impcode)
78 {
79 struct scan_field field;
80 uint8_t r[4];
81
82 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_IMPCODE);
83
84 field.num_bits = 32;
85 field.out_value = NULL;
86 field.in_value = r;
87
88 jtag_add_dr_scan(ejtag_info->tap, 1, &field, TAP_IDLE);
89
90 int retval;
91 retval = jtag_execute_queue();
92 if (retval != ERROR_OK) {
93 LOG_ERROR("register read failed");
94 return retval;
95 }
96
97 *impcode = buf_get_u32(field.in_value, 0, 32);
98
99 return ERROR_OK;
100 }
101
102 int mips_ejtag_drscan_32(struct mips_ejtag *ejtag_info, uint32_t *data)
103 {
104 struct jtag_tap *tap;
105 tap = ejtag_info->tap;
106 assert(tap != NULL);
107
108 struct scan_field field;
109 uint8_t t[4], r[4];
110 int retval;
111
112 field.num_bits = 32;
113 field.out_value = t;
114 buf_set_u32(t, 0, field.num_bits, *data);
115 field.in_value = r;
116
117 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
118
119 retval = jtag_execute_queue();
120 if (retval != ERROR_OK) {
121 LOG_ERROR("register read failed");
122 return retval;
123 }
124
125 *data = buf_get_u32(field.in_value, 0, 32);
126
127 keep_alive();
128
129 return ERROR_OK;
130 }
131
132 void mips_ejtag_drscan_32_out(struct mips_ejtag *ejtag_info, uint32_t data)
133 {
134 uint8_t t[4];
135 struct jtag_tap *tap;
136 tap = ejtag_info->tap;
137 assert(tap != NULL);
138
139 struct scan_field field;
140
141 field.num_bits = 32;
142 field.out_value = t;
143 buf_set_u32(t, 0, field.num_bits, data);
144
145 field.in_value = NULL;
146
147 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
148 }
149
150 int mips_ejtag_drscan_8(struct mips_ejtag *ejtag_info, uint32_t *data)
151 {
152 struct jtag_tap *tap;
153 tap = ejtag_info->tap;
154 assert(tap != NULL);
155
156 struct scan_field field;
157 uint8_t t[4] = {0, 0, 0, 0}, r[4];
158 int retval;
159
160 field.num_bits = 8;
161 field.out_value = t;
162 buf_set_u32(t, 0, field.num_bits, *data);
163 field.in_value = r;
164
165 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
166
167 retval = jtag_execute_queue();
168 if (retval != ERROR_OK) {
169 LOG_ERROR("register read failed");
170 return retval;
171 }
172
173 *data = buf_get_u32(field.in_value, 0, 32);
174
175 return ERROR_OK;
176 }
177
178 void mips_ejtag_drscan_8_out(struct mips_ejtag *ejtag_info, uint8_t data)
179 {
180 struct jtag_tap *tap;
181 tap = ejtag_info->tap;
182 assert(tap != NULL);
183
184 struct scan_field field;
185
186 field.num_bits = 8;
187 field.out_value = &data;
188 field.in_value = NULL;
189
190 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
191 }
192
193 /* Set (to enable) or clear (to disable stepping) the SSt bit (bit 8) in Cp0 Debug reg (reg 23, sel 0) */
194 int mips_ejtag_config_step(struct mips_ejtag *ejtag_info, int enable_step)
195 {
196 int code_len = enable_step ? 6 : 7;
197
198 uint32_t *code = malloc(code_len * sizeof(uint32_t));
199 if (code == NULL) {
200 LOG_ERROR("Out of memory");
201 return ERROR_FAIL;
202 }
203 uint32_t *code_p = code;
204
205 *code_p++ = MIPS32_MTC0(1, 31, 0); /* move $1 to COP0 DeSave */
206 *code_p++ = MIPS32_MFC0(1, 23, 0), /* move COP0 Debug to $1 */
207 *code_p++ = MIPS32_ORI(1, 1, 0x0100); /* set SSt bit in debug reg */
208 if (!enable_step)
209 *code_p++ = MIPS32_XORI(1, 1, 0x0100); /* clear SSt bit in debug reg */
210
211 *code_p++ = MIPS32_MTC0(1, 23, 0); /* move $1 to COP0 Debug */
212 *code_p++ = MIPS32_B(NEG16((code_len - 1))); /* jump to start */
213 *code_p = MIPS32_MFC0(1, 31, 0); /* move COP0 DeSave to $1 */
214
215 int retval = mips32_pracc_exec(ejtag_info, code_len, code, 0, NULL, 0, NULL, 1);
216
217 free(code);
218 return retval;
219 }
220
221 int mips_ejtag_enter_debug(struct mips_ejtag *ejtag_info)
222 {
223 uint32_t ejtag_ctrl;
224 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
225
226 /* set debug break bit */
227 ejtag_ctrl = ejtag_info->ejtag_ctrl | EJTAG_CTRL_JTAGBRK;
228 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
229
230 /* break bit will be cleared by hardware */
231 ejtag_ctrl = ejtag_info->ejtag_ctrl;
232 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
233 LOG_DEBUG("ejtag_ctrl: 0x%8.8" PRIx32 "", ejtag_ctrl);
234 if ((ejtag_ctrl & EJTAG_CTRL_BRKST) == 0) {
235 LOG_ERROR("Failed to enter Debug Mode!");
236 return ERROR_FAIL;
237 }
238
239 return ERROR_OK;
240 }
241
242 int mips_ejtag_exit_debug(struct mips_ejtag *ejtag_info)
243 {
244 uint32_t inst;
245 inst = MIPS32_DRET;
246
247 /* execute our dret instruction */
248 int retval = mips32_pracc_exec(ejtag_info, 1, &inst, 0, NULL, 0, NULL, 0);
249
250 /* pic32mx workaround, false pending at low core clock */
251 jtag_add_sleep(1000);
252
253 return retval;
254 }
255
256 int mips_ejtag_init(struct mips_ejtag *ejtag_info)
257 {
258 uint32_t ejtag_version;
259 int retval;
260
261 retval = mips_ejtag_get_impcode(ejtag_info, &ejtag_info->impcode);
262 if (retval != ERROR_OK)
263 return retval;
264 LOG_DEBUG("impcode: 0x%8.8" PRIx32 "", ejtag_info->impcode);
265
266 /* get ejtag version */
267 ejtag_version = ((ejtag_info->impcode >> 29) & 0x07);
268
269 switch (ejtag_version) {
270 case 0:
271 LOG_DEBUG("EJTAG: Version 1 or 2.0 Detected");
272 break;
273 case 1:
274 LOG_DEBUG("EJTAG: Version 2.5 Detected");
275 break;
276 case 2:
277 LOG_DEBUG("EJTAG: Version 2.6 Detected");
278 break;
279 case 3:
280 LOG_DEBUG("EJTAG: Version 3.1 Detected");
281 break;
282 case 4:
283 LOG_DEBUG("EJTAG: Version 4.1 Detected");
284 break;
285 case 5:
286 LOG_DEBUG("EJTAG: Version 5.1 Detected");
287 break;
288 default:
289 LOG_DEBUG("EJTAG: Unknown Version Detected");
290 break;
291 }
292 LOG_DEBUG("EJTAG: features:%s%s%s%s%s%s%s",
293 ejtag_info->impcode & EJTAG_IMP_R3K ? " R3k" : " R4k",
294 ejtag_info->impcode & EJTAG_IMP_DINT ? " DINT" : "",
295 ejtag_info->impcode & (1 << 22) ? " ASID_8" : "",
296 ejtag_info->impcode & (1 << 21) ? " ASID_6" : "",
297 ejtag_info->impcode & EJTAG_IMP_MIPS16 ? " MIPS16" : "",
298 ejtag_info->impcode & EJTAG_IMP_NODMA ? " noDMA" : " DMA",
299 ejtag_info->impcode & EJTAG_DCR_MIPS64 ? " MIPS64" : " MIPS32");
300
301 if ((ejtag_info->impcode & EJTAG_IMP_NODMA) == 0)
302 LOG_DEBUG("EJTAG: DMA Access Mode Support Enabled");
303
304 /* set initial state for ejtag control reg */
305 ejtag_info->ejtag_ctrl = EJTAG_CTRL_ROCC | EJTAG_CTRL_PRACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_SETDEV;
306 ejtag_info->fast_access_save = -1;
307
308 return ERROR_OK;
309 }
310
311 int mips_ejtag_fastdata_scan(struct mips_ejtag *ejtag_info, int write_t, uint32_t *data)
312 {
313 struct jtag_tap *tap;
314
315 tap = ejtag_info->tap;
316 assert(tap != NULL);
317
318 struct scan_field fields[2];
319 uint8_t spracc = 0;
320 uint8_t t[4] = {0, 0, 0, 0};
321
322 /* fastdata 1-bit register */
323 fields[0].num_bits = 1;
324 fields[0].out_value = &spracc;
325 fields[0].in_value = NULL;
326
327 /* processor access data register 32 bit */
328 fields[1].num_bits = 32;
329 fields[1].out_value = t;
330
331 if (write_t) {
332 fields[1].in_value = NULL;
333 buf_set_u32(t, 0, 32, *data);
334 } else
335 fields[1].in_value = (void *) data;
336
337 jtag_add_dr_scan(tap, 2, fields, TAP_IDLE);
338
339 if (!write_t && data)
340 jtag_add_callback(mips_le_to_h_u32,
341 (jtag_callback_data_t) data);
342
343 keep_alive();
344
345 return ERROR_OK;
346 }

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)