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 char *mips32_core_reg_list
[] = {
39 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
40 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
41 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
42 "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra",
43 "status", "lo", "hi", "badvaddr", "cause", "pc"
46 static const char *mips_isa_strings
[] = {
50 static struct mips32_core_reg mips32_core_reg_list_arch_info
[MIPS32NUMCOREREGS
] = {
92 /* number of mips dummy fp regs fp0 - fp31 + fsr and fir
93 * we also add 18 unknown registers to handle gdb requests */
95 #define MIPS32NUMFPREGS (34 + 18)
97 static uint8_t mips32_gdb_dummy_fp_value
[] = {0, 0, 0, 0};
99 static struct reg mips32_gdb_dummy_fp_reg
= {
100 .name
= "GDB dummy floating-point register",
101 .value
= mips32_gdb_dummy_fp_value
,
108 static int mips32_get_core_reg(struct reg
*reg
)
111 struct mips32_core_reg
*mips32_reg
= reg
->arch_info
;
112 struct target
*target
= mips32_reg
->target
;
113 struct mips32_common
*mips32_target
= target_to_mips32(target
);
115 if (target
->state
!= TARGET_HALTED
)
116 return ERROR_TARGET_NOT_HALTED
;
118 retval
= mips32_target
->read_core_reg(target
, mips32_reg
->num
);
123 static int mips32_set_core_reg(struct reg
*reg
, uint8_t *buf
)
125 struct mips32_core_reg
*mips32_reg
= reg
->arch_info
;
126 struct target
*target
= mips32_reg
->target
;
127 uint32_t value
= buf_get_u32(buf
, 0, 32);
129 if (target
->state
!= TARGET_HALTED
)
130 return ERROR_TARGET_NOT_HALTED
;
132 buf_set_u32(reg
->value
, 0, 32, value
);
139 static int mips32_read_core_reg(struct target
*target
, int num
)
143 /* get pointers to arch-specific information */
144 struct mips32_common
*mips32
= target_to_mips32(target
);
146 if ((num
< 0) || (num
>= MIPS32NUMCOREREGS
))
147 return ERROR_COMMAND_SYNTAX_ERROR
;
149 reg_value
= mips32
->core_regs
[num
];
150 buf_set_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32, reg_value
);
151 mips32
->core_cache
->reg_list
[num
].valid
= 1;
152 mips32
->core_cache
->reg_list
[num
].dirty
= 0;
157 static int mips32_write_core_reg(struct target
*target
, int num
)
161 /* get pointers to arch-specific information */
162 struct mips32_common
*mips32
= target_to_mips32(target
);
164 if ((num
< 0) || (num
>= MIPS32NUMCOREREGS
))
165 return ERROR_COMMAND_SYNTAX_ERROR
;
167 reg_value
= buf_get_u32(mips32
->core_cache
->reg_list
[num
].value
, 0, 32);
168 mips32
->core_regs
[num
] = reg_value
;
169 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", num
, reg_value
);
170 mips32
->core_cache
->reg_list
[num
].valid
= 1;
171 mips32
->core_cache
->reg_list
[num
].dirty
= 0;
176 int mips32_get_gdb_reg_list(struct target
*target
, struct reg
**reg_list
[], int *reg_list_size
)
178 /* get pointers to arch-specific information */
179 struct mips32_common
*mips32
= target_to_mips32(target
);
182 /* include floating point registers */
183 *reg_list_size
= MIPS32NUMCOREREGS
+ MIPS32NUMFPREGS
;
184 *reg_list
= malloc(sizeof(struct reg
*) * (*reg_list_size
));
186 for (i
= 0; i
< MIPS32NUMCOREREGS
; i
++)
187 (*reg_list
)[i
] = &mips32
->core_cache
->reg_list
[i
];
189 /* add dummy floating points regs */
190 for (i
= MIPS32NUMCOREREGS
; i
< (MIPS32NUMCOREREGS
+ MIPS32NUMFPREGS
); i
++)
191 (*reg_list
)[i
] = &mips32_gdb_dummy_fp_reg
;
196 int mips32_save_context(struct target
*target
)
200 /* get pointers to arch-specific information */
201 struct mips32_common
*mips32
= target_to_mips32(target
);
202 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
204 /* read core registers */
205 mips32_pracc_read_regs(ejtag_info
, mips32
->core_regs
);
207 for (i
= 0; i
< MIPS32NUMCOREREGS
; i
++) {
208 if (!mips32
->core_cache
->reg_list
[i
].valid
)
209 mips32
->read_core_reg(target
, i
);
215 int mips32_restore_context(struct target
*target
)
219 /* get pointers to arch-specific information */
220 struct mips32_common
*mips32
= target_to_mips32(target
);
221 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
223 for (i
= 0; i
< MIPS32NUMCOREREGS
; i
++) {
224 if (mips32
->core_cache
->reg_list
[i
].dirty
)
225 mips32
->write_core_reg(target
, i
);
228 /* write core regs */
229 mips32_pracc_write_regs(ejtag_info
, mips32
->core_regs
);
234 int mips32_arch_state(struct target
*target
)
236 struct mips32_common
*mips32
= target_to_mips32(target
);
238 LOG_USER("target halted in %s mode due to %s, pc: 0x%8.8" PRIx32
"",
239 mips_isa_strings
[mips32
->isa_mode
],
240 debug_reason_name(target
),
241 buf_get_u32(mips32
->core_cache
->reg_list
[MIPS32_PC
].value
, 0, 32));
246 static const struct reg_arch_type mips32_reg_type
= {
247 .get
= mips32_get_core_reg
,
248 .set
= mips32_set_core_reg
,
251 struct reg_cache
*mips32_build_reg_cache(struct target
*target
)
253 /* get pointers to arch-specific information */
254 struct mips32_common
*mips32
= target_to_mips32(target
);
256 int num_regs
= MIPS32NUMCOREREGS
;
257 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
258 struct reg_cache
*cache
= malloc(sizeof(struct reg_cache
));
259 struct reg
*reg_list
= malloc(sizeof(struct reg
) * num_regs
);
260 struct mips32_core_reg
*arch_info
= malloc(sizeof(struct mips32_core_reg
) * num_regs
);
263 register_init_dummy(&mips32_gdb_dummy_fp_reg
);
265 /* Build the process context cache */
266 cache
->name
= "mips32 registers";
268 cache
->reg_list
= reg_list
;
269 cache
->num_regs
= num_regs
;
271 mips32
->core_cache
= cache
;
273 for (i
= 0; i
< num_regs
; i
++) {
274 arch_info
[i
] = mips32_core_reg_list_arch_info
[i
];
275 arch_info
[i
].target
= target
;
276 arch_info
[i
].mips32_common
= mips32
;
277 reg_list
[i
].name
= mips32_core_reg_list
[i
];
278 reg_list
[i
].size
= 32;
279 reg_list
[i
].value
= calloc(1, 4);
280 reg_list
[i
].dirty
= 0;
281 reg_list
[i
].valid
= 0;
282 reg_list
[i
].type
= &mips32_reg_type
;
283 reg_list
[i
].arch_info
= &arch_info
[i
];
289 int mips32_init_arch_info(struct target
*target
, struct mips32_common
*mips32
, struct jtag_tap
*tap
)
291 target
->arch_info
= mips32
;
292 mips32
->common_magic
= MIPS32_COMMON_MAGIC
;
293 mips32
->fast_data_area
= NULL
;
295 /* has breakpoint/watchpint unit been scanned */
296 mips32
->bp_scanned
= 0;
297 mips32
->data_break_list
= NULL
;
299 mips32
->ejtag_info
.tap
= tap
;
300 mips32
->read_core_reg
= mips32_read_core_reg
;
301 mips32
->write_core_reg
= mips32_write_core_reg
;
303 mips32
->ejtag_info
.scan_delay
= 2000000; /* Initial default value */
304 mips32
->ejtag_info
.mode
= 0; /* Initial default value */
309 /* run to exit point. return error if exit point was not reached. */
310 static int mips32_run_and_wait(struct target
*target
, uint32_t entry_point
,
311 int timeout_ms
, uint32_t exit_point
, struct mips32_common
*mips32
)
315 /* This code relies on the target specific resume() and poll()->debug_entry()
316 * sequence to write register values to the processor and the read them back */
317 retval
= target_resume(target
, 0, entry_point
, 0, 1);
318 if (retval
!= ERROR_OK
)
321 retval
= target_wait_state(target
, TARGET_HALTED
, timeout_ms
);
322 /* If the target fails to halt due to the breakpoint, force a halt */
323 if (retval
!= ERROR_OK
|| target
->state
!= TARGET_HALTED
) {
324 retval
= target_halt(target
);
325 if (retval
!= ERROR_OK
)
327 retval
= target_wait_state(target
, TARGET_HALTED
, 500);
328 if (retval
!= ERROR_OK
)
330 return ERROR_TARGET_TIMEOUT
;
333 pc
= buf_get_u32(mips32
->core_cache
->reg_list
[MIPS32_PC
].value
, 0, 32);
334 if (exit_point
&& (pc
!= exit_point
)) {
335 LOG_DEBUG("failed algorithm halted at 0x%" PRIx32
" ", pc
);
336 return ERROR_TARGET_TIMEOUT
;
342 int mips32_run_algorithm(struct target
*target
, int num_mem_params
,
343 struct mem_param
*mem_params
, int num_reg_params
,
344 struct reg_param
*reg_params
, uint32_t entry_point
,
345 uint32_t exit_point
, int timeout_ms
, void *arch_info
)
347 struct mips32_common
*mips32
= target_to_mips32(target
);
348 struct mips32_algorithm
*mips32_algorithm_info
= arch_info
;
349 enum mips32_isa_mode isa_mode
= mips32
->isa_mode
;
351 uint32_t context
[MIPS32NUMCOREREGS
];
353 int retval
= ERROR_OK
;
355 LOG_DEBUG("Running algorithm");
357 /* NOTE: mips32_run_algorithm requires that each algorithm uses a software breakpoint
358 * at the exit point */
360 if (mips32
->common_magic
!= MIPS32_COMMON_MAGIC
) {
361 LOG_ERROR("current target isn't a MIPS32 target");
362 return ERROR_TARGET_INVALID
;
365 if (target
->state
!= TARGET_HALTED
) {
366 LOG_WARNING("target not halted");
367 return ERROR_TARGET_NOT_HALTED
;
370 /* refresh core register cache */
371 for (i
= 0; i
< MIPS32NUMCOREREGS
; i
++) {
372 if (!mips32
->core_cache
->reg_list
[i
].valid
)
373 mips32
->read_core_reg(target
, i
);
374 context
[i
] = buf_get_u32(mips32
->core_cache
->reg_list
[i
].value
, 0, 32);
377 for (i
= 0; i
< num_mem_params
; i
++) {
378 retval
= target_write_buffer(target
, mem_params
[i
].address
,
379 mem_params
[i
].size
, mem_params
[i
].value
);
380 if (retval
!= ERROR_OK
)
384 for (i
= 0; i
< num_reg_params
; i
++) {
385 struct reg
*reg
= register_get_by_name(mips32
->core_cache
, reg_params
[i
].reg_name
, 0);
388 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
389 return ERROR_COMMAND_SYNTAX_ERROR
;
392 if (reg
->size
!= reg_params
[i
].size
) {
393 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
394 reg_params
[i
].reg_name
);
395 return ERROR_COMMAND_SYNTAX_ERROR
;
398 mips32_set_core_reg(reg
, reg_params
[i
].value
);
401 mips32
->isa_mode
= mips32_algorithm_info
->isa_mode
;
403 retval
= mips32_run_and_wait(target
, entry_point
, timeout_ms
, exit_point
, mips32
);
405 if (retval
!= ERROR_OK
)
408 for (i
= 0; i
< num_mem_params
; i
++) {
409 if (mem_params
[i
].direction
!= PARAM_OUT
) {
410 retval
= target_read_buffer(target
, mem_params
[i
].address
, mem_params
[i
].size
,
411 mem_params
[i
].value
);
412 if (retval
!= ERROR_OK
)
417 for (i
= 0; i
< num_reg_params
; i
++) {
418 if (reg_params
[i
].direction
!= PARAM_OUT
) {
419 struct reg
*reg
= register_get_by_name(mips32
->core_cache
, reg_params
[i
].reg_name
, 0);
421 LOG_ERROR("BUG: register '%s' not found", reg_params
[i
].reg_name
);
422 return ERROR_COMMAND_SYNTAX_ERROR
;
425 if (reg
->size
!= reg_params
[i
].size
) {
426 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
427 reg_params
[i
].reg_name
);
428 return ERROR_COMMAND_SYNTAX_ERROR
;
431 buf_set_u32(reg_params
[i
].value
, 0, 32, buf_get_u32(reg
->value
, 0, 32));
435 /* restore everything we saved before */
436 for (i
= 0; i
< MIPS32NUMCOREREGS
; i
++) {
438 regvalue
= buf_get_u32(mips32
->core_cache
->reg_list
[i
].value
, 0, 32);
439 if (regvalue
!= context
[i
]) {
440 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32
,
441 mips32
->core_cache
->reg_list
[i
].name
, context
[i
]);
442 buf_set_u32(mips32
->core_cache
->reg_list
[i
].value
,
444 mips32
->core_cache
->reg_list
[i
].valid
= 1;
445 mips32
->core_cache
->reg_list
[i
].dirty
= 1;
449 mips32
->isa_mode
= isa_mode
;
454 int mips32_examine(struct target
*target
)
456 struct mips32_common
*mips32
= target_to_mips32(target
);
458 if (!target_was_examined(target
)) {
459 target_set_examined(target
);
461 /* we will configure later */
462 mips32
->bp_scanned
= 0;
463 mips32
->num_inst_bpoints
= 0;
464 mips32
->num_data_bpoints
= 0;
465 mips32
->num_inst_bpoints_avail
= 0;
466 mips32
->num_data_bpoints_avail
= 0;
472 static int mips32_configure_ibs(struct target
*target
)
474 struct mips32_common
*mips32
= target_to_mips32(target
);
478 /* get number of inst breakpoints */
479 retval
= target_read_u32(target
, EJTAG_IBS
, &bpinfo
);
480 if (retval
!= ERROR_OK
)
483 mips32
->num_inst_bpoints
= (bpinfo
>> 24) & 0x0F;
484 mips32
->num_inst_bpoints_avail
= mips32
->num_inst_bpoints
;
485 mips32
->inst_break_list
= calloc(mips32
->num_inst_bpoints
,
486 sizeof(struct mips32_comparator
));
488 for (i
= 0; i
< mips32
->num_inst_bpoints
; i
++)
489 mips32
->inst_break_list
[i
].reg_address
=
490 EJTAG_IBA1
+ (0x100 * i
);
493 retval
= target_write_u32(target
, EJTAG_IBS
, 0);
497 static int mips32_configure_dbs(struct target
*target
)
499 struct mips32_common
*mips32
= target_to_mips32(target
);
503 /* get number of data breakpoints */
504 retval
= target_read_u32(target
, EJTAG_DBS
, &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_DBA1
+ (0x100 * i
);
518 retval
= target_write_u32(target
, EJTAG_DBS
, 0);
522 int mips32_configure_break_unit(struct target
*target
)
524 /* get pointers to arch-specific information */
525 struct mips32_common
*mips32
= target_to_mips32(target
);
529 if (mips32
->bp_scanned
)
532 /* get info about breakpoint support */
533 retval
= target_read_u32(target
, EJTAG_DCR
, &dcr
);
534 if (retval
!= ERROR_OK
)
537 if (dcr
& EJTAG_DCR_IB
) {
538 retval
= mips32_configure_ibs(target
);
539 if (retval
!= ERROR_OK
)
543 if (dcr
& EJTAG_DCR_DB
) {
544 retval
= mips32_configure_dbs(target
);
545 if (retval
!= ERROR_OK
)
549 /* check if target endianness settings matches debug control register */
550 if (((dcr
& EJTAG_DCR_ENM
) && (target
->endianness
== TARGET_LITTLE_ENDIAN
)) ||
551 (!(dcr
& EJTAG_DCR_ENM
) && (target
->endianness
== TARGET_BIG_ENDIAN
)))
552 LOG_WARNING("DCR endianness settings does not match target settings");
554 LOG_DEBUG("DCR 0x%" PRIx32
" numinst %i numdata %i", dcr
, mips32
->num_inst_bpoints
,
555 mips32
->num_data_bpoints
);
557 mips32
->bp_scanned
= 1;
562 int mips32_enable_interrupts(struct target
*target
, int enable
)
568 /* read debug control register */
569 retval
= target_read_u32(target
, EJTAG_DCR
, &dcr
);
570 if (retval
!= ERROR_OK
)
574 if (!(dcr
& EJTAG_DCR_INTE
)) {
575 /* enable interrupts */
576 dcr
|= EJTAG_DCR_INTE
;
580 if (dcr
& EJTAG_DCR_INTE
) {
581 /* disable interrupts */
582 dcr
&= ~EJTAG_DCR_INTE
;
588 retval
= target_write_u32(target
, EJTAG_DCR
, dcr
);
589 if (retval
!= ERROR_OK
)
596 int mips32_checksum_memory(struct target
*target
, uint32_t address
,
597 uint32_t count
, uint32_t *checksum
)
599 struct working_area
*crc_algorithm
;
600 struct reg_param reg_params
[2];
601 struct mips32_algorithm mips32_info
;
605 /* see contib/loaders/checksum/mips32.s for src */
607 static const uint32_t mips_crc_code
[] = {
608 0x248C0000, /* addiu $t4, $a0, 0 */
609 0x24AA0000, /* addiu $t2, $a1, 0 */
610 0x2404FFFF, /* addiu $a0, $zero, 0xffffffff */
611 0x10000010, /* beq $zero, $zero, ncomp */
612 0x240B0000, /* addiu $t3, $zero, 0 */
614 0x81850000, /* lb $a1, ($t4) */
615 0x218C0001, /* addi $t4, $t4, 1 */
616 0x00052E00, /* sll $a1, $a1, 24 */
617 0x3C0204C1, /* lui $v0, 0x04c1 */
618 0x00852026, /* xor $a0, $a0, $a1 */
619 0x34471DB7, /* ori $a3, $v0, 0x1db7 */
620 0x00003021, /* addu $a2, $zero, $zero */
622 0x00044040, /* sll $t0, $a0, 1 */
623 0x24C60001, /* addiu $a2, $a2, 1 */
624 0x28840000, /* slti $a0, $a0, 0 */
625 0x01074826, /* xor $t1, $t0, $a3 */
626 0x0124400B, /* movn $t0, $t1, $a0 */
627 0x28C30008, /* slti $v1, $a2, 8 */
628 0x1460FFF9, /* bne $v1, $zero, loop */
629 0x01002021, /* addu $a0, $t0, $zero */
631 0x154BFFF0, /* bne $t2, $t3, nbyte */
632 0x256B0001, /* addiu $t3, $t3, 1 */
633 0x7000003F, /* sdbbp */
636 /* make sure we have a working area */
637 if (target_alloc_working_area(target
, sizeof(mips_crc_code
), &crc_algorithm
) != ERROR_OK
)
638 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
640 /* convert flash writing code into a buffer in target endianness */
641 for (i
= 0; i
< ARRAY_SIZE(mips_crc_code
); i
++)
642 target_write_u32(target
, crc_algorithm
->address
+ i
*sizeof(uint32_t), mips_crc_code
[i
]);
644 mips32_info
.common_magic
= MIPS32_COMMON_MAGIC
;
645 mips32_info
.isa_mode
= MIPS32_ISA_MIPS32
;
647 init_reg_param(®_params
[0], "a0", 32, PARAM_IN_OUT
);
648 buf_set_u32(reg_params
[0].value
, 0, 32, address
);
650 init_reg_param(®_params
[1], "a1", 32, PARAM_OUT
);
651 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
653 int timeout
= 20000 * (1 + (count
/ (1024 * 1024)));
655 retval
= target_run_algorithm(target
, 0, NULL
, 2, reg_params
,
656 crc_algorithm
->address
, crc_algorithm
->address
+ (sizeof(mips_crc_code
)-4), timeout
,
658 if (retval
!= ERROR_OK
) {
659 destroy_reg_param(®_params
[0]);
660 destroy_reg_param(®_params
[1]);
661 target_free_working_area(target
, crc_algorithm
);
665 *checksum
= buf_get_u32(reg_params
[0].value
, 0, 32);
667 destroy_reg_param(®_params
[0]);
668 destroy_reg_param(®_params
[1]);
670 target_free_working_area(target
, crc_algorithm
);
675 /** Checks whether a memory region is zeroed. */
676 int mips32_blank_check_memory(struct target
*target
,
677 uint32_t address
, uint32_t count
, uint32_t *blank
)
679 struct working_area
*erase_check_algorithm
;
680 struct reg_param reg_params
[3];
681 struct mips32_algorithm mips32_info
;
685 static const uint32_t erase_check_code
[] = {
687 0x80880000, /* lb $t0, ($a0) */
688 0x00C83024, /* and $a2, $a2, $t0 */
689 0x24A5FFFF, /* addiu $a1, $a1, -1 */
690 0x14A0FFFC, /* bne $a1, $zero, nbyte */
691 0x24840001, /* addiu $a0, $a0, 1 */
692 0x7000003F /* sdbbp */
695 /* make sure we have a working area */
696 if (target_alloc_working_area(target
, sizeof(erase_check_code
), &erase_check_algorithm
) != ERROR_OK
)
697 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
699 /* convert flash writing code into a buffer in target endianness */
700 for (i
= 0; i
< ARRAY_SIZE(erase_check_code
); i
++) {
701 target_write_u32(target
, erase_check_algorithm
->address
+ i
*sizeof(uint32_t),
702 erase_check_code
[i
]);
705 mips32_info
.common_magic
= MIPS32_COMMON_MAGIC
;
706 mips32_info
.isa_mode
= MIPS32_ISA_MIPS32
;
708 init_reg_param(®_params
[0], "a0", 32, PARAM_OUT
);
709 buf_set_u32(reg_params
[0].value
, 0, 32, address
);
711 init_reg_param(®_params
[1], "a1", 32, PARAM_OUT
);
712 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
714 init_reg_param(®_params
[2], "a2", 32, PARAM_IN_OUT
);
715 buf_set_u32(reg_params
[2].value
, 0, 32, 0xff);
717 retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
,
718 erase_check_algorithm
->address
,
719 erase_check_algorithm
->address
+ (sizeof(erase_check_code
)-4),
720 10000, &mips32_info
);
721 if (retval
!= ERROR_OK
) {
722 destroy_reg_param(®_params
[0]);
723 destroy_reg_param(®_params
[1]);
724 destroy_reg_param(®_params
[2]);
725 target_free_working_area(target
, erase_check_algorithm
);
729 *blank
= buf_get_u32(reg_params
[2].value
, 0, 32);
731 destroy_reg_param(®_params
[0]);
732 destroy_reg_param(®_params
[1]);
733 destroy_reg_param(®_params
[2]);
735 target_free_working_area(target
, erase_check_algorithm
);
740 static int mips32_verify_pointer(struct command_context
*cmd_ctx
,
741 struct mips32_common
*mips32
)
743 if (mips32
->common_magic
!= MIPS32_COMMON_MAGIC
) {
744 command_print(cmd_ctx
, "target is not an MIPS32");
745 return ERROR_TARGET_INVALID
;
751 * MIPS32 targets expose command interface
752 * to manipulate CP0 registers
754 COMMAND_HANDLER(mips32_handle_cp0_command
)
757 struct target
*target
= get_current_target(CMD_CTX
);
758 struct mips32_common
*mips32
= target_to_mips32(target
);
759 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
762 retval
= mips32_verify_pointer(CMD_CTX
, mips32
);
763 if (retval
!= ERROR_OK
)
766 if (target
->state
!= TARGET_HALTED
) {
767 command_print(CMD_CTX
, "target must be stopped for \"%s\" command", CMD_NAME
);
771 /* two or more argument, access a single register/select (write if third argument is given) */
773 return ERROR_COMMAND_SYNTAX_ERROR
;
775 uint32_t cp0_reg
, cp0_sel
;
776 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], cp0_reg
);
777 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], cp0_sel
);
782 retval
= mips32_cp0_read(ejtag_info
, &value
, cp0_reg
, cp0_sel
);
783 if (retval
!= ERROR_OK
) {
784 command_print(CMD_CTX
,
785 "couldn't access reg %" PRIi32
,
789 command_print(CMD_CTX
, "cp0 reg %" PRIi32
", select %" PRIi32
": %8.8" PRIx32
,
790 cp0_reg
, cp0_sel
, value
);
792 } else if (CMD_ARGC
== 3) {
794 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], value
);
795 retval
= mips32_cp0_write(ejtag_info
, value
, cp0_reg
, cp0_sel
);
796 if (retval
!= ERROR_OK
) {
797 command_print(CMD_CTX
,
798 "couldn't access cp0 reg %" PRIi32
", select %" PRIi32
,
802 command_print(CMD_CTX
, "cp0 reg %" PRIi32
", select %" PRIi32
": %8.8" PRIx32
,
803 cp0_reg
, cp0_sel
, value
);
810 COMMAND_HANDLER(mips32_handle_scan_delay_command
)
812 struct target
*target
= get_current_target(CMD_CTX
);
813 struct mips32_common
*mips32
= target_to_mips32(target
);
814 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
817 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], ejtag_info
->scan_delay
);
818 else if (CMD_ARGC
> 1)
819 return ERROR_COMMAND_SYNTAX_ERROR
;
821 command_print(CMD_CTX
, "scan delay: %d nsec", ejtag_info
->scan_delay
);
822 if (ejtag_info
->scan_delay
>= 2000000) {
823 ejtag_info
->mode
= 0;
824 command_print(CMD_CTX
, "running in legacy mode");
826 ejtag_info
->mode
= 1;
827 command_print(CMD_CTX
, "running in fast queued mode");
833 static const struct command_registration mips32_exec_command_handlers
[] = {
836 .handler
= mips32_handle_cp0_command
,
837 .mode
= COMMAND_EXEC
,
838 .usage
= "regnum select [value]",
839 .help
= "display/modify cp0 register",
842 .name
= "scan_delay",
843 .handler
= mips32_handle_scan_delay_command
,
845 .help
= "display/set scan delay in nano seconds",
848 COMMAND_REGISTRATION_DONE
851 const struct command_registration mips32_command_handlers
[] = {
855 .help
= "mips32 command group",
857 .chain
= mips32_exec_command_handlers
,
859 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)