1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2006 by Magnus Lundin *
8 * Copyright (C) 2008 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
27 * Cortex-M3(tm) TRM, ARM DDI 0337E (r1p1) and 0337G (r2p0) *
29 ***************************************************************************/
34 #include "breakpoints.h"
35 #include "cortex_m3.h"
36 #include "target_request.h"
37 #include "target_type.h"
38 #include "arm_disassembler.h"
40 #include "arm_opcodes.h"
41 #include "arm_semihosting.h"
43 /* NOTE: most of this should work fine for the Cortex-M1 and
44 * Cortex-M0 cores too, although they're ARMv6-M not ARMv7-M.
45 * Some differences: M0/M1 doesn't have FBP remapping or the
46 * DWT tracing/profiling support. (So the cycle counter will
47 * not be usable; the other stuff isn't currently used here.)
49 * Although there are some workarounds for errata seen only in r0p0
50 * silicon, such old parts are hard to find and thus not much tested
55 /* forward declarations */
56 static int cortex_m3_set_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
);
57 static int cortex_m3_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
);
58 static void cortex_m3_enable_watchpoints(struct target
*target
);
59 static int cortex_m3_store_core_reg_u32(struct target
*target
,
60 enum armv7m_regtype type
, uint32_t num
, uint32_t value
);
62 static int cortexm3_dap_read_coreregister_u32(struct adiv5_dap
*swjdp
,
63 uint32_t *value
, int regnum
)
68 /* because the DCB_DCRDR is used for the emulated dcc channel
69 * we have to save/restore the DCB_DCRDR when used */
71 retval
= mem_ap_read_u32(swjdp
, DCB_DCRDR
, &dcrdr
);
72 if (retval
!= ERROR_OK
)
75 /* mem_ap_write_u32(swjdp, DCB_DCRSR, regnum); */
76 retval
= dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRSR
& 0xFFFFFFF0);
77 if (retval
!= ERROR_OK
)
79 retval
= dap_queue_ap_write(swjdp
, AP_REG_BD0
| (DCB_DCRSR
& 0xC), regnum
);
80 if (retval
!= ERROR_OK
)
83 /* mem_ap_read_u32(swjdp, DCB_DCRDR, value); */
84 retval
= dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRDR
& 0xFFFFFFF0);
85 if (retval
!= ERROR_OK
)
87 retval
= dap_queue_ap_read(swjdp
, AP_REG_BD0
| (DCB_DCRDR
& 0xC), value
);
88 if (retval
!= ERROR_OK
)
91 retval
= dap_run(swjdp
);
92 if (retval
!= ERROR_OK
)
95 /* restore DCB_DCRDR - this needs to be in a seperate
96 * transaction otherwise the emulated DCC channel breaks */
97 if (retval
== ERROR_OK
)
98 retval
= mem_ap_write_atomic_u32(swjdp
, DCB_DCRDR
, dcrdr
);
103 static int cortexm3_dap_write_coreregister_u32(struct adiv5_dap
*swjdp
,
104 uint32_t value
, int regnum
)
109 /* because the DCB_DCRDR is used for the emulated dcc channel
110 * we have to save/restore the DCB_DCRDR when used */
112 retval
= mem_ap_read_u32(swjdp
, DCB_DCRDR
, &dcrdr
);
113 if (retval
!= ERROR_OK
)
116 /* mem_ap_write_u32(swjdp, DCB_DCRDR, core_regs[i]); */
117 retval
= dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRDR
& 0xFFFFFFF0);
118 if (retval
!= ERROR_OK
)
120 retval
= dap_queue_ap_write(swjdp
, AP_REG_BD0
| (DCB_DCRDR
& 0xC), value
);
123 /* mem_ap_write_u32(swjdp, DCB_DCRSR, i | DCRSR_WnR); */
124 retval
= dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRSR
& 0xFFFFFFF0);
125 if (retval
!= ERROR_OK
)
127 retval
= dap_queue_ap_write(swjdp
, AP_REG_BD0
| (DCB_DCRSR
& 0xC), regnum
| DCRSR_WnR
);
130 retval
= dap_run(swjdp
);
132 /* restore DCB_DCRDR - this needs to be in a seperate
133 * transaction otherwise the emulated DCC channel breaks */
134 if (retval
== ERROR_OK
)
135 retval
= mem_ap_write_atomic_u32(swjdp
, DCB_DCRDR
, dcrdr
);
140 static int cortex_m3_write_debug_halt_mask(struct target
*target
,
141 uint32_t mask_on
, uint32_t mask_off
)
143 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
144 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
146 /* mask off status bits */
147 cortex_m3
->dcb_dhcsr
&= ~((0xFFFF << 16) | mask_off
);
148 /* create new register mask */
149 cortex_m3
->dcb_dhcsr
|= DBGKEY
| C_DEBUGEN
| mask_on
;
151 return mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, cortex_m3
->dcb_dhcsr
);
154 static int cortex_m3_clear_halt(struct target
*target
)
156 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
157 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
160 /* clear step if any */
161 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_STEP
);
163 /* Read Debug Fault Status Register */
164 retval
= mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
165 if (retval
!= ERROR_OK
)
168 /* Clear Debug Fault Status */
169 retval
= mem_ap_write_atomic_u32(swjdp
, NVIC_DFSR
, cortex_m3
->nvic_dfsr
);
170 if (retval
!= ERROR_OK
)
172 LOG_DEBUG(" NVIC_DFSR 0x%" PRIx32
"", cortex_m3
->nvic_dfsr
);
177 static int cortex_m3_single_step_core(struct target
*target
)
179 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
180 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
184 /* backup dhcsr reg */
185 dhcsr_save
= cortex_m3
->dcb_dhcsr
;
187 /* Mask interrupts before clearing halt, if done already. This avoids
188 * Erratum 377497 (fixed in r1p0) where setting MASKINTS while clearing
189 * HALT can put the core into an unknown state.
191 if (!(cortex_m3
->dcb_dhcsr
& C_MASKINTS
))
193 retval
= mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
,
194 DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
195 if (retval
!= ERROR_OK
)
198 retval
= mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
,
199 DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
200 if (retval
!= ERROR_OK
)
204 /* restore dhcsr reg */
205 cortex_m3
->dcb_dhcsr
= dhcsr_save
;
206 cortex_m3_clear_halt(target
);
211 static int cortex_m3_endreset_event(struct target
*target
)
216 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
217 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
218 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
219 struct cortex_m3_fp_comparator
*fp_list
= cortex_m3
->fp_comparator_list
;
220 struct cortex_m3_dwt_comparator
*dwt_list
= cortex_m3
->dwt_comparator_list
;
222 /* REVISIT The four debug monitor bits are currently ignored... */
223 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
224 if (retval
!= ERROR_OK
)
226 LOG_DEBUG("DCB_DEMCR = 0x%8.8" PRIx32
"",dcb_demcr
);
228 /* this register is used for emulated dcc channel */
229 retval
= mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
230 if (retval
!= ERROR_OK
)
233 /* Enable debug requests */
234 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
235 if (retval
!= ERROR_OK
)
237 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
239 retval
= mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
240 if (retval
!= ERROR_OK
)
244 /* clear any interrupt masking */
245 cortex_m3_write_debug_halt_mask(target
, 0, C_MASKINTS
);
247 /* Enable features controlled by ITM and DWT blocks, and catch only
248 * the vectors we were told to pay attention to.
250 * Target firmware is responsible for all fault handling policy
251 * choices *EXCEPT* explicitly scripted overrides like "vector_catch"
252 * or manual updates to the NVIC SHCSR and CCR registers.
254 retval
= mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| armv7m
->demcr
);
255 if (retval
!= ERROR_OK
)
258 /* Paranoia: evidently some (early?) chips don't preserve all the
259 * debug state (including FBP, DWT, etc) across reset...
263 retval
= target_write_u32(target
, FP_CTRL
, 3);
264 if (retval
!= ERROR_OK
)
267 cortex_m3
->fpb_enabled
= 1;
269 /* Restore FPB registers */
270 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
272 retval
= target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
273 if (retval
!= ERROR_OK
)
277 /* Restore DWT registers */
278 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
280 retval
= target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 0,
282 if (retval
!= ERROR_OK
)
284 retval
= target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 4,
286 if (retval
!= ERROR_OK
)
288 retval
= target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 8,
289 dwt_list
[i
].function
);
290 if (retval
!= ERROR_OK
)
293 retval
= dap_run(swjdp
);
294 if (retval
!= ERROR_OK
)
297 register_cache_invalidate(cortex_m3
->armv7m
.core_cache
);
299 /* make sure we have latest dhcsr flags */
300 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
305 static int cortex_m3_examine_debug_reason(struct target
*target
)
307 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
309 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
310 /* only check the debug reason if we don't know it already */
312 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
313 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
315 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
317 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
318 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
319 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
321 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
322 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
323 else if (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
)
324 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
325 else /* EXTERNAL, HALTED */
326 target
->debug_reason
= DBG_REASON_UNDEFINED
;
332 static int cortex_m3_examine_exception_reason(struct target
*target
)
334 uint32_t shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
335 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
336 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
339 retval
= mem_ap_read_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
340 if (retval
!= ERROR_OK
)
342 switch (armv7m
->exception_number
)
346 case 3: /* Hard Fault */
347 retval
= mem_ap_read_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
348 if (retval
!= ERROR_OK
)
350 if (except_sr
& 0x40000000)
352 retval
= mem_ap_read_u32(swjdp
, NVIC_CFSR
, &cfsr
);
353 if (retval
!= ERROR_OK
)
357 case 4: /* Memory Management */
358 retval
= mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
359 if (retval
!= ERROR_OK
)
361 retval
= mem_ap_read_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
362 if (retval
!= ERROR_OK
)
365 case 5: /* Bus Fault */
366 retval
= mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
367 if (retval
!= ERROR_OK
)
369 retval
= mem_ap_read_u32(swjdp
, NVIC_BFAR
, &except_ar
);
370 if (retval
!= ERROR_OK
)
373 case 6: /* Usage Fault */
374 retval
= mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
375 if (retval
!= ERROR_OK
)
378 case 11: /* SVCall */
380 case 12: /* Debug Monitor */
381 retval
= mem_ap_read_u32(swjdp
, NVIC_DFSR
, &except_sr
);
382 if (retval
!= ERROR_OK
)
385 case 14: /* PendSV */
387 case 15: /* SysTick */
393 retval
= dap_run(swjdp
);
394 if (retval
== ERROR_OK
)
395 LOG_DEBUG("%s SHCSR 0x%" PRIx32
", SR 0x%" PRIx32
396 ", CFSR 0x%" PRIx32
", AR 0x%" PRIx32
,
397 armv7m_exception_string(armv7m
->exception_number
),
398 shcsr
, except_sr
, cfsr
, except_ar
);
402 /* PSP is used in some thread modes */
403 static const int armv7m_psp_reg_map
[17] = {
404 ARMV7M_R0
, ARMV7M_R1
, ARMV7M_R2
, ARMV7M_R3
,
405 ARMV7M_R4
, ARMV7M_R5
, ARMV7M_R6
, ARMV7M_R7
,
406 ARMV7M_R8
, ARMV7M_R9
, ARMV7M_R10
, ARMV7M_R11
,
407 ARMV7M_R12
, ARMV7M_PSP
, ARMV7M_R14
, ARMV7M_PC
,
411 /* MSP is used in handler and some thread modes */
412 static const int armv7m_msp_reg_map
[17] = {
413 ARMV7M_R0
, ARMV7M_R1
, ARMV7M_R2
, ARMV7M_R3
,
414 ARMV7M_R4
, ARMV7M_R5
, ARMV7M_R6
, ARMV7M_R7
,
415 ARMV7M_R8
, ARMV7M_R9
, ARMV7M_R10
, ARMV7M_R11
,
416 ARMV7M_R12
, ARMV7M_MSP
, ARMV7M_R14
, ARMV7M_PC
,
420 static int cortex_m3_debug_entry(struct target
*target
)
425 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
426 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
427 struct arm
*arm
= &armv7m
->arm
;
428 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
433 cortex_m3_clear_halt(target
);
434 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
435 if (retval
!= ERROR_OK
)
438 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
441 /* Examine target state and mode */
442 /* First load register acessible through core debug port*/
443 int num_regs
= armv7m
->core_cache
->num_regs
;
445 for (i
= 0; i
< num_regs
; i
++)
447 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
448 armv7m
->read_core_reg(target
, i
);
451 r
= armv7m
->core_cache
->reg_list
+ ARMV7M_xPSR
;
452 xPSR
= buf_get_u32(r
->value
, 0, 32);
454 #ifdef ARMV7_GDB_HACKS
455 /* FIXME this breaks on scan chains with more than one Cortex-M3.
456 * Instead, each CM3 should have its own dummy value...
458 /* copy real xpsr reg for gdb, setting thumb bit */
459 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 0, 32, xPSR
);
460 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 5, 1, 1);
461 armv7m_gdb_dummy_cpsr_reg
.valid
= r
->valid
;
462 armv7m_gdb_dummy_cpsr_reg
.dirty
= r
->dirty
;
465 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
469 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
472 /* Are we in an exception handler */
475 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
476 armv7m
->exception_number
= (xPSR
& 0x1FF);
478 arm
->core_mode
= ARM_MODE_HANDLER
;
479 arm
->map
= armv7m_msp_reg_map
;
483 unsigned control
= buf_get_u32(armv7m
->core_cache
484 ->reg_list
[ARMV7M_CONTROL
].value
, 0, 2);
486 /* is this thread privileged? */
487 armv7m
->core_mode
= control
& 1;
488 arm
->core_mode
= armv7m
->core_mode
489 ? ARM_MODE_USER_THREAD
492 /* which stack is it using? */
494 arm
->map
= armv7m_psp_reg_map
;
496 arm
->map
= armv7m_msp_reg_map
;
498 armv7m
->exception_number
= 0;
501 if (armv7m
->exception_number
)
503 cortex_m3_examine_exception_reason(target
);
506 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32
", target->state: %s",
507 armv7m_mode_strings
[armv7m
->core_mode
],
508 *(uint32_t*)(arm
->pc
->value
),
509 target_state_name(target
));
511 if (armv7m
->post_debug_entry
)
513 retval
= armv7m
->post_debug_entry(target
);
514 if (retval
!= ERROR_OK
)
521 static int cortex_m3_poll(struct target
*target
)
523 int detected_failure
= ERROR_OK
;
524 int retval
= ERROR_OK
;
525 enum target_state prev_target_state
= target
->state
;
526 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
527 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
529 /* Read from Debug Halting Control and Status Register */
530 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
531 if (retval
!= ERROR_OK
)
533 target
->state
= TARGET_UNKNOWN
;
537 /* Recover from lockup. See ARMv7-M architecture spec,
538 * section B1.5.15 "Unrecoverable exception cases".
540 if (cortex_m3
->dcb_dhcsr
& S_LOCKUP
) {
541 LOG_ERROR("%s -- clearing lockup after double fault",
542 target_name(target
));
543 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
544 target
->debug_reason
= DBG_REASON_DBGRQ
;
546 /* We have to execute the rest (the "finally" equivalent, but
547 * still throw this exception again).
549 detected_failure
= ERROR_FAIL
;
551 /* refresh status bits */
552 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
553 if (retval
!= ERROR_OK
)
557 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
559 /* check if still in reset */
560 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
561 if (retval
!= ERROR_OK
)
564 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
566 target
->state
= TARGET_RESET
;
571 if (target
->state
== TARGET_RESET
)
573 /* Cannot switch context while running so endreset is
574 * called with target->state == TARGET_RESET
576 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%" PRIx32
,
577 cortex_m3
->dcb_dhcsr
);
578 cortex_m3_endreset_event(target
);
579 target
->state
= TARGET_RUNNING
;
580 prev_target_state
= TARGET_RUNNING
;
583 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
585 target
->state
= TARGET_HALTED
;
587 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
589 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
592 if (arm_semihosting(target
, &retval
) != 0)
595 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
597 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
600 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
603 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
607 /* REVISIT when S_SLEEP is set, it's in a Sleep or DeepSleep state.
608 * How best to model low power modes?
611 if (target
->state
== TARGET_UNKNOWN
)
613 /* check if processor is retiring instructions */
614 if (cortex_m3
->dcb_dhcsr
& S_RETIRE_ST
)
616 target
->state
= TARGET_RUNNING
;
621 /* Did we detect a failure condition that we cleared? */
622 if (detected_failure
!= ERROR_OK
)
623 retval
= detected_failure
;
627 static int cortex_m3_halt(struct target
*target
)
629 LOG_DEBUG("target->state: %s",
630 target_state_name(target
));
632 if (target
->state
== TARGET_HALTED
)
634 LOG_DEBUG("target was already halted");
638 if (target
->state
== TARGET_UNKNOWN
)
640 LOG_WARNING("target was in unknown state when halt was requested");
643 if (target
->state
== TARGET_RESET
)
645 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst())
647 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
648 return ERROR_TARGET_FAILURE
;
652 /* we came here in a reset_halt or reset_init sequence
653 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
655 target
->debug_reason
= DBG_REASON_DBGRQ
;
661 /* Write to Debug Halting Control and Status Register */
662 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
664 target
->debug_reason
= DBG_REASON_DBGRQ
;
669 static int cortex_m3_soft_reset_halt(struct target
*target
)
671 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
672 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
673 uint32_t dcb_dhcsr
= 0;
674 int retval
, timeout
= 0;
676 /* Enter debug state on reset; restore DEMCR in endreset_event() */
677 retval
= mem_ap_write_u32(swjdp
, DCB_DEMCR
,
678 TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
679 if (retval
!= ERROR_OK
)
682 /* Request a core-only reset */
683 retval
= mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
,
684 AIRCR_VECTKEY
| AIRCR_VECTRESET
);
685 if (retval
!= ERROR_OK
)
687 target
->state
= TARGET_RESET
;
689 /* registers are now invalid */
690 register_cache_invalidate(cortex_m3
->armv7m
.core_cache
);
692 while (timeout
< 100)
694 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
695 if (retval
== ERROR_OK
)
697 retval
= mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
,
698 &cortex_m3
->nvic_dfsr
);
699 if (retval
!= ERROR_OK
)
701 if ((dcb_dhcsr
& S_HALT
)
702 && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
704 LOG_DEBUG("system reset-halted, DHCSR 0x%08x, "
706 (unsigned) dcb_dhcsr
,
707 (unsigned) cortex_m3
->nvic_dfsr
);
708 cortex_m3_poll(target
);
709 /* FIXME restore user's vector catch config */
713 LOG_DEBUG("waiting for system reset-halt, "
714 "DHCSR 0x%08x, %d ms",
715 (unsigned) dcb_dhcsr
, timeout
);
724 static void cortex_m3_enable_breakpoints(struct target
*target
)
726 struct breakpoint
*breakpoint
= target
->breakpoints
;
728 /* set any pending breakpoints */
731 if (!breakpoint
->set
)
732 cortex_m3_set_breakpoint(target
, breakpoint
);
733 breakpoint
= breakpoint
->next
;
737 static int cortex_m3_resume(struct target
*target
, int current
,
738 uint32_t address
, int handle_breakpoints
, int debug_execution
)
740 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
741 struct breakpoint
*breakpoint
= NULL
;
745 if (target
->state
!= TARGET_HALTED
)
747 LOG_WARNING("target not halted");
748 return ERROR_TARGET_NOT_HALTED
;
751 if (!debug_execution
)
753 target_free_all_working_areas(target
);
754 cortex_m3_enable_breakpoints(target
);
755 cortex_m3_enable_watchpoints(target
);
760 r
= armv7m
->core_cache
->reg_list
+ ARMV7M_PRIMASK
;
762 /* Disable interrupts */
763 /* We disable interrupts in the PRIMASK register instead of
764 * masking with C_MASKINTS. This is probably the same issue
765 * as Cortex-M3 Erratum 377493 (fixed in r1p0): C_MASKINTS
766 * in parallel with disabled interrupts can cause local faults
769 * REVISIT this clearly breaks non-debug execution, since the
770 * PRIMASK register state isn't saved/restored... workaround
771 * by never resuming app code after debug execution.
773 buf_set_u32(r
->value
, 0, 1, 1);
777 /* Make sure we are in Thumb mode */
778 r
= armv7m
->core_cache
->reg_list
+ ARMV7M_xPSR
;
779 buf_set_u32(r
->value
, 24, 1, 1);
784 /* current = 1: continue on current pc, otherwise continue at <address> */
788 buf_set_u32(r
->value
, 0, 32, address
);
793 /* if we halted last time due to a bkpt instruction
794 * then we have to manually step over it, otherwise
795 * the core will break again */
797 if (!breakpoint_find(target
, buf_get_u32(r
->value
, 0, 32))
800 armv7m_maybe_skip_bkpt_inst(target
, NULL
);
803 resume_pc
= buf_get_u32(r
->value
, 0, 32);
805 armv7m_restore_context(target
);
807 /* the front-end may request us not to handle breakpoints */
808 if (handle_breakpoints
)
810 /* Single step past breakpoint at current address */
811 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
813 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
" (ID: %d)",
815 breakpoint
->unique_id
);
816 cortex_m3_unset_breakpoint(target
, breakpoint
);
817 cortex_m3_single_step_core(target
);
818 cortex_m3_set_breakpoint(target
, breakpoint
);
823 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
825 target
->debug_reason
= DBG_REASON_NOTHALTED
;
827 /* registers are now invalid */
828 register_cache_invalidate(armv7m
->core_cache
);
830 if (!debug_execution
)
832 target
->state
= TARGET_RUNNING
;
833 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
834 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
838 target
->state
= TARGET_DEBUG_RUNNING
;
839 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
840 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
846 /* int irqstepcount = 0; */
847 static int cortex_m3_step(struct target
*target
, int current
,
848 uint32_t address
, int handle_breakpoints
)
850 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
851 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
852 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
853 struct breakpoint
*breakpoint
= NULL
;
854 struct reg
*pc
= armv7m
->arm
.pc
;
855 bool bkpt_inst_found
= false;
857 if (target
->state
!= TARGET_HALTED
)
859 LOG_WARNING("target not halted");
860 return ERROR_TARGET_NOT_HALTED
;
863 /* current = 1: continue on current pc, otherwise continue at <address> */
865 buf_set_u32(pc
->value
, 0, 32, address
);
867 /* the front-end may request us not to handle breakpoints */
868 if (handle_breakpoints
) {
869 breakpoint
= breakpoint_find(target
,
870 buf_get_u32(pc
->value
, 0, 32));
872 cortex_m3_unset_breakpoint(target
, breakpoint
);
875 armv7m_maybe_skip_bkpt_inst(target
, &bkpt_inst_found
);
877 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
879 armv7m_restore_context(target
);
881 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
883 /* if no bkpt instruction is found at pc then we can perform
884 * a normal step, otherwise we have to manually step over the bkpt
885 * instruction - as such simulate a step */
886 if (bkpt_inst_found
== false)
888 /* set step and clear halt */
889 cortex_m3_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
893 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
894 if (retval
!= ERROR_OK
)
897 /* registers are now invalid */
898 register_cache_invalidate(cortex_m3
->armv7m
.core_cache
);
901 cortex_m3_set_breakpoint(target
, breakpoint
);
903 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
904 " nvic_icsr = 0x%" PRIx32
,
905 cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
907 retval
= cortex_m3_debug_entry(target
);
908 if (retval
!= ERROR_OK
)
910 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
912 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
913 " nvic_icsr = 0x%" PRIx32
,
914 cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
919 static int cortex_m3_assert_reset(struct target
*target
)
921 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
922 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
923 enum cortex_m3_soft_reset_config reset_config
= cortex_m3
->soft_reset_config
;
925 LOG_DEBUG("target->state: %s",
926 target_state_name(target
));
928 enum reset_types jtag_reset_config
= jtag_get_reset_config();
930 /* Enable debug requests */
932 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
933 if (retval
!= ERROR_OK
)
935 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
937 retval
= mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
938 if (retval
!= ERROR_OK
)
942 retval
= mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
943 if (retval
!= ERROR_OK
)
946 if (!target
->reset_halt
)
948 /* Set/Clear C_MASKINTS in a separate operation */
949 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
951 retval
= mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
,
952 DBGKEY
| C_DEBUGEN
| C_HALT
);
953 if (retval
!= ERROR_OK
)
957 /* clear any debug flags before resuming */
958 cortex_m3_clear_halt(target
);
960 /* clear C_HALT in dhcsr reg */
961 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
965 /* Halt in debug on reset; endreset_event() restores DEMCR.
967 * REVISIT catching BUSERR presumably helps to defend against
968 * bad vector table entries. Should this include MMERR or
971 retval
= mem_ap_write_atomic_u32(swjdp
, DCB_DEMCR
,
972 TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
973 if (retval
!= ERROR_OK
)
977 if (jtag_reset_config
& RESET_HAS_SRST
)
979 /* default to asserting srst */
980 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
982 jtag_add_reset(1, 1);
986 jtag_add_reset(0, 1);
991 /* Use a standard Cortex-M3 software reset mechanism.
992 * We default to using VECRESET as it is supported on all current cores.
993 * This has the disadvantage of not resetting the peripherals, so a
994 * reset-init event handler is needed to perform any peripheral resets.
996 retval
= mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
,
997 AIRCR_VECTKEY
| ((reset_config
== CORTEX_M3_RESET_SYSRESETREQ
)
998 ? AIRCR_SYSRESETREQ
: AIRCR_VECTRESET
));
999 if (retval
!= ERROR_OK
)
1002 LOG_DEBUG("Using Cortex-M3 %s", (reset_config
== CORTEX_M3_RESET_SYSRESETREQ
)
1003 ? "SYSRESETREQ" : "VECTRESET");
1005 if (reset_config
== CORTEX_M3_RESET_VECTRESET
) {
1006 LOG_WARNING("Only resetting the Cortex-M3 core, use a reset-init event "
1007 "handler to reset any peripherals");
1011 /* I do not know why this is necessary, but it
1012 * fixes strange effects (step/resume cause NMI
1013 * after reset) on LM3S6918 -- Michael Schwingen
1016 retval
= mem_ap_read_atomic_u32(swjdp
, NVIC_AIRCR
, &tmp
);
1017 if (retval
!= ERROR_OK
)
1022 target
->state
= TARGET_RESET
;
1023 jtag_add_sleep(50000);
1025 register_cache_invalidate(cortex_m3
->armv7m
.core_cache
);
1027 if (target
->reset_halt
)
1029 if ((retval
= target_halt(target
)) != ERROR_OK
)
1036 static int cortex_m3_deassert_reset(struct target
*target
)
1038 LOG_DEBUG("target->state: %s",
1039 target_state_name(target
));
1041 /* deassert reset lines */
1042 jtag_add_reset(0, 0);
1048 cortex_m3_set_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1053 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1054 struct cortex_m3_fp_comparator
*comparator_list
= cortex_m3
->fp_comparator_list
;
1056 if (breakpoint
->set
)
1058 LOG_WARNING("breakpoint (BPID: %d) already set", breakpoint
->unique_id
);
1062 if (cortex_m3
->auto_bp_type
)
1064 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1067 if (breakpoint
->type
== BKPT_HARD
)
1069 while (comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
1071 if (fp_num
>= cortex_m3
->fp_num_code
)
1073 LOG_ERROR("Can not find free FPB Comparator!");
1076 breakpoint
->set
= fp_num
+ 1;
1077 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
1078 comparator_list
[fp_num
].used
= 1;
1079 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
1080 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
1081 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32
"", fp_num
, comparator_list
[fp_num
].fpcr_value
);
1082 if (!cortex_m3
->fpb_enabled
)
1084 LOG_DEBUG("FPB wasn't enabled, do it now");
1085 target_write_u32(target
, FP_CTRL
, 3);
1088 else if (breakpoint
->type
== BKPT_SOFT
)
1092 /* NOTE: on ARMv6-M and ARMv7-M, BKPT(0xab) is used for
1093 * semihosting; don't use that. Otherwise the BKPT
1094 * parameter is arbitrary.
1096 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1097 retval
= target_read_memory(target
,
1098 breakpoint
->address
& 0xFFFFFFFE,
1099 breakpoint
->length
, 1,
1100 breakpoint
->orig_instr
);
1101 if (retval
!= ERROR_OK
)
1103 retval
= target_write_memory(target
,
1104 breakpoint
->address
& 0xFFFFFFFE,
1105 breakpoint
->length
, 1,
1107 if (retval
!= ERROR_OK
)
1109 breakpoint
->set
= true;
1112 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
1113 breakpoint
->unique_id
,
1114 (int)(breakpoint
->type
),
1115 breakpoint
->address
,
1123 cortex_m3_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1126 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1127 struct cortex_m3_fp_comparator
* comparator_list
= cortex_m3
->fp_comparator_list
;
1129 if (!breakpoint
->set
)
1131 LOG_WARNING("breakpoint not set");
1135 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
1136 breakpoint
->unique_id
,
1137 (int)(breakpoint
->type
),
1138 breakpoint
->address
,
1142 if (breakpoint
->type
== BKPT_HARD
)
1144 int fp_num
= breakpoint
->set
- 1;
1145 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
1147 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
1150 comparator_list
[fp_num
].used
= 0;
1151 comparator_list
[fp_num
].fpcr_value
= 0;
1152 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
1156 /* restore original instruction (kept in target endianness) */
1157 if (breakpoint
->length
== 4)
1159 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
1166 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
1172 breakpoint
->set
= false;
1178 cortex_m3_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1180 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1182 if (cortex_m3
->auto_bp_type
)
1184 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1185 #ifdef ARMV7_GDB_HACKS
1186 if (breakpoint
->length
!= 2) {
1187 /* XXX Hack: Replace all breakpoints with length != 2 with
1188 * a hardware breakpoint. */
1189 breakpoint
->type
= BKPT_HARD
;
1190 breakpoint
->length
= 2;
1195 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
1197 LOG_INFO("flash patch comparator requested outside code memory region");
1198 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1201 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
1203 LOG_INFO("soft breakpoint requested in code (flash) memory region");
1204 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1207 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
1209 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
1210 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1213 if ((breakpoint
->length
!= 2))
1215 LOG_INFO("only breakpoints of two bytes length supported");
1216 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1219 if (breakpoint
->type
== BKPT_HARD
)
1220 cortex_m3
->fp_code_available
--;
1222 return cortex_m3_set_breakpoint(target
, breakpoint
);
1226 cortex_m3_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1228 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1230 /* REVISIT why check? FBP can be updated with core running ... */
1231 if (target
->state
!= TARGET_HALTED
)
1233 LOG_WARNING("target not halted");
1234 return ERROR_TARGET_NOT_HALTED
;
1237 if (cortex_m3
->auto_bp_type
)
1239 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1242 if (breakpoint
->set
)
1244 cortex_m3_unset_breakpoint(target
, breakpoint
);
1247 if (breakpoint
->type
== BKPT_HARD
)
1248 cortex_m3
->fp_code_available
++;
1254 cortex_m3_set_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1257 uint32_t mask
, temp
;
1258 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1260 /* watchpoint params were validated earlier */
1262 temp
= watchpoint
->length
;
1269 /* REVISIT Don't fully trust these "not used" records ... users
1270 * may set up breakpoints by hand, e.g. dual-address data value
1271 * watchpoint using comparator #1; comparator #0 matching cycle
1272 * count; send data trace info through ITM and TPIU; etc
1274 struct cortex_m3_dwt_comparator
*comparator
;
1276 for (comparator
= cortex_m3
->dwt_comparator_list
;
1277 comparator
->used
&& dwt_num
< cortex_m3
->dwt_num_comp
;
1278 comparator
++, dwt_num
++)
1280 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
1282 LOG_ERROR("Can not find free DWT Comparator");
1285 comparator
->used
= 1;
1286 watchpoint
->set
= dwt_num
+ 1;
1288 comparator
->comp
= watchpoint
->address
;
1289 target_write_u32(target
, comparator
->dwt_comparator_address
+ 0,
1292 comparator
->mask
= mask
;
1293 target_write_u32(target
, comparator
->dwt_comparator_address
+ 4,
1296 switch (watchpoint
->rw
) {
1298 comparator
->function
= 5;
1301 comparator
->function
= 6;
1304 comparator
->function
= 7;
1307 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1308 comparator
->function
);
1310 LOG_DEBUG("Watchpoint (ID %d) DWT%d 0x%08x 0x%x 0x%05x",
1311 watchpoint
->unique_id
, dwt_num
,
1312 (unsigned) comparator
->comp
,
1313 (unsigned) comparator
->mask
,
1314 (unsigned) comparator
->function
);
1319 cortex_m3_unset_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1321 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1322 struct cortex_m3_dwt_comparator
*comparator
;
1325 if (!watchpoint
->set
)
1327 LOG_WARNING("watchpoint (wpid: %d) not set",
1328 watchpoint
->unique_id
);
1332 dwt_num
= watchpoint
->set
- 1;
1334 LOG_DEBUG("Watchpoint (ID %d) DWT%d address: 0x%08x clear",
1335 watchpoint
->unique_id
, dwt_num
,
1336 (unsigned) watchpoint
->address
);
1338 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1340 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1344 comparator
= cortex_m3
->dwt_comparator_list
+ dwt_num
;
1345 comparator
->used
= 0;
1346 comparator
->function
= 0;
1347 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1348 comparator
->function
);
1350 watchpoint
->set
= false;
1356 cortex_m3_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1358 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1360 if (cortex_m3
->dwt_comp_available
< 1)
1362 LOG_DEBUG("no comparators?");
1363 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1366 /* hardware doesn't support data value masking */
1367 if (watchpoint
->mask
!= ~(uint32_t)0) {
1368 LOG_DEBUG("watchpoint value masks not supported");
1369 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1372 /* hardware allows address masks of up to 32K */
1375 for (mask
= 0; mask
< 16; mask
++) {
1376 if ((1u << mask
) == watchpoint
->length
)
1380 LOG_DEBUG("unsupported watchpoint length");
1381 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1383 if (watchpoint
->address
& ((1 << mask
) - 1)) {
1384 LOG_DEBUG("watchpoint address is unaligned");
1385 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1388 /* Caller doesn't seem to be able to describe watching for data
1389 * values of zero; that flags "no value".
1391 * REVISIT This DWT may well be able to watch for specific data
1392 * values. Requires comparator #1 to set DATAVMATCH and match
1393 * the data, and another comparator (DATAVADDR0) matching addr.
1395 if (watchpoint
->value
) {
1396 LOG_DEBUG("data value watchpoint not YET supported");
1397 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1400 cortex_m3
->dwt_comp_available
--;
1401 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1407 cortex_m3_remove_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1409 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1411 /* REVISIT why check? DWT can be updated with core running ... */
1412 if (target
->state
!= TARGET_HALTED
)
1414 LOG_WARNING("target not halted");
1415 return ERROR_TARGET_NOT_HALTED
;
1418 if (watchpoint
->set
)
1420 cortex_m3_unset_watchpoint(target
, watchpoint
);
1423 cortex_m3
->dwt_comp_available
++;
1424 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1429 static void cortex_m3_enable_watchpoints(struct target
*target
)
1431 struct watchpoint
*watchpoint
= target
->watchpoints
;
1433 /* set any pending watchpoints */
1436 if (!watchpoint
->set
)
1437 cortex_m3_set_watchpoint(target
, watchpoint
);
1438 watchpoint
= watchpoint
->next
;
1442 static int cortex_m3_load_core_reg_u32(struct target
*target
,
1443 enum armv7m_regtype type
, uint32_t num
, uint32_t * value
)
1446 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1447 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1449 /* NOTE: we "know" here that the register identifiers used
1450 * in the v7m header match the Cortex-M3 Debug Core Register
1451 * Selector values for R0..R15, xPSR, MSP, and PSP.
1455 /* read a normal core register */
1456 retval
= cortexm3_dap_read_coreregister_u32(swjdp
, value
, num
);
1458 if (retval
!= ERROR_OK
)
1460 LOG_ERROR("JTAG failure %i",retval
);
1461 return ERROR_JTAG_DEVICE_ERROR
;
1463 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
"",(int)num
,*value
);
1466 case ARMV7M_PRIMASK
:
1467 case ARMV7M_BASEPRI
:
1468 case ARMV7M_FAULTMASK
:
1469 case ARMV7M_CONTROL
:
1470 /* Cortex-M3 packages these four registers as bitfields
1471 * in one Debug Core register. So say r0 and r2 docs;
1472 * it was removed from r1 docs, but still works.
1474 cortexm3_dap_read_coreregister_u32(swjdp
, value
, 20);
1478 case ARMV7M_PRIMASK
:
1479 *value
= buf_get_u32((uint8_t*)value
, 0, 1);
1482 case ARMV7M_BASEPRI
:
1483 *value
= buf_get_u32((uint8_t*)value
, 8, 8);
1486 case ARMV7M_FAULTMASK
:
1487 *value
= buf_get_u32((uint8_t*)value
, 16, 1);
1490 case ARMV7M_CONTROL
:
1491 *value
= buf_get_u32((uint8_t*)value
, 24, 2);
1495 LOG_DEBUG("load from special reg %i value 0x%" PRIx32
"", (int)num
, *value
);
1499 return ERROR_INVALID_ARGUMENTS
;
1505 static int cortex_m3_store_core_reg_u32(struct target
*target
,
1506 enum armv7m_regtype type
, uint32_t num
, uint32_t value
)
1510 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1511 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1513 #ifdef ARMV7_GDB_HACKS
1514 /* If the LR register is being modified, make sure it will put us
1515 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1516 * hack to deal with the fact that gdb will sometimes "forge"
1517 * return addresses, and doesn't set the LSB correctly (i.e., when
1518 * printing expressions containing function calls, it sets LR = 0.)
1519 * Valid exception return codes have bit 0 set too.
1521 if (num
== ARMV7M_R14
)
1525 /* NOTE: we "know" here that the register identifiers used
1526 * in the v7m header match the Cortex-M3 Debug Core Register
1527 * Selector values for R0..R15, xPSR, MSP, and PSP.
1531 retval
= cortexm3_dap_write_coreregister_u32(swjdp
, value
, num
);
1532 if (retval
!= ERROR_OK
)
1536 LOG_ERROR("JTAG failure %i", retval
);
1537 r
= armv7m
->core_cache
->reg_list
+ num
;
1538 r
->dirty
= r
->valid
;
1539 return ERROR_JTAG_DEVICE_ERROR
;
1541 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", (int)num
, value
);
1544 case ARMV7M_PRIMASK
:
1545 case ARMV7M_BASEPRI
:
1546 case ARMV7M_FAULTMASK
:
1547 case ARMV7M_CONTROL
:
1548 /* Cortex-M3 packages these four registers as bitfields
1549 * in one Debug Core register. So say r0 and r2 docs;
1550 * it was removed from r1 docs, but still works.
1552 cortexm3_dap_read_coreregister_u32(swjdp
, ®
, 20);
1556 case ARMV7M_PRIMASK
:
1557 buf_set_u32((uint8_t*)®
, 0, 1, value
);
1560 case ARMV7M_BASEPRI
:
1561 buf_set_u32((uint8_t*)®
, 8, 8, value
);
1564 case ARMV7M_FAULTMASK
:
1565 buf_set_u32((uint8_t*)®
, 16, 1, value
);
1568 case ARMV7M_CONTROL
:
1569 buf_set_u32((uint8_t*)®
, 24, 2, value
);
1573 cortexm3_dap_write_coreregister_u32(swjdp
, reg
, 20);
1575 LOG_DEBUG("write special reg %i value 0x%" PRIx32
" ", (int)num
, value
);
1579 return ERROR_INVALID_ARGUMENTS
;
1585 static int cortex_m3_read_memory(struct target
*target
, uint32_t address
,
1586 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1588 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1589 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1590 int retval
= ERROR_INVALID_ARGUMENTS
;
1592 /* cortex_m3 handles unaligned memory access */
1593 if (count
&& buffer
) {
1596 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1599 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1602 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1610 static int cortex_m3_write_memory(struct target
*target
, uint32_t address
,
1611 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1613 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1614 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1615 int retval
= ERROR_INVALID_ARGUMENTS
;
1617 if (count
&& buffer
) {
1620 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1623 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1626 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1634 static int cortex_m3_bulk_write_memory(struct target
*target
, uint32_t address
,
1635 uint32_t count
, uint8_t *buffer
)
1637 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1640 static int cortex_m3_init_target(struct command_context
*cmd_ctx
,
1641 struct target
*target
)
1643 armv7m_build_reg_cache(target
);
1647 /* REVISIT cache valid/dirty bits are unmaintained. We could set "valid"
1648 * on r/w if the core is not running, and clear on resume or reset ... or
1649 * at least, in a post_restore_context() method.
1652 struct dwt_reg_state
{
1653 struct target
*target
;
1655 uint32_t value
; /* scratch/cache */
1658 static int cortex_m3_dwt_get_reg(struct reg
*reg
)
1660 struct dwt_reg_state
*state
= reg
->arch_info
;
1662 return target_read_u32(state
->target
, state
->addr
, &state
->value
);
1665 static int cortex_m3_dwt_set_reg(struct reg
*reg
, uint8_t *buf
)
1667 struct dwt_reg_state
*state
= reg
->arch_info
;
1669 return target_write_u32(state
->target
, state
->addr
,
1670 buf_get_u32(buf
, 0, reg
->size
));
1679 static struct dwt_reg dwt_base_regs
[] = {
1680 { DWT_CTRL
, "dwt_ctrl", 32, },
1681 /* NOTE that Erratum 532314 (fixed r2p0) affects CYCCNT: it wrongly
1682 * increments while the core is asleep.
1684 { DWT_CYCCNT
, "dwt_cyccnt", 32, },
1685 /* plus some 8 bit counters, useful for profiling with TPIU */
1688 static struct dwt_reg dwt_comp
[] = {
1689 #define DWT_COMPARATOR(i) \
1690 { DWT_COMP0 + 0x10 * (i), "dwt_" #i "_comp", 32, }, \
1691 { DWT_MASK0 + 0x10 * (i), "dwt_" #i "_mask", 4, }, \
1692 { DWT_FUNCTION0 + 0x10 * (i), "dwt_" #i "_function", 32, }
1697 #undef DWT_COMPARATOR
1700 static const struct reg_arch_type dwt_reg_type
= {
1701 .get
= cortex_m3_dwt_get_reg
,
1702 .set
= cortex_m3_dwt_set_reg
,
1706 cortex_m3_dwt_addreg(struct target
*t
, struct reg
*r
, struct dwt_reg
*d
)
1708 struct dwt_reg_state
*state
;
1710 state
= calloc(1, sizeof *state
);
1713 state
->addr
= d
->addr
;
1718 r
->value
= &state
->value
;
1719 r
->arch_info
= state
;
1720 r
->type
= &dwt_reg_type
;
1724 cortex_m3_dwt_setup(struct cortex_m3_common
*cm3
, struct target
*target
)
1727 struct reg_cache
*cache
;
1728 struct cortex_m3_dwt_comparator
*comparator
;
1731 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1733 LOG_DEBUG("no DWT");
1737 cm3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1738 cm3
->dwt_comp_available
= cm3
->dwt_num_comp
;
1739 cm3
->dwt_comparator_list
= calloc(cm3
->dwt_num_comp
,
1740 sizeof(struct cortex_m3_dwt_comparator
));
1741 if (!cm3
->dwt_comparator_list
) {
1743 cm3
->dwt_num_comp
= 0;
1744 LOG_ERROR("out of mem");
1748 cache
= calloc(1, sizeof *cache
);
1751 free(cm3
->dwt_comparator_list
);
1754 cache
->name
= "cortex-m3 dwt registers";
1755 cache
->num_regs
= 2 + cm3
->dwt_num_comp
* 3;
1756 cache
->reg_list
= calloc(cache
->num_regs
, sizeof *cache
->reg_list
);
1757 if (!cache
->reg_list
) {
1762 for (reg
= 0; reg
< 2; reg
++)
1763 cortex_m3_dwt_addreg(target
, cache
->reg_list
+ reg
,
1764 dwt_base_regs
+ reg
);
1766 comparator
= cm3
->dwt_comparator_list
;
1767 for (i
= 0; i
< cm3
->dwt_num_comp
; i
++, comparator
++) {
1770 comparator
->dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1771 for (j
= 0; j
< 3; j
++, reg
++)
1772 cortex_m3_dwt_addreg(target
, cache
->reg_list
+ reg
,
1773 dwt_comp
+ 3 * i
+ j
);
1776 *register_get_last_cache_p(&target
->reg_cache
) = cache
;
1777 cm3
->dwt_cache
= cache
;
1779 LOG_DEBUG("DWT dwtcr 0x%" PRIx32
", comp %d, watch%s",
1780 dwtcr
, cm3
->dwt_num_comp
,
1781 (dwtcr
& (0xf << 24)) ? " only" : "/trigger");
1783 /* REVISIT: if num_comp > 1, check whether comparator #1 can
1784 * implement single-address data value watchpoints ... so we
1785 * won't need to check it later, when asked to set one up.
1789 static int cortex_m3_examine(struct target
*target
)
1792 uint32_t cpuid
, fpcr
;
1794 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1795 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
1797 if ((retval
= ahbap_debugport_init(swjdp
)) != ERROR_OK
)
1800 if (!target_was_examined(target
))
1802 target_set_examined(target
);
1804 /* Read from Device Identification Registers */
1805 retval
= target_read_u32(target
, CPUID
, &cpuid
);
1806 if (retval
!= ERROR_OK
)
1809 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1810 LOG_DEBUG("Cortex-M3 r%" PRId8
"p%" PRId8
" processor detected",
1811 (uint8_t)((cpuid
>> 20) & 0xf), (uint8_t)((cpuid
>> 0) & 0xf));
1812 LOG_DEBUG("cpuid: 0x%8.8" PRIx32
"", cpuid
);
1814 /* NOTE: FPB and DWT are both optional. */
1817 target_read_u32(target
, FP_CTRL
, &fpcr
);
1818 cortex_m3
->auto_bp_type
= 1;
1819 cortex_m3
->fp_num_code
= ((fpcr
>> 8) & 0x70) | ((fpcr
>> 4) & 0xF); /* bits [14:12] and [7:4] */
1820 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1821 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1822 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(struct cortex_m3_fp_comparator
));
1823 cortex_m3
->fpb_enabled
= fpcr
& 1;
1824 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1826 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1827 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1829 LOG_DEBUG("FPB fpcr 0x%" PRIx32
", numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1832 cortex_m3_dwt_setup(cortex_m3
, target
);
1834 /* These hardware breakpoints only work for code in flash! */
1835 LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints",
1836 target_name(target
),
1837 cortex_m3
->fp_num_code
,
1838 cortex_m3
->dwt_num_comp
);
1844 static int cortex_m3_dcc_read(struct adiv5_dap
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1849 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1850 *ctrl
= (uint8_t)dcrdr
;
1851 *value
= (uint8_t)(dcrdr
>> 8);
1853 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1855 /* write ack back to software dcc register
1856 * signify we have read data */
1857 if (dcrdr
& (1 << 0))
1860 retval
= mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1861 if (retval
!= ERROR_OK
)
1868 static int cortex_m3_target_request_data(struct target
*target
,
1869 uint32_t size
, uint8_t *buffer
)
1871 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1872 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1877 for (i
= 0; i
< (size
* 4); i
++)
1879 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1886 static int cortex_m3_handle_target_request(void *priv
)
1888 struct target
*target
= priv
;
1889 if (!target_was_examined(target
))
1891 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1892 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1894 if (!target
->dbg_msg_enabled
)
1897 if (target
->state
== TARGET_RUNNING
)
1902 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1904 /* check if we have data */
1905 if (ctrl
& (1 << 0))
1909 /* we assume target is quick enough */
1911 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1912 request
|= (data
<< 8);
1913 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1914 request
|= (data
<< 16);
1915 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1916 request
|= (data
<< 24);
1917 target_request(target
, request
);
1924 static int cortex_m3_init_arch_info(struct target
*target
,
1925 struct cortex_m3_common
*cortex_m3
, struct jtag_tap
*tap
)
1928 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
1930 armv7m_init_arch_info(target
, armv7m
);
1932 /* prepare JTAG information for the new target */
1933 cortex_m3
->jtag_info
.tap
= tap
;
1934 cortex_m3
->jtag_info
.scann_size
= 4;
1936 /* default reset mode is to use srst if fitted
1937 * if not it will use CORTEX_M3_RESET_VECTRESET */
1938 cortex_m3
->soft_reset_config
= CORTEX_M3_RESET_VECTRESET
;
1940 armv7m
->arm
.dap
= &armv7m
->dap
;
1942 /* Leave (only) generic DAP stuff for debugport_init(); */
1943 armv7m
->dap
.jtag_info
= &cortex_m3
->jtag_info
;
1944 armv7m
->dap
.memaccess_tck
= 8;
1945 /* Cortex-M3 has 4096 bytes autoincrement range */
1946 armv7m
->dap
.tar_autoincr_block
= (1 << 12);
1948 /* register arch-specific functions */
1949 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1951 armv7m
->post_debug_entry
= NULL
;
1953 armv7m
->pre_restore_context
= NULL
;
1955 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1956 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1958 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1960 if ((retval
= arm_jtag_setup_connection(&cortex_m3
->jtag_info
)) != ERROR_OK
)
1968 static int cortex_m3_target_create(struct target
*target
, Jim_Interp
*interp
)
1970 struct cortex_m3_common
*cortex_m3
= calloc(1,sizeof(struct cortex_m3_common
));
1972 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1973 cortex_m3_init_arch_info(target
, cortex_m3
, target
->tap
);
1978 /*--------------------------------------------------------------------------*/
1980 static int cortex_m3_verify_pointer(struct command_context
*cmd_ctx
,
1981 struct cortex_m3_common
*cm3
)
1983 if (cm3
->common_magic
!= CORTEX_M3_COMMON_MAGIC
) {
1984 command_print(cmd_ctx
, "target is not a Cortex-M3");
1985 return ERROR_TARGET_INVALID
;
1991 * Only stuff below this line should need to verify that its target
1992 * is a Cortex-M3. Everything else should have indirected through the
1993 * cortexm3_target structure, which is only used with CM3 targets.
1996 static const struct {
2000 { "hard_err", VC_HARDERR
, },
2001 { "int_err", VC_INTERR
, },
2002 { "bus_err", VC_BUSERR
, },
2003 { "state_err", VC_STATERR
, },
2004 { "chk_err", VC_CHKERR
, },
2005 { "nocp_err", VC_NOCPERR
, },
2006 { "mm_err", VC_MMERR
, },
2007 { "reset", VC_CORERESET
, },
2010 COMMAND_HANDLER(handle_cortex_m3_vector_catch_command
)
2012 struct target
*target
= get_current_target(CMD_CTX
);
2013 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
2014 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
2015 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
2019 retval
= cortex_m3_verify_pointer(CMD_CTX
, cortex_m3
);
2020 if (retval
!= ERROR_OK
)
2023 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &demcr
);
2024 if (retval
!= ERROR_OK
)
2030 if (CMD_ARGC
== 1) {
2031 if (strcmp(CMD_ARGV
[0], "all") == 0) {
2032 catch = VC_HARDERR
| VC_INTERR
| VC_BUSERR
2033 | VC_STATERR
| VC_CHKERR
| VC_NOCPERR
2034 | VC_MMERR
| VC_CORERESET
;
2036 } else if (strcmp(CMD_ARGV
[0], "none") == 0) {
2040 while (CMD_ARGC
-- > 0) {
2042 for (i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++) {
2043 if (strcmp(CMD_ARGV
[CMD_ARGC
], vec_ids
[i
].name
) != 0)
2045 catch |= vec_ids
[i
].mask
;
2048 if (i
== ARRAY_SIZE(vec_ids
)) {
2049 LOG_ERROR("No CM3 vector '%s'", CMD_ARGV
[CMD_ARGC
]);
2050 return ERROR_INVALID_ARGUMENTS
;
2054 /* For now, armv7m->demcr only stores vector catch flags. */
2055 armv7m
->demcr
= catch;
2060 /* write, but don't assume it stuck (why not??) */
2061 retval
= mem_ap_write_u32(swjdp
, DCB_DEMCR
, demcr
);
2062 if (retval
!= ERROR_OK
)
2064 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &demcr
);
2065 if (retval
!= ERROR_OK
)
2068 /* FIXME be sure to clear DEMCR on clean server shutdown.
2069 * Otherwise the vector catch hardware could fire when there's
2070 * no debugger hooked up, causing much confusion...
2074 for (unsigned i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++)
2076 command_print(CMD_CTX
, "%9s: %s", vec_ids
[i
].name
,
2077 (demcr
& vec_ids
[i
].mask
) ? "catch" : "ignore");
2083 COMMAND_HANDLER(handle_cortex_m3_mask_interrupts_command
)
2085 struct target
*target
= get_current_target(CMD_CTX
);
2086 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
2089 retval
= cortex_m3_verify_pointer(CMD_CTX
, cortex_m3
);
2090 if (retval
!= ERROR_OK
)
2093 if (target
->state
!= TARGET_HALTED
)
2095 command_print(CMD_CTX
, "target must be stopped for \"%s\" command", CMD_NAME
);
2102 COMMAND_PARSE_ON_OFF(CMD_ARGV
[0], enable
);
2103 uint32_t mask_on
= C_HALT
| (enable
? C_MASKINTS
: 0);
2104 uint32_t mask_off
= enable
? 0 : C_MASKINTS
;
2105 cortex_m3_write_debug_halt_mask(target
, mask_on
, mask_off
);
2108 command_print(CMD_CTX
, "cortex_m3 interrupt mask %s",
2109 (cortex_m3
->dcb_dhcsr
& C_MASKINTS
) ? "on" : "off");
2114 COMMAND_HANDLER(handle_cortex_m3_reset_config_command
)
2116 struct target
*target
= get_current_target(CMD_CTX
);
2117 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
2121 retval
= cortex_m3_verify_pointer(CMD_CTX
, cortex_m3
);
2122 if (retval
!= ERROR_OK
)
2127 if (strcmp(*CMD_ARGV
, "sysresetreq") == 0)
2128 cortex_m3
->soft_reset_config
= CORTEX_M3_RESET_SYSRESETREQ
;
2129 else if (strcmp(*CMD_ARGV
, "vectreset") == 0)
2130 cortex_m3
->soft_reset_config
= CORTEX_M3_RESET_VECTRESET
;
2133 switch (cortex_m3
->soft_reset_config
)
2135 case CORTEX_M3_RESET_SYSRESETREQ
:
2136 reset_config
= "sysresetreq";
2139 case CORTEX_M3_RESET_VECTRESET
:
2140 reset_config
= "vectreset";
2144 reset_config
= "unknown";
2148 command_print(CMD_CTX
, "cortex_m3 reset_config %s", reset_config
);
2153 static const struct command_registration cortex_m3_exec_command_handlers
[] = {
2156 .handler
= handle_cortex_m3_mask_interrupts_command
,
2157 .mode
= COMMAND_EXEC
,
2158 .help
= "mask cortex_m3 interrupts",
2159 .usage
= "['on'|'off']",
2162 .name
= "vector_catch",
2163 .handler
= handle_cortex_m3_vector_catch_command
,
2164 .mode
= COMMAND_EXEC
,
2165 .help
= "configure hardware vectors to trigger debug entry",
2166 .usage
= "['all'|'none'|('bus_err'|'chk_err'|...)*]",
2169 .name
= "reset_config",
2170 .handler
= handle_cortex_m3_reset_config_command
,
2171 .mode
= COMMAND_ANY
,
2172 .help
= "configure software reset handling",
2173 .usage
= "['srst'|'sysresetreq'|'vectreset']",
2175 COMMAND_REGISTRATION_DONE
2177 static const struct command_registration cortex_m3_command_handlers
[] = {
2179 .chain
= armv7m_command_handlers
,
2182 .name
= "cortex_m3",
2183 .mode
= COMMAND_EXEC
,
2184 .help
= "Cortex-M3 command group",
2185 .chain
= cortex_m3_exec_command_handlers
,
2187 COMMAND_REGISTRATION_DONE
2190 struct target_type cortexm3_target
=
2192 .name
= "cortex_m3",
2194 .poll
= cortex_m3_poll
,
2195 .arch_state
= armv7m_arch_state
,
2197 .target_request_data
= cortex_m3_target_request_data
,
2199 .halt
= cortex_m3_halt
,
2200 .resume
= cortex_m3_resume
,
2201 .step
= cortex_m3_step
,
2203 .assert_reset
= cortex_m3_assert_reset
,
2204 .deassert_reset
= cortex_m3_deassert_reset
,
2205 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
2207 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
2209 .read_memory
= cortex_m3_read_memory
,
2210 .write_memory
= cortex_m3_write_memory
,
2211 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
2212 .checksum_memory
= armv7m_checksum_memory
,
2213 .blank_check_memory
= armv7m_blank_check_memory
,
2215 .run_algorithm
= armv7m_run_algorithm
,
2217 .add_breakpoint
= cortex_m3_add_breakpoint
,
2218 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
2219 .add_watchpoint
= cortex_m3_add_watchpoint
,
2220 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
2222 .commands
= cortex_m3_command_handlers
,
2223 .target_create
= cortex_m3_target_create
,
2224 .init_target
= cortex_m3_init_target
,
2225 .examine
= cortex_m3_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)