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, see <http://www.gnu.org/licenses/>. *
25 * Cortex-M3(tm) TRM, ARM DDI 0337E (r1p1) and 0337G (r2p0) *
27 ***************************************************************************/
32 #include "jtag/interface.h"
33 #include "breakpoints.h"
35 #include "target_request.h"
36 #include "target_type.h"
37 #include "arm_adi_v5.h"
38 #include "arm_disassembler.h"
40 #include "arm_opcodes.h"
41 #include "arm_semihosting.h"
42 #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 FPB 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
56 /* Supported Cortex-M Cores */
57 static const struct cortex_m_part_info cortex_m_parts
[] = {
59 .partno
= CORTEX_M0_PARTNO
,
64 .partno
= CORTEX_M0P_PARTNO
,
69 .partno
= CORTEX_M1_PARTNO
,
74 .partno
= CORTEX_M3_PARTNO
,
77 .flags
= CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K
,
80 .partno
= CORTEX_M4_PARTNO
,
83 .flags
= CORTEX_M_F_HAS_FPV4
| CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K
,
86 .partno
= CORTEX_M7_PARTNO
,
89 .flags
= CORTEX_M_F_HAS_FPV5
,
92 .partno
= CORTEX_M23_PARTNO
,
97 .partno
= CORTEX_M33_PARTNO
,
100 .flags
= CORTEX_M_F_HAS_FPV5
,
103 .partno
= CORTEX_M35P_PARTNO
,
104 .name
= "Cortex-M35P",
105 .arch
= ARM_ARCH_V8M
,
106 .flags
= CORTEX_M_F_HAS_FPV5
,
109 .partno
= CORTEX_M55_PARTNO
,
110 .name
= "Cortex-M55",
111 .arch
= ARM_ARCH_V8M
,
112 .flags
= CORTEX_M_F_HAS_FPV5
,
116 /* forward declarations */
117 static int cortex_m_store_core_reg_u32(struct target
*target
,
118 uint32_t num
, uint32_t value
);
119 static void cortex_m_dwt_free(struct target
*target
);
121 static int cortex_m_load_core_reg_u32(struct target
*target
,
122 uint32_t regsel
, uint32_t *value
)
124 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
128 /* because the DCB_DCRDR is used for the emulated dcc channel
129 * we have to save/restore the DCB_DCRDR when used */
130 if (target
->dbg_msg_enabled
) {
131 retval
= mem_ap_read_u32(armv7m
->debug_ap
, DCB_DCRDR
, &dcrdr
);
132 if (retval
!= ERROR_OK
)
136 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DCRSR
, regsel
);
137 if (retval
!= ERROR_OK
)
140 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DCRDR
, value
);
141 if (retval
!= ERROR_OK
)
144 if (target
->dbg_msg_enabled
) {
145 /* restore DCB_DCRDR - this needs to be in a separate
146 * transaction otherwise the emulated DCC channel breaks */
147 if (retval
== ERROR_OK
)
148 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DCRDR
, dcrdr
);
154 static int cortex_m_store_core_reg_u32(struct target
*target
,
155 uint32_t regsel
, uint32_t value
)
157 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
161 /* because the DCB_DCRDR is used for the emulated dcc channel
162 * we have to save/restore the DCB_DCRDR when used */
163 if (target
->dbg_msg_enabled
) {
164 retval
= mem_ap_read_u32(armv7m
->debug_ap
, DCB_DCRDR
, &dcrdr
);
165 if (retval
!= ERROR_OK
)
169 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DCRDR
, value
);
170 if (retval
!= ERROR_OK
)
173 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DCRSR
, regsel
| DCRSR_WNR
);
174 if (retval
!= ERROR_OK
)
177 if (target
->dbg_msg_enabled
) {
178 /* restore DCB_DCRDR - this needs to be in a separate
179 * transaction otherwise the emulated DCC channel breaks */
180 if (retval
== ERROR_OK
)
181 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DCRDR
, dcrdr
);
187 static int cortex_m_write_debug_halt_mask(struct target
*target
,
188 uint32_t mask_on
, uint32_t mask_off
)
190 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
191 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
193 /* mask off status bits */
194 cortex_m
->dcb_dhcsr
&= ~((0xFFFFul
<< 16) | mask_off
);
195 /* create new register mask */
196 cortex_m
->dcb_dhcsr
|= DBGKEY
| C_DEBUGEN
| mask_on
;
198 return mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, cortex_m
->dcb_dhcsr
);
201 static int cortex_m_set_maskints(struct target
*target
, bool mask
)
203 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
204 if (!!(cortex_m
->dcb_dhcsr
& C_MASKINTS
) != mask
)
205 return cortex_m_write_debug_halt_mask(target
, mask
? C_MASKINTS
: 0, mask
? 0 : C_MASKINTS
);
210 static int cortex_m_set_maskints_for_halt(struct target
*target
)
212 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
213 switch (cortex_m
->isrmasking_mode
) {
214 case CORTEX_M_ISRMASK_AUTO
:
215 /* interrupts taken at resume, whether for step or run -> no mask */
216 return cortex_m_set_maskints(target
, false);
218 case CORTEX_M_ISRMASK_OFF
:
219 /* interrupts never masked */
220 return cortex_m_set_maskints(target
, false);
222 case CORTEX_M_ISRMASK_ON
:
223 /* interrupts always masked */
224 return cortex_m_set_maskints(target
, true);
226 case CORTEX_M_ISRMASK_STEPONLY
:
227 /* interrupts masked for single step only -> mask now if MASKINTS
228 * erratum, otherwise only mask before stepping */
229 return cortex_m_set_maskints(target
, cortex_m
->maskints_erratum
);
234 static int cortex_m_set_maskints_for_run(struct target
*target
)
236 switch (target_to_cm(target
)->isrmasking_mode
) {
237 case CORTEX_M_ISRMASK_AUTO
:
238 /* interrupts taken at resume, whether for step or run -> no mask */
239 return cortex_m_set_maskints(target
, false);
241 case CORTEX_M_ISRMASK_OFF
:
242 /* interrupts never masked */
243 return cortex_m_set_maskints(target
, false);
245 case CORTEX_M_ISRMASK_ON
:
246 /* interrupts always masked */
247 return cortex_m_set_maskints(target
, true);
249 case CORTEX_M_ISRMASK_STEPONLY
:
250 /* interrupts masked for single step only -> no mask */
251 return cortex_m_set_maskints(target
, false);
256 static int cortex_m_set_maskints_for_step(struct target
*target
)
258 switch (target_to_cm(target
)->isrmasking_mode
) {
259 case CORTEX_M_ISRMASK_AUTO
:
260 /* the auto-interrupt should already be done -> mask */
261 return cortex_m_set_maskints(target
, true);
263 case CORTEX_M_ISRMASK_OFF
:
264 /* interrupts never masked */
265 return cortex_m_set_maskints(target
, false);
267 case CORTEX_M_ISRMASK_ON
:
268 /* interrupts always masked */
269 return cortex_m_set_maskints(target
, true);
271 case CORTEX_M_ISRMASK_STEPONLY
:
272 /* interrupts masked for single step only -> mask */
273 return cortex_m_set_maskints(target
, true);
278 static int cortex_m_clear_halt(struct target
*target
)
280 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
281 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
284 /* clear step if any */
285 cortex_m_write_debug_halt_mask(target
, C_HALT
, C_STEP
);
287 /* Read Debug Fault Status Register */
288 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, NVIC_DFSR
, &cortex_m
->nvic_dfsr
);
289 if (retval
!= ERROR_OK
)
292 /* Clear Debug Fault Status */
293 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, NVIC_DFSR
, cortex_m
->nvic_dfsr
);
294 if (retval
!= ERROR_OK
)
296 LOG_DEBUG(" NVIC_DFSR 0x%" PRIx32
"", cortex_m
->nvic_dfsr
);
301 static int cortex_m_single_step_core(struct target
*target
)
303 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
304 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
307 /* Mask interrupts before clearing halt, if not done already. This avoids
308 * Erratum 377497 (fixed in r1p0) where setting MASKINTS while clearing
309 * HALT can put the core into an unknown state.
311 if (!(cortex_m
->dcb_dhcsr
& C_MASKINTS
)) {
312 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
,
313 DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
314 if (retval
!= ERROR_OK
)
317 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
,
318 DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
319 if (retval
!= ERROR_OK
)
323 /* restore dhcsr reg */
324 cortex_m_clear_halt(target
);
329 static int cortex_m_enable_fpb(struct target
*target
)
331 int retval
= target_write_u32(target
, FP_CTRL
, 3);
332 if (retval
!= ERROR_OK
)
335 /* check the fpb is actually enabled */
337 retval
= target_read_u32(target
, FP_CTRL
, &fpctrl
);
338 if (retval
!= ERROR_OK
)
347 static int cortex_m_endreset_event(struct target
*target
)
351 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
352 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
353 struct adiv5_dap
*swjdp
= cortex_m
->armv7m
.arm
.dap
;
354 struct cortex_m_fp_comparator
*fp_list
= cortex_m
->fp_comparator_list
;
355 struct cortex_m_dwt_comparator
*dwt_list
= cortex_m
->dwt_comparator_list
;
357 /* REVISIT The four debug monitor bits are currently ignored... */
358 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DEMCR
, &dcb_demcr
);
359 if (retval
!= ERROR_OK
)
361 LOG_DEBUG("DCB_DEMCR = 0x%8.8" PRIx32
"", dcb_demcr
);
363 /* this register is used for emulated dcc channel */
364 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DCRDR
, 0);
365 if (retval
!= ERROR_OK
)
368 /* Enable debug requests */
369 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
370 if (retval
!= ERROR_OK
)
372 if (!(cortex_m
->dcb_dhcsr
& C_DEBUGEN
)) {
373 retval
= cortex_m_write_debug_halt_mask(target
, 0, C_HALT
| C_STEP
| C_MASKINTS
);
374 if (retval
!= ERROR_OK
)
378 /* Restore proper interrupt masking setting for running CPU. */
379 cortex_m_set_maskints_for_run(target
);
381 /* Enable features controlled by ITM and DWT blocks, and catch only
382 * the vectors we were told to pay attention to.
384 * Target firmware is responsible for all fault handling policy
385 * choices *EXCEPT* explicitly scripted overrides like "vector_catch"
386 * or manual updates to the NVIC SHCSR and CCR registers.
388 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DEMCR
, TRCENA
| armv7m
->demcr
);
389 if (retval
!= ERROR_OK
)
392 /* Paranoia: evidently some (early?) chips don't preserve all the
393 * debug state (including FPB, DWT, etc) across reset...
397 retval
= cortex_m_enable_fpb(target
);
398 if (retval
!= ERROR_OK
) {
399 LOG_ERROR("Failed to enable the FPB");
403 cortex_m
->fpb_enabled
= true;
405 /* Restore FPB registers */
406 for (unsigned int i
= 0; i
< cortex_m
->fp_num_code
+ cortex_m
->fp_num_lit
; i
++) {
407 retval
= target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
408 if (retval
!= ERROR_OK
)
412 /* Restore DWT registers */
413 for (unsigned int i
= 0; i
< cortex_m
->dwt_num_comp
; i
++) {
414 retval
= target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 0,
416 if (retval
!= ERROR_OK
)
418 retval
= target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 4,
420 if (retval
!= ERROR_OK
)
422 retval
= target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 8,
423 dwt_list
[i
].function
);
424 if (retval
!= ERROR_OK
)
427 retval
= dap_run(swjdp
);
428 if (retval
!= ERROR_OK
)
431 register_cache_invalidate(armv7m
->arm
.core_cache
);
433 /* make sure we have latest dhcsr flags */
434 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
439 static int cortex_m_examine_debug_reason(struct target
*target
)
441 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
443 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason
444 * only check the debug reason if we don't know it already */
446 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
447 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
)) {
448 if (cortex_m
->nvic_dfsr
& DFSR_BKPT
) {
449 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
450 if (cortex_m
->nvic_dfsr
& DFSR_DWTTRAP
)
451 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
452 } else if (cortex_m
->nvic_dfsr
& DFSR_DWTTRAP
)
453 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
454 else if (cortex_m
->nvic_dfsr
& DFSR_VCATCH
)
455 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
456 else if (cortex_m
->nvic_dfsr
& DFSR_EXTERNAL
)
457 target
->debug_reason
= DBG_REASON_DBGRQ
;
459 target
->debug_reason
= DBG_REASON_UNDEFINED
;
465 static int cortex_m_examine_exception_reason(struct target
*target
)
467 uint32_t shcsr
= 0, except_sr
= 0, cfsr
= -1, except_ar
= -1;
468 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
469 struct adiv5_dap
*swjdp
= armv7m
->arm
.dap
;
472 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_SHCSR
, &shcsr
);
473 if (retval
!= ERROR_OK
)
475 switch (armv7m
->exception_number
) {
478 case 3: /* Hard Fault */
479 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, NVIC_HFSR
, &except_sr
);
480 if (retval
!= ERROR_OK
)
482 if (except_sr
& 0x40000000) {
483 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_CFSR
, &cfsr
);
484 if (retval
!= ERROR_OK
)
488 case 4: /* Memory Management */
489 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_CFSR
, &except_sr
);
490 if (retval
!= ERROR_OK
)
492 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_MMFAR
, &except_ar
);
493 if (retval
!= ERROR_OK
)
496 case 5: /* Bus Fault */
497 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_CFSR
, &except_sr
);
498 if (retval
!= ERROR_OK
)
500 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_BFAR
, &except_ar
);
501 if (retval
!= ERROR_OK
)
504 case 6: /* Usage Fault */
505 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_CFSR
, &except_sr
);
506 if (retval
!= ERROR_OK
)
509 case 7: /* Secure Fault */
510 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_SFSR
, &except_sr
);
511 if (retval
!= ERROR_OK
)
513 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_SFAR
, &except_ar
);
514 if (retval
!= ERROR_OK
)
517 case 11: /* SVCall */
519 case 12: /* Debug Monitor */
520 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_DFSR
, &except_sr
);
521 if (retval
!= ERROR_OK
)
524 case 14: /* PendSV */
526 case 15: /* SysTick */
532 retval
= dap_run(swjdp
);
533 if (retval
== ERROR_OK
)
534 LOG_DEBUG("%s SHCSR 0x%" PRIx32
", SR 0x%" PRIx32
535 ", CFSR 0x%" PRIx32
", AR 0x%" PRIx32
,
536 armv7m_exception_string(armv7m
->exception_number
),
537 shcsr
, except_sr
, cfsr
, except_ar
);
541 static int cortex_m_debug_entry(struct target
*target
)
546 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
547 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
548 struct arm
*arm
= &armv7m
->arm
;
553 /* Do this really early to minimize the window where the MASKINTS erratum
554 * can pile up pending interrupts. */
555 cortex_m_set_maskints_for_halt(target
);
557 cortex_m_clear_halt(target
);
558 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
559 if (retval
!= ERROR_OK
)
562 retval
= armv7m
->examine_debug_reason(target
);
563 if (retval
!= ERROR_OK
)
566 /* examine PE security state */
567 bool secure_state
= false;
568 if (armv7m
->arm
.arch
== ARM_ARCH_V8M
) {
571 retval
= mem_ap_read_u32(armv7m
->debug_ap
, DCB_DSCSR
, &dscsr
);
572 if (retval
!= ERROR_OK
)
575 secure_state
= (dscsr
& DSCSR_CDS
) == DSCSR_CDS
;
578 /* Examine target state and mode
579 * First load register accessible through core debug port */
580 int num_regs
= arm
->core_cache
->num_regs
;
582 for (i
= 0; i
< num_regs
; i
++) {
583 r
= &armv7m
->arm
.core_cache
->reg_list
[i
];
584 if (r
->exist
&& !r
->valid
)
585 arm
->read_core_reg(target
, r
, i
, ARM_MODE_ANY
);
589 xPSR
= buf_get_u32(r
->value
, 0, 32);
591 /* Are we in an exception handler */
593 armv7m
->exception_number
= (xPSR
& 0x1FF);
595 arm
->core_mode
= ARM_MODE_HANDLER
;
596 arm
->map
= armv7m_msp_reg_map
;
598 unsigned control
= buf_get_u32(arm
->core_cache
599 ->reg_list
[ARMV7M_CONTROL
].value
, 0, 3);
601 /* is this thread privileged? */
602 arm
->core_mode
= control
& 1
603 ? ARM_MODE_USER_THREAD
606 /* which stack is it using? */
608 arm
->map
= armv7m_psp_reg_map
;
610 arm
->map
= armv7m_msp_reg_map
;
612 armv7m
->exception_number
= 0;
615 if (armv7m
->exception_number
)
616 cortex_m_examine_exception_reason(target
);
618 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32
", cpu in %s state, target->state: %s",
619 arm_mode_name(arm
->core_mode
),
620 buf_get_u32(arm
->pc
->value
, 0, 32),
621 secure_state
? "Secure" : "Non-Secure",
622 target_state_name(target
));
624 if (armv7m
->post_debug_entry
) {
625 retval
= armv7m
->post_debug_entry(target
);
626 if (retval
!= ERROR_OK
)
633 static int cortex_m_poll(struct target
*target
)
635 int detected_failure
= ERROR_OK
;
636 int retval
= ERROR_OK
;
637 enum target_state prev_target_state
= target
->state
;
638 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
639 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
641 /* Read from Debug Halting Control and Status Register */
642 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
643 if (retval
!= ERROR_OK
) {
644 target
->state
= TARGET_UNKNOWN
;
648 /* Recover from lockup. See ARMv7-M architecture spec,
649 * section B1.5.15 "Unrecoverable exception cases".
651 if (cortex_m
->dcb_dhcsr
& S_LOCKUP
) {
652 LOG_ERROR("%s -- clearing lockup after double fault",
653 target_name(target
));
654 cortex_m_write_debug_halt_mask(target
, C_HALT
, 0);
655 target
->debug_reason
= DBG_REASON_DBGRQ
;
657 /* We have to execute the rest (the "finally" equivalent, but
658 * still throw this exception again).
660 detected_failure
= ERROR_FAIL
;
662 /* refresh status bits */
663 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
664 if (retval
!= ERROR_OK
)
668 if (cortex_m
->dcb_dhcsr
& S_RESET_ST
) {
669 if (target
->state
!= TARGET_RESET
) {
670 target
->state
= TARGET_RESET
;
671 LOG_INFO("%s: external reset detected", target_name(target
));
676 if (target
->state
== TARGET_RESET
) {
677 /* Cannot switch context while running so endreset is
678 * called with target->state == TARGET_RESET
680 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%" PRIx32
,
681 cortex_m
->dcb_dhcsr
);
682 retval
= cortex_m_endreset_event(target
);
683 if (retval
!= ERROR_OK
) {
684 target
->state
= TARGET_UNKNOWN
;
687 target
->state
= TARGET_RUNNING
;
688 prev_target_state
= TARGET_RUNNING
;
691 if (cortex_m
->dcb_dhcsr
& S_HALT
) {
692 target
->state
= TARGET_HALTED
;
694 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
)) {
695 retval
= cortex_m_debug_entry(target
);
696 if (retval
!= ERROR_OK
)
699 if (arm_semihosting(target
, &retval
) != 0)
702 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
704 if (prev_target_state
== TARGET_DEBUG_RUNNING
) {
706 retval
= cortex_m_debug_entry(target
);
707 if (retval
!= ERROR_OK
)
710 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
714 if (target
->state
== TARGET_UNKNOWN
) {
715 /* check if processor is retiring instructions or sleeping */
716 if (cortex_m
->dcb_dhcsr
& S_RETIRE_ST
|| cortex_m
->dcb_dhcsr
& S_SLEEP
) {
717 target
->state
= TARGET_RUNNING
;
722 /* Check that target is truly halted, since the target could be resumed externally */
723 if ((prev_target_state
== TARGET_HALTED
) && !(cortex_m
->dcb_dhcsr
& S_HALT
)) {
724 /* registers are now invalid */
725 register_cache_invalidate(armv7m
->arm
.core_cache
);
727 target
->state
= TARGET_RUNNING
;
728 LOG_WARNING("%s: external resume detected", target_name(target
));
729 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
733 /* Did we detect a failure condition that we cleared? */
734 if (detected_failure
!= ERROR_OK
)
735 retval
= detected_failure
;
739 static int cortex_m_halt(struct target
*target
)
741 LOG_DEBUG("target->state: %s",
742 target_state_name(target
));
744 if (target
->state
== TARGET_HALTED
) {
745 LOG_DEBUG("target was already halted");
749 if (target
->state
== TARGET_UNKNOWN
)
750 LOG_WARNING("target was in unknown state when halt was requested");
752 if (target
->state
== TARGET_RESET
) {
753 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst()) {
754 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
755 return ERROR_TARGET_FAILURE
;
757 /* we came here in a reset_halt or reset_init sequence
758 * debug entry was already prepared in cortex_m3_assert_reset()
760 target
->debug_reason
= DBG_REASON_DBGRQ
;
766 /* Write to Debug Halting Control and Status Register */
767 cortex_m_write_debug_halt_mask(target
, C_HALT
, 0);
769 /* Do this really early to minimize the window where the MASKINTS erratum
770 * can pile up pending interrupts. */
771 cortex_m_set_maskints_for_halt(target
);
773 target
->debug_reason
= DBG_REASON_DBGRQ
;
778 static int cortex_m_soft_reset_halt(struct target
*target
)
780 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
781 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
782 uint32_t dcb_dhcsr
= 0;
783 int retval
, timeout
= 0;
785 /* on single cortex_m MCU soft_reset_halt should be avoided as same functionality
786 * can be obtained by using 'reset halt' and 'cortex_m reset_config vectreset'.
787 * As this reset only uses VC_CORERESET it would only ever reset the cortex_m
788 * core, not the peripherals */
789 LOG_DEBUG("soft_reset_halt is discouraged, please use 'reset halt' instead.");
791 if (!cortex_m
->vectreset_supported
) {
792 LOG_ERROR("VECTRESET is not supported on this Cortex-M core");
797 retval
= cortex_m_write_debug_halt_mask(target
, 0, C_STEP
| C_MASKINTS
);
798 if (retval
!= ERROR_OK
)
801 /* Enter debug state on reset; restore DEMCR in endreset_event() */
802 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DEMCR
,
803 TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
804 if (retval
!= ERROR_OK
)
807 /* Request a core-only reset */
808 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, NVIC_AIRCR
,
809 AIRCR_VECTKEY
| AIRCR_VECTRESET
);
810 if (retval
!= ERROR_OK
)
812 target
->state
= TARGET_RESET
;
814 /* registers are now invalid */
815 register_cache_invalidate(cortex_m
->armv7m
.arm
.core_cache
);
817 while (timeout
< 100) {
818 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &dcb_dhcsr
);
819 if (retval
== ERROR_OK
) {
820 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, NVIC_DFSR
,
821 &cortex_m
->nvic_dfsr
);
822 if (retval
!= ERROR_OK
)
824 if ((dcb_dhcsr
& S_HALT
)
825 && (cortex_m
->nvic_dfsr
& DFSR_VCATCH
)) {
826 LOG_DEBUG("system reset-halted, DHCSR 0x%08x, "
828 (unsigned) dcb_dhcsr
,
829 (unsigned) cortex_m
->nvic_dfsr
);
830 cortex_m_poll(target
);
831 /* FIXME restore user's vector catch config */
834 LOG_DEBUG("waiting for system reset-halt, "
835 "DHCSR 0x%08x, %d ms",
836 (unsigned) dcb_dhcsr
, timeout
);
845 void cortex_m_enable_breakpoints(struct target
*target
)
847 struct breakpoint
*breakpoint
= target
->breakpoints
;
849 /* set any pending breakpoints */
851 if (!breakpoint
->set
)
852 cortex_m_set_breakpoint(target
, breakpoint
);
853 breakpoint
= breakpoint
->next
;
857 static int cortex_m_resume(struct target
*target
, int current
,
858 target_addr_t address
, int handle_breakpoints
, int debug_execution
)
860 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
861 struct breakpoint
*breakpoint
= NULL
;
865 if (target
->state
!= TARGET_HALTED
) {
866 LOG_WARNING("target not halted");
867 return ERROR_TARGET_NOT_HALTED
;
870 if (!debug_execution
) {
871 target_free_all_working_areas(target
);
872 cortex_m_enable_breakpoints(target
);
873 cortex_m_enable_watchpoints(target
);
876 if (debug_execution
) {
877 r
= armv7m
->arm
.core_cache
->reg_list
+ ARMV7M_PRIMASK
;
879 /* Disable interrupts */
880 /* We disable interrupts in the PRIMASK register instead of
881 * masking with C_MASKINTS. This is probably the same issue
882 * as Cortex-M3 Erratum 377493 (fixed in r1p0): C_MASKINTS
883 * in parallel with disabled interrupts can cause local faults
886 * This breaks non-debug (application) execution if not
887 * called from armv7m_start_algorithm() which saves registers.
889 buf_set_u32(r
->value
, 0, 1, 1);
893 /* Make sure we are in Thumb mode, set xPSR.T bit */
894 /* armv7m_start_algorithm() initializes entire xPSR register.
895 * This duplicity handles the case when cortex_m_resume()
896 * is used with the debug_execution flag directly,
897 * not called through armv7m_start_algorithm().
899 r
= armv7m
->arm
.cpsr
;
900 buf_set_u32(r
->value
, 24, 1, 1);
905 /* current = 1: continue on current pc, otherwise continue at <address> */
908 buf_set_u32(r
->value
, 0, 32, address
);
913 /* if we halted last time due to a bkpt instruction
914 * then we have to manually step over it, otherwise
915 * the core will break again */
917 if (!breakpoint_find(target
, buf_get_u32(r
->value
, 0, 32))
919 armv7m_maybe_skip_bkpt_inst(target
, NULL
);
921 resume_pc
= buf_get_u32(r
->value
, 0, 32);
923 armv7m_restore_context(target
);
925 /* the front-end may request us not to handle breakpoints */
926 if (handle_breakpoints
) {
927 /* Single step past breakpoint at current address */
928 breakpoint
= breakpoint_find(target
, resume_pc
);
930 LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT
" (ID: %" PRIu32
")",
932 breakpoint
->unique_id
);
933 cortex_m_unset_breakpoint(target
, breakpoint
);
934 cortex_m_single_step_core(target
);
935 cortex_m_set_breakpoint(target
, breakpoint
);
940 cortex_m_set_maskints_for_run(target
);
941 cortex_m_write_debug_halt_mask(target
, 0, C_HALT
);
943 target
->debug_reason
= DBG_REASON_NOTHALTED
;
945 /* registers are now invalid */
946 register_cache_invalidate(armv7m
->arm
.core_cache
);
948 if (!debug_execution
) {
949 target
->state
= TARGET_RUNNING
;
950 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
951 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
953 target
->state
= TARGET_DEBUG_RUNNING
;
954 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
955 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
961 /* int irqstepcount = 0; */
962 static int cortex_m_step(struct target
*target
, int current
,
963 target_addr_t address
, int handle_breakpoints
)
965 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
966 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
967 struct breakpoint
*breakpoint
= NULL
;
968 struct reg
*pc
= armv7m
->arm
.pc
;
969 bool bkpt_inst_found
= false;
971 bool isr_timed_out
= false;
973 if (target
->state
!= TARGET_HALTED
) {
974 LOG_WARNING("target not halted");
975 return ERROR_TARGET_NOT_HALTED
;
978 /* current = 1: continue on current pc, otherwise continue at <address> */
980 buf_set_u32(pc
->value
, 0, 32, address
);
985 uint32_t pc_value
= buf_get_u32(pc
->value
, 0, 32);
987 /* the front-end may request us not to handle breakpoints */
988 if (handle_breakpoints
) {
989 breakpoint
= breakpoint_find(target
, pc_value
);
991 cortex_m_unset_breakpoint(target
, breakpoint
);
994 armv7m_maybe_skip_bkpt_inst(target
, &bkpt_inst_found
);
996 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
998 armv7m_restore_context(target
);
1000 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1002 /* if no bkpt instruction is found at pc then we can perform
1003 * a normal step, otherwise we have to manually step over the bkpt
1004 * instruction - as such simulate a step */
1005 if (bkpt_inst_found
== false) {
1006 if (cortex_m
->isrmasking_mode
!= CORTEX_M_ISRMASK_AUTO
) {
1007 /* Automatic ISR masking mode off: Just step over the next
1008 * instruction, with interrupts on or off as appropriate. */
1009 cortex_m_set_maskints_for_step(target
);
1010 cortex_m_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
1012 /* Process interrupts during stepping in a way they don't interfere
1017 * Set a temporary break point at the current pc and let the core run
1018 * with interrupts enabled. Pending interrupts get served and we run
1019 * into the breakpoint again afterwards. Then we step over the next
1020 * instruction with interrupts disabled.
1022 * If the pending interrupts don't complete within time, we leave the
1023 * core running. This may happen if the interrupts trigger faster
1024 * than the core can process them or the handler doesn't return.
1026 * If no more breakpoints are available we simply do a step with
1027 * interrupts enabled.
1033 * If a break point is already set on the lower half word then a break point on
1034 * the upper half word will not break again when the core is restarted. So we
1035 * just step over the instruction with interrupts disabled.
1037 * The documentation has no information about this, it was found by observation
1038 * on STM32F1 and STM32F2. Proper explanation welcome. STM32F0 doesn't seem to
1039 * suffer from this problem.
1041 * To add some confusion: pc_value has bit 0 always set, while the breakpoint
1042 * address has it always cleared. The former is done to indicate thumb mode
1046 if ((pc_value
& 0x02) && breakpoint_find(target
, pc_value
& ~0x03)) {
1047 LOG_DEBUG("Stepping over next instruction with interrupts disabled");
1048 cortex_m_write_debug_halt_mask(target
, C_HALT
| C_MASKINTS
, 0);
1049 cortex_m_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
1050 /* Re-enable interrupts if appropriate */
1051 cortex_m_write_debug_halt_mask(target
, C_HALT
, 0);
1052 cortex_m_set_maskints_for_halt(target
);
1055 /* Set a temporary break point */
1057 retval
= cortex_m_set_breakpoint(target
, breakpoint
);
1059 enum breakpoint_type type
= BKPT_HARD
;
1060 if (cortex_m
->fp_rev
== 0 && pc_value
> 0x1FFFFFFF) {
1061 /* FPB rev.1 cannot handle such addr, try BKPT instr */
1064 retval
= breakpoint_add(target
, pc_value
, 2, type
);
1067 bool tmp_bp_set
= (retval
== ERROR_OK
);
1069 /* No more breakpoints left, just do a step */
1071 cortex_m_set_maskints_for_step(target
);
1072 cortex_m_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
1073 /* Re-enable interrupts if appropriate */
1074 cortex_m_write_debug_halt_mask(target
, C_HALT
, 0);
1075 cortex_m_set_maskints_for_halt(target
);
1077 /* Start the core */
1078 LOG_DEBUG("Starting core to serve pending interrupts");
1079 int64_t t_start
= timeval_ms();
1080 cortex_m_set_maskints_for_run(target
);
1081 cortex_m_write_debug_halt_mask(target
, 0, C_HALT
| C_STEP
);
1083 /* Wait for pending handlers to complete or timeout */
1085 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
,
1087 &cortex_m
->dcb_dhcsr
);
1088 if (retval
!= ERROR_OK
) {
1089 target
->state
= TARGET_UNKNOWN
;
1092 isr_timed_out
= ((timeval_ms() - t_start
) > 500);
1093 } while (!((cortex_m
->dcb_dhcsr
& S_HALT
) || isr_timed_out
));
1095 /* only remove breakpoint if we created it */
1097 cortex_m_unset_breakpoint(target
, breakpoint
);
1099 /* Remove the temporary breakpoint */
1100 breakpoint_remove(target
, pc_value
);
1103 if (isr_timed_out
) {
1104 LOG_DEBUG("Interrupt handlers didn't complete within time, "
1105 "leaving target running");
1107 /* Step over next instruction with interrupts disabled */
1108 cortex_m_set_maskints_for_step(target
);
1109 cortex_m_write_debug_halt_mask(target
,
1110 C_HALT
| C_MASKINTS
,
1112 cortex_m_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
1113 /* Re-enable interrupts if appropriate */
1114 cortex_m_write_debug_halt_mask(target
, C_HALT
, 0);
1115 cortex_m_set_maskints_for_halt(target
);
1122 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
1123 if (retval
!= ERROR_OK
)
1126 /* registers are now invalid */
1127 register_cache_invalidate(armv7m
->arm
.core_cache
);
1130 cortex_m_set_breakpoint(target
, breakpoint
);
1132 if (isr_timed_out
) {
1133 /* Leave the core running. The user has to stop execution manually. */
1134 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1135 target
->state
= TARGET_RUNNING
;
1139 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
1140 " nvic_icsr = 0x%" PRIx32
,
1141 cortex_m
->dcb_dhcsr
, cortex_m
->nvic_icsr
);
1143 retval
= cortex_m_debug_entry(target
);
1144 if (retval
!= ERROR_OK
)
1146 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1148 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
1149 " nvic_icsr = 0x%" PRIx32
,
1150 cortex_m
->dcb_dhcsr
, cortex_m
->nvic_icsr
);
1155 static int cortex_m_assert_reset(struct target
*target
)
1157 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1158 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
1159 enum cortex_m_soft_reset_config reset_config
= cortex_m
->soft_reset_config
;
1161 LOG_DEBUG("target->state: %s",
1162 target_state_name(target
));
1164 enum reset_types jtag_reset_config
= jtag_get_reset_config();
1166 if (target_has_event_action(target
, TARGET_EVENT_RESET_ASSERT
)) {
1167 /* allow scripts to override the reset event */
1169 target_handle_event(target
, TARGET_EVENT_RESET_ASSERT
);
1170 register_cache_invalidate(cortex_m
->armv7m
.arm
.core_cache
);
1171 target
->state
= TARGET_RESET
;
1176 /* some cores support connecting while srst is asserted
1177 * use that mode is it has been configured */
1179 bool srst_asserted
= false;
1181 if (!target_was_examined(target
)) {
1182 if (jtag_reset_config
& RESET_HAS_SRST
) {
1183 adapter_assert_reset();
1184 if (target
->reset_halt
)
1185 LOG_ERROR("Target not examined, will not halt after reset!");
1188 LOG_ERROR("Target not examined, reset NOT asserted!");
1193 if ((jtag_reset_config
& RESET_HAS_SRST
) &&
1194 (jtag_reset_config
& RESET_SRST_NO_GATING
)) {
1195 adapter_assert_reset();
1196 srst_asserted
= true;
1199 /* Enable debug requests */
1201 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
1202 /* Store important errors instead of failing and proceed to reset assert */
1204 if (retval
!= ERROR_OK
|| !(cortex_m
->dcb_dhcsr
& C_DEBUGEN
))
1205 retval
= cortex_m_write_debug_halt_mask(target
, 0, C_HALT
| C_STEP
| C_MASKINTS
);
1207 /* If the processor is sleeping in a WFI or WFE instruction, the
1208 * C_HALT bit must be asserted to regain control */
1209 if (retval
== ERROR_OK
&& (cortex_m
->dcb_dhcsr
& S_SLEEP
))
1210 retval
= cortex_m_write_debug_halt_mask(target
, C_HALT
, 0);
1212 mem_ap_write_u32(armv7m
->debug_ap
, DCB_DCRDR
, 0);
1213 /* Ignore less important errors */
1215 if (!target
->reset_halt
) {
1216 /* Set/Clear C_MASKINTS in a separate operation */
1217 cortex_m_set_maskints_for_run(target
);
1219 /* clear any debug flags before resuming */
1220 cortex_m_clear_halt(target
);
1222 /* clear C_HALT in dhcsr reg */
1223 cortex_m_write_debug_halt_mask(target
, 0, C_HALT
);
1225 /* Halt in debug on reset; endreset_event() restores DEMCR.
1227 * REVISIT catching BUSERR presumably helps to defend against
1228 * bad vector table entries. Should this include MMERR or
1232 retval2
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DEMCR
,
1233 TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
1234 if (retval
!= ERROR_OK
|| retval2
!= ERROR_OK
)
1235 LOG_INFO("AP write error, reset will not halt");
1238 if (jtag_reset_config
& RESET_HAS_SRST
) {
1239 /* default to asserting srst */
1241 adapter_assert_reset();
1243 /* srst is asserted, ignore AP access errors */
1246 /* Use a standard Cortex-M3 software reset mechanism.
1247 * We default to using VECTRESET as it is supported on all current cores
1248 * (except Cortex-M0, M0+ and M1 which support SYSRESETREQ only!)
1249 * This has the disadvantage of not resetting the peripherals, so a
1250 * reset-init event handler is needed to perform any peripheral resets.
1252 if (!cortex_m
->vectreset_supported
1253 && reset_config
== CORTEX_M_RESET_VECTRESET
) {
1254 reset_config
= CORTEX_M_RESET_SYSRESETREQ
;
1255 LOG_WARNING("VECTRESET is not supported on this Cortex-M core, using SYSRESETREQ instead.");
1256 LOG_WARNING("Set 'cortex_m reset_config sysresetreq'.");
1259 LOG_DEBUG("Using Cortex-M %s", (reset_config
== CORTEX_M_RESET_SYSRESETREQ
)
1260 ? "SYSRESETREQ" : "VECTRESET");
1262 if (reset_config
== CORTEX_M_RESET_VECTRESET
) {
1263 LOG_WARNING("Only resetting the Cortex-M core, use a reset-init event "
1264 "handler to reset any peripherals or configure hardware srst support.");
1268 retval3
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, NVIC_AIRCR
,
1269 AIRCR_VECTKEY
| ((reset_config
== CORTEX_M_RESET_SYSRESETREQ
)
1270 ? AIRCR_SYSRESETREQ
: AIRCR_VECTRESET
));
1271 if (retval3
!= ERROR_OK
)
1272 LOG_DEBUG("Ignoring AP write error right after reset");
1274 retval3
= dap_dp_init_or_reconnect(armv7m
->debug_ap
->dap
);
1275 if (retval3
!= ERROR_OK
) {
1276 LOG_ERROR("DP initialisation failed");
1277 /* The error return value must not be propagated in this case.
1278 * SYSRESETREQ or VECTRESET have been possibly triggered
1279 * so reset processing should continue */
1281 /* I do not know why this is necessary, but it
1282 * fixes strange effects (step/resume cause NMI
1283 * after reset) on LM3S6918 -- Michael Schwingen
1286 mem_ap_read_atomic_u32(armv7m
->debug_ap
, NVIC_AIRCR
, &tmp
);
1290 target
->state
= TARGET_RESET
;
1293 register_cache_invalidate(cortex_m
->armv7m
.arm
.core_cache
);
1295 /* now return stored error code if any */
1296 if (retval
!= ERROR_OK
)
1299 if (target
->reset_halt
) {
1300 retval
= target_halt(target
);
1301 if (retval
!= ERROR_OK
)
1308 static int cortex_m_deassert_reset(struct target
*target
)
1310 struct armv7m_common
*armv7m
= &target_to_cm(target
)->armv7m
;
1312 LOG_DEBUG("target->state: %s",
1313 target_state_name(target
));
1315 /* deassert reset lines */
1316 adapter_deassert_reset();
1318 enum reset_types jtag_reset_config
= jtag_get_reset_config();
1320 if ((jtag_reset_config
& RESET_HAS_SRST
) &&
1321 !(jtag_reset_config
& RESET_SRST_NO_GATING
) &&
1322 target_was_examined(target
)) {
1324 int retval
= dap_dp_init_or_reconnect(armv7m
->debug_ap
->dap
);
1325 if (retval
!= ERROR_OK
) {
1326 LOG_ERROR("DP initialisation failed");
1334 int cortex_m_set_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1337 unsigned int fp_num
= 0;
1338 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1339 struct cortex_m_fp_comparator
*comparator_list
= cortex_m
->fp_comparator_list
;
1341 if (breakpoint
->set
) {
1342 LOG_WARNING("breakpoint (BPID: %" PRIu32
") already set", breakpoint
->unique_id
);
1346 if (breakpoint
->type
== BKPT_HARD
) {
1347 uint32_t fpcr_value
;
1348 while (comparator_list
[fp_num
].used
&& (fp_num
< cortex_m
->fp_num_code
))
1350 if (fp_num
>= cortex_m
->fp_num_code
) {
1351 LOG_ERROR("Can not find free FPB Comparator!");
1352 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1354 breakpoint
->set
= fp_num
+ 1;
1355 fpcr_value
= breakpoint
->address
| 1;
1356 if (cortex_m
->fp_rev
== 0) {
1357 if (breakpoint
->address
> 0x1FFFFFFF) {
1358 LOG_ERROR("Cortex-M Flash Patch Breakpoint rev.1 cannot handle HW breakpoint above address 0x1FFFFFFE");
1362 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
1363 fpcr_value
= (fpcr_value
& 0x1FFFFFFC) | hilo
| 1;
1364 } else if (cortex_m
->fp_rev
> 1) {
1365 LOG_ERROR("Unhandled Cortex-M Flash Patch Breakpoint architecture revision");
1368 comparator_list
[fp_num
].used
= true;
1369 comparator_list
[fp_num
].fpcr_value
= fpcr_value
;
1370 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
,
1371 comparator_list
[fp_num
].fpcr_value
);
1372 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32
"",
1374 comparator_list
[fp_num
].fpcr_value
);
1375 if (!cortex_m
->fpb_enabled
) {
1376 LOG_DEBUG("FPB wasn't enabled, do it now");
1377 retval
= cortex_m_enable_fpb(target
);
1378 if (retval
!= ERROR_OK
) {
1379 LOG_ERROR("Failed to enable the FPB");
1383 cortex_m
->fpb_enabled
= true;
1385 } else if (breakpoint
->type
== BKPT_SOFT
) {
1388 /* NOTE: on ARMv6-M and ARMv7-M, BKPT(0xab) is used for
1389 * semihosting; don't use that. Otherwise the BKPT
1390 * parameter is arbitrary.
1392 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1393 retval
= target_read_memory(target
,
1394 breakpoint
->address
& 0xFFFFFFFE,
1395 breakpoint
->length
, 1,
1396 breakpoint
->orig_instr
);
1397 if (retval
!= ERROR_OK
)
1399 retval
= target_write_memory(target
,
1400 breakpoint
->address
& 0xFFFFFFFE,
1401 breakpoint
->length
, 1,
1403 if (retval
!= ERROR_OK
)
1405 breakpoint
->set
= true;
1408 LOG_DEBUG("BPID: %" PRIu32
", Type: %d, Address: " TARGET_ADDR_FMT
" Length: %d (set=%d)",
1409 breakpoint
->unique_id
,
1410 (int)(breakpoint
->type
),
1411 breakpoint
->address
,
1418 int cortex_m_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1421 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1422 struct cortex_m_fp_comparator
*comparator_list
= cortex_m
->fp_comparator_list
;
1424 if (breakpoint
->set
<= 0) {
1425 LOG_WARNING("breakpoint not set");
1429 LOG_DEBUG("BPID: %" PRIu32
", Type: %d, Address: " TARGET_ADDR_FMT
" Length: %d (set=%d)",
1430 breakpoint
->unique_id
,
1431 (int)(breakpoint
->type
),
1432 breakpoint
->address
,
1436 if (breakpoint
->type
== BKPT_HARD
) {
1437 unsigned int fp_num
= breakpoint
->set
- 1;
1438 if (fp_num
>= cortex_m
->fp_num_code
) {
1439 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
1442 comparator_list
[fp_num
].used
= false;
1443 comparator_list
[fp_num
].fpcr_value
= 0;
1444 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
,
1445 comparator_list
[fp_num
].fpcr_value
);
1447 /* restore original instruction (kept in target endianness) */
1448 retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE,
1449 breakpoint
->length
, 1,
1450 breakpoint
->orig_instr
);
1451 if (retval
!= ERROR_OK
)
1454 breakpoint
->set
= false;
1459 int cortex_m_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1461 if (breakpoint
->length
== 3) {
1462 LOG_DEBUG("Using a two byte breakpoint for 32bit Thumb-2 request");
1463 breakpoint
->length
= 2;
1466 if ((breakpoint
->length
!= 2)) {
1467 LOG_INFO("only breakpoints of two bytes length supported");
1468 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1471 return cortex_m_set_breakpoint(target
, breakpoint
);
1474 int cortex_m_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1476 if (!breakpoint
->set
)
1479 return cortex_m_unset_breakpoint(target
, breakpoint
);
1482 static int cortex_m_set_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1484 unsigned int dwt_num
= 0;
1485 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1487 /* REVISIT Don't fully trust these "not used" records ... users
1488 * may set up breakpoints by hand, e.g. dual-address data value
1489 * watchpoint using comparator #1; comparator #0 matching cycle
1490 * count; send data trace info through ITM and TPIU; etc
1492 struct cortex_m_dwt_comparator
*comparator
;
1494 for (comparator
= cortex_m
->dwt_comparator_list
;
1495 comparator
->used
&& dwt_num
< cortex_m
->dwt_num_comp
;
1496 comparator
++, dwt_num
++)
1498 if (dwt_num
>= cortex_m
->dwt_num_comp
) {
1499 LOG_ERROR("Can not find free DWT Comparator");
1502 comparator
->used
= true;
1503 watchpoint
->set
= dwt_num
+ 1;
1505 comparator
->comp
= watchpoint
->address
;
1506 target_write_u32(target
, comparator
->dwt_comparator_address
+ 0,
1509 if ((cortex_m
->dwt_devarch
& 0x1FFFFF) != DWT_DEVARCH_ARMV8M
) {
1510 uint32_t mask
= 0, temp
;
1512 /* watchpoint params were validated earlier */
1513 temp
= watchpoint
->length
;
1520 comparator
->mask
= mask
;
1521 target_write_u32(target
, comparator
->dwt_comparator_address
+ 4,
1524 switch (watchpoint
->rw
) {
1526 comparator
->function
= 5;
1529 comparator
->function
= 6;
1532 comparator
->function
= 7;
1536 uint32_t data_size
= watchpoint
->length
>> 1;
1537 comparator
->mask
= (watchpoint
->length
>> 1) | 1;
1539 switch (watchpoint
->rw
) {
1541 comparator
->function
= 4;
1544 comparator
->function
= 5;
1547 comparator
->function
= 6;
1550 comparator
->function
= comparator
->function
| (1 << 4) |
1554 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1555 comparator
->function
);
1557 LOG_DEBUG("Watchpoint (ID %d) DWT%d 0x%08x 0x%x 0x%05x",
1558 watchpoint
->unique_id
, dwt_num
,
1559 (unsigned) comparator
->comp
,
1560 (unsigned) comparator
->mask
,
1561 (unsigned) comparator
->function
);
1565 static int cortex_m_unset_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1567 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1568 struct cortex_m_dwt_comparator
*comparator
;
1570 if (watchpoint
->set
<= 0) {
1571 LOG_WARNING("watchpoint (wpid: %d) not set",
1572 watchpoint
->unique_id
);
1576 unsigned int dwt_num
= watchpoint
->set
- 1;
1578 LOG_DEBUG("Watchpoint (ID %d) DWT%d address: 0x%08x clear",
1579 watchpoint
->unique_id
, dwt_num
,
1580 (unsigned) watchpoint
->address
);
1582 if (dwt_num
>= cortex_m
->dwt_num_comp
) {
1583 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1587 comparator
= cortex_m
->dwt_comparator_list
+ dwt_num
;
1588 comparator
->used
= false;
1589 comparator
->function
= 0;
1590 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1591 comparator
->function
);
1593 watchpoint
->set
= false;
1598 int cortex_m_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1600 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1602 if (cortex_m
->dwt_comp_available
< 1) {
1603 LOG_DEBUG("no comparators?");
1604 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1607 /* hardware doesn't support data value masking */
1608 if (watchpoint
->mask
!= ~(uint32_t)0) {
1609 LOG_DEBUG("watchpoint value masks not supported");
1610 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1613 /* hardware allows address masks of up to 32K */
1616 for (mask
= 0; mask
< 16; mask
++) {
1617 if ((1u << mask
) == watchpoint
->length
)
1621 LOG_DEBUG("unsupported watchpoint length");
1622 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1624 if (watchpoint
->address
& ((1 << mask
) - 1)) {
1625 LOG_DEBUG("watchpoint address is unaligned");
1626 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1629 /* Caller doesn't seem to be able to describe watching for data
1630 * values of zero; that flags "no value".
1632 * REVISIT This DWT may well be able to watch for specific data
1633 * values. Requires comparator #1 to set DATAVMATCH and match
1634 * the data, and another comparator (DATAVADDR0) matching addr.
1636 if (watchpoint
->value
) {
1637 LOG_DEBUG("data value watchpoint not YET supported");
1638 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1641 cortex_m
->dwt_comp_available
--;
1642 LOG_DEBUG("dwt_comp_available: %d", cortex_m
->dwt_comp_available
);
1647 int cortex_m_remove_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1649 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1651 /* REVISIT why check? DWT can be updated with core running ... */
1652 if (target
->state
!= TARGET_HALTED
) {
1653 LOG_WARNING("target not halted");
1654 return ERROR_TARGET_NOT_HALTED
;
1657 if (watchpoint
->set
)
1658 cortex_m_unset_watchpoint(target
, watchpoint
);
1660 cortex_m
->dwt_comp_available
++;
1661 LOG_DEBUG("dwt_comp_available: %d", cortex_m
->dwt_comp_available
);
1666 int cortex_m_hit_watchpoint(struct target
*target
, struct watchpoint
**hit_watchpoint
)
1668 if (target
->debug_reason
!= DBG_REASON_WATCHPOINT
)
1671 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1673 for (struct watchpoint
*wp
= target
->watchpoints
; wp
; wp
= wp
->next
) {
1677 unsigned int dwt_num
= wp
->set
- 1;
1678 struct cortex_m_dwt_comparator
*comparator
= cortex_m
->dwt_comparator_list
+ dwt_num
;
1680 uint32_t dwt_function
;
1681 int retval
= target_read_u32(target
, comparator
->dwt_comparator_address
+ 8, &dwt_function
);
1682 if (retval
!= ERROR_OK
)
1685 /* check the MATCHED bit */
1686 if (dwt_function
& BIT(24)) {
1687 *hit_watchpoint
= wp
;
1695 void cortex_m_enable_watchpoints(struct target
*target
)
1697 struct watchpoint
*watchpoint
= target
->watchpoints
;
1699 /* set any pending watchpoints */
1700 while (watchpoint
) {
1701 if (!watchpoint
->set
)
1702 cortex_m_set_watchpoint(target
, watchpoint
);
1703 watchpoint
= watchpoint
->next
;
1707 static int cortex_m_read_memory(struct target
*target
, target_addr_t address
,
1708 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1710 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1712 if (armv7m
->arm
.arch
== ARM_ARCH_V6M
) {
1713 /* armv6m does not handle unaligned memory access */
1714 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1715 return ERROR_TARGET_UNALIGNED_ACCESS
;
1718 return mem_ap_read_buf(armv7m
->debug_ap
, buffer
, size
, count
, address
);
1721 static int cortex_m_write_memory(struct target
*target
, target_addr_t address
,
1722 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
1724 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1726 if (armv7m
->arm
.arch
== ARM_ARCH_V6M
) {
1727 /* armv6m does not handle unaligned memory access */
1728 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1729 return ERROR_TARGET_UNALIGNED_ACCESS
;
1732 return mem_ap_write_buf(armv7m
->debug_ap
, buffer
, size
, count
, address
);
1735 static int cortex_m_init_target(struct command_context
*cmd_ctx
,
1736 struct target
*target
)
1738 armv7m_build_reg_cache(target
);
1739 arm_semihosting_init(target
);
1743 void cortex_m_deinit_target(struct target
*target
)
1745 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1747 free(cortex_m
->fp_comparator_list
);
1749 cortex_m_dwt_free(target
);
1750 armv7m_free_reg_cache(target
);
1752 free(target
->private_config
);
1756 int cortex_m_profiling(struct target
*target
, uint32_t *samples
,
1757 uint32_t max_num_samples
, uint32_t *num_samples
, uint32_t seconds
)
1759 struct timeval timeout
, now
;
1760 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1764 retval
= target_read_u32(target
, DWT_PCSR
, ®_value
);
1765 if (retval
!= ERROR_OK
) {
1766 LOG_ERROR("Error while reading PCSR");
1769 if (reg_value
== 0) {
1770 LOG_INFO("PCSR sampling not supported on this processor.");
1771 return target_profiling_default(target
, samples
, max_num_samples
, num_samples
, seconds
);
1774 gettimeofday(&timeout
, NULL
);
1775 timeval_add_time(&timeout
, seconds
, 0);
1777 LOG_INFO("Starting Cortex-M profiling. Sampling DWT_PCSR as fast as we can...");
1779 /* Make sure the target is running */
1780 target_poll(target
);
1781 if (target
->state
== TARGET_HALTED
)
1782 retval
= target_resume(target
, 1, 0, 0, 0);
1784 if (retval
!= ERROR_OK
) {
1785 LOG_ERROR("Error while resuming target");
1789 uint32_t sample_count
= 0;
1792 if (armv7m
&& armv7m
->debug_ap
) {
1793 uint32_t read_count
= max_num_samples
- sample_count
;
1794 if (read_count
> 1024)
1797 retval
= mem_ap_read_buf_noincr(armv7m
->debug_ap
,
1798 (void *)&samples
[sample_count
],
1799 4, read_count
, DWT_PCSR
);
1800 sample_count
+= read_count
;
1802 target_read_u32(target
, DWT_PCSR
, &samples
[sample_count
++]);
1805 if (retval
!= ERROR_OK
) {
1806 LOG_ERROR("Error while reading PCSR");
1811 gettimeofday(&now
, NULL
);
1812 if (sample_count
>= max_num_samples
|| timeval_compare(&now
, &timeout
) > 0) {
1813 LOG_INFO("Profiling completed. %" PRIu32
" samples.", sample_count
);
1818 *num_samples
= sample_count
;
1823 /* REVISIT cache valid/dirty bits are unmaintained. We could set "valid"
1824 * on r/w if the core is not running, and clear on resume or reset ... or
1825 * at least, in a post_restore_context() method.
1828 struct dwt_reg_state
{
1829 struct target
*target
;
1831 uint8_t value
[4]; /* scratch/cache */
1834 static int cortex_m_dwt_get_reg(struct reg
*reg
)
1836 struct dwt_reg_state
*state
= reg
->arch_info
;
1839 int retval
= target_read_u32(state
->target
, state
->addr
, &tmp
);
1840 if (retval
!= ERROR_OK
)
1843 buf_set_u32(state
->value
, 0, 32, tmp
);
1847 static int cortex_m_dwt_set_reg(struct reg
*reg
, uint8_t *buf
)
1849 struct dwt_reg_state
*state
= reg
->arch_info
;
1851 return target_write_u32(state
->target
, state
->addr
,
1852 buf_get_u32(buf
, 0, reg
->size
));
1861 static const struct dwt_reg dwt_base_regs
[] = {
1862 { DWT_CTRL
, "dwt_ctrl", 32, },
1863 /* NOTE that Erratum 532314 (fixed r2p0) affects CYCCNT: it wrongly
1864 * increments while the core is asleep.
1866 { DWT_CYCCNT
, "dwt_cyccnt", 32, },
1867 /* plus some 8 bit counters, useful for profiling with TPIU */
1870 static const struct dwt_reg dwt_comp
[] = {
1871 #define DWT_COMPARATOR(i) \
1872 { DWT_COMP0 + 0x10 * (i), "dwt_" #i "_comp", 32, }, \
1873 { DWT_MASK0 + 0x10 * (i), "dwt_" #i "_mask", 4, }, \
1874 { DWT_FUNCTION0 + 0x10 * (i), "dwt_" #i "_function", 32, }
1891 #undef DWT_COMPARATOR
1894 static const struct reg_arch_type dwt_reg_type
= {
1895 .get
= cortex_m_dwt_get_reg
,
1896 .set
= cortex_m_dwt_set_reg
,
1899 static void cortex_m_dwt_addreg(struct target
*t
, struct reg
*r
, const struct dwt_reg
*d
)
1901 struct dwt_reg_state
*state
;
1903 state
= calloc(1, sizeof(*state
));
1906 state
->addr
= d
->addr
;
1911 r
->value
= state
->value
;
1912 r
->arch_info
= state
;
1913 r
->type
= &dwt_reg_type
;
1916 static void cortex_m_dwt_setup(struct cortex_m_common
*cm
, struct target
*target
)
1919 struct reg_cache
*cache
;
1920 struct cortex_m_dwt_comparator
*comparator
;
1923 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1924 LOG_DEBUG("DWT_CTRL: 0x%" PRIx32
, dwtcr
);
1926 LOG_DEBUG("no DWT");
1930 target_read_u32(target
, DWT_DEVARCH
, &cm
->dwt_devarch
);
1931 LOG_DEBUG("DWT_DEVARCH: 0x%" PRIx32
, cm
->dwt_devarch
);
1933 cm
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1934 cm
->dwt_comp_available
= cm
->dwt_num_comp
;
1935 cm
->dwt_comparator_list
= calloc(cm
->dwt_num_comp
,
1936 sizeof(struct cortex_m_dwt_comparator
));
1937 if (!cm
->dwt_comparator_list
) {
1939 cm
->dwt_num_comp
= 0;
1940 LOG_ERROR("out of mem");
1944 cache
= calloc(1, sizeof(*cache
));
1947 free(cm
->dwt_comparator_list
);
1950 cache
->name
= "Cortex-M DWT registers";
1951 cache
->num_regs
= 2 + cm
->dwt_num_comp
* 3;
1952 cache
->reg_list
= calloc(cache
->num_regs
, sizeof(*cache
->reg_list
));
1953 if (!cache
->reg_list
) {
1958 for (reg
= 0; reg
< 2; reg
++)
1959 cortex_m_dwt_addreg(target
, cache
->reg_list
+ reg
,
1960 dwt_base_regs
+ reg
);
1962 comparator
= cm
->dwt_comparator_list
;
1963 for (unsigned int i
= 0; i
< cm
->dwt_num_comp
; i
++, comparator
++) {
1966 comparator
->dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1967 for (j
= 0; j
< 3; j
++, reg
++)
1968 cortex_m_dwt_addreg(target
, cache
->reg_list
+ reg
,
1969 dwt_comp
+ 3 * i
+ j
);
1971 /* make sure we clear any watchpoints enabled on the target */
1972 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8, 0);
1975 *register_get_last_cache_p(&target
->reg_cache
) = cache
;
1976 cm
->dwt_cache
= cache
;
1978 LOG_DEBUG("DWT dwtcr 0x%" PRIx32
", comp %d, watch%s",
1979 dwtcr
, cm
->dwt_num_comp
,
1980 (dwtcr
& (0xf << 24)) ? " only" : "/trigger");
1982 /* REVISIT: if num_comp > 1, check whether comparator #1 can
1983 * implement single-address data value watchpoints ... so we
1984 * won't need to check it later, when asked to set one up.
1988 static void cortex_m_dwt_free(struct target
*target
)
1990 struct cortex_m_common
*cm
= target_to_cm(target
);
1991 struct reg_cache
*cache
= cm
->dwt_cache
;
1993 free(cm
->dwt_comparator_list
);
1994 cm
->dwt_comparator_list
= NULL
;
1995 cm
->dwt_num_comp
= 0;
1998 register_unlink_cache(&target
->reg_cache
, cache
);
2000 if (cache
->reg_list
) {
2001 for (size_t i
= 0; i
< cache
->num_regs
; i
++)
2002 free(cache
->reg_list
[i
].arch_info
);
2003 free(cache
->reg_list
);
2007 cm
->dwt_cache
= NULL
;
2010 #define MVFR0 0xe000ef40
2011 #define MVFR1 0xe000ef44
2013 #define MVFR0_DEFAULT_M4 0x10110021
2014 #define MVFR1_DEFAULT_M4 0x11000011
2016 #define MVFR0_DEFAULT_M7_SP 0x10110021
2017 #define MVFR0_DEFAULT_M7_DP 0x10110221
2018 #define MVFR1_DEFAULT_M7_SP 0x11000011
2019 #define MVFR1_DEFAULT_M7_DP 0x12000011
2021 static int cortex_m_find_mem_ap(struct adiv5_dap
*swjdp
,
2022 struct adiv5_ap
**debug_ap
)
2024 if (dap_find_ap(swjdp
, AP_TYPE_AHB3_AP
, debug_ap
) == ERROR_OK
)
2027 return dap_find_ap(swjdp
, AP_TYPE_AHB5_AP
, debug_ap
);
2030 int cortex_m_examine(struct target
*target
)
2033 uint32_t cpuid
, fpcr
, mvfr0
, mvfr1
;
2034 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
2035 struct adiv5_dap
*swjdp
= cortex_m
->armv7m
.arm
.dap
;
2036 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
2038 /* hla_target shares the examine handler but does not support
2040 if (!armv7m
->is_hla_target
) {
2041 if (cortex_m
->apsel
== DP_APSEL_INVALID
) {
2042 /* Search for the MEM-AP */
2043 retval
= cortex_m_find_mem_ap(swjdp
, &armv7m
->debug_ap
);
2044 if (retval
!= ERROR_OK
) {
2045 LOG_ERROR("Could not find MEM-AP to control the core");
2049 armv7m
->debug_ap
= dap_ap(swjdp
, cortex_m
->apsel
);
2052 /* Leave (only) generic DAP stuff for debugport_init(); */
2053 armv7m
->debug_ap
->memaccess_tck
= 8;
2055 retval
= mem_ap_init(armv7m
->debug_ap
);
2056 if (retval
!= ERROR_OK
)
2060 if (!target_was_examined(target
)) {
2061 target_set_examined(target
);
2063 /* Read from Device Identification Registers */
2064 retval
= target_read_u32(target
, CPUID
, &cpuid
);
2065 if (retval
!= ERROR_OK
)
2068 /* Get ARCH and CPU types */
2069 const enum cortex_m_partno core_partno
= (cpuid
& ARM_CPUID_PARTNO_MASK
) >> ARM_CPUID_PARTNO_POS
;
2071 for (unsigned int n
= 0; n
< ARRAY_SIZE(cortex_m_parts
); n
++) {
2072 if (core_partno
== cortex_m_parts
[n
].partno
) {
2073 cortex_m
->core_info
= &cortex_m_parts
[n
];
2078 if (!cortex_m
->core_info
) {
2079 LOG_ERROR("Cortex-M PARTNO 0x%x is unrecognized", core_partno
);
2083 armv7m
->arm
.arch
= cortex_m
->core_info
->arch
;
2085 LOG_INFO("%s: %s r%" PRId8
"p%" PRId8
" processor detected",
2086 target_name(target
),
2087 cortex_m
->core_info
->name
,
2088 (uint8_t)((cpuid
>> 20) & 0xf),
2089 (uint8_t)((cpuid
>> 0) & 0xf));
2091 cortex_m
->maskints_erratum
= false;
2092 if (core_partno
== CORTEX_M7_PARTNO
) {
2094 rev
= (cpuid
>> 20) & 0xf;
2095 patch
= (cpuid
>> 0) & 0xf;
2096 if ((rev
== 0) && (patch
< 2)) {
2097 LOG_WARNING("Silicon bug: single stepping may enter pending exception handler!");
2098 cortex_m
->maskints_erratum
= true;
2101 LOG_DEBUG("cpuid: 0x%8.8" PRIx32
"", cpuid
);
2103 if (cortex_m
->core_info
->flags
& CORTEX_M_F_HAS_FPV4
) {
2104 target_read_u32(target
, MVFR0
, &mvfr0
);
2105 target_read_u32(target
, MVFR1
, &mvfr1
);
2107 /* test for floating point feature on Cortex-M4 */
2108 if ((mvfr0
== MVFR0_DEFAULT_M4
) && (mvfr1
== MVFR1_DEFAULT_M4
)) {
2109 LOG_DEBUG("%s floating point feature FPv4_SP found", cortex_m
->core_info
->name
);
2110 armv7m
->fp_feature
= FPV4_SP
;
2112 } else if (cortex_m
->core_info
->flags
& CORTEX_M_F_HAS_FPV5
) {
2113 target_read_u32(target
, MVFR0
, &mvfr0
);
2114 target_read_u32(target
, MVFR1
, &mvfr1
);
2116 /* test for floating point features on Cortex-M7 */
2117 if ((mvfr0
== MVFR0_DEFAULT_M7_SP
) && (mvfr1
== MVFR1_DEFAULT_M7_SP
)) {
2118 LOG_DEBUG("%s floating point feature FPv5_SP found", cortex_m
->core_info
->name
);
2119 armv7m
->fp_feature
= FPV5_SP
;
2120 } else if ((mvfr0
== MVFR0_DEFAULT_M7_DP
) && (mvfr1
== MVFR1_DEFAULT_M7_DP
)) {
2121 LOG_DEBUG("%s floating point feature FPv5_DP found", cortex_m
->core_info
->name
);
2122 armv7m
->fp_feature
= FPV5_DP
;
2126 /* VECTRESET is supported only on ARMv7-M cores */
2127 cortex_m
->vectreset_supported
= armv7m
->arm
.arch
== ARM_ARCH_V7M
;
2129 /* Check for FPU, otherwise mark FPU register as non-existent */
2130 if (armv7m
->fp_feature
== FP_NONE
)
2131 for (size_t idx
= ARMV7M_FPU_FIRST_REG
; idx
<= ARMV7M_FPU_LAST_REG
; idx
++)
2132 armv7m
->arm
.core_cache
->reg_list
[idx
].exist
= false;
2134 if (armv7m
->arm
.arch
!= ARM_ARCH_V8M
)
2135 for (size_t idx
= ARMV8M_FIRST_REG
; idx
<= ARMV8M_LAST_REG
; idx
++)
2136 armv7m
->arm
.core_cache
->reg_list
[idx
].exist
= false;
2138 if (!armv7m
->is_hla_target
) {
2139 if (cortex_m
->core_info
->flags
& CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K
)
2140 /* Cortex-M3/M4 have 4096 bytes autoincrement range,
2141 * s. ARM IHI 0031C: MEM-AP 7.2.2 */
2142 armv7m
->debug_ap
->tar_autoincr_block
= (1 << 12);
2145 /* Enable debug requests */
2146 retval
= target_read_u32(target
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
2147 if (retval
!= ERROR_OK
)
2149 if (!(cortex_m
->dcb_dhcsr
& C_DEBUGEN
)) {
2150 uint32_t dhcsr
= (cortex_m
->dcb_dhcsr
| C_DEBUGEN
) & ~(C_HALT
| C_STEP
| C_MASKINTS
);
2152 retval
= target_write_u32(target
, DCB_DHCSR
, DBGKEY
| (dhcsr
& 0x0000FFFFUL
));
2153 if (retval
!= ERROR_OK
)
2155 cortex_m
->dcb_dhcsr
= dhcsr
;
2158 /* Configure trace modules */
2159 retval
= target_write_u32(target
, DCB_DEMCR
, TRCENA
| armv7m
->demcr
);
2160 if (retval
!= ERROR_OK
)
2163 if (armv7m
->trace_config
.itm_deferred_config
)
2164 armv7m_trace_itm_config(target
);
2166 /* NOTE: FPB and DWT are both optional. */
2169 target_read_u32(target
, FP_CTRL
, &fpcr
);
2170 /* bits [14:12] and [7:4] */
2171 cortex_m
->fp_num_code
= ((fpcr
>> 8) & 0x70) | ((fpcr
>> 4) & 0xF);
2172 cortex_m
->fp_num_lit
= (fpcr
>> 8) & 0xF;
2173 /* Detect flash patch revision, see RM DDI 0403E.b page C1-817.
2174 Revision is zero base, fp_rev == 1 means Rev.2 ! */
2175 cortex_m
->fp_rev
= (fpcr
>> 28) & 0xf;
2176 free(cortex_m
->fp_comparator_list
);
2177 cortex_m
->fp_comparator_list
= calloc(
2178 cortex_m
->fp_num_code
+ cortex_m
->fp_num_lit
,
2179 sizeof(struct cortex_m_fp_comparator
));
2180 cortex_m
->fpb_enabled
= fpcr
& 1;
2181 for (unsigned int i
= 0; i
< cortex_m
->fp_num_code
+ cortex_m
->fp_num_lit
; i
++) {
2182 cortex_m
->fp_comparator_list
[i
].type
=
2183 (i
< cortex_m
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
2184 cortex_m
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
2186 /* make sure we clear any breakpoints enabled on the target */
2187 target_write_u32(target
, cortex_m
->fp_comparator_list
[i
].fpcr_address
, 0);
2189 LOG_DEBUG("FPB fpcr 0x%" PRIx32
", numcode %i, numlit %i",
2191 cortex_m
->fp_num_code
,
2192 cortex_m
->fp_num_lit
);
2195 cortex_m_dwt_free(target
);
2196 cortex_m_dwt_setup(cortex_m
, target
);
2198 /* These hardware breakpoints only work for code in flash! */
2199 LOG_INFO("%s: target has %d breakpoints, %d watchpoints",
2200 target_name(target
),
2201 cortex_m
->fp_num_code
,
2202 cortex_m
->dwt_num_comp
);
2208 static int cortex_m_dcc_read(struct target
*target
, uint8_t *value
, uint8_t *ctrl
)
2210 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
2215 retval
= mem_ap_read_buf_noincr(armv7m
->debug_ap
, buf
, 2, 1, DCB_DCRDR
);
2216 if (retval
!= ERROR_OK
)
2219 dcrdr
= target_buffer_get_u16(target
, buf
);
2220 *ctrl
= (uint8_t)dcrdr
;
2221 *value
= (uint8_t)(dcrdr
>> 8);
2223 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
2225 /* write ack back to software dcc register
2226 * signify we have read data */
2227 if (dcrdr
& (1 << 0)) {
2228 target_buffer_set_u16(target
, buf
, 0);
2229 retval
= mem_ap_write_buf_noincr(armv7m
->debug_ap
, buf
, 2, 1, DCB_DCRDR
);
2230 if (retval
!= ERROR_OK
)
2237 static int cortex_m_target_request_data(struct target
*target
,
2238 uint32_t size
, uint8_t *buffer
)
2244 for (i
= 0; i
< (size
* 4); i
++) {
2245 int retval
= cortex_m_dcc_read(target
, &data
, &ctrl
);
2246 if (retval
!= ERROR_OK
)
2254 static int cortex_m_handle_target_request(void *priv
)
2256 struct target
*target
= priv
;
2257 if (!target_was_examined(target
))
2260 if (!target
->dbg_msg_enabled
)
2263 if (target
->state
== TARGET_RUNNING
) {
2268 retval
= cortex_m_dcc_read(target
, &data
, &ctrl
);
2269 if (retval
!= ERROR_OK
)
2272 /* check if we have data */
2273 if (ctrl
& (1 << 0)) {
2276 /* we assume target is quick enough */
2278 for (int i
= 1; i
<= 3; i
++) {
2279 retval
= cortex_m_dcc_read(target
, &data
, &ctrl
);
2280 if (retval
!= ERROR_OK
)
2282 request
|= ((uint32_t)data
<< (i
* 8));
2284 target_request(target
, request
);
2291 static int cortex_m_init_arch_info(struct target
*target
,
2292 struct cortex_m_common
*cortex_m
, struct adiv5_dap
*dap
)
2294 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
2296 armv7m_init_arch_info(target
, armv7m
);
2298 /* default reset mode is to use srst if fitted
2299 * if not it will use CORTEX_M3_RESET_VECTRESET */
2300 cortex_m
->soft_reset_config
= CORTEX_M_RESET_VECTRESET
;
2302 armv7m
->arm
.dap
= dap
;
2304 /* register arch-specific functions */
2305 armv7m
->examine_debug_reason
= cortex_m_examine_debug_reason
;
2307 armv7m
->post_debug_entry
= NULL
;
2309 armv7m
->pre_restore_context
= NULL
;
2311 armv7m
->load_core_reg_u32
= cortex_m_load_core_reg_u32
;
2312 armv7m
->store_core_reg_u32
= cortex_m_store_core_reg_u32
;
2314 target_register_timer_callback(cortex_m_handle_target_request
, 1,
2315 TARGET_TIMER_TYPE_PERIODIC
, target
);
2320 static int cortex_m_target_create(struct target
*target
, Jim_Interp
*interp
)
2322 struct adiv5_private_config
*pc
;
2324 pc
= (struct adiv5_private_config
*)target
->private_config
;
2325 if (adiv5_verify_config(pc
) != ERROR_OK
)
2328 struct cortex_m_common
*cortex_m
= calloc(1, sizeof(struct cortex_m_common
));
2330 LOG_ERROR("No memory creating target");
2334 cortex_m
->common_magic
= CORTEX_M_COMMON_MAGIC
;
2335 cortex_m
->apsel
= pc
->ap_num
;
2337 cortex_m_init_arch_info(target
, cortex_m
, pc
->dap
);
2342 /*--------------------------------------------------------------------------*/
2344 static int cortex_m_verify_pointer(struct command_invocation
*cmd
,
2345 struct cortex_m_common
*cm
)
2347 if (cm
->common_magic
!= CORTEX_M_COMMON_MAGIC
) {
2348 command_print(cmd
, "target is not a Cortex-M");
2349 return ERROR_TARGET_INVALID
;
2355 * Only stuff below this line should need to verify that its target
2356 * is a Cortex-M3. Everything else should have indirected through the
2357 * cortexm3_target structure, which is only used with CM3 targets.
2360 COMMAND_HANDLER(handle_cortex_m_vector_catch_command
)
2362 struct target
*target
= get_current_target(CMD_CTX
);
2363 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
2364 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
2368 static const struct {
2372 { "hard_err", VC_HARDERR
, },
2373 { "int_err", VC_INTERR
, },
2374 { "bus_err", VC_BUSERR
, },
2375 { "state_err", VC_STATERR
, },
2376 { "chk_err", VC_CHKERR
, },
2377 { "nocp_err", VC_NOCPERR
, },
2378 { "mm_err", VC_MMERR
, },
2379 { "reset", VC_CORERESET
, },
2382 retval
= cortex_m_verify_pointer(CMD
, cortex_m
);
2383 if (retval
!= ERROR_OK
)
2386 if (!target_was_examined(target
)) {
2387 LOG_ERROR("Target not examined yet");
2391 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DEMCR
, &demcr
);
2392 if (retval
!= ERROR_OK
)
2398 if (CMD_ARGC
== 1) {
2399 if (strcmp(CMD_ARGV
[0], "all") == 0) {
2400 catch = VC_HARDERR
| VC_INTERR
| VC_BUSERR
2401 | VC_STATERR
| VC_CHKERR
| VC_NOCPERR
2402 | VC_MMERR
| VC_CORERESET
;
2404 } else if (strcmp(CMD_ARGV
[0], "none") == 0)
2407 while (CMD_ARGC
-- > 0) {
2409 for (i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++) {
2410 if (strcmp(CMD_ARGV
[CMD_ARGC
], vec_ids
[i
].name
) != 0)
2412 catch |= vec_ids
[i
].mask
;
2415 if (i
== ARRAY_SIZE(vec_ids
)) {
2416 LOG_ERROR("No CM3 vector '%s'", CMD_ARGV
[CMD_ARGC
]);
2417 return ERROR_COMMAND_SYNTAX_ERROR
;
2421 /* For now, armv7m->demcr only stores vector catch flags. */
2422 armv7m
->demcr
= catch;
2427 /* write, but don't assume it stuck (why not??) */
2428 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DEMCR
, demcr
);
2429 if (retval
!= ERROR_OK
)
2431 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DEMCR
, &demcr
);
2432 if (retval
!= ERROR_OK
)
2435 /* FIXME be sure to clear DEMCR on clean server shutdown.
2436 * Otherwise the vector catch hardware could fire when there's
2437 * no debugger hooked up, causing much confusion...
2441 for (unsigned i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++) {
2442 command_print(CMD
, "%9s: %s", vec_ids
[i
].name
,
2443 (demcr
& vec_ids
[i
].mask
) ? "catch" : "ignore");
2449 COMMAND_HANDLER(handle_cortex_m_mask_interrupts_command
)
2451 struct target
*target
= get_current_target(CMD_CTX
);
2452 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
2455 static const struct jim_nvp nvp_maskisr_modes
[] = {
2456 { .name
= "auto", .value
= CORTEX_M_ISRMASK_AUTO
},
2457 { .name
= "off", .value
= CORTEX_M_ISRMASK_OFF
},
2458 { .name
= "on", .value
= CORTEX_M_ISRMASK_ON
},
2459 { .name
= "steponly", .value
= CORTEX_M_ISRMASK_STEPONLY
},
2460 { .name
= NULL
, .value
= -1 },
2462 const struct jim_nvp
*n
;
2465 retval
= cortex_m_verify_pointer(CMD
, cortex_m
);
2466 if (retval
!= ERROR_OK
)
2469 if (target
->state
!= TARGET_HALTED
) {
2470 command_print(CMD
, "target must be stopped for \"%s\" command", CMD_NAME
);
2475 n
= jim_nvp_name2value_simple(nvp_maskisr_modes
, CMD_ARGV
[0]);
2477 return ERROR_COMMAND_SYNTAX_ERROR
;
2478 cortex_m
->isrmasking_mode
= n
->value
;
2479 cortex_m_set_maskints_for_halt(target
);
2482 n
= jim_nvp_value2name_simple(nvp_maskisr_modes
, cortex_m
->isrmasking_mode
);
2483 command_print(CMD
, "cortex_m interrupt mask %s", n
->name
);
2488 COMMAND_HANDLER(handle_cortex_m_reset_config_command
)
2490 struct target
*target
= get_current_target(CMD_CTX
);
2491 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
2495 retval
= cortex_m_verify_pointer(CMD
, cortex_m
);
2496 if (retval
!= ERROR_OK
)
2500 if (strcmp(*CMD_ARGV
, "sysresetreq") == 0)
2501 cortex_m
->soft_reset_config
= CORTEX_M_RESET_SYSRESETREQ
;
2503 else if (strcmp(*CMD_ARGV
, "vectreset") == 0) {
2504 if (target_was_examined(target
)
2505 && !cortex_m
->vectreset_supported
)
2506 LOG_WARNING("VECTRESET is not supported on your Cortex-M core!");
2508 cortex_m
->soft_reset_config
= CORTEX_M_RESET_VECTRESET
;
2511 return ERROR_COMMAND_SYNTAX_ERROR
;
2514 switch (cortex_m
->soft_reset_config
) {
2515 case CORTEX_M_RESET_SYSRESETREQ
:
2516 reset_config
= "sysresetreq";
2519 case CORTEX_M_RESET_VECTRESET
:
2520 reset_config
= "vectreset";
2524 reset_config
= "unknown";
2528 command_print(CMD
, "cortex_m reset_config %s", reset_config
);
2533 static const struct command_registration cortex_m_exec_command_handlers
[] = {
2536 .handler
= handle_cortex_m_mask_interrupts_command
,
2537 .mode
= COMMAND_EXEC
,
2538 .help
= "mask cortex_m interrupts",
2539 .usage
= "['auto'|'on'|'off'|'steponly']",
2542 .name
= "vector_catch",
2543 .handler
= handle_cortex_m_vector_catch_command
,
2544 .mode
= COMMAND_EXEC
,
2545 .help
= "configure hardware vectors to trigger debug entry",
2546 .usage
= "['all'|'none'|('bus_err'|'chk_err'|...)*]",
2549 .name
= "reset_config",
2550 .handler
= handle_cortex_m_reset_config_command
,
2551 .mode
= COMMAND_ANY
,
2552 .help
= "configure software reset handling",
2553 .usage
= "['sysresetreq'|'vectreset']",
2555 COMMAND_REGISTRATION_DONE
2557 static const struct command_registration cortex_m_command_handlers
[] = {
2559 .chain
= armv7m_command_handlers
,
2562 .chain
= armv7m_trace_command_handlers
,
2564 /* START_DEPRECATED_TPIU */
2566 .chain
= arm_tpiu_deprecated_command_handlers
,
2568 /* END_DEPRECATED_TPIU */
2571 .mode
= COMMAND_EXEC
,
2572 .help
= "Cortex-M command group",
2574 .chain
= cortex_m_exec_command_handlers
,
2577 .chain
= rtt_target_command_handlers
,
2579 COMMAND_REGISTRATION_DONE
2582 struct target_type cortexm_target
= {
2585 .poll
= cortex_m_poll
,
2586 .arch_state
= armv7m_arch_state
,
2588 .target_request_data
= cortex_m_target_request_data
,
2590 .halt
= cortex_m_halt
,
2591 .resume
= cortex_m_resume
,
2592 .step
= cortex_m_step
,
2594 .assert_reset
= cortex_m_assert_reset
,
2595 .deassert_reset
= cortex_m_deassert_reset
,
2596 .soft_reset_halt
= cortex_m_soft_reset_halt
,
2598 .get_gdb_arch
= arm_get_gdb_arch
,
2599 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
2601 .read_memory
= cortex_m_read_memory
,
2602 .write_memory
= cortex_m_write_memory
,
2603 .checksum_memory
= armv7m_checksum_memory
,
2604 .blank_check_memory
= armv7m_blank_check_memory
,
2606 .run_algorithm
= armv7m_run_algorithm
,
2607 .start_algorithm
= armv7m_start_algorithm
,
2608 .wait_algorithm
= armv7m_wait_algorithm
,
2610 .add_breakpoint
= cortex_m_add_breakpoint
,
2611 .remove_breakpoint
= cortex_m_remove_breakpoint
,
2612 .add_watchpoint
= cortex_m_add_watchpoint
,
2613 .remove_watchpoint
= cortex_m_remove_watchpoint
,
2614 .hit_watchpoint
= cortex_m_hit_watchpoint
,
2616 .commands
= cortex_m_command_handlers
,
2617 .target_create
= cortex_m_target_create
,
2618 .target_jim_configure
= adiv5_jim_configure
,
2619 .init_target
= cortex_m_init_target
,
2620 .examine
= cortex_m_examine
,
2621 .deinit_target
= cortex_m_deinit_target
,
2623 .profiling
= cortex_m_profiling
,
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)