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