1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2008 by Spencer Oliver *
5 * spen@spen-soft.co.uk *
7 * Copyright (C) 2008 by David T.L. Wong *
9 * Copyright (C) 2009 by David N. Claffey <dnclaffey@gmail.com> *
10 ***************************************************************************/
17 #include "mips_ejtag.h"
18 #include "mips32_dmaacc.h"
20 #include "mips64_pracc.h"
22 void mips_ejtag_set_instr(struct mips_ejtag
*ejtag_info
, uint32_t new_instr
)
24 assert(ejtag_info
->tap
);
25 struct jtag_tap
*tap
= ejtag_info
->tap
;
27 if (buf_get_u32(tap
->cur_instr
, 0, tap
->ir_length
) != new_instr
) {
29 struct scan_field field
;
30 field
.num_bits
= tap
->ir_length
;
34 buf_set_u32(t
, 0, field
.num_bits
, new_instr
);
36 field
.in_value
= NULL
;
38 jtag_add_ir_scan(tap
, &field
, TAP_IDLE
);
42 int mips_ejtag_get_idcode(struct mips_ejtag
*ejtag_info
)
44 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_IDCODE
);
46 ejtag_info
->idcode
= 0;
47 return mips_ejtag_drscan_32(ejtag_info
, &ejtag_info
->idcode
);
50 int mips_ejtag_get_impcode(struct mips_ejtag
*ejtag_info
)
52 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_IMPCODE
);
54 ejtag_info
->impcode
= 0;
55 return mips_ejtag_drscan_32(ejtag_info
, &ejtag_info
->impcode
);
58 void mips_ejtag_add_scan_96(struct mips_ejtag
*ejtag_info
, uint32_t ctrl
, uint32_t data
, uint8_t *in_scan_buf
)
60 assert(ejtag_info
->tap
);
61 struct jtag_tap
*tap
= ejtag_info
->tap
;
63 struct scan_field field
;
66 /* processor access "all" register 96 bit */
69 field
.out_value
= out_scan
;
70 buf_set_u32(out_scan
, 0, 32, ctrl
);
71 buf_set_u32(out_scan
+ 4, 0, 32, data
);
72 buf_set_u32(out_scan
+ 8, 0, 32, 0);
74 field
.in_value
= in_scan_buf
;
76 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
81 int mips_ejtag_drscan_64(struct mips_ejtag
*ejtag_info
, uint64_t *data
)
84 tap
= ejtag_info
->tap
;
88 struct scan_field field
;
89 uint8_t t
[8] = { 0 }, r
[8];
94 buf_set_u64(t
, 0, field
.num_bits
, *data
);
97 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
98 retval
= jtag_execute_queue();
99 if (retval
!= ERROR_OK
) {
100 LOG_ERROR("register read failed");
104 *data
= buf_get_u64(field
.in_value
, 0, 64);
111 static void mips_ejtag_drscan_32_queued(struct mips_ejtag
*ejtag_info
,
112 uint32_t data_out
, uint8_t *data_in
)
114 assert(ejtag_info
->tap
);
115 struct jtag_tap
*tap
= ejtag_info
->tap
;
117 struct scan_field field
;
120 uint8_t scan_out
[4] = { 0 };
121 field
.out_value
= scan_out
;
122 buf_set_u32(scan_out
, 0, field
.num_bits
, data_out
);
124 field
.in_value
= data_in
;
125 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
130 int mips_ejtag_drscan_32(struct mips_ejtag
*ejtag_info
, uint32_t *data
)
133 mips_ejtag_drscan_32_queued(ejtag_info
, *data
, scan_in
);
135 int retval
= jtag_execute_queue();
136 if (retval
!= ERROR_OK
) {
137 LOG_ERROR("register read failed");
141 *data
= buf_get_u32(scan_in
, 0, 32);
145 void mips_ejtag_drscan_32_out(struct mips_ejtag
*ejtag_info
, uint32_t data
)
147 mips_ejtag_drscan_32_queued(ejtag_info
, data
, NULL
);
150 int mips_ejtag_drscan_8(struct mips_ejtag
*ejtag_info
, uint8_t *data
)
152 assert(ejtag_info
->tap
);
153 struct jtag_tap
*tap
= ejtag_info
->tap
;
155 struct scan_field field
;
158 field
.out_value
= data
;
159 field
.in_value
= data
;
161 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
163 int retval
= jtag_execute_queue();
164 if (retval
!= ERROR_OK
) {
165 LOG_ERROR("register read failed");
171 void mips_ejtag_drscan_8_out(struct mips_ejtag
*ejtag_info
, uint8_t data
)
173 assert(ejtag_info
->tap
);
174 struct jtag_tap
*tap
= ejtag_info
->tap
;
176 struct scan_field field
;
179 field
.out_value
= &data
;
180 field
.in_value
= NULL
;
182 jtag_add_dr_scan(tap
, 1, &field
, TAP_IDLE
);
185 /* Set (to enable) or clear (to disable stepping) the SSt bit (bit 8) in Cp0 Debug reg (reg 23, sel 0) */
186 int mips_ejtag_config_step(struct mips_ejtag
*ejtag_info
, int enable_step
)
188 struct pracc_queue_info ctx
= {.ejtag_info
= ejtag_info
};
189 pracc_queue_init(&ctx
);
191 pracc_add(&ctx
, 0, MIPS32_MFC0(ctx
.isa
, 8, 23, 0)); /* move COP0 Debug to $8 */
192 pracc_add(&ctx
, 0, MIPS32_ORI(ctx
.isa
, 8, 8, 0x0100)); /* set SSt bit in debug reg */
194 pracc_add(&ctx
, 0, MIPS32_XORI(ctx
.isa
, 8, 8, 0x0100)); /* clear SSt bit in debug reg */
196 pracc_add(&ctx
, 0, MIPS32_MTC0(ctx
.isa
, 8, 23, 0)); /* move $8 to COP0 Debug */
197 pracc_add(&ctx
, 0, MIPS32_LUI(ctx
.isa
, 8, UPPER16(ejtag_info
->reg8
))); /* restore upper 16 bits of $8 */
198 pracc_add(&ctx
, 0, MIPS32_B(ctx
.isa
, NEG16((ctx
.code_count
+ 1) << ctx
.isa
))); /* jump to start */
199 pracc_add(&ctx
, 0, MIPS32_ORI(ctx
.isa
, 8, 8, LOWER16(ejtag_info
->reg8
))); /* restore lower 16 bits of $8 */
201 ctx
.retval
= mips32_pracc_queue_exec(ejtag_info
, &ctx
, NULL
, 1);
202 pracc_queue_free(&ctx
);
207 * Disable memory protection for 0xFF20.0000–0xFF3F.FFFF
208 * It is needed by EJTAG 1.5-2.0, especially for BMIPS CPUs
209 * For example bcm7401 and others. At leas on some
210 * CPUs, DebugMode wont start if this bit is not removed.
212 static int disable_dcr_mp(struct mips_ejtag
*ejtag_info
)
217 retval
= mips32_dmaacc_read_mem(ejtag_info
, EJTAG_DCR
, 4, 1, &dcr
);
218 if (retval
!= ERROR_OK
)
221 dcr
&= ~EJTAG_DCR_MP
;
222 retval
= mips32_dmaacc_write_mem(ejtag_info
, EJTAG_DCR
, 4, 1, &dcr
);
223 if (retval
!= ERROR_OK
)
227 LOG_ERROR("Failed to remove DCR MPbit!");
231 int mips_ejtag_enter_debug(struct mips_ejtag
*ejtag_info
)
234 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_CONTROL
);
236 if (ejtag_info
->ejtag_version
== EJTAG_VERSION_20
) {
237 if (disable_dcr_mp(ejtag_info
) != ERROR_OK
)
241 /* set debug break bit */
242 ejtag_ctrl
= ejtag_info
->ejtag_ctrl
| EJTAG_CTRL_JTAGBRK
;
243 mips_ejtag_drscan_32(ejtag_info
, &ejtag_ctrl
);
245 /* break bit will be cleared by hardware */
246 ejtag_ctrl
= ejtag_info
->ejtag_ctrl
;
247 mips_ejtag_drscan_32(ejtag_info
, &ejtag_ctrl
);
248 LOG_DEBUG("ejtag_ctrl: 0x%8.8" PRIx32
"", ejtag_ctrl
);
249 if ((ejtag_ctrl
& EJTAG_CTRL_BRKST
) == 0)
254 LOG_ERROR("Failed to enter Debug Mode!");
258 int mips_ejtag_exit_debug(struct mips_ejtag
*ejtag_info
)
260 struct pa_list pracc_list
= {.instr
= MIPS32_DRET(ejtag_info
->isa
), .addr
= 0};
261 struct pracc_queue_info ctx
= {.max_code
= 1, .pracc_list
= &pracc_list
, .code_count
= 1, .store_count
= 0};
262 struct mips32_common
*mips32
= container_of(ejtag_info
,
263 struct mips32_common
, ejtag_info
);
265 /* execute our dret instruction */
266 ctx
.retval
= mips32_pracc_queue_exec(ejtag_info
, &ctx
, NULL
,
267 mips32
->cpu_quirks
& EJTAG_QUIRK_PAD_DRET
);
269 /* pic32mx workaround, false pending at low core clock */
270 jtag_add_sleep(1000);
274 /* mips_ejtag_init_mmr - assign Memory-Mapped Registers depending
277 static void mips_ejtag_init_mmr(struct mips_ejtag
*ejtag_info
)
279 if (ejtag_info
->ejtag_version
== EJTAG_VERSION_20
) {
280 ejtag_info
->ejtag_ibs_addr
= EJTAG_V20_IBS
;
281 ejtag_info
->ejtag_iba0_addr
= EJTAG_V20_IBA0
;
282 ejtag_info
->ejtag_ibc_offs
= EJTAG_V20_IBC_OFFS
;
283 ejtag_info
->ejtag_ibm_offs
= EJTAG_V20_IBM_OFFS
;
285 ejtag_info
->ejtag_dbs_addr
= EJTAG_V20_DBS
;
286 ejtag_info
->ejtag_dba0_addr
= EJTAG_V20_DBA0
;
287 ejtag_info
->ejtag_dbc_offs
= EJTAG_V20_DBC_OFFS
;
288 ejtag_info
->ejtag_dbm_offs
= EJTAG_V20_DBM_OFFS
;
289 ejtag_info
->ejtag_dbv_offs
= EJTAG_V20_DBV_OFFS
;
291 ejtag_info
->ejtag_iba_step_size
= EJTAG_V20_IBAN_STEP
;
292 ejtag_info
->ejtag_dba_step_size
= EJTAG_V20_DBAN_STEP
;
294 ejtag_info
->ejtag_ibs_addr
= EJTAG_V25_IBS
;
295 ejtag_info
->ejtag_iba0_addr
= EJTAG_V25_IBA0
;
296 ejtag_info
->ejtag_ibm_offs
= EJTAG_V25_IBM_OFFS
;
297 ejtag_info
->ejtag_ibasid_offs
= EJTAG_V25_IBASID_OFFS
;
298 ejtag_info
->ejtag_ibc_offs
= EJTAG_V25_IBC_OFFS
;
300 ejtag_info
->ejtag_dbs_addr
= EJTAG_V25_DBS
;
301 ejtag_info
->ejtag_dba0_addr
= EJTAG_V25_DBA0
;
302 ejtag_info
->ejtag_dbm_offs
= EJTAG_V25_DBM_OFFS
;
303 ejtag_info
->ejtag_dbasid_offs
= EJTAG_V25_DBASID_OFFS
;
304 ejtag_info
->ejtag_dbc_offs
= EJTAG_V25_DBC_OFFS
;
305 ejtag_info
->ejtag_dbv_offs
= EJTAG_V25_DBV_OFFS
;
307 ejtag_info
->ejtag_iba_step_size
= EJTAG_V25_IBAN_STEP
;
308 ejtag_info
->ejtag_dba_step_size
= EJTAG_V25_DBAN_STEP
;
312 static void ejtag_v20_print_imp(struct mips_ejtag
*ejtag_info
)
314 LOG_DEBUG("EJTAG v2.0: features:%s%s%s%s%s%s%s%s",
315 EJTAG_IMP_HAS(EJTAG_V20_IMP_SDBBP
) ? " SDBBP_SPECIAL2" : " SDBBP",
316 EJTAG_IMP_HAS(EJTAG_V20_IMP_EADDR_NO32BIT
) ? " EADDR>32bit" : " EADDR=32bit",
317 EJTAG_IMP_HAS(EJTAG_V20_IMP_COMPLEX_BREAK
) ? " COMPLEX_BREAK" : "",
318 EJTAG_IMP_HAS(EJTAG_V20_IMP_DCACHE_COH
) ? " DCACHE_COH" : " DCACHE_NOT_COH",
319 EJTAG_IMP_HAS(EJTAG_V20_IMP_ICACHE_COH
) ? " ICACHE_COH" : " ICACHE_NOT_COH",
320 EJTAG_IMP_HAS(EJTAG_V20_IMP_NOPB
) ? " noPB" : " PB",
321 EJTAG_IMP_HAS(EJTAG_V20_IMP_NODB
) ? " noDB" : " DB",
322 EJTAG_IMP_HAS(EJTAG_V20_IMP_NOIB
) ? " noIB" : " IB");
323 LOG_DEBUG("EJTAG v2.0: Break Channels: %" PRIu8
,
324 (uint8_t)((ejtag_info
->impcode
>> EJTAG_V20_IMP_BCHANNELS_SHIFT
) &
325 EJTAG_V20_IMP_BCHANNELS_MASK
));
328 static void ejtag_v26_print_imp(struct mips_ejtag
*ejtag_info
)
330 LOG_DEBUG("EJTAG v2.6: features:%s%s",
331 EJTAG_IMP_HAS(EJTAG_V26_IMP_R3K
) ? " R3k" : " R4k",
332 EJTAG_IMP_HAS(EJTAG_V26_IMP_DINT
) ? " DINT" : "");
335 void ejtag_main_print_imp(struct mips_ejtag
*ejtag_info
)
337 LOG_DEBUG("EJTAG main: features:%s%s%s%s%s",
338 EJTAG_IMP_HAS(EJTAG_IMP_ASID8
) ? " ASID_8" : "",
339 EJTAG_IMP_HAS(EJTAG_IMP_ASID6
) ? " ASID_6" : "",
340 EJTAG_IMP_HAS(EJTAG_IMP_MIPS16
) ? " MIPS16" : "",
341 EJTAG_IMP_HAS(EJTAG_IMP_NODMA
) ? " noDMA" : " DMA",
342 EJTAG_IMP_HAS(EJTAG_IMP_MIPS64
) ? " MIPS64" : " MIPS32");
344 switch (ejtag_info
->ejtag_version
) {
345 case EJTAG_VERSION_20
:
346 ejtag_v20_print_imp(ejtag_info
);
348 case EJTAG_VERSION_25
:
349 case EJTAG_VERSION_26
:
350 case EJTAG_VERSION_31
:
351 case EJTAG_VERSION_41
:
352 case EJTAG_VERSION_51
:
353 ejtag_v26_print_imp(ejtag_info
);
360 int mips_ejtag_init(struct mips_ejtag
*ejtag_info
)
362 int retval
= mips_ejtag_get_impcode(ejtag_info
);
363 if (retval
!= ERROR_OK
) {
364 LOG_ERROR("impcode read failed");
368 /* get ejtag version */
369 ejtag_info
->ejtag_version
= ((ejtag_info
->impcode
>> 29) & 0x07);
371 switch (ejtag_info
->ejtag_version
) {
372 case EJTAG_VERSION_20
:
373 LOG_DEBUG("EJTAG: Version 1 or 2.0 Detected");
375 case EJTAG_VERSION_25
:
376 LOG_DEBUG("EJTAG: Version 2.5 Detected");
378 case EJTAG_VERSION_26
:
379 LOG_DEBUG("EJTAG: Version 2.6 Detected");
381 case EJTAG_VERSION_31
:
382 LOG_DEBUG("EJTAG: Version 3.1 Detected");
384 case EJTAG_VERSION_41
:
385 LOG_DEBUG("EJTAG: Version 4.1 Detected");
387 case EJTAG_VERSION_51
:
388 LOG_DEBUG("EJTAG: Version 5.1 Detected");
391 LOG_DEBUG("EJTAG: Unknown Version Detected");
394 ejtag_main_print_imp(ejtag_info
);
396 if ((ejtag_info
->impcode
& EJTAG_IMP_NODMA
) == 0) {
397 LOG_DEBUG("EJTAG: DMA Access Mode detected. Disabling to "
398 "workaround current broken code.");
399 ejtag_info
->impcode
|= EJTAG_IMP_NODMA
;
402 ejtag_info
->ejtag_ctrl
= EJTAG_CTRL_PRACC
| EJTAG_CTRL_PROBEN
;
404 if (ejtag_info
->ejtag_version
!= EJTAG_VERSION_20
)
405 ejtag_info
->ejtag_ctrl
|= EJTAG_CTRL_ROCC
| EJTAG_CTRL_SETDEV
;
407 ejtag_info
->fast_access_save
= -1;
409 mips_ejtag_init_mmr(ejtag_info
);
414 int mips_ejtag_fastdata_scan(struct mips_ejtag
*ejtag_info
, int write_t
, uint32_t *data
)
416 assert(ejtag_info
->tap
);
417 struct jtag_tap
*tap
= ejtag_info
->tap
;
419 struct scan_field fields
[2];
421 /* fastdata 1-bit register */
422 fields
[0].num_bits
= 1;
425 fields
[0].out_value
= &spracc
;
426 fields
[0].in_value
= NULL
;
428 /* processor access data register 32 bit */
429 fields
[1].num_bits
= 32;
431 uint8_t t
[4] = {0, 0, 0, 0};
432 fields
[1].out_value
= t
;
435 fields
[1].in_value
= NULL
;
436 buf_set_u32(t
, 0, 32, *data
);
438 fields
[1].in_value
= (uint8_t *) data
;
440 jtag_add_dr_scan(tap
, 2, fields
, TAP_IDLE
);
442 if (!write_t
&& data
)
443 jtag_add_callback(mips_le_to_h_u32
,
444 (jtag_callback_data_t
) data
);
451 int mips64_ejtag_config_step(struct mips_ejtag
*ejtag_info
, bool enable_step
)
453 const uint32_t code_enable
[] = {
454 MIPS64_MTC0(1, 31, 0), /* move $1 to COP0 DeSave */
455 MIPS64_MFC0(1, 23, 0), /* move COP0 Debug to $1 */
456 MIPS64_ORI(1, 1, 0x0100), /* set SSt bit in debug reg */
457 MIPS64_MTC0(1, 23, 0), /* move $1 to COP0 Debug */
459 MIPS64_MFC0(1, 31, 0), /* move COP0 DeSave to $1 */
470 const uint32_t code_disable
[] = {
471 MIPS64_MTC0(15, 31, 0), /* move $15 to COP0 DeSave */
472 MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK
)), /* $15 = MIPS64_PRACC_STACK */
473 MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK
)),
474 MIPS64_SD(1, 0, 15), /* sw $1,($15) */
475 MIPS64_SD(2, 0, 15), /* sw $2,($15) */
476 MIPS64_MFC0(1, 23, 0), /* move COP0 Debug to $1 */
477 MIPS64_LUI(2, 0xFFFF), /* $2 = 0xfffffeff */
478 MIPS64_ORI(2, 2, 0xFEFF),
480 MIPS64_MTC0(1, 23, 0), /* move $1 to COP0 Debug */
485 MIPS64_MFC0(15, 31, 0), /* move COP0 DeSave to $15 */
495 const uint32_t *code
= enable_step
? code_enable
: code_disable
;
496 unsigned int code_len
= enable_step
? ARRAY_SIZE(code_enable
) :
497 ARRAY_SIZE(code_disable
);
499 return mips64_pracc_exec(ejtag_info
,
500 code_len
, code
, 0, NULL
, 0, NULL
);
503 int mips64_ejtag_exit_debug(struct mips_ejtag
*ejtag_info
)
505 const uint32_t code
[] = {
515 LOG_DEBUG("enter mips64_pracc_exec");
516 return mips64_pracc_exec(ejtag_info
,
517 ARRAY_SIZE(code
), code
, 0, NULL
, 0, NULL
);
520 int mips64_ejtag_fastdata_scan(struct mips_ejtag
*ejtag_info
, bool write_t
, uint64_t *data
)
522 struct jtag_tap
*tap
;
524 tap
= ejtag_info
->tap
;
527 struct scan_field fields
[2];
529 uint8_t t
[8] = {0, 0, 0, 0, 0, 0, 0, 0};
531 /* fastdata 1-bit register */
532 fields
[0].num_bits
= 1;
533 fields
[0].out_value
= &spracc
;
534 fields
[0].in_value
= NULL
;
536 /* processor access data register 64 bit */
537 fields
[1].num_bits
= 64;
538 fields
[1].out_value
= t
;
541 fields
[1].in_value
= NULL
;
542 buf_set_u64(t
, 0, 64, *data
);
544 fields
[1].in_value
= (uint8_t *) data
;
546 jtag_add_dr_scan(tap
, 2, fields
, TAP_IDLE
);
548 if (!write_t
&& data
)
549 jtag_add_callback(mips_le_to_h_u64
,
550 (jtag_callback_data_t
) data
);