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
);
984 uint32_t pc_value
= buf_get_u32(pc
->value
, 0, 32);
986 /* the front-end may request us not to handle breakpoints */
987 if (handle_breakpoints
) {
988 breakpoint
= breakpoint_find(target
, pc_value
);
990 cortex_m_unset_breakpoint(target
, breakpoint
);
993 armv7m_maybe_skip_bkpt_inst(target
, &bkpt_inst_found
);
995 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
997 armv7m_restore_context(target
);
999 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1001 /* if no bkpt instruction is found at pc then we can perform
1002 * a normal step, otherwise we have to manually step over the bkpt
1003 * instruction - as such simulate a step */
1004 if (bkpt_inst_found
== false) {
1005 if (cortex_m
->isrmasking_mode
!= CORTEX_M_ISRMASK_AUTO
) {
1006 /* Automatic ISR masking mode off: Just step over the next
1007 * instruction, with interrupts on or off as appropriate. */
1008 cortex_m_set_maskints_for_step(target
);
1009 cortex_m_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
1011 /* Process interrupts during stepping in a way they don't interfere
1016 * Set a temporary break point at the current pc and let the core run
1017 * with interrupts enabled. Pending interrupts get served and we run
1018 * into the breakpoint again afterwards. Then we step over the next
1019 * instruction with interrupts disabled.
1021 * If the pending interrupts don't complete within time, we leave the
1022 * core running. This may happen if the interrupts trigger faster
1023 * than the core can process them or the handler doesn't return.
1025 * If no more breakpoints are available we simply do a step with
1026 * interrupts enabled.
1032 * If a break point is already set on the lower half word then a break point on
1033 * the upper half word will not break again when the core is restarted. So we
1034 * just step over the instruction with interrupts disabled.
1036 * The documentation has no information about this, it was found by observation
1037 * on STM32F1 and STM32F2. Proper explanation welcome. STM32F0 doesn't seem to
1038 * suffer from this problem.
1040 * To add some confusion: pc_value has bit 0 always set, while the breakpoint
1041 * address has it always cleared. The former is done to indicate thumb mode
1045 if ((pc_value
& 0x02) && breakpoint_find(target
, pc_value
& ~0x03)) {
1046 LOG_DEBUG("Stepping over next instruction with interrupts disabled");
1047 cortex_m_write_debug_halt_mask(target
, C_HALT
| C_MASKINTS
, 0);
1048 cortex_m_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
1049 /* Re-enable interrupts if appropriate */
1050 cortex_m_write_debug_halt_mask(target
, C_HALT
, 0);
1051 cortex_m_set_maskints_for_halt(target
);
1054 /* Set a temporary break point */
1056 retval
= cortex_m_set_breakpoint(target
, breakpoint
);
1058 enum breakpoint_type type
= BKPT_HARD
;
1059 if (cortex_m
->fp_rev
== 0 && pc_value
> 0x1FFFFFFF) {
1060 /* FPB rev.1 cannot handle such addr, try BKPT instr */
1063 retval
= breakpoint_add(target
, pc_value
, 2, type
);
1066 bool tmp_bp_set
= (retval
== ERROR_OK
);
1068 /* No more breakpoints left, just do a step */
1070 cortex_m_set_maskints_for_step(target
);
1071 cortex_m_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
1072 /* Re-enable interrupts if appropriate */
1073 cortex_m_write_debug_halt_mask(target
, C_HALT
, 0);
1074 cortex_m_set_maskints_for_halt(target
);
1076 /* Start the core */
1077 LOG_DEBUG("Starting core to serve pending interrupts");
1078 int64_t t_start
= timeval_ms();
1079 cortex_m_set_maskints_for_run(target
);
1080 cortex_m_write_debug_halt_mask(target
, 0, C_HALT
| C_STEP
);
1082 /* Wait for pending handlers to complete or timeout */
1084 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
,
1086 &cortex_m
->dcb_dhcsr
);
1087 if (retval
!= ERROR_OK
) {
1088 target
->state
= TARGET_UNKNOWN
;
1091 isr_timed_out
= ((timeval_ms() - t_start
) > 500);
1092 } while (!((cortex_m
->dcb_dhcsr
& S_HALT
) || isr_timed_out
));
1094 /* only remove breakpoint if we created it */
1096 cortex_m_unset_breakpoint(target
, breakpoint
);
1098 /* Remove the temporary breakpoint */
1099 breakpoint_remove(target
, pc_value
);
1102 if (isr_timed_out
) {
1103 LOG_DEBUG("Interrupt handlers didn't complete within time, "
1104 "leaving target running");
1106 /* Step over next instruction with interrupts disabled */
1107 cortex_m_set_maskints_for_step(target
);
1108 cortex_m_write_debug_halt_mask(target
,
1109 C_HALT
| C_MASKINTS
,
1111 cortex_m_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
1112 /* Re-enable interrupts if appropriate */
1113 cortex_m_write_debug_halt_mask(target
, C_HALT
, 0);
1114 cortex_m_set_maskints_for_halt(target
);
1121 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
1122 if (retval
!= ERROR_OK
)
1125 /* registers are now invalid */
1126 register_cache_invalidate(armv7m
->arm
.core_cache
);
1129 cortex_m_set_breakpoint(target
, breakpoint
);
1131 if (isr_timed_out
) {
1132 /* Leave the core running. The user has to stop execution manually. */
1133 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1134 target
->state
= TARGET_RUNNING
;
1138 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
1139 " nvic_icsr = 0x%" PRIx32
,
1140 cortex_m
->dcb_dhcsr
, cortex_m
->nvic_icsr
);
1142 retval
= cortex_m_debug_entry(target
);
1143 if (retval
!= ERROR_OK
)
1145 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1147 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
1148 " nvic_icsr = 0x%" PRIx32
,
1149 cortex_m
->dcb_dhcsr
, cortex_m
->nvic_icsr
);
1154 static int cortex_m_assert_reset(struct target
*target
)
1156 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1157 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
1158 enum cortex_m_soft_reset_config reset_config
= cortex_m
->soft_reset_config
;
1160 LOG_DEBUG("target->state: %s",
1161 target_state_name(target
));
1163 enum reset_types jtag_reset_config
= jtag_get_reset_config();
1165 if (target_has_event_action(target
, TARGET_EVENT_RESET_ASSERT
)) {
1166 /* allow scripts to override the reset event */
1168 target_handle_event(target
, TARGET_EVENT_RESET_ASSERT
);
1169 register_cache_invalidate(cortex_m
->armv7m
.arm
.core_cache
);
1170 target
->state
= TARGET_RESET
;
1175 /* some cores support connecting while srst is asserted
1176 * use that mode is it has been configured */
1178 bool srst_asserted
= false;
1180 if (!target_was_examined(target
)) {
1181 if (jtag_reset_config
& RESET_HAS_SRST
) {
1182 adapter_assert_reset();
1183 if (target
->reset_halt
)
1184 LOG_ERROR("Target not examined, will not halt after reset!");
1187 LOG_ERROR("Target not examined, reset NOT asserted!");
1192 if ((jtag_reset_config
& RESET_HAS_SRST
) &&
1193 (jtag_reset_config
& RESET_SRST_NO_GATING
)) {
1194 adapter_assert_reset();
1195 srst_asserted
= true;
1198 /* Enable debug requests */
1200 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
1201 /* Store important errors instead of failing and proceed to reset assert */
1203 if (retval
!= ERROR_OK
|| !(cortex_m
->dcb_dhcsr
& C_DEBUGEN
))
1204 retval
= cortex_m_write_debug_halt_mask(target
, 0, C_HALT
| C_STEP
| C_MASKINTS
);
1206 /* If the processor is sleeping in a WFI or WFE instruction, the
1207 * C_HALT bit must be asserted to regain control */
1208 if (retval
== ERROR_OK
&& (cortex_m
->dcb_dhcsr
& S_SLEEP
))
1209 retval
= cortex_m_write_debug_halt_mask(target
, C_HALT
, 0);
1211 mem_ap_write_u32(armv7m
->debug_ap
, DCB_DCRDR
, 0);
1212 /* Ignore less important errors */
1214 if (!target
->reset_halt
) {
1215 /* Set/Clear C_MASKINTS in a separate operation */
1216 cortex_m_set_maskints_for_run(target
);
1218 /* clear any debug flags before resuming */
1219 cortex_m_clear_halt(target
);
1221 /* clear C_HALT in dhcsr reg */
1222 cortex_m_write_debug_halt_mask(target
, 0, C_HALT
);
1224 /* Halt in debug on reset; endreset_event() restores DEMCR.
1226 * REVISIT catching BUSERR presumably helps to defend against
1227 * bad vector table entries. Should this include MMERR or
1231 retval2
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DEMCR
,
1232 TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
1233 if (retval
!= ERROR_OK
|| retval2
!= ERROR_OK
)
1234 LOG_INFO("AP write error, reset will not halt");
1237 if (jtag_reset_config
& RESET_HAS_SRST
) {
1238 /* default to asserting srst */
1240 adapter_assert_reset();
1242 /* srst is asserted, ignore AP access errors */
1245 /* Use a standard Cortex-M3 software reset mechanism.
1246 * We default to using VECTRESET as it is supported on all current cores
1247 * (except Cortex-M0, M0+ and M1 which support SYSRESETREQ only!)
1248 * This has the disadvantage of not resetting the peripherals, so a
1249 * reset-init event handler is needed to perform any peripheral resets.
1251 if (!cortex_m
->vectreset_supported
1252 && reset_config
== CORTEX_M_RESET_VECTRESET
) {
1253 reset_config
= CORTEX_M_RESET_SYSRESETREQ
;
1254 LOG_WARNING("VECTRESET is not supported on this Cortex-M core, using SYSRESETREQ instead.");
1255 LOG_WARNING("Set 'cortex_m reset_config sysresetreq'.");
1258 LOG_DEBUG("Using Cortex-M %s", (reset_config
== CORTEX_M_RESET_SYSRESETREQ
)
1259 ? "SYSRESETREQ" : "VECTRESET");
1261 if (reset_config
== CORTEX_M_RESET_VECTRESET
) {
1262 LOG_WARNING("Only resetting the Cortex-M core, use a reset-init event "
1263 "handler to reset any peripherals or configure hardware srst support.");
1267 retval3
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, NVIC_AIRCR
,
1268 AIRCR_VECTKEY
| ((reset_config
== CORTEX_M_RESET_SYSRESETREQ
)
1269 ? AIRCR_SYSRESETREQ
: AIRCR_VECTRESET
));
1270 if (retval3
!= ERROR_OK
)
1271 LOG_DEBUG("Ignoring AP write error right after reset");
1273 retval3
= dap_dp_init_or_reconnect(armv7m
->debug_ap
->dap
);
1274 if (retval3
!= ERROR_OK
) {
1275 LOG_ERROR("DP initialisation failed");
1276 /* The error return value must not be propagated in this case.
1277 * SYSRESETREQ or VECTRESET have been possibly triggered
1278 * so reset processing should continue */
1280 /* I do not know why this is necessary, but it
1281 * fixes strange effects (step/resume cause NMI
1282 * after reset) on LM3S6918 -- Michael Schwingen
1285 mem_ap_read_atomic_u32(armv7m
->debug_ap
, NVIC_AIRCR
, &tmp
);
1289 target
->state
= TARGET_RESET
;
1292 register_cache_invalidate(cortex_m
->armv7m
.arm
.core_cache
);
1294 /* now return stored error code if any */
1295 if (retval
!= ERROR_OK
)
1298 if (target
->reset_halt
) {
1299 retval
= target_halt(target
);
1300 if (retval
!= ERROR_OK
)
1307 static int cortex_m_deassert_reset(struct target
*target
)
1309 struct armv7m_common
*armv7m
= &target_to_cm(target
)->armv7m
;
1311 LOG_DEBUG("target->state: %s",
1312 target_state_name(target
));
1314 /* deassert reset lines */
1315 adapter_deassert_reset();
1317 enum reset_types jtag_reset_config
= jtag_get_reset_config();
1319 if ((jtag_reset_config
& RESET_HAS_SRST
) &&
1320 !(jtag_reset_config
& RESET_SRST_NO_GATING
) &&
1321 target_was_examined(target
)) {
1323 int retval
= dap_dp_init_or_reconnect(armv7m
->debug_ap
->dap
);
1324 if (retval
!= ERROR_OK
) {
1325 LOG_ERROR("DP initialisation failed");
1333 int cortex_m_set_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1336 unsigned int fp_num
= 0;
1337 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1338 struct cortex_m_fp_comparator
*comparator_list
= cortex_m
->fp_comparator_list
;
1340 if (breakpoint
->set
) {
1341 LOG_WARNING("breakpoint (BPID: %" PRIu32
") already set", breakpoint
->unique_id
);
1345 if (breakpoint
->type
== BKPT_HARD
) {
1346 uint32_t fpcr_value
;
1347 while (comparator_list
[fp_num
].used
&& (fp_num
< cortex_m
->fp_num_code
))
1349 if (fp_num
>= cortex_m
->fp_num_code
) {
1350 LOG_ERROR("Can not find free FPB Comparator!");
1351 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1353 breakpoint
->set
= fp_num
+ 1;
1354 fpcr_value
= breakpoint
->address
| 1;
1355 if (cortex_m
->fp_rev
== 0) {
1356 if (breakpoint
->address
> 0x1FFFFFFF) {
1357 LOG_ERROR("Cortex-M Flash Patch Breakpoint rev.1 cannot handle HW breakpoint above address 0x1FFFFFFE");
1361 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
1362 fpcr_value
= (fpcr_value
& 0x1FFFFFFC) | hilo
| 1;
1363 } else if (cortex_m
->fp_rev
> 1) {
1364 LOG_ERROR("Unhandled Cortex-M Flash Patch Breakpoint architecture revision");
1367 comparator_list
[fp_num
].used
= true;
1368 comparator_list
[fp_num
].fpcr_value
= fpcr_value
;
1369 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
,
1370 comparator_list
[fp_num
].fpcr_value
);
1371 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32
"",
1373 comparator_list
[fp_num
].fpcr_value
);
1374 if (!cortex_m
->fpb_enabled
) {
1375 LOG_DEBUG("FPB wasn't enabled, do it now");
1376 retval
= cortex_m_enable_fpb(target
);
1377 if (retval
!= ERROR_OK
) {
1378 LOG_ERROR("Failed to enable the FPB");
1382 cortex_m
->fpb_enabled
= true;
1384 } else if (breakpoint
->type
== BKPT_SOFT
) {
1387 /* NOTE: on ARMv6-M and ARMv7-M, BKPT(0xab) is used for
1388 * semihosting; don't use that. Otherwise the BKPT
1389 * parameter is arbitrary.
1391 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1392 retval
= target_read_memory(target
,
1393 breakpoint
->address
& 0xFFFFFFFE,
1394 breakpoint
->length
, 1,
1395 breakpoint
->orig_instr
);
1396 if (retval
!= ERROR_OK
)
1398 retval
= target_write_memory(target
,
1399 breakpoint
->address
& 0xFFFFFFFE,
1400 breakpoint
->length
, 1,
1402 if (retval
!= ERROR_OK
)
1404 breakpoint
->set
= true;
1407 LOG_DEBUG("BPID: %" PRIu32
", Type: %d, Address: " TARGET_ADDR_FMT
" Length: %d (set=%d)",
1408 breakpoint
->unique_id
,
1409 (int)(breakpoint
->type
),
1410 breakpoint
->address
,
1417 int cortex_m_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1420 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1421 struct cortex_m_fp_comparator
*comparator_list
= cortex_m
->fp_comparator_list
;
1423 if (breakpoint
->set
<= 0) {
1424 LOG_WARNING("breakpoint not set");
1428 LOG_DEBUG("BPID: %" PRIu32
", Type: %d, Address: " TARGET_ADDR_FMT
" Length: %d (set=%d)",
1429 breakpoint
->unique_id
,
1430 (int)(breakpoint
->type
),
1431 breakpoint
->address
,
1435 if (breakpoint
->type
== BKPT_HARD
) {
1436 unsigned int fp_num
= breakpoint
->set
- 1;
1437 if (fp_num
>= cortex_m
->fp_num_code
) {
1438 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
1441 comparator_list
[fp_num
].used
= false;
1442 comparator_list
[fp_num
].fpcr_value
= 0;
1443 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
,
1444 comparator_list
[fp_num
].fpcr_value
);
1446 /* restore original instruction (kept in target endianness) */
1447 retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE,
1448 breakpoint
->length
, 1,
1449 breakpoint
->orig_instr
);
1450 if (retval
!= ERROR_OK
)
1453 breakpoint
->set
= false;
1458 int cortex_m_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1460 if (breakpoint
->length
== 3) {
1461 LOG_DEBUG("Using a two byte breakpoint for 32bit Thumb-2 request");
1462 breakpoint
->length
= 2;
1465 if ((breakpoint
->length
!= 2)) {
1466 LOG_INFO("only breakpoints of two bytes length supported");
1467 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1470 return cortex_m_set_breakpoint(target
, breakpoint
);
1473 int cortex_m_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1475 if (!breakpoint
->set
)
1478 return cortex_m_unset_breakpoint(target
, breakpoint
);
1481 static int cortex_m_set_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1483 unsigned int dwt_num
= 0;
1484 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1486 /* REVISIT Don't fully trust these "not used" records ... users
1487 * may set up breakpoints by hand, e.g. dual-address data value
1488 * watchpoint using comparator #1; comparator #0 matching cycle
1489 * count; send data trace info through ITM and TPIU; etc
1491 struct cortex_m_dwt_comparator
*comparator
;
1493 for (comparator
= cortex_m
->dwt_comparator_list
;
1494 comparator
->used
&& dwt_num
< cortex_m
->dwt_num_comp
;
1495 comparator
++, dwt_num
++)
1497 if (dwt_num
>= cortex_m
->dwt_num_comp
) {
1498 LOG_ERROR("Can not find free DWT Comparator");
1501 comparator
->used
= true;
1502 watchpoint
->set
= dwt_num
+ 1;
1504 comparator
->comp
= watchpoint
->address
;
1505 target_write_u32(target
, comparator
->dwt_comparator_address
+ 0,
1508 if ((cortex_m
->dwt_devarch
& 0x1FFFFF) != DWT_DEVARCH_ARMV8M
) {
1509 uint32_t mask
= 0, temp
;
1511 /* watchpoint params were validated earlier */
1512 temp
= watchpoint
->length
;
1519 comparator
->mask
= mask
;
1520 target_write_u32(target
, comparator
->dwt_comparator_address
+ 4,
1523 switch (watchpoint
->rw
) {
1525 comparator
->function
= 5;
1528 comparator
->function
= 6;
1531 comparator
->function
= 7;
1535 uint32_t data_size
= watchpoint
->length
>> 1;
1536 comparator
->mask
= (watchpoint
->length
>> 1) | 1;
1538 switch (watchpoint
->rw
) {
1540 comparator
->function
= 4;
1543 comparator
->function
= 5;
1546 comparator
->function
= 6;
1549 comparator
->function
= comparator
->function
| (1 << 4) |
1553 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1554 comparator
->function
);
1556 LOG_DEBUG("Watchpoint (ID %d) DWT%d 0x%08x 0x%x 0x%05x",
1557 watchpoint
->unique_id
, dwt_num
,
1558 (unsigned) comparator
->comp
,
1559 (unsigned) comparator
->mask
,
1560 (unsigned) comparator
->function
);
1564 static int cortex_m_unset_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1566 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1567 struct cortex_m_dwt_comparator
*comparator
;
1569 if (watchpoint
->set
<= 0) {
1570 LOG_WARNING("watchpoint (wpid: %d) not set",
1571 watchpoint
->unique_id
);
1575 unsigned int dwt_num
= watchpoint
->set
- 1;
1577 LOG_DEBUG("Watchpoint (ID %d) DWT%d address: 0x%08x clear",
1578 watchpoint
->unique_id
, dwt_num
,
1579 (unsigned) watchpoint
->address
);
1581 if (dwt_num
>= cortex_m
->dwt_num_comp
) {
1582 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1586 comparator
= cortex_m
->dwt_comparator_list
+ dwt_num
;
1587 comparator
->used
= false;
1588 comparator
->function
= 0;
1589 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1590 comparator
->function
);
1592 watchpoint
->set
= false;
1597 int cortex_m_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1599 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1601 if (cortex_m
->dwt_comp_available
< 1) {
1602 LOG_DEBUG("no comparators?");
1603 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1606 /* hardware doesn't support data value masking */
1607 if (watchpoint
->mask
!= ~(uint32_t)0) {
1608 LOG_DEBUG("watchpoint value masks not supported");
1609 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1612 /* hardware allows address masks of up to 32K */
1615 for (mask
= 0; mask
< 16; mask
++) {
1616 if ((1u << mask
) == watchpoint
->length
)
1620 LOG_DEBUG("unsupported watchpoint length");
1621 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1623 if (watchpoint
->address
& ((1 << mask
) - 1)) {
1624 LOG_DEBUG("watchpoint address is unaligned");
1625 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1628 /* Caller doesn't seem to be able to describe watching for data
1629 * values of zero; that flags "no value".
1631 * REVISIT This DWT may well be able to watch for specific data
1632 * values. Requires comparator #1 to set DATAVMATCH and match
1633 * the data, and another comparator (DATAVADDR0) matching addr.
1635 if (watchpoint
->value
) {
1636 LOG_DEBUG("data value watchpoint not YET supported");
1637 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1640 cortex_m
->dwt_comp_available
--;
1641 LOG_DEBUG("dwt_comp_available: %d", cortex_m
->dwt_comp_available
);
1646 int cortex_m_remove_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1648 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1650 /* REVISIT why check? DWT can be updated with core running ... */
1651 if (target
->state
!= TARGET_HALTED
) {
1652 LOG_WARNING("target not halted");
1653 return ERROR_TARGET_NOT_HALTED
;
1656 if (watchpoint
->set
)
1657 cortex_m_unset_watchpoint(target
, watchpoint
);
1659 cortex_m
->dwt_comp_available
++;
1660 LOG_DEBUG("dwt_comp_available: %d", cortex_m
->dwt_comp_available
);
1665 int cortex_m_hit_watchpoint(struct target
*target
, struct watchpoint
**hit_watchpoint
)
1667 if (target
->debug_reason
!= DBG_REASON_WATCHPOINT
)
1670 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1672 for (struct watchpoint
*wp
= target
->watchpoints
; wp
; wp
= wp
->next
) {
1676 unsigned int dwt_num
= wp
->set
- 1;
1677 struct cortex_m_dwt_comparator
*comparator
= cortex_m
->dwt_comparator_list
+ dwt_num
;
1679 uint32_t dwt_function
;
1680 int retval
= target_read_u32(target
, comparator
->dwt_comparator_address
+ 8, &dwt_function
);
1681 if (retval
!= ERROR_OK
)
1684 /* check the MATCHED bit */
1685 if (dwt_function
& BIT(24)) {
1686 *hit_watchpoint
= wp
;
1694 void cortex_m_enable_watchpoints(struct target
*target
)
1696 struct watchpoint
*watchpoint
= target
->watchpoints
;
1698 /* set any pending watchpoints */
1699 while (watchpoint
) {
1700 if (!watchpoint
->set
)
1701 cortex_m_set_watchpoint(target
, watchpoint
);
1702 watchpoint
= watchpoint
->next
;
1706 static int cortex_m_read_memory(struct target
*target
, target_addr_t address
,
1707 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1709 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1711 if (armv7m
->arm
.arch
== ARM_ARCH_V6M
) {
1712 /* armv6m does not handle unaligned memory access */
1713 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1714 return ERROR_TARGET_UNALIGNED_ACCESS
;
1717 return mem_ap_read_buf(armv7m
->debug_ap
, buffer
, size
, count
, address
);
1720 static int cortex_m_write_memory(struct target
*target
, target_addr_t address
,
1721 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
1723 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1725 if (armv7m
->arm
.arch
== ARM_ARCH_V6M
) {
1726 /* armv6m does not handle unaligned memory access */
1727 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1728 return ERROR_TARGET_UNALIGNED_ACCESS
;
1731 return mem_ap_write_buf(armv7m
->debug_ap
, buffer
, size
, count
, address
);
1734 static int cortex_m_init_target(struct command_context
*cmd_ctx
,
1735 struct target
*target
)
1737 armv7m_build_reg_cache(target
);
1738 arm_semihosting_init(target
);
1742 void cortex_m_deinit_target(struct target
*target
)
1744 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1746 free(cortex_m
->fp_comparator_list
);
1748 cortex_m_dwt_free(target
);
1749 armv7m_free_reg_cache(target
);
1751 free(target
->private_config
);
1755 int cortex_m_profiling(struct target
*target
, uint32_t *samples
,
1756 uint32_t max_num_samples
, uint32_t *num_samples
, uint32_t seconds
)
1758 struct timeval timeout
, now
;
1759 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1763 retval
= target_read_u32(target
, DWT_PCSR
, ®_value
);
1764 if (retval
!= ERROR_OK
) {
1765 LOG_ERROR("Error while reading PCSR");
1768 if (reg_value
== 0) {
1769 LOG_INFO("PCSR sampling not supported on this processor.");
1770 return target_profiling_default(target
, samples
, max_num_samples
, num_samples
, seconds
);
1773 gettimeofday(&timeout
, NULL
);
1774 timeval_add_time(&timeout
, seconds
, 0);
1776 LOG_INFO("Starting Cortex-M profiling. Sampling DWT_PCSR as fast as we can...");
1778 /* Make sure the target is running */
1779 target_poll(target
);
1780 if (target
->state
== TARGET_HALTED
)
1781 retval
= target_resume(target
, 1, 0, 0, 0);
1783 if (retval
!= ERROR_OK
) {
1784 LOG_ERROR("Error while resuming target");
1788 uint32_t sample_count
= 0;
1791 if (armv7m
&& armv7m
->debug_ap
) {
1792 uint32_t read_count
= max_num_samples
- sample_count
;
1793 if (read_count
> 1024)
1796 retval
= mem_ap_read_buf_noincr(armv7m
->debug_ap
,
1797 (void *)&samples
[sample_count
],
1798 4, read_count
, DWT_PCSR
);
1799 sample_count
+= read_count
;
1801 target_read_u32(target
, DWT_PCSR
, &samples
[sample_count
++]);
1804 if (retval
!= ERROR_OK
) {
1805 LOG_ERROR("Error while reading PCSR");
1810 gettimeofday(&now
, NULL
);
1811 if (sample_count
>= max_num_samples
|| timeval_compare(&now
, &timeout
) > 0) {
1812 LOG_INFO("Profiling completed. %" PRIu32
" samples.", sample_count
);
1817 *num_samples
= sample_count
;
1822 /* REVISIT cache valid/dirty bits are unmaintained. We could set "valid"
1823 * on r/w if the core is not running, and clear on resume or reset ... or
1824 * at least, in a post_restore_context() method.
1827 struct dwt_reg_state
{
1828 struct target
*target
;
1830 uint8_t value
[4]; /* scratch/cache */
1833 static int cortex_m_dwt_get_reg(struct reg
*reg
)
1835 struct dwt_reg_state
*state
= reg
->arch_info
;
1838 int retval
= target_read_u32(state
->target
, state
->addr
, &tmp
);
1839 if (retval
!= ERROR_OK
)
1842 buf_set_u32(state
->value
, 0, 32, tmp
);
1846 static int cortex_m_dwt_set_reg(struct reg
*reg
, uint8_t *buf
)
1848 struct dwt_reg_state
*state
= reg
->arch_info
;
1850 return target_write_u32(state
->target
, state
->addr
,
1851 buf_get_u32(buf
, 0, reg
->size
));
1860 static const struct dwt_reg dwt_base_regs
[] = {
1861 { DWT_CTRL
, "dwt_ctrl", 32, },
1862 /* NOTE that Erratum 532314 (fixed r2p0) affects CYCCNT: it wrongly
1863 * increments while the core is asleep.
1865 { DWT_CYCCNT
, "dwt_cyccnt", 32, },
1866 /* plus some 8 bit counters, useful for profiling with TPIU */
1869 static const struct dwt_reg dwt_comp
[] = {
1870 #define DWT_COMPARATOR(i) \
1871 { DWT_COMP0 + 0x10 * (i), "dwt_" #i "_comp", 32, }, \
1872 { DWT_MASK0 + 0x10 * (i), "dwt_" #i "_mask", 4, }, \
1873 { DWT_FUNCTION0 + 0x10 * (i), "dwt_" #i "_function", 32, }
1890 #undef DWT_COMPARATOR
1893 static const struct reg_arch_type dwt_reg_type
= {
1894 .get
= cortex_m_dwt_get_reg
,
1895 .set
= cortex_m_dwt_set_reg
,
1898 static void cortex_m_dwt_addreg(struct target
*t
, struct reg
*r
, const struct dwt_reg
*d
)
1900 struct dwt_reg_state
*state
;
1902 state
= calloc(1, sizeof(*state
));
1905 state
->addr
= d
->addr
;
1910 r
->value
= state
->value
;
1911 r
->arch_info
= state
;
1912 r
->type
= &dwt_reg_type
;
1915 static void cortex_m_dwt_setup(struct cortex_m_common
*cm
, struct target
*target
)
1918 struct reg_cache
*cache
;
1919 struct cortex_m_dwt_comparator
*comparator
;
1922 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1923 LOG_DEBUG("DWT_CTRL: 0x%" PRIx32
, dwtcr
);
1925 LOG_DEBUG("no DWT");
1929 target_read_u32(target
, DWT_DEVARCH
, &cm
->dwt_devarch
);
1930 LOG_DEBUG("DWT_DEVARCH: 0x%" PRIx32
, cm
->dwt_devarch
);
1932 cm
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1933 cm
->dwt_comp_available
= cm
->dwt_num_comp
;
1934 cm
->dwt_comparator_list
= calloc(cm
->dwt_num_comp
,
1935 sizeof(struct cortex_m_dwt_comparator
));
1936 if (!cm
->dwt_comparator_list
) {
1938 cm
->dwt_num_comp
= 0;
1939 LOG_ERROR("out of mem");
1943 cache
= calloc(1, sizeof(*cache
));
1946 free(cm
->dwt_comparator_list
);
1949 cache
->name
= "Cortex-M DWT registers";
1950 cache
->num_regs
= 2 + cm
->dwt_num_comp
* 3;
1951 cache
->reg_list
= calloc(cache
->num_regs
, sizeof(*cache
->reg_list
));
1952 if (!cache
->reg_list
) {
1957 for (reg
= 0; reg
< 2; reg
++)
1958 cortex_m_dwt_addreg(target
, cache
->reg_list
+ reg
,
1959 dwt_base_regs
+ reg
);
1961 comparator
= cm
->dwt_comparator_list
;
1962 for (unsigned int i
= 0; i
< cm
->dwt_num_comp
; i
++, comparator
++) {
1965 comparator
->dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1966 for (j
= 0; j
< 3; j
++, reg
++)
1967 cortex_m_dwt_addreg(target
, cache
->reg_list
+ reg
,
1968 dwt_comp
+ 3 * i
+ j
);
1970 /* make sure we clear any watchpoints enabled on the target */
1971 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8, 0);
1974 *register_get_last_cache_p(&target
->reg_cache
) = cache
;
1975 cm
->dwt_cache
= cache
;
1977 LOG_DEBUG("DWT dwtcr 0x%" PRIx32
", comp %d, watch%s",
1978 dwtcr
, cm
->dwt_num_comp
,
1979 (dwtcr
& (0xf << 24)) ? " only" : "/trigger");
1981 /* REVISIT: if num_comp > 1, check whether comparator #1 can
1982 * implement single-address data value watchpoints ... so we
1983 * won't need to check it later, when asked to set one up.
1987 static void cortex_m_dwt_free(struct target
*target
)
1989 struct cortex_m_common
*cm
= target_to_cm(target
);
1990 struct reg_cache
*cache
= cm
->dwt_cache
;
1992 free(cm
->dwt_comparator_list
);
1993 cm
->dwt_comparator_list
= NULL
;
1994 cm
->dwt_num_comp
= 0;
1997 register_unlink_cache(&target
->reg_cache
, cache
);
1999 if (cache
->reg_list
) {
2000 for (size_t i
= 0; i
< cache
->num_regs
; i
++)
2001 free(cache
->reg_list
[i
].arch_info
);
2002 free(cache
->reg_list
);
2006 cm
->dwt_cache
= NULL
;
2009 #define MVFR0 0xe000ef40
2010 #define MVFR1 0xe000ef44
2012 #define MVFR0_DEFAULT_M4 0x10110021
2013 #define MVFR1_DEFAULT_M4 0x11000011
2015 #define MVFR0_DEFAULT_M7_SP 0x10110021
2016 #define MVFR0_DEFAULT_M7_DP 0x10110221
2017 #define MVFR1_DEFAULT_M7_SP 0x11000011
2018 #define MVFR1_DEFAULT_M7_DP 0x12000011
2020 static int cortex_m_find_mem_ap(struct adiv5_dap
*swjdp
,
2021 struct adiv5_ap
**debug_ap
)
2023 if (dap_find_ap(swjdp
, AP_TYPE_AHB3_AP
, debug_ap
) == ERROR_OK
)
2026 return dap_find_ap(swjdp
, AP_TYPE_AHB5_AP
, debug_ap
);
2029 int cortex_m_examine(struct target
*target
)
2032 uint32_t cpuid
, fpcr
, mvfr0
, mvfr1
;
2033 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
2034 struct adiv5_dap
*swjdp
= cortex_m
->armv7m
.arm
.dap
;
2035 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
2037 /* hla_target shares the examine handler but does not support
2039 if (!armv7m
->is_hla_target
) {
2040 if (cortex_m
->apsel
== DP_APSEL_INVALID
) {
2041 /* Search for the MEM-AP */
2042 retval
= cortex_m_find_mem_ap(swjdp
, &armv7m
->debug_ap
);
2043 if (retval
!= ERROR_OK
) {
2044 LOG_ERROR("Could not find MEM-AP to control the core");
2048 armv7m
->debug_ap
= dap_ap(swjdp
, cortex_m
->apsel
);
2051 /* Leave (only) generic DAP stuff for debugport_init(); */
2052 armv7m
->debug_ap
->memaccess_tck
= 8;
2054 retval
= mem_ap_init(armv7m
->debug_ap
);
2055 if (retval
!= ERROR_OK
)
2059 if (!target_was_examined(target
)) {
2060 target_set_examined(target
);
2062 /* Read from Device Identification Registers */
2063 retval
= target_read_u32(target
, CPUID
, &cpuid
);
2064 if (retval
!= ERROR_OK
)
2067 /* Get ARCH and CPU types */
2068 const enum cortex_m_partno core_partno
= (cpuid
& ARM_CPUID_PARTNO_MASK
) >> ARM_CPUID_PARTNO_POS
;
2070 for (unsigned int n
= 0; n
< ARRAY_SIZE(cortex_m_parts
); n
++) {
2071 if (core_partno
== cortex_m_parts
[n
].partno
) {
2072 cortex_m
->core_info
= &cortex_m_parts
[n
];
2077 if (!cortex_m
->core_info
) {
2078 LOG_ERROR("Cortex-M PARTNO 0x%x is unrecognized", core_partno
);
2082 armv7m
->arm
.arch
= cortex_m
->core_info
->arch
;
2084 LOG_DEBUG("%s r%" PRId8
"p%" PRId8
" processor detected",
2085 cortex_m
->core_info
->name
, (uint8_t)((cpuid
>> 20) & 0xf), (uint8_t)((cpuid
>> 0) & 0xf));
2086 cortex_m
->maskints_erratum
= false;
2087 if (core_partno
== CORTEX_M7_PARTNO
) {
2089 rev
= (cpuid
>> 20) & 0xf;
2090 patch
= (cpuid
>> 0) & 0xf;
2091 if ((rev
== 0) && (patch
< 2)) {
2092 LOG_WARNING("Silicon bug: single stepping may enter pending exception handler!");
2093 cortex_m
->maskints_erratum
= true;
2096 LOG_DEBUG("cpuid: 0x%8.8" PRIx32
"", cpuid
);
2098 if (cortex_m
->core_info
->flags
& CORTEX_M_F_HAS_FPV4
) {
2099 target_read_u32(target
, MVFR0
, &mvfr0
);
2100 target_read_u32(target
, MVFR1
, &mvfr1
);
2102 /* test for floating point feature on Cortex-M4 */
2103 if ((mvfr0
== MVFR0_DEFAULT_M4
) && (mvfr1
== MVFR1_DEFAULT_M4
)) {
2104 LOG_DEBUG("%s floating point feature FPv4_SP found", cortex_m
->core_info
->name
);
2105 armv7m
->fp_feature
= FPV4_SP
;
2107 } else if (cortex_m
->core_info
->flags
& CORTEX_M_F_HAS_FPV5
) {
2108 target_read_u32(target
, MVFR0
, &mvfr0
);
2109 target_read_u32(target
, MVFR1
, &mvfr1
);
2111 /* test for floating point features on Cortex-M7 */
2112 if ((mvfr0
== MVFR0_DEFAULT_M7_SP
) && (mvfr1
== MVFR1_DEFAULT_M7_SP
)) {
2113 LOG_DEBUG("%s floating point feature FPv5_SP found", cortex_m
->core_info
->name
);
2114 armv7m
->fp_feature
= FPV5_SP
;
2115 } else if ((mvfr0
== MVFR0_DEFAULT_M7_DP
) && (mvfr1
== MVFR1_DEFAULT_M7_DP
)) {
2116 LOG_DEBUG("%s floating point feature FPv5_DP found", cortex_m
->core_info
->name
);
2117 armv7m
->fp_feature
= FPV5_DP
;
2121 /* VECTRESET is supported only on ARMv7-M cores */
2122 cortex_m
->vectreset_supported
= armv7m
->arm
.arch
== ARM_ARCH_V7M
;
2124 /* Check for FPU, otherwise mark FPU register as non-existent */
2125 if (armv7m
->fp_feature
== FP_NONE
)
2126 for (size_t idx
= ARMV7M_FPU_FIRST_REG
; idx
<= ARMV7M_FPU_LAST_REG
; idx
++)
2127 armv7m
->arm
.core_cache
->reg_list
[idx
].exist
= false;
2129 if (armv7m
->arm
.arch
!= ARM_ARCH_V8M
)
2130 for (size_t idx
= ARMV8M_FIRST_REG
; idx
<= ARMV8M_LAST_REG
; idx
++)
2131 armv7m
->arm
.core_cache
->reg_list
[idx
].exist
= false;
2133 if (!armv7m
->is_hla_target
) {
2134 if (cortex_m
->core_info
->flags
& CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K
)
2135 /* Cortex-M3/M4 have 4096 bytes autoincrement range,
2136 * s. ARM IHI 0031C: MEM-AP 7.2.2 */
2137 armv7m
->debug_ap
->tar_autoincr_block
= (1 << 12);
2140 /* Enable debug requests */
2141 retval
= target_read_u32(target
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
2142 if (retval
!= ERROR_OK
)
2144 if (!(cortex_m
->dcb_dhcsr
& C_DEBUGEN
)) {
2145 uint32_t dhcsr
= (cortex_m
->dcb_dhcsr
| C_DEBUGEN
) & ~(C_HALT
| C_STEP
| C_MASKINTS
);
2147 retval
= target_write_u32(target
, DCB_DHCSR
, DBGKEY
| (dhcsr
& 0x0000FFFFUL
));
2148 if (retval
!= ERROR_OK
)
2150 cortex_m
->dcb_dhcsr
= dhcsr
;
2153 /* Configure trace modules */
2154 retval
= target_write_u32(target
, DCB_DEMCR
, TRCENA
| armv7m
->demcr
);
2155 if (retval
!= ERROR_OK
)
2158 if (armv7m
->trace_config
.itm_deferred_config
)
2159 armv7m_trace_itm_config(target
);
2161 /* NOTE: FPB and DWT are both optional. */
2164 target_read_u32(target
, FP_CTRL
, &fpcr
);
2165 /* bits [14:12] and [7:4] */
2166 cortex_m
->fp_num_code
= ((fpcr
>> 8) & 0x70) | ((fpcr
>> 4) & 0xF);
2167 cortex_m
->fp_num_lit
= (fpcr
>> 8) & 0xF;
2168 /* Detect flash patch revision, see RM DDI 0403E.b page C1-817.
2169 Revision is zero base, fp_rev == 1 means Rev.2 ! */
2170 cortex_m
->fp_rev
= (fpcr
>> 28) & 0xf;
2171 free(cortex_m
->fp_comparator_list
);
2172 cortex_m
->fp_comparator_list
= calloc(
2173 cortex_m
->fp_num_code
+ cortex_m
->fp_num_lit
,
2174 sizeof(struct cortex_m_fp_comparator
));
2175 cortex_m
->fpb_enabled
= fpcr
& 1;
2176 for (unsigned int i
= 0; i
< cortex_m
->fp_num_code
+ cortex_m
->fp_num_lit
; i
++) {
2177 cortex_m
->fp_comparator_list
[i
].type
=
2178 (i
< cortex_m
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
2179 cortex_m
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
2181 /* make sure we clear any breakpoints enabled on the target */
2182 target_write_u32(target
, cortex_m
->fp_comparator_list
[i
].fpcr_address
, 0);
2184 LOG_DEBUG("FPB fpcr 0x%" PRIx32
", numcode %i, numlit %i",
2186 cortex_m
->fp_num_code
,
2187 cortex_m
->fp_num_lit
);
2190 cortex_m_dwt_free(target
);
2191 cortex_m_dwt_setup(cortex_m
, target
);
2193 /* These hardware breakpoints only work for code in flash! */
2194 LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints",
2195 target_name(target
),
2196 cortex_m
->fp_num_code
,
2197 cortex_m
->dwt_num_comp
);
2203 static int cortex_m_dcc_read(struct target
*target
, uint8_t *value
, uint8_t *ctrl
)
2205 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
2210 retval
= mem_ap_read_buf_noincr(armv7m
->debug_ap
, buf
, 2, 1, DCB_DCRDR
);
2211 if (retval
!= ERROR_OK
)
2214 dcrdr
= target_buffer_get_u16(target
, buf
);
2215 *ctrl
= (uint8_t)dcrdr
;
2216 *value
= (uint8_t)(dcrdr
>> 8);
2218 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
2220 /* write ack back to software dcc register
2221 * signify we have read data */
2222 if (dcrdr
& (1 << 0)) {
2223 target_buffer_set_u16(target
, buf
, 0);
2224 retval
= mem_ap_write_buf_noincr(armv7m
->debug_ap
, buf
, 2, 1, DCB_DCRDR
);
2225 if (retval
!= ERROR_OK
)
2232 static int cortex_m_target_request_data(struct target
*target
,
2233 uint32_t size
, uint8_t *buffer
)
2239 for (i
= 0; i
< (size
* 4); i
++) {
2240 int retval
= cortex_m_dcc_read(target
, &data
, &ctrl
);
2241 if (retval
!= ERROR_OK
)
2249 static int cortex_m_handle_target_request(void *priv
)
2251 struct target
*target
= priv
;
2252 if (!target_was_examined(target
))
2255 if (!target
->dbg_msg_enabled
)
2258 if (target
->state
== TARGET_RUNNING
) {
2263 retval
= cortex_m_dcc_read(target
, &data
, &ctrl
);
2264 if (retval
!= ERROR_OK
)
2267 /* check if we have data */
2268 if (ctrl
& (1 << 0)) {
2271 /* we assume target is quick enough */
2273 for (int i
= 1; i
<= 3; i
++) {
2274 retval
= cortex_m_dcc_read(target
, &data
, &ctrl
);
2275 if (retval
!= ERROR_OK
)
2277 request
|= ((uint32_t)data
<< (i
* 8));
2279 target_request(target
, request
);
2286 static int cortex_m_init_arch_info(struct target
*target
,
2287 struct cortex_m_common
*cortex_m
, struct adiv5_dap
*dap
)
2289 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
2291 armv7m_init_arch_info(target
, armv7m
);
2293 /* default reset mode is to use srst if fitted
2294 * if not it will use CORTEX_M3_RESET_VECTRESET */
2295 cortex_m
->soft_reset_config
= CORTEX_M_RESET_VECTRESET
;
2297 armv7m
->arm
.dap
= dap
;
2299 /* register arch-specific functions */
2300 armv7m
->examine_debug_reason
= cortex_m_examine_debug_reason
;
2302 armv7m
->post_debug_entry
= NULL
;
2304 armv7m
->pre_restore_context
= NULL
;
2306 armv7m
->load_core_reg_u32
= cortex_m_load_core_reg_u32
;
2307 armv7m
->store_core_reg_u32
= cortex_m_store_core_reg_u32
;
2309 target_register_timer_callback(cortex_m_handle_target_request
, 1,
2310 TARGET_TIMER_TYPE_PERIODIC
, target
);
2315 static int cortex_m_target_create(struct target
*target
, Jim_Interp
*interp
)
2317 struct adiv5_private_config
*pc
;
2319 pc
= (struct adiv5_private_config
*)target
->private_config
;
2320 if (adiv5_verify_config(pc
) != ERROR_OK
)
2323 struct cortex_m_common
*cortex_m
= calloc(1, sizeof(struct cortex_m_common
));
2325 LOG_ERROR("No memory creating target");
2329 cortex_m
->common_magic
= CORTEX_M_COMMON_MAGIC
;
2330 cortex_m
->apsel
= pc
->ap_num
;
2332 cortex_m_init_arch_info(target
, cortex_m
, pc
->dap
);
2337 /*--------------------------------------------------------------------------*/
2339 static int cortex_m_verify_pointer(struct command_invocation
*cmd
,
2340 struct cortex_m_common
*cm
)
2342 if (cm
->common_magic
!= CORTEX_M_COMMON_MAGIC
) {
2343 command_print(cmd
, "target is not a Cortex-M");
2344 return ERROR_TARGET_INVALID
;
2350 * Only stuff below this line should need to verify that its target
2351 * is a Cortex-M3. Everything else should have indirected through the
2352 * cortexm3_target structure, which is only used with CM3 targets.
2355 COMMAND_HANDLER(handle_cortex_m_vector_catch_command
)
2357 struct target
*target
= get_current_target(CMD_CTX
);
2358 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
2359 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
2363 static const struct {
2367 { "hard_err", VC_HARDERR
, },
2368 { "int_err", VC_INTERR
, },
2369 { "bus_err", VC_BUSERR
, },
2370 { "state_err", VC_STATERR
, },
2371 { "chk_err", VC_CHKERR
, },
2372 { "nocp_err", VC_NOCPERR
, },
2373 { "mm_err", VC_MMERR
, },
2374 { "reset", VC_CORERESET
, },
2377 retval
= cortex_m_verify_pointer(CMD
, cortex_m
);
2378 if (retval
!= ERROR_OK
)
2381 if (!target_was_examined(target
)) {
2382 LOG_ERROR("Target not examined yet");
2386 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DEMCR
, &demcr
);
2387 if (retval
!= ERROR_OK
)
2393 if (CMD_ARGC
== 1) {
2394 if (strcmp(CMD_ARGV
[0], "all") == 0) {
2395 catch = VC_HARDERR
| VC_INTERR
| VC_BUSERR
2396 | VC_STATERR
| VC_CHKERR
| VC_NOCPERR
2397 | VC_MMERR
| VC_CORERESET
;
2399 } else if (strcmp(CMD_ARGV
[0], "none") == 0)
2402 while (CMD_ARGC
-- > 0) {
2404 for (i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++) {
2405 if (strcmp(CMD_ARGV
[CMD_ARGC
], vec_ids
[i
].name
) != 0)
2407 catch |= vec_ids
[i
].mask
;
2410 if (i
== ARRAY_SIZE(vec_ids
)) {
2411 LOG_ERROR("No CM3 vector '%s'", CMD_ARGV
[CMD_ARGC
]);
2412 return ERROR_COMMAND_SYNTAX_ERROR
;
2416 /* For now, armv7m->demcr only stores vector catch flags. */
2417 armv7m
->demcr
= catch;
2422 /* write, but don't assume it stuck (why not??) */
2423 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DEMCR
, demcr
);
2424 if (retval
!= ERROR_OK
)
2426 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DEMCR
, &demcr
);
2427 if (retval
!= ERROR_OK
)
2430 /* FIXME be sure to clear DEMCR on clean server shutdown.
2431 * Otherwise the vector catch hardware could fire when there's
2432 * no debugger hooked up, causing much confusion...
2436 for (unsigned i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++) {
2437 command_print(CMD
, "%9s: %s", vec_ids
[i
].name
,
2438 (demcr
& vec_ids
[i
].mask
) ? "catch" : "ignore");
2444 COMMAND_HANDLER(handle_cortex_m_mask_interrupts_command
)
2446 struct target
*target
= get_current_target(CMD_CTX
);
2447 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
2450 static const struct jim_nvp nvp_maskisr_modes
[] = {
2451 { .name
= "auto", .value
= CORTEX_M_ISRMASK_AUTO
},
2452 { .name
= "off", .value
= CORTEX_M_ISRMASK_OFF
},
2453 { .name
= "on", .value
= CORTEX_M_ISRMASK_ON
},
2454 { .name
= "steponly", .value
= CORTEX_M_ISRMASK_STEPONLY
},
2455 { .name
= NULL
, .value
= -1 },
2457 const struct jim_nvp
*n
;
2460 retval
= cortex_m_verify_pointer(CMD
, cortex_m
);
2461 if (retval
!= ERROR_OK
)
2464 if (target
->state
!= TARGET_HALTED
) {
2465 command_print(CMD
, "target must be stopped for \"%s\" command", CMD_NAME
);
2470 n
= jim_nvp_name2value_simple(nvp_maskisr_modes
, CMD_ARGV
[0]);
2472 return ERROR_COMMAND_SYNTAX_ERROR
;
2473 cortex_m
->isrmasking_mode
= n
->value
;
2474 cortex_m_set_maskints_for_halt(target
);
2477 n
= jim_nvp_value2name_simple(nvp_maskisr_modes
, cortex_m
->isrmasking_mode
);
2478 command_print(CMD
, "cortex_m interrupt mask %s", n
->name
);
2483 COMMAND_HANDLER(handle_cortex_m_reset_config_command
)
2485 struct target
*target
= get_current_target(CMD_CTX
);
2486 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
2490 retval
= cortex_m_verify_pointer(CMD
, cortex_m
);
2491 if (retval
!= ERROR_OK
)
2495 if (strcmp(*CMD_ARGV
, "sysresetreq") == 0)
2496 cortex_m
->soft_reset_config
= CORTEX_M_RESET_SYSRESETREQ
;
2498 else if (strcmp(*CMD_ARGV
, "vectreset") == 0) {
2499 if (target_was_examined(target
)
2500 && !cortex_m
->vectreset_supported
)
2501 LOG_WARNING("VECTRESET is not supported on your Cortex-M core!");
2503 cortex_m
->soft_reset_config
= CORTEX_M_RESET_VECTRESET
;
2506 return ERROR_COMMAND_SYNTAX_ERROR
;
2509 switch (cortex_m
->soft_reset_config
) {
2510 case CORTEX_M_RESET_SYSRESETREQ
:
2511 reset_config
= "sysresetreq";
2514 case CORTEX_M_RESET_VECTRESET
:
2515 reset_config
= "vectreset";
2519 reset_config
= "unknown";
2523 command_print(CMD
, "cortex_m reset_config %s", reset_config
);
2528 static const struct command_registration cortex_m_exec_command_handlers
[] = {
2531 .handler
= handle_cortex_m_mask_interrupts_command
,
2532 .mode
= COMMAND_EXEC
,
2533 .help
= "mask cortex_m interrupts",
2534 .usage
= "['auto'|'on'|'off'|'steponly']",
2537 .name
= "vector_catch",
2538 .handler
= handle_cortex_m_vector_catch_command
,
2539 .mode
= COMMAND_EXEC
,
2540 .help
= "configure hardware vectors to trigger debug entry",
2541 .usage
= "['all'|'none'|('bus_err'|'chk_err'|...)*]",
2544 .name
= "reset_config",
2545 .handler
= handle_cortex_m_reset_config_command
,
2546 .mode
= COMMAND_ANY
,
2547 .help
= "configure software reset handling",
2548 .usage
= "['sysresetreq'|'vectreset']",
2550 COMMAND_REGISTRATION_DONE
2552 static const struct command_registration cortex_m_command_handlers
[] = {
2554 .chain
= armv7m_command_handlers
,
2557 .chain
= armv7m_trace_command_handlers
,
2559 /* START_DEPRECATED_TPIU */
2561 .chain
= arm_tpiu_deprecated_command_handlers
,
2563 /* END_DEPRECATED_TPIU */
2566 .mode
= COMMAND_EXEC
,
2567 .help
= "Cortex-M command group",
2569 .chain
= cortex_m_exec_command_handlers
,
2572 .chain
= rtt_target_command_handlers
,
2574 COMMAND_REGISTRATION_DONE
2577 struct target_type cortexm_target
= {
2580 .poll
= cortex_m_poll
,
2581 .arch_state
= armv7m_arch_state
,
2583 .target_request_data
= cortex_m_target_request_data
,
2585 .halt
= cortex_m_halt
,
2586 .resume
= cortex_m_resume
,
2587 .step
= cortex_m_step
,
2589 .assert_reset
= cortex_m_assert_reset
,
2590 .deassert_reset
= cortex_m_deassert_reset
,
2591 .soft_reset_halt
= cortex_m_soft_reset_halt
,
2593 .get_gdb_arch
= arm_get_gdb_arch
,
2594 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
2596 .read_memory
= cortex_m_read_memory
,
2597 .write_memory
= cortex_m_write_memory
,
2598 .checksum_memory
= armv7m_checksum_memory
,
2599 .blank_check_memory
= armv7m_blank_check_memory
,
2601 .run_algorithm
= armv7m_run_algorithm
,
2602 .start_algorithm
= armv7m_start_algorithm
,
2603 .wait_algorithm
= armv7m_wait_algorithm
,
2605 .add_breakpoint
= cortex_m_add_breakpoint
,
2606 .remove_breakpoint
= cortex_m_remove_breakpoint
,
2607 .add_watchpoint
= cortex_m_add_watchpoint
,
2608 .remove_watchpoint
= cortex_m_remove_watchpoint
,
2609 .hit_watchpoint
= cortex_m_hit_watchpoint
,
2611 .commands
= cortex_m_command_handlers
,
2612 .target_create
= cortex_m_target_create
,
2613 .target_jim_configure
= adiv5_jim_configure
,
2614 .init_target
= cortex_m_init_target
,
2615 .examine
= cortex_m_examine
,
2616 .deinit_target
= cortex_m_deinit_target
,
2618 .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)