- merged mips target into svn trunk
[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 jtag_add_end_state(TAP_RTI);
198 mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
199
200 /* set debug break bit */
201 ejtag_info->ejtag_ctrl = EJTAG_CTRL_ROCC | EJTAG_CTRL_PRACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_SETDEV | EJTAG_CTRL_JTAGBRK;
202 mips_ejtag_drscan_32(ejtag_info, &ejtag_info->ejtag_ctrl);
203
204 /* break bit will be cleared by hardware */
205 ejtag_info->ejtag_ctrl = EJTAG_CTRL_ROCC | EJTAG_CTRL_PRACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_SETDEV;
206 mips_ejtag_drscan_32(ejtag_info, &ejtag_info->ejtag_ctrl);
207
208 return ERROR_OK;
209 }
210
211 int mips_ejtag_exit_debug(mips_ejtag_t *ejtag_info, int enable_interrupts)
212 {
213 u32 inst;
214 inst = MIPS32_DRET;
215
216 /* TODO : enable/disable interrrupts */
217
218 /* execute our dret instruction */
219 mips32_pracc_exec(ejtag_info, 1, &inst, 0, NULL, 0, NULL, 0);
220
221 return ERROR_OK;
222 }
223
224 int mips_ejtag_read_debug(mips_ejtag_t *ejtag_info, u32* debug_reg)
225 {
226 u32 code[] = {
227 MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */
228 MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
229 MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
230 MIPS32_SW(1,0,15), /* sw $1,($15) */
231 MIPS32_SW(2,0,15), /* sw $2,($15) */
232 MIPS32_LUI(1,UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $1 = MIPS32_PRACC_PARAM_OUT */
233 MIPS32_ORI(1,1,LOWER16(MIPS32_PRACC_PARAM_OUT)),
234 MIPS32_MFC0(2,23,0), /* move COP0 Debug to $1 */
235 MIPS32_SW(2,0,1),
236 MIPS32_LW(2,0,15),
237 MIPS32_LW(1,0,15),
238 MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */
239 MIPS32_NOP,
240 MIPS32_B(NEG16(14)),
241 MIPS32_NOP,
242 };
243
244 mips32_pracc_exec(ejtag_info, sizeof(code)/sizeof(code[0]), code, \
245 0, NULL, 1, debug_reg, 1);
246
247 return ERROR_OK;
248 }
249
250 int mips_ejtag_init(mips_ejtag_t *ejtag_info)
251 {
252 u32 ejtag_version;
253
254 mips_ejtag_get_impcode(ejtag_info, &ejtag_info->impcode, NULL);
255 LOG_DEBUG("impcode: 0x%8.8x", ejtag_info->impcode);
256
257 /* get ejtag version */
258 ejtag_version = ((ejtag_info->impcode >> 29) & 0x07);
259
260 switch (ejtag_version)
261 {
262 case 0:
263 LOG_DEBUG("EJTAG: Version 1 or 2.0 Detected");
264 break;
265 case 1:
266 LOG_DEBUG("EJTAG: Version 2.5 Detected");
267 break;
268 case 2:
269 LOG_DEBUG("EJTAG: Version 2.6 Detected");
270 break;
271 case 3:
272 LOG_DEBUG("EJTAG: Version 3.1 Detected");
273 break;
274 default:
275 LOG_DEBUG("EJTAG: Unknown Version Detected");
276 break;
277 }
278
279 /* set initial state for ejtag control reg */
280 ejtag_info->ejtag_ctrl = EJTAG_CTRL_ROCC | EJTAG_CTRL_PRACC | EJTAG_CTRL_PROBEN | EJTAG_CTRL_SETDEV;
281
282 return ERROR_OK;
283 }

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)