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_disassembler.h"
39 #include "arm_opcodes.h"
40 #include "arm_semihosting.h"
41 #include <helper/time_support.h>
44 /* NOTE: most of this should work fine for the Cortex-M1 and
45 * Cortex-M0 cores too, although they're ARMv6-M not ARMv7-M.
46 * Some differences: M0/M1 doesn't have FPB remapping or the
47 * DWT tracing/profiling support. (So the cycle counter will
48 * not be usable; the other stuff isn't currently used here.)
50 * Although there are some workarounds for errata seen only in r0p0
51 * silicon, such old parts are hard to find and thus not much tested
55 /* Supported Cortex-M Cores */
56 static const struct cortex_m_part_info cortex_m_parts
[] = {
58 .partno
= CORTEX_M0_PARTNO
,
63 .partno
= CORTEX_M0P_PARTNO
,
68 .partno
= CORTEX_M1_PARTNO
,
73 .partno
= CORTEX_M3_PARTNO
,
76 .flags
= CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K
,
79 .partno
= CORTEX_M4_PARTNO
,
82 .flags
= CORTEX_M_F_HAS_FPV4
| CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K
,
85 .partno
= CORTEX_M7_PARTNO
,
88 .flags
= CORTEX_M_F_HAS_FPV5
,
91 .partno
= CORTEX_M23_PARTNO
,
96 .partno
= CORTEX_M33_PARTNO
,
99 .flags
= CORTEX_M_F_HAS_FPV5
,
102 .partno
= CORTEX_M35P_PARTNO
,
103 .name
= "Cortex-M35P",
104 .arch
= ARM_ARCH_V8M
,
105 .flags
= CORTEX_M_F_HAS_FPV5
,
108 .partno
= CORTEX_M55_PARTNO
,
109 .name
= "Cortex-M55",
110 .arch
= ARM_ARCH_V8M
,
111 .flags
= CORTEX_M_F_HAS_FPV5
,
115 /* forward declarations */
116 static int cortex_m_store_core_reg_u32(struct target
*target
,
117 uint32_t num
, uint32_t value
);
118 static void cortex_m_dwt_free(struct target
*target
);
120 static int cortex_m_load_core_reg_u32(struct target
*target
,
121 uint32_t regsel
, uint32_t *value
)
123 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
127 /* because the DCB_DCRDR is used for the emulated dcc channel
128 * we have to save/restore the DCB_DCRDR when used */
129 if (target
->dbg_msg_enabled
) {
130 retval
= mem_ap_read_u32(armv7m
->debug_ap
, DCB_DCRDR
, &dcrdr
);
131 if (retval
!= ERROR_OK
)
135 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DCRSR
, regsel
);
136 if (retval
!= ERROR_OK
)
139 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DCRDR
, value
);
140 if (retval
!= ERROR_OK
)
143 if (target
->dbg_msg_enabled
) {
144 /* restore DCB_DCRDR - this needs to be in a separate
145 * transaction otherwise the emulated DCC channel breaks */
146 if (retval
== ERROR_OK
)
147 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DCRDR
, dcrdr
);
153 static int cortex_m_store_core_reg_u32(struct target
*target
,
154 uint32_t regsel
, uint32_t value
)
156 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
160 /* because the DCB_DCRDR is used for the emulated dcc channel
161 * we have to save/restore the DCB_DCRDR when used */
162 if (target
->dbg_msg_enabled
) {
163 retval
= mem_ap_read_u32(armv7m
->debug_ap
, DCB_DCRDR
, &dcrdr
);
164 if (retval
!= ERROR_OK
)
168 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DCRDR
, value
);
169 if (retval
!= ERROR_OK
)
172 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DCRSR
, regsel
| DCRSR_WNR
);
173 if (retval
!= ERROR_OK
)
176 if (target
->dbg_msg_enabled
) {
177 /* restore DCB_DCRDR - this needs to be in a separate
178 * transaction otherwise the emulated DCC channel breaks */
179 if (retval
== ERROR_OK
)
180 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DCRDR
, dcrdr
);
186 static int cortex_m_write_debug_halt_mask(struct target
*target
,
187 uint32_t mask_on
, uint32_t mask_off
)
189 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
190 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
192 /* mask off status bits */
193 cortex_m
->dcb_dhcsr
&= ~((0xFFFFul
<< 16) | mask_off
);
194 /* create new register mask */
195 cortex_m
->dcb_dhcsr
|= DBGKEY
| C_DEBUGEN
| mask_on
;
197 return mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, cortex_m
->dcb_dhcsr
);
200 static int cortex_m_set_maskints(struct target
*target
, bool mask
)
202 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
203 if (!!(cortex_m
->dcb_dhcsr
& C_MASKINTS
) != mask
)
204 return cortex_m_write_debug_halt_mask(target
, mask
? C_MASKINTS
: 0, mask
? 0 : C_MASKINTS
);
209 static int cortex_m_set_maskints_for_halt(struct target
*target
)
211 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
212 switch (cortex_m
->isrmasking_mode
) {
213 case CORTEX_M_ISRMASK_AUTO
:
214 /* interrupts taken at resume, whether for step or run -> no mask */
215 return cortex_m_set_maskints(target
, false);
217 case CORTEX_M_ISRMASK_OFF
:
218 /* interrupts never masked */
219 return cortex_m_set_maskints(target
, false);
221 case CORTEX_M_ISRMASK_ON
:
222 /* interrupts always masked */
223 return cortex_m_set_maskints(target
, true);
225 case CORTEX_M_ISRMASK_STEPONLY
:
226 /* interrupts masked for single step only -> mask now if MASKINTS
227 * erratum, otherwise only mask before stepping */
228 return cortex_m_set_maskints(target
, cortex_m
->maskints_erratum
);
233 static int cortex_m_set_maskints_for_run(struct target
*target
)
235 switch (target_to_cm(target
)->isrmasking_mode
) {
236 case CORTEX_M_ISRMASK_AUTO
:
237 /* interrupts taken at resume, whether for step or run -> no mask */
238 return cortex_m_set_maskints(target
, false);
240 case CORTEX_M_ISRMASK_OFF
:
241 /* interrupts never masked */
242 return cortex_m_set_maskints(target
, false);
244 case CORTEX_M_ISRMASK_ON
:
245 /* interrupts always masked */
246 return cortex_m_set_maskints(target
, true);
248 case CORTEX_M_ISRMASK_STEPONLY
:
249 /* interrupts masked for single step only -> no mask */
250 return cortex_m_set_maskints(target
, false);
255 static int cortex_m_set_maskints_for_step(struct target
*target
)
257 switch (target_to_cm(target
)->isrmasking_mode
) {
258 case CORTEX_M_ISRMASK_AUTO
:
259 /* the auto-interrupt should already be done -> mask */
260 return cortex_m_set_maskints(target
, true);
262 case CORTEX_M_ISRMASK_OFF
:
263 /* interrupts never masked */
264 return cortex_m_set_maskints(target
, false);
266 case CORTEX_M_ISRMASK_ON
:
267 /* interrupts always masked */
268 return cortex_m_set_maskints(target
, true);
270 case CORTEX_M_ISRMASK_STEPONLY
:
271 /* interrupts masked for single step only -> mask */
272 return cortex_m_set_maskints(target
, true);
277 static int cortex_m_clear_halt(struct target
*target
)
279 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
280 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
283 /* clear step if any */
284 cortex_m_write_debug_halt_mask(target
, C_HALT
, C_STEP
);
286 /* Read Debug Fault Status Register */
287 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, NVIC_DFSR
, &cortex_m
->nvic_dfsr
);
288 if (retval
!= ERROR_OK
)
291 /* Clear Debug Fault Status */
292 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, NVIC_DFSR
, cortex_m
->nvic_dfsr
);
293 if (retval
!= ERROR_OK
)
295 LOG_DEBUG(" NVIC_DFSR 0x%" PRIx32
"", cortex_m
->nvic_dfsr
);
300 static int cortex_m_single_step_core(struct target
*target
)
302 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
303 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
306 /* Mask interrupts before clearing halt, if not done already. This avoids
307 * Erratum 377497 (fixed in r1p0) where setting MASKINTS while clearing
308 * HALT can put the core into an unknown state.
310 if (!(cortex_m
->dcb_dhcsr
& C_MASKINTS
)) {
311 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
,
312 DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
313 if (retval
!= ERROR_OK
)
316 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
,
317 DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
318 if (retval
!= ERROR_OK
)
322 /* restore dhcsr reg */
323 cortex_m_clear_halt(target
);
328 static int cortex_m_enable_fpb(struct target
*target
)
330 int retval
= target_write_u32(target
, FP_CTRL
, 3);
331 if (retval
!= ERROR_OK
)
334 /* check the fpb is actually enabled */
336 retval
= target_read_u32(target
, FP_CTRL
, &fpctrl
);
337 if (retval
!= ERROR_OK
)
346 static int cortex_m_endreset_event(struct target
*target
)
350 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
351 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
352 struct adiv5_dap
*swjdp
= cortex_m
->armv7m
.arm
.dap
;
353 struct cortex_m_fp_comparator
*fp_list
= cortex_m
->fp_comparator_list
;
354 struct cortex_m_dwt_comparator
*dwt_list
= cortex_m
->dwt_comparator_list
;
356 /* REVISIT The four debug monitor bits are currently ignored... */
357 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DEMCR
, &dcb_demcr
);
358 if (retval
!= ERROR_OK
)
360 LOG_DEBUG("DCB_DEMCR = 0x%8.8" PRIx32
"", dcb_demcr
);
362 /* this register is used for emulated dcc channel */
363 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DCRDR
, 0);
364 if (retval
!= ERROR_OK
)
367 /* Enable debug requests */
368 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
369 if (retval
!= ERROR_OK
)
371 if (!(cortex_m
->dcb_dhcsr
& C_DEBUGEN
)) {
372 retval
= cortex_m_write_debug_halt_mask(target
, 0, C_HALT
| C_STEP
| C_MASKINTS
);
373 if (retval
!= ERROR_OK
)
377 /* Restore proper interrupt masking setting for running CPU. */
378 cortex_m_set_maskints_for_run(target
);
380 /* Enable features controlled by ITM and DWT blocks, and catch only
381 * the vectors we were told to pay attention to.
383 * Target firmware is responsible for all fault handling policy
384 * choices *EXCEPT* explicitly scripted overrides like "vector_catch"
385 * or manual updates to the NVIC SHCSR and CCR registers.
387 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DEMCR
, TRCENA
| armv7m
->demcr
);
388 if (retval
!= ERROR_OK
)
391 /* Paranoia: evidently some (early?) chips don't preserve all the
392 * debug state (including FPB, DWT, etc) across reset...
396 retval
= cortex_m_enable_fpb(target
);
397 if (retval
!= ERROR_OK
) {
398 LOG_ERROR("Failed to enable the FPB");
402 cortex_m
->fpb_enabled
= true;
404 /* Restore FPB registers */
405 for (unsigned int i
= 0; i
< cortex_m
->fp_num_code
+ cortex_m
->fp_num_lit
; i
++) {
406 retval
= target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
407 if (retval
!= ERROR_OK
)
411 /* Restore DWT registers */
412 for (unsigned int i
= 0; i
< cortex_m
->dwt_num_comp
; i
++) {
413 retval
= target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 0,
415 if (retval
!= ERROR_OK
)
417 retval
= target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 4,
419 if (retval
!= ERROR_OK
)
421 retval
= target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 8,
422 dwt_list
[i
].function
);
423 if (retval
!= ERROR_OK
)
426 retval
= dap_run(swjdp
);
427 if (retval
!= ERROR_OK
)
430 register_cache_invalidate(armv7m
->arm
.core_cache
);
432 /* make sure we have latest dhcsr flags */
433 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
438 static int cortex_m_examine_debug_reason(struct target
*target
)
440 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
442 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason
443 * only check the debug reason if we don't know it already */
445 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
446 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
)) {
447 if (cortex_m
->nvic_dfsr
& DFSR_BKPT
) {
448 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
449 if (cortex_m
->nvic_dfsr
& DFSR_DWTTRAP
)
450 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
451 } else if (cortex_m
->nvic_dfsr
& DFSR_DWTTRAP
)
452 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
453 else if (cortex_m
->nvic_dfsr
& DFSR_VCATCH
)
454 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
455 else if (cortex_m
->nvic_dfsr
& DFSR_EXTERNAL
)
456 target
->debug_reason
= DBG_REASON_DBGRQ
;
458 target
->debug_reason
= DBG_REASON_UNDEFINED
;
464 static int cortex_m_examine_exception_reason(struct target
*target
)
466 uint32_t shcsr
= 0, except_sr
= 0, cfsr
= -1, except_ar
= -1;
467 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
468 struct adiv5_dap
*swjdp
= armv7m
->arm
.dap
;
471 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_SHCSR
, &shcsr
);
472 if (retval
!= ERROR_OK
)
474 switch (armv7m
->exception_number
) {
477 case 3: /* Hard Fault */
478 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, NVIC_HFSR
, &except_sr
);
479 if (retval
!= ERROR_OK
)
481 if (except_sr
& 0x40000000) {
482 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_CFSR
, &cfsr
);
483 if (retval
!= ERROR_OK
)
487 case 4: /* Memory Management */
488 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_CFSR
, &except_sr
);
489 if (retval
!= ERROR_OK
)
491 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_MMFAR
, &except_ar
);
492 if (retval
!= ERROR_OK
)
495 case 5: /* Bus Fault */
496 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_CFSR
, &except_sr
);
497 if (retval
!= ERROR_OK
)
499 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_BFAR
, &except_ar
);
500 if (retval
!= ERROR_OK
)
503 case 6: /* Usage Fault */
504 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_CFSR
, &except_sr
);
505 if (retval
!= ERROR_OK
)
508 case 7: /* Secure Fault */
509 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_SFSR
, &except_sr
);
510 if (retval
!= ERROR_OK
)
512 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_SFAR
, &except_ar
);
513 if (retval
!= ERROR_OK
)
516 case 11: /* SVCall */
518 case 12: /* Debug Monitor */
519 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_DFSR
, &except_sr
);
520 if (retval
!= ERROR_OK
)
523 case 14: /* PendSV */
525 case 15: /* SysTick */
531 retval
= dap_run(swjdp
);
532 if (retval
== ERROR_OK
)
533 LOG_DEBUG("%s SHCSR 0x%" PRIx32
", SR 0x%" PRIx32
534 ", CFSR 0x%" PRIx32
", AR 0x%" PRIx32
,
535 armv7m_exception_string(armv7m
->exception_number
),
536 shcsr
, except_sr
, cfsr
, except_ar
);
540 static int cortex_m_debug_entry(struct target
*target
)
545 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
546 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
547 struct arm
*arm
= &armv7m
->arm
;
552 /* Do this really early to minimize the window where the MASKINTS erratum
553 * can pile up pending interrupts. */
554 cortex_m_set_maskints_for_halt(target
);
556 cortex_m_clear_halt(target
);
557 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
558 if (retval
!= ERROR_OK
)
561 retval
= armv7m
->examine_debug_reason(target
);
562 if (retval
!= ERROR_OK
)
565 /* examine PE security state */
566 bool secure_state
= false;
567 if (armv7m
->arm
.arch
== ARM_ARCH_V8M
) {
570 retval
= mem_ap_read_u32(armv7m
->debug_ap
, DCB_DSCSR
, &dscsr
);
571 if (retval
!= ERROR_OK
)
574 secure_state
= (dscsr
& DSCSR_CDS
) == DSCSR_CDS
;
577 /* Examine target state and mode
578 * First load register accessible through core debug port */
579 int num_regs
= arm
->core_cache
->num_regs
;
581 for (i
= 0; i
< num_regs
; i
++) {
582 r
= &armv7m
->arm
.core_cache
->reg_list
[i
];
583 if (r
->exist
&& !r
->valid
)
584 arm
->read_core_reg(target
, r
, i
, ARM_MODE_ANY
);
588 xPSR
= buf_get_u32(r
->value
, 0, 32);
590 /* Are we in an exception handler */
592 armv7m
->exception_number
= (xPSR
& 0x1FF);
594 arm
->core_mode
= ARM_MODE_HANDLER
;
595 arm
->map
= armv7m_msp_reg_map
;
597 unsigned control
= buf_get_u32(arm
->core_cache
598 ->reg_list
[ARMV7M_CONTROL
].value
, 0, 3);
600 /* is this thread privileged? */
601 arm
->core_mode
= control
& 1
602 ? ARM_MODE_USER_THREAD
605 /* which stack is it using? */
607 arm
->map
= armv7m_psp_reg_map
;
609 arm
->map
= armv7m_msp_reg_map
;
611 armv7m
->exception_number
= 0;
614 if (armv7m
->exception_number
)
615 cortex_m_examine_exception_reason(target
);
617 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32
", cpu in %s state, target->state: %s",
618 arm_mode_name(arm
->core_mode
),
619 buf_get_u32(arm
->pc
->value
, 0, 32),
620 secure_state
? "Secure" : "Non-Secure",
621 target_state_name(target
));
623 if (armv7m
->post_debug_entry
) {
624 retval
= armv7m
->post_debug_entry(target
);
625 if (retval
!= ERROR_OK
)
632 static int cortex_m_poll(struct target
*target
)
634 int detected_failure
= ERROR_OK
;
635 int retval
= ERROR_OK
;
636 enum target_state prev_target_state
= target
->state
;
637 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
638 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
640 /* Read from Debug Halting Control and Status Register */
641 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
642 if (retval
!= ERROR_OK
) {
643 target
->state
= TARGET_UNKNOWN
;
647 /* Recover from lockup. See ARMv7-M architecture spec,
648 * section B1.5.15 "Unrecoverable exception cases".
650 if (cortex_m
->dcb_dhcsr
& S_LOCKUP
) {
651 LOG_ERROR("%s -- clearing lockup after double fault",
652 target_name(target
));
653 cortex_m_write_debug_halt_mask(target
, C_HALT
, 0);
654 target
->debug_reason
= DBG_REASON_DBGRQ
;
656 /* We have to execute the rest (the "finally" equivalent, but
657 * still throw this exception again).
659 detected_failure
= ERROR_FAIL
;
661 /* refresh status bits */
662 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
663 if (retval
!= ERROR_OK
)
667 if (cortex_m
->dcb_dhcsr
& S_RESET_ST
) {
668 if (target
->state
!= TARGET_RESET
) {
669 target
->state
= TARGET_RESET
;
670 LOG_INFO("%s: external reset detected", target_name(target
));
675 if (target
->state
== TARGET_RESET
) {
676 /* Cannot switch context while running so endreset is
677 * called with target->state == TARGET_RESET
679 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%" PRIx32
,
680 cortex_m
->dcb_dhcsr
);
681 retval
= cortex_m_endreset_event(target
);
682 if (retval
!= ERROR_OK
) {
683 target
->state
= TARGET_UNKNOWN
;
686 target
->state
= TARGET_RUNNING
;
687 prev_target_state
= TARGET_RUNNING
;
690 if (cortex_m
->dcb_dhcsr
& S_HALT
) {
691 target
->state
= TARGET_HALTED
;
693 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
)) {
694 retval
= cortex_m_debug_entry(target
);
695 if (retval
!= ERROR_OK
)
698 if (arm_semihosting(target
, &retval
) != 0)
701 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
703 if (prev_target_state
== TARGET_DEBUG_RUNNING
) {
705 retval
= cortex_m_debug_entry(target
);
706 if (retval
!= ERROR_OK
)
709 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
713 if (target
->state
== TARGET_UNKNOWN
) {
714 /* check if processor is retiring instructions or sleeping */
715 if (cortex_m
->dcb_dhcsr
& S_RETIRE_ST
|| cortex_m
->dcb_dhcsr
& S_SLEEP
) {
716 target
->state
= TARGET_RUNNING
;
721 /* Check that target is truly halted, since the target could be resumed externally */
722 if ((prev_target_state
== TARGET_HALTED
) && !(cortex_m
->dcb_dhcsr
& S_HALT
)) {
723 /* registers are now invalid */
724 register_cache_invalidate(armv7m
->arm
.core_cache
);
726 target
->state
= TARGET_RUNNING
;
727 LOG_WARNING("%s: external resume detected", target_name(target
));
728 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
732 /* Did we detect a failure condition that we cleared? */
733 if (detected_failure
!= ERROR_OK
)
734 retval
= detected_failure
;
738 static int cortex_m_halt(struct target
*target
)
740 LOG_DEBUG("target->state: %s",
741 target_state_name(target
));
743 if (target
->state
== TARGET_HALTED
) {
744 LOG_DEBUG("target was already halted");
748 if (target
->state
== TARGET_UNKNOWN
)
749 LOG_WARNING("target was in unknown state when halt was requested");
751 if (target
->state
== TARGET_RESET
) {
752 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst()) {
753 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
754 return ERROR_TARGET_FAILURE
;
756 /* we came here in a reset_halt or reset_init sequence
757 * debug entry was already prepared in cortex_m3_assert_reset()
759 target
->debug_reason
= DBG_REASON_DBGRQ
;
765 /* Write to Debug Halting Control and Status Register */
766 cortex_m_write_debug_halt_mask(target
, C_HALT
, 0);
768 /* Do this really early to minimize the window where the MASKINTS erratum
769 * can pile up pending interrupts. */
770 cortex_m_set_maskints_for_halt(target
);
772 target
->debug_reason
= DBG_REASON_DBGRQ
;
777 static int cortex_m_soft_reset_halt(struct target
*target
)
779 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
780 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
781 uint32_t dcb_dhcsr
= 0;
782 int retval
, timeout
= 0;
784 /* on single cortex_m MCU soft_reset_halt should be avoided as same functionality
785 * can be obtained by using 'reset halt' and 'cortex_m reset_config vectreset'.
786 * As this reset only uses VC_CORERESET it would only ever reset the cortex_m
787 * core, not the peripherals */
788 LOG_DEBUG("soft_reset_halt is discouraged, please use 'reset halt' instead.");
790 if (!cortex_m
->vectreset_supported
) {
791 LOG_ERROR("VECTRESET is not supported on this Cortex-M core");
796 retval
= cortex_m_write_debug_halt_mask(target
, 0, C_STEP
| C_MASKINTS
);
797 if (retval
!= ERROR_OK
)
800 /* Enter debug state on reset; restore DEMCR in endreset_event() */
801 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DEMCR
,
802 TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
803 if (retval
!= ERROR_OK
)
806 /* Request a core-only reset */
807 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, NVIC_AIRCR
,
808 AIRCR_VECTKEY
| AIRCR_VECTRESET
);
809 if (retval
!= ERROR_OK
)
811 target
->state
= TARGET_RESET
;
813 /* registers are now invalid */
814 register_cache_invalidate(cortex_m
->armv7m
.arm
.core_cache
);
816 while (timeout
< 100) {
817 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &dcb_dhcsr
);
818 if (retval
== ERROR_OK
) {
819 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, NVIC_DFSR
,
820 &cortex_m
->nvic_dfsr
);
821 if (retval
!= ERROR_OK
)
823 if ((dcb_dhcsr
& S_HALT
)
824 && (cortex_m
->nvic_dfsr
& DFSR_VCATCH
)) {
825 LOG_DEBUG("system reset-halted, DHCSR 0x%08x, "
827 (unsigned) dcb_dhcsr
,
828 (unsigned) cortex_m
->nvic_dfsr
);
829 cortex_m_poll(target
);
830 /* FIXME restore user's vector catch config */
833 LOG_DEBUG("waiting for system reset-halt, "
834 "DHCSR 0x%08x, %d ms",
835 (unsigned) dcb_dhcsr
, timeout
);
844 void cortex_m_enable_breakpoints(struct target
*target
)
846 struct breakpoint
*breakpoint
= target
->breakpoints
;
848 /* set any pending breakpoints */
850 if (!breakpoint
->set
)
851 cortex_m_set_breakpoint(target
, breakpoint
);
852 breakpoint
= breakpoint
->next
;
856 static int cortex_m_resume(struct target
*target
, int current
,
857 target_addr_t address
, int handle_breakpoints
, int debug_execution
)
859 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
860 struct breakpoint
*breakpoint
= NULL
;
864 if (target
->state
!= TARGET_HALTED
) {
865 LOG_WARNING("target not halted");
866 return ERROR_TARGET_NOT_HALTED
;
869 if (!debug_execution
) {
870 target_free_all_working_areas(target
);
871 cortex_m_enable_breakpoints(target
);
872 cortex_m_enable_watchpoints(target
);
875 if (debug_execution
) {
876 r
= armv7m
->arm
.core_cache
->reg_list
+ ARMV7M_PRIMASK
;
878 /* Disable interrupts */
879 /* We disable interrupts in the PRIMASK register instead of
880 * masking with C_MASKINTS. This is probably the same issue
881 * as Cortex-M3 Erratum 377493 (fixed in r1p0): C_MASKINTS
882 * in parallel with disabled interrupts can cause local faults
885 * This breaks non-debug (application) execution if not
886 * called from armv7m_start_algorithm() which saves registers.
888 buf_set_u32(r
->value
, 0, 1, 1);
892 /* Make sure we are in Thumb mode, set xPSR.T bit */
893 /* armv7m_start_algorithm() initializes entire xPSR register.
894 * This duplicity handles the case when cortex_m_resume()
895 * is used with the debug_execution flag directly,
896 * not called through armv7m_start_algorithm().
898 r
= armv7m
->arm
.cpsr
;
899 buf_set_u32(r
->value
, 24, 1, 1);
904 /* current = 1: continue on current pc, otherwise continue at <address> */
907 buf_set_u32(r
->value
, 0, 32, address
);
912 /* if we halted last time due to a bkpt instruction
913 * then we have to manually step over it, otherwise
914 * the core will break again */
916 if (!breakpoint_find(target
, buf_get_u32(r
->value
, 0, 32))
918 armv7m_maybe_skip_bkpt_inst(target
, NULL
);
920 resume_pc
= buf_get_u32(r
->value
, 0, 32);
922 armv7m_restore_context(target
);
924 /* the front-end may request us not to handle breakpoints */
925 if (handle_breakpoints
) {
926 /* Single step past breakpoint at current address */
927 breakpoint
= breakpoint_find(target
, resume_pc
);
929 LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT
" (ID: %" PRIu32
")",
931 breakpoint
->unique_id
);
932 cortex_m_unset_breakpoint(target
, breakpoint
);
933 cortex_m_single_step_core(target
);
934 cortex_m_set_breakpoint(target
, breakpoint
);
939 cortex_m_set_maskints_for_run(target
);
940 cortex_m_write_debug_halt_mask(target
, 0, C_HALT
);
942 target
->debug_reason
= DBG_REASON_NOTHALTED
;
944 /* registers are now invalid */
945 register_cache_invalidate(armv7m
->arm
.core_cache
);
947 if (!debug_execution
) {
948 target
->state
= TARGET_RUNNING
;
949 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
950 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
952 target
->state
= TARGET_DEBUG_RUNNING
;
953 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
954 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
960 /* int irqstepcount = 0; */
961 static int cortex_m_step(struct target
*target
, int current
,
962 target_addr_t address
, int handle_breakpoints
)
964 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
965 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
966 struct breakpoint
*breakpoint
= NULL
;
967 struct reg
*pc
= armv7m
->arm
.pc
;
968 bool bkpt_inst_found
= false;
970 bool isr_timed_out
= false;
972 if (target
->state
!= TARGET_HALTED
) {
973 LOG_WARNING("target not halted");
974 return ERROR_TARGET_NOT_HALTED
;
977 /* current = 1: continue on current pc, otherwise continue at <address> */
979 buf_set_u32(pc
->value
, 0, 32, address
);
981 uint32_t pc_value
= buf_get_u32(pc
->value
, 0, 32);
983 /* the front-end may request us not to handle breakpoints */
984 if (handle_breakpoints
) {
985 breakpoint
= breakpoint_find(target
, pc_value
);
987 cortex_m_unset_breakpoint(target
, breakpoint
);
990 armv7m_maybe_skip_bkpt_inst(target
, &bkpt_inst_found
);
992 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
994 armv7m_restore_context(target
);
996 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
998 /* if no bkpt instruction is found at pc then we can perform
999 * a normal step, otherwise we have to manually step over the bkpt
1000 * instruction - as such simulate a step */
1001 if (bkpt_inst_found
== false) {
1002 if (cortex_m
->isrmasking_mode
!= CORTEX_M_ISRMASK_AUTO
) {
1003 /* Automatic ISR masking mode off: Just step over the next
1004 * instruction, with interrupts on or off as appropriate. */
1005 cortex_m_set_maskints_for_step(target
);
1006 cortex_m_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
1008 /* Process interrupts during stepping in a way they don't interfere
1013 * Set a temporary break point at the current pc and let the core run
1014 * with interrupts enabled. Pending interrupts get served and we run
1015 * into the breakpoint again afterwards. Then we step over the next
1016 * instruction with interrupts disabled.
1018 * If the pending interrupts don't complete within time, we leave the
1019 * core running. This may happen if the interrupts trigger faster
1020 * than the core can process them or the handler doesn't return.
1022 * If no more breakpoints are available we simply do a step with
1023 * interrupts enabled.
1029 * If a break point is already set on the lower half word then a break point on
1030 * the upper half word will not break again when the core is restarted. So we
1031 * just step over the instruction with interrupts disabled.
1033 * The documentation has no information about this, it was found by observation
1034 * on STM32F1 and STM32F2. Proper explanation welcome. STM32F0 doesn't seem to
1035 * suffer from this problem.
1037 * To add some confusion: pc_value has bit 0 always set, while the breakpoint
1038 * address has it always cleared. The former is done to indicate thumb mode
1042 if ((pc_value
& 0x02) && breakpoint_find(target
, pc_value
& ~0x03)) {
1043 LOG_DEBUG("Stepping over next instruction with interrupts disabled");
1044 cortex_m_write_debug_halt_mask(target
, C_HALT
| C_MASKINTS
, 0);
1045 cortex_m_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
1046 /* Re-enable interrupts if appropriate */
1047 cortex_m_write_debug_halt_mask(target
, C_HALT
, 0);
1048 cortex_m_set_maskints_for_halt(target
);
1051 /* Set a temporary break point */
1053 retval
= cortex_m_set_breakpoint(target
, breakpoint
);
1055 enum breakpoint_type type
= BKPT_HARD
;
1056 if (cortex_m
->fp_rev
== 0 && pc_value
> 0x1FFFFFFF) {
1057 /* FPB rev.1 cannot handle such addr, try BKPT instr */
1060 retval
= breakpoint_add(target
, pc_value
, 2, type
);
1063 bool tmp_bp_set
= (retval
== ERROR_OK
);
1065 /* No more breakpoints left, just do a step */
1067 cortex_m_set_maskints_for_step(target
);
1068 cortex_m_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
1069 /* Re-enable interrupts if appropriate */
1070 cortex_m_write_debug_halt_mask(target
, C_HALT
, 0);
1071 cortex_m_set_maskints_for_halt(target
);
1073 /* Start the core */
1074 LOG_DEBUG("Starting core to serve pending interrupts");
1075 int64_t t_start
= timeval_ms();
1076 cortex_m_set_maskints_for_run(target
);
1077 cortex_m_write_debug_halt_mask(target
, 0, C_HALT
| C_STEP
);
1079 /* Wait for pending handlers to complete or timeout */
1081 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
,
1083 &cortex_m
->dcb_dhcsr
);
1084 if (retval
!= ERROR_OK
) {
1085 target
->state
= TARGET_UNKNOWN
;
1088 isr_timed_out
= ((timeval_ms() - t_start
) > 500);
1089 } while (!((cortex_m
->dcb_dhcsr
& S_HALT
) || isr_timed_out
));
1091 /* only remove breakpoint if we created it */
1093 cortex_m_unset_breakpoint(target
, breakpoint
);
1095 /* Remove the temporary breakpoint */
1096 breakpoint_remove(target
, pc_value
);
1099 if (isr_timed_out
) {
1100 LOG_DEBUG("Interrupt handlers didn't complete within time, "
1101 "leaving target running");
1103 /* Step over next instruction with interrupts disabled */
1104 cortex_m_set_maskints_for_step(target
);
1105 cortex_m_write_debug_halt_mask(target
,
1106 C_HALT
| C_MASKINTS
,
1108 cortex_m_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
1109 /* Re-enable interrupts if appropriate */
1110 cortex_m_write_debug_halt_mask(target
, C_HALT
, 0);
1111 cortex_m_set_maskints_for_halt(target
);
1118 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
1119 if (retval
!= ERROR_OK
)
1122 /* registers are now invalid */
1123 register_cache_invalidate(armv7m
->arm
.core_cache
);
1126 cortex_m_set_breakpoint(target
, breakpoint
);
1128 if (isr_timed_out
) {
1129 /* Leave the core running. The user has to stop execution manually. */
1130 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1131 target
->state
= TARGET_RUNNING
;
1135 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
1136 " nvic_icsr = 0x%" PRIx32
,
1137 cortex_m
->dcb_dhcsr
, cortex_m
->nvic_icsr
);
1139 retval
= cortex_m_debug_entry(target
);
1140 if (retval
!= ERROR_OK
)
1142 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1144 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
1145 " nvic_icsr = 0x%" PRIx32
,
1146 cortex_m
->dcb_dhcsr
, cortex_m
->nvic_icsr
);
1151 static int cortex_m_assert_reset(struct target
*target
)
1153 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1154 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
1155 enum cortex_m_soft_reset_config reset_config
= cortex_m
->soft_reset_config
;
1157 LOG_DEBUG("target->state: %s",
1158 target_state_name(target
));
1160 enum reset_types jtag_reset_config
= jtag_get_reset_config();
1162 if (target_has_event_action(target
, TARGET_EVENT_RESET_ASSERT
)) {
1163 /* allow scripts to override the reset event */
1165 target_handle_event(target
, TARGET_EVENT_RESET_ASSERT
);
1166 register_cache_invalidate(cortex_m
->armv7m
.arm
.core_cache
);
1167 target
->state
= TARGET_RESET
;
1172 /* some cores support connecting while srst is asserted
1173 * use that mode is it has been configured */
1175 bool srst_asserted
= false;
1177 if (!target_was_examined(target
)) {
1178 if (jtag_reset_config
& RESET_HAS_SRST
) {
1179 adapter_assert_reset();
1180 if (target
->reset_halt
)
1181 LOG_ERROR("Target not examined, will not halt after reset!");
1184 LOG_ERROR("Target not examined, reset NOT asserted!");
1189 if ((jtag_reset_config
& RESET_HAS_SRST
) &&
1190 (jtag_reset_config
& RESET_SRST_NO_GATING
)) {
1191 adapter_assert_reset();
1192 srst_asserted
= true;
1195 /* Enable debug requests */
1197 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
1198 /* Store important errors instead of failing and proceed to reset assert */
1200 if (retval
!= ERROR_OK
|| !(cortex_m
->dcb_dhcsr
& C_DEBUGEN
))
1201 retval
= cortex_m_write_debug_halt_mask(target
, 0, C_HALT
| C_STEP
| C_MASKINTS
);
1203 /* If the processor is sleeping in a WFI or WFE instruction, the
1204 * C_HALT bit must be asserted to regain control */
1205 if (retval
== ERROR_OK
&& (cortex_m
->dcb_dhcsr
& S_SLEEP
))
1206 retval
= cortex_m_write_debug_halt_mask(target
, C_HALT
, 0);
1208 mem_ap_write_u32(armv7m
->debug_ap
, DCB_DCRDR
, 0);
1209 /* Ignore less important errors */
1211 if (!target
->reset_halt
) {
1212 /* Set/Clear C_MASKINTS in a separate operation */
1213 cortex_m_set_maskints_for_run(target
);
1215 /* clear any debug flags before resuming */
1216 cortex_m_clear_halt(target
);
1218 /* clear C_HALT in dhcsr reg */
1219 cortex_m_write_debug_halt_mask(target
, 0, C_HALT
);
1221 /* Halt in debug on reset; endreset_event() restores DEMCR.
1223 * REVISIT catching BUSERR presumably helps to defend against
1224 * bad vector table entries. Should this include MMERR or
1228 retval2
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DEMCR
,
1229 TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
1230 if (retval
!= ERROR_OK
|| retval2
!= ERROR_OK
)
1231 LOG_INFO("AP write error, reset will not halt");
1234 if (jtag_reset_config
& RESET_HAS_SRST
) {
1235 /* default to asserting srst */
1237 adapter_assert_reset();
1239 /* srst is asserted, ignore AP access errors */
1242 /* Use a standard Cortex-M3 software reset mechanism.
1243 * We default to using VECRESET as it is supported on all current cores
1244 * (except Cortex-M0, M0+ and M1 which support SYSRESETREQ only!)
1245 * This has the disadvantage of not resetting the peripherals, so a
1246 * reset-init event handler is needed to perform any peripheral resets.
1248 if (!cortex_m
->vectreset_supported
1249 && reset_config
== CORTEX_M_RESET_VECTRESET
) {
1250 reset_config
= CORTEX_M_RESET_SYSRESETREQ
;
1251 LOG_WARNING("VECTRESET is not supported on this Cortex-M core, using SYSRESETREQ instead.");
1252 LOG_WARNING("Set 'cortex_m reset_config sysresetreq'.");
1255 LOG_DEBUG("Using Cortex-M %s", (reset_config
== CORTEX_M_RESET_SYSRESETREQ
)
1256 ? "SYSRESETREQ" : "VECTRESET");
1258 if (reset_config
== CORTEX_M_RESET_VECTRESET
) {
1259 LOG_WARNING("Only resetting the Cortex-M core, use a reset-init event "
1260 "handler to reset any peripherals or configure hardware srst support.");
1264 retval3
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, NVIC_AIRCR
,
1265 AIRCR_VECTKEY
| ((reset_config
== CORTEX_M_RESET_SYSRESETREQ
)
1266 ? AIRCR_SYSRESETREQ
: AIRCR_VECTRESET
));
1267 if (retval3
!= ERROR_OK
)
1268 LOG_DEBUG("Ignoring AP write error right after reset");
1270 retval3
= dap_dp_init_or_reconnect(armv7m
->debug_ap
->dap
);
1271 if (retval3
!= ERROR_OK
) {
1272 LOG_ERROR("DP initialisation failed");
1273 /* The error return value must not be propagated in this case.
1274 * SYSRESETREQ or VECTRESET have been possibly triggered
1275 * so reset processing should continue */
1277 /* I do not know why this is necessary, but it
1278 * fixes strange effects (step/resume cause NMI
1279 * after reset) on LM3S6918 -- Michael Schwingen
1282 mem_ap_read_atomic_u32(armv7m
->debug_ap
, NVIC_AIRCR
, &tmp
);
1286 target
->state
= TARGET_RESET
;
1289 register_cache_invalidate(cortex_m
->armv7m
.arm
.core_cache
);
1291 /* now return stored error code if any */
1292 if (retval
!= ERROR_OK
)
1295 if (target
->reset_halt
) {
1296 retval
= target_halt(target
);
1297 if (retval
!= ERROR_OK
)
1304 static int cortex_m_deassert_reset(struct target
*target
)
1306 struct armv7m_common
*armv7m
= &target_to_cm(target
)->armv7m
;
1308 LOG_DEBUG("target->state: %s",
1309 target_state_name(target
));
1311 /* deassert reset lines */
1312 adapter_deassert_reset();
1314 enum reset_types jtag_reset_config
= jtag_get_reset_config();
1316 if ((jtag_reset_config
& RESET_HAS_SRST
) &&
1317 !(jtag_reset_config
& RESET_SRST_NO_GATING
) &&
1318 target_was_examined(target
)) {
1320 int retval
= dap_dp_init_or_reconnect(armv7m
->debug_ap
->dap
);
1321 if (retval
!= ERROR_OK
) {
1322 LOG_ERROR("DP initialisation failed");
1330 int cortex_m_set_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1333 unsigned int fp_num
= 0;
1334 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1335 struct cortex_m_fp_comparator
*comparator_list
= cortex_m
->fp_comparator_list
;
1337 if (breakpoint
->set
) {
1338 LOG_WARNING("breakpoint (BPID: %" PRIu32
") already set", breakpoint
->unique_id
);
1342 if (breakpoint
->type
== BKPT_HARD
) {
1343 uint32_t fpcr_value
;
1344 while (comparator_list
[fp_num
].used
&& (fp_num
< cortex_m
->fp_num_code
))
1346 if (fp_num
>= cortex_m
->fp_num_code
) {
1347 LOG_ERROR("Can not find free FPB Comparator!");
1348 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1350 breakpoint
->set
= fp_num
+ 1;
1351 fpcr_value
= breakpoint
->address
| 1;
1352 if (cortex_m
->fp_rev
== 0) {
1353 if (breakpoint
->address
> 0x1FFFFFFF) {
1354 LOG_ERROR("Cortex-M Flash Patch Breakpoint rev.1 cannot handle HW breakpoint above address 0x1FFFFFFE");
1358 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
1359 fpcr_value
= (fpcr_value
& 0x1FFFFFFC) | hilo
| 1;
1360 } else if (cortex_m
->fp_rev
> 1) {
1361 LOG_ERROR("Unhandled Cortex-M Flash Patch Breakpoint architecture revision");
1364 comparator_list
[fp_num
].used
= true;
1365 comparator_list
[fp_num
].fpcr_value
= fpcr_value
;
1366 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
,
1367 comparator_list
[fp_num
].fpcr_value
);
1368 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32
"",
1370 comparator_list
[fp_num
].fpcr_value
);
1371 if (!cortex_m
->fpb_enabled
) {
1372 LOG_DEBUG("FPB wasn't enabled, do it now");
1373 retval
= cortex_m_enable_fpb(target
);
1374 if (retval
!= ERROR_OK
) {
1375 LOG_ERROR("Failed to enable the FPB");
1379 cortex_m
->fpb_enabled
= true;
1381 } else if (breakpoint
->type
== BKPT_SOFT
) {
1384 /* NOTE: on ARMv6-M and ARMv7-M, BKPT(0xab) is used for
1385 * semihosting; don't use that. Otherwise the BKPT
1386 * parameter is arbitrary.
1388 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1389 retval
= target_read_memory(target
,
1390 breakpoint
->address
& 0xFFFFFFFE,
1391 breakpoint
->length
, 1,
1392 breakpoint
->orig_instr
);
1393 if (retval
!= ERROR_OK
)
1395 retval
= target_write_memory(target
,
1396 breakpoint
->address
& 0xFFFFFFFE,
1397 breakpoint
->length
, 1,
1399 if (retval
!= ERROR_OK
)
1401 breakpoint
->set
= true;
1404 LOG_DEBUG("BPID: %" PRIu32
", Type: %d, Address: " TARGET_ADDR_FMT
" Length: %d (set=%d)",
1405 breakpoint
->unique_id
,
1406 (int)(breakpoint
->type
),
1407 breakpoint
->address
,
1414 int cortex_m_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1417 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1418 struct cortex_m_fp_comparator
*comparator_list
= cortex_m
->fp_comparator_list
;
1420 if (breakpoint
->set
<= 0) {
1421 LOG_WARNING("breakpoint not set");
1425 LOG_DEBUG("BPID: %" PRIu32
", Type: %d, Address: " TARGET_ADDR_FMT
" Length: %d (set=%d)",
1426 breakpoint
->unique_id
,
1427 (int)(breakpoint
->type
),
1428 breakpoint
->address
,
1432 if (breakpoint
->type
== BKPT_HARD
) {
1433 unsigned int fp_num
= breakpoint
->set
- 1;
1434 if (fp_num
>= cortex_m
->fp_num_code
) {
1435 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
1438 comparator_list
[fp_num
].used
= false;
1439 comparator_list
[fp_num
].fpcr_value
= 0;
1440 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
,
1441 comparator_list
[fp_num
].fpcr_value
);
1443 /* restore original instruction (kept in target endianness) */
1444 retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE,
1445 breakpoint
->length
, 1,
1446 breakpoint
->orig_instr
);
1447 if (retval
!= ERROR_OK
)
1450 breakpoint
->set
= false;
1455 int cortex_m_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1457 if (breakpoint
->length
== 3) {
1458 LOG_DEBUG("Using a two byte breakpoint for 32bit Thumb-2 request");
1459 breakpoint
->length
= 2;
1462 if ((breakpoint
->length
!= 2)) {
1463 LOG_INFO("only breakpoints of two bytes length supported");
1464 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1467 return cortex_m_set_breakpoint(target
, breakpoint
);
1470 int cortex_m_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1472 if (!breakpoint
->set
)
1475 return cortex_m_unset_breakpoint(target
, breakpoint
);
1478 static int cortex_m_set_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1480 unsigned int dwt_num
= 0;
1481 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1483 /* REVISIT Don't fully trust these "not used" records ... users
1484 * may set up breakpoints by hand, e.g. dual-address data value
1485 * watchpoint using comparator #1; comparator #0 matching cycle
1486 * count; send data trace info through ITM and TPIU; etc
1488 struct cortex_m_dwt_comparator
*comparator
;
1490 for (comparator
= cortex_m
->dwt_comparator_list
;
1491 comparator
->used
&& dwt_num
< cortex_m
->dwt_num_comp
;
1492 comparator
++, dwt_num
++)
1494 if (dwt_num
>= cortex_m
->dwt_num_comp
) {
1495 LOG_ERROR("Can not find free DWT Comparator");
1498 comparator
->used
= true;
1499 watchpoint
->set
= dwt_num
+ 1;
1501 comparator
->comp
= watchpoint
->address
;
1502 target_write_u32(target
, comparator
->dwt_comparator_address
+ 0,
1505 if ((cortex_m
->dwt_devarch
& 0x1FFFFF) != DWT_DEVARCH_ARMV8M
) {
1506 uint32_t mask
= 0, temp
;
1508 /* watchpoint params were validated earlier */
1509 temp
= watchpoint
->length
;
1516 comparator
->mask
= mask
;
1517 target_write_u32(target
, comparator
->dwt_comparator_address
+ 4,
1520 switch (watchpoint
->rw
) {
1522 comparator
->function
= 5;
1525 comparator
->function
= 6;
1528 comparator
->function
= 7;
1532 uint32_t data_size
= watchpoint
->length
>> 1;
1533 comparator
->mask
= (watchpoint
->length
>> 1) | 1;
1535 switch (watchpoint
->rw
) {
1537 comparator
->function
= 4;
1540 comparator
->function
= 5;
1543 comparator
->function
= 6;
1546 comparator
->function
= comparator
->function
| (1 << 4) |
1550 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1551 comparator
->function
);
1553 LOG_DEBUG("Watchpoint (ID %d) DWT%d 0x%08x 0x%x 0x%05x",
1554 watchpoint
->unique_id
, dwt_num
,
1555 (unsigned) comparator
->comp
,
1556 (unsigned) comparator
->mask
,
1557 (unsigned) comparator
->function
);
1561 static int cortex_m_unset_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1563 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1564 struct cortex_m_dwt_comparator
*comparator
;
1566 if (watchpoint
->set
<= 0) {
1567 LOG_WARNING("watchpoint (wpid: %d) not set",
1568 watchpoint
->unique_id
);
1572 unsigned int dwt_num
= watchpoint
->set
- 1;
1574 LOG_DEBUG("Watchpoint (ID %d) DWT%d address: 0x%08x clear",
1575 watchpoint
->unique_id
, dwt_num
,
1576 (unsigned) watchpoint
->address
);
1578 if (dwt_num
>= cortex_m
->dwt_num_comp
) {
1579 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1583 comparator
= cortex_m
->dwt_comparator_list
+ dwt_num
;
1584 comparator
->used
= false;
1585 comparator
->function
= 0;
1586 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1587 comparator
->function
);
1589 watchpoint
->set
= false;
1594 int cortex_m_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1596 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1598 if (cortex_m
->dwt_comp_available
< 1) {
1599 LOG_DEBUG("no comparators?");
1600 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1603 /* hardware doesn't support data value masking */
1604 if (watchpoint
->mask
!= ~(uint32_t)0) {
1605 LOG_DEBUG("watchpoint value masks not supported");
1606 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1609 /* hardware allows address masks of up to 32K */
1612 for (mask
= 0; mask
< 16; mask
++) {
1613 if ((1u << mask
) == watchpoint
->length
)
1617 LOG_DEBUG("unsupported watchpoint length");
1618 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1620 if (watchpoint
->address
& ((1 << mask
) - 1)) {
1621 LOG_DEBUG("watchpoint address is unaligned");
1622 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1625 /* Caller doesn't seem to be able to describe watching for data
1626 * values of zero; that flags "no value".
1628 * REVISIT This DWT may well be able to watch for specific data
1629 * values. Requires comparator #1 to set DATAVMATCH and match
1630 * the data, and another comparator (DATAVADDR0) matching addr.
1632 if (watchpoint
->value
) {
1633 LOG_DEBUG("data value watchpoint not YET supported");
1634 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1637 cortex_m
->dwt_comp_available
--;
1638 LOG_DEBUG("dwt_comp_available: %d", cortex_m
->dwt_comp_available
);
1643 int cortex_m_remove_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1645 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1647 /* REVISIT why check? DWT can be updated with core running ... */
1648 if (target
->state
!= TARGET_HALTED
) {
1649 LOG_WARNING("target not halted");
1650 return ERROR_TARGET_NOT_HALTED
;
1653 if (watchpoint
->set
)
1654 cortex_m_unset_watchpoint(target
, watchpoint
);
1656 cortex_m
->dwt_comp_available
++;
1657 LOG_DEBUG("dwt_comp_available: %d", cortex_m
->dwt_comp_available
);
1662 int cortex_m_hit_watchpoint(struct target
*target
, struct watchpoint
**hit_watchpoint
)
1664 if (target
->debug_reason
!= DBG_REASON_WATCHPOINT
)
1667 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1669 for (struct watchpoint
*wp
= target
->watchpoints
; wp
; wp
= wp
->next
) {
1673 unsigned int dwt_num
= wp
->set
- 1;
1674 struct cortex_m_dwt_comparator
*comparator
= cortex_m
->dwt_comparator_list
+ dwt_num
;
1676 uint32_t dwt_function
;
1677 int retval
= target_read_u32(target
, comparator
->dwt_comparator_address
+ 8, &dwt_function
);
1678 if (retval
!= ERROR_OK
)
1681 /* check the MATCHED bit */
1682 if (dwt_function
& BIT(24)) {
1683 *hit_watchpoint
= wp
;
1691 void cortex_m_enable_watchpoints(struct target
*target
)
1693 struct watchpoint
*watchpoint
= target
->watchpoints
;
1695 /* set any pending watchpoints */
1696 while (watchpoint
) {
1697 if (!watchpoint
->set
)
1698 cortex_m_set_watchpoint(target
, watchpoint
);
1699 watchpoint
= watchpoint
->next
;
1703 static int cortex_m_read_memory(struct target
*target
, target_addr_t address
,
1704 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1706 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1708 if (armv7m
->arm
.arch
== ARM_ARCH_V6M
) {
1709 /* armv6m does not handle unaligned memory access */
1710 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1711 return ERROR_TARGET_UNALIGNED_ACCESS
;
1714 return mem_ap_read_buf(armv7m
->debug_ap
, buffer
, size
, count
, address
);
1717 static int cortex_m_write_memory(struct target
*target
, target_addr_t address
,
1718 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
1720 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1722 if (armv7m
->arm
.arch
== ARM_ARCH_V6M
) {
1723 /* armv6m does not handle unaligned memory access */
1724 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1725 return ERROR_TARGET_UNALIGNED_ACCESS
;
1728 return mem_ap_write_buf(armv7m
->debug_ap
, buffer
, size
, count
, address
);
1731 static int cortex_m_init_target(struct command_context
*cmd_ctx
,
1732 struct target
*target
)
1734 armv7m_build_reg_cache(target
);
1735 arm_semihosting_init(target
);
1739 void cortex_m_deinit_target(struct target
*target
)
1741 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1743 free(cortex_m
->fp_comparator_list
);
1745 cortex_m_dwt_free(target
);
1746 armv7m_free_reg_cache(target
);
1748 free(target
->private_config
);
1752 int cortex_m_profiling(struct target
*target
, uint32_t *samples
,
1753 uint32_t max_num_samples
, uint32_t *num_samples
, uint32_t seconds
)
1755 struct timeval timeout
, now
;
1756 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1760 retval
= target_read_u32(target
, DWT_PCSR
, ®_value
);
1761 if (retval
!= ERROR_OK
) {
1762 LOG_ERROR("Error while reading PCSR");
1765 if (reg_value
== 0) {
1766 LOG_INFO("PCSR sampling not supported on this processor.");
1767 return target_profiling_default(target
, samples
, max_num_samples
, num_samples
, seconds
);
1770 gettimeofday(&timeout
, NULL
);
1771 timeval_add_time(&timeout
, seconds
, 0);
1773 LOG_INFO("Starting Cortex-M profiling. Sampling DWT_PCSR as fast as we can...");
1775 /* Make sure the target is running */
1776 target_poll(target
);
1777 if (target
->state
== TARGET_HALTED
)
1778 retval
= target_resume(target
, 1, 0, 0, 0);
1780 if (retval
!= ERROR_OK
) {
1781 LOG_ERROR("Error while resuming target");
1785 uint32_t sample_count
= 0;
1788 if (armv7m
&& armv7m
->debug_ap
) {
1789 uint32_t read_count
= max_num_samples
- sample_count
;
1790 if (read_count
> 1024)
1793 retval
= mem_ap_read_buf_noincr(armv7m
->debug_ap
,
1794 (void *)&samples
[sample_count
],
1795 4, read_count
, DWT_PCSR
);
1796 sample_count
+= read_count
;
1798 target_read_u32(target
, DWT_PCSR
, &samples
[sample_count
++]);
1801 if (retval
!= ERROR_OK
) {
1802 LOG_ERROR("Error while reading PCSR");
1807 gettimeofday(&now
, NULL
);
1808 if (sample_count
>= max_num_samples
|| timeval_compare(&now
, &timeout
) > 0) {
1809 LOG_INFO("Profiling completed. %" PRIu32
" samples.", sample_count
);
1814 *num_samples
= sample_count
;
1819 /* REVISIT cache valid/dirty bits are unmaintained. We could set "valid"
1820 * on r/w if the core is not running, and clear on resume or reset ... or
1821 * at least, in a post_restore_context() method.
1824 struct dwt_reg_state
{
1825 struct target
*target
;
1827 uint8_t value
[4]; /* scratch/cache */
1830 static int cortex_m_dwt_get_reg(struct reg
*reg
)
1832 struct dwt_reg_state
*state
= reg
->arch_info
;
1835 int retval
= target_read_u32(state
->target
, state
->addr
, &tmp
);
1836 if (retval
!= ERROR_OK
)
1839 buf_set_u32(state
->value
, 0, 32, tmp
);
1843 static int cortex_m_dwt_set_reg(struct reg
*reg
, uint8_t *buf
)
1845 struct dwt_reg_state
*state
= reg
->arch_info
;
1847 return target_write_u32(state
->target
, state
->addr
,
1848 buf_get_u32(buf
, 0, reg
->size
));
1857 static const struct dwt_reg dwt_base_regs
[] = {
1858 { DWT_CTRL
, "dwt_ctrl", 32, },
1859 /* NOTE that Erratum 532314 (fixed r2p0) affects CYCCNT: it wrongly
1860 * increments while the core is asleep.
1862 { DWT_CYCCNT
, "dwt_cyccnt", 32, },
1863 /* plus some 8 bit counters, useful for profiling with TPIU */
1866 static const struct dwt_reg dwt_comp
[] = {
1867 #define DWT_COMPARATOR(i) \
1868 { DWT_COMP0 + 0x10 * (i), "dwt_" #i "_comp", 32, }, \
1869 { DWT_MASK0 + 0x10 * (i), "dwt_" #i "_mask", 4, }, \
1870 { DWT_FUNCTION0 + 0x10 * (i), "dwt_" #i "_function", 32, }
1887 #undef DWT_COMPARATOR
1890 static const struct reg_arch_type dwt_reg_type
= {
1891 .get
= cortex_m_dwt_get_reg
,
1892 .set
= cortex_m_dwt_set_reg
,
1895 static void cortex_m_dwt_addreg(struct target
*t
, struct reg
*r
, const struct dwt_reg
*d
)
1897 struct dwt_reg_state
*state
;
1899 state
= calloc(1, sizeof(*state
));
1902 state
->addr
= d
->addr
;
1907 r
->value
= state
->value
;
1908 r
->arch_info
= state
;
1909 r
->type
= &dwt_reg_type
;
1912 static void cortex_m_dwt_setup(struct cortex_m_common
*cm
, struct target
*target
)
1915 struct reg_cache
*cache
;
1916 struct cortex_m_dwt_comparator
*comparator
;
1919 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1920 LOG_DEBUG("DWT_CTRL: 0x%" PRIx32
, dwtcr
);
1922 LOG_DEBUG("no DWT");
1926 target_read_u32(target
, DWT_DEVARCH
, &cm
->dwt_devarch
);
1927 LOG_DEBUG("DWT_DEVARCH: 0x%" PRIx32
, cm
->dwt_devarch
);
1929 cm
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1930 cm
->dwt_comp_available
= cm
->dwt_num_comp
;
1931 cm
->dwt_comparator_list
= calloc(cm
->dwt_num_comp
,
1932 sizeof(struct cortex_m_dwt_comparator
));
1933 if (!cm
->dwt_comparator_list
) {
1935 cm
->dwt_num_comp
= 0;
1936 LOG_ERROR("out of mem");
1940 cache
= calloc(1, sizeof(*cache
));
1943 free(cm
->dwt_comparator_list
);
1946 cache
->name
= "Cortex-M DWT registers";
1947 cache
->num_regs
= 2 + cm
->dwt_num_comp
* 3;
1948 cache
->reg_list
= calloc(cache
->num_regs
, sizeof(*cache
->reg_list
));
1949 if (!cache
->reg_list
) {
1954 for (reg
= 0; reg
< 2; reg
++)
1955 cortex_m_dwt_addreg(target
, cache
->reg_list
+ reg
,
1956 dwt_base_regs
+ reg
);
1958 comparator
= cm
->dwt_comparator_list
;
1959 for (unsigned int i
= 0; i
< cm
->dwt_num_comp
; i
++, comparator
++) {
1962 comparator
->dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1963 for (j
= 0; j
< 3; j
++, reg
++)
1964 cortex_m_dwt_addreg(target
, cache
->reg_list
+ reg
,
1965 dwt_comp
+ 3 * i
+ j
);
1967 /* make sure we clear any watchpoints enabled on the target */
1968 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8, 0);
1971 *register_get_last_cache_p(&target
->reg_cache
) = cache
;
1972 cm
->dwt_cache
= cache
;
1974 LOG_DEBUG("DWT dwtcr 0x%" PRIx32
", comp %d, watch%s",
1975 dwtcr
, cm
->dwt_num_comp
,
1976 (dwtcr
& (0xf << 24)) ? " only" : "/trigger");
1978 /* REVISIT: if num_comp > 1, check whether comparator #1 can
1979 * implement single-address data value watchpoints ... so we
1980 * won't need to check it later, when asked to set one up.
1984 static void cortex_m_dwt_free(struct target
*target
)
1986 struct cortex_m_common
*cm
= target_to_cm(target
);
1987 struct reg_cache
*cache
= cm
->dwt_cache
;
1989 free(cm
->dwt_comparator_list
);
1990 cm
->dwt_comparator_list
= NULL
;
1991 cm
->dwt_num_comp
= 0;
1994 register_unlink_cache(&target
->reg_cache
, cache
);
1996 if (cache
->reg_list
) {
1997 for (size_t i
= 0; i
< cache
->num_regs
; i
++)
1998 free(cache
->reg_list
[i
].arch_info
);
1999 free(cache
->reg_list
);
2003 cm
->dwt_cache
= NULL
;
2006 #define MVFR0 0xe000ef40
2007 #define MVFR1 0xe000ef44
2009 #define MVFR0_DEFAULT_M4 0x10110021
2010 #define MVFR1_DEFAULT_M4 0x11000011
2012 #define MVFR0_DEFAULT_M7_SP 0x10110021
2013 #define MVFR0_DEFAULT_M7_DP 0x10110221
2014 #define MVFR1_DEFAULT_M7_SP 0x11000011
2015 #define MVFR1_DEFAULT_M7_DP 0x12000011
2017 static int cortex_m_find_mem_ap(struct adiv5_dap
*swjdp
,
2018 struct adiv5_ap
**debug_ap
)
2020 if (dap_find_ap(swjdp
, AP_TYPE_AHB3_AP
, debug_ap
) == ERROR_OK
)
2023 return dap_find_ap(swjdp
, AP_TYPE_AHB5_AP
, debug_ap
);
2026 int cortex_m_examine(struct target
*target
)
2029 uint32_t cpuid
, fpcr
, mvfr0
, mvfr1
;
2030 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
2031 struct adiv5_dap
*swjdp
= cortex_m
->armv7m
.arm
.dap
;
2032 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
2034 /* hla_target shares the examine handler but does not support
2036 if (!armv7m
->is_hla_target
) {
2037 if (cortex_m
->apsel
== DP_APSEL_INVALID
) {
2038 /* Search for the MEM-AP */
2039 retval
= cortex_m_find_mem_ap(swjdp
, &armv7m
->debug_ap
);
2040 if (retval
!= ERROR_OK
) {
2041 LOG_ERROR("Could not find MEM-AP to control the core");
2045 armv7m
->debug_ap
= dap_ap(swjdp
, cortex_m
->apsel
);
2048 /* Leave (only) generic DAP stuff for debugport_init(); */
2049 armv7m
->debug_ap
->memaccess_tck
= 8;
2051 retval
= mem_ap_init(armv7m
->debug_ap
);
2052 if (retval
!= ERROR_OK
)
2056 if (!target_was_examined(target
)) {
2057 target_set_examined(target
);
2059 /* Read from Device Identification Registers */
2060 retval
= target_read_u32(target
, CPUID
, &cpuid
);
2061 if (retval
!= ERROR_OK
)
2064 /* Get ARCH and CPU types */
2065 const enum cortex_m_partno core_partno
= (cpuid
& ARM_CPUID_PARTNO_MASK
) >> ARM_CPUID_PARTNO_POS
;
2067 for (unsigned int n
= 0; n
< ARRAY_SIZE(cortex_m_parts
); n
++) {
2068 if (core_partno
== cortex_m_parts
[n
].partno
) {
2069 cortex_m
->core_info
= &cortex_m_parts
[n
];
2074 if (!cortex_m
->core_info
) {
2075 LOG_ERROR("Cortex-M PARTNO 0x%x is unrecognized", core_partno
);
2079 armv7m
->arm
.arch
= cortex_m
->core_info
->arch
;
2081 LOG_DEBUG("%s r%" PRId8
"p%" PRId8
" processor detected",
2082 cortex_m
->core_info
->name
, (uint8_t)((cpuid
>> 20) & 0xf), (uint8_t)((cpuid
>> 0) & 0xf));
2083 cortex_m
->maskints_erratum
= false;
2084 if (core_partno
== CORTEX_M7_PARTNO
) {
2086 rev
= (cpuid
>> 20) & 0xf;
2087 patch
= (cpuid
>> 0) & 0xf;
2088 if ((rev
== 0) && (patch
< 2)) {
2089 LOG_WARNING("Silicon bug: single stepping may enter pending exception handler!");
2090 cortex_m
->maskints_erratum
= true;
2093 LOG_DEBUG("cpuid: 0x%8.8" PRIx32
"", cpuid
);
2095 if (cortex_m
->core_info
->flags
& CORTEX_M_F_HAS_FPV4
) {
2096 target_read_u32(target
, MVFR0
, &mvfr0
);
2097 target_read_u32(target
, MVFR1
, &mvfr1
);
2099 /* test for floating point feature on Cortex-M4 */
2100 if ((mvfr0
== MVFR0_DEFAULT_M4
) && (mvfr1
== MVFR1_DEFAULT_M4
)) {
2101 LOG_DEBUG("%s floating point feature FPv4_SP found", cortex_m
->core_info
->name
);
2102 armv7m
->fp_feature
= FPV4_SP
;
2104 } else if (cortex_m
->core_info
->flags
& CORTEX_M_F_HAS_FPV5
) {
2105 target_read_u32(target
, MVFR0
, &mvfr0
);
2106 target_read_u32(target
, MVFR1
, &mvfr1
);
2108 /* test for floating point features on Cortex-M7 */
2109 if ((mvfr0
== MVFR0_DEFAULT_M7_SP
) && (mvfr1
== MVFR1_DEFAULT_M7_SP
)) {
2110 LOG_DEBUG("%s floating point feature FPv5_SP found", cortex_m
->core_info
->name
);
2111 armv7m
->fp_feature
= FPV5_SP
;
2112 } else if ((mvfr0
== MVFR0_DEFAULT_M7_DP
) && (mvfr1
== MVFR1_DEFAULT_M7_DP
)) {
2113 LOG_DEBUG("%s floating point feature FPv5_DP found", cortex_m
->core_info
->name
);
2114 armv7m
->fp_feature
= FPV5_DP
;
2118 /* VECTRESET is supported only on ARMv7-M cores */
2119 cortex_m
->vectreset_supported
= armv7m
->arm
.arch
== ARM_ARCH_V7M
;
2121 /* Check for FPU, otherwise mark FPU register as non-existent */
2122 if (armv7m
->fp_feature
== FP_NONE
)
2123 for (size_t idx
= ARMV7M_FPU_FIRST_REG
; idx
<= ARMV7M_FPU_LAST_REG
; idx
++)
2124 armv7m
->arm
.core_cache
->reg_list
[idx
].exist
= false;
2126 if (armv7m
->arm
.arch
!= ARM_ARCH_V8M
)
2127 for (size_t idx
= ARMV8M_FIRST_REG
; idx
<= ARMV8M_LAST_REG
; idx
++)
2128 armv7m
->arm
.core_cache
->reg_list
[idx
].exist
= false;
2130 if (!armv7m
->is_hla_target
) {
2131 if (cortex_m
->core_info
->flags
& CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K
)
2132 /* Cortex-M3/M4 have 4096 bytes autoincrement range,
2133 * s. ARM IHI 0031C: MEM-AP 7.2.2 */
2134 armv7m
->debug_ap
->tar_autoincr_block
= (1 << 12);
2137 /* Enable debug requests */
2138 retval
= target_read_u32(target
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
2139 if (retval
!= ERROR_OK
)
2141 if (!(cortex_m
->dcb_dhcsr
& C_DEBUGEN
)) {
2142 uint32_t dhcsr
= (cortex_m
->dcb_dhcsr
| C_DEBUGEN
) & ~(C_HALT
| C_STEP
| C_MASKINTS
);
2144 retval
= target_write_u32(target
, DCB_DHCSR
, DBGKEY
| (dhcsr
& 0x0000FFFFUL
));
2145 if (retval
!= ERROR_OK
)
2147 cortex_m
->dcb_dhcsr
= dhcsr
;
2150 /* Configure trace modules */
2151 retval
= target_write_u32(target
, DCB_DEMCR
, TRCENA
| armv7m
->demcr
);
2152 if (retval
!= ERROR_OK
)
2155 if (armv7m
->trace_config
.itm_deferred_config
)
2156 armv7m_trace_itm_config(target
);
2158 /* NOTE: FPB and DWT are both optional. */
2161 target_read_u32(target
, FP_CTRL
, &fpcr
);
2162 /* bits [14:12] and [7:4] */
2163 cortex_m
->fp_num_code
= ((fpcr
>> 8) & 0x70) | ((fpcr
>> 4) & 0xF);
2164 cortex_m
->fp_num_lit
= (fpcr
>> 8) & 0xF;
2165 /* Detect flash patch revision, see RM DDI 0403E.b page C1-817.
2166 Revision is zero base, fp_rev == 1 means Rev.2 ! */
2167 cortex_m
->fp_rev
= (fpcr
>> 28) & 0xf;
2168 free(cortex_m
->fp_comparator_list
);
2169 cortex_m
->fp_comparator_list
= calloc(
2170 cortex_m
->fp_num_code
+ cortex_m
->fp_num_lit
,
2171 sizeof(struct cortex_m_fp_comparator
));
2172 cortex_m
->fpb_enabled
= fpcr
& 1;
2173 for (unsigned int i
= 0; i
< cortex_m
->fp_num_code
+ cortex_m
->fp_num_lit
; i
++) {
2174 cortex_m
->fp_comparator_list
[i
].type
=
2175 (i
< cortex_m
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
2176 cortex_m
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
2178 /* make sure we clear any breakpoints enabled on the target */
2179 target_write_u32(target
, cortex_m
->fp_comparator_list
[i
].fpcr_address
, 0);
2181 LOG_DEBUG("FPB fpcr 0x%" PRIx32
", numcode %i, numlit %i",
2183 cortex_m
->fp_num_code
,
2184 cortex_m
->fp_num_lit
);
2187 cortex_m_dwt_free(target
);
2188 cortex_m_dwt_setup(cortex_m
, target
);
2190 /* These hardware breakpoints only work for code in flash! */
2191 LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints",
2192 target_name(target
),
2193 cortex_m
->fp_num_code
,
2194 cortex_m
->dwt_num_comp
);
2200 static int cortex_m_dcc_read(struct target
*target
, uint8_t *value
, uint8_t *ctrl
)
2202 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
2207 retval
= mem_ap_read_buf_noincr(armv7m
->debug_ap
, buf
, 2, 1, DCB_DCRDR
);
2208 if (retval
!= ERROR_OK
)
2211 dcrdr
= target_buffer_get_u16(target
, buf
);
2212 *ctrl
= (uint8_t)dcrdr
;
2213 *value
= (uint8_t)(dcrdr
>> 8);
2215 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
2217 /* write ack back to software dcc register
2218 * signify we have read data */
2219 if (dcrdr
& (1 << 0)) {
2220 target_buffer_set_u16(target
, buf
, 0);
2221 retval
= mem_ap_write_buf_noincr(armv7m
->debug_ap
, buf
, 2, 1, DCB_DCRDR
);
2222 if (retval
!= ERROR_OK
)
2229 static int cortex_m_target_request_data(struct target
*target
,
2230 uint32_t size
, uint8_t *buffer
)
2236 for (i
= 0; i
< (size
* 4); i
++) {
2237 int retval
= cortex_m_dcc_read(target
, &data
, &ctrl
);
2238 if (retval
!= ERROR_OK
)
2246 static int cortex_m_handle_target_request(void *priv
)
2248 struct target
*target
= priv
;
2249 if (!target_was_examined(target
))
2252 if (!target
->dbg_msg_enabled
)
2255 if (target
->state
== TARGET_RUNNING
) {
2260 retval
= cortex_m_dcc_read(target
, &data
, &ctrl
);
2261 if (retval
!= ERROR_OK
)
2264 /* check if we have data */
2265 if (ctrl
& (1 << 0)) {
2268 /* we assume target is quick enough */
2270 for (int i
= 1; i
<= 3; i
++) {
2271 retval
= cortex_m_dcc_read(target
, &data
, &ctrl
);
2272 if (retval
!= ERROR_OK
)
2274 request
|= ((uint32_t)data
<< (i
* 8));
2276 target_request(target
, request
);
2283 static int cortex_m_init_arch_info(struct target
*target
,
2284 struct cortex_m_common
*cortex_m
, struct adiv5_dap
*dap
)
2286 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
2288 armv7m_init_arch_info(target
, armv7m
);
2290 /* default reset mode is to use srst if fitted
2291 * if not it will use CORTEX_M3_RESET_VECTRESET */
2292 cortex_m
->soft_reset_config
= CORTEX_M_RESET_VECTRESET
;
2294 armv7m
->arm
.dap
= dap
;
2296 /* register arch-specific functions */
2297 armv7m
->examine_debug_reason
= cortex_m_examine_debug_reason
;
2299 armv7m
->post_debug_entry
= NULL
;
2301 armv7m
->pre_restore_context
= NULL
;
2303 armv7m
->load_core_reg_u32
= cortex_m_load_core_reg_u32
;
2304 armv7m
->store_core_reg_u32
= cortex_m_store_core_reg_u32
;
2306 target_register_timer_callback(cortex_m_handle_target_request
, 1,
2307 TARGET_TIMER_TYPE_PERIODIC
, target
);
2312 static int cortex_m_target_create(struct target
*target
, Jim_Interp
*interp
)
2314 struct adiv5_private_config
*pc
;
2316 pc
= (struct adiv5_private_config
*)target
->private_config
;
2317 if (adiv5_verify_config(pc
) != ERROR_OK
)
2320 struct cortex_m_common
*cortex_m
= calloc(1, sizeof(struct cortex_m_common
));
2322 LOG_ERROR("No memory creating target");
2326 cortex_m
->common_magic
= CORTEX_M_COMMON_MAGIC
;
2327 cortex_m
->apsel
= pc
->ap_num
;
2329 cortex_m_init_arch_info(target
, cortex_m
, pc
->dap
);
2334 /*--------------------------------------------------------------------------*/
2336 static int cortex_m_verify_pointer(struct command_invocation
*cmd
,
2337 struct cortex_m_common
*cm
)
2339 if (cm
->common_magic
!= CORTEX_M_COMMON_MAGIC
) {
2340 command_print(cmd
, "target is not a Cortex-M");
2341 return ERROR_TARGET_INVALID
;
2347 * Only stuff below this line should need to verify that its target
2348 * is a Cortex-M3. Everything else should have indirected through the
2349 * cortexm3_target structure, which is only used with CM3 targets.
2352 COMMAND_HANDLER(handle_cortex_m_vector_catch_command
)
2354 struct target
*target
= get_current_target(CMD_CTX
);
2355 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
2356 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
2360 static const struct {
2364 { "hard_err", VC_HARDERR
, },
2365 { "int_err", VC_INTERR
, },
2366 { "bus_err", VC_BUSERR
, },
2367 { "state_err", VC_STATERR
, },
2368 { "chk_err", VC_CHKERR
, },
2369 { "nocp_err", VC_NOCPERR
, },
2370 { "mm_err", VC_MMERR
, },
2371 { "reset", VC_CORERESET
, },
2374 retval
= cortex_m_verify_pointer(CMD
, cortex_m
);
2375 if (retval
!= ERROR_OK
)
2378 if (!target_was_examined(target
)) {
2379 LOG_ERROR("Target not examined yet");
2383 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DEMCR
, &demcr
);
2384 if (retval
!= ERROR_OK
)
2390 if (CMD_ARGC
== 1) {
2391 if (strcmp(CMD_ARGV
[0], "all") == 0) {
2392 catch = VC_HARDERR
| VC_INTERR
| VC_BUSERR
2393 | VC_STATERR
| VC_CHKERR
| VC_NOCPERR
2394 | VC_MMERR
| VC_CORERESET
;
2396 } else if (strcmp(CMD_ARGV
[0], "none") == 0)
2399 while (CMD_ARGC
-- > 0) {
2401 for (i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++) {
2402 if (strcmp(CMD_ARGV
[CMD_ARGC
], vec_ids
[i
].name
) != 0)
2404 catch |= vec_ids
[i
].mask
;
2407 if (i
== ARRAY_SIZE(vec_ids
)) {
2408 LOG_ERROR("No CM3 vector '%s'", CMD_ARGV
[CMD_ARGC
]);
2409 return ERROR_COMMAND_SYNTAX_ERROR
;
2413 /* For now, armv7m->demcr only stores vector catch flags. */
2414 armv7m
->demcr
= catch;
2419 /* write, but don't assume it stuck (why not??) */
2420 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DEMCR
, demcr
);
2421 if (retval
!= ERROR_OK
)
2423 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DEMCR
, &demcr
);
2424 if (retval
!= ERROR_OK
)
2427 /* FIXME be sure to clear DEMCR on clean server shutdown.
2428 * Otherwise the vector catch hardware could fire when there's
2429 * no debugger hooked up, causing much confusion...
2433 for (unsigned i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++) {
2434 command_print(CMD
, "%9s: %s", vec_ids
[i
].name
,
2435 (demcr
& vec_ids
[i
].mask
) ? "catch" : "ignore");
2441 COMMAND_HANDLER(handle_cortex_m_mask_interrupts_command
)
2443 struct target
*target
= get_current_target(CMD_CTX
);
2444 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
2447 static const struct jim_nvp nvp_maskisr_modes
[] = {
2448 { .name
= "auto", .value
= CORTEX_M_ISRMASK_AUTO
},
2449 { .name
= "off", .value
= CORTEX_M_ISRMASK_OFF
},
2450 { .name
= "on", .value
= CORTEX_M_ISRMASK_ON
},
2451 { .name
= "steponly", .value
= CORTEX_M_ISRMASK_STEPONLY
},
2452 { .name
= NULL
, .value
= -1 },
2454 const struct jim_nvp
*n
;
2457 retval
= cortex_m_verify_pointer(CMD
, cortex_m
);
2458 if (retval
!= ERROR_OK
)
2461 if (target
->state
!= TARGET_HALTED
) {
2462 command_print(CMD
, "target must be stopped for \"%s\" command", CMD_NAME
);
2467 n
= jim_nvp_name2value_simple(nvp_maskisr_modes
, CMD_ARGV
[0]);
2469 return ERROR_COMMAND_SYNTAX_ERROR
;
2470 cortex_m
->isrmasking_mode
= n
->value
;
2471 cortex_m_set_maskints_for_halt(target
);
2474 n
= jim_nvp_value2name_simple(nvp_maskisr_modes
, cortex_m
->isrmasking_mode
);
2475 command_print(CMD
, "cortex_m interrupt mask %s", n
->name
);
2480 COMMAND_HANDLER(handle_cortex_m_reset_config_command
)
2482 struct target
*target
= get_current_target(CMD_CTX
);
2483 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
2487 retval
= cortex_m_verify_pointer(CMD
, cortex_m
);
2488 if (retval
!= ERROR_OK
)
2492 if (strcmp(*CMD_ARGV
, "sysresetreq") == 0)
2493 cortex_m
->soft_reset_config
= CORTEX_M_RESET_SYSRESETREQ
;
2495 else if (strcmp(*CMD_ARGV
, "vectreset") == 0) {
2496 if (target_was_examined(target
)
2497 && !cortex_m
->vectreset_supported
)
2498 LOG_WARNING("VECTRESET is not supported on your Cortex-M core!");
2500 cortex_m
->soft_reset_config
= CORTEX_M_RESET_VECTRESET
;
2503 return ERROR_COMMAND_SYNTAX_ERROR
;
2506 switch (cortex_m
->soft_reset_config
) {
2507 case CORTEX_M_RESET_SYSRESETREQ
:
2508 reset_config
= "sysresetreq";
2511 case CORTEX_M_RESET_VECTRESET
:
2512 reset_config
= "vectreset";
2516 reset_config
= "unknown";
2520 command_print(CMD
, "cortex_m reset_config %s", reset_config
);
2525 static const struct command_registration cortex_m_exec_command_handlers
[] = {
2528 .handler
= handle_cortex_m_mask_interrupts_command
,
2529 .mode
= COMMAND_EXEC
,
2530 .help
= "mask cortex_m interrupts",
2531 .usage
= "['auto'|'on'|'off'|'steponly']",
2534 .name
= "vector_catch",
2535 .handler
= handle_cortex_m_vector_catch_command
,
2536 .mode
= COMMAND_EXEC
,
2537 .help
= "configure hardware vectors to trigger debug entry",
2538 .usage
= "['all'|'none'|('bus_err'|'chk_err'|...)*]",
2541 .name
= "reset_config",
2542 .handler
= handle_cortex_m_reset_config_command
,
2543 .mode
= COMMAND_ANY
,
2544 .help
= "configure software reset handling",
2545 .usage
= "['sysresetreq'|'vectreset']",
2547 COMMAND_REGISTRATION_DONE
2549 static const struct command_registration cortex_m_command_handlers
[] = {
2551 .chain
= armv7m_command_handlers
,
2554 .chain
= armv7m_trace_command_handlers
,
2556 /* START_DEPRECATED_TPIU */
2558 .chain
= arm_tpiu_deprecated_command_handlers
,
2560 /* END_DEPRECATED_TPIU */
2563 .mode
= COMMAND_EXEC
,
2564 .help
= "Cortex-M command group",
2566 .chain
= cortex_m_exec_command_handlers
,
2569 .chain
= rtt_target_command_handlers
,
2571 COMMAND_REGISTRATION_DONE
2574 struct target_type cortexm_target
= {
2577 .poll
= cortex_m_poll
,
2578 .arch_state
= armv7m_arch_state
,
2580 .target_request_data
= cortex_m_target_request_data
,
2582 .halt
= cortex_m_halt
,
2583 .resume
= cortex_m_resume
,
2584 .step
= cortex_m_step
,
2586 .assert_reset
= cortex_m_assert_reset
,
2587 .deassert_reset
= cortex_m_deassert_reset
,
2588 .soft_reset_halt
= cortex_m_soft_reset_halt
,
2590 .get_gdb_arch
= arm_get_gdb_arch
,
2591 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
2593 .read_memory
= cortex_m_read_memory
,
2594 .write_memory
= cortex_m_write_memory
,
2595 .checksum_memory
= armv7m_checksum_memory
,
2596 .blank_check_memory
= armv7m_blank_check_memory
,
2598 .run_algorithm
= armv7m_run_algorithm
,
2599 .start_algorithm
= armv7m_start_algorithm
,
2600 .wait_algorithm
= armv7m_wait_algorithm
,
2602 .add_breakpoint
= cortex_m_add_breakpoint
,
2603 .remove_breakpoint
= cortex_m_remove_breakpoint
,
2604 .add_watchpoint
= cortex_m_add_watchpoint
,
2605 .remove_watchpoint
= cortex_m_remove_watchpoint
,
2606 .hit_watchpoint
= cortex_m_hit_watchpoint
,
2608 .commands
= cortex_m_command_handlers
,
2609 .target_create
= cortex_m_target_create
,
2610 .target_jim_configure
= adiv5_jim_configure
,
2611 .init_target
= cortex_m_init_target
,
2612 .examine
= cortex_m_examine
,
2613 .deinit_target
= cortex_m_deinit_target
,
2615 .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)