2 * MIPS64 generic target support
4 * Copyright (C) 2014 by Andrey Sidorov <anysidorov@gmail.com>
5 * Copyright (C) 2014 by Aleksey Kuleshov <rndfax@yandex.ru>
6 * Copyright (C) 2014-2019 by Peter Mamonov <pmamonov@gmail.com>
8 * Based on the work of:
9 * Copyright (C) 2008 by Spencer Oliver
10 * Copyright (C) 2008 by David T.L. Wong
12 * SPDX-License-Identifier: GPL-2.0-or-later
19 #if BUILD_TARGET64 == 1
21 #include "breakpoints.h"
24 #include "mips_mips64.h"
25 #include "target_type.h"
28 static int mips_mips64_unset_breakpoint(struct target
*target
,
29 struct breakpoint
*breakpoint
);
31 static uint64_t mips64_extend_sign(uint64_t addr
)
36 return addr
| (ULLONG_MAX
<< 32);
40 static int mips_mips64_examine_debug_reason(struct target
*target
)
42 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
43 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
44 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
49 static int mips_mips64_debug_entry(struct target
*target
)
51 struct mips64_common
*mips64
= target
->arch_info
;
52 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
53 struct reg
*pc
= &mips64
->core_cache
->reg_list
[MIPS64_PC
];
55 mips64_save_context(target
);
57 /* make sure stepping disabled, SSt bit in CP0 debug register cleared */
58 mips64_ejtag_config_step(ejtag_info
, 0);
60 /* make sure break unit configured */
61 mips64_configure_break_unit(target
);
63 /* attempt to find halt reason */
64 mips_mips64_examine_debug_reason(target
);
66 LOG_DEBUG("entered debug state at PC 0x%" PRIx64
", target->state: %s",
67 *(uint64_t *)pc
->value
, target_state_name(target
));
72 static int mips_mips64_poll(struct target
*target
)
75 struct mips64_common
*mips64
= target
->arch_info
;
76 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
77 uint32_t ejtag_ctrl
= ejtag_info
->ejtag_ctrl
;
79 /* read ejtag control reg */
80 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_CONTROL
);
81 mips_ejtag_drscan_32(ejtag_info
, &ejtag_ctrl
);
83 /* clear this bit before handling polling
84 * as after reset registers will read zero */
85 if (ejtag_ctrl
& EJTAG_CTRL_ROCC
) {
86 /* we have detected a reset, clear flag
87 * otherwise ejtag will not work */
88 ejtag_ctrl
= ejtag_info
->ejtag_ctrl
& ~EJTAG_CTRL_ROCC
;
90 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_CONTROL
);
91 mips_ejtag_drscan_32(ejtag_info
, &ejtag_ctrl
);
92 LOG_DEBUG("Reset Detected");
95 /* check for processor halted */
96 if (ejtag_ctrl
& EJTAG_CTRL_BRKST
) {
97 if ((target
->state
== TARGET_RUNNING
) || (target
->state
== TARGET_RESET
)) {
98 target
->state
= TARGET_HALTED
;
99 retval
= mips_mips64_debug_entry(target
);
100 if (retval
!= ERROR_OK
)
102 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
103 } else if (target
->state
== TARGET_DEBUG_RUNNING
) {
104 target
->state
= TARGET_HALTED
;
105 retval
= mips_mips64_debug_entry(target
);
106 if (retval
!= ERROR_OK
)
109 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
112 target
->state
= TARGET_RUNNING
;
118 static int mips_mips64_halt(struct target
*target
)
120 struct mips64_common
*mips64
= target
->arch_info
;
121 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
123 LOG_DEBUG("target->state: %s",
124 target_state_name(target
));
126 if (target
->state
== TARGET_HALTED
) {
127 LOG_DEBUG("target was already halted");
131 if (target
->state
== TARGET_UNKNOWN
)
132 LOG_WARNING("target was in unknown state when halt was requested");
134 if (target
->state
== TARGET_RESET
) {
135 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst()) {
136 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
137 return ERROR_TARGET_FAILURE
;
139 /* we came here in a reset_halt or reset_init sequence
140 * debug entry was already prepared in mips64_prepare_reset_halt()
142 target
->debug_reason
= DBG_REASON_DBGRQ
;
148 /* break processor */
149 mips_ejtag_enter_debug(ejtag_info
);
151 target
->debug_reason
= DBG_REASON_DBGRQ
;
156 static int mips_mips64_assert_reset(struct target
*target
)
158 struct mips64_common
*mips64
= target
->arch_info
;
159 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
162 LOG_DEBUG("target->state: %s",
163 target_state_name(target
));
165 enum reset_types jtag_reset_config
= jtag_get_reset_config();
166 if (!(jtag_reset_config
& RESET_HAS_SRST
)) {
167 LOG_ERROR("Can't assert SRST");
171 if (target
->reset_halt
)
172 /* use hardware to catch reset */
173 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_EJTAGBOOT
);
175 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_NORMALBOOT
);
177 /* here we should issue a srst only, but we may have to assert trst as well */
178 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
179 jtag_add_reset(1, 1);
181 jtag_add_reset(0, 1);
183 target
->state
= TARGET_RESET
;
184 jtag_add_sleep(5000);
186 retval
= mips64_invalidate_core_regs(target
);
187 if (retval
!= ERROR_OK
)
190 if (target
->reset_halt
) {
191 retval
= target_halt(target
);
192 if (retval
!= ERROR_OK
)
199 static int mips_mips64_deassert_reset(struct target
*target
)
201 LOG_DEBUG("target->state: %s",
202 target_state_name(target
));
204 /* deassert reset lines */
205 jtag_add_reset(0, 0);
210 static int mips_mips64_soft_reset_halt(struct target
*target
)
216 static int mips_mips64_single_step_core(struct target
*target
)
218 struct mips64_common
*mips64
= target
->arch_info
;
219 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
222 /* configure single step mode */
223 mips64_ejtag_config_step(ejtag_info
, 1);
225 /* disable interrupts while stepping */
226 retval
= mips64_enable_interrupts(target
, false);
227 if (retval
!= ERROR_OK
)
230 /* exit debug mode */
231 retval
= mips64_ejtag_exit_debug(ejtag_info
);
232 if (retval
!= ERROR_OK
)
235 mips_mips64_debug_entry(target
);
240 /* TODO: HW breakpoints are in EJTAG spec. Should we share it for MIPS32? */
241 static int mips_mips64_set_hwbp(struct target
*target
, struct breakpoint
*bp
)
243 struct mips64_common
*mips64
= target
->arch_info
;
244 struct mips64_comparator
*c
, *cl
= mips64
->inst_break_list
;
246 int retval
, bp_num
= 0;
248 while (cl
[bp_num
].used
&& (bp_num
< mips64
->num_inst_bpoints
))
251 if (bp_num
>= mips64
->num_inst_bpoints
) {
252 LOG_DEBUG("ERROR Can not find free FP Comparator(bpid: %d)",
254 LOG_WARNING("ERROR Can not find free FP Comparator");
260 c
->bp_value
= bp
->address
;
261 bp_value
= bp
->address
;
263 /* Instruction Breakpoint Address n (IBAn) Register */
264 retval
= target_write_u64(target
, c
->reg_address
, bp_value
);
265 if (retval
!= ERROR_OK
)
268 /* TODO: use defines */
269 /* Instruction Breakpoint Address Mask n (IBMn) Register */
270 retval
= target_write_u64(target
, c
->reg_address
+ 0x08, 0);
271 if (retval
!= ERROR_OK
)
274 /* Instruction Breakpoint Control n (IBCn) Register */
275 retval
= target_write_u64(target
, c
->reg_address
+ 0x18, 1);
276 if (retval
!= ERROR_OK
)
279 LOG_DEBUG("bpid: %d, bp_num %i bp_value 0x%" PRIx64
"", bp
->unique_id
,
280 bp_num
, c
->bp_value
);
285 /* TODO: is it MIPS64 or MIPS32 instruction. If MIPS32, can it be shared with
287 static int mips_mips64_set_sdbbp(struct target
*target
, struct breakpoint
*bp
)
292 retval
= target_read_memory(target
,
293 bp
->address
, bp
->length
, 1,
295 if (retval
!= ERROR_OK
)
298 retval
= target_write_u32(target
, bp
->address
, MIPS64_SDBBP
);
299 if (retval
!= ERROR_OK
)
302 retval
= target_read_u32(target
, bp
->address
, &verify
);
303 if (retval
!= ERROR_OK
)
306 if (verify
!= MIPS64_SDBBP
) {
307 LOG_ERROR("Unable to set 32bit breakpoint at address %16" PRIx64
,
315 /* TODO do MIPS64 support MIPS16 instructions? Can it be shared with MIPS32
317 static int mips_mips16_set_sdbbp(struct target
*target
, struct breakpoint
*bp
)
319 uint32_t isa_req
= bp
->length
& 1;
323 retval
= target_read_memory(target
,
324 bp
->address
, bp
->length
, 1,
326 if (retval
!= ERROR_OK
)
329 retval
= target_write_u16(target
, bp
->address
, MIPS16_SDBBP(isa_req
));
330 if (retval
!= ERROR_OK
)
333 retval
= target_read_u16(target
, bp
->address
, &verify
);
334 if (retval
!= ERROR_OK
)
337 if (verify
!= MIPS16_SDBBP(isa_req
)) {
338 LOG_ERROR("Unable to set 16bit breakpoint at address %16" PRIx64
,
346 static int mips_mips64_set_breakpoint(struct target
*target
,
347 struct breakpoint
*bp
)
352 LOG_WARNING("breakpoint already set");
356 if (bp
->type
== BKPT_HARD
) {
357 retval
= mips_mips64_set_hwbp(target
, bp
);
359 LOG_DEBUG("bpid: %d", bp
->unique_id
);
361 switch (bp
->length
) {
362 case MIPS64_SDBBP_SIZE
:
363 retval
= mips_mips64_set_sdbbp(target
, bp
);
365 case MIPS16_SDBBP_SIZE
:
366 retval
= mips_mips16_set_sdbbp(target
, bp
);
373 if (retval
!= ERROR_OK
) {
374 LOG_ERROR("can't unset breakpoint. Some thing wrong happened");
383 static int mips_mips64_enable_breakpoints(struct target
*target
)
385 struct breakpoint
*bp
= target
->breakpoints
;
386 int retval
= ERROR_OK
;
388 /* set any pending breakpoints */
391 retval
= mips_mips64_set_breakpoint(target
, bp
);
392 if (retval
!= ERROR_OK
)
401 /* TODO: HW data breakpoints are in EJTAG spec. Should we share it for MIPS32? */
402 static int mips_mips64_set_watchpoint(struct target
*target
,
403 struct watchpoint
*watchpoint
)
406 struct mips64_common
*mips64
= target
->arch_info
;
407 struct mips64_comparator
*c
, *cl
= mips64
->data_break_list
;
408 int retval
, wp_num
= 0;
411 * watchpoint enabled, ignore all byte lanes in value register
412 * and exclude both load and store accesses from watchpoint
413 * condition evaluation
415 int enable
= EJTAG_DBCn_NOSB
| EJTAG_DBCn_NOLB
| EJTAG_DBCn_BE
416 | (0xff << EJTAG_DBCn_BLM_SHIFT
);
418 if (watchpoint
->set
) {
419 LOG_WARNING("watchpoint already set");
423 while (cl
[wp_num
].used
&& (wp_num
< mips64
->num_data_bpoints
))
426 if (wp_num
>= mips64
->num_data_bpoints
) {
427 LOG_ERROR("ERROR Can not find free comparator");
428 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
431 if (watchpoint
->length
!= 4) {
432 LOG_ERROR("Only watchpoints of length 4 are supported");
433 return ERROR_TARGET_UNALIGNED_ACCESS
;
436 if (watchpoint
->address
% 4) {
437 LOG_ERROR("Watchpoints address should be word aligned");
438 return ERROR_TARGET_UNALIGNED_ACCESS
;
441 switch (watchpoint
->rw
) {
443 enable
&= ~EJTAG_DBCn_NOLB
;
446 enable
&= ~EJTAG_DBCn_NOSB
;
449 enable
&= ~(EJTAG_DBCn_NOLB
| EJTAG_DBCn_NOSB
);
452 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
456 watchpoint
->set
= wp_num
+ 1;
458 c
->bp_value
= watchpoint
->address
;
460 wp_value
= watchpoint
->address
;
461 if (wp_value
& 0x80000000)
462 wp_value
|= ULLONG_MAX
<< 32;
464 retval
= target_write_u64(target
, c
->reg_address
, wp_value
);
465 if (retval
!= ERROR_OK
)
468 retval
= target_write_u64(target
, c
->reg_address
+ 0x08, 0);
469 if (retval
!= ERROR_OK
)
472 retval
= target_write_u64(target
, c
->reg_address
+ 0x10, 0);
473 if (retval
!= ERROR_OK
)
476 retval
= target_write_u64(target
, c
->reg_address
+ 0x18, enable
);
477 if (retval
!= ERROR_OK
)
480 retval
= target_write_u64(target
, c
->reg_address
+ 0x20, 0);
481 if (retval
!= ERROR_OK
)
484 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx64
"", wp_num
, c
->bp_value
);
489 static int mips_mips64_enable_watchpoints(struct target
*target
)
491 struct watchpoint
*watchpoint
= target
->watchpoints
;
494 /* set any pending watchpoints */
496 if (watchpoint
->set
== 0) {
497 retval
= mips_mips64_set_watchpoint(target
, watchpoint
);
498 if (retval
!= ERROR_OK
)
501 watchpoint
= watchpoint
->next
;
507 static int mips_mips64_unset_hwbp(struct target
*target
, struct breakpoint
*bp
)
509 struct mips64_common
*mips64
= target
->arch_info
;
510 struct mips64_comparator
*comparator_list
= mips64
->inst_break_list
;
513 bp_num
= bp
->set
- 1;
515 if ((bp_num
< 0) || (bp_num
>= mips64
->num_inst_bpoints
)) {
516 LOG_DEBUG("Invalid FP Comparator number in breakpoint (bpid: %d)",
521 LOG_DEBUG("bpid: %d - releasing hw: %d", bp
->unique_id
, bp_num
);
522 comparator_list
[bp_num
].used
= false;
523 comparator_list
[bp_num
].bp_value
= 0;
525 return target_write_u64(target
,
526 comparator_list
[bp_num
].reg_address
+ 0x18, 0);
529 static int mips_mips64_unset_sdbbp(struct target
*target
, struct breakpoint
*bp
)
531 uint8_t buf
[MIPS64_SDBBP_SIZE
];
535 retval
= target_read_memory(target
, bp
->address
, MIPS64_SDBBP_SIZE
, 1,
537 if (retval
!= ERROR_OK
)
540 instr
= target_buffer_get_u32(target
, &buf
[0]);
541 if (instr
!= MIPS64_SDBBP
)
544 return target_write_memory(target
, bp
->address
, MIPS64_SDBBP_SIZE
, 1,
548 static int mips_mips16_unset_sdbbp(struct target
*target
, struct breakpoint
*bp
)
550 uint8_t buf
[MIPS16_SDBBP_SIZE
];
554 retval
= target_read_memory(target
, bp
->address
, MIPS16_SDBBP_SIZE
, 1,
556 if (retval
!= ERROR_OK
)
559 instr
= target_buffer_get_u16(target
, &buf
[0]);
560 if (instr
!= MIPS16_SDBBP(bp
->length
& 1))
563 return target_write_memory(target
, bp
->address
, MIPS16_SDBBP_SIZE
, 1,
567 static int mips_mips64_unset_breakpoint(struct target
*target
,
568 struct breakpoint
*bp
)
570 /* get pointers to arch-specific information */
574 LOG_WARNING("breakpoint not set");
578 if (bp
->type
== BKPT_HARD
) {
579 retval
= mips_mips64_unset_hwbp(target
, bp
);
581 LOG_DEBUG("bpid: %d", bp
->unique_id
);
583 switch (bp
->length
) {
584 case MIPS64_SDBBP_SIZE
:
585 retval
= mips_mips64_unset_sdbbp(target
, bp
);
587 case MIPS16_SDBBP_SIZE
:
588 retval
= mips_mips16_unset_sdbbp(target
, bp
);
594 if (retval
!= ERROR_OK
) {
595 LOG_ERROR("can't unset breakpoint. Some thing wrong happened");
604 static int mips_mips64_resume(struct target
*target
, int current
,
605 uint64_t address
, int handle_breakpoints
,
608 struct mips64_common
*mips64
= target
->arch_info
;
609 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
610 int retval
= ERROR_OK
;
614 if (mips64
->mips64mode32
)
615 address
= mips64_extend_sign(address
);
617 if (target
->state
!= TARGET_HALTED
) {
618 LOG_WARNING("target not halted %d", target
->state
);
619 return ERROR_TARGET_NOT_HALTED
;
622 if (!debug_execution
) {
623 target_free_all_working_areas(target
);
624 retval
= mips_mips64_enable_breakpoints(target
);
625 if (retval
!= ERROR_OK
)
628 retval
= mips_mips64_enable_watchpoints(target
);
629 if (retval
!= ERROR_OK
)
633 pc
= &mips64
->core_cache
->reg_list
[MIPS64_PC
];
634 /* current = 1: continue on current pc, otherwise continue at <address> */
636 buf_set_u64(pc
->value
, 0, 64, address
);
641 resume_pc
= buf_get_u64(pc
->value
, 0, 64);
643 retval
= mips64_restore_context(target
);
644 if (retval
!= ERROR_OK
)
647 /* the front-end may request us not to handle breakpoints */
648 if (handle_breakpoints
) {
649 struct breakpoint
*bp
;
651 /* Single step past breakpoint at current address */
652 bp
= breakpoint_find(target
, (uint64_t) resume_pc
);
654 LOG_DEBUG("unset breakpoint at 0x%16.16" PRIx64
"",
656 retval
= mips_mips64_unset_breakpoint(target
, bp
);
657 if (retval
!= ERROR_OK
)
660 retval
= mips_mips64_single_step_core(target
);
661 if (retval
!= ERROR_OK
)
664 retval
= mips_mips64_set_breakpoint(target
, bp
);
665 if (retval
!= ERROR_OK
)
670 /* enable interrupts if we are running */
671 retval
= mips64_enable_interrupts(target
, !debug_execution
);
672 if (retval
!= ERROR_OK
)
675 /* exit debug mode */
676 retval
= mips64_ejtag_exit_debug(ejtag_info
);
677 if (retval
!= ERROR_OK
)
680 target
->debug_reason
= DBG_REASON_NOTHALTED
;
682 /* registers are now invalid */
683 retval
= mips64_invalidate_core_regs(target
);
684 if (retval
!= ERROR_OK
)
687 if (!debug_execution
) {
688 target
->state
= TARGET_RUNNING
;
689 retval
= target_call_event_callbacks(target
,
690 TARGET_EVENT_RESUMED
);
691 if (retval
!= ERROR_OK
)
694 LOG_DEBUG("target resumed at 0x%" PRIx64
"", resume_pc
);
696 target
->state
= TARGET_DEBUG_RUNNING
;
697 retval
= target_call_event_callbacks(target
,
698 TARGET_EVENT_DEBUG_RESUMED
);
699 if (retval
!= ERROR_OK
)
702 LOG_DEBUG("target debug resumed at 0x%" PRIx64
"", resume_pc
);
708 static int mips_mips64_step(struct target
*target
, int current
,
709 uint64_t address
, int handle_breakpoints
)
711 struct mips64_common
*mips64
= target
->arch_info
;
712 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
713 struct reg
*pc
= &mips64
->core_cache
->reg_list
[MIPS64_PC
];
714 struct breakpoint
*bp
= NULL
;
715 int retval
= ERROR_OK
;
717 if (target
->state
!= TARGET_HALTED
) {
718 LOG_WARNING("target not halted");
719 return ERROR_TARGET_NOT_HALTED
;
722 if (mips64
->mips64mode32
)
723 address
= mips64_extend_sign(address
);
725 /* current = 1: continue on current pc, otherwise continue at
728 buf_set_u64(pc
->value
, 0, 64, address
);
733 /* the front-end may request us not to handle breakpoints */
734 if (handle_breakpoints
) {
735 bp
= breakpoint_find(target
, buf_get_u64(pc
->value
, 0, 64));
737 retval
= mips_mips64_unset_breakpoint(target
, bp
);
738 if (retval
!= ERROR_OK
)
743 retval
= mips64_restore_context(target
);
744 if (retval
!= ERROR_OK
)
747 /* configure single step mode */
748 retval
= mips64_ejtag_config_step(ejtag_info
, 1);
749 if (retval
!= ERROR_OK
)
752 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
754 retval
= target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
755 if (retval
!= ERROR_OK
)
758 /* disable interrupts while stepping */
759 retval
= mips64_enable_interrupts(target
, false);
760 if (retval
!= ERROR_OK
)
763 /* exit debug mode */
764 retval
= mips64_ejtag_exit_debug(ejtag_info
);
765 if (retval
!= ERROR_OK
)
768 /* registers are now invalid */
769 retval
= mips64_invalidate_core_regs(target
);
770 if (retval
!= ERROR_OK
)
774 retval
= mips_mips64_set_breakpoint(target
, bp
);
775 if (retval
!= ERROR_OK
)
779 LOG_DEBUG("target stepped ");
781 retval
= mips_mips64_debug_entry(target
);
782 if (retval
!= ERROR_OK
)
785 return target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
788 static int mips_mips64_add_breakpoint(struct target
*target
,
789 struct breakpoint
*bp
)
791 struct mips64_common
*mips64
= target
->arch_info
;
793 if (mips64
->mips64mode32
)
794 bp
->address
= mips64_extend_sign(bp
->address
);
796 if (bp
->type
== BKPT_HARD
) {
797 if (mips64
->num_inst_bpoints_avail
< 1) {
798 LOG_INFO("no hardware breakpoint available");
799 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
802 mips64
->num_inst_bpoints_avail
--;
805 return mips_mips64_set_breakpoint(target
, bp
);
808 static int mips_mips64_remove_breakpoint(struct target
*target
,
809 struct breakpoint
*bp
)
811 /* get pointers to arch-specific information */
812 struct mips64_common
*mips64
= target
->arch_info
;
813 int retval
= ERROR_OK
;
815 if (target
->state
!= TARGET_HALTED
) {
816 LOG_WARNING("target not halted");
817 return ERROR_TARGET_NOT_HALTED
;
821 retval
= mips_mips64_unset_breakpoint(target
, bp
);
823 if (bp
->type
== BKPT_HARD
)
824 mips64
->num_inst_bpoints_avail
++;
829 static int mips_mips64_unset_watchpoint(struct target
*target
,
830 struct watchpoint
*watchpoint
)
832 /* get pointers to arch-specific information */
833 struct mips64_common
*mips64
= target
->arch_info
;
834 struct mips64_comparator
*comparator_list
= mips64
->data_break_list
;
836 if (!watchpoint
->set
) {
837 LOG_WARNING("watchpoint not set");
841 int wp_num
= watchpoint
->set
- 1;
842 if ((wp_num
< 0) || (wp_num
>= mips64
->num_data_bpoints
)) {
843 LOG_DEBUG("Invalid FP Comparator number in watchpoint");
846 comparator_list
[wp_num
].used
= false;
847 comparator_list
[wp_num
].bp_value
= 0;
848 target_write_u64(target
, comparator_list
[wp_num
].reg_address
+ 0x18, 0);
854 static int mips_mips64_add_watchpoint(struct target
*target
,
855 struct watchpoint
*watchpoint
)
857 struct mips64_common
*mips64
= target
->arch_info
;
859 if (mips64
->num_data_bpoints_avail
< 1) {
860 LOG_INFO("no hardware watchpoints available");
861 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
864 mips64
->num_data_bpoints_avail
--;
866 return mips_mips64_set_watchpoint(target
, watchpoint
);
869 static int mips_mips64_remove_watchpoint(struct target
*target
,
870 struct watchpoint
*watchpoint
)
872 /* get pointers to arch-specific information */
873 struct mips64_common
*mips64
= target
->arch_info
;
874 int retval
= ERROR_OK
;
876 if (target
->state
!= TARGET_HALTED
) {
877 LOG_WARNING("target not halted");
878 return ERROR_TARGET_NOT_HALTED
;
882 retval
= mips_mips64_unset_watchpoint(target
, watchpoint
);
884 mips64
->num_data_bpoints_avail
++;
889 static int mips_mips64_read_memory(struct target
*target
, uint64_t address
,
890 uint32_t size
, uint32_t count
, uint8_t *buffer
)
892 struct mips64_common
*mips64
= target
->arch_info
;
893 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
897 if (target
->state
!= TARGET_HALTED
) {
898 LOG_WARNING("target not halted %d", target
->state
);
899 return ERROR_TARGET_NOT_HALTED
;
902 if (mips64
->mips64mode32
)
903 address
= mips64_extend_sign(address
);
905 /* sanitize arguments */
906 if (((size
!= 8) && (size
!= 4) && (size
!= 2) && (size
!= 1))
907 || !count
|| !buffer
)
908 return ERROR_COMMAND_ARGUMENT_INVALID
;
910 if (((size
== 8) && (address
& 0x7)) || ((size
== 4) && (address
& 0x3))
911 || ((size
== 2) && (address
& 0x1)))
912 return ERROR_TARGET_UNALIGNED_ACCESS
;
915 t
= calloc(count
, size
);
917 LOG_ERROR("Out of memory");
923 LOG_DEBUG("address: 0x%16.16" PRIx64
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
924 address
, size
, count
);
925 retval
= mips64_pracc_read_mem(ejtag_info
, address
, size
, count
,
928 if (ERROR_OK
!= retval
) {
929 LOG_ERROR("mips64_pracc_read_mem filed");
935 target_buffer_set_u64_array(target
, buffer
, count
, t
);
938 target_buffer_set_u32_array(target
, buffer
, count
, t
);
941 target_buffer_set_u16_array(target
, buffer
, count
, t
);
952 static int mips_mips64_bulk_write_memory(struct target
*target
,
953 target_addr_t address
, uint32_t count
,
954 const uint8_t *buffer
)
956 struct mips64_common
*mips64
= target
->arch_info
;
957 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
958 struct working_area
*fast_data_area
;
961 LOG_DEBUG("address: " TARGET_ADDR_FMT
", count: 0x%8.8" PRIx32
"",
965 return ERROR_TARGET_UNALIGNED_ACCESS
;
967 if (!mips64
->fast_data_area
) {
968 /* Get memory for block write handler
969 * we preserve this area between calls and gain a speed increase
970 * of about 3kb/sec when writing flash
971 * this will be released/nulled by the system when the target is resumed or reset */
972 retval
= target_alloc_working_area(target
,
973 MIPS64_FASTDATA_HANDLER_SIZE
,
974 &mips64
->fast_data_area
);
975 if (retval
!= ERROR_OK
) {
976 LOG_ERROR("No working area available");
980 /* reset fastadata state so the algo get reloaded */
981 ejtag_info
->fast_access_save
= -1;
984 fast_data_area
= mips64
->fast_data_area
;
986 if (address
<= fast_data_area
->address
+ fast_data_area
->size
&&
987 fast_data_area
->address
<= address
+ count
) {
988 LOG_ERROR("fast_data (" TARGET_ADDR_FMT
") is within write area "
989 "(" TARGET_ADDR_FMT
"-" TARGET_ADDR_FMT
").",
990 fast_data_area
->address
, address
, address
+ count
);
991 LOG_ERROR("Change work-area-phys or load_image address!");
995 /* mips32_pracc_fastdata_xfer requires uint32_t in host endianness, */
996 /* but byte array represents target endianness */
999 t
= calloc(count
, sizeof(uint64_t));
1001 LOG_ERROR("Out of memory");
1005 target_buffer_get_u64_array(target
, buffer
, count
, t
);
1007 retval
= mips64_pracc_fastdata_xfer(ejtag_info
, mips64
->fast_data_area
,
1008 true, address
, count
, t
);
1010 if (retval
!= ERROR_OK
)
1011 LOG_ERROR("Fastdata access Failed");
1018 static int mips_mips64_write_memory(struct target
*target
, uint64_t address
,
1019 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
1021 struct mips64_common
*mips64
= target
->arch_info
;
1022 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
1025 if (target
->state
!= TARGET_HALTED
) {
1026 LOG_WARNING("target not halted");
1027 return ERROR_TARGET_NOT_HALTED
;
1030 if (mips64
->mips64mode32
)
1031 address
= mips64_extend_sign(address
);
1033 /* sanitize arguments */
1034 if (((size
!= 8) && (size
!= 4) && (size
!= 2) && (size
!= 1))
1035 || !count
|| !buffer
)
1036 return ERROR_COMMAND_ARGUMENT_INVALID
;
1038 if (((size
== 8) && (address
& 0x7)) || ((size
== 4) && (address
& 0x3))
1039 || ((size
== 2) && (address
& 0x1)))
1040 return ERROR_TARGET_UNALIGNED_ACCESS
;
1044 if (size
== 8 && count
> 8) {
1045 retval
= mips_mips64_bulk_write_memory(target
, address
, count
,
1047 if (retval
== ERROR_OK
)
1050 LOG_WARNING("Falling back to non-bulk write");
1055 t
= calloc(count
, size
);
1057 LOG_ERROR("unable to allocate t for write buffer");
1063 target_buffer_get_u64_array(target
, buffer
, count
,
1067 target_buffer_get_u32_array(target
, buffer
, count
,
1071 target_buffer_get_u16_array(target
, buffer
, count
,
1078 LOG_DEBUG("address: 0x%16.16" PRIx64
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
1079 address
, size
, count
);
1081 retval
= mips64_pracc_write_mem(ejtag_info
, address
, size
, count
,
1088 static int mips_mips64_init_target(struct command_context
*cmd_ctx
,
1089 struct target
*target
)
1091 return mips64_build_reg_cache(target
);
1094 static int mips_mips64_target_create(struct target
*target
, Jim_Interp
*interp
)
1096 struct mips_mips64_common
*mips_mips64
;
1097 struct mips64_common
*mips64
;
1099 mips_mips64
= calloc(1, sizeof(*mips_mips64
));
1101 LOG_ERROR("unable to allocate mips_mips64");
1105 mips_mips64
->common_magic
= MIPS64_COMMON_MAGIC
;
1107 mips64
= &mips_mips64
->mips64_common
;
1108 mips64
->arch_info
= mips_mips64
;
1109 target
->arch_info
= mips64
;
1111 return mips64_init_arch_info(target
, mips64
, target
->tap
);
1114 static int mips_mips64_examine(struct target
*target
)
1117 struct mips64_common
*mips64
= target
->arch_info
;
1119 retval
= mips_ejtag_init(&mips64
->ejtag_info
);
1120 if (retval
!= ERROR_OK
)
1123 return mips64_examine(target
);
1126 static int mips_mips64_checksum_memory(struct target
*target
, uint64_t address
,
1127 uint32_t size
, uint32_t *checksum
)
1129 return ERROR_FAIL
; /* use bulk read method */
1132 COMMAND_HANDLER(handle_mips64mode32
)
1134 struct target
*target
= get_current_target(CMD_CTX
);
1135 struct mips64_common
*mips64
= target
->arch_info
;
1138 COMMAND_PARSE_BOOL(CMD_ARGV
[0], mips64
->mips64mode32
, "on", "off");
1140 if (mips64
->mips64mode32
)
1141 command_print(CMD
, "enabled");
1143 command_print(CMD
, "disabled");
1149 static const struct command_registration mips64_commands_handlers
[] = {
1151 .name
= "mips64mode32",
1152 .mode
= COMMAND_EXEC
,
1153 .help
= "Enable/disable 32 bit mode",
1155 .handler
= handle_mips64mode32
1157 COMMAND_REGISTRATION_DONE
1160 struct target_type mips_mips64_target
= {
1161 .name
= "mips_mips64",
1163 .poll
= mips_mips64_poll
,
1164 .arch_state
= mips64_arch_state
,
1166 .target_request_data
= NULL
,
1168 .halt
= mips_mips64_halt
,
1169 .resume
= mips_mips64_resume
,
1170 .step
= mips_mips64_step
,
1172 .assert_reset
= mips_mips64_assert_reset
,
1173 .deassert_reset
= mips_mips64_deassert_reset
,
1174 .soft_reset_halt
= mips_mips64_soft_reset_halt
,
1176 .get_gdb_reg_list
= mips64_get_gdb_reg_list
,
1178 .read_memory
= mips_mips64_read_memory
,
1179 .write_memory
= mips_mips64_write_memory
,
1180 .checksum_memory
= mips_mips64_checksum_memory
,
1181 .blank_check_memory
= NULL
,
1183 .run_algorithm
= mips64_run_algorithm
,
1185 .add_breakpoint
= mips_mips64_add_breakpoint
,
1186 .remove_breakpoint
= mips_mips64_remove_breakpoint
,
1187 .add_watchpoint
= mips_mips64_add_watchpoint
,
1188 .remove_watchpoint
= mips_mips64_remove_watchpoint
,
1190 .target_create
= mips_mips64_target_create
,
1191 .init_target
= mips_mips64_init_target
,
1192 .examine
= mips_mips64_examine
,
1194 .commands
= mips64_commands_handlers
,
1197 #endif /* BUILD_TARGET64 */
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)