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

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)