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

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)