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 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
27 * Cortex-M3(tm) TRM, ARM DDI 0337E (r1p1) and 0337G (r2p0) *
29 ***************************************************************************/
34 #include "jtag/interface.h"
35 #include "breakpoints.h"
37 #include "target_request.h"
38 #include "target_type.h"
39 #include "arm_disassembler.h"
41 #include "arm_opcodes.h"
42 #include "arm_semihosting.h"
43 #include <helper/time_support.h>
45 /* NOTE: most of this should work fine for the Cortex-M1 and
46 * Cortex-M0 cores too, although they're ARMv6-M not ARMv7-M.
47 * Some differences: M0/M1 doesn't have FBP remapping or the
48 * DWT tracing/profiling support. (So the cycle counter will
49 * not be usable; the other stuff isn't currently used here.)
51 * Although there are some workarounds for errata seen only in r0p0
52 * silicon, such old parts are hard to find and thus not much tested
57 * Returns the type of a break point required by address location
59 #define BKPT_TYPE_BY_ADDR(addr) ((addr) < 0x20000000 ? BKPT_HARD : BKPT_SOFT)
61 /* forward declarations */
62 static int cortex_m_store_core_reg_u32(struct target
*target
,
63 uint32_t num
, uint32_t value
);
64 static void cortex_m_dwt_free(struct target
*target
);
66 static int cortexm_dap_read_coreregister_u32(struct target
*target
,
67 uint32_t *value
, int regnum
)
69 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
73 /* because the DCB_DCRDR is used for the emulated dcc channel
74 * we have to save/restore the DCB_DCRDR when used */
75 if (target
->dbg_msg_enabled
) {
76 retval
= mem_ap_read_u32(armv7m
->debug_ap
, DCB_DCRDR
, &dcrdr
);
77 if (retval
!= ERROR_OK
)
81 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DCRSR
, regnum
);
82 if (retval
!= ERROR_OK
)
85 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DCRDR
, value
);
86 if (retval
!= ERROR_OK
)
89 if (target
->dbg_msg_enabled
) {
90 /* restore DCB_DCRDR - this needs to be in a separate
91 * transaction otherwise the emulated DCC channel breaks */
92 if (retval
== ERROR_OK
)
93 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DCRDR
, dcrdr
);
99 static int cortexm_dap_write_coreregister_u32(struct target
*target
,
100 uint32_t value
, int regnum
)
102 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
106 /* because the DCB_DCRDR is used for the emulated dcc channel
107 * we have to save/restore the DCB_DCRDR when used */
108 if (target
->dbg_msg_enabled
) {
109 retval
= mem_ap_read_u32(armv7m
->debug_ap
, DCB_DCRDR
, &dcrdr
);
110 if (retval
!= ERROR_OK
)
114 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DCRDR
, value
);
115 if (retval
!= ERROR_OK
)
118 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DCRSR
, regnum
| DCRSR_WnR
);
119 if (retval
!= ERROR_OK
)
122 if (target
->dbg_msg_enabled
) {
123 /* restore DCB_DCRDR - this needs to be in a seperate
124 * transaction otherwise the emulated DCC channel breaks */
125 if (retval
== ERROR_OK
)
126 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DCRDR
, dcrdr
);
132 static int cortex_m_write_debug_halt_mask(struct target
*target
,
133 uint32_t mask_on
, uint32_t mask_off
)
135 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
136 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
138 /* mask off status bits */
139 cortex_m
->dcb_dhcsr
&= ~((0xFFFF << 16) | mask_off
);
140 /* create new register mask */
141 cortex_m
->dcb_dhcsr
|= DBGKEY
| C_DEBUGEN
| mask_on
;
143 return mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, cortex_m
->dcb_dhcsr
);
146 static int cortex_m_clear_halt(struct target
*target
)
148 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
149 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
152 /* clear step if any */
153 cortex_m_write_debug_halt_mask(target
, C_HALT
, C_STEP
);
155 /* Read Debug Fault Status Register */
156 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, NVIC_DFSR
, &cortex_m
->nvic_dfsr
);
157 if (retval
!= ERROR_OK
)
160 /* Clear Debug Fault Status */
161 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, NVIC_DFSR
, cortex_m
->nvic_dfsr
);
162 if (retval
!= ERROR_OK
)
164 LOG_DEBUG(" NVIC_DFSR 0x%" PRIx32
"", cortex_m
->nvic_dfsr
);
169 static int cortex_m_single_step_core(struct target
*target
)
171 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
172 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
176 /* backup dhcsr reg */
177 dhcsr_save
= cortex_m
->dcb_dhcsr
;
179 /* Mask interrupts before clearing halt, if done already. This avoids
180 * Erratum 377497 (fixed in r1p0) where setting MASKINTS while clearing
181 * HALT can put the core into an unknown state.
183 if (!(cortex_m
->dcb_dhcsr
& C_MASKINTS
)) {
184 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
,
185 DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
186 if (retval
!= ERROR_OK
)
189 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
,
190 DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
191 if (retval
!= ERROR_OK
)
195 /* restore dhcsr reg */
196 cortex_m
->dcb_dhcsr
= dhcsr_save
;
197 cortex_m_clear_halt(target
);
202 static int cortex_m_enable_fpb(struct target
*target
)
204 int retval
= target_write_u32(target
, FP_CTRL
, 3);
205 if (retval
!= ERROR_OK
)
208 /* check the fpb is actually enabled */
210 retval
= target_read_u32(target
, FP_CTRL
, &fpctrl
);
211 if (retval
!= ERROR_OK
)
220 static int cortex_m_endreset_event(struct target
*target
)
225 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
226 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
227 struct adiv5_dap
*swjdp
= cortex_m
->armv7m
.arm
.dap
;
228 struct cortex_m_fp_comparator
*fp_list
= cortex_m
->fp_comparator_list
;
229 struct cortex_m_dwt_comparator
*dwt_list
= cortex_m
->dwt_comparator_list
;
231 /* REVISIT The four debug monitor bits are currently ignored... */
232 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DEMCR
, &dcb_demcr
);
233 if (retval
!= ERROR_OK
)
235 LOG_DEBUG("DCB_DEMCR = 0x%8.8" PRIx32
"", dcb_demcr
);
237 /* this register is used for emulated dcc channel */
238 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DCRDR
, 0);
239 if (retval
!= ERROR_OK
)
242 /* Enable debug requests */
243 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
244 if (retval
!= ERROR_OK
)
246 if (!(cortex_m
->dcb_dhcsr
& C_DEBUGEN
)) {
247 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
248 if (retval
!= ERROR_OK
)
252 /* clear any interrupt masking */
253 cortex_m_write_debug_halt_mask(target
, 0, C_MASKINTS
);
255 /* Enable features controlled by ITM and DWT blocks, and catch only
256 * the vectors we were told to pay attention to.
258 * Target firmware is responsible for all fault handling policy
259 * choices *EXCEPT* explicitly scripted overrides like "vector_catch"
260 * or manual updates to the NVIC SHCSR and CCR registers.
262 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DEMCR
, TRCENA
| armv7m
->demcr
);
263 if (retval
!= ERROR_OK
)
266 /* Paranoia: evidently some (early?) chips don't preserve all the
267 * debug state (including FBP, DWT, etc) across reset...
271 retval
= cortex_m_enable_fpb(target
);
272 if (retval
!= ERROR_OK
) {
273 LOG_ERROR("Failed to enable the FPB");
277 cortex_m
->fpb_enabled
= 1;
279 /* Restore FPB registers */
280 for (i
= 0; i
< cortex_m
->fp_num_code
+ cortex_m
->fp_num_lit
; i
++) {
281 retval
= target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
282 if (retval
!= ERROR_OK
)
286 /* Restore DWT registers */
287 for (i
= 0; i
< cortex_m
->dwt_num_comp
; i
++) {
288 retval
= target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 0,
290 if (retval
!= ERROR_OK
)
292 retval
= target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 4,
294 if (retval
!= ERROR_OK
)
296 retval
= target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 8,
297 dwt_list
[i
].function
);
298 if (retval
!= ERROR_OK
)
301 retval
= dap_run(swjdp
);
302 if (retval
!= ERROR_OK
)
305 register_cache_invalidate(armv7m
->arm
.core_cache
);
307 /* make sure we have latest dhcsr flags */
308 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
313 static int cortex_m_examine_debug_reason(struct target
*target
)
315 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
317 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason
318 * only check the debug reason if we don't know it already */
320 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
321 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
)) {
322 if (cortex_m
->nvic_dfsr
& DFSR_BKPT
) {
323 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
324 if (cortex_m
->nvic_dfsr
& DFSR_DWTTRAP
)
325 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
326 } else if (cortex_m
->nvic_dfsr
& DFSR_DWTTRAP
)
327 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
328 else if (cortex_m
->nvic_dfsr
& DFSR_VCATCH
)
329 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
330 else /* EXTERNAL, HALTED */
331 target
->debug_reason
= DBG_REASON_UNDEFINED
;
337 static int cortex_m_examine_exception_reason(struct target
*target
)
339 uint32_t shcsr
= 0, except_sr
= 0, cfsr
= -1, except_ar
= -1;
340 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
341 struct adiv5_dap
*swjdp
= armv7m
->arm
.dap
;
344 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_SHCSR
, &shcsr
);
345 if (retval
!= ERROR_OK
)
347 switch (armv7m
->exception_number
) {
350 case 3: /* Hard Fault */
351 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, NVIC_HFSR
, &except_sr
);
352 if (retval
!= ERROR_OK
)
354 if (except_sr
& 0x40000000) {
355 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_CFSR
, &cfsr
);
356 if (retval
!= ERROR_OK
)
360 case 4: /* Memory Management */
361 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_CFSR
, &except_sr
);
362 if (retval
!= ERROR_OK
)
364 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_MMFAR
, &except_ar
);
365 if (retval
!= ERROR_OK
)
368 case 5: /* Bus Fault */
369 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_CFSR
, &except_sr
);
370 if (retval
!= ERROR_OK
)
372 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_BFAR
, &except_ar
);
373 if (retval
!= ERROR_OK
)
376 case 6: /* Usage Fault */
377 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_CFSR
, &except_sr
);
378 if (retval
!= ERROR_OK
)
381 case 11: /* SVCall */
383 case 12: /* Debug Monitor */
384 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_DFSR
, &except_sr
);
385 if (retval
!= ERROR_OK
)
388 case 14: /* PendSV */
390 case 15: /* SysTick */
396 retval
= dap_run(swjdp
);
397 if (retval
== ERROR_OK
)
398 LOG_DEBUG("%s SHCSR 0x%" PRIx32
", SR 0x%" PRIx32
399 ", CFSR 0x%" PRIx32
", AR 0x%" PRIx32
,
400 armv7m_exception_string(armv7m
->exception_number
),
401 shcsr
, except_sr
, cfsr
, except_ar
);
405 static int cortex_m_debug_entry(struct target
*target
)
410 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
411 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
412 struct arm
*arm
= &armv7m
->arm
;
417 cortex_m_clear_halt(target
);
418 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
419 if (retval
!= ERROR_OK
)
422 retval
= armv7m
->examine_debug_reason(target
);
423 if (retval
!= ERROR_OK
)
426 /* Examine target state and mode
427 * First load register accessible through core debug port */
428 int num_regs
= arm
->core_cache
->num_regs
;
430 for (i
= 0; i
< num_regs
; i
++) {
431 r
= &armv7m
->arm
.core_cache
->reg_list
[i
];
433 arm
->read_core_reg(target
, r
, i
, ARM_MODE_ANY
);
437 xPSR
= buf_get_u32(r
->value
, 0, 32);
439 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
442 cortex_m_store_core_reg_u32(target
, 16, xPSR
& ~0xff);
445 /* Are we in an exception handler */
447 armv7m
->exception_number
= (xPSR
& 0x1FF);
449 arm
->core_mode
= ARM_MODE_HANDLER
;
450 arm
->map
= armv7m_msp_reg_map
;
452 unsigned control
= buf_get_u32(arm
->core_cache
453 ->reg_list
[ARMV7M_CONTROL
].value
, 0, 2);
455 /* is this thread privileged? */
456 arm
->core_mode
= control
& 1
457 ? ARM_MODE_USER_THREAD
460 /* which stack is it using? */
462 arm
->map
= armv7m_psp_reg_map
;
464 arm
->map
= armv7m_msp_reg_map
;
466 armv7m
->exception_number
= 0;
469 if (armv7m
->exception_number
)
470 cortex_m_examine_exception_reason(target
);
472 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32
", target->state: %s",
473 arm_mode_name(arm
->core_mode
),
474 buf_get_u32(arm
->pc
->value
, 0, 32),
475 target_state_name(target
));
477 if (armv7m
->post_debug_entry
) {
478 retval
= armv7m
->post_debug_entry(target
);
479 if (retval
!= ERROR_OK
)
486 static int cortex_m_poll(struct target
*target
)
488 int detected_failure
= ERROR_OK
;
489 int retval
= ERROR_OK
;
490 enum target_state prev_target_state
= target
->state
;
491 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
492 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
494 /* Read from Debug Halting Control and Status Register */
495 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
496 if (retval
!= ERROR_OK
) {
497 target
->state
= TARGET_UNKNOWN
;
501 /* Recover from lockup. See ARMv7-M architecture spec,
502 * section B1.5.15 "Unrecoverable exception cases".
504 if (cortex_m
->dcb_dhcsr
& S_LOCKUP
) {
505 LOG_ERROR("%s -- clearing lockup after double fault",
506 target_name(target
));
507 cortex_m_write_debug_halt_mask(target
, C_HALT
, 0);
508 target
->debug_reason
= DBG_REASON_DBGRQ
;
510 /* We have to execute the rest (the "finally" equivalent, but
511 * still throw this exception again).
513 detected_failure
= ERROR_FAIL
;
515 /* refresh status bits */
516 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
517 if (retval
!= ERROR_OK
)
521 if (cortex_m
->dcb_dhcsr
& S_RESET_ST
) {
522 target
->state
= TARGET_RESET
;
526 if (target
->state
== TARGET_RESET
) {
527 /* Cannot switch context while running so endreset is
528 * called with target->state == TARGET_RESET
530 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%" PRIx32
,
531 cortex_m
->dcb_dhcsr
);
532 retval
= cortex_m_endreset_event(target
);
533 if (retval
!= ERROR_OK
) {
534 target
->state
= TARGET_UNKNOWN
;
537 target
->state
= TARGET_RUNNING
;
538 prev_target_state
= TARGET_RUNNING
;
541 if (cortex_m
->dcb_dhcsr
& S_HALT
) {
542 target
->state
= TARGET_HALTED
;
544 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
)) {
545 retval
= cortex_m_debug_entry(target
);
546 if (retval
!= ERROR_OK
)
549 if (arm_semihosting(target
, &retval
) != 0)
552 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
554 if (prev_target_state
== TARGET_DEBUG_RUNNING
) {
556 retval
= cortex_m_debug_entry(target
);
557 if (retval
!= ERROR_OK
)
560 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
564 /* REVISIT when S_SLEEP is set, it's in a Sleep or DeepSleep state.
565 * How best to model low power modes?
568 if (target
->state
== TARGET_UNKNOWN
) {
569 /* check if processor is retiring instructions */
570 if (cortex_m
->dcb_dhcsr
& S_RETIRE_ST
) {
571 target
->state
= TARGET_RUNNING
;
576 /* Did we detect a failure condition that we cleared? */
577 if (detected_failure
!= ERROR_OK
)
578 retval
= detected_failure
;
582 static int cortex_m_halt(struct target
*target
)
584 LOG_DEBUG("target->state: %s",
585 target_state_name(target
));
587 if (target
->state
== TARGET_HALTED
) {
588 LOG_DEBUG("target was already halted");
592 if (target
->state
== TARGET_UNKNOWN
)
593 LOG_WARNING("target was in unknown state when halt was requested");
595 if (target
->state
== TARGET_RESET
) {
596 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst()) {
597 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
598 return ERROR_TARGET_FAILURE
;
600 /* we came here in a reset_halt or reset_init sequence
601 * debug entry was already prepared in cortex_m3_assert_reset()
603 target
->debug_reason
= DBG_REASON_DBGRQ
;
609 /* Write to Debug Halting Control and Status Register */
610 cortex_m_write_debug_halt_mask(target
, C_HALT
, 0);
612 target
->debug_reason
= DBG_REASON_DBGRQ
;
617 static int cortex_m_soft_reset_halt(struct target
*target
)
619 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
620 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
621 uint32_t dcb_dhcsr
= 0;
622 int retval
, timeout
= 0;
624 /* soft_reset_halt is deprecated on cortex_m as the same functionality
625 * can be obtained by using 'reset halt' and 'cortex_m reset_config vectreset'
626 * As this reset only used VC_CORERESET it would only ever reset the cortex_m
627 * core, not the peripherals */
628 LOG_WARNING("soft_reset_halt is deprecated, please use 'reset halt' instead.");
630 /* Enter debug state on reset; restore DEMCR in endreset_event() */
631 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DEMCR
,
632 TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
633 if (retval
!= ERROR_OK
)
636 /* Request a core-only reset */
637 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, NVIC_AIRCR
,
638 AIRCR_VECTKEY
| AIRCR_VECTRESET
);
639 if (retval
!= ERROR_OK
)
641 target
->state
= TARGET_RESET
;
643 /* registers are now invalid */
644 register_cache_invalidate(cortex_m
->armv7m
.arm
.core_cache
);
646 while (timeout
< 100) {
647 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &dcb_dhcsr
);
648 if (retval
== ERROR_OK
) {
649 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, NVIC_DFSR
,
650 &cortex_m
->nvic_dfsr
);
651 if (retval
!= ERROR_OK
)
653 if ((dcb_dhcsr
& S_HALT
)
654 && (cortex_m
->nvic_dfsr
& DFSR_VCATCH
)) {
655 LOG_DEBUG("system reset-halted, DHCSR 0x%08x, "
657 (unsigned) dcb_dhcsr
,
658 (unsigned) cortex_m
->nvic_dfsr
);
659 cortex_m_poll(target
);
660 /* FIXME restore user's vector catch config */
663 LOG_DEBUG("waiting for system reset-halt, "
664 "DHCSR 0x%08x, %d ms",
665 (unsigned) dcb_dhcsr
, timeout
);
674 void cortex_m_enable_breakpoints(struct target
*target
)
676 struct breakpoint
*breakpoint
= target
->breakpoints
;
678 /* set any pending breakpoints */
680 if (!breakpoint
->set
)
681 cortex_m_set_breakpoint(target
, breakpoint
);
682 breakpoint
= breakpoint
->next
;
686 static int cortex_m_resume(struct target
*target
, int current
,
687 uint32_t address
, int handle_breakpoints
, int debug_execution
)
689 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
690 struct breakpoint
*breakpoint
= NULL
;
694 if (target
->state
!= TARGET_HALTED
) {
695 LOG_WARNING("target not halted");
696 return ERROR_TARGET_NOT_HALTED
;
699 if (!debug_execution
) {
700 target_free_all_working_areas(target
);
701 cortex_m_enable_breakpoints(target
);
702 cortex_m_enable_watchpoints(target
);
705 if (debug_execution
) {
706 r
= armv7m
->arm
.core_cache
->reg_list
+ ARMV7M_PRIMASK
;
708 /* Disable interrupts */
709 /* We disable interrupts in the PRIMASK register instead of
710 * masking with C_MASKINTS. This is probably the same issue
711 * as Cortex-M3 Erratum 377493 (fixed in r1p0): C_MASKINTS
712 * in parallel with disabled interrupts can cause local faults
715 * REVISIT this clearly breaks non-debug execution, since the
716 * PRIMASK register state isn't saved/restored... workaround
717 * by never resuming app code after debug execution.
719 buf_set_u32(r
->value
, 0, 1, 1);
723 /* Make sure we are in Thumb mode */
724 r
= armv7m
->arm
.cpsr
;
725 buf_set_u32(r
->value
, 24, 1, 1);
730 /* current = 1: continue on current pc, otherwise continue at <address> */
733 buf_set_u32(r
->value
, 0, 32, address
);
738 /* if we halted last time due to a bkpt instruction
739 * then we have to manually step over it, otherwise
740 * the core will break again */
742 if (!breakpoint_find(target
, buf_get_u32(r
->value
, 0, 32))
744 armv7m_maybe_skip_bkpt_inst(target
, NULL
);
746 resume_pc
= buf_get_u32(r
->value
, 0, 32);
748 armv7m_restore_context(target
);
750 /* the front-end may request us not to handle breakpoints */
751 if (handle_breakpoints
) {
752 /* Single step past breakpoint at current address */
753 breakpoint
= breakpoint_find(target
, resume_pc
);
755 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
" (ID: %" PRIu32
")",
757 breakpoint
->unique_id
);
758 cortex_m_unset_breakpoint(target
, breakpoint
);
759 cortex_m_single_step_core(target
);
760 cortex_m_set_breakpoint(target
, breakpoint
);
765 cortex_m_write_debug_halt_mask(target
, 0, C_HALT
);
767 target
->debug_reason
= DBG_REASON_NOTHALTED
;
769 /* registers are now invalid */
770 register_cache_invalidate(armv7m
->arm
.core_cache
);
772 if (!debug_execution
) {
773 target
->state
= TARGET_RUNNING
;
774 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
775 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
777 target
->state
= TARGET_DEBUG_RUNNING
;
778 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
779 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
785 /* int irqstepcount = 0; */
786 static int cortex_m_step(struct target
*target
, int current
,
787 uint32_t address
, int handle_breakpoints
)
789 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
790 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
791 struct breakpoint
*breakpoint
= NULL
;
792 struct reg
*pc
= armv7m
->arm
.pc
;
793 bool bkpt_inst_found
= false;
795 bool isr_timed_out
= false;
797 if (target
->state
!= TARGET_HALTED
) {
798 LOG_WARNING("target not halted");
799 return ERROR_TARGET_NOT_HALTED
;
802 /* current = 1: continue on current pc, otherwise continue at <address> */
804 buf_set_u32(pc
->value
, 0, 32, address
);
806 uint32_t pc_value
= buf_get_u32(pc
->value
, 0, 32);
808 /* the front-end may request us not to handle breakpoints */
809 if (handle_breakpoints
) {
810 breakpoint
= breakpoint_find(target
, pc_value
);
812 cortex_m_unset_breakpoint(target
, breakpoint
);
815 armv7m_maybe_skip_bkpt_inst(target
, &bkpt_inst_found
);
817 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
819 armv7m_restore_context(target
);
821 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
823 /* if no bkpt instruction is found at pc then we can perform
824 * a normal step, otherwise we have to manually step over the bkpt
825 * instruction - as such simulate a step */
826 if (bkpt_inst_found
== false) {
827 /* Automatic ISR masking mode off: Just step over the next instruction */
828 if ((cortex_m
->isrmasking_mode
!= CORTEX_M_ISRMASK_AUTO
))
829 cortex_m_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
831 /* Process interrupts during stepping in a way they don't interfere
836 * Set a temporary break point at the current pc and let the core run
837 * with interrupts enabled. Pending interrupts get served and we run
838 * into the breakpoint again afterwards. Then we step over the next
839 * instruction with interrupts disabled.
841 * If the pending interrupts don't complete within time, we leave the
842 * core running. This may happen if the interrupts trigger faster
843 * than the core can process them or the handler doesn't return.
845 * If no more breakpoints are available we simply do a step with
846 * interrupts enabled.
852 * If a break point is already set on the lower half word then a break point on
853 * the upper half word will not break again when the core is restarted. So we
854 * just step over the instruction with interrupts disabled.
856 * The documentation has no information about this, it was found by observation
857 * on STM32F1 and STM32F2. Proper explanation welcome. STM32F0 dosen't seem to
858 * suffer from this problem.
860 * To add some confusion: pc_value has bit 0 always set, while the breakpoint
861 * address has it always cleared. The former is done to indicate thumb mode
865 if ((pc_value
& 0x02) && breakpoint_find(target
, pc_value
& ~0x03)) {
866 LOG_DEBUG("Stepping over next instruction with interrupts disabled");
867 cortex_m_write_debug_halt_mask(target
, C_HALT
| C_MASKINTS
, 0);
868 cortex_m_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
869 /* Re-enable interrupts */
870 cortex_m_write_debug_halt_mask(target
, C_HALT
, C_MASKINTS
);
874 /* Set a temporary break point */
876 retval
= cortex_m_set_breakpoint(target
, breakpoint
);
878 retval
= breakpoint_add(target
, pc_value
, 2, BKPT_TYPE_BY_ADDR(pc_value
));
879 bool tmp_bp_set
= (retval
== ERROR_OK
);
881 /* No more breakpoints left, just do a step */
883 cortex_m_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
886 LOG_DEBUG("Starting core to serve pending interrupts");
887 int64_t t_start
= timeval_ms();
888 cortex_m_write_debug_halt_mask(target
, 0, C_HALT
| C_STEP
);
890 /* Wait for pending handlers to complete or timeout */
892 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
,
894 &cortex_m
->dcb_dhcsr
);
895 if (retval
!= ERROR_OK
) {
896 target
->state
= TARGET_UNKNOWN
;
899 isr_timed_out
= ((timeval_ms() - t_start
) > 500);
900 } while (!((cortex_m
->dcb_dhcsr
& S_HALT
) || isr_timed_out
));
902 /* only remove breakpoint if we created it */
904 cortex_m_unset_breakpoint(target
, breakpoint
);
906 /* Remove the temporary breakpoint */
907 breakpoint_remove(target
, pc_value
);
911 LOG_DEBUG("Interrupt handlers didn't complete within time, "
912 "leaving target running");
914 /* Step over next instruction with interrupts disabled */
915 cortex_m_write_debug_halt_mask(target
,
918 cortex_m_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
919 /* Re-enable interrupts */
920 cortex_m_write_debug_halt_mask(target
, C_HALT
, C_MASKINTS
);
927 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
928 if (retval
!= ERROR_OK
)
931 /* registers are now invalid */
932 register_cache_invalidate(armv7m
->arm
.core_cache
);
935 cortex_m_set_breakpoint(target
, breakpoint
);
938 /* Leave the core running. The user has to stop execution manually. */
939 target
->debug_reason
= DBG_REASON_NOTHALTED
;
940 target
->state
= TARGET_RUNNING
;
944 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
945 " nvic_icsr = 0x%" PRIx32
,
946 cortex_m
->dcb_dhcsr
, cortex_m
->nvic_icsr
);
948 retval
= cortex_m_debug_entry(target
);
949 if (retval
!= ERROR_OK
)
951 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
953 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
954 " nvic_icsr = 0x%" PRIx32
,
955 cortex_m
->dcb_dhcsr
, cortex_m
->nvic_icsr
);
960 static int cortex_m_assert_reset(struct target
*target
)
962 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
963 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
964 enum cortex_m_soft_reset_config reset_config
= cortex_m
->soft_reset_config
;
966 LOG_DEBUG("target->state: %s",
967 target_state_name(target
));
969 enum reset_types jtag_reset_config
= jtag_get_reset_config();
971 if (target_has_event_action(target
, TARGET_EVENT_RESET_ASSERT
)) {
972 /* allow scripts to override the reset event */
974 target_handle_event(target
, TARGET_EVENT_RESET_ASSERT
);
975 register_cache_invalidate(cortex_m
->armv7m
.arm
.core_cache
);
976 target
->state
= TARGET_RESET
;
981 /* some cores support connecting while srst is asserted
982 * use that mode is it has been configured */
984 bool srst_asserted
= false;
986 if ((jtag_reset_config
& RESET_HAS_SRST
) &&
987 (jtag_reset_config
& RESET_SRST_NO_GATING
)) {
988 adapter_assert_reset();
989 srst_asserted
= true;
992 /* Enable debug requests */
994 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
995 /* Store important errors instead of failing and proceed to reset assert */
997 if (retval
!= ERROR_OK
|| !(cortex_m
->dcb_dhcsr
& C_DEBUGEN
))
998 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
1000 /* If the processor is sleeping in a WFI or WFE instruction, the
1001 * C_HALT bit must be asserted to regain control */
1002 if (retval
== ERROR_OK
&& (cortex_m
->dcb_dhcsr
& S_SLEEP
))
1003 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DHCSR
, DBGKEY
| C_HALT
| C_DEBUGEN
);
1005 mem_ap_write_u32(armv7m
->debug_ap
, DCB_DCRDR
, 0);
1006 /* Ignore less important errors */
1008 if (!target
->reset_halt
) {
1009 /* Set/Clear C_MASKINTS in a separate operation */
1010 if (cortex_m
->dcb_dhcsr
& C_MASKINTS
)
1011 mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
,
1012 DBGKEY
| C_DEBUGEN
| C_HALT
);
1014 /* clear any debug flags before resuming */
1015 cortex_m_clear_halt(target
);
1017 /* clear C_HALT in dhcsr reg */
1018 cortex_m_write_debug_halt_mask(target
, 0, C_HALT
);
1020 /* Halt in debug on reset; endreset_event() restores DEMCR.
1022 * REVISIT catching BUSERR presumably helps to defend against
1023 * bad vector table entries. Should this include MMERR or
1027 retval2
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DEMCR
,
1028 TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
1029 if (retval
!= ERROR_OK
|| retval2
!= ERROR_OK
)
1030 LOG_INFO("AP write error, reset will not halt");
1033 if (jtag_reset_config
& RESET_HAS_SRST
) {
1034 /* default to asserting srst */
1036 adapter_assert_reset();
1038 /* srst is asserted, ignore AP access errors */
1041 /* Use a standard Cortex-M3 software reset mechanism.
1042 * We default to using VECRESET as it is supported on all current cores.
1043 * This has the disadvantage of not resetting the peripherals, so a
1044 * reset-init event handler is needed to perform any peripheral resets.
1046 LOG_DEBUG("Using Cortex-M %s", (reset_config
== CORTEX_M_RESET_SYSRESETREQ
)
1047 ? "SYSRESETREQ" : "VECTRESET");
1049 if (reset_config
== CORTEX_M_RESET_VECTRESET
) {
1050 LOG_WARNING("Only resetting the Cortex-M core, use a reset-init event "
1051 "handler to reset any peripherals or configure hardware srst support.");
1055 retval3
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, NVIC_AIRCR
,
1056 AIRCR_VECTKEY
| ((reset_config
== CORTEX_M_RESET_SYSRESETREQ
)
1057 ? AIRCR_SYSRESETREQ
: AIRCR_VECTRESET
));
1058 if (retval3
!= ERROR_OK
)
1059 LOG_DEBUG("Ignoring AP write error right after reset");
1061 retval3
= dap_dp_init(armv7m
->debug_ap
->dap
);
1062 if (retval3
!= ERROR_OK
)
1063 LOG_ERROR("DP initialisation failed");
1066 /* I do not know why this is necessary, but it
1067 * fixes strange effects (step/resume cause NMI
1068 * after reset) on LM3S6918 -- Michael Schwingen
1071 mem_ap_read_atomic_u32(armv7m
->debug_ap
, NVIC_AIRCR
, &tmp
);
1075 target
->state
= TARGET_RESET
;
1076 jtag_add_sleep(50000);
1078 register_cache_invalidate(cortex_m
->armv7m
.arm
.core_cache
);
1080 /* now return stored error code if any */
1081 if (retval
!= ERROR_OK
)
1084 if (target
->reset_halt
) {
1085 retval
= target_halt(target
);
1086 if (retval
!= ERROR_OK
)
1093 static int cortex_m_deassert_reset(struct target
*target
)
1095 struct armv7m_common
*armv7m
= &target_to_cm(target
)->armv7m
;
1097 LOG_DEBUG("target->state: %s",
1098 target_state_name(target
));
1100 /* deassert reset lines */
1101 adapter_deassert_reset();
1103 enum reset_types jtag_reset_config
= jtag_get_reset_config();
1105 if ((jtag_reset_config
& RESET_HAS_SRST
) &&
1106 !(jtag_reset_config
& RESET_SRST_NO_GATING
)) {
1107 int retval
= dap_dp_init(armv7m
->debug_ap
->dap
);
1108 if (retval
!= ERROR_OK
) {
1109 LOG_ERROR("DP initialisation failed");
1117 int cortex_m_set_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1121 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1122 struct cortex_m_fp_comparator
*comparator_list
= cortex_m
->fp_comparator_list
;
1124 if (breakpoint
->set
) {
1125 LOG_WARNING("breakpoint (BPID: %" PRIu32
") already set", breakpoint
->unique_id
);
1129 if (cortex_m
->auto_bp_type
)
1130 breakpoint
->type
= BKPT_TYPE_BY_ADDR(breakpoint
->address
);
1132 if (breakpoint
->type
== BKPT_HARD
) {
1133 uint32_t fpcr_value
;
1134 while (comparator_list
[fp_num
].used
&& (fp_num
< cortex_m
->fp_num_code
))
1136 if (fp_num
>= cortex_m
->fp_num_code
) {
1137 LOG_ERROR("Can not find free FPB Comparator!");
1140 breakpoint
->set
= fp_num
+ 1;
1141 fpcr_value
= breakpoint
->address
| 1;
1142 if (cortex_m
->fp_rev
== 0) {
1144 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
1145 fpcr_value
= (fpcr_value
& 0x1FFFFFFC) | hilo
| 1;
1146 } else if (cortex_m
->fp_rev
> 1) {
1147 LOG_ERROR("Unhandled Cortex-M Flash Patch Breakpoint architecture revision");
1150 comparator_list
[fp_num
].used
= 1;
1151 comparator_list
[fp_num
].fpcr_value
= fpcr_value
;
1152 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
,
1153 comparator_list
[fp_num
].fpcr_value
);
1154 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32
"",
1156 comparator_list
[fp_num
].fpcr_value
);
1157 if (!cortex_m
->fpb_enabled
) {
1158 LOG_DEBUG("FPB wasn't enabled, do it now");
1159 retval
= cortex_m_enable_fpb(target
);
1160 if (retval
!= ERROR_OK
) {
1161 LOG_ERROR("Failed to enable the FPB");
1165 cortex_m
->fpb_enabled
= 1;
1167 } else if (breakpoint
->type
== BKPT_SOFT
) {
1170 /* NOTE: on ARMv6-M and ARMv7-M, BKPT(0xab) is used for
1171 * semihosting; don't use that. Otherwise the BKPT
1172 * parameter is arbitrary.
1174 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1175 retval
= target_read_memory(target
,
1176 breakpoint
->address
& 0xFFFFFFFE,
1177 breakpoint
->length
, 1,
1178 breakpoint
->orig_instr
);
1179 if (retval
!= ERROR_OK
)
1181 retval
= target_write_memory(target
,
1182 breakpoint
->address
& 0xFFFFFFFE,
1183 breakpoint
->length
, 1,
1185 if (retval
!= ERROR_OK
)
1187 breakpoint
->set
= true;
1190 LOG_DEBUG("BPID: %" PRIu32
", Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
1191 breakpoint
->unique_id
,
1192 (int)(breakpoint
->type
),
1193 breakpoint
->address
,
1200 int cortex_m_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1203 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1204 struct cortex_m_fp_comparator
*comparator_list
= cortex_m
->fp_comparator_list
;
1206 if (!breakpoint
->set
) {
1207 LOG_WARNING("breakpoint not set");
1211 LOG_DEBUG("BPID: %" PRIu32
", Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
1212 breakpoint
->unique_id
,
1213 (int)(breakpoint
->type
),
1214 breakpoint
->address
,
1218 if (breakpoint
->type
== BKPT_HARD
) {
1219 int fp_num
= breakpoint
->set
- 1;
1220 if ((fp_num
< 0) || (fp_num
>= cortex_m
->fp_num_code
)) {
1221 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
1224 comparator_list
[fp_num
].used
= 0;
1225 comparator_list
[fp_num
].fpcr_value
= 0;
1226 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
,
1227 comparator_list
[fp_num
].fpcr_value
);
1229 /* restore original instruction (kept in target endianness) */
1230 if (breakpoint
->length
== 4) {
1231 retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1,
1232 breakpoint
->orig_instr
);
1233 if (retval
!= ERROR_OK
)
1236 retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1,
1237 breakpoint
->orig_instr
);
1238 if (retval
!= ERROR_OK
)
1242 breakpoint
->set
= false;
1247 int cortex_m_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1249 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1251 if (cortex_m
->auto_bp_type
)
1252 breakpoint
->type
= BKPT_TYPE_BY_ADDR(breakpoint
->address
);
1254 if (breakpoint
->type
!= BKPT_TYPE_BY_ADDR(breakpoint
->address
)) {
1255 if (breakpoint
->type
== BKPT_HARD
) {
1256 LOG_INFO("flash patch comparator requested outside code memory region");
1257 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1260 if (breakpoint
->type
== BKPT_SOFT
) {
1261 LOG_INFO("soft breakpoint requested in code (flash) memory region");
1262 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1266 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m
->fp_code_available
< 1)) {
1267 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
1268 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1271 if (breakpoint
->length
== 3) {
1272 LOG_DEBUG("Using a two byte breakpoint for 32bit Thumb-2 request");
1273 breakpoint
->length
= 2;
1276 if ((breakpoint
->length
!= 2)) {
1277 LOG_INFO("only breakpoints of two bytes length supported");
1278 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1281 if (breakpoint
->type
== BKPT_HARD
)
1282 cortex_m
->fp_code_available
--;
1284 return cortex_m_set_breakpoint(target
, breakpoint
);
1287 int cortex_m_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1289 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1291 /* REVISIT why check? FBP can be updated with core running ... */
1292 if (target
->state
!= TARGET_HALTED
) {
1293 LOG_WARNING("target not halted");
1294 return ERROR_TARGET_NOT_HALTED
;
1297 if (cortex_m
->auto_bp_type
)
1298 breakpoint
->type
= BKPT_TYPE_BY_ADDR(breakpoint
->address
);
1300 if (breakpoint
->set
)
1301 cortex_m_unset_breakpoint(target
, breakpoint
);
1303 if (breakpoint
->type
== BKPT_HARD
)
1304 cortex_m
->fp_code_available
++;
1309 int cortex_m_set_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1312 uint32_t mask
, temp
;
1313 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1315 /* watchpoint params were validated earlier */
1317 temp
= watchpoint
->length
;
1324 /* REVISIT Don't fully trust these "not used" records ... users
1325 * may set up breakpoints by hand, e.g. dual-address data value
1326 * watchpoint using comparator #1; comparator #0 matching cycle
1327 * count; send data trace info through ITM and TPIU; etc
1329 struct cortex_m_dwt_comparator
*comparator
;
1331 for (comparator
= cortex_m
->dwt_comparator_list
;
1332 comparator
->used
&& dwt_num
< cortex_m
->dwt_num_comp
;
1333 comparator
++, dwt_num
++)
1335 if (dwt_num
>= cortex_m
->dwt_num_comp
) {
1336 LOG_ERROR("Can not find free DWT Comparator");
1339 comparator
->used
= 1;
1340 watchpoint
->set
= dwt_num
+ 1;
1342 comparator
->comp
= watchpoint
->address
;
1343 target_write_u32(target
, comparator
->dwt_comparator_address
+ 0,
1346 comparator
->mask
= mask
;
1347 target_write_u32(target
, comparator
->dwt_comparator_address
+ 4,
1350 switch (watchpoint
->rw
) {
1352 comparator
->function
= 5;
1355 comparator
->function
= 6;
1358 comparator
->function
= 7;
1361 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1362 comparator
->function
);
1364 LOG_DEBUG("Watchpoint (ID %d) DWT%d 0x%08x 0x%x 0x%05x",
1365 watchpoint
->unique_id
, dwt_num
,
1366 (unsigned) comparator
->comp
,
1367 (unsigned) comparator
->mask
,
1368 (unsigned) comparator
->function
);
1372 int cortex_m_unset_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1374 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1375 struct cortex_m_dwt_comparator
*comparator
;
1378 if (!watchpoint
->set
) {
1379 LOG_WARNING("watchpoint (wpid: %d) not set",
1380 watchpoint
->unique_id
);
1384 dwt_num
= watchpoint
->set
- 1;
1386 LOG_DEBUG("Watchpoint (ID %d) DWT%d address: 0x%08x clear",
1387 watchpoint
->unique_id
, dwt_num
,
1388 (unsigned) watchpoint
->address
);
1390 if ((dwt_num
< 0) || (dwt_num
>= cortex_m
->dwt_num_comp
)) {
1391 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1395 comparator
= cortex_m
->dwt_comparator_list
+ dwt_num
;
1396 comparator
->used
= 0;
1397 comparator
->function
= 0;
1398 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1399 comparator
->function
);
1401 watchpoint
->set
= false;
1406 int cortex_m_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1408 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1410 if (cortex_m
->dwt_comp_available
< 1) {
1411 LOG_DEBUG("no comparators?");
1412 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1415 /* hardware doesn't support data value masking */
1416 if (watchpoint
->mask
!= ~(uint32_t)0) {
1417 LOG_DEBUG("watchpoint value masks not supported");
1418 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1421 /* hardware allows address masks of up to 32K */
1424 for (mask
= 0; mask
< 16; mask
++) {
1425 if ((1u << mask
) == watchpoint
->length
)
1429 LOG_DEBUG("unsupported watchpoint length");
1430 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1432 if (watchpoint
->address
& ((1 << mask
) - 1)) {
1433 LOG_DEBUG("watchpoint address is unaligned");
1434 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1437 /* Caller doesn't seem to be able to describe watching for data
1438 * values of zero; that flags "no value".
1440 * REVISIT This DWT may well be able to watch for specific data
1441 * values. Requires comparator #1 to set DATAVMATCH and match
1442 * the data, and another comparator (DATAVADDR0) matching addr.
1444 if (watchpoint
->value
) {
1445 LOG_DEBUG("data value watchpoint not YET supported");
1446 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1449 cortex_m
->dwt_comp_available
--;
1450 LOG_DEBUG("dwt_comp_available: %d", cortex_m
->dwt_comp_available
);
1455 int cortex_m_remove_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1457 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1459 /* REVISIT why check? DWT can be updated with core running ... */
1460 if (target
->state
!= TARGET_HALTED
) {
1461 LOG_WARNING("target not halted");
1462 return ERROR_TARGET_NOT_HALTED
;
1465 if (watchpoint
->set
)
1466 cortex_m_unset_watchpoint(target
, watchpoint
);
1468 cortex_m
->dwt_comp_available
++;
1469 LOG_DEBUG("dwt_comp_available: %d", cortex_m
->dwt_comp_available
);
1474 void cortex_m_enable_watchpoints(struct target
*target
)
1476 struct watchpoint
*watchpoint
= target
->watchpoints
;
1478 /* set any pending watchpoints */
1479 while (watchpoint
) {
1480 if (!watchpoint
->set
)
1481 cortex_m_set_watchpoint(target
, watchpoint
);
1482 watchpoint
= watchpoint
->next
;
1486 static int cortex_m_load_core_reg_u32(struct target
*target
,
1487 uint32_t num
, uint32_t *value
)
1491 /* NOTE: we "know" here that the register identifiers used
1492 * in the v7m header match the Cortex-M3 Debug Core Register
1493 * Selector values for R0..R15, xPSR, MSP, and PSP.
1497 /* read a normal core register */
1498 retval
= cortexm_dap_read_coreregister_u32(target
, value
, num
);
1500 if (retval
!= ERROR_OK
) {
1501 LOG_ERROR("JTAG failure %i", retval
);
1502 return ERROR_JTAG_DEVICE_ERROR
;
1504 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
"", (int)num
, *value
);
1508 /* Floating-point Status and Registers */
1509 retval
= target_write_u32(target
, DCB_DCRSR
, 0x21);
1510 if (retval
!= ERROR_OK
)
1512 retval
= target_read_u32(target
, DCB_DCRDR
, value
);
1513 if (retval
!= ERROR_OK
)
1515 LOG_DEBUG("load from FPSCR value 0x%" PRIx32
, *value
);
1518 case ARMV7M_S0
... ARMV7M_S31
:
1519 /* Floating-point Status and Registers */
1520 retval
= target_write_u32(target
, DCB_DCRSR
, num
- ARMV7M_S0
+ 0x40);
1521 if (retval
!= ERROR_OK
)
1523 retval
= target_read_u32(target
, DCB_DCRDR
, value
);
1524 if (retval
!= ERROR_OK
)
1526 LOG_DEBUG("load from FPU reg S%d value 0x%" PRIx32
,
1527 (int)(num
- ARMV7M_S0
), *value
);
1530 case ARMV7M_PRIMASK
:
1531 case ARMV7M_BASEPRI
:
1532 case ARMV7M_FAULTMASK
:
1533 case ARMV7M_CONTROL
:
1534 /* Cortex-M3 packages these four registers as bitfields
1535 * in one Debug Core register. So say r0 and r2 docs;
1536 * it was removed from r1 docs, but still works.
1538 cortexm_dap_read_coreregister_u32(target
, value
, 20);
1541 case ARMV7M_PRIMASK
:
1542 *value
= buf_get_u32((uint8_t *)value
, 0, 1);
1545 case ARMV7M_BASEPRI
:
1546 *value
= buf_get_u32((uint8_t *)value
, 8, 8);
1549 case ARMV7M_FAULTMASK
:
1550 *value
= buf_get_u32((uint8_t *)value
, 16, 1);
1553 case ARMV7M_CONTROL
:
1554 *value
= buf_get_u32((uint8_t *)value
, 24, 2);
1558 LOG_DEBUG("load from special reg %i value 0x%" PRIx32
"", (int)num
, *value
);
1562 return ERROR_COMMAND_SYNTAX_ERROR
;
1568 static int cortex_m_store_core_reg_u32(struct target
*target
,
1569 uint32_t num
, uint32_t value
)
1573 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1575 /* NOTE: we "know" here that the register identifiers used
1576 * in the v7m header match the Cortex-M3 Debug Core Register
1577 * Selector values for R0..R15, xPSR, MSP, and PSP.
1581 retval
= cortexm_dap_write_coreregister_u32(target
, value
, num
);
1582 if (retval
!= ERROR_OK
) {
1585 LOG_ERROR("JTAG failure");
1586 r
= armv7m
->arm
.core_cache
->reg_list
+ num
;
1587 r
->dirty
= r
->valid
;
1588 return ERROR_JTAG_DEVICE_ERROR
;
1590 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", (int)num
, value
);
1594 /* Floating-point Status and Registers */
1595 retval
= target_write_u32(target
, DCB_DCRDR
, value
);
1596 if (retval
!= ERROR_OK
)
1598 retval
= target_write_u32(target
, DCB_DCRSR
, 0x21 | (1<<16));
1599 if (retval
!= ERROR_OK
)
1601 LOG_DEBUG("write FPSCR value 0x%" PRIx32
, value
);
1604 case ARMV7M_S0
... ARMV7M_S31
:
1605 /* Floating-point Status and Registers */
1606 retval
= target_write_u32(target
, DCB_DCRDR
, value
);
1607 if (retval
!= ERROR_OK
)
1609 retval
= target_write_u32(target
, DCB_DCRSR
, (num
- ARMV7M_S0
+ 0x40) | (1<<16));
1610 if (retval
!= ERROR_OK
)
1612 LOG_DEBUG("write FPU reg S%d value 0x%" PRIx32
,
1613 (int)(num
- ARMV7M_S0
), value
);
1616 case ARMV7M_PRIMASK
:
1617 case ARMV7M_BASEPRI
:
1618 case ARMV7M_FAULTMASK
:
1619 case ARMV7M_CONTROL
:
1620 /* Cortex-M3 packages these four registers as bitfields
1621 * in one Debug Core register. So say r0 and r2 docs;
1622 * it was removed from r1 docs, but still works.
1624 cortexm_dap_read_coreregister_u32(target
, ®
, 20);
1627 case ARMV7M_PRIMASK
:
1628 buf_set_u32((uint8_t *)®
, 0, 1, value
);
1631 case ARMV7M_BASEPRI
:
1632 buf_set_u32((uint8_t *)®
, 8, 8, value
);
1635 case ARMV7M_FAULTMASK
:
1636 buf_set_u32((uint8_t *)®
, 16, 1, value
);
1639 case ARMV7M_CONTROL
:
1640 buf_set_u32((uint8_t *)®
, 24, 2, value
);
1644 cortexm_dap_write_coreregister_u32(target
, reg
, 20);
1646 LOG_DEBUG("write special reg %i value 0x%" PRIx32
" ", (int)num
, value
);
1650 return ERROR_COMMAND_SYNTAX_ERROR
;
1656 static int cortex_m_read_memory(struct target
*target
, uint32_t address
,
1657 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1659 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1661 if (armv7m
->arm
.is_armv6m
) {
1662 /* armv6m does not handle unaligned memory access */
1663 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1664 return ERROR_TARGET_UNALIGNED_ACCESS
;
1667 return mem_ap_read_buf(armv7m
->debug_ap
, buffer
, size
, count
, address
);
1670 static int cortex_m_write_memory(struct target
*target
, uint32_t address
,
1671 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
1673 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1675 if (armv7m
->arm
.is_armv6m
) {
1676 /* armv6m does not handle unaligned memory access */
1677 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1678 return ERROR_TARGET_UNALIGNED_ACCESS
;
1681 return mem_ap_write_buf(armv7m
->debug_ap
, buffer
, size
, count
, address
);
1684 static int cortex_m_init_target(struct command_context
*cmd_ctx
,
1685 struct target
*target
)
1687 armv7m_build_reg_cache(target
);
1691 void cortex_m_deinit_target(struct target
*target
)
1693 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1695 free(cortex_m
->fp_comparator_list
);
1697 cortex_m_dwt_free(target
);
1698 armv7m_free_reg_cache(target
);
1703 /* REVISIT cache valid/dirty bits are unmaintained. We could set "valid"
1704 * on r/w if the core is not running, and clear on resume or reset ... or
1705 * at least, in a post_restore_context() method.
1708 struct dwt_reg_state
{
1709 struct target
*target
;
1711 uint8_t value
[4]; /* scratch/cache */
1714 static int cortex_m_dwt_get_reg(struct reg
*reg
)
1716 struct dwt_reg_state
*state
= reg
->arch_info
;
1719 int retval
= target_read_u32(state
->target
, state
->addr
, &tmp
);
1720 if (retval
!= ERROR_OK
)
1723 buf_set_u32(state
->value
, 0, 32, tmp
);
1727 static int cortex_m_dwt_set_reg(struct reg
*reg
, uint8_t *buf
)
1729 struct dwt_reg_state
*state
= reg
->arch_info
;
1731 return target_write_u32(state
->target
, state
->addr
,
1732 buf_get_u32(buf
, 0, reg
->size
));
1741 static struct dwt_reg dwt_base_regs
[] = {
1742 { DWT_CTRL
, "dwt_ctrl", 32, },
1743 /* NOTE that Erratum 532314 (fixed r2p0) affects CYCCNT: it wrongly
1744 * increments while the core is asleep.
1746 { DWT_CYCCNT
, "dwt_cyccnt", 32, },
1747 /* plus some 8 bit counters, useful for profiling with TPIU */
1750 static struct dwt_reg dwt_comp
[] = {
1751 #define DWT_COMPARATOR(i) \
1752 { DWT_COMP0 + 0x10 * (i), "dwt_" #i "_comp", 32, }, \
1753 { DWT_MASK0 + 0x10 * (i), "dwt_" #i "_mask", 4, }, \
1754 { DWT_FUNCTION0 + 0x10 * (i), "dwt_" #i "_function", 32, }
1759 #undef DWT_COMPARATOR
1762 static const struct reg_arch_type dwt_reg_type
= {
1763 .get
= cortex_m_dwt_get_reg
,
1764 .set
= cortex_m_dwt_set_reg
,
1767 static void cortex_m_dwt_addreg(struct target
*t
, struct reg
*r
, struct dwt_reg
*d
)
1769 struct dwt_reg_state
*state
;
1771 state
= calloc(1, sizeof *state
);
1774 state
->addr
= d
->addr
;
1779 r
->value
= state
->value
;
1780 r
->arch_info
= state
;
1781 r
->type
= &dwt_reg_type
;
1784 void cortex_m_dwt_setup(struct cortex_m_common
*cm
, struct target
*target
)
1787 struct reg_cache
*cache
;
1788 struct cortex_m_dwt_comparator
*comparator
;
1791 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1793 LOG_DEBUG("no DWT");
1797 cm
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1798 cm
->dwt_comp_available
= cm
->dwt_num_comp
;
1799 cm
->dwt_comparator_list
= calloc(cm
->dwt_num_comp
,
1800 sizeof(struct cortex_m_dwt_comparator
));
1801 if (!cm
->dwt_comparator_list
) {
1803 cm
->dwt_num_comp
= 0;
1804 LOG_ERROR("out of mem");
1808 cache
= calloc(1, sizeof *cache
);
1811 free(cm
->dwt_comparator_list
);
1814 cache
->name
= "Cortex-M DWT registers";
1815 cache
->num_regs
= 2 + cm
->dwt_num_comp
* 3;
1816 cache
->reg_list
= calloc(cache
->num_regs
, sizeof *cache
->reg_list
);
1817 if (!cache
->reg_list
) {
1822 for (reg
= 0; reg
< 2; reg
++)
1823 cortex_m_dwt_addreg(target
, cache
->reg_list
+ reg
,
1824 dwt_base_regs
+ reg
);
1826 comparator
= cm
->dwt_comparator_list
;
1827 for (i
= 0; i
< cm
->dwt_num_comp
; i
++, comparator
++) {
1830 comparator
->dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1831 for (j
= 0; j
< 3; j
++, reg
++)
1832 cortex_m_dwt_addreg(target
, cache
->reg_list
+ reg
,
1833 dwt_comp
+ 3 * i
+ j
);
1835 /* make sure we clear any watchpoints enabled on the target */
1836 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8, 0);
1839 *register_get_last_cache_p(&target
->reg_cache
) = cache
;
1840 cm
->dwt_cache
= cache
;
1842 LOG_DEBUG("DWT dwtcr 0x%" PRIx32
", comp %d, watch%s",
1843 dwtcr
, cm
->dwt_num_comp
,
1844 (dwtcr
& (0xf << 24)) ? " only" : "/trigger");
1846 /* REVISIT: if num_comp > 1, check whether comparator #1 can
1847 * implement single-address data value watchpoints ... so we
1848 * won't need to check it later, when asked to set one up.
1852 static void cortex_m_dwt_free(struct target
*target
)
1854 struct cortex_m_common
*cm
= target_to_cm(target
);
1855 struct reg_cache
*cache
= cm
->dwt_cache
;
1857 free(cm
->dwt_comparator_list
);
1858 cm
->dwt_comparator_list
= NULL
;
1859 cm
->dwt_num_comp
= 0;
1862 register_unlink_cache(&target
->reg_cache
, cache
);
1864 if (cache
->reg_list
) {
1865 for (size_t i
= 0; i
< cache
->num_regs
; i
++)
1866 free(cache
->reg_list
[i
].arch_info
);
1867 free(cache
->reg_list
);
1871 cm
->dwt_cache
= NULL
;
1874 #define MVFR0 0xe000ef40
1875 #define MVFR1 0xe000ef44
1877 #define MVFR0_DEFAULT_M4 0x10110021
1878 #define MVFR1_DEFAULT_M4 0x11000011
1880 int cortex_m_examine(struct target
*target
)
1883 uint32_t cpuid
, fpcr
, mvfr0
, mvfr1
;
1885 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1886 struct adiv5_dap
*swjdp
= cortex_m
->armv7m
.arm
.dap
;
1887 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1889 /* stlink shares the examine handler but does not support
1891 if (!armv7m
->stlink
) {
1892 retval
= dap_dp_init(swjdp
);
1893 if (retval
!= ERROR_OK
) {
1894 LOG_ERROR("Could not initialize the debug port");
1898 /* Search for the MEM-AP */
1899 retval
= dap_find_ap(swjdp
, AP_TYPE_AHB_AP
, &armv7m
->debug_ap
);
1900 if (retval
!= ERROR_OK
) {
1901 LOG_ERROR("Could not find MEM-AP to control the core");
1905 /* Leave (only) generic DAP stuff for debugport_init(); */
1906 armv7m
->debug_ap
->memaccess_tck
= 8;
1908 retval
= mem_ap_init(armv7m
->debug_ap
);
1909 if (retval
!= ERROR_OK
)
1913 if (!target_was_examined(target
)) {
1914 target_set_examined(target
);
1916 /* Read from Device Identification Registers */
1917 retval
= target_read_u32(target
, CPUID
, &cpuid
);
1918 if (retval
!= ERROR_OK
)
1922 i
= (cpuid
>> 4) & 0xf;
1924 LOG_DEBUG("Cortex-M%d r%" PRId8
"p%" PRId8
" processor detected",
1925 i
, (uint8_t)((cpuid
>> 20) & 0xf), (uint8_t)((cpuid
>> 0) & 0xf));
1926 LOG_DEBUG("cpuid: 0x%8.8" PRIx32
"", cpuid
);
1928 /* test for floating point feature on cortex-m4 */
1930 target_read_u32(target
, MVFR0
, &mvfr0
);
1931 target_read_u32(target
, MVFR1
, &mvfr1
);
1933 if ((mvfr0
== MVFR0_DEFAULT_M4
) && (mvfr1
== MVFR1_DEFAULT_M4
)) {
1934 LOG_DEBUG("Cortex-M%d floating point feature FPv4_SP found", i
);
1935 armv7m
->fp_feature
= FPv4_SP
;
1937 } else if (i
== 0) {
1938 /* Cortex-M0 does not support unaligned memory access */
1939 armv7m
->arm
.is_armv6m
= true;
1942 if (armv7m
->fp_feature
!= FPv4_SP
&&
1943 armv7m
->arm
.core_cache
->num_regs
> ARMV7M_NUM_CORE_REGS_NOFP
) {
1944 /* free unavailable FPU registers */
1947 for (idx
= ARMV7M_NUM_CORE_REGS_NOFP
;
1948 idx
< armv7m
->arm
.core_cache
->num_regs
;
1950 free(armv7m
->arm
.core_cache
->reg_list
[idx
].value
);
1951 free(armv7m
->arm
.core_cache
->reg_list
[idx
].feature
);
1952 free(armv7m
->arm
.core_cache
->reg_list
[idx
].reg_data_type
);
1954 armv7m
->arm
.core_cache
->num_regs
= ARMV7M_NUM_CORE_REGS_NOFP
;
1957 if ((i
== 4 || i
== 3) && !armv7m
->stlink
) {
1958 /* Cortex-M3/M4 has 4096 bytes autoincrement range */
1959 armv7m
->debug_ap
->tar_autoincr_block
= (1 << 12);
1962 /* Configure trace modules */
1963 retval
= target_write_u32(target
, DCB_DEMCR
, TRCENA
| armv7m
->demcr
);
1964 if (retval
!= ERROR_OK
)
1967 if (armv7m
->trace_config
.config_type
!= DISABLED
) {
1968 armv7m_trace_tpiu_config(target
);
1969 armv7m_trace_itm_config(target
);
1972 /* NOTE: FPB and DWT are both optional. */
1975 target_read_u32(target
, FP_CTRL
, &fpcr
);
1976 cortex_m
->auto_bp_type
= 1;
1977 /* bits [14:12] and [7:4] */
1978 cortex_m
->fp_num_code
= ((fpcr
>> 8) & 0x70) | ((fpcr
>> 4) & 0xF);
1979 cortex_m
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1980 cortex_m
->fp_code_available
= cortex_m
->fp_num_code
;
1981 /* Detect flash patch revision, see RM DDI 0403E.b page C1-817.
1982 Revision is zero base, fp_rev == 1 means Rev.2 ! */
1983 cortex_m
->fp_rev
= (fpcr
>> 28) & 0xf;
1984 free(cortex_m
->fp_comparator_list
);
1985 cortex_m
->fp_comparator_list
= calloc(
1986 cortex_m
->fp_num_code
+ cortex_m
->fp_num_lit
,
1987 sizeof(struct cortex_m_fp_comparator
));
1988 cortex_m
->fpb_enabled
= fpcr
& 1;
1989 for (i
= 0; i
< cortex_m
->fp_num_code
+ cortex_m
->fp_num_lit
; i
++) {
1990 cortex_m
->fp_comparator_list
[i
].type
=
1991 (i
< cortex_m
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1992 cortex_m
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1994 /* make sure we clear any breakpoints enabled on the target */
1995 target_write_u32(target
, cortex_m
->fp_comparator_list
[i
].fpcr_address
, 0);
1997 LOG_DEBUG("FPB fpcr 0x%" PRIx32
", numcode %i, numlit %i",
1999 cortex_m
->fp_num_code
,
2000 cortex_m
->fp_num_lit
);
2003 cortex_m_dwt_free(target
);
2004 cortex_m_dwt_setup(cortex_m
, target
);
2006 /* These hardware breakpoints only work for code in flash! */
2007 LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints",
2008 target_name(target
),
2009 cortex_m
->fp_num_code
,
2010 cortex_m
->dwt_num_comp
);
2016 static int cortex_m_dcc_read(struct target
*target
, uint8_t *value
, uint8_t *ctrl
)
2018 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
2023 retval
= mem_ap_read_buf_noincr(armv7m
->debug_ap
, buf
, 2, 1, DCB_DCRDR
);
2024 if (retval
!= ERROR_OK
)
2027 dcrdr
= target_buffer_get_u16(target
, buf
);
2028 *ctrl
= (uint8_t)dcrdr
;
2029 *value
= (uint8_t)(dcrdr
>> 8);
2031 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
2033 /* write ack back to software dcc register
2034 * signify we have read data */
2035 if (dcrdr
& (1 << 0)) {
2036 target_buffer_set_u16(target
, buf
, 0);
2037 retval
= mem_ap_write_buf_noincr(armv7m
->debug_ap
, buf
, 2, 1, DCB_DCRDR
);
2038 if (retval
!= ERROR_OK
)
2045 static int cortex_m_target_request_data(struct target
*target
,
2046 uint32_t size
, uint8_t *buffer
)
2052 for (i
= 0; i
< (size
* 4); i
++) {
2053 int retval
= cortex_m_dcc_read(target
, &data
, &ctrl
);
2054 if (retval
!= ERROR_OK
)
2062 static int cortex_m_handle_target_request(void *priv
)
2064 struct target
*target
= priv
;
2065 if (!target_was_examined(target
))
2068 if (!target
->dbg_msg_enabled
)
2071 if (target
->state
== TARGET_RUNNING
) {
2076 retval
= cortex_m_dcc_read(target
, &data
, &ctrl
);
2077 if (retval
!= ERROR_OK
)
2080 /* check if we have data */
2081 if (ctrl
& (1 << 0)) {
2084 /* we assume target is quick enough */
2086 for (int i
= 1; i
<= 3; i
++) {
2087 retval
= cortex_m_dcc_read(target
, &data
, &ctrl
);
2088 if (retval
!= ERROR_OK
)
2090 request
|= ((uint32_t)data
<< (i
* 8));
2092 target_request(target
, request
);
2099 static int cortex_m_init_arch_info(struct target
*target
,
2100 struct cortex_m_common
*cortex_m
, struct jtag_tap
*tap
)
2102 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
2104 armv7m_init_arch_info(target
, armv7m
);
2106 /* tap has no dap initialized */
2108 tap
->dap
= dap_init();
2110 /* Leave (only) generic DAP stuff for debugport_init() */
2111 tap
->dap
->tap
= tap
;
2114 /* default reset mode is to use srst if fitted
2115 * if not it will use CORTEX_M3_RESET_VECTRESET */
2116 cortex_m
->soft_reset_config
= CORTEX_M_RESET_VECTRESET
;
2118 armv7m
->arm
.dap
= tap
->dap
;
2120 /* register arch-specific functions */
2121 armv7m
->examine_debug_reason
= cortex_m_examine_debug_reason
;
2123 armv7m
->post_debug_entry
= NULL
;
2125 armv7m
->pre_restore_context
= NULL
;
2127 armv7m
->load_core_reg_u32
= cortex_m_load_core_reg_u32
;
2128 armv7m
->store_core_reg_u32
= cortex_m_store_core_reg_u32
;
2130 target_register_timer_callback(cortex_m_handle_target_request
, 1, 1, target
);
2135 static int cortex_m_target_create(struct target
*target
, Jim_Interp
*interp
)
2137 struct cortex_m_common
*cortex_m
= calloc(1, sizeof(struct cortex_m_common
));
2139 cortex_m
->common_magic
= CORTEX_M_COMMON_MAGIC
;
2140 cortex_m_init_arch_info(target
, cortex_m
, target
->tap
);
2145 /*--------------------------------------------------------------------------*/
2147 static int cortex_m_verify_pointer(struct command_context
*cmd_ctx
,
2148 struct cortex_m_common
*cm
)
2150 if (cm
->common_magic
!= CORTEX_M_COMMON_MAGIC
) {
2151 command_print(cmd_ctx
, "target is not a Cortex-M");
2152 return ERROR_TARGET_INVALID
;
2158 * Only stuff below this line should need to verify that its target
2159 * is a Cortex-M3. Everything else should have indirected through the
2160 * cortexm3_target structure, which is only used with CM3 targets.
2163 static const struct {
2167 { "hard_err", VC_HARDERR
, },
2168 { "int_err", VC_INTERR
, },
2169 { "bus_err", VC_BUSERR
, },
2170 { "state_err", VC_STATERR
, },
2171 { "chk_err", VC_CHKERR
, },
2172 { "nocp_err", VC_NOCPERR
, },
2173 { "mm_err", VC_MMERR
, },
2174 { "reset", VC_CORERESET
, },
2177 COMMAND_HANDLER(handle_cortex_m_vector_catch_command
)
2179 struct target
*target
= get_current_target(CMD_CTX
);
2180 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
2181 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
2185 retval
= cortex_m_verify_pointer(CMD_CTX
, cortex_m
);
2186 if (retval
!= ERROR_OK
)
2189 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DEMCR
, &demcr
);
2190 if (retval
!= ERROR_OK
)
2196 if (CMD_ARGC
== 1) {
2197 if (strcmp(CMD_ARGV
[0], "all") == 0) {
2198 catch = VC_HARDERR
| VC_INTERR
| VC_BUSERR
2199 | VC_STATERR
| VC_CHKERR
| VC_NOCPERR
2200 | VC_MMERR
| VC_CORERESET
;
2202 } else if (strcmp(CMD_ARGV
[0], "none") == 0)
2205 while (CMD_ARGC
-- > 0) {
2207 for (i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++) {
2208 if (strcmp(CMD_ARGV
[CMD_ARGC
], vec_ids
[i
].name
) != 0)
2210 catch |= vec_ids
[i
].mask
;
2213 if (i
== ARRAY_SIZE(vec_ids
)) {
2214 LOG_ERROR("No CM3 vector '%s'", CMD_ARGV
[CMD_ARGC
]);
2215 return ERROR_COMMAND_SYNTAX_ERROR
;
2219 /* For now, armv7m->demcr only stores vector catch flags. */
2220 armv7m
->demcr
= catch;
2225 /* write, but don't assume it stuck (why not??) */
2226 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DEMCR
, demcr
);
2227 if (retval
!= ERROR_OK
)
2229 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DEMCR
, &demcr
);
2230 if (retval
!= ERROR_OK
)
2233 /* FIXME be sure to clear DEMCR on clean server shutdown.
2234 * Otherwise the vector catch hardware could fire when there's
2235 * no debugger hooked up, causing much confusion...
2239 for (unsigned i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++) {
2240 command_print(CMD_CTX
, "%9s: %s", vec_ids
[i
].name
,
2241 (demcr
& vec_ids
[i
].mask
) ? "catch" : "ignore");
2247 COMMAND_HANDLER(handle_cortex_m_mask_interrupts_command
)
2249 struct target
*target
= get_current_target(CMD_CTX
);
2250 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
2253 static const Jim_Nvp nvp_maskisr_modes
[] = {
2254 { .name
= "auto", .value
= CORTEX_M_ISRMASK_AUTO
},
2255 { .name
= "off", .value
= CORTEX_M_ISRMASK_OFF
},
2256 { .name
= "on", .value
= CORTEX_M_ISRMASK_ON
},
2257 { .name
= NULL
, .value
= -1 },
2262 retval
= cortex_m_verify_pointer(CMD_CTX
, cortex_m
);
2263 if (retval
!= ERROR_OK
)
2266 if (target
->state
!= TARGET_HALTED
) {
2267 command_print(CMD_CTX
, "target must be stopped for \"%s\" command", CMD_NAME
);
2272 n
= Jim_Nvp_name2value_simple(nvp_maskisr_modes
, CMD_ARGV
[0]);
2273 if (n
->name
== NULL
)
2274 return ERROR_COMMAND_SYNTAX_ERROR
;
2275 cortex_m
->isrmasking_mode
= n
->value
;
2278 if (cortex_m
->isrmasking_mode
== CORTEX_M_ISRMASK_ON
)
2279 cortex_m_write_debug_halt_mask(target
, C_HALT
| C_MASKINTS
, 0);
2281 cortex_m_write_debug_halt_mask(target
, C_HALT
, C_MASKINTS
);
2284 n
= Jim_Nvp_value2name_simple(nvp_maskisr_modes
, cortex_m
->isrmasking_mode
);
2285 command_print(CMD_CTX
, "cortex_m interrupt mask %s", n
->name
);
2290 COMMAND_HANDLER(handle_cortex_m_reset_config_command
)
2292 struct target
*target
= get_current_target(CMD_CTX
);
2293 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
2297 retval
= cortex_m_verify_pointer(CMD_CTX
, cortex_m
);
2298 if (retval
!= ERROR_OK
)
2302 if (strcmp(*CMD_ARGV
, "sysresetreq") == 0)
2303 cortex_m
->soft_reset_config
= CORTEX_M_RESET_SYSRESETREQ
;
2304 else if (strcmp(*CMD_ARGV
, "vectreset") == 0)
2305 cortex_m
->soft_reset_config
= CORTEX_M_RESET_VECTRESET
;
2308 switch (cortex_m
->soft_reset_config
) {
2309 case CORTEX_M_RESET_SYSRESETREQ
:
2310 reset_config
= "sysresetreq";
2313 case CORTEX_M_RESET_VECTRESET
:
2314 reset_config
= "vectreset";
2318 reset_config
= "unknown";
2322 command_print(CMD_CTX
, "cortex_m reset_config %s", reset_config
);
2327 static const struct command_registration cortex_m_exec_command_handlers
[] = {
2330 .handler
= handle_cortex_m_mask_interrupts_command
,
2331 .mode
= COMMAND_EXEC
,
2332 .help
= "mask cortex_m interrupts",
2333 .usage
= "['auto'|'on'|'off']",
2336 .name
= "vector_catch",
2337 .handler
= handle_cortex_m_vector_catch_command
,
2338 .mode
= COMMAND_EXEC
,
2339 .help
= "configure hardware vectors to trigger debug entry",
2340 .usage
= "['all'|'none'|('bus_err'|'chk_err'|...)*]",
2343 .name
= "reset_config",
2344 .handler
= handle_cortex_m_reset_config_command
,
2345 .mode
= COMMAND_ANY
,
2346 .help
= "configure software reset handling",
2347 .usage
= "['srst'|'sysresetreq'|'vectreset']",
2349 COMMAND_REGISTRATION_DONE
2351 static const struct command_registration cortex_m_command_handlers
[] = {
2353 .chain
= armv7m_command_handlers
,
2356 .chain
= armv7m_trace_command_handlers
,
2360 .mode
= COMMAND_EXEC
,
2361 .help
= "Cortex-M command group",
2363 .chain
= cortex_m_exec_command_handlers
,
2365 COMMAND_REGISTRATION_DONE
2368 struct target_type cortexm_target
= {
2370 .deprecated_name
= "cortex_m3",
2372 .poll
= cortex_m_poll
,
2373 .arch_state
= armv7m_arch_state
,
2375 .target_request_data
= cortex_m_target_request_data
,
2377 .halt
= cortex_m_halt
,
2378 .resume
= cortex_m_resume
,
2379 .step
= cortex_m_step
,
2381 .assert_reset
= cortex_m_assert_reset
,
2382 .deassert_reset
= cortex_m_deassert_reset
,
2383 .soft_reset_halt
= cortex_m_soft_reset_halt
,
2385 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
2387 .read_memory
= cortex_m_read_memory
,
2388 .write_memory
= cortex_m_write_memory
,
2389 .checksum_memory
= armv7m_checksum_memory
,
2390 .blank_check_memory
= armv7m_blank_check_memory
,
2392 .run_algorithm
= armv7m_run_algorithm
,
2393 .start_algorithm
= armv7m_start_algorithm
,
2394 .wait_algorithm
= armv7m_wait_algorithm
,
2396 .add_breakpoint
= cortex_m_add_breakpoint
,
2397 .remove_breakpoint
= cortex_m_remove_breakpoint
,
2398 .add_watchpoint
= cortex_m_add_watchpoint
,
2399 .remove_watchpoint
= cortex_m_remove_watchpoint
,
2401 .commands
= cortex_m_command_handlers
,
2402 .target_create
= cortex_m_target_create
,
2403 .init_target
= cortex_m_init_target
,
2404 .examine
= cortex_m_examine
,
2405 .deinit_target
= cortex_m_deinit_target
,
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)