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  *   Copyright (C) 2009 by David N. Claffey <dnclaffey@gmail.com>          *
8  *                                                                         *
9  *   This program is free software; you can redistribute it and/or modify  *
10  *   it under the terms of the GNU General Public License as published by  *
11  *   the Free Software Foundation; either version 2 of the License, or     *
12  *   (at your option) any later version.                                   *
13  *                                                                         *
14  *   This program is distributed in the hope that it will be useful,       *
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
17  *   GNU General Public License for more details.                          *
18  *                                                                         *
19  *   You should have received a copy of the GNU General Public License     *
20  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
21  ***************************************************************************/
22 
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 
27 #include "mips32.h"
28 #include "mips_ejtag.h"
29 #include "mips32_dmaacc.h"
30 #include "mips64.h"
31 #include "mips64_pracc.h"
32 
mips_ejtag_set_instr(struct mips_ejtag * ejtag_info,uint32_t new_instr)33 void mips_ejtag_set_instr(struct mips_ejtag *ejtag_info, uint32_t new_instr)
34 {
35 	assert(ejtag_info->tap != NULL);
36 	struct jtag_tap *tap = ejtag_info->tap;
37 
38 	if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) {
39 
40 		struct scan_field field;
41 		field.num_bits = tap->ir_length;
42 
43 		uint8_t t[4] = { 0 };
44 		field.out_value = t;
45 		buf_set_u32(t, 0, field.num_bits, new_instr);
46 
47 		field.in_value = NULL;
48 
49 		jtag_add_ir_scan(tap, &field, TAP_IDLE);
50 	}
51 }
52 
mips_ejtag_get_idcode(struct mips_ejtag * ejtag_info)53 int mips_ejtag_get_idcode(struct mips_ejtag *ejtag_info)
54 {
55 	mips_ejtag_set_instr(ejtag_info, EJTAG_INST_IDCODE);
56 
57 	ejtag_info->idcode = 0;
58 	return mips_ejtag_drscan_32(ejtag_info, &ejtag_info->idcode);
59 }
60 
mips_ejtag_get_impcode(struct mips_ejtag * ejtag_info)61 static int mips_ejtag_get_impcode(struct mips_ejtag *ejtag_info)
62 {
63 	mips_ejtag_set_instr(ejtag_info, EJTAG_INST_IMPCODE);
64 
65 	ejtag_info->impcode = 0;
66 	return mips_ejtag_drscan_32(ejtag_info, &ejtag_info->impcode);
67 }
68 
mips_ejtag_add_scan_96(struct mips_ejtag * ejtag_info,uint32_t ctrl,uint32_t data,uint8_t * in_scan_buf)69 void mips_ejtag_add_scan_96(struct mips_ejtag *ejtag_info, uint32_t ctrl, uint32_t data, uint8_t *in_scan_buf)
70 {
71 	assert(ejtag_info->tap != NULL);
72 	struct jtag_tap *tap = ejtag_info->tap;
73 
74 	struct scan_field field;
75 	uint8_t out_scan[12];
76 
77 	/* processor access "all" register 96 bit */
78 	field.num_bits = 96;
79 
80 	field.out_value = out_scan;
81 	buf_set_u32(out_scan, 0, 32, ctrl);
82 	buf_set_u32(out_scan + 4, 0, 32, data);
83 	buf_set_u32(out_scan + 8, 0, 32, 0);
84 
85 	field.in_value = in_scan_buf;
86 
87 	jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
88 
89 	keep_alive();
90 }
91 
mips_ejtag_drscan_64(struct mips_ejtag * ejtag_info,uint64_t * data)92 int mips_ejtag_drscan_64(struct mips_ejtag *ejtag_info, uint64_t *data)
93 {
94 	struct jtag_tap *tap;
95 	tap  = ejtag_info->tap;
96 
97 	if (tap == NULL)
98 		return ERROR_FAIL;
99 	struct scan_field field;
100 	uint8_t t[8] = { 0 }, r[8];
101 	int retval;
102 
103 	field.num_bits = 64;
104 	field.out_value = t;
105 	buf_set_u64(t, 0, field.num_bits, *data);
106 	field.in_value = r;
107 
108 	jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
109 	retval = jtag_execute_queue();
110 	if (retval != ERROR_OK) {
111 		LOG_ERROR("register read failed");
112 		return retval;
113 	}
114 
115 	*data = buf_get_u64(field.in_value, 0, 64);
116 
117 	keep_alive();
118 
119 	return ERROR_OK;
120 }
121 
mips_ejtag_drscan_32_queued(struct mips_ejtag * ejtag_info,uint32_t data_out,uint8_t * data_in)122 static void mips_ejtag_drscan_32_queued(struct mips_ejtag *ejtag_info,
123 		uint32_t data_out, uint8_t *data_in)
124 {
125 	assert(ejtag_info->tap != NULL);
126 	struct jtag_tap *tap = ejtag_info->tap;
127 
128 	struct scan_field field;
129 	field.num_bits = 32;
130 
131 	uint8_t scan_out[4] = { 0 };
132 	field.out_value = scan_out;
133 	buf_set_u32(scan_out, 0, field.num_bits, data_out);
134 
135 	field.in_value = data_in;
136 	jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
137 
138 	keep_alive();
139 }
140 
mips_ejtag_drscan_32(struct mips_ejtag * ejtag_info,uint32_t * data)141 int mips_ejtag_drscan_32(struct mips_ejtag *ejtag_info, uint32_t *data)
142 {
143 	uint8_t scan_in[4];
144 	mips_ejtag_drscan_32_queued(ejtag_info, *data, scan_in);
145 
146 	int retval = jtag_execute_queue();
147 	if (retval != ERROR_OK) {
148 		LOG_ERROR("register read failed");
149 		return retval;
150 	}
151 
152 	*data = buf_get_u32(scan_in, 0, 32);
153 	return ERROR_OK;
154 }
155 
mips_ejtag_drscan_32_out(struct mips_ejtag * ejtag_info,uint32_t data)156 void mips_ejtag_drscan_32_out(struct mips_ejtag *ejtag_info, uint32_t data)
157 {
158 	mips_ejtag_drscan_32_queued(ejtag_info, data, NULL);
159 }
160 
mips_ejtag_drscan_8(struct mips_ejtag * ejtag_info,uint8_t * data)161 int mips_ejtag_drscan_8(struct mips_ejtag *ejtag_info, uint8_t *data)
162 {
163 	assert(ejtag_info->tap != NULL);
164 	struct jtag_tap *tap = ejtag_info->tap;
165 
166 	struct scan_field field;
167 	field.num_bits = 8;
168 
169 	field.out_value = data;
170 	field.in_value = data;
171 
172 	jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
173 
174 	int retval = jtag_execute_queue();
175 	if (retval != ERROR_OK) {
176 		LOG_ERROR("register read failed");
177 		return retval;
178 	}
179 	return ERROR_OK;
180 }
181 
mips_ejtag_drscan_8_out(struct mips_ejtag * ejtag_info,uint8_t data)182 void mips_ejtag_drscan_8_out(struct mips_ejtag *ejtag_info, uint8_t data)
183 {
184 	assert(ejtag_info->tap != NULL);
185 	struct jtag_tap *tap = ejtag_info->tap;
186 
187 	struct scan_field field;
188 	field.num_bits = 8;
189 
190 	field.out_value = &data;
191 	field.in_value = NULL;
192 
193 	jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
194 }
195 
196 /* Set (to enable) or clear (to disable stepping) the SSt bit (bit 8) in Cp0 Debug reg (reg 23, sel 0) */
mips_ejtag_config_step(struct mips_ejtag * ejtag_info,int enable_step)197 int mips_ejtag_config_step(struct mips_ejtag *ejtag_info, int enable_step)
198 {
199 	struct pracc_queue_info ctx = {.ejtag_info = ejtag_info};
200 	pracc_queue_init(&ctx);
201 
202 	pracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 8, 23, 0));			/* move COP0 Debug to $8 */
203 	pracc_add(&ctx, 0, MIPS32_ORI(ctx.isa, 8, 8, 0x0100));			/* set SSt bit in debug reg */
204 	if (!enable_step)
205 		pracc_add(&ctx, 0, MIPS32_XORI(ctx.isa, 8, 8, 0x0100));		/* clear SSt bit in debug reg */
206 
207 	pracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 8, 23, 0));			/* move $8 to COP0 Debug */
208 	pracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 8, UPPER16(ejtag_info->reg8)));	/* restore upper 16 bits  of $8 */
209 	pracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa)));		/* jump to start */
210 	pracc_add(&ctx, 0, MIPS32_ORI(ctx.isa, 8, 8, LOWER16(ejtag_info->reg8))); /* restore lower 16 bits of $8 */
211 
212 	ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);
213 	pracc_queue_free(&ctx);
214 	return ctx.retval;
215 }
216 
217 /*
218  * Disable memory protection for 0xFF20.0000–0xFF3F.FFFF
219  * It is needed by EJTAG 1.5-2.0, especially for BMIPS CPUs
220  * For example bcm7401 and others. At leas on some
221  * CPUs, DebugMode wont start if this bit is not removed.
222  */
disable_dcr_mp(struct mips_ejtag * ejtag_info)223 static int disable_dcr_mp(struct mips_ejtag *ejtag_info)
224 {
225 	uint32_t dcr;
226 	int retval;
227 
228 	retval = mips32_dmaacc_read_mem(ejtag_info, EJTAG_DCR, 4, 1, &dcr);
229 	if (retval != ERROR_OK)
230 		goto error;
231 
232 	dcr &= ~EJTAG_DCR_MP;
233 	retval = mips32_dmaacc_write_mem(ejtag_info, EJTAG_DCR, 4, 1, &dcr);
234 	if (retval != ERROR_OK)
235 		goto error;
236 	return ERROR_OK;
237 error:
238 	LOG_ERROR("Failed to remove DCR MPbit!");
239 	return retval;
240 }
241 
mips_ejtag_enter_debug(struct mips_ejtag * ejtag_info)242 int mips_ejtag_enter_debug(struct mips_ejtag *ejtag_info)
243 {
244 	uint32_t ejtag_ctrl;
245 	mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
246 
247 	if (ejtag_info->ejtag_version == EJTAG_VERSION_20) {
248 		if (disable_dcr_mp(ejtag_info) != ERROR_OK)
249 			goto error;
250 	}
251 
252 	/* set debug break bit */
253 	ejtag_ctrl = ejtag_info->ejtag_ctrl | EJTAG_CTRL_JTAGBRK;
254 	mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
255 
256 	/* break bit will be cleared by hardware */
257 	ejtag_ctrl = ejtag_info->ejtag_ctrl;
258 	mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
259 	LOG_DEBUG("ejtag_ctrl: 0x%8.8" PRIx32 "", ejtag_ctrl);
260 	if ((ejtag_ctrl & EJTAG_CTRL_BRKST) == 0)
261 		goto error;
262 
263 	return ERROR_OK;
264 error:
265 	LOG_ERROR("Failed to enter Debug Mode!");
266 	return ERROR_FAIL;
267 }
268 
mips_ejtag_exit_debug(struct mips_ejtag * ejtag_info)269 int mips_ejtag_exit_debug(struct mips_ejtag *ejtag_info)
270 {
271 	pa_list pracc_list = {.instr = MIPS32_DRET(ejtag_info->isa), .addr = 0};
272 	struct pracc_queue_info ctx = {.max_code = 1, .pracc_list = &pracc_list, .code_count = 1, .store_count = 0};
273 
274 	/* execute our dret instruction */
275 	ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 0); /* shift out instr, omit last check */
276 
277 	/* pic32mx workaround, false pending at low core clock */
278 	jtag_add_sleep(1000);
279 	return ctx.retval;
280 }
281 
282 /* mips_ejtag_init_mmr - assign Memory-Mapped Registers depending
283  *			on EJTAG version.
284  */
mips_ejtag_init_mmr(struct mips_ejtag * ejtag_info)285 static void mips_ejtag_init_mmr(struct mips_ejtag *ejtag_info)
286 {
287 	if (ejtag_info->ejtag_version == EJTAG_VERSION_20) {
288 		ejtag_info->ejtag_ibs_addr	= EJTAG_V20_IBS;
289 		ejtag_info->ejtag_iba0_addr	= EJTAG_V20_IBA0;
290 		ejtag_info->ejtag_ibc_offs	= EJTAG_V20_IBC_OFFS;
291 		ejtag_info->ejtag_ibm_offs	= EJTAG_V20_IBM_OFFS;
292 
293 		ejtag_info->ejtag_dbs_addr	= EJTAG_V20_DBS;
294 		ejtag_info->ejtag_dba0_addr	= EJTAG_V20_DBA0;
295 		ejtag_info->ejtag_dbc_offs	= EJTAG_V20_DBC_OFFS;
296 		ejtag_info->ejtag_dbm_offs	= EJTAG_V20_DBM_OFFS;
297 		ejtag_info->ejtag_dbv_offs	= EJTAG_V20_DBV_OFFS;
298 
299 		ejtag_info->ejtag_iba_step_size	= EJTAG_V20_IBAn_STEP;
300 		ejtag_info->ejtag_dba_step_size	= EJTAG_V20_DBAn_STEP;
301 	} else {
302 		ejtag_info->ejtag_ibs_addr	= EJTAG_V25_IBS;
303 		ejtag_info->ejtag_iba0_addr	= EJTAG_V25_IBA0;
304 		ejtag_info->ejtag_ibm_offs	= EJTAG_V25_IBM_OFFS;
305 		ejtag_info->ejtag_ibasid_offs	= EJTAG_V25_IBASID_OFFS;
306 		ejtag_info->ejtag_ibc_offs	= EJTAG_V25_IBC_OFFS;
307 
308 		ejtag_info->ejtag_dbs_addr	= EJTAG_V25_DBS;
309 		ejtag_info->ejtag_dba0_addr	= EJTAG_V25_DBA0;
310 		ejtag_info->ejtag_dbm_offs	= EJTAG_V25_DBM_OFFS;
311 		ejtag_info->ejtag_dbasid_offs	= EJTAG_V25_DBASID_OFFS;
312 		ejtag_info->ejtag_dbc_offs	= EJTAG_V25_DBC_OFFS;
313 		ejtag_info->ejtag_dbv_offs	= EJTAG_V25_DBV_OFFS;
314 
315 		ejtag_info->ejtag_iba_step_size	= EJTAG_V25_IBAn_STEP;
316 		ejtag_info->ejtag_dba_step_size	= EJTAG_V25_DBAn_STEP;
317 	}
318 }
319 
ejtag_v20_print_imp(struct mips_ejtag * ejtag_info)320 static void ejtag_v20_print_imp(struct mips_ejtag *ejtag_info)
321 {
322 	LOG_DEBUG("EJTAG v2.0: features:%s%s%s%s%s%s%s%s",
323 		EJTAG_IMP_HAS(EJTAG_V20_IMP_SDBBP) ? " SDBBP_SPECIAL2" : " SDBBP",
324 		EJTAG_IMP_HAS(EJTAG_V20_IMP_EADDR_NO32BIT) ? " EADDR>32bit" : " EADDR=32bit",
325 		EJTAG_IMP_HAS(EJTAG_V20_IMP_COMPLEX_BREAK) ? " COMPLEX_BREAK" : "",
326 		EJTAG_IMP_HAS(EJTAG_V20_IMP_DCACHE_COH) ? " DCACHE_COH" : " DCACHE_NOT_COH",
327 		EJTAG_IMP_HAS(EJTAG_V20_IMP_ICACHE_COH) ? " ICACHE_COH" : " ICACHE_NOT_COH",
328 		EJTAG_IMP_HAS(EJTAG_V20_IMP_NOPB) ? " noPB" : " PB",
329 		EJTAG_IMP_HAS(EJTAG_V20_IMP_NODB) ? " noDB" : " DB",
330 		EJTAG_IMP_HAS(EJTAG_V20_IMP_NOIB) ? " noIB" : " IB");
331 	LOG_DEBUG("EJTAG v2.0: Break Channels: %" PRIu8,
332 		(uint8_t)((ejtag_info->impcode >> EJTAG_V20_IMP_BCHANNELS_SHIFT) &
333 		EJTAG_V20_IMP_BCHANNELS_MASK));
334 }
335 
ejtag_v26_print_imp(struct mips_ejtag * ejtag_info)336 static void ejtag_v26_print_imp(struct mips_ejtag *ejtag_info)
337 {
338 	LOG_DEBUG("EJTAG v2.6: features:%s%s",
339 		EJTAG_IMP_HAS(EJTAG_V26_IMP_R3K) ? " R3k" : " R4k",
340 		EJTAG_IMP_HAS(EJTAG_V26_IMP_DINT) ? " DINT" : "");
341 }
342 
ejtag_main_print_imp(struct mips_ejtag * ejtag_info)343 static void ejtag_main_print_imp(struct mips_ejtag *ejtag_info)
344 {
345 	LOG_DEBUG("EJTAG main: features:%s%s%s%s%s",
346 		EJTAG_IMP_HAS(EJTAG_IMP_ASID8) ? " ASID_8" : "",
347 		EJTAG_IMP_HAS(EJTAG_IMP_ASID6) ? " ASID_6" : "",
348 		EJTAG_IMP_HAS(EJTAG_IMP_MIPS16) ? " MIPS16" : "",
349 		EJTAG_IMP_HAS(EJTAG_IMP_NODMA) ? " noDMA" : " DMA",
350 		EJTAG_IMP_HAS(EJTAG_IMP_MIPS64) ? " MIPS64" : " MIPS32");
351 
352 	switch (ejtag_info->ejtag_version) {
353 		case EJTAG_VERSION_20:
354 			ejtag_v20_print_imp(ejtag_info);
355 			break;
356 		case EJTAG_VERSION_25:
357 		case EJTAG_VERSION_26:
358 		case EJTAG_VERSION_31:
359 		case EJTAG_VERSION_41:
360 		case EJTAG_VERSION_51:
361 			ejtag_v26_print_imp(ejtag_info);
362 			break;
363 		default:
364 			break;
365 	}
366 }
367 
mips_ejtag_init(struct mips_ejtag * ejtag_info)368 int mips_ejtag_init(struct mips_ejtag *ejtag_info)
369 {
370 	int retval = mips_ejtag_get_impcode(ejtag_info);
371 	if (retval != ERROR_OK) {
372 		LOG_ERROR("impcode read failed");
373 		return retval;
374 	}
375 
376 	/* get ejtag version */
377 	ejtag_info->ejtag_version = ((ejtag_info->impcode >> 29) & 0x07);
378 
379 	switch (ejtag_info->ejtag_version) {
380 		case EJTAG_VERSION_20:
381 			LOG_DEBUG("EJTAG: Version 1 or 2.0 Detected");
382 			break;
383 		case EJTAG_VERSION_25:
384 			LOG_DEBUG("EJTAG: Version 2.5 Detected");
385 			break;
386 		case EJTAG_VERSION_26:
387 			LOG_DEBUG("EJTAG: Version 2.6 Detected");
388 			break;
389 		case EJTAG_VERSION_31:
390 			LOG_DEBUG("EJTAG: Version 3.1 Detected");
391 			break;
392 		case EJTAG_VERSION_41:
393 			LOG_DEBUG("EJTAG: Version 4.1 Detected");
394 			break;
395 		case EJTAG_VERSION_51:
396 			LOG_DEBUG("EJTAG: Version 5.1 Detected");
397 			break;
398 		default:
399 			LOG_DEBUG("EJTAG: Unknown Version Detected");
400 			break;
401 	}
402 	ejtag_main_print_imp(ejtag_info);
403 
404 	if ((ejtag_info->impcode & EJTAG_IMP_NODMA) == 0) {
405 		LOG_DEBUG("EJTAG: DMA Access Mode detected. Disabling to "
406 			  "workaround current broken code.");
407 		ejtag_info->impcode |= EJTAG_IMP_NODMA;
408 	}
409 
410 	ejtag_info->ejtag_ctrl = EJTAG_CTRL_PRACC | EJTAG_CTRL_PROBEN;
411 
412 	if (ejtag_info->ejtag_version != EJTAG_VERSION_20)
413 		ejtag_info->ejtag_ctrl |= EJTAG_CTRL_ROCC | EJTAG_CTRL_SETDEV;
414 
415 	ejtag_info->fast_access_save = -1;
416 
417 	mips_ejtag_init_mmr(ejtag_info);
418 
419 	return ERROR_OK;
420 }
421 
mips_ejtag_fastdata_scan(struct mips_ejtag * ejtag_info,int write_t,uint32_t * data)422 int mips_ejtag_fastdata_scan(struct mips_ejtag *ejtag_info, int write_t, uint32_t *data)
423 {
424 	assert(ejtag_info->tap != NULL);
425 	struct jtag_tap *tap = ejtag_info->tap;
426 
427 	struct scan_field fields[2];
428 
429 	/* fastdata 1-bit register */
430 	fields[0].num_bits = 1;
431 
432 	uint8_t spracc = 0;
433 	fields[0].out_value = &spracc;
434 	fields[0].in_value = NULL;
435 
436 	/* processor access data register 32 bit */
437 	fields[1].num_bits = 32;
438 
439 	uint8_t t[4] = {0, 0, 0, 0};
440 	fields[1].out_value = t;
441 
442 	if (write_t) {
443 		fields[1].in_value = NULL;
444 		buf_set_u32(t, 0, 32, *data);
445 	} else
446 		fields[1].in_value = (uint8_t *) data;
447 
448 	jtag_add_dr_scan(tap, 2, fields, TAP_IDLE);
449 
450 	if (!write_t && data)
451 		jtag_add_callback(mips_le_to_h_u32,
452 			(jtag_callback_data_t) data);
453 
454 	keep_alive();
455 
456 	return ERROR_OK;
457 }
458 
mips64_ejtag_config_step(struct mips_ejtag * ejtag_info,bool enable_step)459 int mips64_ejtag_config_step(struct mips_ejtag *ejtag_info, bool enable_step)
460 {
461 	const uint32_t code_enable[] = {
462 		MIPS64_MTC0(1, 31, 0),		    /* move $1 to COP0 DeSave */
463 		MIPS64_MFC0(1, 23, 0),		    /* move COP0 Debug to $1 */
464 		MIPS64_ORI(1, 1, 0x0100),		 /* set SSt bit in debug reg */
465 		MIPS64_MTC0(1, 23, 0),		    /* move $1 to COP0 Debug */
466 		MIPS64_B(NEG16(5)),
467 		MIPS64_MFC0(1, 31, 0),		    /* move COP0 DeSave to $1 */
468 		MIPS64_NOP,
469 		MIPS64_NOP,
470 		MIPS64_NOP,
471 		MIPS64_NOP,
472 		MIPS64_NOP,
473 		MIPS64_NOP,
474 		MIPS64_NOP,
475 		MIPS64_NOP,
476 	};
477 
478 	const uint32_t code_disable[] = {
479 		MIPS64_MTC0(15, 31, 0),                           /* move $15 to COP0 DeSave */
480 		MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)),     /* $15 = MIPS64_PRACC_STACK */
481 		MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)),
482 		MIPS64_SD(1, 0, 15),                              /* sw $1,($15) */
483 		MIPS64_SD(2, 0, 15),                              /* sw $2,($15) */
484 		MIPS64_MFC0(1, 23, 0),                            /* move COP0 Debug to $1 */
485 		MIPS64_LUI(2, 0xFFFF),                           /* $2 = 0xfffffeff */
486 		MIPS64_ORI(2, 2, 0xFEFF),
487 		MIPS64_AND(1, 1, 2),
488 		MIPS64_MTC0(1, 23, 0),                            /* move $1 to COP0 Debug */
489 		MIPS64_LD(2, 0, 15),
490 		MIPS64_LD(1, 0, 15),
491 		MIPS64_SYNC,
492 		MIPS64_B(NEG16(14)),
493 		MIPS64_MFC0(15, 31, 0),                           /* move COP0 DeSave to $15 */
494 		MIPS64_NOP,
495 		MIPS64_NOP,
496 		MIPS64_NOP,
497 		MIPS64_NOP,
498 		MIPS64_NOP,
499 		MIPS64_NOP,
500 		MIPS64_NOP,
501 		MIPS64_NOP,
502 	};
503 	const uint32_t *code = enable_step ? code_enable : code_disable;
504 	unsigned code_len = enable_step ? ARRAY_SIZE(code_enable) :
505 					  ARRAY_SIZE(code_disable);
506 
507 	return mips64_pracc_exec(ejtag_info,
508 				 code_len, code, 0, NULL, 0, NULL);
509 }
510 
mips64_ejtag_exit_debug(struct mips_ejtag * ejtag_info)511 int mips64_ejtag_exit_debug(struct mips_ejtag *ejtag_info)
512 {
513 	const uint32_t code[] = {
514 		MIPS64_DRET,
515 		MIPS64_NOP,
516 		MIPS64_NOP,
517 		MIPS64_NOP,
518 		MIPS64_NOP,
519 		MIPS64_NOP,
520 		MIPS64_NOP,
521 		MIPS64_NOP,
522 	};
523 	LOG_DEBUG("enter mips64_pracc_exec");
524 	return mips64_pracc_exec(ejtag_info,
525 				 ARRAY_SIZE(code), code, 0, NULL, 0, NULL);
526 }
527 
mips64_ejtag_fastdata_scan(struct mips_ejtag * ejtag_info,bool write_t,uint64_t * data)528 int mips64_ejtag_fastdata_scan(struct mips_ejtag *ejtag_info, bool write_t, uint64_t *data)
529 {
530 	struct jtag_tap *tap;
531 
532 	tap = ejtag_info->tap;
533 	assert(tap != NULL);
534 
535 	struct scan_field fields[2];
536 	uint8_t spracc = 0;
537 	uint8_t t[8] = {0, 0, 0, 0, 0, 0, 0, 0};
538 
539 	/* fastdata 1-bit register */
540 	fields[0].num_bits = 1;
541 	fields[0].out_value = &spracc;
542 	fields[0].in_value = NULL;
543 
544 	/* processor access data register 64 bit */
545 	fields[1].num_bits = 64;
546 	fields[1].out_value = t;
547 
548 	if (write_t) {
549 		fields[1].in_value = NULL;
550 		buf_set_u64(t, 0, 64, *data);
551 	} else
552 		fields[1].in_value = (uint8_t *) data;
553 
554 	jtag_add_dr_scan(tap, 2, fields, TAP_IDLE);
555 
556 	if (!write_t && data)
557 		jtag_add_callback(mips_le_to_h_u64,
558 			(jtag_callback_data_t) data);
559 	keep_alive();
560 
561 	return ERROR_OK;
562 }
563