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
)
524 enum target_state prev_target_state
= target
->state
;
525 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
526 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
528 /* Read from Debug Halting Control and Status Register */
529 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
530 if (retval
!= ERROR_OK
)
532 target
->state
= TARGET_UNKNOWN
;
536 /* Recover from lockup. See ARMv7-M architecture spec,
537 * section B1.5.15 "Unrecoverable exception cases".
539 * REVISIT Is there a better way to report and handle this?
541 if (cortex_m3
->dcb_dhcsr
& S_LOCKUP
) {
542 LOG_WARNING("%s -- clearing lockup after double fault",
543 target_name(target
));
544 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
545 target
->debug_reason
= DBG_REASON_DBGRQ
;
547 /* refresh status bits */
548 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
549 if (retval
!= ERROR_OK
)
553 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
555 /* check if still in reset */
556 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
557 if (retval
!= ERROR_OK
)
560 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
562 target
->state
= TARGET_RESET
;
567 if (target
->state
== TARGET_RESET
)
569 /* Cannot switch context while running so endreset is
570 * called with target->state == TARGET_RESET
572 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%" PRIx32
,
573 cortex_m3
->dcb_dhcsr
);
574 cortex_m3_endreset_event(target
);
575 target
->state
= TARGET_RUNNING
;
576 prev_target_state
= TARGET_RUNNING
;
579 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
581 target
->state
= TARGET_HALTED
;
583 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
585 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
588 if (arm_semihosting(target
, &retval
) != 0)
591 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
593 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
596 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
599 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
603 /* REVISIT when S_SLEEP is set, it's in a Sleep or DeepSleep state.
604 * How best to model low power modes?
607 if (target
->state
== TARGET_UNKNOWN
)
609 /* check if processor is retiring instructions */
610 if (cortex_m3
->dcb_dhcsr
& S_RETIRE_ST
)
612 target
->state
= TARGET_RUNNING
;
620 static int cortex_m3_halt(struct target
*target
)
622 LOG_DEBUG("target->state: %s",
623 target_state_name(target
));
625 if (target
->state
== TARGET_HALTED
)
627 LOG_DEBUG("target was already halted");
631 if (target
->state
== TARGET_UNKNOWN
)
633 LOG_WARNING("target was in unknown state when halt was requested");
636 if (target
->state
== TARGET_RESET
)
638 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst())
640 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
641 return ERROR_TARGET_FAILURE
;
645 /* we came here in a reset_halt or reset_init sequence
646 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
648 target
->debug_reason
= DBG_REASON_DBGRQ
;
654 /* Write to Debug Halting Control and Status Register */
655 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
657 target
->debug_reason
= DBG_REASON_DBGRQ
;
662 static int cortex_m3_soft_reset_halt(struct target
*target
)
664 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
665 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
666 uint32_t dcb_dhcsr
= 0;
667 int retval
, timeout
= 0;
669 /* Enter debug state on reset; restore DEMCR in endreset_event() */
670 retval
= mem_ap_write_u32(swjdp
, DCB_DEMCR
,
671 TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
672 if (retval
!= ERROR_OK
)
675 /* Request a core-only reset */
676 retval
= mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
,
677 AIRCR_VECTKEY
| AIRCR_VECTRESET
);
678 if (retval
!= ERROR_OK
)
680 target
->state
= TARGET_RESET
;
682 /* registers are now invalid */
683 register_cache_invalidate(cortex_m3
->armv7m
.core_cache
);
685 while (timeout
< 100)
687 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
688 if (retval
== ERROR_OK
)
690 retval
= mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
,
691 &cortex_m3
->nvic_dfsr
);
692 if (retval
!= ERROR_OK
)
694 if ((dcb_dhcsr
& S_HALT
)
695 && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
697 LOG_DEBUG("system reset-halted, DHCSR 0x%08x, "
699 (unsigned) dcb_dhcsr
,
700 (unsigned) cortex_m3
->nvic_dfsr
);
701 cortex_m3_poll(target
);
702 /* FIXME restore user's vector catch config */
706 LOG_DEBUG("waiting for system reset-halt, "
707 "DHCSR 0x%08x, %d ms",
708 (unsigned) dcb_dhcsr
, timeout
);
717 static void cortex_m3_enable_breakpoints(struct target
*target
)
719 struct breakpoint
*breakpoint
= target
->breakpoints
;
721 /* set any pending breakpoints */
724 if (!breakpoint
->set
)
725 cortex_m3_set_breakpoint(target
, breakpoint
);
726 breakpoint
= breakpoint
->next
;
730 static int cortex_m3_resume(struct target
*target
, int current
,
731 uint32_t address
, int handle_breakpoints
, int debug_execution
)
733 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
734 struct breakpoint
*breakpoint
= NULL
;
738 if (target
->state
!= TARGET_HALTED
)
740 LOG_WARNING("target not halted");
741 return ERROR_TARGET_NOT_HALTED
;
744 if (!debug_execution
)
746 target_free_all_working_areas(target
);
747 cortex_m3_enable_breakpoints(target
);
748 cortex_m3_enable_watchpoints(target
);
753 r
= armv7m
->core_cache
->reg_list
+ ARMV7M_PRIMASK
;
755 /* Disable interrupts */
756 /* We disable interrupts in the PRIMASK register instead of
757 * masking with C_MASKINTS. This is probably the same issue
758 * as Cortex-M3 Erratum 377493 (fixed in r1p0): C_MASKINTS
759 * in parallel with disabled interrupts can cause local faults
762 * REVISIT this clearly breaks non-debug execution, since the
763 * PRIMASK register state isn't saved/restored... workaround
764 * by never resuming app code after debug execution.
766 buf_set_u32(r
->value
, 0, 1, 1);
770 /* Make sure we are in Thumb mode */
771 r
= armv7m
->core_cache
->reg_list
+ ARMV7M_xPSR
;
772 buf_set_u32(r
->value
, 24, 1, 1);
777 /* current = 1: continue on current pc, otherwise continue at <address> */
781 buf_set_u32(r
->value
, 0, 32, address
);
786 /* if we halted last time due to a bkpt instruction
787 * then we have to manually step over it, otherwise
788 * the core will break again */
790 if (!breakpoint_find(target
, buf_get_u32(r
->value
, 0, 32))
793 armv7m_maybe_skip_bkpt_inst(target
, NULL
);
796 resume_pc
= buf_get_u32(r
->value
, 0, 32);
798 armv7m_restore_context(target
);
800 /* the front-end may request us not to handle breakpoints */
801 if (handle_breakpoints
)
803 /* Single step past breakpoint at current address */
804 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
806 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
" (ID: %d)",
808 breakpoint
->unique_id
);
809 cortex_m3_unset_breakpoint(target
, breakpoint
);
810 cortex_m3_single_step_core(target
);
811 cortex_m3_set_breakpoint(target
, breakpoint
);
816 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
818 target
->debug_reason
= DBG_REASON_NOTHALTED
;
820 /* registers are now invalid */
821 register_cache_invalidate(armv7m
->core_cache
);
823 if (!debug_execution
)
825 target
->state
= TARGET_RUNNING
;
826 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
827 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
831 target
->state
= TARGET_DEBUG_RUNNING
;
832 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
833 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
839 /* int irqstepcount = 0; */
840 static int cortex_m3_step(struct target
*target
, int current
,
841 uint32_t address
, int handle_breakpoints
)
843 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
844 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
845 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
846 struct breakpoint
*breakpoint
= NULL
;
847 struct reg
*pc
= armv7m
->arm
.pc
;
848 bool bkpt_inst_found
= false;
850 if (target
->state
!= TARGET_HALTED
)
852 LOG_WARNING("target not halted");
853 return ERROR_TARGET_NOT_HALTED
;
856 /* current = 1: continue on current pc, otherwise continue at <address> */
858 buf_set_u32(pc
->value
, 0, 32, address
);
860 /* the front-end may request us not to handle breakpoints */
861 if (handle_breakpoints
) {
862 breakpoint
= breakpoint_find(target
,
863 buf_get_u32(pc
->value
, 0, 32));
865 cortex_m3_unset_breakpoint(target
, breakpoint
);
868 armv7m_maybe_skip_bkpt_inst(target
, &bkpt_inst_found
);
870 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
872 armv7m_restore_context(target
);
874 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
876 /* if no bkpt instruction is found at pc then we can perform
877 * a normal step, otherwise we have to manually step over the bkpt
878 * instruction - as such simulate a step */
879 if (bkpt_inst_found
== false)
881 /* set step and clear halt */
882 cortex_m3_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
886 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
887 if (retval
!= ERROR_OK
)
890 /* registers are now invalid */
891 register_cache_invalidate(cortex_m3
->armv7m
.core_cache
);
894 cortex_m3_set_breakpoint(target
, breakpoint
);
896 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
897 " nvic_icsr = 0x%" PRIx32
,
898 cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
900 retval
= cortex_m3_debug_entry(target
);
901 if (retval
!= ERROR_OK
)
903 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
905 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
906 " nvic_icsr = 0x%" PRIx32
,
907 cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
912 static int cortex_m3_assert_reset(struct target
*target
)
914 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
915 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
916 enum cortex_m3_soft_reset_config reset_config
= cortex_m3
->soft_reset_config
;
918 LOG_DEBUG("target->state: %s",
919 target_state_name(target
));
921 enum reset_types jtag_reset_config
= jtag_get_reset_config();
924 * We can reset Cortex-M3 targets using just the NVIC without
925 * requiring SRST, getting a SoC reset (or a core-only reset)
926 * instead of a system reset.
928 if (!(jtag_reset_config
& RESET_HAS_SRST
) &&
929 (cortex_m3
->soft_reset_config
== CORTEX_M3_RESET_SRST
)) {
930 reset_config
= CORTEX_M3_RESET_VECTRESET
;
933 /* Enable debug requests */
935 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
936 if (retval
!= ERROR_OK
)
938 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
940 retval
= mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
941 if (retval
!= ERROR_OK
)
945 retval
= mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
946 if (retval
!= ERROR_OK
)
949 if (!target
->reset_halt
)
951 /* Set/Clear C_MASKINTS in a separate operation */
952 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
954 retval
= mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
,
955 DBGKEY
| C_DEBUGEN
| C_HALT
);
956 if (retval
!= ERROR_OK
)
960 /* clear any debug flags before resuming */
961 cortex_m3_clear_halt(target
);
963 /* clear C_HALT in dhcsr reg */
964 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
968 /* Halt in debug on reset; endreset_event() restores DEMCR.
970 * REVISIT catching BUSERR presumably helps to defend against
971 * bad vector table entries. Should this include MMERR or
974 retval
= mem_ap_write_atomic_u32(swjdp
, DCB_DEMCR
,
975 TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
976 if (retval
!= ERROR_OK
)
980 if (reset_config
== CORTEX_M3_RESET_SRST
)
982 /* default to asserting srst */
983 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
985 jtag_add_reset(1, 1);
989 jtag_add_reset(0, 1);
994 /* Use a standard Cortex-M3 software reset mechanism.
995 * We default to using VECRESET as it is supported on all current cores.
996 * This has the disadvantage of not resetting the peripherals, so a
997 * reset-init event handler is needed to perform any peripheral resets.
999 retval
= mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
,
1000 AIRCR_VECTKEY
| ((reset_config
== CORTEX_M3_RESET_SYSRESETREQ
)
1001 ? AIRCR_SYSRESETREQ
: AIRCR_VECTRESET
));
1002 if (retval
!= ERROR_OK
)
1005 LOG_DEBUG("Using Cortex-M3 %s", (reset_config
== CORTEX_M3_RESET_SYSRESETREQ
)
1006 ? "SYSRESETREQ" : "VECTRESET");
1008 if (reset_config
== CORTEX_M3_RESET_VECTRESET
) {
1009 LOG_WARNING("Only resetting the Cortex-M3 core, use a reset-init event "
1010 "handler to reset any peripherals");
1014 /* I do not know why this is necessary, but it
1015 * fixes strange effects (step/resume cause NMI
1016 * after reset) on LM3S6918 -- Michael Schwingen
1019 retval
= mem_ap_read_atomic_u32(swjdp
, NVIC_AIRCR
, &tmp
);
1020 if (retval
!= ERROR_OK
)
1025 target
->state
= TARGET_RESET
;
1026 jtag_add_sleep(50000);
1028 register_cache_invalidate(cortex_m3
->armv7m
.core_cache
);
1030 if (target
->reset_halt
)
1032 if ((retval
= target_halt(target
)) != ERROR_OK
)
1039 static int cortex_m3_deassert_reset(struct target
*target
)
1041 LOG_DEBUG("target->state: %s",
1042 target_state_name(target
));
1044 /* deassert reset lines */
1045 jtag_add_reset(0, 0);
1051 cortex_m3_set_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1056 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1057 struct cortex_m3_fp_comparator
*comparator_list
= cortex_m3
->fp_comparator_list
;
1059 if (breakpoint
->set
)
1061 LOG_WARNING("breakpoint (BPID: %d) already set", breakpoint
->unique_id
);
1065 if (cortex_m3
->auto_bp_type
)
1067 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1070 if (breakpoint
->type
== BKPT_HARD
)
1072 while (comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
1074 if (fp_num
>= cortex_m3
->fp_num_code
)
1076 LOG_ERROR("Can not find free FPB Comparator!");
1079 breakpoint
->set
= fp_num
+ 1;
1080 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
1081 comparator_list
[fp_num
].used
= 1;
1082 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
1083 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
1084 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32
"", fp_num
, comparator_list
[fp_num
].fpcr_value
);
1085 if (!cortex_m3
->fpb_enabled
)
1087 LOG_DEBUG("FPB wasn't enabled, do it now");
1088 target_write_u32(target
, FP_CTRL
, 3);
1091 else if (breakpoint
->type
== BKPT_SOFT
)
1095 /* NOTE: on ARMv6-M and ARMv7-M, BKPT(0xab) is used for
1096 * semihosting; don't use that. Otherwise the BKPT
1097 * parameter is arbitrary.
1099 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1100 retval
= target_read_memory(target
,
1101 breakpoint
->address
& 0xFFFFFFFE,
1102 breakpoint
->length
, 1,
1103 breakpoint
->orig_instr
);
1104 if (retval
!= ERROR_OK
)
1106 retval
= target_write_memory(target
,
1107 breakpoint
->address
& 0xFFFFFFFE,
1108 breakpoint
->length
, 1,
1110 if (retval
!= ERROR_OK
)
1112 breakpoint
->set
= true;
1115 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
1116 breakpoint
->unique_id
,
1117 (int)(breakpoint
->type
),
1118 breakpoint
->address
,
1126 cortex_m3_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1129 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1130 struct cortex_m3_fp_comparator
* comparator_list
= cortex_m3
->fp_comparator_list
;
1132 if (!breakpoint
->set
)
1134 LOG_WARNING("breakpoint not set");
1138 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
1139 breakpoint
->unique_id
,
1140 (int)(breakpoint
->type
),
1141 breakpoint
->address
,
1145 if (breakpoint
->type
== BKPT_HARD
)
1147 int fp_num
= breakpoint
->set
- 1;
1148 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
1150 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
1153 comparator_list
[fp_num
].used
= 0;
1154 comparator_list
[fp_num
].fpcr_value
= 0;
1155 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
1159 /* restore original instruction (kept in target endianness) */
1160 if (breakpoint
->length
== 4)
1162 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
1169 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
1175 breakpoint
->set
= false;
1181 cortex_m3_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1183 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1185 if (cortex_m3
->auto_bp_type
)
1187 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1188 #ifdef ARMV7_GDB_HACKS
1189 if (breakpoint
->length
!= 2) {
1190 /* XXX Hack: Replace all breakpoints with length != 2 with
1191 * a hardware breakpoint. */
1192 breakpoint
->type
= BKPT_HARD
;
1193 breakpoint
->length
= 2;
1198 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
1200 LOG_INFO("flash patch comparator requested outside code memory region");
1201 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1204 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
1206 LOG_INFO("soft breakpoint requested in code (flash) memory region");
1207 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1210 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
1212 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
1213 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1216 if ((breakpoint
->length
!= 2))
1218 LOG_INFO("only breakpoints of two bytes length supported");
1219 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1222 if (breakpoint
->type
== BKPT_HARD
)
1223 cortex_m3
->fp_code_available
--;
1225 return cortex_m3_set_breakpoint(target
, breakpoint
);
1229 cortex_m3_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1231 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1233 /* REVISIT why check? FBP can be updated with core running ... */
1234 if (target
->state
!= TARGET_HALTED
)
1236 LOG_WARNING("target not halted");
1237 return ERROR_TARGET_NOT_HALTED
;
1240 if (cortex_m3
->auto_bp_type
)
1242 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1245 if (breakpoint
->set
)
1247 cortex_m3_unset_breakpoint(target
, breakpoint
);
1250 if (breakpoint
->type
== BKPT_HARD
)
1251 cortex_m3
->fp_code_available
++;
1257 cortex_m3_set_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1260 uint32_t mask
, temp
;
1261 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1263 /* watchpoint params were validated earlier */
1265 temp
= watchpoint
->length
;
1272 /* REVISIT Don't fully trust these "not used" records ... users
1273 * may set up breakpoints by hand, e.g. dual-address data value
1274 * watchpoint using comparator #1; comparator #0 matching cycle
1275 * count; send data trace info through ITM and TPIU; etc
1277 struct cortex_m3_dwt_comparator
*comparator
;
1279 for (comparator
= cortex_m3
->dwt_comparator_list
;
1280 comparator
->used
&& dwt_num
< cortex_m3
->dwt_num_comp
;
1281 comparator
++, dwt_num
++)
1283 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
1285 LOG_ERROR("Can not find free DWT Comparator");
1288 comparator
->used
= 1;
1289 watchpoint
->set
= dwt_num
+ 1;
1291 comparator
->comp
= watchpoint
->address
;
1292 target_write_u32(target
, comparator
->dwt_comparator_address
+ 0,
1295 comparator
->mask
= mask
;
1296 target_write_u32(target
, comparator
->dwt_comparator_address
+ 4,
1299 switch (watchpoint
->rw
) {
1301 comparator
->function
= 5;
1304 comparator
->function
= 6;
1307 comparator
->function
= 7;
1310 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1311 comparator
->function
);
1313 LOG_DEBUG("Watchpoint (ID %d) DWT%d 0x%08x 0x%x 0x%05x",
1314 watchpoint
->unique_id
, dwt_num
,
1315 (unsigned) comparator
->comp
,
1316 (unsigned) comparator
->mask
,
1317 (unsigned) comparator
->function
);
1322 cortex_m3_unset_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1324 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1325 struct cortex_m3_dwt_comparator
*comparator
;
1328 if (!watchpoint
->set
)
1330 LOG_WARNING("watchpoint (wpid: %d) not set",
1331 watchpoint
->unique_id
);
1335 dwt_num
= watchpoint
->set
- 1;
1337 LOG_DEBUG("Watchpoint (ID %d) DWT%d address: 0x%08x clear",
1338 watchpoint
->unique_id
, dwt_num
,
1339 (unsigned) watchpoint
->address
);
1341 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1343 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1347 comparator
= cortex_m3
->dwt_comparator_list
+ dwt_num
;
1348 comparator
->used
= 0;
1349 comparator
->function
= 0;
1350 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1351 comparator
->function
);
1353 watchpoint
->set
= false;
1359 cortex_m3_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1361 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1363 if (cortex_m3
->dwt_comp_available
< 1)
1365 LOG_DEBUG("no comparators?");
1366 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1369 /* hardware doesn't support data value masking */
1370 if (watchpoint
->mask
!= ~(uint32_t)0) {
1371 LOG_DEBUG("watchpoint value masks not supported");
1372 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1375 /* hardware allows address masks of up to 32K */
1378 for (mask
= 0; mask
< 16; mask
++) {
1379 if ((1u << mask
) == watchpoint
->length
)
1383 LOG_DEBUG("unsupported watchpoint length");
1384 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1386 if (watchpoint
->address
& ((1 << mask
) - 1)) {
1387 LOG_DEBUG("watchpoint address is unaligned");
1388 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1391 /* Caller doesn't seem to be able to describe watching for data
1392 * values of zero; that flags "no value".
1394 * REVISIT This DWT may well be able to watch for specific data
1395 * values. Requires comparator #1 to set DATAVMATCH and match
1396 * the data, and another comparator (DATAVADDR0) matching addr.
1398 if (watchpoint
->value
) {
1399 LOG_DEBUG("data value watchpoint not YET supported");
1400 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1403 cortex_m3
->dwt_comp_available
--;
1404 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1410 cortex_m3_remove_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1412 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1414 /* REVISIT why check? DWT can be updated with core running ... */
1415 if (target
->state
!= TARGET_HALTED
)
1417 LOG_WARNING("target not halted");
1418 return ERROR_TARGET_NOT_HALTED
;
1421 if (watchpoint
->set
)
1423 cortex_m3_unset_watchpoint(target
, watchpoint
);
1426 cortex_m3
->dwt_comp_available
++;
1427 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1432 static void cortex_m3_enable_watchpoints(struct target
*target
)
1434 struct watchpoint
*watchpoint
= target
->watchpoints
;
1436 /* set any pending watchpoints */
1439 if (!watchpoint
->set
)
1440 cortex_m3_set_watchpoint(target
, watchpoint
);
1441 watchpoint
= watchpoint
->next
;
1445 static int cortex_m3_load_core_reg_u32(struct target
*target
,
1446 enum armv7m_regtype type
, uint32_t num
, uint32_t * value
)
1449 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1450 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1452 /* NOTE: we "know" here that the register identifiers used
1453 * in the v7m header match the Cortex-M3 Debug Core Register
1454 * Selector values for R0..R15, xPSR, MSP, and PSP.
1458 /* read a normal core register */
1459 retval
= cortexm3_dap_read_coreregister_u32(swjdp
, value
, num
);
1461 if (retval
!= ERROR_OK
)
1463 LOG_ERROR("JTAG failure %i",retval
);
1464 return ERROR_JTAG_DEVICE_ERROR
;
1466 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
"",(int)num
,*value
);
1469 case ARMV7M_PRIMASK
:
1470 case ARMV7M_BASEPRI
:
1471 case ARMV7M_FAULTMASK
:
1472 case ARMV7M_CONTROL
:
1473 /* Cortex-M3 packages these four registers as bitfields
1474 * in one Debug Core register. So say r0 and r2 docs;
1475 * it was removed from r1 docs, but still works.
1477 cortexm3_dap_read_coreregister_u32(swjdp
, value
, 20);
1481 case ARMV7M_PRIMASK
:
1482 *value
= buf_get_u32((uint8_t*)value
, 0, 1);
1485 case ARMV7M_BASEPRI
:
1486 *value
= buf_get_u32((uint8_t*)value
, 8, 8);
1489 case ARMV7M_FAULTMASK
:
1490 *value
= buf_get_u32((uint8_t*)value
, 16, 1);
1493 case ARMV7M_CONTROL
:
1494 *value
= buf_get_u32((uint8_t*)value
, 24, 2);
1498 LOG_DEBUG("load from special reg %i value 0x%" PRIx32
"", (int)num
, *value
);
1502 return ERROR_INVALID_ARGUMENTS
;
1508 static int cortex_m3_store_core_reg_u32(struct target
*target
,
1509 enum armv7m_regtype type
, uint32_t num
, uint32_t value
)
1513 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1514 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1516 #ifdef ARMV7_GDB_HACKS
1517 /* If the LR register is being modified, make sure it will put us
1518 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1519 * hack to deal with the fact that gdb will sometimes "forge"
1520 * return addresses, and doesn't set the LSB correctly (i.e., when
1521 * printing expressions containing function calls, it sets LR = 0.)
1522 * Valid exception return codes have bit 0 set too.
1524 if (num
== ARMV7M_R14
)
1528 /* NOTE: we "know" here that the register identifiers used
1529 * in the v7m header match the Cortex-M3 Debug Core Register
1530 * Selector values for R0..R15, xPSR, MSP, and PSP.
1534 retval
= cortexm3_dap_write_coreregister_u32(swjdp
, value
, num
);
1535 if (retval
!= ERROR_OK
)
1539 LOG_ERROR("JTAG failure %i", retval
);
1540 r
= armv7m
->core_cache
->reg_list
+ num
;
1541 r
->dirty
= r
->valid
;
1542 return ERROR_JTAG_DEVICE_ERROR
;
1544 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", (int)num
, value
);
1547 case ARMV7M_PRIMASK
:
1548 case ARMV7M_BASEPRI
:
1549 case ARMV7M_FAULTMASK
:
1550 case ARMV7M_CONTROL
:
1551 /* Cortex-M3 packages these four registers as bitfields
1552 * in one Debug Core register. So say r0 and r2 docs;
1553 * it was removed from r1 docs, but still works.
1555 cortexm3_dap_read_coreregister_u32(swjdp
, ®
, 20);
1559 case ARMV7M_PRIMASK
:
1560 buf_set_u32((uint8_t*)®
, 0, 1, value
);
1563 case ARMV7M_BASEPRI
:
1564 buf_set_u32((uint8_t*)®
, 8, 8, value
);
1567 case ARMV7M_FAULTMASK
:
1568 buf_set_u32((uint8_t*)®
, 16, 1, value
);
1571 case ARMV7M_CONTROL
:
1572 buf_set_u32((uint8_t*)®
, 24, 2, value
);
1576 cortexm3_dap_write_coreregister_u32(swjdp
, reg
, 20);
1578 LOG_DEBUG("write special reg %i value 0x%" PRIx32
" ", (int)num
, value
);
1582 return ERROR_INVALID_ARGUMENTS
;
1588 static int cortex_m3_read_memory(struct target
*target
, uint32_t address
,
1589 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1591 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1592 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1593 int retval
= ERROR_INVALID_ARGUMENTS
;
1595 /* cortex_m3 handles unaligned memory access */
1596 if (count
&& buffer
) {
1599 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1602 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1605 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1613 static int cortex_m3_write_memory(struct target
*target
, uint32_t address
,
1614 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1616 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1617 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1618 int retval
= ERROR_INVALID_ARGUMENTS
;
1620 if (count
&& buffer
) {
1623 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1626 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1629 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1637 static int cortex_m3_bulk_write_memory(struct target
*target
, uint32_t address
,
1638 uint32_t count
, uint8_t *buffer
)
1640 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1643 static int cortex_m3_init_target(struct command_context
*cmd_ctx
,
1644 struct target
*target
)
1646 armv7m_build_reg_cache(target
);
1650 /* REVISIT cache valid/dirty bits are unmaintained. We could set "valid"
1651 * on r/w if the core is not running, and clear on resume or reset ... or
1652 * at least, in a post_restore_context() method.
1655 struct dwt_reg_state
{
1656 struct target
*target
;
1658 uint32_t value
; /* scratch/cache */
1661 static int cortex_m3_dwt_get_reg(struct reg
*reg
)
1663 struct dwt_reg_state
*state
= reg
->arch_info
;
1665 return target_read_u32(state
->target
, state
->addr
, &state
->value
);
1668 static int cortex_m3_dwt_set_reg(struct reg
*reg
, uint8_t *buf
)
1670 struct dwt_reg_state
*state
= reg
->arch_info
;
1672 return target_write_u32(state
->target
, state
->addr
,
1673 buf_get_u32(buf
, 0, reg
->size
));
1682 static struct dwt_reg dwt_base_regs
[] = {
1683 { DWT_CTRL
, "dwt_ctrl", 32, },
1684 /* NOTE that Erratum 532314 (fixed r2p0) affects CYCCNT: it wrongly
1685 * increments while the core is asleep.
1687 { DWT_CYCCNT
, "dwt_cyccnt", 32, },
1688 /* plus some 8 bit counters, useful for profiling with TPIU */
1691 static struct dwt_reg dwt_comp
[] = {
1692 #define DWT_COMPARATOR(i) \
1693 { DWT_COMP0 + 0x10 * (i), "dwt_" #i "_comp", 32, }, \
1694 { DWT_MASK0 + 0x10 * (i), "dwt_" #i "_mask", 4, }, \
1695 { DWT_FUNCTION0 + 0x10 * (i), "dwt_" #i "_function", 32, }
1700 #undef DWT_COMPARATOR
1703 static const struct reg_arch_type dwt_reg_type
= {
1704 .get
= cortex_m3_dwt_get_reg
,
1705 .set
= cortex_m3_dwt_set_reg
,
1709 cortex_m3_dwt_addreg(struct target
*t
, struct reg
*r
, struct dwt_reg
*d
)
1711 struct dwt_reg_state
*state
;
1713 state
= calloc(1, sizeof *state
);
1716 state
->addr
= d
->addr
;
1721 r
->value
= &state
->value
;
1722 r
->arch_info
= state
;
1723 r
->type
= &dwt_reg_type
;
1727 cortex_m3_dwt_setup(struct cortex_m3_common
*cm3
, struct target
*target
)
1730 struct reg_cache
*cache
;
1731 struct cortex_m3_dwt_comparator
*comparator
;
1734 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1736 LOG_DEBUG("no DWT");
1740 cm3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1741 cm3
->dwt_comp_available
= cm3
->dwt_num_comp
;
1742 cm3
->dwt_comparator_list
= calloc(cm3
->dwt_num_comp
,
1743 sizeof(struct cortex_m3_dwt_comparator
));
1744 if (!cm3
->dwt_comparator_list
) {
1746 cm3
->dwt_num_comp
= 0;
1747 LOG_ERROR("out of mem");
1751 cache
= calloc(1, sizeof *cache
);
1754 free(cm3
->dwt_comparator_list
);
1757 cache
->name
= "cortex-m3 dwt registers";
1758 cache
->num_regs
= 2 + cm3
->dwt_num_comp
* 3;
1759 cache
->reg_list
= calloc(cache
->num_regs
, sizeof *cache
->reg_list
);
1760 if (!cache
->reg_list
) {
1765 for (reg
= 0; reg
< 2; reg
++)
1766 cortex_m3_dwt_addreg(target
, cache
->reg_list
+ reg
,
1767 dwt_base_regs
+ reg
);
1769 comparator
= cm3
->dwt_comparator_list
;
1770 for (i
= 0; i
< cm3
->dwt_num_comp
; i
++, comparator
++) {
1773 comparator
->dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1774 for (j
= 0; j
< 3; j
++, reg
++)
1775 cortex_m3_dwt_addreg(target
, cache
->reg_list
+ reg
,
1776 dwt_comp
+ 3 * i
+ j
);
1779 *register_get_last_cache_p(&target
->reg_cache
) = cache
;
1780 cm3
->dwt_cache
= cache
;
1782 LOG_DEBUG("DWT dwtcr 0x%" PRIx32
", comp %d, watch%s",
1783 dwtcr
, cm3
->dwt_num_comp
,
1784 (dwtcr
& (0xf << 24)) ? " only" : "/trigger");
1786 /* REVISIT: if num_comp > 1, check whether comparator #1 can
1787 * implement single-address data value watchpoints ... so we
1788 * won't need to check it later, when asked to set one up.
1792 static int cortex_m3_examine(struct target
*target
)
1795 uint32_t cpuid
, fpcr
;
1797 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1798 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
1800 if ((retval
= ahbap_debugport_init(swjdp
)) != ERROR_OK
)
1803 if (!target_was_examined(target
))
1805 target_set_examined(target
);
1807 /* Read from Device Identification Registers */
1808 retval
= target_read_u32(target
, CPUID
, &cpuid
);
1809 if (retval
!= ERROR_OK
)
1812 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1813 LOG_DEBUG("Cortex-M3 r%" PRId8
"p%" PRId8
" processor detected",
1814 (uint8_t)((cpuid
>> 20) & 0xf), (uint8_t)((cpuid
>> 0) & 0xf));
1815 LOG_DEBUG("cpuid: 0x%8.8" PRIx32
"", cpuid
);
1817 /* NOTE: FPB and DWT are both optional. */
1820 target_read_u32(target
, FP_CTRL
, &fpcr
);
1821 cortex_m3
->auto_bp_type
= 1;
1822 cortex_m3
->fp_num_code
= ((fpcr
>> 8) & 0x70) | ((fpcr
>> 4) & 0xF); /* bits [14:12] and [7:4] */
1823 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1824 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1825 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(struct cortex_m3_fp_comparator
));
1826 cortex_m3
->fpb_enabled
= fpcr
& 1;
1827 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1829 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1830 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1832 LOG_DEBUG("FPB fpcr 0x%" PRIx32
", numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1835 cortex_m3_dwt_setup(cortex_m3
, target
);
1837 /* These hardware breakpoints only work for code in flash! */
1838 LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints",
1839 target_name(target
),
1840 cortex_m3
->fp_num_code
,
1841 cortex_m3
->dwt_num_comp
);
1847 static int cortex_m3_dcc_read(struct adiv5_dap
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1852 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1853 *ctrl
= (uint8_t)dcrdr
;
1854 *value
= (uint8_t)(dcrdr
>> 8);
1856 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1858 /* write ack back to software dcc register
1859 * signify we have read data */
1860 if (dcrdr
& (1 << 0))
1863 retval
= mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1864 if (retval
!= ERROR_OK
)
1871 static int cortex_m3_target_request_data(struct target
*target
,
1872 uint32_t size
, uint8_t *buffer
)
1874 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1875 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1880 for (i
= 0; i
< (size
* 4); i
++)
1882 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1889 static int cortex_m3_handle_target_request(void *priv
)
1891 struct target
*target
= priv
;
1892 if (!target_was_examined(target
))
1894 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1895 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1897 if (!target
->dbg_msg_enabled
)
1900 if (target
->state
== TARGET_RUNNING
)
1905 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1907 /* check if we have data */
1908 if (ctrl
& (1 << 0))
1912 /* we assume target is quick enough */
1914 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1915 request
|= (data
<< 8);
1916 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1917 request
|= (data
<< 16);
1918 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1919 request
|= (data
<< 24);
1920 target_request(target
, request
);
1927 static int cortex_m3_init_arch_info(struct target
*target
,
1928 struct cortex_m3_common
*cortex_m3
, struct jtag_tap
*tap
)
1931 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
1933 armv7m_init_arch_info(target
, armv7m
);
1935 /* prepare JTAG information for the new target */
1936 cortex_m3
->jtag_info
.tap
= tap
;
1937 cortex_m3
->jtag_info
.scann_size
= 4;
1939 /* default reset mode is to use srst if fitted
1940 * if not it will use CORTEX_M3_RESET_VECTRESET */
1941 cortex_m3
->soft_reset_config
= CORTEX_M3_RESET_SRST
;
1943 armv7m
->arm
.dap
= &armv7m
->dap
;
1945 /* Leave (only) generic DAP stuff for debugport_init(); */
1946 armv7m
->dap
.jtag_info
= &cortex_m3
->jtag_info
;
1947 armv7m
->dap
.memaccess_tck
= 8;
1948 /* Cortex-M3 has 4096 bytes autoincrement range */
1949 armv7m
->dap
.tar_autoincr_block
= (1 << 12);
1951 /* register arch-specific functions */
1952 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1954 armv7m
->post_debug_entry
= NULL
;
1956 armv7m
->pre_restore_context
= NULL
;
1958 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1959 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1961 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1963 if ((retval
= arm_jtag_setup_connection(&cortex_m3
->jtag_info
)) != ERROR_OK
)
1971 static int cortex_m3_target_create(struct target
*target
, Jim_Interp
*interp
)
1973 struct cortex_m3_common
*cortex_m3
= calloc(1,sizeof(struct cortex_m3_common
));
1975 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1976 cortex_m3_init_arch_info(target
, cortex_m3
, target
->tap
);
1981 /*--------------------------------------------------------------------------*/
1983 static int cortex_m3_verify_pointer(struct command_context
*cmd_ctx
,
1984 struct cortex_m3_common
*cm3
)
1986 if (cm3
->common_magic
!= CORTEX_M3_COMMON_MAGIC
) {
1987 command_print(cmd_ctx
, "target is not a Cortex-M3");
1988 return ERROR_TARGET_INVALID
;
1994 * Only stuff below this line should need to verify that its target
1995 * is a Cortex-M3. Everything else should have indirected through the
1996 * cortexm3_target structure, which is only used with CM3 targets.
1999 static const struct {
2003 { "hard_err", VC_HARDERR
, },
2004 { "int_err", VC_INTERR
, },
2005 { "bus_err", VC_BUSERR
, },
2006 { "state_err", VC_STATERR
, },
2007 { "chk_err", VC_CHKERR
, },
2008 { "nocp_err", VC_NOCPERR
, },
2009 { "mm_err", VC_MMERR
, },
2010 { "reset", VC_CORERESET
, },
2013 COMMAND_HANDLER(handle_cortex_m3_vector_catch_command
)
2015 struct target
*target
= get_current_target(CMD_CTX
);
2016 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
2017 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
2018 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
2022 retval
= cortex_m3_verify_pointer(CMD_CTX
, cortex_m3
);
2023 if (retval
!= ERROR_OK
)
2026 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &demcr
);
2027 if (retval
!= ERROR_OK
)
2033 if (CMD_ARGC
== 1) {
2034 if (strcmp(CMD_ARGV
[0], "all") == 0) {
2035 catch = VC_HARDERR
| VC_INTERR
| VC_BUSERR
2036 | VC_STATERR
| VC_CHKERR
| VC_NOCPERR
2037 | VC_MMERR
| VC_CORERESET
;
2039 } else if (strcmp(CMD_ARGV
[0], "none") == 0) {
2043 while (CMD_ARGC
-- > 0) {
2045 for (i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++) {
2046 if (strcmp(CMD_ARGV
[CMD_ARGC
], vec_ids
[i
].name
) != 0)
2048 catch |= vec_ids
[i
].mask
;
2051 if (i
== ARRAY_SIZE(vec_ids
)) {
2052 LOG_ERROR("No CM3 vector '%s'", CMD_ARGV
[CMD_ARGC
]);
2053 return ERROR_INVALID_ARGUMENTS
;
2057 /* For now, armv7m->demcr only stores vector catch flags. */
2058 armv7m
->demcr
= catch;
2063 /* write, but don't assume it stuck (why not??) */
2064 retval
= mem_ap_write_u32(swjdp
, DCB_DEMCR
, demcr
);
2065 if (retval
!= ERROR_OK
)
2067 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &demcr
);
2068 if (retval
!= ERROR_OK
)
2071 /* FIXME be sure to clear DEMCR on clean server shutdown.
2072 * Otherwise the vector catch hardware could fire when there's
2073 * no debugger hooked up, causing much confusion...
2077 for (unsigned i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++)
2079 command_print(CMD_CTX
, "%9s: %s", vec_ids
[i
].name
,
2080 (demcr
& vec_ids
[i
].mask
) ? "catch" : "ignore");
2086 COMMAND_HANDLER(handle_cortex_m3_mask_interrupts_command
)
2088 struct target
*target
= get_current_target(CMD_CTX
);
2089 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
2092 retval
= cortex_m3_verify_pointer(CMD_CTX
, cortex_m3
);
2093 if (retval
!= ERROR_OK
)
2096 if (target
->state
!= TARGET_HALTED
)
2098 command_print(CMD_CTX
, "target must be stopped for \"%s\" command", CMD_NAME
);
2105 COMMAND_PARSE_ON_OFF(CMD_ARGV
[0], enable
);
2106 uint32_t mask_on
= C_HALT
| (enable
? C_MASKINTS
: 0);
2107 uint32_t mask_off
= enable
? 0 : C_MASKINTS
;
2108 cortex_m3_write_debug_halt_mask(target
, mask_on
, mask_off
);
2111 command_print(CMD_CTX
, "cortex_m3 interrupt mask %s",
2112 (cortex_m3
->dcb_dhcsr
& C_MASKINTS
) ? "on" : "off");
2117 COMMAND_HANDLER(handle_cortex_m3_reset_config_command
)
2119 struct target
*target
= get_current_target(CMD_CTX
);
2120 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
2124 retval
= cortex_m3_verify_pointer(CMD_CTX
, cortex_m3
);
2125 if (retval
!= ERROR_OK
)
2130 if (strcmp(*CMD_ARGV
, "systesetreq") == 0)
2131 cortex_m3
->soft_reset_config
= CORTEX_M3_RESET_SYSRESETREQ
;
2132 else if (strcmp(*CMD_ARGV
, "vectreset") == 0)
2133 cortex_m3
->soft_reset_config
= CORTEX_M3_RESET_VECTRESET
;
2135 cortex_m3
->soft_reset_config
= CORTEX_M3_RESET_SRST
;
2138 switch (cortex_m3
->soft_reset_config
)
2140 case CORTEX_M3_RESET_SRST
:
2141 reset_config
= "srst";
2144 case CORTEX_M3_RESET_SYSRESETREQ
:
2145 reset_config
= "sysresetreq";
2148 case CORTEX_M3_RESET_VECTRESET
:
2149 reset_config
= "vectreset";
2153 reset_config
= "unknown";
2157 command_print(CMD_CTX
, "cortex_m3 reset_config %s", reset_config
);
2162 static const struct command_registration cortex_m3_exec_command_handlers
[] = {
2165 .handler
= handle_cortex_m3_mask_interrupts_command
,
2166 .mode
= COMMAND_EXEC
,
2167 .help
= "mask cortex_m3 interrupts",
2168 .usage
= "['on'|'off']",
2171 .name
= "vector_catch",
2172 .handler
= handle_cortex_m3_vector_catch_command
,
2173 .mode
= COMMAND_EXEC
,
2174 .help
= "configure hardware vectors to trigger debug entry",
2175 .usage
= "['all'|'none'|('bus_err'|'chk_err'|...)*]",
2178 .name
= "reset_config",
2179 .handler
= handle_cortex_m3_reset_config_command
,
2180 .mode
= COMMAND_ANY
,
2181 .help
= "configure software reset handling",
2182 .usage
= "['srst'|'sysresetreq'|'vectreset']",
2184 COMMAND_REGISTRATION_DONE
2186 static const struct command_registration cortex_m3_command_handlers
[] = {
2188 .chain
= armv7m_command_handlers
,
2191 .name
= "cortex_m3",
2192 .mode
= COMMAND_EXEC
,
2193 .help
= "Cortex-M3 command group",
2194 .chain
= cortex_m3_exec_command_handlers
,
2196 COMMAND_REGISTRATION_DONE
2199 struct target_type cortexm3_target
=
2201 .name
= "cortex_m3",
2203 .poll
= cortex_m3_poll
,
2204 .arch_state
= armv7m_arch_state
,
2206 .target_request_data
= cortex_m3_target_request_data
,
2208 .halt
= cortex_m3_halt
,
2209 .resume
= cortex_m3_resume
,
2210 .step
= cortex_m3_step
,
2212 .assert_reset
= cortex_m3_assert_reset
,
2213 .deassert_reset
= cortex_m3_deassert_reset
,
2214 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
2216 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
2218 .read_memory
= cortex_m3_read_memory
,
2219 .write_memory
= cortex_m3_write_memory
,
2220 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
2221 .checksum_memory
= armv7m_checksum_memory
,
2222 .blank_check_memory
= armv7m_blank_check_memory
,
2224 .run_algorithm
= armv7m_run_algorithm
,
2226 .add_breakpoint
= cortex_m3_add_breakpoint
,
2227 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
2228 .add_watchpoint
= cortex_m3_add_watchpoint
,
2229 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
2231 .commands
= cortex_m3_command_handlers
,
2232 .target_create
= cortex_m3_target_create
,
2233 .init_target
= cortex_m3_init_target
,
2234 .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)