add warnings about not using in_handler
[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, void *delete_me_and_submit_patch)
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) != (u32)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
53 field.in_value = NULL;
54 field.in_check_value = NULL;
55 field.in_check_mask = NULL;
56 field.in_handler = NULL;
57 field.in_handler_priv = NULL;
58 jtag_add_ir_scan(1, &field, TAP_INVALID);
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
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, TAP_INVALID);
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
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, TAP_INVALID);
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
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, TAP_INVALID);
140
141 if ((retval = jtag_execute_queue()) != ERROR_OK)
142 {
143 LOG_ERROR("register read failed");
144 return retval;
145 }
146
147 keep_alive();
148
149 return ERROR_OK;
150 }
151
152 int mips_ejtag_step_enable(mips_ejtag_t *ejtag_info)
153 {
154 u32 code[] = {
155 MIPS32_MTC0(1,31,0), /* move $1 to COP0 DeSave */
156 MIPS32_MFC0(1,23,0), /* move COP0 Debug to $1 */
157 MIPS32_ORI(1,1,0x0100), /* set SSt bit in debug reg */
158 MIPS32_MTC0(1,23,0), /* move $1 to COP0 Debug */
159 MIPS32_MFC0(1,31,0), /* move COP0 DeSave to $1 */
160 MIPS32_NOP,
161 MIPS32_B(NEG16(7)),
162 MIPS32_NOP,
163 };
164
165 mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
166 0, NULL, 0, NULL, 1);
167
168 return ERROR_OK;
169 }
170 int mips_ejtag_step_disable(mips_ejtag_t *ejtag_info)
171 {
172 u32 code[] = {
173 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
174 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
175 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
176 MIPS32_SW(1,0,15), /* sw $1,($15) */
177 MIPS32_SW(2,0,15), /* sw $2,($15) */
178 MIPS32_MFC0(1,23,0), /* move COP0 Debug to $1 */
179 MIPS32_LUI(2,0xFFFF), /* $2 = 0xfffffeff */
180 MIPS32_ORI(2,2,0xFEFF),
181 MIPS32_AND(1,1,2),
182 MIPS32_MTC0(1,23,0), /* move $1 to COP0 Debug */
183 MIPS32_LW(2,0,15),
184 MIPS32_LW(1,0,15),
185 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
186 MIPS32_NOP,
187 MIPS32_B(NEG16(15)),
188 MIPS32_NOP,
189 };
190
191 mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
192 0, NULL, 0, NULL, 1);
193
194 return ERROR_OK;
195 }
196
197 int mips_ejtag_config_step(mips_ejtag_t *ejtag_info, int enable_step)
198 {
199 if (enable_step)
200 return mips_ejtag_step_enable(ejtag_info);
201 return mips_ejtag_step_disable(ejtag_info);
202 }
203
204 int mips_ejtag_enter_debug(mips_ejtag_t *ejtag_info)
205 {
206 u32 ejtag_ctrl;
207 jtag_add_end_state(TAP_IDLE);
208 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
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.8x", 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(mips_ejtag_t *ejtag_info, int enable_interrupts)
225 {
226 u32 inst;
227 inst = MIPS32_DRET;
228
229 /* TODO : enable/disable interrrupts */
230
231 /* execute our dret instruction */
232 mips32_pracc_exec(ejtag_info, 1, &inst, 0, NULL, 0, NULL, 0);
233
234 return ERROR_OK;
235 }
236
237 int mips_ejtag_read_debug(mips_ejtag_t *ejtag_info, u32* debug_reg)
238 {
239 /* read ejtag ECR */
240 u32 code[] = {
241 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
242 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
243 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
244 MIPS32_SW(1,0,15), /* sw $1,($15) */
245 MIPS32_SW(2,0,15), /* sw $2,($15) */
246 MIPS32_LUI(1,UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $1 = MIPS32_PRACC_PARAM_OUT */
247 MIPS32_ORI(1,1,LOWER16(MIPS32_PRACC_PARAM_OUT)),
248 MIPS32_MFC0(2,23,0), /* move COP0 Debug to $2 */
249 MIPS32_SW(2,0,1),
250 MIPS32_LW(2,0,15),
251 MIPS32_LW(1,0,15),
252 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
253 MIPS32_NOP,
254 MIPS32_B(NEG16(14)),
255 MIPS32_NOP,
256 };
257
258 mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
259 0, NULL, 1, debug_reg, 1);
260
261 return ERROR_OK;
262 }
263
264 int mips_ejtag_init(mips_ejtag_t *ejtag_info)
265 {
266 u32 ejtag_version;
267
268 mips_ejtag_get_impcode(ejtag_info, &ejtag_info->impcode, NULL);
269 LOG_DEBUG("impcode: 0x%8.8x", ejtag_info->impcode);
270
271 /* get ejtag version */
272 ejtag_version = ((ejtag_info->impcode >> 29) & 0x07);
273
274 switch (ejtag_version)
275 {
276 case 0:
277 LOG_DEBUG("EJTAG: Version 1 or 2.0 Detected");
278 break;
279 case 1:
280 LOG_DEBUG("EJTAG: Version 2.5 Detected");
281 break;
282 case 2:
283 LOG_DEBUG("EJTAG: Version 2.6 Detected");
284 break;
285 case 3:
286 LOG_DEBUG("EJTAG: Version 3.1 Detected");
287 break;
288 default:
289 LOG_DEBUG("EJTAG: Unknown Version Detected");
290 break;
291 }
292 LOG_DEBUG("EJTAG: features:%s%s%s%s%s%s%s",
293 ejtag_info->impcode & (1<<28) ? " R3k": " R4k",
294 ejtag_info->impcode & (1<<24) ? " DINT": "",
295 ejtag_info->impcode & (1<<22) ? " ASID_8": "",
296 ejtag_info->impcode & (1<<21) ? " ASID_6": "",
297 ejtag_info->impcode & (1<<16) ? " MIPS16": "",
298 ejtag_info->impcode & (1<<14) ? " noDMA": " DMA",
299 ejtag_info->impcode & (1<<0) ? " MIPS64": " MIPS32"
300 );
301
302 if((ejtag_info->impcode & (1<<14)) == 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 }

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)