1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * MIPS64 generic target support
6 * Copyright (C) 2014 by Andrey Sidorov <anysidorov@gmail.com>
7 * Copyright (C) 2014 by Aleksey Kuleshov <rndfax@yandex.ru>
8 * Copyright (C) 2014-2019 by Peter Mamonov <pmamonov@gmail.com>
10 * Based on the work of:
11 * Copyright (C) 2008 by Spencer Oliver
12 * Copyright (C) 2008 by David T.L. Wong
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_single_step_core(struct target
*target
)
210 struct mips64_common
*mips64
= target
->arch_info
;
211 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
214 /* configure single step mode */
215 mips64_ejtag_config_step(ejtag_info
, 1);
217 /* disable interrupts while stepping */
218 retval
= mips64_enable_interrupts(target
, false);
219 if (retval
!= ERROR_OK
)
222 /* exit debug mode */
223 retval
= mips64_ejtag_exit_debug(ejtag_info
);
224 if (retval
!= ERROR_OK
)
227 mips_mips64_debug_entry(target
);
232 /* TODO: HW breakpoints are in EJTAG spec. Should we share it for MIPS32? */
233 static int mips_mips64_set_hwbp(struct target
*target
, struct breakpoint
*bp
)
235 struct mips64_common
*mips64
= target
->arch_info
;
236 struct mips64_comparator
*c
, *cl
= mips64
->inst_break_list
;
238 int retval
, bp_num
= 0;
240 while (cl
[bp_num
].used
&& (bp_num
< mips64
->num_inst_bpoints
))
243 if (bp_num
>= mips64
->num_inst_bpoints
) {
244 LOG_DEBUG("ERROR Can not find free FP Comparator(bpid: %" PRIu32
")",
246 LOG_WARNING("ERROR Can not find free FP Comparator");
252 c
->bp_value
= bp
->address
;
253 bp_value
= bp
->address
;
255 /* Instruction Breakpoint Address n (IBAn) Register */
256 retval
= target_write_u64(target
, c
->reg_address
, bp_value
);
257 if (retval
!= ERROR_OK
)
260 /* TODO: use defines */
261 /* Instruction Breakpoint Address Mask n (IBMn) Register */
262 retval
= target_write_u64(target
, c
->reg_address
+ 0x08, 0);
263 if (retval
!= ERROR_OK
)
266 /* Instruction Breakpoint Control n (IBCn) Register */
267 retval
= target_write_u64(target
, c
->reg_address
+ 0x18, 1);
268 if (retval
!= ERROR_OK
)
271 LOG_DEBUG("bpid: %" PRIu32
", bp_num %i bp_value 0x%" PRIx64
, bp
->unique_id
,
272 bp_num
, c
->bp_value
);
277 /* TODO: is it MIPS64 or MIPS32 instruction. If MIPS32, can it be shared with
279 static int mips_mips64_set_sdbbp(struct target
*target
, struct breakpoint
*bp
)
284 retval
= target_read_memory(target
,
285 bp
->address
, bp
->length
, 1,
287 if (retval
!= ERROR_OK
)
290 retval
= target_write_u32(target
, bp
->address
, MIPS64_SDBBP
);
291 if (retval
!= ERROR_OK
)
294 retval
= target_read_u32(target
, bp
->address
, &verify
);
295 if (retval
!= ERROR_OK
)
298 if (verify
!= MIPS64_SDBBP
) {
299 LOG_ERROR("Unable to set 32bit breakpoint at address %16" PRIx64
,
307 /* TODO do MIPS64 support MIPS16 instructions? Can it be shared with MIPS32
309 static int mips_mips16_set_sdbbp(struct target
*target
, struct breakpoint
*bp
)
311 uint32_t isa_req
= bp
->length
& 1;
315 retval
= target_read_memory(target
,
316 bp
->address
, bp
->length
, 1,
318 if (retval
!= ERROR_OK
)
321 retval
= target_write_u16(target
, bp
->address
, MIPS16_SDBBP(isa_req
));
322 if (retval
!= ERROR_OK
)
325 retval
= target_read_u16(target
, bp
->address
, &verify
);
326 if (retval
!= ERROR_OK
)
329 if (verify
!= MIPS16_SDBBP(isa_req
)) {
330 LOG_ERROR("Unable to set 16bit breakpoint at address %16" PRIx64
,
338 static int mips_mips64_set_breakpoint(struct target
*target
,
339 struct breakpoint
*bp
)
344 LOG_WARNING("breakpoint already set");
348 if (bp
->type
== BKPT_HARD
) {
349 retval
= mips_mips64_set_hwbp(target
, bp
);
351 LOG_DEBUG("bpid: %" PRIu32
, bp
->unique_id
);
353 switch (bp
->length
) {
354 case MIPS64_SDBBP_SIZE
:
355 retval
= mips_mips64_set_sdbbp(target
, bp
);
357 case MIPS16_SDBBP_SIZE
:
358 retval
= mips_mips16_set_sdbbp(target
, bp
);
365 if (retval
!= ERROR_OK
) {
366 LOG_ERROR("can't unset breakpoint. Some thing wrong happened");
375 static int mips_mips64_enable_breakpoints(struct target
*target
)
377 struct breakpoint
*bp
= target
->breakpoints
;
378 int retval
= ERROR_OK
;
380 /* set any pending breakpoints */
383 retval
= mips_mips64_set_breakpoint(target
, bp
);
384 if (retval
!= ERROR_OK
)
393 /* TODO: HW data breakpoints are in EJTAG spec. Should we share it for MIPS32? */
394 static int mips_mips64_set_watchpoint(struct target
*target
,
395 struct watchpoint
*watchpoint
)
398 struct mips64_common
*mips64
= target
->arch_info
;
399 struct mips64_comparator
*c
, *cl
= mips64
->data_break_list
;
400 int retval
, wp_num
= 0;
403 * watchpoint enabled, ignore all byte lanes in value register
404 * and exclude both load and store accesses from watchpoint
405 * condition evaluation
407 int enable
= EJTAG_DBCN_NOSB
| EJTAG_DBCN_NOLB
| EJTAG_DBCN_BE
408 | (0xff << EJTAG_DBCN_BLM_SHIFT
);
410 if (watchpoint
->is_set
) {
411 LOG_WARNING("watchpoint already set");
415 while (cl
[wp_num
].used
&& (wp_num
< mips64
->num_data_bpoints
))
418 if (wp_num
>= mips64
->num_data_bpoints
) {
419 LOG_ERROR("ERROR Can not find free comparator");
420 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
423 if (watchpoint
->length
!= 4) {
424 LOG_ERROR("Only watchpoints of length 4 are supported");
425 return ERROR_TARGET_UNALIGNED_ACCESS
;
428 if (watchpoint
->address
% 4) {
429 LOG_ERROR("Watchpoints address should be word aligned");
430 return ERROR_TARGET_UNALIGNED_ACCESS
;
433 switch (watchpoint
->rw
) {
435 enable
&= ~EJTAG_DBCN_NOLB
;
438 enable
&= ~EJTAG_DBCN_NOSB
;
441 enable
&= ~(EJTAG_DBCN_NOLB
| EJTAG_DBCN_NOSB
);
444 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
448 watchpoint_set(watchpoint
, wp_num
);
450 c
->bp_value
= watchpoint
->address
;
452 wp_value
= watchpoint
->address
;
453 if (wp_value
& 0x80000000)
454 wp_value
|= ULLONG_MAX
<< 32;
456 retval
= target_write_u64(target
, c
->reg_address
, wp_value
);
457 if (retval
!= ERROR_OK
)
460 retval
= target_write_u64(target
, c
->reg_address
+ 0x08, 0);
461 if (retval
!= ERROR_OK
)
464 retval
= target_write_u64(target
, c
->reg_address
+ 0x10, 0);
465 if (retval
!= ERROR_OK
)
468 retval
= target_write_u64(target
, c
->reg_address
+ 0x18, enable
);
469 if (retval
!= ERROR_OK
)
472 retval
= target_write_u64(target
, c
->reg_address
+ 0x20, 0);
473 if (retval
!= ERROR_OK
)
476 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx64
"", wp_num
, c
->bp_value
);
481 static int mips_mips64_enable_watchpoints(struct target
*target
)
483 struct watchpoint
*watchpoint
= target
->watchpoints
;
486 /* set any pending watchpoints */
488 if (!watchpoint
->is_set
) {
489 retval
= mips_mips64_set_watchpoint(target
, watchpoint
);
490 if (retval
!= ERROR_OK
)
493 watchpoint
= watchpoint
->next
;
499 static int mips_mips64_unset_hwbp(struct target
*target
, struct breakpoint
*bp
)
501 struct mips64_common
*mips64
= target
->arch_info
;
502 struct mips64_comparator
*comparator_list
= mips64
->inst_break_list
;
504 int bp_num
= bp
->number
;
506 if (bp_num
>= mips64
->num_inst_bpoints
) {
507 LOG_DEBUG("Invalid FP Comparator number in breakpoint (bpid: %" PRIu32
")",
512 LOG_DEBUG("bpid: %" PRIu32
" - releasing hw: %d", bp
->unique_id
, bp_num
);
513 comparator_list
[bp_num
].used
= false;
514 comparator_list
[bp_num
].bp_value
= 0;
516 return target_write_u64(target
,
517 comparator_list
[bp_num
].reg_address
+ 0x18, 0);
520 static int mips_mips64_unset_sdbbp(struct target
*target
, struct breakpoint
*bp
)
522 uint8_t buf
[MIPS64_SDBBP_SIZE
];
526 retval
= target_read_memory(target
, bp
->address
, MIPS64_SDBBP_SIZE
, 1,
528 if (retval
!= ERROR_OK
)
531 instr
= target_buffer_get_u32(target
, &buf
[0]);
532 if (instr
!= MIPS64_SDBBP
)
535 return target_write_memory(target
, bp
->address
, MIPS64_SDBBP_SIZE
, 1,
539 static int mips_mips16_unset_sdbbp(struct target
*target
, struct breakpoint
*bp
)
541 uint8_t buf
[MIPS16_SDBBP_SIZE
];
545 retval
= target_read_memory(target
, bp
->address
, MIPS16_SDBBP_SIZE
, 1,
547 if (retval
!= ERROR_OK
)
550 instr
= target_buffer_get_u16(target
, &buf
[0]);
551 if (instr
!= MIPS16_SDBBP(bp
->length
& 1))
554 return target_write_memory(target
, bp
->address
, MIPS16_SDBBP_SIZE
, 1,
558 static int mips_mips64_unset_breakpoint(struct target
*target
,
559 struct breakpoint
*bp
)
561 /* get pointers to arch-specific information */
565 LOG_WARNING("breakpoint not set");
569 if (bp
->type
== BKPT_HARD
) {
570 retval
= mips_mips64_unset_hwbp(target
, bp
);
572 LOG_DEBUG("bpid: %" PRIu32
, bp
->unique_id
);
574 switch (bp
->length
) {
575 case MIPS64_SDBBP_SIZE
:
576 retval
= mips_mips64_unset_sdbbp(target
, bp
);
578 case MIPS16_SDBBP_SIZE
:
579 retval
= mips_mips16_unset_sdbbp(target
, bp
);
585 if (retval
!= ERROR_OK
) {
586 LOG_ERROR("can't unset breakpoint. Some thing wrong happened");
595 static int mips_mips64_resume(struct target
*target
, int current
,
596 uint64_t address
, int handle_breakpoints
,
599 struct mips64_common
*mips64
= target
->arch_info
;
600 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
601 int retval
= ERROR_OK
;
605 if (mips64
->mips64mode32
)
606 address
= mips64_extend_sign(address
);
608 if (target
->state
!= TARGET_HALTED
) {
609 LOG_TARGET_ERROR(target
, "not halted");
610 return ERROR_TARGET_NOT_HALTED
;
613 if (!debug_execution
) {
614 target_free_all_working_areas(target
);
615 retval
= mips_mips64_enable_breakpoints(target
);
616 if (retval
!= ERROR_OK
)
619 retval
= mips_mips64_enable_watchpoints(target
);
620 if (retval
!= ERROR_OK
)
624 pc
= &mips64
->core_cache
->reg_list
[MIPS64_PC
];
625 /* current = 1: continue on current pc, otherwise continue at <address> */
627 buf_set_u64(pc
->value
, 0, 64, address
);
632 resume_pc
= buf_get_u64(pc
->value
, 0, 64);
634 retval
= mips64_restore_context(target
);
635 if (retval
!= ERROR_OK
)
638 /* the front-end may request us not to handle breakpoints */
639 if (handle_breakpoints
) {
640 struct breakpoint
*bp
;
642 /* Single step past breakpoint at current address */
643 bp
= breakpoint_find(target
, (uint64_t) resume_pc
);
645 LOG_DEBUG("unset breakpoint at 0x%16.16" PRIx64
"",
647 retval
= mips_mips64_unset_breakpoint(target
, bp
);
648 if (retval
!= ERROR_OK
)
651 retval
= mips_mips64_single_step_core(target
);
652 if (retval
!= ERROR_OK
)
655 retval
= mips_mips64_set_breakpoint(target
, bp
);
656 if (retval
!= ERROR_OK
)
661 /* enable interrupts if we are running */
662 retval
= mips64_enable_interrupts(target
, !debug_execution
);
663 if (retval
!= ERROR_OK
)
666 /* exit debug mode */
667 retval
= mips64_ejtag_exit_debug(ejtag_info
);
668 if (retval
!= ERROR_OK
)
671 target
->debug_reason
= DBG_REASON_NOTHALTED
;
673 /* registers are now invalid */
674 retval
= mips64_invalidate_core_regs(target
);
675 if (retval
!= ERROR_OK
)
678 if (!debug_execution
) {
679 target
->state
= TARGET_RUNNING
;
680 retval
= target_call_event_callbacks(target
,
681 TARGET_EVENT_RESUMED
);
682 if (retval
!= ERROR_OK
)
685 LOG_DEBUG("target resumed at 0x%" PRIx64
"", resume_pc
);
687 target
->state
= TARGET_DEBUG_RUNNING
;
688 retval
= target_call_event_callbacks(target
,
689 TARGET_EVENT_DEBUG_RESUMED
);
690 if (retval
!= ERROR_OK
)
693 LOG_DEBUG("target debug resumed at 0x%" PRIx64
"", resume_pc
);
699 static int mips_mips64_step(struct target
*target
, int current
,
700 uint64_t address
, int handle_breakpoints
)
702 struct mips64_common
*mips64
= target
->arch_info
;
703 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
704 struct reg
*pc
= &mips64
->core_cache
->reg_list
[MIPS64_PC
];
705 struct breakpoint
*bp
= NULL
;
706 int retval
= ERROR_OK
;
708 if (target
->state
!= TARGET_HALTED
) {
709 LOG_TARGET_ERROR(target
, "not halted");
710 return ERROR_TARGET_NOT_HALTED
;
713 if (mips64
->mips64mode32
)
714 address
= mips64_extend_sign(address
);
716 /* current = 1: continue on current pc, otherwise continue at
719 buf_set_u64(pc
->value
, 0, 64, address
);
724 /* the front-end may request us not to handle breakpoints */
725 if (handle_breakpoints
) {
726 bp
= breakpoint_find(target
, buf_get_u64(pc
->value
, 0, 64));
728 retval
= mips_mips64_unset_breakpoint(target
, bp
);
729 if (retval
!= ERROR_OK
)
734 retval
= mips64_restore_context(target
);
735 if (retval
!= ERROR_OK
)
738 /* configure single step mode */
739 retval
= mips64_ejtag_config_step(ejtag_info
, 1);
740 if (retval
!= ERROR_OK
)
743 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
745 retval
= target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
746 if (retval
!= ERROR_OK
)
749 /* disable interrupts while stepping */
750 retval
= mips64_enable_interrupts(target
, false);
751 if (retval
!= ERROR_OK
)
754 /* exit debug mode */
755 retval
= mips64_ejtag_exit_debug(ejtag_info
);
756 if (retval
!= ERROR_OK
)
759 /* registers are now invalid */
760 retval
= mips64_invalidate_core_regs(target
);
761 if (retval
!= ERROR_OK
)
765 retval
= mips_mips64_set_breakpoint(target
, bp
);
766 if (retval
!= ERROR_OK
)
770 LOG_DEBUG("target stepped ");
772 retval
= mips_mips64_debug_entry(target
);
773 if (retval
!= ERROR_OK
)
776 return target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
779 static int mips_mips64_add_breakpoint(struct target
*target
,
780 struct breakpoint
*bp
)
782 struct mips64_common
*mips64
= target
->arch_info
;
784 if (mips64
->mips64mode32
)
785 bp
->address
= mips64_extend_sign(bp
->address
);
787 if (bp
->type
== BKPT_HARD
) {
788 if (mips64
->num_inst_bpoints_avail
< 1) {
789 LOG_INFO("no hardware breakpoint available");
790 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
793 mips64
->num_inst_bpoints_avail
--;
796 return mips_mips64_set_breakpoint(target
, bp
);
799 static int mips_mips64_remove_breakpoint(struct target
*target
,
800 struct breakpoint
*bp
)
802 /* get pointers to arch-specific information */
803 struct mips64_common
*mips64
= target
->arch_info
;
804 int retval
= ERROR_OK
;
806 if (target
->state
!= TARGET_HALTED
) {
807 LOG_TARGET_ERROR(target
, "not halted");
808 return ERROR_TARGET_NOT_HALTED
;
812 retval
= mips_mips64_unset_breakpoint(target
, bp
);
814 if (bp
->type
== BKPT_HARD
)
815 mips64
->num_inst_bpoints_avail
++;
820 static int mips_mips64_unset_watchpoint(struct target
*target
,
821 struct watchpoint
*watchpoint
)
823 /* get pointers to arch-specific information */
824 struct mips64_common
*mips64
= target
->arch_info
;
825 struct mips64_comparator
*comparator_list
= mips64
->data_break_list
;
827 if (!watchpoint
->is_set
) {
828 LOG_WARNING("watchpoint not set");
832 int wp_num
= watchpoint
->number
;
833 if (wp_num
>= mips64
->num_data_bpoints
) {
834 LOG_DEBUG("Invalid FP Comparator number in watchpoint");
837 comparator_list
[wp_num
].used
= false;
838 comparator_list
[wp_num
].bp_value
= 0;
839 target_write_u64(target
, comparator_list
[wp_num
].reg_address
+ 0x18, 0);
840 watchpoint
->is_set
= false;
845 static int mips_mips64_add_watchpoint(struct target
*target
,
846 struct watchpoint
*watchpoint
)
848 struct mips64_common
*mips64
= target
->arch_info
;
850 if (mips64
->num_data_bpoints_avail
< 1) {
851 LOG_INFO("no hardware watchpoints available");
852 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
855 mips64
->num_data_bpoints_avail
--;
857 return mips_mips64_set_watchpoint(target
, watchpoint
);
860 static int mips_mips64_remove_watchpoint(struct target
*target
,
861 struct watchpoint
*watchpoint
)
863 /* get pointers to arch-specific information */
864 struct mips64_common
*mips64
= target
->arch_info
;
865 int retval
= ERROR_OK
;
867 if (target
->state
!= TARGET_HALTED
) {
868 LOG_TARGET_ERROR(target
, "not halted");
869 return ERROR_TARGET_NOT_HALTED
;
872 if (watchpoint
->is_set
)
873 retval
= mips_mips64_unset_watchpoint(target
, watchpoint
);
875 mips64
->num_data_bpoints_avail
++;
880 static int mips_mips64_read_memory(struct target
*target
, uint64_t address
,
881 uint32_t size
, uint32_t count
, uint8_t *buffer
)
883 struct mips64_common
*mips64
= target
->arch_info
;
884 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
888 if (target
->state
!= TARGET_HALTED
) {
889 LOG_TARGET_ERROR(target
, "not halted");
890 return ERROR_TARGET_NOT_HALTED
;
893 if (mips64
->mips64mode32
)
894 address
= mips64_extend_sign(address
);
896 /* sanitize arguments */
897 if (((size
!= 8) && (size
!= 4) && (size
!= 2) && (size
!= 1))
898 || !count
|| !buffer
)
899 return ERROR_COMMAND_ARGUMENT_INVALID
;
901 if (((size
== 8) && (address
& 0x7)) || ((size
== 4) && (address
& 0x3))
902 || ((size
== 2) && (address
& 0x1)))
903 return ERROR_TARGET_UNALIGNED_ACCESS
;
906 t
= calloc(count
, size
);
908 LOG_ERROR("Out of memory");
914 LOG_DEBUG("address: 0x%16.16" PRIx64
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
915 address
, size
, count
);
916 retval
= mips64_pracc_read_mem(ejtag_info
, address
, size
, count
,
919 if (retval
!= ERROR_OK
) {
920 LOG_ERROR("mips64_pracc_read_mem filed");
926 target_buffer_set_u64_array(target
, buffer
, count
, t
);
929 target_buffer_set_u32_array(target
, buffer
, count
, t
);
932 target_buffer_set_u16_array(target
, buffer
, count
, t
);
943 static int mips_mips64_bulk_write_memory(struct target
*target
,
944 target_addr_t address
, uint32_t count
,
945 const uint8_t *buffer
)
947 struct mips64_common
*mips64
= target
->arch_info
;
948 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
949 struct working_area
*fast_data_area
;
952 LOG_DEBUG("address: " TARGET_ADDR_FMT
", count: 0x%8.8" PRIx32
"",
956 return ERROR_TARGET_UNALIGNED_ACCESS
;
958 if (!mips64
->fast_data_area
) {
959 /* Get memory for block write handler
960 * we preserve this area between calls and gain a speed increase
961 * of about 3kb/sec when writing flash
962 * this will be released/nulled by the system when the target is resumed or reset */
963 retval
= target_alloc_working_area(target
,
964 MIPS64_FASTDATA_HANDLER_SIZE
,
965 &mips64
->fast_data_area
);
966 if (retval
!= ERROR_OK
) {
967 LOG_ERROR("No working area available");
971 /* reset fastadata state so the algo get reloaded */
972 ejtag_info
->fast_access_save
= -1;
975 fast_data_area
= mips64
->fast_data_area
;
977 if (address
<= fast_data_area
->address
+ fast_data_area
->size
&&
978 fast_data_area
->address
<= address
+ count
) {
979 LOG_ERROR("fast_data (" TARGET_ADDR_FMT
") is within write area "
980 "(" TARGET_ADDR_FMT
"-" TARGET_ADDR_FMT
").",
981 fast_data_area
->address
, address
, address
+ count
);
982 LOG_ERROR("Change work-area-phys or load_image address!");
986 /* mips32_pracc_fastdata_xfer requires uint32_t in host endianness, */
987 /* but byte array represents target endianness */
990 t
= calloc(count
, sizeof(uint64_t));
992 LOG_ERROR("Out of memory");
996 target_buffer_get_u64_array(target
, buffer
, count
, t
);
998 retval
= mips64_pracc_fastdata_xfer(ejtag_info
, mips64
->fast_data_area
,
999 true, address
, count
, t
);
1001 if (retval
!= ERROR_OK
)
1002 LOG_ERROR("Fastdata access Failed");
1009 static int mips_mips64_write_memory(struct target
*target
, uint64_t address
,
1010 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
1012 struct mips64_common
*mips64
= target
->arch_info
;
1013 struct mips_ejtag
*ejtag_info
= &mips64
->ejtag_info
;
1016 if (target
->state
!= TARGET_HALTED
) {
1017 LOG_TARGET_ERROR(target
, "not halted");
1018 return ERROR_TARGET_NOT_HALTED
;
1021 if (mips64
->mips64mode32
)
1022 address
= mips64_extend_sign(address
);
1024 /* sanitize arguments */
1025 if (((size
!= 8) && (size
!= 4) && (size
!= 2) && (size
!= 1))
1026 || !count
|| !buffer
)
1027 return ERROR_COMMAND_ARGUMENT_INVALID
;
1029 if (((size
== 8) && (address
& 0x7)) || ((size
== 4) && (address
& 0x3))
1030 || ((size
== 2) && (address
& 0x1)))
1031 return ERROR_TARGET_UNALIGNED_ACCESS
;
1035 if (size
== 8 && count
> 8) {
1036 retval
= mips_mips64_bulk_write_memory(target
, address
, count
,
1038 if (retval
== ERROR_OK
)
1041 LOG_WARNING("Falling back to non-bulk write");
1046 t
= calloc(count
, size
);
1048 LOG_ERROR("unable to allocate t for write buffer");
1054 target_buffer_get_u64_array(target
, buffer
, count
,
1058 target_buffer_get_u32_array(target
, buffer
, count
,
1062 target_buffer_get_u16_array(target
, buffer
, count
,
1069 LOG_DEBUG("address: 0x%16.16" PRIx64
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
1070 address
, size
, count
);
1072 retval
= mips64_pracc_write_mem(ejtag_info
, address
, size
, count
,
1079 static int mips_mips64_init_target(struct command_context
*cmd_ctx
,
1080 struct target
*target
)
1082 return mips64_build_reg_cache(target
);
1085 static int mips_mips64_target_create(struct target
*target
, Jim_Interp
*interp
)
1087 struct mips_mips64_common
*mips_mips64
;
1088 struct mips64_common
*mips64
;
1090 mips_mips64
= calloc(1, sizeof(*mips_mips64
));
1092 LOG_ERROR("unable to allocate mips_mips64");
1096 mips_mips64
->common_magic
= MIPS64_COMMON_MAGIC
;
1098 mips64
= &mips_mips64
->mips64_common
;
1099 mips64
->arch_info
= mips_mips64
;
1100 target
->arch_info
= mips64
;
1102 return mips64_init_arch_info(target
, mips64
, target
->tap
);
1105 static int mips_mips64_examine(struct target
*target
)
1108 struct mips64_common
*mips64
= target
->arch_info
;
1110 retval
= mips_ejtag_init(&mips64
->ejtag_info
);
1111 if (retval
!= ERROR_OK
)
1114 return mips64_examine(target
);
1117 static int mips_mips64_checksum_memory(struct target
*target
, uint64_t address
,
1118 uint32_t size
, uint32_t *checksum
)
1120 return ERROR_FAIL
; /* use bulk read method */
1123 COMMAND_HANDLER(handle_mips64mode32
)
1125 struct target
*target
= get_current_target(CMD_CTX
);
1126 struct mips64_common
*mips64
= target
->arch_info
;
1129 COMMAND_PARSE_BOOL(CMD_ARGV
[0], mips64
->mips64mode32
, "on", "off");
1131 if (mips64
->mips64mode32
)
1132 command_print(CMD
, "enabled");
1134 command_print(CMD
, "disabled");
1140 static const struct command_registration mips64_commands_handlers
[] = {
1142 .name
= "mips64mode32",
1143 .mode
= COMMAND_EXEC
,
1144 .help
= "Enable/disable 32 bit mode",
1146 .handler
= handle_mips64mode32
1148 COMMAND_REGISTRATION_DONE
1151 struct target_type mips_mips64_target
= {
1152 .name
= "mips_mips64",
1154 .poll
= mips_mips64_poll
,
1155 .arch_state
= mips64_arch_state
,
1157 .target_request_data
= NULL
,
1159 .halt
= mips_mips64_halt
,
1160 .resume
= mips_mips64_resume
,
1161 .step
= mips_mips64_step
,
1163 .assert_reset
= mips_mips64_assert_reset
,
1164 .deassert_reset
= mips_mips64_deassert_reset
,
1165 /* TODO: add .soft_reset_halt */
1167 .get_gdb_reg_list
= mips64_get_gdb_reg_list
,
1169 .read_memory
= mips_mips64_read_memory
,
1170 .write_memory
= mips_mips64_write_memory
,
1171 .checksum_memory
= mips_mips64_checksum_memory
,
1172 .blank_check_memory
= NULL
,
1174 .run_algorithm
= mips64_run_algorithm
,
1176 .add_breakpoint
= mips_mips64_add_breakpoint
,
1177 .remove_breakpoint
= mips_mips64_remove_breakpoint
,
1178 .add_watchpoint
= mips_mips64_add_watchpoint
,
1179 .remove_watchpoint
= mips_mips64_remove_watchpoint
,
1181 .target_create
= mips_mips64_target_create
,
1182 .init_target
= mips_mips64_init_target
,
1183 .examine
= mips_mips64_examine
,
1185 .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)