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

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)