79160fc4c2b2b7e92019a592daabf759c38d957a
[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, void *delete_me_and_submit_patch)
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, 1, &field, jtag_get_end_state());
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, NULL);
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, jtag_get_end_state());
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, NULL);
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, jtag_get_end_state());
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, jtag_get_end_state());
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_step_enable(struct mips_ejtag *ejtag_info)
131 {
132 uint32_t code[] = {
133 MIPS32_MTC0(1,31,0), /* move $1 to COP0 DeSave */
134 MIPS32_MFC0(1,23,0), /* move COP0 Debug to $1 */
135 MIPS32_ORI(1,1,0x0100), /* set SSt bit in debug reg */
136 MIPS32_MTC0(1,23,0), /* move $1 to COP0 Debug */
137 MIPS32_B(NEG16(5)),
138 MIPS32_MFC0(1,31,0), /* move COP0 DeSave to $1 */
139 };
140
141 mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
142 0, NULL, 0, NULL, 1);
143
144 return ERROR_OK;
145 }
146 int mips_ejtag_step_disable(struct mips_ejtag *ejtag_info)
147 {
148 uint32_t code[] = {
149 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
150 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
151 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
152 MIPS32_SW(1,0,15), /* sw $1,($15) */
153 MIPS32_SW(2,0,15), /* sw $2,($15) */
154 MIPS32_MFC0(1,23,0), /* move COP0 Debug to $1 */
155 MIPS32_LUI(2,0xFFFF), /* $2 = 0xfffffeff */
156 MIPS32_ORI(2,2,0xFEFF),
157 MIPS32_AND(1,1,2),
158 MIPS32_MTC0(1,23,0), /* move $1 to COP0 Debug */
159 MIPS32_LW(2,0,15),
160 MIPS32_LW(1,0,15),
161 MIPS32_B(NEG16(13)),
162 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
163 };
164
165 mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
166 0, NULL, 0, NULL, 1);
167
168 return ERROR_OK;
169 }
170
171 int mips_ejtag_config_step(struct mips_ejtag *ejtag_info, int enable_step)
172 {
173 if (enable_step)
174 return mips_ejtag_step_enable(ejtag_info);
175 return mips_ejtag_step_disable(ejtag_info);
176 }
177
178 int mips_ejtag_enter_debug(struct mips_ejtag *ejtag_info)
179 {
180 uint32_t ejtag_ctrl;
181 jtag_set_end_state(TAP_IDLE);
182 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
183
184 /* set debug break bit */
185 ejtag_ctrl = ejtag_info->ejtag_ctrl | EJTAG_CTRL_JTAGBRK;
186 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
187
188 /* break bit will be cleared by hardware */
189 ejtag_ctrl = ejtag_info->ejtag_ctrl;
190 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
191 LOG_DEBUG("ejtag_ctrl: 0x%8.8" PRIx32 "", ejtag_ctrl);
192 if ((ejtag_ctrl & EJTAG_CTRL_BRKST) == 0)
193 LOG_DEBUG("Failed to enter Debug Mode!");
194
195 return ERROR_OK;
196 }
197
198 int mips_ejtag_exit_debug(struct mips_ejtag *ejtag_info)
199 {
200 uint32_t inst;
201 inst = MIPS32_DRET;
202
203 /* execute our dret instruction */
204 mips32_pracc_exec(ejtag_info, 1, &inst, 0, NULL, 0, NULL, 0);
205
206 return ERROR_OK;
207 }
208
209 int mips_ejtag_read_debug(struct mips_ejtag *ejtag_info, uint32_t* debug_reg)
210 {
211 /* read ejtag ECR */
212 uint32_t code[] = {
213 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
214 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
215 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
216 MIPS32_SW(1,0,15), /* sw $1,($15) */
217 MIPS32_SW(2,0,15), /* sw $2,($15) */
218 MIPS32_LUI(1,UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $1 = MIPS32_PRACC_PARAM_OUT */
219 MIPS32_ORI(1,1,LOWER16(MIPS32_PRACC_PARAM_OUT)),
220 MIPS32_MFC0(2,23,0), /* move COP0 Debug to $2 */
221 MIPS32_SW(2,0,1),
222 MIPS32_LW(2,0,15),
223 MIPS32_LW(1,0,15),
224 MIPS32_B(NEG16(12)),
225 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
226 };
227
228 mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
229 0, NULL, 1, debug_reg, 1);
230
231 return ERROR_OK;
232 }
233
234 int mips_ejtag_init(struct mips_ejtag *ejtag_info)
235 {
236 uint32_t ejtag_version;
237
238 mips_ejtag_get_impcode(ejtag_info, &ejtag_info->impcode);
239 LOG_DEBUG("impcode: 0x%8.8" PRIx32 "", ejtag_info->impcode);
240
241 /* get ejtag version */
242 ejtag_version = ((ejtag_info->impcode >> 29) & 0x07);
243
244 switch (ejtag_version)
245 {
246 case 0:
247 LOG_DEBUG("EJTAG: Version 1 or 2.0 Detected");
248 break;
249 case 1:
250 LOG_DEBUG("EJTAG: Version 2.5 Detected");
251 break;
252 case 2:
253 LOG_DEBUG("EJTAG: Version 2.6 Detected");
254 break;
255 case 3:
256 LOG_DEBUG("EJTAG: Version 3.1 Detected");
257 break;
258 default:
259 LOG_DEBUG("EJTAG: Unknown Version Detected");
260 break;
261 }
262 LOG_DEBUG("EJTAG: features:%s%s%s%s%s%s%s",
263 ejtag_info->impcode & EJTAG_IMP_R3K ? " R3k" : " R4k",
264 ejtag_info->impcode & EJTAG_IMP_DINT ? " DINT" : "",
265 ejtag_info->impcode & (1 << 22) ? " ASID_8" : "",
266 ejtag_info->impcode & (1 << 21) ? " ASID_6" : "",
267 ejtag_info->impcode & EJTAG_IMP_MIPS16 ? " MIPS16" : "",
268 ejtag_info->impcode & EJTAG_IMP_NODMA ? " noDMA" : " DMA",
269 ejtag_info->impcode & EJTAG_DCR_MIPS64 ? " MIPS64" : " MIPS32");
270
271 if ((ejtag_info->impcode & EJTAG_IMP_NODMA) == 0)
272 LOG_DEBUG("EJTAG: DMA Access Mode Support Enabled");
273
274 /* set initial state for ejtag control reg */
275 ejtag_info->ejtag_ctrl = EJTAG_CTRL_ROCC | EJTAG_CTRL_PRACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_SETDEV;
276
277 return ERROR_OK;
278 }
279
280 int mips_ejtag_fastdata_scan(struct mips_ejtag *ejtag_info, int write, uint32_t *data)
281 {
282 struct jtag_tap *tap;
283 tap = ejtag_info->tap;
284
285 if (tap == NULL)
286 return ERROR_FAIL;
287
288 struct scan_field fields[2];
289 uint8_t spracc = 0;
290 uint8_t t[4] = {0, 0, 0, 0};
291
292 /* fastdata 1-bit register */
293 fields[0].num_bits = 1;
294 fields[0].out_value = &spracc;
295 fields[0].in_value = NULL;
296
297 /* processor access data register 32 bit */
298 fields[1].num_bits = 32;
299 fields[1].out_value = t;
300
301 if (write)
302 {
303 fields[1].in_value = NULL;
304 buf_set_u32(t, 0, 32, *data);
305 }
306 else
307 {
308 fields[1].in_value = (uint8_t *) data;
309 }
310
311 jtag_add_dr_scan(tap, 2, fields, jtag_get_end_state());
312 keep_alive();
313
314 return ERROR_OK;
315 }

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)