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
->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
= wp_num
+ 1;
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
->set
== 0) {
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
;
511 bp_num
= bp
->set
- 1;
513 if ((bp_num
< 0) || (bp_num
>= mips64
->num_inst_bpoints
)) {
514 LOG_DEBUG("Invalid FP Comparator number in breakpoint (bpid: %" PRIu32
")",
519 LOG_DEBUG("bpid: %" PRIu32
" - releasing hw: %d", bp
->unique_id
, bp_num
);
520 comparator_list
[bp_num
].used
= false;
521 comparator_list
[bp_num
].bp_value
= 0;
523 return target_write_u64(target
,
524 comparator_list
[bp_num
].reg_address
+ 0x18, 0);
527 static int mips_mips64_unset_sdbbp(struct target
*target
, struct breakpoint
*bp
)
529 uint8_t buf
[MIPS64_SDBBP_SIZE
];
533 retval
= target_read_memory(target
, bp
->address
, MIPS64_SDBBP_SIZE
, 1,
535 if (retval
!= ERROR_OK
)
538 instr
= target_buffer_get_u32(target
, &buf
[0]);
539 if (instr
!= MIPS64_SDBBP
)
542 return target_write_memory(target
, bp
->address
, MIPS64_SDBBP_SIZE
, 1,
546 static int mips_mips16_unset_sdbbp(struct target
*target
, struct breakpoint
*bp
)
548 uint8_t buf
[MIPS16_SDBBP_SIZE
];
552 retval
= target_read_memory(target
, bp
->address
, MIPS16_SDBBP_SIZE
, 1,
554 if (retval
!= ERROR_OK
)
557 instr
= target_buffer_get_u16(target
, &buf
[0]);
558 if (instr
!= MIPS16_SDBBP(bp
->length
& 1))
561 return target_write_memory(target
, bp
->address
, MIPS16_SDBBP_SIZE
, 1,
565 static int mips_mips64_unset_breakpoint(struct target
*target
,
566 struct breakpoint
*bp
)
568 /* get pointers to arch-specific information */
572 LOG_WARNING("breakpoint not set");
576 if (bp
->type
== BKPT_HARD
) {
577 retval
= mips_mips64_unset_hwbp(target
, bp
);
579 LOG_DEBUG("bpid: %" PRIu32
, bp
->unique_id
);
581 switch (bp
->length
) {
582 case MIPS64_SDBBP_SIZE
:
583 retval
= mips_mips64_unset_sdbbp(target
, bp
);
585 case MIPS16_SDBBP_SIZE
:
586 retval
= mips_mips16_unset_sdbbp(target
, bp
);
592 if (retval
!= ERROR_OK
) {
593 LOG_ERROR("can't unset breakpoint. Some thing wrong happened");
602 static int mips_mips64_resume(struct target
*target
, int current
,
603 uint64_t address
, int handle_breakpoints
,
606 struct mips64_common
*mips64
= target
->arch_info
;
607 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
608 int retval
= ERROR_OK
;
612 if (mips64
->mips64mode32
)
613 address
= mips64_extend_sign(address
);
615 if (target
->state
!= TARGET_HALTED
) {
616 LOG_WARNING("target not halted %d", target
->state
);
617 return ERROR_TARGET_NOT_HALTED
;
620 if (!debug_execution
) {
621 target_free_all_working_areas(target
);
622 retval
= mips_mips64_enable_breakpoints(target
);
623 if (retval
!= ERROR_OK
)
626 retval
= mips_mips64_enable_watchpoints(target
);
627 if (retval
!= ERROR_OK
)
631 pc
= &mips64
->core_cache
->reg_list
[MIPS64_PC
];
632 /* current = 1: continue on current pc, otherwise continue at <address> */
634 buf_set_u64(pc
->value
, 0, 64, address
);
639 resume_pc
= buf_get_u64(pc
->value
, 0, 64);
641 retval
= mips64_restore_context(target
);
642 if (retval
!= ERROR_OK
)
645 /* the front-end may request us not to handle breakpoints */
646 if (handle_breakpoints
) {
647 struct breakpoint
*bp
;
649 /* Single step past breakpoint at current address */
650 bp
= breakpoint_find(target
, (uint64_t) resume_pc
);
652 LOG_DEBUG("unset breakpoint at 0x%16.16" PRIx64
"",
654 retval
= mips_mips64_unset_breakpoint(target
, bp
);
655 if (retval
!= ERROR_OK
)
658 retval
= mips_mips64_single_step_core(target
);
659 if (retval
!= ERROR_OK
)
662 retval
= mips_mips64_set_breakpoint(target
, bp
);
663 if (retval
!= ERROR_OK
)
668 /* enable interrupts if we are running */
669 retval
= mips64_enable_interrupts(target
, !debug_execution
);
670 if (retval
!= ERROR_OK
)
673 /* exit debug mode */
674 retval
= mips64_ejtag_exit_debug(ejtag_info
);
675 if (retval
!= ERROR_OK
)
678 target
->debug_reason
= DBG_REASON_NOTHALTED
;
680 /* registers are now invalid */
681 retval
= mips64_invalidate_core_regs(target
);
682 if (retval
!= ERROR_OK
)
685 if (!debug_execution
) {
686 target
->state
= TARGET_RUNNING
;
687 retval
= target_call_event_callbacks(target
,
688 TARGET_EVENT_RESUMED
);
689 if (retval
!= ERROR_OK
)
692 LOG_DEBUG("target resumed at 0x%" PRIx64
"", resume_pc
);
694 target
->state
= TARGET_DEBUG_RUNNING
;
695 retval
= target_call_event_callbacks(target
,
696 TARGET_EVENT_DEBUG_RESUMED
);
697 if (retval
!= ERROR_OK
)
700 LOG_DEBUG("target debug resumed at 0x%" PRIx64
"", resume_pc
);
706 static int mips_mips64_step(struct target
*target
, int current
,
707 uint64_t address
, int handle_breakpoints
)
709 struct mips64_common
*mips64
= target
->arch_info
;
710 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
711 struct reg
*pc
= &mips64
->core_cache
->reg_list
[MIPS64_PC
];
712 struct breakpoint
*bp
= NULL
;
713 int retval
= ERROR_OK
;
715 if (target
->state
!= TARGET_HALTED
) {
716 LOG_WARNING("target not halted");
717 return ERROR_TARGET_NOT_HALTED
;
720 if (mips64
->mips64mode32
)
721 address
= mips64_extend_sign(address
);
723 /* current = 1: continue on current pc, otherwise continue at
726 buf_set_u64(pc
->value
, 0, 64, address
);
731 /* the front-end may request us not to handle breakpoints */
732 if (handle_breakpoints
) {
733 bp
= breakpoint_find(target
, buf_get_u64(pc
->value
, 0, 64));
735 retval
= mips_mips64_unset_breakpoint(target
, bp
);
736 if (retval
!= ERROR_OK
)
741 retval
= mips64_restore_context(target
);
742 if (retval
!= ERROR_OK
)
745 /* configure single step mode */
746 retval
= mips64_ejtag_config_step(ejtag_info
, 1);
747 if (retval
!= ERROR_OK
)
750 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
752 retval
= target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
753 if (retval
!= ERROR_OK
)
756 /* disable interrupts while stepping */
757 retval
= mips64_enable_interrupts(target
, false);
758 if (retval
!= ERROR_OK
)
761 /* exit debug mode */
762 retval
= mips64_ejtag_exit_debug(ejtag_info
);
763 if (retval
!= ERROR_OK
)
766 /* registers are now invalid */
767 retval
= mips64_invalidate_core_regs(target
);
768 if (retval
!= ERROR_OK
)
772 retval
= mips_mips64_set_breakpoint(target
, bp
);
773 if (retval
!= ERROR_OK
)
777 LOG_DEBUG("target stepped ");
779 retval
= mips_mips64_debug_entry(target
);
780 if (retval
!= ERROR_OK
)
783 return target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
786 static int mips_mips64_add_breakpoint(struct target
*target
,
787 struct breakpoint
*bp
)
789 struct mips64_common
*mips64
= target
->arch_info
;
791 if (mips64
->mips64mode32
)
792 bp
->address
= mips64_extend_sign(bp
->address
);
794 if (bp
->type
== BKPT_HARD
) {
795 if (mips64
->num_inst_bpoints_avail
< 1) {
796 LOG_INFO("no hardware breakpoint available");
797 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
800 mips64
->num_inst_bpoints_avail
--;
803 return mips_mips64_set_breakpoint(target
, bp
);
806 static int mips_mips64_remove_breakpoint(struct target
*target
,
807 struct breakpoint
*bp
)
809 /* get pointers to arch-specific information */
810 struct mips64_common
*mips64
= target
->arch_info
;
811 int retval
= ERROR_OK
;
813 if (target
->state
!= TARGET_HALTED
) {
814 LOG_WARNING("target not halted");
815 return ERROR_TARGET_NOT_HALTED
;
819 retval
= mips_mips64_unset_breakpoint(target
, bp
);
821 if (bp
->type
== BKPT_HARD
)
822 mips64
->num_inst_bpoints_avail
++;
827 static int mips_mips64_unset_watchpoint(struct target
*target
,
828 struct watchpoint
*watchpoint
)
830 /* get pointers to arch-specific information */
831 struct mips64_common
*mips64
= target
->arch_info
;
832 struct mips64_comparator
*comparator_list
= mips64
->data_break_list
;
834 if (!watchpoint
->set
) {
835 LOG_WARNING("watchpoint not set");
839 int wp_num
= watchpoint
->set
- 1;
840 if ((wp_num
< 0) || (wp_num
>= mips64
->num_data_bpoints
)) {
841 LOG_DEBUG("Invalid FP Comparator number in watchpoint");
844 comparator_list
[wp_num
].used
= false;
845 comparator_list
[wp_num
].bp_value
= 0;
846 target_write_u64(target
, comparator_list
[wp_num
].reg_address
+ 0x18, 0);
852 static int mips_mips64_add_watchpoint(struct target
*target
,
853 struct watchpoint
*watchpoint
)
855 struct mips64_common
*mips64
= target
->arch_info
;
857 if (mips64
->num_data_bpoints_avail
< 1) {
858 LOG_INFO("no hardware watchpoints available");
859 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
862 mips64
->num_data_bpoints_avail
--;
864 return mips_mips64_set_watchpoint(target
, watchpoint
);
867 static int mips_mips64_remove_watchpoint(struct target
*target
,
868 struct watchpoint
*watchpoint
)
870 /* get pointers to arch-specific information */
871 struct mips64_common
*mips64
= target
->arch_info
;
872 int retval
= ERROR_OK
;
874 if (target
->state
!= TARGET_HALTED
) {
875 LOG_WARNING("target not halted");
876 return ERROR_TARGET_NOT_HALTED
;
880 retval
= mips_mips64_unset_watchpoint(target
, watchpoint
);
882 mips64
->num_data_bpoints_avail
++;
887 static int mips_mips64_read_memory(struct target
*target
, uint64_t address
,
888 uint32_t size
, uint32_t count
, uint8_t *buffer
)
890 struct mips64_common
*mips64
= target
->arch_info
;
891 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
895 if (target
->state
!= TARGET_HALTED
) {
896 LOG_WARNING("target not halted %d", target
->state
);
897 return ERROR_TARGET_NOT_HALTED
;
900 if (mips64
->mips64mode32
)
901 address
= mips64_extend_sign(address
);
903 /* sanitize arguments */
904 if (((size
!= 8) && (size
!= 4) && (size
!= 2) && (size
!= 1))
905 || !count
|| !buffer
)
906 return ERROR_COMMAND_ARGUMENT_INVALID
;
908 if (((size
== 8) && (address
& 0x7)) || ((size
== 4) && (address
& 0x3))
909 || ((size
== 2) && (address
& 0x1)))
910 return ERROR_TARGET_UNALIGNED_ACCESS
;
913 t
= calloc(count
, size
);
915 LOG_ERROR("Out of memory");
921 LOG_DEBUG("address: 0x%16.16" PRIx64
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
922 address
, size
, count
);
923 retval
= mips64_pracc_read_mem(ejtag_info
, address
, size
, count
,
926 if (retval
!= ERROR_OK
) {
927 LOG_ERROR("mips64_pracc_read_mem filed");
933 target_buffer_set_u64_array(target
, buffer
, count
, t
);
936 target_buffer_set_u32_array(target
, buffer
, count
, t
);
939 target_buffer_set_u16_array(target
, buffer
, count
, t
);
950 static int mips_mips64_bulk_write_memory(struct target
*target
,
951 target_addr_t address
, uint32_t count
,
952 const uint8_t *buffer
)
954 struct mips64_common
*mips64
= target
->arch_info
;
955 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
956 struct working_area
*fast_data_area
;
959 LOG_DEBUG("address: " TARGET_ADDR_FMT
", count: 0x%8.8" PRIx32
"",
963 return ERROR_TARGET_UNALIGNED_ACCESS
;
965 if (!mips64
->fast_data_area
) {
966 /* Get memory for block write handler
967 * we preserve this area between calls and gain a speed increase
968 * of about 3kb/sec when writing flash
969 * this will be released/nulled by the system when the target is resumed or reset */
970 retval
= target_alloc_working_area(target
,
971 MIPS64_FASTDATA_HANDLER_SIZE
,
972 &mips64
->fast_data_area
);
973 if (retval
!= ERROR_OK
) {
974 LOG_ERROR("No working area available");
978 /* reset fastadata state so the algo get reloaded */
979 ejtag_info
->fast_access_save
= -1;
982 fast_data_area
= mips64
->fast_data_area
;
984 if (address
<= fast_data_area
->address
+ fast_data_area
->size
&&
985 fast_data_area
->address
<= address
+ count
) {
986 LOG_ERROR("fast_data (" TARGET_ADDR_FMT
") is within write area "
987 "(" TARGET_ADDR_FMT
"-" TARGET_ADDR_FMT
").",
988 fast_data_area
->address
, address
, address
+ count
);
989 LOG_ERROR("Change work-area-phys or load_image address!");
993 /* mips32_pracc_fastdata_xfer requires uint32_t in host endianness, */
994 /* but byte array represents target endianness */
997 t
= calloc(count
, sizeof(uint64_t));
999 LOG_ERROR("Out of memory");
1003 target_buffer_get_u64_array(target
, buffer
, count
, t
);
1005 retval
= mips64_pracc_fastdata_xfer(ejtag_info
, mips64
->fast_data_area
,
1006 true, address
, count
, t
);
1008 if (retval
!= ERROR_OK
)
1009 LOG_ERROR("Fastdata access Failed");
1016 static int mips_mips64_write_memory(struct target
*target
, uint64_t address
,
1017 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
1019 struct mips64_common
*mips64
= target
->arch_info
;
1020 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
1023 if (target
->state
!= TARGET_HALTED
) {
1024 LOG_WARNING("target not halted");
1025 return ERROR_TARGET_NOT_HALTED
;
1028 if (mips64
->mips64mode32
)
1029 address
= mips64_extend_sign(address
);
1031 /* sanitize arguments */
1032 if (((size
!= 8) && (size
!= 4) && (size
!= 2) && (size
!= 1))
1033 || !count
|| !buffer
)
1034 return ERROR_COMMAND_ARGUMENT_INVALID
;
1036 if (((size
== 8) && (address
& 0x7)) || ((size
== 4) && (address
& 0x3))
1037 || ((size
== 2) && (address
& 0x1)))
1038 return ERROR_TARGET_UNALIGNED_ACCESS
;
1042 if (size
== 8 && count
> 8) {
1043 retval
= mips_mips64_bulk_write_memory(target
, address
, count
,
1045 if (retval
== ERROR_OK
)
1048 LOG_WARNING("Falling back to non-bulk write");
1053 t
= calloc(count
, size
);
1055 LOG_ERROR("unable to allocate t for write buffer");
1061 target_buffer_get_u64_array(target
, buffer
, count
,
1065 target_buffer_get_u32_array(target
, buffer
, count
,
1069 target_buffer_get_u16_array(target
, buffer
, count
,
1076 LOG_DEBUG("address: 0x%16.16" PRIx64
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
1077 address
, size
, count
);
1079 retval
= mips64_pracc_write_mem(ejtag_info
, address
, size
, count
,
1086 static int mips_mips64_init_target(struct command_context
*cmd_ctx
,
1087 struct target
*target
)
1089 return mips64_build_reg_cache(target
);
1092 static int mips_mips64_target_create(struct target
*target
, Jim_Interp
*interp
)
1094 struct mips_mips64_common
*mips_mips64
;
1095 struct mips64_common
*mips64
;
1097 mips_mips64
= calloc(1, sizeof(*mips_mips64
));
1099 LOG_ERROR("unable to allocate mips_mips64");
1103 mips_mips64
->common_magic
= MIPS64_COMMON_MAGIC
;
1105 mips64
= &mips_mips64
->mips64_common
;
1106 mips64
->arch_info
= mips_mips64
;
1107 target
->arch_info
= mips64
;
1109 return mips64_init_arch_info(target
, mips64
, target
->tap
);
1112 static int mips_mips64_examine(struct target
*target
)
1115 struct mips64_common
*mips64
= target
->arch_info
;
1117 retval
= mips_ejtag_init(&mips64
->ejtag_info
);
1118 if (retval
!= ERROR_OK
)
1121 return mips64_examine(target
);
1124 static int mips_mips64_checksum_memory(struct target
*target
, uint64_t address
,
1125 uint32_t size
, uint32_t *checksum
)
1127 return ERROR_FAIL
; /* use bulk read method */
1130 COMMAND_HANDLER(handle_mips64mode32
)
1132 struct target
*target
= get_current_target(CMD_CTX
);
1133 struct mips64_common
*mips64
= target
->arch_info
;
1136 COMMAND_PARSE_BOOL(CMD_ARGV
[0], mips64
->mips64mode32
, "on", "off");
1138 if (mips64
->mips64mode32
)
1139 command_print(CMD
, "enabled");
1141 command_print(CMD
, "disabled");
1147 static const struct command_registration mips64_commands_handlers
[] = {
1149 .name
= "mips64mode32",
1150 .mode
= COMMAND_EXEC
,
1151 .help
= "Enable/disable 32 bit mode",
1153 .handler
= handle_mips64mode32
1155 COMMAND_REGISTRATION_DONE
1158 struct target_type mips_mips64_target
= {
1159 .name
= "mips_mips64",
1161 .poll
= mips_mips64_poll
,
1162 .arch_state
= mips64_arch_state
,
1164 .target_request_data
= NULL
,
1166 .halt
= mips_mips64_halt
,
1167 .resume
= mips_mips64_resume
,
1168 .step
= mips_mips64_step
,
1170 .assert_reset
= mips_mips64_assert_reset
,
1171 .deassert_reset
= mips_mips64_deassert_reset
,
1172 .soft_reset_halt
= mips_mips64_soft_reset_halt
,
1174 .get_gdb_reg_list
= mips64_get_gdb_reg_list
,
1176 .read_memory
= mips_mips64_read_memory
,
1177 .write_memory
= mips_mips64_write_memory
,
1178 .checksum_memory
= mips_mips64_checksum_memory
,
1179 .blank_check_memory
= NULL
,
1181 .run_algorithm
= mips64_run_algorithm
,
1183 .add_breakpoint
= mips_mips64_add_breakpoint
,
1184 .remove_breakpoint
= mips_mips64_remove_breakpoint
,
1185 .add_watchpoint
= mips_mips64_add_watchpoint
,
1186 .remove_watchpoint
= mips_mips64_remove_watchpoint
,
1188 .target_create
= mips_mips64_target_create
,
1189 .init_target
= mips_mips64_init_target
,
1190 .examine
= mips_mips64_examine
,
1192 .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)