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 #include "breakpoints.h"
22 #include "mips_mips64.h"
23 #include "target_type.h"
26 static int mips_mips64_unset_breakpoint(struct target
*target
,
27 struct breakpoint
*breakpoint
);
29 static uint64_t mips64_extend_sign(uint64_t addr
)
34 return addr
| (ULLONG_MAX
<< 32);
38 static int mips_mips64_examine_debug_reason(struct target
*target
)
40 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
41 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
42 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
47 static int mips_mips64_debug_entry(struct target
*target
)
49 struct mips64_common
*mips64
= target
->arch_info
;
50 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
51 struct reg
*pc
= &mips64
->core_cache
->reg_list
[MIPS64_PC
];
53 mips64_save_context(target
);
55 /* make sure stepping disabled, SSt bit in CP0 debug register cleared */
56 mips64_ejtag_config_step(ejtag_info
, 0);
58 /* make sure break unit configured */
59 mips64_configure_break_unit(target
);
61 /* attempt to find halt reason */
62 mips_mips64_examine_debug_reason(target
);
64 LOG_DEBUG("entered debug state at PC 0x%" PRIx64
", target->state: %s",
65 buf_get_u64(pc
->value
, 0, 64), target_state_name(target
));
70 static int mips_mips64_poll(struct target
*target
)
73 struct mips64_common
*mips64
= target
->arch_info
;
74 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
75 uint32_t ejtag_ctrl
= ejtag_info
->ejtag_ctrl
;
77 /* read ejtag control reg */
78 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_CONTROL
);
79 mips_ejtag_drscan_32(ejtag_info
, &ejtag_ctrl
);
81 /* clear this bit before handling polling
82 * as after reset registers will read zero */
83 if (ejtag_ctrl
& EJTAG_CTRL_ROCC
) {
84 /* we have detected a reset, clear flag
85 * otherwise ejtag will not work */
86 ejtag_ctrl
= ejtag_info
->ejtag_ctrl
& ~EJTAG_CTRL_ROCC
;
88 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_CONTROL
);
89 mips_ejtag_drscan_32(ejtag_info
, &ejtag_ctrl
);
90 LOG_DEBUG("Reset Detected");
93 /* check for processor halted */
94 if (ejtag_ctrl
& EJTAG_CTRL_BRKST
) {
95 if ((target
->state
== TARGET_RUNNING
) || (target
->state
== TARGET_RESET
)) {
96 target
->state
= TARGET_HALTED
;
97 retval
= mips_mips64_debug_entry(target
);
98 if (retval
!= ERROR_OK
)
100 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
101 } else if (target
->state
== TARGET_DEBUG_RUNNING
) {
102 target
->state
= TARGET_HALTED
;
103 retval
= mips_mips64_debug_entry(target
);
104 if (retval
!= ERROR_OK
)
107 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
110 target
->state
= TARGET_RUNNING
;
116 static int mips_mips64_halt(struct target
*target
)
118 struct mips64_common
*mips64
= target
->arch_info
;
119 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
121 LOG_DEBUG("target->state: %s",
122 target_state_name(target
));
124 if (target
->state
== TARGET_HALTED
) {
125 LOG_DEBUG("target was already halted");
129 if (target
->state
== TARGET_UNKNOWN
)
130 LOG_WARNING("target was in unknown state when halt was requested");
132 if (target
->state
== TARGET_RESET
) {
133 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst()) {
134 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
135 return ERROR_TARGET_FAILURE
;
137 /* we came here in a reset_halt or reset_init sequence
138 * debug entry was already prepared in mips64_prepare_reset_halt()
140 target
->debug_reason
= DBG_REASON_DBGRQ
;
146 /* break processor */
147 mips_ejtag_enter_debug(ejtag_info
);
149 target
->debug_reason
= DBG_REASON_DBGRQ
;
154 static int mips_mips64_assert_reset(struct target
*target
)
156 struct mips64_common
*mips64
= target
->arch_info
;
157 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
160 LOG_DEBUG("target->state: %s",
161 target_state_name(target
));
163 enum reset_types jtag_reset_config
= jtag_get_reset_config();
164 if (!(jtag_reset_config
& RESET_HAS_SRST
)) {
165 LOG_ERROR("Can't assert SRST");
169 if (target
->reset_halt
)
170 /* use hardware to catch reset */
171 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_EJTAGBOOT
);
173 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_NORMALBOOT
);
175 /* here we should issue a srst only, but we may have to assert trst as well */
176 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
177 jtag_add_reset(1, 1);
179 jtag_add_reset(0, 1);
181 target
->state
= TARGET_RESET
;
182 jtag_add_sleep(5000);
184 retval
= mips64_invalidate_core_regs(target
);
185 if (retval
!= ERROR_OK
)
188 if (target
->reset_halt
) {
189 retval
= target_halt(target
);
190 if (retval
!= ERROR_OK
)
197 static int mips_mips64_deassert_reset(struct target
*target
)
199 LOG_DEBUG("target->state: %s",
200 target_state_name(target
));
202 /* deassert reset lines */
203 jtag_add_reset(0, 0);
208 static int mips_mips64_soft_reset_halt(struct target
*target
)
214 static int mips_mips64_single_step_core(struct target
*target
)
216 struct mips64_common
*mips64
= target
->arch_info
;
217 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
220 /* configure single step mode */
221 mips64_ejtag_config_step(ejtag_info
, 1);
223 /* disable interrupts while stepping */
224 retval
= mips64_enable_interrupts(target
, false);
225 if (retval
!= ERROR_OK
)
228 /* exit debug mode */
229 retval
= mips64_ejtag_exit_debug(ejtag_info
);
230 if (retval
!= ERROR_OK
)
233 mips_mips64_debug_entry(target
);
238 /* TODO: HW breakpoints are in EJTAG spec. Should we share it for MIPS32? */
239 static int mips_mips64_set_hwbp(struct target
*target
, struct breakpoint
*bp
)
241 struct mips64_common
*mips64
= target
->arch_info
;
242 struct mips64_comparator
*c
, *cl
= mips64
->inst_break_list
;
244 int retval
, bp_num
= 0;
246 while (cl
[bp_num
].used
&& (bp_num
< mips64
->num_inst_bpoints
))
249 if (bp_num
>= mips64
->num_inst_bpoints
) {
250 LOG_DEBUG("ERROR Can not find free FP Comparator(bpid: %" PRIu32
")",
252 LOG_WARNING("ERROR Can not find free FP Comparator");
258 c
->bp_value
= bp
->address
;
259 bp_value
= bp
->address
;
261 /* Instruction Breakpoint Address n (IBAn) Register */
262 retval
= target_write_u64(target
, c
->reg_address
, bp_value
);
263 if (retval
!= ERROR_OK
)
266 /* TODO: use defines */
267 /* Instruction Breakpoint Address Mask n (IBMn) Register */
268 retval
= target_write_u64(target
, c
->reg_address
+ 0x08, 0);
269 if (retval
!= ERROR_OK
)
272 /* Instruction Breakpoint Control n (IBCn) Register */
273 retval
= target_write_u64(target
, c
->reg_address
+ 0x18, 1);
274 if (retval
!= ERROR_OK
)
277 LOG_DEBUG("bpid: %" PRIu32
", bp_num %i bp_value 0x%" PRIx64
, bp
->unique_id
,
278 bp_num
, c
->bp_value
);
283 /* TODO: is it MIPS64 or MIPS32 instruction. If MIPS32, can it be shared with
285 static int mips_mips64_set_sdbbp(struct target
*target
, struct breakpoint
*bp
)
290 retval
= target_read_memory(target
,
291 bp
->address
, bp
->length
, 1,
293 if (retval
!= ERROR_OK
)
296 retval
= target_write_u32(target
, bp
->address
, MIPS64_SDBBP
);
297 if (retval
!= ERROR_OK
)
300 retval
= target_read_u32(target
, bp
->address
, &verify
);
301 if (retval
!= ERROR_OK
)
304 if (verify
!= MIPS64_SDBBP
) {
305 LOG_ERROR("Unable to set 32bit breakpoint at address %16" PRIx64
,
313 /* TODO do MIPS64 support MIPS16 instructions? Can it be shared with MIPS32
315 static int mips_mips16_set_sdbbp(struct target
*target
, struct breakpoint
*bp
)
317 uint32_t isa_req
= bp
->length
& 1;
321 retval
= target_read_memory(target
,
322 bp
->address
, bp
->length
, 1,
324 if (retval
!= ERROR_OK
)
327 retval
= target_write_u16(target
, bp
->address
, MIPS16_SDBBP(isa_req
));
328 if (retval
!= ERROR_OK
)
331 retval
= target_read_u16(target
, bp
->address
, &verify
);
332 if (retval
!= ERROR_OK
)
335 if (verify
!= MIPS16_SDBBP(isa_req
)) {
336 LOG_ERROR("Unable to set 16bit breakpoint at address %16" PRIx64
,
344 static int mips_mips64_set_breakpoint(struct target
*target
,
345 struct breakpoint
*bp
)
350 LOG_WARNING("breakpoint already set");
354 if (bp
->type
== BKPT_HARD
) {
355 retval
= mips_mips64_set_hwbp(target
, bp
);
357 LOG_DEBUG("bpid: %" PRIu32
, bp
->unique_id
);
359 switch (bp
->length
) {
360 case MIPS64_SDBBP_SIZE
:
361 retval
= mips_mips64_set_sdbbp(target
, bp
);
363 case MIPS16_SDBBP_SIZE
:
364 retval
= mips_mips16_set_sdbbp(target
, bp
);
371 if (retval
!= ERROR_OK
) {
372 LOG_ERROR("can't unset breakpoint. Some thing wrong happened");
381 static int mips_mips64_enable_breakpoints(struct target
*target
)
383 struct breakpoint
*bp
= target
->breakpoints
;
384 int retval
= ERROR_OK
;
386 /* set any pending breakpoints */
389 retval
= mips_mips64_set_breakpoint(target
, bp
);
390 if (retval
!= ERROR_OK
)
399 /* TODO: HW data breakpoints are in EJTAG spec. Should we share it for MIPS32? */
400 static int mips_mips64_set_watchpoint(struct target
*target
,
401 struct watchpoint
*watchpoint
)
404 struct mips64_common
*mips64
= target
->arch_info
;
405 struct mips64_comparator
*c
, *cl
= mips64
->data_break_list
;
406 int retval
, wp_num
= 0;
409 * watchpoint enabled, ignore all byte lanes in value register
410 * and exclude both load and store accesses from watchpoint
411 * condition evaluation
413 int enable
= EJTAG_DBCN_NOSB
| EJTAG_DBCN_NOLB
| EJTAG_DBCN_BE
414 | (0xff << EJTAG_DBCN_BLM_SHIFT
);
416 if (watchpoint
->is_set
) {
417 LOG_WARNING("watchpoint already set");
421 while (cl
[wp_num
].used
&& (wp_num
< mips64
->num_data_bpoints
))
424 if (wp_num
>= mips64
->num_data_bpoints
) {
425 LOG_ERROR("ERROR Can not find free comparator");
426 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
429 if (watchpoint
->length
!= 4) {
430 LOG_ERROR("Only watchpoints of length 4 are supported");
431 return ERROR_TARGET_UNALIGNED_ACCESS
;
434 if (watchpoint
->address
% 4) {
435 LOG_ERROR("Watchpoints address should be word aligned");
436 return ERROR_TARGET_UNALIGNED_ACCESS
;
439 switch (watchpoint
->rw
) {
441 enable
&= ~EJTAG_DBCN_NOLB
;
444 enable
&= ~EJTAG_DBCN_NOSB
;
447 enable
&= ~(EJTAG_DBCN_NOLB
| EJTAG_DBCN_NOSB
);
450 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
454 watchpoint_set(watchpoint
, wp_num
);
456 c
->bp_value
= watchpoint
->address
;
458 wp_value
= watchpoint
->address
;
459 if (wp_value
& 0x80000000)
460 wp_value
|= ULLONG_MAX
<< 32;
462 retval
= target_write_u64(target
, c
->reg_address
, wp_value
);
463 if (retval
!= ERROR_OK
)
466 retval
= target_write_u64(target
, c
->reg_address
+ 0x08, 0);
467 if (retval
!= ERROR_OK
)
470 retval
= target_write_u64(target
, c
->reg_address
+ 0x10, 0);
471 if (retval
!= ERROR_OK
)
474 retval
= target_write_u64(target
, c
->reg_address
+ 0x18, enable
);
475 if (retval
!= ERROR_OK
)
478 retval
= target_write_u64(target
, c
->reg_address
+ 0x20, 0);
479 if (retval
!= ERROR_OK
)
482 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx64
"", wp_num
, c
->bp_value
);
487 static int mips_mips64_enable_watchpoints(struct target
*target
)
489 struct watchpoint
*watchpoint
= target
->watchpoints
;
492 /* set any pending watchpoints */
494 if (!watchpoint
->is_set
) {
495 retval
= mips_mips64_set_watchpoint(target
, watchpoint
);
496 if (retval
!= ERROR_OK
)
499 watchpoint
= watchpoint
->next
;
505 static int mips_mips64_unset_hwbp(struct target
*target
, struct breakpoint
*bp
)
507 struct mips64_common
*mips64
= target
->arch_info
;
508 struct mips64_comparator
*comparator_list
= mips64
->inst_break_list
;
510 int bp_num
= bp
->number
;
512 if (bp_num
>= mips64
->num_inst_bpoints
) {
513 LOG_DEBUG("Invalid FP Comparator number in breakpoint (bpid: %" PRIu32
")",
518 LOG_DEBUG("bpid: %" PRIu32
" - releasing hw: %d", bp
->unique_id
, bp_num
);
519 comparator_list
[bp_num
].used
= false;
520 comparator_list
[bp_num
].bp_value
= 0;
522 return target_write_u64(target
,
523 comparator_list
[bp_num
].reg_address
+ 0x18, 0);
526 static int mips_mips64_unset_sdbbp(struct target
*target
, struct breakpoint
*bp
)
528 uint8_t buf
[MIPS64_SDBBP_SIZE
];
532 retval
= target_read_memory(target
, bp
->address
, MIPS64_SDBBP_SIZE
, 1,
534 if (retval
!= ERROR_OK
)
537 instr
= target_buffer_get_u32(target
, &buf
[0]);
538 if (instr
!= MIPS64_SDBBP
)
541 return target_write_memory(target
, bp
->address
, MIPS64_SDBBP_SIZE
, 1,
545 static int mips_mips16_unset_sdbbp(struct target
*target
, struct breakpoint
*bp
)
547 uint8_t buf
[MIPS16_SDBBP_SIZE
];
551 retval
= target_read_memory(target
, bp
->address
, MIPS16_SDBBP_SIZE
, 1,
553 if (retval
!= ERROR_OK
)
556 instr
= target_buffer_get_u16(target
, &buf
[0]);
557 if (instr
!= MIPS16_SDBBP(bp
->length
& 1))
560 return target_write_memory(target
, bp
->address
, MIPS16_SDBBP_SIZE
, 1,
564 static int mips_mips64_unset_breakpoint(struct target
*target
,
565 struct breakpoint
*bp
)
567 /* get pointers to arch-specific information */
571 LOG_WARNING("breakpoint not set");
575 if (bp
->type
== BKPT_HARD
) {
576 retval
= mips_mips64_unset_hwbp(target
, bp
);
578 LOG_DEBUG("bpid: %" PRIu32
, bp
->unique_id
);
580 switch (bp
->length
) {
581 case MIPS64_SDBBP_SIZE
:
582 retval
= mips_mips64_unset_sdbbp(target
, bp
);
584 case MIPS16_SDBBP_SIZE
:
585 retval
= mips_mips16_unset_sdbbp(target
, bp
);
591 if (retval
!= ERROR_OK
) {
592 LOG_ERROR("can't unset breakpoint. Some thing wrong happened");
601 static int mips_mips64_resume(struct target
*target
, int current
,
602 uint64_t address
, int handle_breakpoints
,
605 struct mips64_common
*mips64
= target
->arch_info
;
606 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
607 int retval
= ERROR_OK
;
611 if (mips64
->mips64mode32
)
612 address
= mips64_extend_sign(address
);
614 if (target
->state
!= TARGET_HALTED
) {
615 LOG_WARNING("target not halted %d", target
->state
);
616 return ERROR_TARGET_NOT_HALTED
;
619 if (!debug_execution
) {
620 target_free_all_working_areas(target
);
621 retval
= mips_mips64_enable_breakpoints(target
);
622 if (retval
!= ERROR_OK
)
625 retval
= mips_mips64_enable_watchpoints(target
);
626 if (retval
!= ERROR_OK
)
630 pc
= &mips64
->core_cache
->reg_list
[MIPS64_PC
];
631 /* current = 1: continue on current pc, otherwise continue at <address> */
633 buf_set_u64(pc
->value
, 0, 64, address
);
638 resume_pc
= buf_get_u64(pc
->value
, 0, 64);
640 retval
= mips64_restore_context(target
);
641 if (retval
!= ERROR_OK
)
644 /* the front-end may request us not to handle breakpoints */
645 if (handle_breakpoints
) {
646 struct breakpoint
*bp
;
648 /* Single step past breakpoint at current address */
649 bp
= breakpoint_find(target
, (uint64_t) resume_pc
);
651 LOG_DEBUG("unset breakpoint at 0x%16.16" PRIx64
"",
653 retval
= mips_mips64_unset_breakpoint(target
, bp
);
654 if (retval
!= ERROR_OK
)
657 retval
= mips_mips64_single_step_core(target
);
658 if (retval
!= ERROR_OK
)
661 retval
= mips_mips64_set_breakpoint(target
, bp
);
662 if (retval
!= ERROR_OK
)
667 /* enable interrupts if we are running */
668 retval
= mips64_enable_interrupts(target
, !debug_execution
);
669 if (retval
!= ERROR_OK
)
672 /* exit debug mode */
673 retval
= mips64_ejtag_exit_debug(ejtag_info
);
674 if (retval
!= ERROR_OK
)
677 target
->debug_reason
= DBG_REASON_NOTHALTED
;
679 /* registers are now invalid */
680 retval
= mips64_invalidate_core_regs(target
);
681 if (retval
!= ERROR_OK
)
684 if (!debug_execution
) {
685 target
->state
= TARGET_RUNNING
;
686 retval
= target_call_event_callbacks(target
,
687 TARGET_EVENT_RESUMED
);
688 if (retval
!= ERROR_OK
)
691 LOG_DEBUG("target resumed at 0x%" PRIx64
"", resume_pc
);
693 target
->state
= TARGET_DEBUG_RUNNING
;
694 retval
= target_call_event_callbacks(target
,
695 TARGET_EVENT_DEBUG_RESUMED
);
696 if (retval
!= ERROR_OK
)
699 LOG_DEBUG("target debug resumed at 0x%" PRIx64
"", resume_pc
);
705 static int mips_mips64_step(struct target
*target
, int current
,
706 uint64_t address
, int handle_breakpoints
)
708 struct mips64_common
*mips64
= target
->arch_info
;
709 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
710 struct reg
*pc
= &mips64
->core_cache
->reg_list
[MIPS64_PC
];
711 struct breakpoint
*bp
= NULL
;
712 int retval
= ERROR_OK
;
714 if (target
->state
!= TARGET_HALTED
) {
715 LOG_WARNING("target not halted");
716 return ERROR_TARGET_NOT_HALTED
;
719 if (mips64
->mips64mode32
)
720 address
= mips64_extend_sign(address
);
722 /* current = 1: continue on current pc, otherwise continue at
725 buf_set_u64(pc
->value
, 0, 64, address
);
730 /* the front-end may request us not to handle breakpoints */
731 if (handle_breakpoints
) {
732 bp
= breakpoint_find(target
, buf_get_u64(pc
->value
, 0, 64));
734 retval
= mips_mips64_unset_breakpoint(target
, bp
);
735 if (retval
!= ERROR_OK
)
740 retval
= mips64_restore_context(target
);
741 if (retval
!= ERROR_OK
)
744 /* configure single step mode */
745 retval
= mips64_ejtag_config_step(ejtag_info
, 1);
746 if (retval
!= ERROR_OK
)
749 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
751 retval
= target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
752 if (retval
!= ERROR_OK
)
755 /* disable interrupts while stepping */
756 retval
= mips64_enable_interrupts(target
, false);
757 if (retval
!= ERROR_OK
)
760 /* exit debug mode */
761 retval
= mips64_ejtag_exit_debug(ejtag_info
);
762 if (retval
!= ERROR_OK
)
765 /* registers are now invalid */
766 retval
= mips64_invalidate_core_regs(target
);
767 if (retval
!= ERROR_OK
)
771 retval
= mips_mips64_set_breakpoint(target
, bp
);
772 if (retval
!= ERROR_OK
)
776 LOG_DEBUG("target stepped ");
778 retval
= mips_mips64_debug_entry(target
);
779 if (retval
!= ERROR_OK
)
782 return target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
785 static int mips_mips64_add_breakpoint(struct target
*target
,
786 struct breakpoint
*bp
)
788 struct mips64_common
*mips64
= target
->arch_info
;
790 if (mips64
->mips64mode32
)
791 bp
->address
= mips64_extend_sign(bp
->address
);
793 if (bp
->type
== BKPT_HARD
) {
794 if (mips64
->num_inst_bpoints_avail
< 1) {
795 LOG_INFO("no hardware breakpoint available");
796 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
799 mips64
->num_inst_bpoints_avail
--;
802 return mips_mips64_set_breakpoint(target
, bp
);
805 static int mips_mips64_remove_breakpoint(struct target
*target
,
806 struct breakpoint
*bp
)
808 /* get pointers to arch-specific information */
809 struct mips64_common
*mips64
= target
->arch_info
;
810 int retval
= ERROR_OK
;
812 if (target
->state
!= TARGET_HALTED
) {
813 LOG_WARNING("target not halted");
814 return ERROR_TARGET_NOT_HALTED
;
818 retval
= mips_mips64_unset_breakpoint(target
, bp
);
820 if (bp
->type
== BKPT_HARD
)
821 mips64
->num_inst_bpoints_avail
++;
826 static int mips_mips64_unset_watchpoint(struct target
*target
,
827 struct watchpoint
*watchpoint
)
829 /* get pointers to arch-specific information */
830 struct mips64_common
*mips64
= target
->arch_info
;
831 struct mips64_comparator
*comparator_list
= mips64
->data_break_list
;
833 if (!watchpoint
->is_set
) {
834 LOG_WARNING("watchpoint not set");
838 int wp_num
= watchpoint
->number
;
839 if (wp_num
>= mips64
->num_data_bpoints
) {
840 LOG_DEBUG("Invalid FP Comparator number in watchpoint");
843 comparator_list
[wp_num
].used
= false;
844 comparator_list
[wp_num
].bp_value
= 0;
845 target_write_u64(target
, comparator_list
[wp_num
].reg_address
+ 0x18, 0);
846 watchpoint
->is_set
= false;
851 static int mips_mips64_add_watchpoint(struct target
*target
,
852 struct watchpoint
*watchpoint
)
854 struct mips64_common
*mips64
= target
->arch_info
;
856 if (mips64
->num_data_bpoints_avail
< 1) {
857 LOG_INFO("no hardware watchpoints available");
858 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
861 mips64
->num_data_bpoints_avail
--;
863 return mips_mips64_set_watchpoint(target
, watchpoint
);
866 static int mips_mips64_remove_watchpoint(struct target
*target
,
867 struct watchpoint
*watchpoint
)
869 /* get pointers to arch-specific information */
870 struct mips64_common
*mips64
= target
->arch_info
;
871 int retval
= ERROR_OK
;
873 if (target
->state
!= TARGET_HALTED
) {
874 LOG_WARNING("target not halted");
875 return ERROR_TARGET_NOT_HALTED
;
878 if (watchpoint
->is_set
)
879 retval
= mips_mips64_unset_watchpoint(target
, watchpoint
);
881 mips64
->num_data_bpoints_avail
++;
886 static int mips_mips64_read_memory(struct target
*target
, uint64_t address
,
887 uint32_t size
, uint32_t count
, uint8_t *buffer
)
889 struct mips64_common
*mips64
= target
->arch_info
;
890 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
894 if (target
->state
!= TARGET_HALTED
) {
895 LOG_WARNING("target not halted %d", target
->state
);
896 return ERROR_TARGET_NOT_HALTED
;
899 if (mips64
->mips64mode32
)
900 address
= mips64_extend_sign(address
);
902 /* sanitize arguments */
903 if (((size
!= 8) && (size
!= 4) && (size
!= 2) && (size
!= 1))
904 || !count
|| !buffer
)
905 return ERROR_COMMAND_ARGUMENT_INVALID
;
907 if (((size
== 8) && (address
& 0x7)) || ((size
== 4) && (address
& 0x3))
908 || ((size
== 2) && (address
& 0x1)))
909 return ERROR_TARGET_UNALIGNED_ACCESS
;
912 t
= calloc(count
, size
);
914 LOG_ERROR("Out of memory");
920 LOG_DEBUG("address: 0x%16.16" PRIx64
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
921 address
, size
, count
);
922 retval
= mips64_pracc_read_mem(ejtag_info
, address
, size
, count
,
925 if (retval
!= ERROR_OK
) {
926 LOG_ERROR("mips64_pracc_read_mem filed");
932 target_buffer_set_u64_array(target
, buffer
, count
, t
);
935 target_buffer_set_u32_array(target
, buffer
, count
, t
);
938 target_buffer_set_u16_array(target
, buffer
, count
, t
);
949 static int mips_mips64_bulk_write_memory(struct target
*target
,
950 target_addr_t address
, uint32_t count
,
951 const uint8_t *buffer
)
953 struct mips64_common
*mips64
= target
->arch_info
;
954 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
955 struct working_area
*fast_data_area
;
958 LOG_DEBUG("address: " TARGET_ADDR_FMT
", count: 0x%8.8" PRIx32
"",
962 return ERROR_TARGET_UNALIGNED_ACCESS
;
964 if (!mips64
->fast_data_area
) {
965 /* Get memory for block write handler
966 * we preserve this area between calls and gain a speed increase
967 * of about 3kb/sec when writing flash
968 * this will be released/nulled by the system when the target is resumed or reset */
969 retval
= target_alloc_working_area(target
,
970 MIPS64_FASTDATA_HANDLER_SIZE
,
971 &mips64
->fast_data_area
);
972 if (retval
!= ERROR_OK
) {
973 LOG_ERROR("No working area available");
977 /* reset fastadata state so the algo get reloaded */
978 ejtag_info
->fast_access_save
= -1;
981 fast_data_area
= mips64
->fast_data_area
;
983 if (address
<= fast_data_area
->address
+ fast_data_area
->size
&&
984 fast_data_area
->address
<= address
+ count
) {
985 LOG_ERROR("fast_data (" TARGET_ADDR_FMT
") is within write area "
986 "(" TARGET_ADDR_FMT
"-" TARGET_ADDR_FMT
").",
987 fast_data_area
->address
, address
, address
+ count
);
988 LOG_ERROR("Change work-area-phys or load_image address!");
992 /* mips32_pracc_fastdata_xfer requires uint32_t in host endianness, */
993 /* but byte array represents target endianness */
996 t
= calloc(count
, sizeof(uint64_t));
998 LOG_ERROR("Out of memory");
1002 target_buffer_get_u64_array(target
, buffer
, count
, t
);
1004 retval
= mips64_pracc_fastdata_xfer(ejtag_info
, mips64
->fast_data_area
,
1005 true, address
, count
, t
);
1007 if (retval
!= ERROR_OK
)
1008 LOG_ERROR("Fastdata access Failed");
1015 static int mips_mips64_write_memory(struct target
*target
, uint64_t address
,
1016 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
1018 struct mips64_common
*mips64
= target
->arch_info
;
1019 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
1022 if (target
->state
!= TARGET_HALTED
) {
1023 LOG_WARNING("target not halted");
1024 return ERROR_TARGET_NOT_HALTED
;
1027 if (mips64
->mips64mode32
)
1028 address
= mips64_extend_sign(address
);
1030 /* sanitize arguments */
1031 if (((size
!= 8) && (size
!= 4) && (size
!= 2) && (size
!= 1))
1032 || !count
|| !buffer
)
1033 return ERROR_COMMAND_ARGUMENT_INVALID
;
1035 if (((size
== 8) && (address
& 0x7)) || ((size
== 4) && (address
& 0x3))
1036 || ((size
== 2) && (address
& 0x1)))
1037 return ERROR_TARGET_UNALIGNED_ACCESS
;
1041 if (size
== 8 && count
> 8) {
1042 retval
= mips_mips64_bulk_write_memory(target
, address
, count
,
1044 if (retval
== ERROR_OK
)
1047 LOG_WARNING("Falling back to non-bulk write");
1052 t
= calloc(count
, size
);
1054 LOG_ERROR("unable to allocate t for write buffer");
1060 target_buffer_get_u64_array(target
, buffer
, count
,
1064 target_buffer_get_u32_array(target
, buffer
, count
,
1068 target_buffer_get_u16_array(target
, buffer
, count
,
1075 LOG_DEBUG("address: 0x%16.16" PRIx64
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
1076 address
, size
, count
);
1078 retval
= mips64_pracc_write_mem(ejtag_info
, address
, size
, count
,
1085 static int mips_mips64_init_target(struct command_context
*cmd_ctx
,
1086 struct target
*target
)
1088 return mips64_build_reg_cache(target
);
1091 static int mips_mips64_target_create(struct target
*target
, Jim_Interp
*interp
)
1093 struct mips_mips64_common
*mips_mips64
;
1094 struct mips64_common
*mips64
;
1096 mips_mips64
= calloc(1, sizeof(*mips_mips64
));
1098 LOG_ERROR("unable to allocate mips_mips64");
1102 mips_mips64
->common_magic
= MIPS64_COMMON_MAGIC
;
1104 mips64
= &mips_mips64
->mips64_common
;
1105 mips64
->arch_info
= mips_mips64
;
1106 target
->arch_info
= mips64
;
1108 return mips64_init_arch_info(target
, mips64
, target
->tap
);
1111 static int mips_mips64_examine(struct target
*target
)
1114 struct mips64_common
*mips64
= target
->arch_info
;
1116 retval
= mips_ejtag_init(&mips64
->ejtag_info
);
1117 if (retval
!= ERROR_OK
)
1120 return mips64_examine(target
);
1123 static int mips_mips64_checksum_memory(struct target
*target
, uint64_t address
,
1124 uint32_t size
, uint32_t *checksum
)
1126 return ERROR_FAIL
; /* use bulk read method */
1129 COMMAND_HANDLER(handle_mips64mode32
)
1131 struct target
*target
= get_current_target(CMD_CTX
);
1132 struct mips64_common
*mips64
= target
->arch_info
;
1135 COMMAND_PARSE_BOOL(CMD_ARGV
[0], mips64
->mips64mode32
, "on", "off");
1137 if (mips64
->mips64mode32
)
1138 command_print(CMD
, "enabled");
1140 command_print(CMD
, "disabled");
1146 static const struct command_registration mips64_commands_handlers
[] = {
1148 .name
= "mips64mode32",
1149 .mode
= COMMAND_EXEC
,
1150 .help
= "Enable/disable 32 bit mode",
1152 .handler
= handle_mips64mode32
1154 COMMAND_REGISTRATION_DONE
1157 struct target_type mips_mips64_target
= {
1158 .name
= "mips_mips64",
1160 .poll
= mips_mips64_poll
,
1161 .arch_state
= mips64_arch_state
,
1163 .target_request_data
= NULL
,
1165 .halt
= mips_mips64_halt
,
1166 .resume
= mips_mips64_resume
,
1167 .step
= mips_mips64_step
,
1169 .assert_reset
= mips_mips64_assert_reset
,
1170 .deassert_reset
= mips_mips64_deassert_reset
,
1171 .soft_reset_halt
= mips_mips64_soft_reset_halt
,
1173 .get_gdb_reg_list
= mips64_get_gdb_reg_list
,
1175 .read_memory
= mips_mips64_read_memory
,
1176 .write_memory
= mips_mips64_write_memory
,
1177 .checksum_memory
= mips_mips64_checksum_memory
,
1178 .blank_check_memory
= NULL
,
1180 .run_algorithm
= mips64_run_algorithm
,
1182 .add_breakpoint
= mips_mips64_add_breakpoint
,
1183 .remove_breakpoint
= mips_mips64_remove_breakpoint
,
1184 .add_watchpoint
= mips_mips64_add_watchpoint
,
1185 .remove_watchpoint
= mips_mips64_remove_watchpoint
,
1187 .target_create
= mips_mips64_target_create
,
1188 .init_target
= mips_mips64_init_target
,
1189 .examine
= mips_mips64_examine
,
1191 .commands
= mips64_commands_handlers
,
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)