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

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)