1 /***************************************************************************
2 * Copyright (C) 2008 by Spencer Oliver *
3 * spen@spen-soft.co.uk *
5 * Copyright (C) 2008 by David T.L. Wong *
7 * Copyright (C) 2007,2008 Øyvind Harboe *
8 * oyvind.harboe@zylin.com *
10 * Copyright (C) 2011 by Drasko DRASKOVIC *
11 * drasko.draskovic@gmail.com *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
18 * This program is distributed in the hope that it will be useful, *
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
21 * GNU General Public License for more details. *
23 * You should have received a copy of the GNU General Public License *
24 * along with this program; if not, write to the *
25 * Free Software Foundation, Inc., *
26 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
27 ***************************************************************************/
34 #include "breakpoints.h"
35 #include "algorithm.h"
38 static const char *mips_isa_strings
[] = {
45 } mips32_regs
[MIPS32NUMCOREREGS
] = {
87 /* number of mips dummy fp regs fp0 - fp31 + fsr and fir
88 * we also add 18 unknown registers to handle gdb requests */
90 #define MIPS32NUMFPREGS (34 + 18)
92 static uint8_t mips32_gdb_dummy_fp_value
[] = {0, 0, 0, 0};
94 static struct reg mips32_gdb_dummy_fp_reg
= {
95 .name
= "GDB dummy floating-point register",
96 .value
= mips32_gdb_dummy_fp_value
,
103 static int mips32_get_core_reg(struct reg
*reg
)
106 struct mips32_core_reg
*mips32_reg
= reg
->arch_info
;
107 struct target
*target
= mips32_reg
->target
;
108 struct mips32_common
*mips32_target
= target_to_mips32(target
);
110 if (target
->state
!= TARGET_HALTED
)
111 return ERROR_TARGET_NOT_HALTED
;
113 retval
= mips32_target
->read_core_reg(target
, mips32_reg
->num
);
118 static int mips32_set_core_reg(struct reg
*reg
, uint8_t *buf
)
120 struct mips32_core_reg
*mips32_reg
= reg
->arch_info
;
121 struct target
*target
= mips32_reg
->target
;
122 uint32_t value
= buf_get_u32(buf
, 0, 32);
124 if (target
->state
!= TARGET_HALTED
)
125 return ERROR_TARGET_NOT_HALTED
;
127 buf_set_u32(reg
->value
, 0, 32, value
);
134 static int mips32_read_core_reg(struct target
*target
, int num
)
138 /* get pointers to arch-specific information */
139 struct mips32_common
*mips32
= target_to_mips32(target
);
141 if ((num
< 0) || (num
>= MIPS32NUMCOREREGS
))
142 return ERROR_COMMAND_SYNTAX_ERROR
;
144 reg_value
= mips32
->core_regs
[num
];
145 buf_set_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
146 mips32
->core_cache
->reg_list
[num
].valid
= 1;
147 mips32
->core_cache
->reg_list
[num
].dirty
= 0;
152 static int mips32_write_core_reg(struct target
*target
, int num
)
156 /* get pointers to arch-specific information */
157 struct mips32_common
*mips32
= target_to_mips32(target
);
159 if ((num
< 0) || (num
>= MIPS32NUMCOREREGS
))
160 return ERROR_COMMAND_SYNTAX_ERROR
;
162 reg_value
= buf_get_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32);
163 mips32
->core_regs
[num
] = reg_value
;
164 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", num
, reg_value
);
165 mips32
->core_cache
->reg_list
[num
].valid
= 1;
166 mips32
->core_cache
->reg_list
[num
].dirty
= 0;
171 int mips32_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[],
172 int *reg_list_size
, enum target_register_class reg_class
)
174 /* get pointers to arch-specific information */
175 struct mips32_common
*mips32
= target_to_mips32(target
);
178 /* include floating point registers */
179 *reg_list_size
= MIPS32NUMCOREREGS
+ MIPS32NUMFPREGS
;
180 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
182 for (i
= 0; i
< MIPS32NUMCOREREGS
; i
++)
183 (*reg_list
)[i
] = &mips32
->core_cache
->reg_list
[i
];
185 /* add dummy floating points regs */
186 for (i
= MIPS32NUMCOREREGS
; i
< (MIPS32NUMCOREREGS
+ MIPS32NUMFPREGS
); i
++)
187 (*reg_list
)[i
] = &mips32_gdb_dummy_fp_reg
;
192 int mips32_save_context(struct target
*target
)
196 /* get pointers to arch-specific information */
197 struct mips32_common
*mips32
= target_to_mips32(target
);
198 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
200 /* read core registers */
201 mips32_pracc_read_regs(ejtag_info
, mips32
->core_regs
);
203 for (i
= 0; i
< MIPS32NUMCOREREGS
; i
++) {
204 if (!mips32
->core_cache
->reg_list
[i
].valid
)
205 mips32
->read_core_reg(target
, i
);
211 int mips32_restore_context(struct target
*target
)
215 /* get pointers to arch-specific information */
216 struct mips32_common
*mips32
= target_to_mips32(target
);
217 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
219 for (i
= 0; i
< MIPS32NUMCOREREGS
; i
++) {
220 if (mips32
->core_cache
->reg_list
[i
].dirty
)
221 mips32
->write_core_reg(target
, i
);
224 /* write core regs */
225 mips32_pracc_write_regs(ejtag_info
, mips32
->core_regs
);
230 int mips32_arch_state(struct target
*target
)
232 struct mips32_common
*mips32
= target_to_mips32(target
);
234 LOG_USER("target halted in %s mode due to %s, pc: 0x%8.8" PRIx32
"",
235 mips_isa_strings
[mips32
->isa_mode
],
236 debug_reason_name(target
),
237 buf_get_u32(mips32
->core_cache
->reg_list
[MIPS32_PC
].value
, 0, 32));
242 static const struct reg_arch_type mips32_reg_type
= {
243 .get
= mips32_get_core_reg
,
244 .set
= mips32_set_core_reg
,
247 struct reg_cache
*mips32_build_reg_cache(struct target
*target
)
249 /* get pointers to arch-specific information */
250 struct mips32_common
*mips32
= target_to_mips32(target
);
252 int num_regs
= MIPS32NUMCOREREGS
;
253 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
254 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
255 struct reg
*reg_list
= calloc(num_regs
, sizeof(struct reg
));
256 struct mips32_core_reg
*arch_info
= malloc(sizeof(struct mips32_core_reg
) * num_regs
);
259 register_init_dummy(&mips32_gdb_dummy_fp_reg
);
261 /* Build the process context cache */
262 cache
->name
= "mips32 registers";
264 cache
->reg_list
= reg_list
;
265 cache
->num_regs
= num_regs
;
267 mips32
->core_cache
= cache
;
269 for (i
= 0; i
< num_regs
; i
++) {
270 arch_info
[i
].num
= mips32_regs
[i
].id
;
271 arch_info
[i
].target
= target
;
272 arch_info
[i
].mips32_common
= mips32
;
274 reg_list
[i
].name
= mips32_regs
[i
].name
;
275 reg_list
[i
].size
= 32;
276 reg_list
[i
].value
= calloc(1, 4);
277 reg_list
[i
].dirty
= 0;
278 reg_list
[i
].valid
= 0;
279 reg_list
[i
].type
= &mips32_reg_type
;
280 reg_list
[i
].arch_info
= &arch_info
[i
];
286 int mips32_init_arch_info(struct target
*target
, struct mips32_common
*mips32
, struct jtag_tap
*tap
)
288 target
->arch_info
= mips32
;
289 mips32
->common_magic
= MIPS32_COMMON_MAGIC
;
290 mips32
->fast_data_area
= NULL
;
292 /* has breakpoint/watchpint unit been scanned */
293 mips32
->bp_scanned
= 0;
294 mips32
->data_break_list
= NULL
;
296 mips32
->ejtag_info
.tap
= tap
;
297 mips32
->read_core_reg
= mips32_read_core_reg
;
298 mips32
->write_core_reg
= mips32_write_core_reg
;
300 mips32
->ejtag_info
.scan_delay
= 2000000; /* Initial default value */
301 mips32
->ejtag_info
.mode
= 0; /* Initial default value */
306 /* run to exit point. return error if exit point was not reached. */
307 static int mips32_run_and_wait(struct target
*target
, uint32_t entry_point
,
308 int timeout_ms
, uint32_t exit_point
, struct mips32_common
*mips32
)
312 /* This code relies on the target specific resume() and poll()->debug_entry()
313 * sequence to write register values to the processor and the read them back */
314 retval
= target_resume(target
, 0, entry_point
, 0, 1);
315 if (retval
!= ERROR_OK
)
318 retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
);
319 /* If the target fails to halt due to the breakpoint, force a halt */
320 if (retval
!= ERROR_OK
|| target
->state
!= TARGET_HALTED
) {
321 retval
= target_halt(target
);
322 if (retval
!= ERROR_OK
)
324 retval
= target_wait_state(target
, TARGET_HALTED
, 500);
325 if (retval
!= ERROR_OK
)
327 return ERROR_TARGET_TIMEOUT
;
330 pc
= buf_get_u32(mips32
->core_cache
->reg_list
[MIPS32_PC
].value
, 0, 32);
331 if (exit_point
&& (pc
!= exit_point
)) {
332 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32
" ", pc
);
333 return ERROR_TARGET_TIMEOUT
;
339 int mips32_run_algorithm(struct target
*target
, int num_mem_params
,
340 struct mem_param
*mem_params
, int num_reg_params
,
341 struct reg_param
*reg_params
, uint32_t entry_point
,
342 uint32_t exit_point
, int timeout_ms
, void *arch_info
)
344 struct mips32_common
*mips32
= target_to_mips32(target
);
345 struct mips32_algorithm
*mips32_algorithm_info
= arch_info
;
346 enum mips32_isa_mode isa_mode
= mips32
->isa_mode
;
348 uint32_t context
[MIPS32NUMCOREREGS
];
350 int retval
= ERROR_OK
;
352 LOG_DEBUG("Running algorithm");
354 /* NOTE: mips32_run_algorithm requires that each algorithm uses a software breakpoint
355 * at the exit point */
357 if (mips32
->common_magic
!= MIPS32_COMMON_MAGIC
) {
358 LOG_ERROR("current target isn't a MIPS32 target");
359 return ERROR_TARGET_INVALID
;
362 if (target
->state
!= TARGET_HALTED
) {
363 LOG_WARNING("target not halted");
364 return ERROR_TARGET_NOT_HALTED
;
367 /* refresh core register cache */
368 for (i
= 0; i
< MIPS32NUMCOREREGS
; i
++) {
369 if (!mips32
->core_cache
->reg_list
[i
].valid
)
370 mips32
->read_core_reg(target
, i
);
371 context
[i
] = buf_get_u32(mips32
->core_cache
->reg_list
[i
].value
, 0, 32);
374 for (i
= 0; i
< num_mem_params
; i
++) {
375 retval
= target_write_buffer(target
, mem_params
[i
].address
,
376 mem_params
[i
].size
, mem_params
[i
].value
);
377 if (retval
!= ERROR_OK
)
381 for (i
= 0; i
< num_reg_params
; i
++) {
382 struct reg
*reg
= register_get_by_name(mips32
->core_cache
, reg_params
[i
].reg_name
, 0);
385 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
386 return ERROR_COMMAND_SYNTAX_ERROR
;
389 if (reg
->size
!= reg_params
[i
].size
) {
390 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
391 reg_params
[i
].reg_name
);
392 return ERROR_COMMAND_SYNTAX_ERROR
;
395 mips32_set_core_reg(reg
, reg_params
[i
].value
);
398 mips32
->isa_mode
= mips32_algorithm_info
->isa_mode
;
400 retval
= mips32_run_and_wait(target
, entry_point
, timeout_ms
, exit_point
, mips32
);
402 if (retval
!= ERROR_OK
)
405 for (i
= 0; i
< num_mem_params
; i
++) {
406 if (mem_params
[i
].direction
!= PARAM_OUT
) {
407 retval
= target_read_buffer(target
, mem_params
[i
].address
, mem_params
[i
].size
,
408 mem_params
[i
].value
);
409 if (retval
!= ERROR_OK
)
414 for (i
= 0; i
< num_reg_params
; i
++) {
415 if (reg_params
[i
].direction
!= PARAM_OUT
) {
416 struct reg
*reg
= register_get_by_name(mips32
->core_cache
, reg_params
[i
].reg_name
, 0);
418 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
419 return ERROR_COMMAND_SYNTAX_ERROR
;
422 if (reg
->size
!= reg_params
[i
].size
) {
423 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
424 reg_params
[i
].reg_name
);
425 return ERROR_COMMAND_SYNTAX_ERROR
;
428 buf_set_u32(reg_params
[i
].value
, 0, 32, buf_get_u32(reg
->value
, 0, 32));
432 /* restore everything we saved before */
433 for (i
= 0; i
< MIPS32NUMCOREREGS
; i
++) {
435 regvalue
= buf_get_u32(mips32
->core_cache
->reg_list
[i
].value
, 0, 32);
436 if (regvalue
!= context
[i
]) {
437 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32
,
438 mips32
->core_cache
->reg_list
[i
].name
, context
[i
]);
439 buf_set_u32(mips32
->core_cache
->reg_list
[i
].value
,
441 mips32
->core_cache
->reg_list
[i
].valid
= 1;
442 mips32
->core_cache
->reg_list
[i
].dirty
= 1;
446 mips32
->isa_mode
= isa_mode
;
451 int mips32_examine(struct target
*target
)
453 struct mips32_common
*mips32
= target_to_mips32(target
);
455 if (!target_was_examined(target
)) {
456 target_set_examined(target
);
458 /* we will configure later */
459 mips32
->bp_scanned
= 0;
460 mips32
->num_inst_bpoints
= 0;
461 mips32
->num_data_bpoints
= 0;
462 mips32
->num_inst_bpoints_avail
= 0;
463 mips32
->num_data_bpoints_avail
= 0;
469 static int mips32_configure_ibs(struct target
*target
)
471 struct mips32_common
*mips32
= target_to_mips32(target
);
472 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
476 /* get number of inst breakpoints */
477 retval
= target_read_u32(target
, ejtag_info
->ejtag_ibs_addr
, &bpinfo
);
478 if (retval
!= ERROR_OK
)
481 mips32
->num_inst_bpoints
= (bpinfo
>> 24) & 0x0F;
482 mips32
->num_inst_bpoints_avail
= mips32
->num_inst_bpoints
;
483 mips32
->inst_break_list
= calloc(mips32
->num_inst_bpoints
,
484 sizeof(struct mips32_comparator
));
486 for (i
= 0; i
< mips32
->num_inst_bpoints
; i
++)
487 mips32
->inst_break_list
[i
].reg_address
=
488 ejtag_info
->ejtag_iba0_addr
+
489 (ejtag_info
->ejtag_iba_step_size
* i
);
492 retval
= target_write_u32(target
, ejtag_info
->ejtag_ibs_addr
, 0);
496 static int mips32_configure_dbs(struct target
*target
)
498 struct mips32_common
*mips32
= target_to_mips32(target
);
499 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
503 /* get number of data breakpoints */
504 retval
= target_read_u32(target
, ejtag_info
->ejtag_dbs_addr
, &bpinfo
);
505 if (retval
!= ERROR_OK
)
508 mips32
->num_data_bpoints
= (bpinfo
>> 24) & 0x0F;
509 mips32
->num_data_bpoints_avail
= mips32
->num_data_bpoints
;
510 mips32
->data_break_list
= calloc(mips32
->num_data_bpoints
,
511 sizeof(struct mips32_comparator
));
513 for (i
= 0; i
< mips32
->num_data_bpoints
; i
++)
514 mips32
->data_break_list
[i
].reg_address
=
515 ejtag_info
->ejtag_dba0_addr
+
516 (ejtag_info
->ejtag_dba_step_size
* i
);
519 retval
= target_write_u32(target
, ejtag_info
->ejtag_dbs_addr
, 0);
523 int mips32_configure_break_unit(struct target
*target
)
525 /* get pointers to arch-specific information */
526 struct mips32_common
*mips32
= target_to_mips32(target
);
527 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
531 if (mips32
->bp_scanned
)
534 /* get info about breakpoint support */
535 retval
= target_read_u32(target
, EJTAG_DCR
, &dcr
);
536 if (retval
!= ERROR_OK
)
539 /* EJTAG 2.0 defines IB and DB bits in IMP instead of DCR.
540 * Since these DCR bits should be reserved on EJTAG 2.0, we can
541 * just remap them. */
542 if (ejtag_info
->ejtag_version
== EJTAG_VERSION_20
) {
543 if (!(ejtag_info
->impcode
& EJTAG_V20_IMP_NOIB
))
545 if (!(ejtag_info
->impcode
& EJTAG_V20_IMP_NODB
))
549 if (dcr
& EJTAG_DCR_IB
) {
550 retval
= mips32_configure_ibs(target
);
551 if (retval
!= ERROR_OK
)
555 if (dcr
& EJTAG_DCR_DB
) {
556 retval
= mips32_configure_dbs(target
);
557 if (retval
!= ERROR_OK
)
561 /* check if target endianness settings matches debug control register */
562 if (((dcr
& EJTAG_DCR_ENM
) && (target
->endianness
== TARGET_LITTLE_ENDIAN
)) ||
563 (!(dcr
& EJTAG_DCR_ENM
) && (target
->endianness
== TARGET_BIG_ENDIAN
)))
564 LOG_WARNING("DCR endianness settings does not match target settings");
566 LOG_DEBUG("DCR 0x%" PRIx32
" numinst %i numdata %i", dcr
, mips32
->num_inst_bpoints
,
567 mips32
->num_data_bpoints
);
569 mips32
->bp_scanned
= 1;
574 int mips32_enable_interrupts(struct target
*target
, int enable
)
580 /* read debug control register */
581 retval
= target_read_u32(target
, EJTAG_DCR
, &dcr
);
582 if (retval
!= ERROR_OK
)
586 if (!(dcr
& EJTAG_DCR_INTE
)) {
587 /* enable interrupts */
588 dcr
|= EJTAG_DCR_INTE
;
592 if (dcr
& EJTAG_DCR_INTE
) {
593 /* disable interrupts */
594 dcr
&= ~EJTAG_DCR_INTE
;
600 retval
= target_write_u32(target
, EJTAG_DCR
, dcr
);
601 if (retval
!= ERROR_OK
)
608 int mips32_checksum_memory(struct target
*target
, uint32_t address
,
609 uint32_t count
, uint32_t *checksum
)
611 struct working_area
*crc_algorithm
;
612 struct reg_param reg_params
[2];
613 struct mips32_algorithm mips32_info
;
615 /* see contrib/loaders/checksum/mips32.s for src */
617 static const uint32_t mips_crc_code
[] = {
618 0x248C0000, /* addiu $t4, $a0, 0 */
619 0x24AA0000, /* addiu $t2, $a1, 0 */
620 0x2404FFFF, /* addiu $a0, $zero, 0xffffffff */
621 0x10000010, /* beq $zero, $zero, ncomp */
622 0x240B0000, /* addiu $t3, $zero, 0 */
624 0x81850000, /* lb $a1, ($t4) */
625 0x218C0001, /* addi $t4, $t4, 1 */
626 0x00052E00, /* sll $a1, $a1, 24 */
627 0x3C0204C1, /* lui $v0, 0x04c1 */
628 0x00852026, /* xor $a0, $a0, $a1 */
629 0x34471DB7, /* ori $a3, $v0, 0x1db7 */
630 0x00003021, /* addu $a2, $zero, $zero */
632 0x00044040, /* sll $t0, $a0, 1 */
633 0x24C60001, /* addiu $a2, $a2, 1 */
634 0x28840000, /* slti $a0, $a0, 0 */
635 0x01074826, /* xor $t1, $t0, $a3 */
636 0x0124400B, /* movn $t0, $t1, $a0 */
637 0x28C30008, /* slti $v1, $a2, 8 */
638 0x1460FFF9, /* bne $v1, $zero, loop */
639 0x01002021, /* addu $a0, $t0, $zero */
641 0x154BFFF0, /* bne $t2, $t3, nbyte */
642 0x256B0001, /* addiu $t3, $t3, 1 */
643 0x7000003F, /* sdbbp */
646 /* make sure we have a working area */
647 if (target_alloc_working_area(target
, sizeof(mips_crc_code
), &crc_algorithm
) != ERROR_OK
)
648 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
650 /* convert mips crc code into a buffer in target endianness */
651 uint8_t mips_crc_code_8
[sizeof(mips_crc_code
)];
652 target_buffer_set_u32_array(target
, mips_crc_code_8
,
653 ARRAY_SIZE(mips_crc_code
), mips_crc_code
);
655 target_write_buffer(target
, crc_algorithm
->address
, sizeof(mips_crc_code
), mips_crc_code_8
);
657 mips32_info
.common_magic
= MIPS32_COMMON_MAGIC
;
658 mips32_info
.isa_mode
= MIPS32_ISA_MIPS32
;
660 init_reg_param(®_params
[0], "a0", 32, PARAM_IN_OUT
);
661 buf_set_u32(reg_params
[0].value
, 0, 32, address
);
663 init_reg_param(®_params
[1], "a1", 32, PARAM_OUT
);
664 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
666 int timeout
= 20000 * (1 + (count
/ (1024 * 1024)));
668 int retval
= target_run_algorithm(target
, 0, NULL
, 2, reg_params
,
669 crc_algorithm
->address
, crc_algorithm
->address
+ (sizeof(mips_crc_code
) - 4), timeout
,
672 if (retval
== ERROR_OK
)
673 *checksum
= buf_get_u32(reg_params
[0].value
, 0, 32);
675 destroy_reg_param(®_params
[0]);
676 destroy_reg_param(®_params
[1]);
678 target_free_working_area(target
, crc_algorithm
);
683 /** Checks whether a memory region is zeroed. */
684 int mips32_blank_check_memory(struct target
*target
,
685 uint32_t address
, uint32_t count
, uint32_t *blank
)
687 struct working_area
*erase_check_algorithm
;
688 struct reg_param reg_params
[3];
689 struct mips32_algorithm mips32_info
;
691 static const uint32_t erase_check_code
[] = {
693 0x80880000, /* lb $t0, ($a0) */
694 0x00C83024, /* and $a2, $a2, $t0 */
695 0x24A5FFFF, /* addiu $a1, $a1, -1 */
696 0x14A0FFFC, /* bne $a1, $zero, nbyte */
697 0x24840001, /* addiu $a0, $a0, 1 */
698 0x7000003F /* sdbbp */
701 /* make sure we have a working area */
702 if (target_alloc_working_area(target
, sizeof(erase_check_code
), &erase_check_algorithm
) != ERROR_OK
)
703 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
705 /* convert erase check code into a buffer in target endianness */
706 uint8_t erase_check_code_8
[sizeof(erase_check_code
)];
707 target_buffer_set_u32_array(target
, erase_check_code_8
,
708 ARRAY_SIZE(erase_check_code
), erase_check_code
);
710 target_write_buffer(target
, erase_check_algorithm
->address
, sizeof(erase_check_code
), erase_check_code_8
);
712 mips32_info
.common_magic
= MIPS32_COMMON_MAGIC
;
713 mips32_info
.isa_mode
= MIPS32_ISA_MIPS32
;
715 init_reg_param(®_params
[0], "a0", 32, PARAM_OUT
);
716 buf_set_u32(reg_params
[0].value
, 0, 32, address
);
718 init_reg_param(®_params
[1], "a1", 32, PARAM_OUT
);
719 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
721 init_reg_param(®_params
[2], "a2", 32, PARAM_IN_OUT
);
722 buf_set_u32(reg_params
[2].value
, 0, 32, 0xff);
724 int retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
,
725 erase_check_algorithm
->address
,
726 erase_check_algorithm
->address
+ (sizeof(erase_check_code
) - 4),
727 10000, &mips32_info
);
729 if (retval
== ERROR_OK
)
730 *blank
= buf_get_u32(reg_params
[2].value
, 0, 32);
732 destroy_reg_param(®_params
[0]);
733 destroy_reg_param(®_params
[1]);
734 destroy_reg_param(®_params
[2]);
736 target_free_working_area(target
, erase_check_algorithm
);
741 static int mips32_verify_pointer(struct command_context
*cmd_ctx
,
742 struct mips32_common
*mips32
)
744 if (mips32
->common_magic
!= MIPS32_COMMON_MAGIC
) {
745 command_print(cmd_ctx
, "target is not an MIPS32");
746 return ERROR_TARGET_INVALID
;
752 * MIPS32 targets expose command interface
753 * to manipulate CP0 registers
755 COMMAND_HANDLER(mips32_handle_cp0_command
)
758 struct target
*target
= get_current_target(CMD_CTX
);
759 struct mips32_common
*mips32
= target_to_mips32(target
);
760 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
763 retval
= mips32_verify_pointer(CMD_CTX
, mips32
);
764 if (retval
!= ERROR_OK
)
767 if (target
->state
!= TARGET_HALTED
) {
768 command_print(CMD_CTX
, "target must be stopped for \"%s\" command", CMD_NAME
);
772 /* two or more argument, access a single register/select (write if third argument is given) */
774 return ERROR_COMMAND_SYNTAX_ERROR
;
776 uint32_t cp0_reg
, cp0_sel
;
777 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], cp0_reg
);
778 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], cp0_sel
);
783 retval
= mips32_cp0_read(ejtag_info
, &value
, cp0_reg
, cp0_sel
);
784 if (retval
!= ERROR_OK
) {
785 command_print(CMD_CTX
,
786 "couldn't access reg %" PRIi32
,
790 command_print(CMD_CTX
, "cp0 reg %" PRIi32
", select %" PRIi32
": %8.8" PRIx32
,
791 cp0_reg
, cp0_sel
, value
);
793 } else if (CMD_ARGC
== 3) {
795 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], value
);
796 retval
= mips32_cp0_write(ejtag_info
, value
, cp0_reg
, cp0_sel
);
797 if (retval
!= ERROR_OK
) {
798 command_print(CMD_CTX
,
799 "couldn't access cp0 reg %" PRIi32
", select %" PRIi32
,
803 command_print(CMD_CTX
, "cp0 reg %" PRIi32
", select %" PRIi32
": %8.8" PRIx32
,
804 cp0_reg
, cp0_sel
, value
);
811 COMMAND_HANDLER(mips32_handle_scan_delay_command
)
813 struct target
*target
= get_current_target(CMD_CTX
);
814 struct mips32_common
*mips32
= target_to_mips32(target
);
815 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
818 COMMAND_PARSE_NUMBER(uint
, CMD_ARGV
[0], ejtag_info
->scan_delay
);
819 else if (CMD_ARGC
> 1)
820 return ERROR_COMMAND_SYNTAX_ERROR
;
822 command_print(CMD_CTX
, "scan delay: %d nsec", ejtag_info
->scan_delay
);
823 if (ejtag_info
->scan_delay
>= 2000000) {
824 ejtag_info
->mode
= 0;
825 command_print(CMD_CTX
, "running in legacy mode");
827 ejtag_info
->mode
= 1;
828 command_print(CMD_CTX
, "running in fast queued mode");
834 static const struct command_registration mips32_exec_command_handlers
[] = {
837 .handler
= mips32_handle_cp0_command
,
838 .mode
= COMMAND_EXEC
,
839 .usage
= "regnum select [value]",
840 .help
= "display/modify cp0 register",
843 .name
= "scan_delay",
844 .handler
= mips32_handle_scan_delay_command
,
846 .help
= "display/set scan delay in nano seconds",
849 COMMAND_REGISTRATION_DONE
852 const struct command_registration mips32_command_handlers
[] = {
856 .help
= "mips32 command group",
858 .chain
= mips32_exec_command_handlers
,
860 COMMAND_REGISTRATION_DONE
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)