1 /***************************************************************************
2 * Copyright (C) 2008 by Spencer Oliver *
3 * spen@spen-soft.co.uk *
5 * Copyright (C) 2008 by David T.L. Wong *
7 * Copyright (C) 2009 by David N. Claffey <dnclaffey@gmail.com> *
9 * Copyright (C) 2011 by Drasko DRASKOVIC *
10 * drasko.draskovic@gmail.com *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
17 * This program is distributed in the hope that it will be useful, *
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
20 * GNU General Public License for more details. *
22 * You should have received a copy of the GNU General Public License *
23 * along with this program; if not, write to the *
24 * Free Software Foundation, Inc., *
25 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
26 ***************************************************************************/
32 #include "breakpoints.h"
35 #include "mips32_dmaacc.h"
36 #include "target_type.h"
39 static void mips_m4k_enable_breakpoints(struct target
*target
);
40 static void mips_m4k_enable_watchpoints(struct target
*target
);
41 static int mips_m4k_set_breakpoint(struct target
*target
,
42 struct breakpoint
*breakpoint
);
43 static int mips_m4k_unset_breakpoint(struct target
*target
,
44 struct breakpoint
*breakpoint
);
46 static int mips_m4k_examine_debug_reason(struct target
*target
)
48 uint32_t break_status
;
51 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
52 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
)) {
53 /* get info about inst breakpoint support */
54 retval
= target_read_u32(target
, EJTAG_IBS
, &break_status
);
55 if (retval
!= ERROR_OK
)
57 if (break_status
& 0x1f) {
58 /* we have halted on a breakpoint */
59 retval
= target_write_u32(target
, EJTAG_IBS
, 0);
60 if (retval
!= ERROR_OK
)
62 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
65 /* get info about data breakpoint support */
66 retval
= target_read_u32(target
, EJTAG_DBS
, &break_status
);
67 if (retval
!= ERROR_OK
)
69 if (break_status
& 0x1f) {
70 /* we have halted on a breakpoint */
71 retval
= target_write_u32(target
, EJTAG_DBS
, 0);
72 if (retval
!= ERROR_OK
)
74 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
81 static int mips_m4k_debug_entry(struct target
*target
)
83 struct mips32_common
*mips32
= target_to_mips32(target
);
84 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
87 /* read debug register */
88 mips_ejtag_read_debug(ejtag_info
, &debug_reg
);
90 /* make sure break unit configured */
91 mips32_configure_break_unit(target
);
93 /* attempt to find halt reason */
94 mips_m4k_examine_debug_reason(target
);
96 /* clear single step if active */
97 if (debug_reg
& EJTAG_DEBUG_DSS
) {
98 /* stopped due to single step - clear step bit */
99 mips_ejtag_config_step(ejtag_info
, 0);
102 mips32_save_context(target
);
104 /* default to mips32 isa, it will be changed below if required */
105 mips32
->isa_mode
= MIPS32_ISA_MIPS32
;
107 if (ejtag_info
->impcode
& EJTAG_IMP_MIPS16
)
108 mips32
->isa_mode
= buf_get_u32(mips32
->core_cache
->reg_list
[MIPS32_PC
].value
, 0, 1);
110 LOG_DEBUG("entered debug state at PC 0x%" PRIx32
", target->state: %s",
111 buf_get_u32(mips32
->core_cache
->reg_list
[MIPS32_PC
].value
, 0, 32),
112 target_state_name(target
));
117 static int mips_m4k_poll(struct target
*target
)
120 struct mips32_common
*mips32
= target_to_mips32(target
);
121 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
122 uint32_t ejtag_ctrl
= ejtag_info
->ejtag_ctrl
;
124 /* read ejtag control reg */
125 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_CONTROL
);
126 retval
= mips_ejtag_drscan_32(ejtag_info
, &ejtag_ctrl
);
127 if (retval
!= ERROR_OK
)
130 /* clear this bit before handling polling
131 * as after reset registers will read zero */
132 if (ejtag_ctrl
& EJTAG_CTRL_ROCC
) {
133 /* we have detected a reset, clear flag
134 * otherwise ejtag will not work */
135 ejtag_ctrl
= ejtag_info
->ejtag_ctrl
& ~EJTAG_CTRL_ROCC
;
137 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_CONTROL
);
138 retval
= mips_ejtag_drscan_32(ejtag_info
, &ejtag_ctrl
);
139 if (retval
!= ERROR_OK
)
141 LOG_DEBUG("Reset Detected");
144 /* check for processor halted */
145 if (ejtag_ctrl
& EJTAG_CTRL_BRKST
) {
146 if (target
->state
== TARGET_UNKNOWN
) {
147 LOG_DEBUG("EJTAG_CTRL_BRKST already set during server startup.");
149 /* OpenOCD was was probably started on the board with EJTAG_CTRL_BRKST already set
150 * (maybe put on by HALT-ing the board in the previous session).
152 * Force target to RUNNING state to enable debug entry for this session.
154 target
->state
= TARGET_RUNNING
;
157 if ((target
->state
== TARGET_RUNNING
) || (target
->state
== TARGET_RESET
)) {
158 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_NORMALBOOT
);
160 target
->state
= TARGET_HALTED
;
162 retval
= mips_m4k_debug_entry(target
);
163 if (retval
!= ERROR_OK
)
166 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
167 } else if (target
->state
== TARGET_DEBUG_RUNNING
) {
168 target
->state
= TARGET_HALTED
;
170 retval
= mips_m4k_debug_entry(target
);
171 if (retval
!= ERROR_OK
)
174 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
177 target
->state
= TARGET_RUNNING
;
179 /* LOG_DEBUG("ctrl = 0x%08X", ejtag_ctrl); */
184 static int mips_m4k_halt(struct target
*target
)
186 struct mips32_common
*mips32
= target_to_mips32(target
);
187 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
189 LOG_DEBUG("target->state: %s", target_state_name(target
));
191 if (target
->state
== TARGET_HALTED
) {
192 LOG_DEBUG("target was already halted");
196 if (target
->state
== TARGET_UNKNOWN
)
197 LOG_WARNING("target was in unknown state when halt was requested");
199 if (target
->state
== TARGET_RESET
) {
200 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst()) {
201 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
202 return ERROR_TARGET_FAILURE
;
204 /* we came here in a reset_halt or reset_init sequence
205 * debug entry was already prepared in mips_m4k_assert_reset()
207 target
->debug_reason
= DBG_REASON_DBGRQ
;
213 /* break processor */
214 mips_ejtag_enter_debug(ejtag_info
);
216 target
->debug_reason
= DBG_REASON_DBGRQ
;
221 static int mips_m4k_assert_reset(struct target
*target
)
223 struct mips_m4k_common
*mips_m4k
= target_to_m4k(target
);
224 struct mips_ejtag
*ejtag_info
= &mips_m4k
->mips32
.ejtag_info
;
226 LOG_DEBUG("target->state: %s",
227 target_state_name(target
));
229 enum reset_types jtag_reset_config
= jtag_get_reset_config();
231 /* some cores support connecting while srst is asserted
232 * use that mode is it has been configured */
234 bool srst_asserted
= false;
236 if (!(jtag_reset_config
& RESET_SRST_PULLS_TRST
) &&
237 (jtag_reset_config
& RESET_SRST_NO_GATING
)) {
238 jtag_add_reset(0, 1);
239 srst_asserted
= true;
242 if (target
->reset_halt
) {
243 /* use hardware to catch reset */
244 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_EJTAGBOOT
);
246 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_NORMALBOOT
);
248 if (jtag_reset_config
& RESET_HAS_SRST
) {
249 /* here we should issue a srst only, but we may have to assert trst as well */
250 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
251 jtag_add_reset(1, 1);
252 else if (!srst_asserted
)
253 jtag_add_reset(0, 1);
255 if (mips_m4k
->is_pic32mx
) {
256 LOG_DEBUG("Using MTAP reset to reset processor...");
258 /* use microchip specific MTAP reset */
259 mips_ejtag_set_instr(ejtag_info
, MTAP_SW_MTAP
);
260 mips_ejtag_set_instr(ejtag_info
, MTAP_COMMAND
);
262 mips_ejtag_drscan_8_out(ejtag_info
, MCHP_ASERT_RST
);
263 mips_ejtag_drscan_8_out(ejtag_info
, MCHP_DE_ASSERT_RST
);
264 mips_ejtag_set_instr(ejtag_info
, MTAP_SW_ETAP
);
266 /* use ejtag reset - not supported by all cores */
267 uint32_t ejtag_ctrl
= ejtag_info
->ejtag_ctrl
| EJTAG_CTRL_PRRST
| EJTAG_CTRL_PERRST
;
268 LOG_DEBUG("Using EJTAG reset (PRRST) to reset processor...");
269 mips_ejtag_set_instr(ejtag_info
, EJTAG_INST_CONTROL
);
270 mips_ejtag_drscan_32_out(ejtag_info
, ejtag_ctrl
);
274 target
->state
= TARGET_RESET
;
275 jtag_add_sleep(50000);
277 register_cache_invalidate(mips_m4k
->mips32
.core_cache
);
279 if (target
->reset_halt
) {
280 int retval
= target_halt(target
);
281 if (retval
!= ERROR_OK
)
288 static int mips_m4k_deassert_reset(struct target
*target
)
290 LOG_DEBUG("target->state: %s", target_state_name(target
));
292 /* deassert reset lines */
293 jtag_add_reset(0, 0);
298 static int mips_m4k_soft_reset_halt(struct target
*target
)
304 static int mips_m4k_single_step_core(struct target
*target
)
306 struct mips32_common
*mips32
= target_to_mips32(target
);
307 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
309 /* configure single step mode */
310 mips_ejtag_config_step(ejtag_info
, 1);
312 /* disable interrupts while stepping */
313 mips32_enable_interrupts(target
, 0);
315 /* exit debug mode */
316 mips_ejtag_exit_debug(ejtag_info
);
318 mips_m4k_debug_entry(target
);
323 static int mips_m4k_resume(struct target
*target
, int current
,
324 uint32_t address
, int handle_breakpoints
, int debug_execution
)
326 struct mips32_common
*mips32
= target_to_mips32(target
);
327 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
328 struct breakpoint
*breakpoint
= NULL
;
331 if (target
->state
!= TARGET_HALTED
) {
332 LOG_WARNING("target not halted");
333 return ERROR_TARGET_NOT_HALTED
;
336 if (!debug_execution
) {
337 target_free_all_working_areas(target
);
338 mips_m4k_enable_breakpoints(target
);
339 mips_m4k_enable_watchpoints(target
);
342 /* current = 1: continue on current pc, otherwise continue at <address> */
344 buf_set_u32(mips32
->core_cache
->reg_list
[MIPS32_PC
].value
, 0, 32, address
);
345 mips32
->core_cache
->reg_list
[MIPS32_PC
].dirty
= 1;
346 mips32
->core_cache
->reg_list
[MIPS32_PC
].valid
= 1;
349 if (ejtag_info
->impcode
& EJTAG_IMP_MIPS16
)
350 buf_set_u32(mips32
->core_cache
->reg_list
[MIPS32_PC
].value
, 0, 1, mips32
->isa_mode
);
352 resume_pc
= buf_get_u32(mips32
->core_cache
->reg_list
[MIPS32_PC
].value
, 0, 32);
354 mips32_restore_context(target
);
356 /* the front-end may request us not to handle breakpoints */
357 if (handle_breakpoints
) {
358 /* Single step past breakpoint at current address */
359 breakpoint
= breakpoint_find(target
, resume_pc
);
361 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
"", breakpoint
->address
);
362 mips_m4k_unset_breakpoint(target
, breakpoint
);
363 mips_m4k_single_step_core(target
);
364 mips_m4k_set_breakpoint(target
, breakpoint
);
368 /* enable interrupts if we are running */
369 mips32_enable_interrupts(target
, !debug_execution
);
371 /* exit debug mode */
372 mips_ejtag_exit_debug(ejtag_info
);
373 target
->debug_reason
= DBG_REASON_NOTHALTED
;
375 /* registers are now invalid */
376 register_cache_invalidate(mips32
->core_cache
);
378 if (!debug_execution
) {
379 target
->state
= TARGET_RUNNING
;
380 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
381 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
383 target
->state
= TARGET_DEBUG_RUNNING
;
384 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
385 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
391 static int mips_m4k_step(struct target
*target
, int current
,
392 uint32_t address
, int handle_breakpoints
)
394 /* get pointers to arch-specific information */
395 struct mips32_common
*mips32
= target_to_mips32(target
);
396 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
397 struct breakpoint
*breakpoint
= NULL
;
399 if (target
->state
!= TARGET_HALTED
) {
400 LOG_WARNING("target not halted");
401 return ERROR_TARGET_NOT_HALTED
;
404 /* current = 1: continue on current pc, otherwise continue at <address> */
406 buf_set_u32(mips32
->core_cache
->reg_list
[MIPS32_PC
].value
, 0, 32, address
);
407 mips32
->core_cache
->reg_list
[MIPS32_PC
].dirty
= 1;
408 mips32
->core_cache
->reg_list
[MIPS32_PC
].valid
= 1;
411 /* the front-end may request us not to handle breakpoints */
412 if (handle_breakpoints
) {
413 breakpoint
= breakpoint_find(target
,
414 buf_get_u32(mips32
->core_cache
->reg_list
[MIPS32_PC
].value
, 0, 32));
416 mips_m4k_unset_breakpoint(target
, breakpoint
);
419 /* restore context */
420 mips32_restore_context(target
);
422 /* configure single step mode */
423 mips_ejtag_config_step(ejtag_info
, 1);
425 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
427 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
429 /* disable interrupts while stepping */
430 mips32_enable_interrupts(target
, 0);
432 /* exit debug mode */
433 mips_ejtag_exit_debug(ejtag_info
);
435 /* registers are now invalid */
436 register_cache_invalidate(mips32
->core_cache
);
439 mips_m4k_set_breakpoint(target
, breakpoint
);
441 LOG_DEBUG("target stepped ");
443 mips_m4k_debug_entry(target
);
444 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
449 static void mips_m4k_enable_breakpoints(struct target
*target
)
451 struct breakpoint
*breakpoint
= target
->breakpoints
;
453 /* set any pending breakpoints */
455 if (breakpoint
->set
== 0)
456 mips_m4k_set_breakpoint(target
, breakpoint
);
457 breakpoint
= breakpoint
->next
;
461 static int mips_m4k_set_breakpoint(struct target
*target
,
462 struct breakpoint
*breakpoint
)
464 struct mips32_common
*mips32
= target_to_mips32(target
);
465 struct mips32_comparator
*comparator_list
= mips32
->inst_break_list
;
468 if (breakpoint
->set
) {
469 LOG_WARNING("breakpoint already set");
473 if (breakpoint
->type
== BKPT_HARD
) {
476 while (comparator_list
[bp_num
].used
&& (bp_num
< mips32
->num_inst_bpoints
))
478 if (bp_num
>= mips32
->num_inst_bpoints
) {
479 LOG_ERROR("Can not find free FP Comparator(bpid: %d)",
480 breakpoint
->unique_id
);
481 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
483 breakpoint
->set
= bp_num
+ 1;
484 comparator_list
[bp_num
].used
= 1;
485 comparator_list
[bp_num
].bp_value
= breakpoint
->address
;
486 target_write_u32(target
, comparator_list
[bp_num
].reg_address
,
487 comparator_list
[bp_num
].bp_value
);
488 target_write_u32(target
, comparator_list
[bp_num
].reg_address
+ 0x08, 0x00000000);
489 target_write_u32(target
, comparator_list
[bp_num
].reg_address
+ 0x18, 1);
490 LOG_DEBUG("bpid: %d, bp_num %i bp_value 0x%" PRIx32
"",
491 breakpoint
->unique_id
,
492 bp_num
, comparator_list
[bp_num
].bp_value
);
493 } else if (breakpoint
->type
== BKPT_SOFT
) {
494 LOG_DEBUG("bpid: %d", breakpoint
->unique_id
);
495 if (breakpoint
->length
== 4) {
496 uint32_t verify
= 0xffffffff;
498 retval
= target_read_memory(target
, breakpoint
->address
, breakpoint
->length
, 1,
499 breakpoint
->orig_instr
);
500 if (retval
!= ERROR_OK
)
502 retval
= target_write_u32(target
, breakpoint
->address
, MIPS32_SDBBP
);
503 if (retval
!= ERROR_OK
)
506 retval
= target_read_u32(target
, breakpoint
->address
, &verify
);
507 if (retval
!= ERROR_OK
)
509 if (verify
!= MIPS32_SDBBP
) {
510 LOG_ERROR("Unable to set 32bit breakpoint at address %08" PRIx32
511 " - check that memory is read/writable", breakpoint
->address
);
515 uint16_t verify
= 0xffff;
517 retval
= target_read_memory(target
, breakpoint
->address
, breakpoint
->length
, 1,
518 breakpoint
->orig_instr
);
519 if (retval
!= ERROR_OK
)
521 retval
= target_write_u16(target
, breakpoint
->address
, MIPS16_SDBBP
);
522 if (retval
!= ERROR_OK
)
525 retval
= target_read_u16(target
, breakpoint
->address
, &verify
);
526 if (retval
!= ERROR_OK
)
528 if (verify
!= MIPS16_SDBBP
) {
529 LOG_ERROR("Unable to set 16bit breakpoint at address %08" PRIx32
530 " - check that memory is read/writable", breakpoint
->address
);
535 breakpoint
->set
= 20; /* Any nice value but 0 */
541 static int mips_m4k_unset_breakpoint(struct target
*target
,
542 struct breakpoint
*breakpoint
)
544 /* get pointers to arch-specific information */
545 struct mips32_common
*mips32
= target_to_mips32(target
);
546 struct mips32_comparator
*comparator_list
= mips32
->inst_break_list
;
549 if (!breakpoint
->set
) {
550 LOG_WARNING("breakpoint not set");
554 if (breakpoint
->type
== BKPT_HARD
) {
555 int bp_num
= breakpoint
->set
- 1;
556 if ((bp_num
< 0) || (bp_num
>= mips32
->num_inst_bpoints
)) {
557 LOG_DEBUG("Invalid FP Comparator number in breakpoint (bpid: %d)",
558 breakpoint
->unique_id
);
561 LOG_DEBUG("bpid: %d - releasing hw: %d",
562 breakpoint
->unique_id
,
564 comparator_list
[bp_num
].used
= 0;
565 comparator_list
[bp_num
].bp_value
= 0;
566 target_write_u32(target
, comparator_list
[bp_num
].reg_address
+ 0x18, 0);
569 /* restore original instruction (kept in target endianness) */
570 LOG_DEBUG("bpid: %d", breakpoint
->unique_id
);
571 if (breakpoint
->length
== 4) {
572 uint32_t current_instr
;
574 /* check that user program has not modified breakpoint instruction */
575 retval
= target_read_memory(target
, breakpoint
->address
, 4, 1,
576 (uint8_t *)¤t_instr
);
577 if (retval
!= ERROR_OK
)
581 * target_read_memory() gets us data in _target_ endianess.
582 * If we want to use this data on the host for comparisons with some macros
583 * we must first transform it to _host_ endianess using target_buffer_get_u32().
585 current_instr
= target_buffer_get_u32(target
, (uint8_t *)¤t_instr
);
587 if (current_instr
== MIPS32_SDBBP
) {
588 retval
= target_write_memory(target
, breakpoint
->address
, 4, 1,
589 breakpoint
->orig_instr
);
590 if (retval
!= ERROR_OK
)
594 uint16_t current_instr
;
596 /* check that user program has not modified breakpoint instruction */
597 retval
= target_read_memory(target
, breakpoint
->address
, 2, 1,
598 (uint8_t *)¤t_instr
);
599 if (retval
!= ERROR_OK
)
601 current_instr
= target_buffer_get_u16(target
, (uint8_t *)¤t_instr
);
602 if (current_instr
== MIPS16_SDBBP
) {
603 retval
= target_write_memory(target
, breakpoint
->address
, 2, 1,
604 breakpoint
->orig_instr
);
605 if (retval
!= ERROR_OK
)
615 static int mips_m4k_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
617 struct mips32_common
*mips32
= target_to_mips32(target
);
619 if (breakpoint
->type
== BKPT_HARD
) {
620 if (mips32
->num_inst_bpoints_avail
< 1) {
621 LOG_INFO("no hardware breakpoint available");
622 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
625 mips32
->num_inst_bpoints_avail
--;
628 return mips_m4k_set_breakpoint(target
, breakpoint
);
631 static int mips_m4k_remove_breakpoint(struct target
*target
,
632 struct breakpoint
*breakpoint
)
634 /* get pointers to arch-specific information */
635 struct mips32_common
*mips32
= target_to_mips32(target
);
637 if (target
->state
!= TARGET_HALTED
) {
638 LOG_WARNING("target not halted");
639 return ERROR_TARGET_NOT_HALTED
;
643 mips_m4k_unset_breakpoint(target
, breakpoint
);
645 if (breakpoint
->type
== BKPT_HARD
)
646 mips32
->num_inst_bpoints_avail
++;
651 static int mips_m4k_set_watchpoint(struct target
*target
,
652 struct watchpoint
*watchpoint
)
654 struct mips32_common
*mips32
= target_to_mips32(target
);
655 struct mips32_comparator
*comparator_list
= mips32
->data_break_list
;
658 * watchpoint enabled, ignore all byte lanes in value register
659 * and exclude both load and store accesses from watchpoint
660 * condition evaluation
662 int enable
= EJTAG_DBCn_NOSB
| EJTAG_DBCn_NOLB
| EJTAG_DBCn_BE
|
663 (0xff << EJTAG_DBCn_BLM_SHIFT
);
665 if (watchpoint
->set
) {
666 LOG_WARNING("watchpoint already set");
670 while (comparator_list
[wp_num
].used
&& (wp_num
< mips32
->num_data_bpoints
))
672 if (wp_num
>= mips32
->num_data_bpoints
) {
673 LOG_ERROR("Can not find free FP Comparator");
677 if (watchpoint
->length
!= 4) {
678 LOG_ERROR("Only watchpoints of length 4 are supported");
679 return ERROR_TARGET_UNALIGNED_ACCESS
;
682 if (watchpoint
->address
% 4) {
683 LOG_ERROR("Watchpoints address should be word aligned");
684 return ERROR_TARGET_UNALIGNED_ACCESS
;
687 switch (watchpoint
->rw
) {
689 enable
&= ~EJTAG_DBCn_NOLB
;
692 enable
&= ~EJTAG_DBCn_NOSB
;
695 enable
&= ~(EJTAG_DBCn_NOLB
| EJTAG_DBCn_NOSB
);
698 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
701 watchpoint
->set
= wp_num
+ 1;
702 comparator_list
[wp_num
].used
= 1;
703 comparator_list
[wp_num
].bp_value
= watchpoint
->address
;
704 target_write_u32(target
, comparator_list
[wp_num
].reg_address
, comparator_list
[wp_num
].bp_value
);
705 target_write_u32(target
, comparator_list
[wp_num
].reg_address
+ 0x08, 0x00000000);
706 target_write_u32(target
, comparator_list
[wp_num
].reg_address
+ 0x10, 0x00000000);
707 target_write_u32(target
, comparator_list
[wp_num
].reg_address
+ 0x18, enable
);
708 target_write_u32(target
, comparator_list
[wp_num
].reg_address
+ 0x20, 0);
709 LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32
"", wp_num
, comparator_list
[wp_num
].bp_value
);
714 static int mips_m4k_unset_watchpoint(struct target
*target
,
715 struct watchpoint
*watchpoint
)
717 /* get pointers to arch-specific information */
718 struct mips32_common
*mips32
= target_to_mips32(target
);
719 struct mips32_comparator
*comparator_list
= mips32
->data_break_list
;
721 if (!watchpoint
->set
) {
722 LOG_WARNING("watchpoint not set");
726 int wp_num
= watchpoint
->set
- 1;
727 if ((wp_num
< 0) || (wp_num
>= mips32
->num_data_bpoints
)) {
728 LOG_DEBUG("Invalid FP Comparator number in watchpoint");
731 comparator_list
[wp_num
].used
= 0;
732 comparator_list
[wp_num
].bp_value
= 0;
733 target_write_u32(target
, comparator_list
[wp_num
].reg_address
+ 0x18, 0);
739 static int mips_m4k_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
741 struct mips32_common
*mips32
= target_to_mips32(target
);
743 if (mips32
->num_data_bpoints_avail
< 1) {
744 LOG_INFO("no hardware watchpoints available");
745 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
748 mips32
->num_data_bpoints_avail
--;
750 mips_m4k_set_watchpoint(target
, watchpoint
);
754 static int mips_m4k_remove_watchpoint(struct target
*target
,
755 struct watchpoint
*watchpoint
)
757 /* get pointers to arch-specific information */
758 struct mips32_common
*mips32
= target_to_mips32(target
);
760 if (target
->state
!= TARGET_HALTED
) {
761 LOG_WARNING("target not halted");
762 return ERROR_TARGET_NOT_HALTED
;
766 mips_m4k_unset_watchpoint(target
, watchpoint
);
768 mips32
->num_data_bpoints_avail
++;
773 static void mips_m4k_enable_watchpoints(struct target
*target
)
775 struct watchpoint
*watchpoint
= target
->watchpoints
;
777 /* set any pending watchpoints */
779 if (watchpoint
->set
== 0)
780 mips_m4k_set_watchpoint(target
, watchpoint
);
781 watchpoint
= watchpoint
->next
;
785 static int mips_m4k_read_memory(struct target
*target
, uint32_t address
,
786 uint32_t size
, uint32_t count
, uint8_t *buffer
)
788 struct mips32_common
*mips32
= target_to_mips32(target
);
789 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
791 LOG_DEBUG("address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
792 address
, size
, count
);
794 if (target
->state
!= TARGET_HALTED
) {
795 LOG_WARNING("target not halted");
796 return ERROR_TARGET_NOT_HALTED
;
799 /* sanitize arguments */
800 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
801 return ERROR_COMMAND_SYNTAX_ERROR
;
803 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
804 return ERROR_TARGET_UNALIGNED_ACCESS
;
806 /* since we don't know if buffer is aligned, we allocate new mem that is always aligned */
810 t
= malloc(count
* size
* sizeof(uint8_t));
812 LOG_ERROR("Out of memory");
818 /* if noDMA off, use DMAACC mode for memory read */
820 if (ejtag_info
->impcode
& EJTAG_IMP_NODMA
)
821 retval
= mips32_pracc_read_mem(ejtag_info
, address
, size
, count
, t
);
823 retval
= mips32_dmaacc_read_mem(ejtag_info
, address
, size
, count
, t
);
825 /* mips32_..._read_mem with size 4/2 returns uint32_t/uint16_t in host */
826 /* endianness, but byte array should represent target endianness */
827 if (ERROR_OK
== retval
) {
830 target_buffer_set_u32_array(target
, buffer
, count
, t
);
833 target_buffer_set_u16_array(target
, buffer
, count
, t
);
838 if ((size
> 1) && (t
!= NULL
))
844 static int mips_m4k_write_memory(struct target
*target
, uint32_t address
,
845 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
847 struct mips32_common
*mips32
= target_to_mips32(target
);
848 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
850 LOG_DEBUG("address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"",
851 address
, size
, count
);
853 if (target
->state
!= TARGET_HALTED
) {
854 LOG_WARNING("target not halted");
855 return ERROR_TARGET_NOT_HALTED
;
858 /* sanitize arguments */
859 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
860 return ERROR_COMMAND_SYNTAX_ERROR
;
862 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
863 return ERROR_TARGET_UNALIGNED_ACCESS
;
865 /** correct endianess if we have word or hword access */
868 /* mips32_..._write_mem with size 4/2 requires uint32_t/uint16_t in host */
869 /* endianness, but byte array represents target endianness */
870 t
= malloc(count
* size
* sizeof(uint8_t));
872 LOG_ERROR("Out of memory");
878 target_buffer_get_u32_array(target
, buffer
, count
, (uint32_t *)t
);
881 target_buffer_get_u16_array(target
, buffer
, count
, (uint16_t *)t
);
887 /* if noDMA off, use DMAACC mode for memory write */
889 if (ejtag_info
->impcode
& EJTAG_IMP_NODMA
)
890 retval
= mips32_pracc_write_mem(ejtag_info
, address
, size
, count
, (void *)buffer
);
892 retval
= mips32_dmaacc_write_mem(ejtag_info
, address
, size
, count
, (void *)buffer
);
897 if (ERROR_OK
!= retval
)
903 static int mips_m4k_init_target(struct command_context
*cmd_ctx
,
904 struct target
*target
)
906 mips32_build_reg_cache(target
);
911 static int mips_m4k_init_arch_info(struct target
*target
,
912 struct mips_m4k_common
*mips_m4k
, struct jtag_tap
*tap
)
914 struct mips32_common
*mips32
= &mips_m4k
->mips32
;
916 mips_m4k
->common_magic
= MIPSM4K_COMMON_MAGIC
;
918 /* initialize mips4k specific info */
919 mips32_init_arch_info(target
, mips32
, tap
);
920 mips32
->arch_info
= mips_m4k
;
925 static int mips_m4k_target_create(struct target
*target
, Jim_Interp
*interp
)
927 struct mips_m4k_common
*mips_m4k
= calloc(1, sizeof(struct mips_m4k_common
));
929 mips_m4k_init_arch_info(target
, mips_m4k
, target
->tap
);
934 static int mips_m4k_examine(struct target
*target
)
937 struct mips_m4k_common
*mips_m4k
= target_to_m4k(target
);
938 struct mips_ejtag
*ejtag_info
= &mips_m4k
->mips32
.ejtag_info
;
941 if (!target_was_examined(target
)) {
942 retval
= mips_ejtag_get_idcode(ejtag_info
, &idcode
);
943 if (retval
!= ERROR_OK
)
945 ejtag_info
->idcode
= idcode
;
947 if (((idcode
>> 1) & 0x7FF) == 0x29) {
948 /* we are using a pic32mx so select ejtag port
949 * as it is not selected by default */
950 mips_ejtag_set_instr(ejtag_info
, MTAP_SW_ETAP
);
951 LOG_DEBUG("PIC32MX Detected - using EJTAG Interface");
952 mips_m4k
->is_pic32mx
= true;
956 /* init rest of ejtag interface */
957 retval
= mips_ejtag_init(ejtag_info
);
958 if (retval
!= ERROR_OK
)
961 retval
= mips32_examine(target
);
962 if (retval
!= ERROR_OK
)
968 static int mips_m4k_bulk_write_memory(struct target
*target
, uint32_t address
,
969 uint32_t count
, const uint8_t *buffer
)
971 struct mips32_common
*mips32
= target_to_mips32(target
);
972 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
976 LOG_DEBUG("address: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
"", address
, count
);
978 if (target
->state
!= TARGET_HALTED
) {
979 LOG_WARNING("target not halted");
980 return ERROR_TARGET_NOT_HALTED
;
983 /* check alignment */
985 return ERROR_TARGET_UNALIGNED_ACCESS
;
987 if (mips32
->fast_data_area
== NULL
) {
988 /* Get memory for block write handler
989 * we preserve this area between calls and gain a speed increase
990 * of about 3kb/sec when writing flash
991 * this will be released/nulled by the system when the target is resumed or reset */
992 retval
= target_alloc_working_area(target
,
993 MIPS32_FASTDATA_HANDLER_SIZE
,
994 &mips32
->fast_data_area
);
995 if (retval
!= ERROR_OK
) {
996 LOG_WARNING("No working area available, falling back to non-bulk write");
997 return mips_m4k_write_memory(target
, address
, 4, count
, buffer
);
1000 /* reset fastadata state so the algo get reloaded */
1001 ejtag_info
->fast_access_save
= -1;
1004 /* mips32_pracc_fastdata_xfer requires uint32_t in host endianness, */
1005 /* but byte array represents target endianness */
1007 t
= malloc(count
* sizeof(uint32_t));
1009 LOG_ERROR("Out of memory");
1013 target_buffer_get_u32_array(target
, buffer
, count
, t
);
1015 retval
= mips32_pracc_fastdata_xfer(ejtag_info
, mips32
->fast_data_area
, write_t
, address
,
1021 if (retval
!= ERROR_OK
) {
1022 /* FASTDATA access failed, try normal memory write */
1023 LOG_DEBUG("Fastdata access Failed, falling back to non-bulk write");
1024 retval
= mips_m4k_write_memory(target
, address
, 4, count
, buffer
);
1030 static int mips_m4k_verify_pointer(struct command_context
*cmd_ctx
,
1031 struct mips_m4k_common
*mips_m4k
)
1033 if (mips_m4k
->common_magic
!= MIPSM4K_COMMON_MAGIC
) {
1034 command_print(cmd_ctx
, "target is not an MIPS_M4K");
1035 return ERROR_TARGET_INVALID
;
1040 COMMAND_HANDLER(mips_m4k_handle_cp0_command
)
1043 struct target
*target
= get_current_target(CMD_CTX
);
1044 struct mips_m4k_common
*mips_m4k
= target_to_m4k(target
);
1045 struct mips_ejtag
*ejtag_info
= &mips_m4k
->mips32
.ejtag_info
;
1047 retval
= mips_m4k_verify_pointer(CMD_CTX
, mips_m4k
);
1048 if (retval
!= ERROR_OK
)
1051 if (target
->state
!= TARGET_HALTED
) {
1052 command_print(CMD_CTX
, "target must be stopped for \"%s\" command", CMD_NAME
);
1056 /* two or more argument, access a single register/select (write if third argument is given) */
1058 return ERROR_COMMAND_SYNTAX_ERROR
;
1060 uint32_t cp0_reg
, cp0_sel
;
1061 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], cp0_reg
);
1062 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], cp0_sel
);
1064 if (CMD_ARGC
== 2) {
1067 retval
= mips32_cp0_read(ejtag_info
, &value
, cp0_reg
, cp0_sel
);
1068 if (retval
!= ERROR_OK
) {
1069 command_print(CMD_CTX
,
1070 "couldn't access reg %" PRIi32
,
1074 retval
= jtag_execute_queue();
1075 if (retval
!= ERROR_OK
)
1078 command_print(CMD_CTX
, "cp0 reg %" PRIi32
", select %" PRIi32
": %8.8" PRIx32
,
1079 cp0_reg
, cp0_sel
, value
);
1080 } else if (CMD_ARGC
== 3) {
1082 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], value
);
1083 retval
= mips32_cp0_write(ejtag_info
, value
, cp0_reg
, cp0_sel
);
1084 if (retval
!= ERROR_OK
) {
1085 command_print(CMD_CTX
,
1086 "couldn't access cp0 reg %" PRIi32
", select %" PRIi32
,
1090 command_print(CMD_CTX
, "cp0 reg %" PRIi32
", select %" PRIi32
": %8.8" PRIx32
,
1091 cp0_reg
, cp0_sel
, value
);
1098 static const struct command_registration mips_m4k_exec_command_handlers
[] = {
1101 .handler
= mips_m4k_handle_cp0_command
,
1102 .mode
= COMMAND_EXEC
,
1103 .usage
= "regnum [value]",
1104 .help
= "display/modify cp0 register",
1106 COMMAND_REGISTRATION_DONE
1109 const struct command_registration mips_m4k_command_handlers
[] = {
1111 .chain
= mips32_command_handlers
,
1115 .mode
= COMMAND_ANY
,
1116 .help
= "mips_m4k command group",
1118 .chain
= mips_m4k_exec_command_handlers
,
1120 COMMAND_REGISTRATION_DONE
1123 struct target_type mips_m4k_target
= {
1126 .poll
= mips_m4k_poll
,
1127 .arch_state
= mips32_arch_state
,
1129 .target_request_data
= NULL
,
1131 .halt
= mips_m4k_halt
,
1132 .resume
= mips_m4k_resume
,
1133 .step
= mips_m4k_step
,
1135 .assert_reset
= mips_m4k_assert_reset
,
1136 .deassert_reset
= mips_m4k_deassert_reset
,
1137 .soft_reset_halt
= mips_m4k_soft_reset_halt
,
1139 .get_gdb_reg_list
= mips32_get_gdb_reg_list
,
1141 .read_memory
= mips_m4k_read_memory
,
1142 .write_memory
= mips_m4k_write_memory
,
1143 .bulk_write_memory
= mips_m4k_bulk_write_memory
,
1144 .checksum_memory
= mips32_checksum_memory
,
1145 .blank_check_memory
= mips32_blank_check_memory
,
1147 .run_algorithm
= mips32_run_algorithm
,
1149 .add_breakpoint
= mips_m4k_add_breakpoint
,
1150 .remove_breakpoint
= mips_m4k_remove_breakpoint
,
1151 .add_watchpoint
= mips_m4k_add_watchpoint
,
1152 .remove_watchpoint
= mips_m4k_remove_watchpoint
,
1154 .commands
= mips_m4k_command_handlers
,
1155 .target_create
= mips_m4k_target_create
,
1156 .init_target
= mips_m4k_init_target
,
1157 .examine
= mips_m4k_examine
,
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)