6ce702fdbb0c43e07809c97db49b5b06a64c4250
[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 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include "mips32.h"
29 #include "mips_ejtag.h"
30
31 int mips_ejtag_set_instr(struct mips_ejtag *ejtag_info, int new_instr)
32 {
33 struct jtag_tap *tap;
34
35 tap = ejtag_info->tap;
36 if (tap == NULL)
37 return ERROR_FAIL;
38
39 if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != (uint32_t)new_instr)
40 {
41 struct scan_field field;
42 uint8_t t[4];
43
44 field.num_bits = tap->ir_length;
45 field.out_value = t;
46 buf_set_u32(t, 0, field.num_bits, new_instr);
47 field.in_value = NULL;
48
49 jtag_add_ir_scan(tap, &field, TAP_IDLE);
50 }
51
52 return ERROR_OK;
53 }
54
55 int mips_ejtag_get_idcode(struct mips_ejtag *ejtag_info, uint32_t *idcode)
56 {
57 struct scan_field field;
58
59 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_IDCODE);
60
61 field.num_bits = 32;
62 field.out_value = NULL;
63 field.in_value = (void*)idcode;
64
65 jtag_add_dr_scan(ejtag_info->tap, 1, &field, TAP_IDLE);
66
67 int retval;
68 if ((retval = jtag_execute_queue()) != ERROR_OK)
69 {
70 LOG_ERROR("register read failed");
71 return retval;
72 }
73 return ERROR_OK;
74 }
75
76 static int mips_ejtag_get_impcode(struct mips_ejtag *ejtag_info, uint32_t *impcode)
77 {
78 struct scan_field field;
79
80 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_IMPCODE);
81
82 field.num_bits = 32;
83 field.out_value = NULL;
84 field.in_value = (void*)impcode;
85
86 jtag_add_dr_scan(ejtag_info->tap, 1, &field, TAP_IDLE);
87
88 int retval;
89 if ((retval = jtag_execute_queue()) != ERROR_OK)
90 {
91 LOG_ERROR("register read failed");
92 return retval;
93 }
94 return ERROR_OK;
95 }
96
97 int mips_ejtag_drscan_32(struct mips_ejtag *ejtag_info, uint32_t *data)
98 {
99 struct jtag_tap *tap;
100 tap = ejtag_info->tap;
101
102 if (tap == NULL)
103 return ERROR_FAIL;
104 struct scan_field field;
105 uint8_t t[4], r[4];
106 int retval;
107
108 field.num_bits = 32;
109 field.out_value = t;
110 buf_set_u32(t, 0, field.num_bits, *data);
111 field.in_value = r;
112
113 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
114
115 if ((retval = jtag_execute_queue()) != ERROR_OK)
116 {
117 LOG_ERROR("register read failed");
118 return retval;
119 }
120
121 *data = buf_get_u32(field.in_value, 0, 32);
122
123 keep_alive();
124
125 return ERROR_OK;
126 }
127
128 int mips_ejtag_drscan_8(struct mips_ejtag *ejtag_info, uint32_t *data)
129 {
130 struct jtag_tap *tap;
131 tap = ejtag_info->tap;
132
133 if (tap == NULL)
134 return ERROR_FAIL;
135 struct scan_field field;
136 uint8_t t[4] = {0, 0, 0, 0}, r[4];
137 int retval;
138
139 field.num_bits = 8;
140 field.out_value = t;
141 buf_set_u32(t, 0, field.num_bits, *data);
142 field.in_value = r;
143
144 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
145
146 if ((retval = jtag_execute_queue()) != ERROR_OK)
147 {
148 LOG_ERROR("register read failed");
149 return retval;
150 }
151
152 *data = buf_get_u32(field.in_value, 0, 32);
153
154 keep_alive();
155
156 return ERROR_OK;
157 }
158
159 static int mips_ejtag_step_enable(struct mips_ejtag *ejtag_info)
160 {
161 static const uint32_t code[] = {
162 MIPS32_MTC0(1,31,0), /* move $1 to COP0 DeSave */
163 MIPS32_MFC0(1,23,0), /* move COP0 Debug to $1 */
164 MIPS32_ORI(1,1,0x0100), /* set SSt bit in debug reg */
165 MIPS32_MTC0(1,23,0), /* move $1 to COP0 Debug */
166 MIPS32_B(NEG16(5)),
167 MIPS32_MFC0(1,31,0), /* move COP0 DeSave to $1 */
168 };
169
170 mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
171 0, NULL, 0, NULL, 1);
172
173 return ERROR_OK;
174 }
175
176 static int mips_ejtag_step_disable(struct mips_ejtag *ejtag_info)
177 {
178 static const uint32_t code[] = {
179 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
180 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
181 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
182 MIPS32_SW(1,0,15), /* sw $1,($15) */
183 MIPS32_SW(2,0,15), /* sw $2,($15) */
184 MIPS32_MFC0(1,23,0), /* move COP0 Debug to $1 */
185 MIPS32_LUI(2,0xFFFF), /* $2 = 0xfffffeff */
186 MIPS32_ORI(2,2,0xFEFF),
187 MIPS32_AND(1,1,2),
188 MIPS32_MTC0(1,23,0), /* move $1 to COP0 Debug */
189 MIPS32_LW(2,0,15),
190 MIPS32_LW(1,0,15),
191 MIPS32_B(NEG16(13)),
192 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
193 };
194
195 mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
196 0, NULL, 0, NULL, 1);
197
198 return ERROR_OK;
199 }
200
201 int mips_ejtag_config_step(struct mips_ejtag *ejtag_info, int enable_step)
202 {
203 if (enable_step)
204 return mips_ejtag_step_enable(ejtag_info);
205 return mips_ejtag_step_disable(ejtag_info);
206 }
207
208 int mips_ejtag_enter_debug(struct mips_ejtag *ejtag_info)
209 {
210 uint32_t ejtag_ctrl;
211 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
212
213 /* set debug break bit */
214 ejtag_ctrl = ejtag_info->ejtag_ctrl | EJTAG_CTRL_JTAGBRK;
215 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
216
217 /* break bit will be cleared by hardware */
218 ejtag_ctrl = ejtag_info->ejtag_ctrl;
219 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
220 LOG_DEBUG("ejtag_ctrl: 0x%8.8" PRIx32 "", ejtag_ctrl);
221 if ((ejtag_ctrl & EJTAG_CTRL_BRKST) == 0)
222 LOG_DEBUG("Failed to enter Debug Mode!");
223
224 return ERROR_OK;
225 }
226
227 int mips_ejtag_exit_debug(struct mips_ejtag *ejtag_info)
228 {
229 uint32_t inst;
230 inst = MIPS32_DRET;
231
232 /* execute our dret instruction */
233 mips32_pracc_exec(ejtag_info, 1, &inst, 0, NULL, 0, NULL, 0);
234
235 return ERROR_OK;
236 }
237
238 int mips_ejtag_read_debug(struct mips_ejtag *ejtag_info, uint32_t* debug_reg)
239 {
240 /* read ejtag ECR */
241 static const uint32_t code[] = {
242 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
243 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
244 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
245 MIPS32_SW(1,0,15), /* sw $1,($15) */
246 MIPS32_SW(2,0,15), /* sw $2,($15) */
247 MIPS32_LUI(1,UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $1 = MIPS32_PRACC_PARAM_OUT */
248 MIPS32_ORI(1,1,LOWER16(MIPS32_PRACC_PARAM_OUT)),
249 MIPS32_MFC0(2,23,0), /* move COP0 Debug to $2 */
250 MIPS32_SW(2,0,1),
251 MIPS32_LW(2,0,15),
252 MIPS32_LW(1,0,15),
253 MIPS32_B(NEG16(12)),
254 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
255 };
256
257 mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
258 0, NULL, 1, debug_reg, 1);
259
260 return ERROR_OK;
261 }
262
263 int mips_ejtag_init(struct mips_ejtag *ejtag_info)
264 {
265 uint32_t ejtag_version;
266
267 mips_ejtag_get_impcode(ejtag_info, &ejtag_info->impcode);
268 LOG_DEBUG("impcode: 0x%8.8" PRIx32 "", ejtag_info->impcode);
269
270 /* get ejtag version */
271 ejtag_version = ((ejtag_info->impcode >> 29) & 0x07);
272
273 switch (ejtag_version)
274 {
275 case 0:
276 LOG_DEBUG("EJTAG: Version 1 or 2.0 Detected");
277 break;
278 case 1:
279 LOG_DEBUG("EJTAG: Version 2.5 Detected");
280 break;
281 case 2:
282 LOG_DEBUG("EJTAG: Version 2.6 Detected");
283 break;
284 case 3:
285 LOG_DEBUG("EJTAG: Version 3.1 Detected");
286 break;
287 default:
288 LOG_DEBUG("EJTAG: Unknown Version Detected");
289 break;
290 }
291 LOG_DEBUG("EJTAG: features:%s%s%s%s%s%s%s",
292 ejtag_info->impcode & EJTAG_IMP_R3K ? " R3k" : " R4k",
293 ejtag_info->impcode & EJTAG_IMP_DINT ? " DINT" : "",
294 ejtag_info->impcode & (1 << 22) ? " ASID_8" : "",
295 ejtag_info->impcode & (1 << 21) ? " ASID_6" : "",
296 ejtag_info->impcode & EJTAG_IMP_MIPS16 ? " MIPS16" : "",
297 ejtag_info->impcode & EJTAG_IMP_NODMA ? " noDMA" : " DMA",
298 ejtag_info->impcode & EJTAG_DCR_MIPS64 ? " MIPS64" : " MIPS32");
299
300 if ((ejtag_info->impcode & EJTAG_IMP_NODMA) == 0)
301 LOG_DEBUG("EJTAG: DMA Access Mode Support Enabled");
302
303 /* set initial state for ejtag control reg */
304 ejtag_info->ejtag_ctrl = EJTAG_CTRL_ROCC | EJTAG_CTRL_PRACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_SETDEV;
305 ejtag_info->fast_access_save = -1;
306
307 return ERROR_OK;
308 }
309
310 int mips_ejtag_fastdata_scan(struct mips_ejtag *ejtag_info, int write_t, uint32_t *data)
311 {
312 struct jtag_tap *tap;
313 tap = ejtag_info->tap;
314
315 if (tap == NULL)
316 return ERROR_FAIL;
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 {
333 fields[1].in_value = NULL;
334 buf_set_u32(t, 0, 32, *data);
335 }
336 else
337 {
338 fields[1].in_value = (uint8_t *) data;
339 }
340
341 jtag_add_dr_scan(tap, 2, fields, TAP_IDLE);
342 keep_alive();
343
344 return ERROR_OK;
345 }

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)