mips_ejtag: Adding EJTAG 4.x and 5.x as valid versions
[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 return mips32_pracc_exec(ejtag_info, 1, &inst, 0, NULL, 0, NULL, 0);
249 }
250
251 int mips_ejtag_init(struct mips_ejtag *ejtag_info)
252 {
253 uint32_t ejtag_version;
254 int retval;
255
256 retval = mips_ejtag_get_impcode(ejtag_info, &ejtag_info->impcode);
257 if (retval != ERROR_OK)
258 return retval;
259 LOG_DEBUG("impcode: 0x%8.8" PRIx32 "", ejtag_info->impcode);
260
261 /* get ejtag version */
262 ejtag_version = ((ejtag_info->impcode >> 29) & 0x07);
263
264 switch (ejtag_version) {
265 case 0:
266 LOG_DEBUG("EJTAG: Version 1 or 2.0 Detected");
267 break;
268 case 1:
269 LOG_DEBUG("EJTAG: Version 2.5 Detected");
270 break;
271 case 2:
272 LOG_DEBUG("EJTAG: Version 2.6 Detected");
273 break;
274 case 3:
275 LOG_DEBUG("EJTAG: Version 3.1 Detected");
276 break;
277 case 4:
278 LOG_DEBUG("EJTAG: Version 4.1 Detected");
279 break;
280 case 5:
281 LOG_DEBUG("EJTAG: Version 5.1 Detected");
282 break;
283 default:
284 LOG_DEBUG("EJTAG: Unknown Version Detected");
285 break;
286 }
287 LOG_DEBUG("EJTAG: features:%s%s%s%s%s%s%s",
288 ejtag_info->impcode & EJTAG_IMP_R3K ? " R3k" : " R4k",
289 ejtag_info->impcode & EJTAG_IMP_DINT ? " DINT" : "",
290 ejtag_info->impcode & (1 << 22) ? " ASID_8" : "",
291 ejtag_info->impcode & (1 << 21) ? " ASID_6" : "",
292 ejtag_info->impcode & EJTAG_IMP_MIPS16 ? " MIPS16" : "",
293 ejtag_info->impcode & EJTAG_IMP_NODMA ? " noDMA" : " DMA",
294 ejtag_info->impcode & EJTAG_DCR_MIPS64 ? " MIPS64" : " MIPS32");
295
296 if ((ejtag_info->impcode & EJTAG_IMP_NODMA) == 0)
297 LOG_DEBUG("EJTAG: DMA Access Mode Support Enabled");
298
299 /* set initial state for ejtag control reg */
300 ejtag_info->ejtag_ctrl = EJTAG_CTRL_ROCC | EJTAG_CTRL_PRACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_SETDEV;
301 ejtag_info->fast_access_save = -1;
302
303 return ERROR_OK;
304 }
305
306 int mips_ejtag_fastdata_scan(struct mips_ejtag *ejtag_info, int write_t, uint32_t *data)
307 {
308 struct jtag_tap *tap;
309
310 tap = ejtag_info->tap;
311 assert(tap != NULL);
312
313 struct scan_field fields[2];
314 uint8_t spracc = 0;
315 uint8_t t[4] = {0, 0, 0, 0};
316
317 /* fastdata 1-bit register */
318 fields[0].num_bits = 1;
319 fields[0].out_value = &spracc;
320 fields[0].in_value = NULL;
321
322 /* processor access data register 32 bit */
323 fields[1].num_bits = 32;
324 fields[1].out_value = t;
325
326 if (write_t) {
327 fields[1].in_value = NULL;
328 buf_set_u32(t, 0, 32, *data);
329 } else
330 fields[1].in_value = (void *) data;
331
332 jtag_add_dr_scan(tap, 2, fields, TAP_IDLE);
333
334 if (!write_t && data)
335 jtag_add_callback(mips_le_to_h_u32,
336 (jtag_callback_data_t) data);
337
338 keep_alive();
339
340 return ERROR_OK;
341 }

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)