build: cleanup src/target directory
[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 static int mips_ejtag_step_enable(struct mips_ejtag *ejtag_info)
194 {
195 static const uint32_t code[] = {
196 MIPS32_MTC0(1, 31, 0), /* move $1 to COP0 DeSave */
197 MIPS32_MFC0(1, 23, 0), /* move COP0 Debug to $1 */
198 MIPS32_ORI(1, 1, 0x0100), /* set SSt bit in debug reg */
199 MIPS32_MTC0(1, 23, 0), /* move $1 to COP0 Debug */
200 MIPS32_B(NEG16(5)),
201 MIPS32_MFC0(1, 31, 0), /* move COP0 DeSave to $1 */
202 };
203
204 return mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
205 0, NULL, 0, NULL, 1);
206 }
207
208 static int mips_ejtag_step_disable(struct mips_ejtag *ejtag_info)
209 {
210 static const uint32_t code[] = {
211 MIPS32_MTC0(15, 31, 0), /* move $15 to COP0 DeSave */
212 MIPS32_LUI(15, UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
213 MIPS32_ORI(15, 15, LOWER16(MIPS32_PRACC_STACK)),
214 MIPS32_SW(1, 0, 15), /* sw $1,($15) */
215 MIPS32_SW(2, 0, 15), /* sw $2,($15) */
216 MIPS32_MFC0(1, 23, 0), /* move COP0 Debug to $1 */
217 MIPS32_LUI(2, 0xFFFF), /* $2 = 0xfffffeff */
218 MIPS32_ORI(2, 2, 0xFEFF),
219 MIPS32_AND(1, 1, 2),
220 MIPS32_MTC0(1, 23, 0), /* move $1 to COP0 Debug */
221 MIPS32_LW(2, 0, 15),
222 MIPS32_LW(1, 0, 15),
223 MIPS32_B(NEG16(13)),
224 MIPS32_MFC0(15, 31, 0), /* move COP0 DeSave to $15 */
225 };
226
227 return mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
228 0, NULL, 0, NULL, 1);
229 }
230
231 int mips_ejtag_config_step(struct mips_ejtag *ejtag_info, int enable_step)
232 {
233 if (enable_step)
234 return mips_ejtag_step_enable(ejtag_info);
235 return mips_ejtag_step_disable(ejtag_info);
236 }
237
238 int mips_ejtag_enter_debug(struct mips_ejtag *ejtag_info)
239 {
240 uint32_t ejtag_ctrl;
241 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
242
243 /* set debug break bit */
244 ejtag_ctrl = ejtag_info->ejtag_ctrl | EJTAG_CTRL_JTAGBRK;
245 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
246
247 /* break bit will be cleared by hardware */
248 ejtag_ctrl = ejtag_info->ejtag_ctrl;
249 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
250 LOG_DEBUG("ejtag_ctrl: 0x%8.8" PRIx32 "", ejtag_ctrl);
251 if ((ejtag_ctrl & EJTAG_CTRL_BRKST) == 0) {
252 LOG_ERROR("Failed to enter Debug Mode!");
253 return ERROR_FAIL;
254 }
255
256 return ERROR_OK;
257 }
258
259 int mips_ejtag_exit_debug(struct mips_ejtag *ejtag_info)
260 {
261 uint32_t inst;
262 inst = MIPS32_DRET;
263
264 /* execute our dret instruction */
265 return mips32_pracc_exec(ejtag_info, 1, &inst, 0, NULL, 0, NULL, 0);
266 }
267
268 int mips_ejtag_read_debug(struct mips_ejtag *ejtag_info, uint32_t* debug_reg)
269 {
270 /* read ejtag ECR */
271 static const uint32_t code[] = {
272 MIPS32_MTC0(15, 31, 0), /* move $15 to COP0 DeSave */
273 MIPS32_LUI(15, UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
274 MIPS32_ORI(15, 15, LOWER16(MIPS32_PRACC_STACK)),
275 MIPS32_SW(1, 0, 15), /* sw $1,($15) */
276 MIPS32_SW(2, 0, 15), /* sw $2,($15) */
277 MIPS32_LUI(1, UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $1 = MIPS32_PRACC_PARAM_OUT */
278 MIPS32_ORI(1, 1, LOWER16(MIPS32_PRACC_PARAM_OUT)),
279 MIPS32_MFC0(2, 23, 0), /* move COP0 Debug to $2 */
280 MIPS32_SW(2, 0, 1),
281 MIPS32_LW(2, 0, 15),
282 MIPS32_LW(1, 0, 15),
283 MIPS32_B(NEG16(12)),
284 MIPS32_MFC0(15, 31, 0), /* move COP0 DeSave to $15 */
285 };
286
287 return mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
288 0, NULL, 1, debug_reg, 1);
289 }
290
291 int mips_ejtag_init(struct mips_ejtag *ejtag_info)
292 {
293 uint32_t ejtag_version;
294 int retval;
295
296 retval = mips_ejtag_get_impcode(ejtag_info, &ejtag_info->impcode);
297 if (retval != ERROR_OK)
298 return retval;
299 LOG_DEBUG("impcode: 0x%8.8" PRIx32 "", ejtag_info->impcode);
300
301 /* get ejtag version */
302 ejtag_version = ((ejtag_info->impcode >> 29) & 0x07);
303
304 switch (ejtag_version) {
305 case 0:
306 LOG_DEBUG("EJTAG: Version 1 or 2.0 Detected");
307 break;
308 case 1:
309 LOG_DEBUG("EJTAG: Version 2.5 Detected");
310 break;
311 case 2:
312 LOG_DEBUG("EJTAG: Version 2.6 Detected");
313 break;
314 case 3:
315 LOG_DEBUG("EJTAG: Version 3.1 Detected");
316 break;
317 default:
318 LOG_DEBUG("EJTAG: Unknown Version Detected");
319 break;
320 }
321 LOG_DEBUG("EJTAG: features:%s%s%s%s%s%s%s",
322 ejtag_info->impcode & EJTAG_IMP_R3K ? " R3k" : " R4k",
323 ejtag_info->impcode & EJTAG_IMP_DINT ? " DINT" : "",
324 ejtag_info->impcode & (1 << 22) ? " ASID_8" : "",
325 ejtag_info->impcode & (1 << 21) ? " ASID_6" : "",
326 ejtag_info->impcode & EJTAG_IMP_MIPS16 ? " MIPS16" : "",
327 ejtag_info->impcode & EJTAG_IMP_NODMA ? " noDMA" : " DMA",
328 ejtag_info->impcode & EJTAG_DCR_MIPS64 ? " MIPS64" : " MIPS32");
329
330 if ((ejtag_info->impcode & EJTAG_IMP_NODMA) == 0)
331 LOG_DEBUG("EJTAG: DMA Access Mode Support Enabled");
332
333 /* set initial state for ejtag control reg */
334 ejtag_info->ejtag_ctrl = EJTAG_CTRL_ROCC | EJTAG_CTRL_PRACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_SETDEV;
335 ejtag_info->fast_access_save = -1;
336
337 return ERROR_OK;
338 }
339
340 int mips_ejtag_fastdata_scan(struct mips_ejtag *ejtag_info, int write_t, uint32_t *data)
341 {
342 struct jtag_tap *tap;
343
344 tap = ejtag_info->tap;
345 assert(tap != NULL);
346
347 struct scan_field fields[2];
348 uint8_t spracc = 0;
349 uint8_t t[4] = {0, 0, 0, 0};
350
351 /* fastdata 1-bit register */
352 fields[0].num_bits = 1;
353 fields[0].out_value = &spracc;
354 fields[0].in_value = NULL;
355
356 /* processor access data register 32 bit */
357 fields[1].num_bits = 32;
358 fields[1].out_value = t;
359
360 if (write_t) {
361 fields[1].in_value = NULL;
362 buf_set_u32(t, 0, 32, *data);
363 } else
364 fields[1].in_value = (void *) data;
365
366 jtag_add_dr_scan(tap, 2, fields, TAP_IDLE);
367
368 if (!write_t && data)
369 jtag_add_callback(mips_le_to_h_u32,
370 (jtag_callback_data_t) data);
371
372 keep_alive();
373
374 return ERROR_OK;
375 }

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)