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

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)