Change tap_state naming to be consistent with SVF documentation.
[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 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 ***************************************************************************/
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "mips32.h"
27 #include "mips_ejtag.h"
28
29 #include "binarybuffer.h"
30 #include "log.h"
31 #include "jtag.h"
32
33 #include <stdlib.h>
34
35 int mips_ejtag_set_instr(mips_ejtag_t *ejtag_info, int new_instr, in_handler_t handler)
36 {
37 jtag_tap_t *tap;
38
39 tap = ejtag_info->tap;
40 if (tap==NULL)
41 return ERROR_FAIL;
42
43 if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr)
44 {
45 scan_field_t field;
46 u8 t[4];
47
48 field.tap = tap;
49 field.num_bits = tap->ir_length;
50 field.out_value = t;
51 buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
52 field.out_mask = NULL;
53 field.in_value = NULL;
54 field.in_check_value = NULL;
55 field.in_check_mask = NULL;
56 field.in_handler = handler;
57 field.in_handler_priv = NULL;
58 jtag_add_ir_scan(1, &field, -1);
59 }
60
61 return ERROR_OK;
62 }
63
64 int mips_ejtag_get_idcode(mips_ejtag_t *ejtag_info, u32 *idcode, in_handler_t handler)
65 {
66 scan_field_t field;
67
68 jtag_add_end_state(TAP_IDLE);
69
70 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_IDCODE, NULL);
71
72 field.tap = ejtag_info->tap;
73 field.num_bits = 32;
74 field.out_value = NULL;
75 field.out_mask = NULL;
76 field.in_value = (void*)idcode;
77 field.in_check_value = NULL;
78 field.in_check_mask = NULL;
79 field.in_handler = NULL;
80 field.in_handler_priv = NULL;
81 jtag_add_dr_scan(1, &field, -1);
82
83 if (jtag_execute_queue() != ERROR_OK)
84 {
85 LOG_ERROR("register read failed");
86 }
87
88 return ERROR_OK;
89 }
90
91 int mips_ejtag_get_impcode(mips_ejtag_t *ejtag_info, u32 *impcode, in_handler_t handler)
92 {
93 scan_field_t field;
94
95 jtag_add_end_state(TAP_IDLE);
96
97 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_IMPCODE, NULL);
98
99 field.tap = ejtag_info->tap;
100 field.num_bits = 32;
101 field.out_value = NULL;
102 field.out_mask = NULL;
103 field.in_value = (void*)impcode;
104 field.in_check_value = NULL;
105 field.in_check_mask = NULL;
106 field.in_handler = NULL;
107 field.in_handler_priv = NULL;
108 jtag_add_dr_scan(1, &field, -1);
109
110 if (jtag_execute_queue() != ERROR_OK)
111 {
112 LOG_ERROR("register read failed");
113 }
114
115 return ERROR_OK;
116 }
117
118 int mips_ejtag_drscan_32(mips_ejtag_t *ejtag_info, u32 *data)
119 {
120 jtag_tap_t *tap;
121 tap = ejtag_info->tap;
122
123 if (tap==NULL)
124 return ERROR_FAIL;
125 scan_field_t field;
126 u8 t[4];
127 int retval;
128
129 field.tap = tap;
130 field.num_bits = 32;
131 field.out_value = t;
132 buf_set_u32(field.out_value, 0, field.num_bits, *data);
133 field.out_mask = NULL;
134 field.in_value = (u8*)data;
135 field.in_check_value = NULL;
136 field.in_check_mask = NULL;
137 field.in_handler = NULL;
138 field.in_handler_priv = NULL;
139 jtag_add_dr_scan(1, &field, -1);
140
141 if ((retval = jtag_execute_queue()) != ERROR_OK)
142 {
143 LOG_ERROR("register read failed");
144 return retval;
145 }
146
147 return ERROR_OK;
148 }
149
150 int mips_ejtag_step_enable(mips_ejtag_t *ejtag_info)
151 {
152 u32 code[] = {
153 MIPS32_MTC0(1,31,0), /* move $1 to COP0 DeSave */
154 MIPS32_MFC0(1,23,0), /* move COP0 Debug to $1 */
155 MIPS32_ORI(1,1,0x0100), /* set SSt bit in debug reg */
156 MIPS32_MTC0(1,23,0), /* move $1 to COP0 Debug */
157 MIPS32_MFC0(1,31,0), /* move COP0 DeSave to $1 */
158 MIPS32_NOP,
159 MIPS32_B(NEG16(7)),
160 MIPS32_NOP,
161 };
162
163 mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
164 0, NULL, 0, NULL, 1);
165
166 return ERROR_OK;
167 }
168 int mips_ejtag_step_disable(mips_ejtag_t *ejtag_info)
169 {
170 u32 code[] = {
171 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
172 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
173 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
174 MIPS32_SW(1,0,15), /* sw $1,($15) */
175 MIPS32_SW(2,0,15), /* sw $2,($15) */
176 MIPS32_MFC0(1,23,0), /* move COP0 Debug to $1 */
177 MIPS32_LUI(2,0xFFFF), /* $2 = 0xfffffeff */
178 MIPS32_ORI(2,2,0xFEFF),
179 MIPS32_AND(1,1,2),
180 MIPS32_MTC0(1,23,0), /* move $1 to COP0 Debug */
181 MIPS32_LW(2,0,15),
182 MIPS32_LW(1,0,15),
183 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
184 MIPS32_NOP,
185 MIPS32_B(NEG16(15)),
186 MIPS32_NOP,
187 };
188
189 mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
190 0, NULL, 0, NULL, 1);
191
192 return ERROR_OK;
193 }
194
195 int mips_ejtag_config_step(mips_ejtag_t *ejtag_info, int enable_step)
196 {
197 if (enable_step)
198 return mips_ejtag_step_enable(ejtag_info);
199 return mips_ejtag_step_disable(ejtag_info);
200 }
201
202 int mips_ejtag_enter_debug(mips_ejtag_t *ejtag_info)
203 {
204 u32 ejtag_ctrl;
205 jtag_add_end_state(TAP_IDLE);
206 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
207
208 /* set debug break bit */
209 ejtag_ctrl = ejtag_info->ejtag_ctrl | EJTAG_CTRL_JTAGBRK;
210 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
211
212 /* break bit will be cleared by hardware */
213 ejtag_ctrl = ejtag_info->ejtag_ctrl;
214 mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
215 LOG_DEBUG("ejtag_ctrl: 0x%8.8x", ejtag_ctrl);
216 if((ejtag_ctrl & EJTAG_CTRL_BRKST) == 0)
217 LOG_DEBUG("Failed to enter Debug Mode!");
218
219 return ERROR_OK;
220 }
221
222 int mips_ejtag_exit_debug(mips_ejtag_t *ejtag_info, int enable_interrupts)
223 {
224 u32 inst;
225 inst = MIPS32_DRET;
226
227 /* TODO : enable/disable interrrupts */
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(mips_ejtag_t *ejtag_info, u32* debug_reg)
236 {
237 /* read ejtag ECR */
238 u32 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_MFC0(15,31,0), /* move COP0 DeSave to $15 */
251 MIPS32_NOP,
252 MIPS32_B(NEG16(14)),
253 MIPS32_NOP,
254 };
255
256 mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
257 0, NULL, 1, debug_reg, 1);
258
259 return ERROR_OK;
260 }
261
262 int mips_ejtag_init(mips_ejtag_t *ejtag_info)
263 {
264 u32 ejtag_version;
265
266 mips_ejtag_get_impcode(ejtag_info, &ejtag_info->impcode, NULL);
267 LOG_DEBUG("impcode: 0x%8.8x", ejtag_info->impcode);
268
269 /* get ejtag version */
270 ejtag_version = ((ejtag_info->impcode >> 29) & 0x07);
271
272 switch (ejtag_version)
273 {
274 case 0:
275 LOG_DEBUG("EJTAG: Version 1 or 2.0 Detected");
276 break;
277 case 1:
278 LOG_DEBUG("EJTAG: Version 2.5 Detected");
279 break;
280 case 2:
281 LOG_DEBUG("EJTAG: Version 2.6 Detected");
282 break;
283 case 3:
284 LOG_DEBUG("EJTAG: Version 3.1 Detected");
285 break;
286 default:
287 LOG_DEBUG("EJTAG: Unknown Version Detected");
288 break;
289 }
290 LOG_DEBUG("EJTAG: features:%s%s%s%s%s%s%s",
291 ejtag_info->impcode & (1<<28) ? " R3k": " R4k",
292 ejtag_info->impcode & (1<<24) ? " DINT": "",
293 ejtag_info->impcode & (1<<22) ? " ASID_8": "",
294 ejtag_info->impcode & (1<<21) ? " ASID_6": "",
295 ejtag_info->impcode & (1<<16) ? " MIPS16": "",
296 ejtag_info->impcode & (1<<14) ? " noDMA": " DMA",
297 ejtag_info->impcode & (1<<0) ? " MIPS64": " MIPS32"
298 );
299
300 if((ejtag_info->impcode & (1<<14)) == 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
306 return ERROR_OK;
307 }

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)