1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2006 by Magnus Lundin *
8 * Copyright (C) 2008 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
25 * Cortex-M3(tm) TRM, ARM DDI 0337E (r1p1) and 0337G (r2p0) *
27 ***************************************************************************/
32 #include "jtag/interface.h"
33 #include "breakpoints.h"
35 #include "target_request.h"
36 #include "target_type.h"
37 #include "arm_adi_v5.h"
38 #include "arm_disassembler.h"
40 #include "arm_opcodes.h"
41 #include "arm_semihosting.h"
42 #include <helper/time_support.h>
45 /* NOTE: most of this should work fine for the Cortex-M1 and
46 * Cortex-M0 cores too, although they're ARMv6-M not ARMv7-M.
47 * Some differences: M0/M1 doesn't have FPB remapping or the
48 * DWT tracing/profiling support. (So the cycle counter will
49 * not be usable; the other stuff isn't currently used here.)
51 * Although there are some workarounds for errata seen only in r0p0
52 * silicon, such old parts are hard to find and thus not much tested
56 /* Supported Cortex-M Cores */
57 static const struct cortex_m_part_info cortex_m_parts
[] = {
59 .partno
= CORTEX_M0_PARTNO
,
64 .partno
= CORTEX_M0P_PARTNO
,
69 .partno
= CORTEX_M1_PARTNO
,
74 .partno
= CORTEX_M3_PARTNO
,
77 .flags
= CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K
,
80 .partno
= CORTEX_M4_PARTNO
,
83 .flags
= CORTEX_M_F_HAS_FPV4
| CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K
,
86 .partno
= CORTEX_M7_PARTNO
,
89 .flags
= CORTEX_M_F_HAS_FPV5
,
92 .partno
= CORTEX_M23_PARTNO
,
97 .partno
= CORTEX_M33_PARTNO
,
100 .flags
= CORTEX_M_F_HAS_FPV5
,
103 .partno
= CORTEX_M35P_PARTNO
,
104 .name
= "Cortex-M35P",
105 .arch
= ARM_ARCH_V8M
,
106 .flags
= CORTEX_M_F_HAS_FPV5
,
109 .partno
= CORTEX_M55_PARTNO
,
110 .name
= "Cortex-M55",
111 .arch
= ARM_ARCH_V8M
,
112 .flags
= CORTEX_M_F_HAS_FPV5
,
116 /* forward declarations */
117 static int cortex_m_store_core_reg_u32(struct target
*target
,
118 uint32_t num
, uint32_t value
);
119 static void cortex_m_dwt_free(struct target
*target
);
121 static int cortex_m_load_core_reg_u32(struct target
*target
,
122 uint32_t regsel
, uint32_t *value
)
124 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
128 /* because the DCB_DCRDR is used for the emulated dcc channel
129 * we have to save/restore the DCB_DCRDR when used */
130 if (target
->dbg_msg_enabled
) {
131 retval
= mem_ap_read_u32(armv7m
->debug_ap
, DCB_DCRDR
, &dcrdr
);
132 if (retval
!= ERROR_OK
)
136 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DCRSR
, regsel
);
137 if (retval
!= ERROR_OK
)
140 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DCRDR
, value
);
141 if (retval
!= ERROR_OK
)
144 if (target
->dbg_msg_enabled
) {
145 /* restore DCB_DCRDR - this needs to be in a separate
146 * transaction otherwise the emulated DCC channel breaks */
147 if (retval
== ERROR_OK
)
148 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DCRDR
, dcrdr
);
154 static int cortex_m_store_core_reg_u32(struct target
*target
,
155 uint32_t regsel
, uint32_t value
)
157 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
161 /* because the DCB_DCRDR is used for the emulated dcc channel
162 * we have to save/restore the DCB_DCRDR when used */
163 if (target
->dbg_msg_enabled
) {
164 retval
= mem_ap_read_u32(armv7m
->debug_ap
, DCB_DCRDR
, &dcrdr
);
165 if (retval
!= ERROR_OK
)
169 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DCRDR
, value
);
170 if (retval
!= ERROR_OK
)
173 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DCRSR
, regsel
| DCRSR_WNR
);
174 if (retval
!= ERROR_OK
)
177 if (target
->dbg_msg_enabled
) {
178 /* restore DCB_DCRDR - this needs to be in a separate
179 * transaction otherwise the emulated DCC channel breaks */
180 if (retval
== ERROR_OK
)
181 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DCRDR
, dcrdr
);
187 static int cortex_m_write_debug_halt_mask(struct target
*target
,
188 uint32_t mask_on
, uint32_t mask_off
)
190 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
191 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
193 /* mask off status bits */
194 cortex_m
->dcb_dhcsr
&= ~((0xFFFFul
<< 16) | mask_off
);
195 /* create new register mask */
196 cortex_m
->dcb_dhcsr
|= DBGKEY
| C_DEBUGEN
| mask_on
;
198 return mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, cortex_m
->dcb_dhcsr
);
201 static int cortex_m_set_maskints(struct target
*target
, bool mask
)
203 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
204 if (!!(cortex_m
->dcb_dhcsr
& C_MASKINTS
) != mask
)
205 return cortex_m_write_debug_halt_mask(target
, mask
? C_MASKINTS
: 0, mask
? 0 : C_MASKINTS
);
210 static int cortex_m_set_maskints_for_halt(struct target
*target
)
212 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
213 switch (cortex_m
->isrmasking_mode
) {
214 case CORTEX_M_ISRMASK_AUTO
:
215 /* interrupts taken at resume, whether for step or run -> no mask */
216 return cortex_m_set_maskints(target
, false);
218 case CORTEX_M_ISRMASK_OFF
:
219 /* interrupts never masked */
220 return cortex_m_set_maskints(target
, false);
222 case CORTEX_M_ISRMASK_ON
:
223 /* interrupts always masked */
224 return cortex_m_set_maskints(target
, true);
226 case CORTEX_M_ISRMASK_STEPONLY
:
227 /* interrupts masked for single step only -> mask now if MASKINTS
228 * erratum, otherwise only mask before stepping */
229 return cortex_m_set_maskints(target
, cortex_m
->maskints_erratum
);
234 static int cortex_m_set_maskints_for_run(struct target
*target
)
236 switch (target_to_cm(target
)->isrmasking_mode
) {
237 case CORTEX_M_ISRMASK_AUTO
:
238 /* interrupts taken at resume, whether for step or run -> no mask */
239 return cortex_m_set_maskints(target
, false);
241 case CORTEX_M_ISRMASK_OFF
:
242 /* interrupts never masked */
243 return cortex_m_set_maskints(target
, false);
245 case CORTEX_M_ISRMASK_ON
:
246 /* interrupts always masked */
247 return cortex_m_set_maskints(target
, true);
249 case CORTEX_M_ISRMASK_STEPONLY
:
250 /* interrupts masked for single step only -> no mask */
251 return cortex_m_set_maskints(target
, false);
256 static int cortex_m_set_maskints_for_step(struct target
*target
)
258 switch (target_to_cm(target
)->isrmasking_mode
) {
259 case CORTEX_M_ISRMASK_AUTO
:
260 /* the auto-interrupt should already be done -> mask */
261 return cortex_m_set_maskints(target
, true);
263 case CORTEX_M_ISRMASK_OFF
:
264 /* interrupts never masked */
265 return cortex_m_set_maskints(target
, false);
267 case CORTEX_M_ISRMASK_ON
:
268 /* interrupts always masked */
269 return cortex_m_set_maskints(target
, true);
271 case CORTEX_M_ISRMASK_STEPONLY
:
272 /* interrupts masked for single step only -> mask */
273 return cortex_m_set_maskints(target
, true);
278 static int cortex_m_clear_halt(struct target
*target
)
280 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
281 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
284 /* clear step if any */
285 cortex_m_write_debug_halt_mask(target
, C_HALT
, C_STEP
);
287 /* Read Debug Fault Status Register */
288 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, NVIC_DFSR
, &cortex_m
->nvic_dfsr
);
289 if (retval
!= ERROR_OK
)
292 /* Clear Debug Fault Status */
293 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, NVIC_DFSR
, cortex_m
->nvic_dfsr
);
294 if (retval
!= ERROR_OK
)
296 LOG_DEBUG(" NVIC_DFSR 0x%" PRIx32
"", cortex_m
->nvic_dfsr
);
301 static int cortex_m_single_step_core(struct target
*target
)
303 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
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
= cortex_m_write_debug_halt_mask(target
, C_MASKINTS
, 0);
312 if (retval
!= ERROR_OK
)
315 retval
= cortex_m_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
316 if (retval
!= ERROR_OK
)
320 /* restore dhcsr reg */
321 cortex_m_clear_halt(target
);
326 static int cortex_m_enable_fpb(struct target
*target
)
328 int retval
= target_write_u32(target
, FP_CTRL
, 3);
329 if (retval
!= ERROR_OK
)
332 /* check the fpb is actually enabled */
334 retval
= target_read_u32(target
, FP_CTRL
, &fpctrl
);
335 if (retval
!= ERROR_OK
)
344 static int cortex_m_endreset_event(struct target
*target
)
348 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
349 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
350 struct adiv5_dap
*swjdp
= cortex_m
->armv7m
.arm
.dap
;
351 struct cortex_m_fp_comparator
*fp_list
= cortex_m
->fp_comparator_list
;
352 struct cortex_m_dwt_comparator
*dwt_list
= cortex_m
->dwt_comparator_list
;
354 /* REVISIT The four debug monitor bits are currently ignored... */
355 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DEMCR
, &dcb_demcr
);
356 if (retval
!= ERROR_OK
)
358 LOG_DEBUG("DCB_DEMCR = 0x%8.8" PRIx32
"", dcb_demcr
);
360 /* this register is used for emulated dcc channel */
361 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DCRDR
, 0);
362 if (retval
!= ERROR_OK
)
365 /* Enable debug requests */
366 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
367 if (retval
!= ERROR_OK
)
369 if (!(cortex_m
->dcb_dhcsr
& C_DEBUGEN
)) {
370 retval
= cortex_m_write_debug_halt_mask(target
, 0, C_HALT
| C_STEP
| C_MASKINTS
);
371 if (retval
!= ERROR_OK
)
375 /* Restore proper interrupt masking setting for running CPU. */
376 cortex_m_set_maskints_for_run(target
);
378 /* Enable features controlled by ITM and DWT blocks, and catch only
379 * the vectors we were told to pay attention to.
381 * Target firmware is responsible for all fault handling policy
382 * choices *EXCEPT* explicitly scripted overrides like "vector_catch"
383 * or manual updates to the NVIC SHCSR and CCR registers.
385 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DEMCR
, TRCENA
| armv7m
->demcr
);
386 if (retval
!= ERROR_OK
)
389 /* Paranoia: evidently some (early?) chips don't preserve all the
390 * debug state (including FPB, DWT, etc) across reset...
394 retval
= cortex_m_enable_fpb(target
);
395 if (retval
!= ERROR_OK
) {
396 LOG_ERROR("Failed to enable the FPB");
400 cortex_m
->fpb_enabled
= true;
402 /* Restore FPB registers */
403 for (unsigned int i
= 0; i
< cortex_m
->fp_num_code
+ cortex_m
->fp_num_lit
; i
++) {
404 retval
= target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
405 if (retval
!= ERROR_OK
)
409 /* Restore DWT registers */
410 for (unsigned int i
= 0; i
< cortex_m
->dwt_num_comp
; i
++) {
411 retval
= target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 0,
413 if (retval
!= ERROR_OK
)
415 retval
= target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 4,
417 if (retval
!= ERROR_OK
)
419 retval
= target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 8,
420 dwt_list
[i
].function
);
421 if (retval
!= ERROR_OK
)
424 retval
= dap_run(swjdp
);
425 if (retval
!= ERROR_OK
)
428 register_cache_invalidate(armv7m
->arm
.core_cache
);
430 /* make sure we have latest dhcsr flags */
431 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
436 static int cortex_m_examine_debug_reason(struct target
*target
)
438 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
440 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason
441 * only check the debug reason if we don't know it already */
443 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
444 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
)) {
445 if (cortex_m
->nvic_dfsr
& DFSR_BKPT
) {
446 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
447 if (cortex_m
->nvic_dfsr
& DFSR_DWTTRAP
)
448 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
449 } else if (cortex_m
->nvic_dfsr
& DFSR_DWTTRAP
)
450 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
451 else if (cortex_m
->nvic_dfsr
& DFSR_VCATCH
)
452 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
453 else if (cortex_m
->nvic_dfsr
& DFSR_EXTERNAL
)
454 target
->debug_reason
= DBG_REASON_DBGRQ
;
456 target
->debug_reason
= DBG_REASON_UNDEFINED
;
462 static int cortex_m_examine_exception_reason(struct target
*target
)
464 uint32_t shcsr
= 0, except_sr
= 0, cfsr
= -1, except_ar
= -1;
465 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
466 struct adiv5_dap
*swjdp
= armv7m
->arm
.dap
;
469 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_SHCSR
, &shcsr
);
470 if (retval
!= ERROR_OK
)
472 switch (armv7m
->exception_number
) {
475 case 3: /* Hard Fault */
476 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, NVIC_HFSR
, &except_sr
);
477 if (retval
!= ERROR_OK
)
479 if (except_sr
& 0x40000000) {
480 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_CFSR
, &cfsr
);
481 if (retval
!= ERROR_OK
)
485 case 4: /* Memory Management */
486 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_CFSR
, &except_sr
);
487 if (retval
!= ERROR_OK
)
489 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_MMFAR
, &except_ar
);
490 if (retval
!= ERROR_OK
)
493 case 5: /* Bus Fault */
494 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_CFSR
, &except_sr
);
495 if (retval
!= ERROR_OK
)
497 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_BFAR
, &except_ar
);
498 if (retval
!= ERROR_OK
)
501 case 6: /* Usage Fault */
502 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_CFSR
, &except_sr
);
503 if (retval
!= ERROR_OK
)
506 case 7: /* Secure Fault */
507 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_SFSR
, &except_sr
);
508 if (retval
!= ERROR_OK
)
510 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_SFAR
, &except_ar
);
511 if (retval
!= ERROR_OK
)
514 case 11: /* SVCall */
516 case 12: /* Debug Monitor */
517 retval
= mem_ap_read_u32(armv7m
->debug_ap
, NVIC_DFSR
, &except_sr
);
518 if (retval
!= ERROR_OK
)
521 case 14: /* PendSV */
523 case 15: /* SysTick */
529 retval
= dap_run(swjdp
);
530 if (retval
== ERROR_OK
)
531 LOG_DEBUG("%s SHCSR 0x%" PRIx32
", SR 0x%" PRIx32
532 ", CFSR 0x%" PRIx32
", AR 0x%" PRIx32
,
533 armv7m_exception_string(armv7m
->exception_number
),
534 shcsr
, except_sr
, cfsr
, except_ar
);
538 static int cortex_m_debug_entry(struct target
*target
)
543 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
544 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
545 struct arm
*arm
= &armv7m
->arm
;
550 /* Do this really early to minimize the window where the MASKINTS erratum
551 * can pile up pending interrupts. */
552 cortex_m_set_maskints_for_halt(target
);
554 cortex_m_clear_halt(target
);
555 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
556 if (retval
!= ERROR_OK
)
559 retval
= armv7m
->examine_debug_reason(target
);
560 if (retval
!= ERROR_OK
)
563 /* examine PE security state */
564 bool secure_state
= false;
565 if (armv7m
->arm
.arch
== ARM_ARCH_V8M
) {
568 retval
= mem_ap_read_u32(armv7m
->debug_ap
, DCB_DSCSR
, &dscsr
);
569 if (retval
!= ERROR_OK
)
572 secure_state
= (dscsr
& DSCSR_CDS
) == DSCSR_CDS
;
575 /* Examine target state and mode
576 * First load register accessible through core debug port */
577 int num_regs
= arm
->core_cache
->num_regs
;
579 for (i
= 0; i
< num_regs
; i
++) {
580 r
= &armv7m
->arm
.core_cache
->reg_list
[i
];
581 if (r
->exist
&& !r
->valid
)
582 arm
->read_core_reg(target
, r
, i
, ARM_MODE_ANY
);
586 xPSR
= buf_get_u32(r
->value
, 0, 32);
588 /* Are we in an exception handler */
590 armv7m
->exception_number
= (xPSR
& 0x1FF);
592 arm
->core_mode
= ARM_MODE_HANDLER
;
593 arm
->map
= armv7m_msp_reg_map
;
595 unsigned control
= buf_get_u32(arm
->core_cache
596 ->reg_list
[ARMV7M_CONTROL
].value
, 0, 3);
598 /* is this thread privileged? */
599 arm
->core_mode
= control
& 1
600 ? ARM_MODE_USER_THREAD
603 /* which stack is it using? */
605 arm
->map
= armv7m_psp_reg_map
;
607 arm
->map
= armv7m_msp_reg_map
;
609 armv7m
->exception_number
= 0;
612 if (armv7m
->exception_number
)
613 cortex_m_examine_exception_reason(target
);
615 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32
", cpu in %s state, target->state: %s",
616 arm_mode_name(arm
->core_mode
),
617 buf_get_u32(arm
->pc
->value
, 0, 32),
618 secure_state
? "Secure" : "Non-Secure",
619 target_state_name(target
));
621 if (armv7m
->post_debug_entry
) {
622 retval
= armv7m
->post_debug_entry(target
);
623 if (retval
!= ERROR_OK
)
630 static int cortex_m_poll(struct target
*target
)
632 int detected_failure
= ERROR_OK
;
633 int retval
= ERROR_OK
;
634 enum target_state prev_target_state
= target
->state
;
635 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
636 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
638 /* Read from Debug Halting Control and Status Register */
639 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
640 if (retval
!= ERROR_OK
) {
641 target
->state
= TARGET_UNKNOWN
;
645 /* Recover from lockup. See ARMv7-M architecture spec,
646 * section B1.5.15 "Unrecoverable exception cases".
648 if (cortex_m
->dcb_dhcsr
& S_LOCKUP
) {
649 LOG_ERROR("%s -- clearing lockup after double fault",
650 target_name(target
));
651 cortex_m_write_debug_halt_mask(target
, C_HALT
, 0);
652 target
->debug_reason
= DBG_REASON_DBGRQ
;
654 /* We have to execute the rest (the "finally" equivalent, but
655 * still throw this exception again).
657 detected_failure
= ERROR_FAIL
;
659 /* refresh status bits */
660 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
661 if (retval
!= ERROR_OK
)
665 if (cortex_m
->dcb_dhcsr
& S_RESET_ST
) {
666 if (target
->state
!= TARGET_RESET
) {
667 target
->state
= TARGET_RESET
;
668 LOG_INFO("%s: external reset detected", target_name(target
));
673 if (target
->state
== TARGET_RESET
) {
674 /* Cannot switch context while running so endreset is
675 * called with target->state == TARGET_RESET
677 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%" PRIx32
,
678 cortex_m
->dcb_dhcsr
);
679 retval
= cortex_m_endreset_event(target
);
680 if (retval
!= ERROR_OK
) {
681 target
->state
= TARGET_UNKNOWN
;
684 target
->state
= TARGET_RUNNING
;
685 prev_target_state
= TARGET_RUNNING
;
688 if (cortex_m
->dcb_dhcsr
& S_HALT
) {
689 target
->state
= TARGET_HALTED
;
691 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
)) {
692 retval
= cortex_m_debug_entry(target
);
693 if (retval
!= ERROR_OK
)
696 if (arm_semihosting(target
, &retval
) != 0)
699 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
701 if (prev_target_state
== TARGET_DEBUG_RUNNING
) {
703 retval
= cortex_m_debug_entry(target
);
704 if (retval
!= ERROR_OK
)
707 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
711 if (target
->state
== TARGET_UNKNOWN
) {
712 /* check if processor is retiring instructions or sleeping */
713 if (cortex_m
->dcb_dhcsr
& S_RETIRE_ST
|| cortex_m
->dcb_dhcsr
& S_SLEEP
) {
714 target
->state
= TARGET_RUNNING
;
719 /* Check that target is truly halted, since the target could be resumed externally */
720 if ((prev_target_state
== TARGET_HALTED
) && !(cortex_m
->dcb_dhcsr
& S_HALT
)) {
721 /* registers are now invalid */
722 register_cache_invalidate(armv7m
->arm
.core_cache
);
724 target
->state
= TARGET_RUNNING
;
725 LOG_WARNING("%s: external resume detected", target_name(target
));
726 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
730 /* Did we detect a failure condition that we cleared? */
731 if (detected_failure
!= ERROR_OK
)
732 retval
= detected_failure
;
736 static int cortex_m_halt(struct target
*target
)
738 LOG_DEBUG("target->state: %s",
739 target_state_name(target
));
741 if (target
->state
== TARGET_HALTED
) {
742 LOG_DEBUG("target was already halted");
746 if (target
->state
== TARGET_UNKNOWN
)
747 LOG_WARNING("target was in unknown state when halt was requested");
749 if (target
->state
== TARGET_RESET
) {
750 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst()) {
751 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
752 return ERROR_TARGET_FAILURE
;
754 /* we came here in a reset_halt or reset_init sequence
755 * debug entry was already prepared in cortex_m3_assert_reset()
757 target
->debug_reason
= DBG_REASON_DBGRQ
;
763 /* Write to Debug Halting Control and Status Register */
764 cortex_m_write_debug_halt_mask(target
, C_HALT
, 0);
766 /* Do this really early to minimize the window where the MASKINTS erratum
767 * can pile up pending interrupts. */
768 cortex_m_set_maskints_for_halt(target
);
770 target
->debug_reason
= DBG_REASON_DBGRQ
;
775 static int cortex_m_soft_reset_halt(struct target
*target
)
777 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
778 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
779 uint32_t dcb_dhcsr
= 0;
780 int retval
, timeout
= 0;
782 /* on single cortex_m MCU soft_reset_halt should be avoided as same functionality
783 * can be obtained by using 'reset halt' and 'cortex_m reset_config vectreset'.
784 * As this reset only uses VC_CORERESET it would only ever reset the cortex_m
785 * core, not the peripherals */
786 LOG_DEBUG("soft_reset_halt is discouraged, please use 'reset halt' instead.");
788 if (!cortex_m
->vectreset_supported
) {
789 LOG_ERROR("VECTRESET is not supported on this Cortex-M core");
794 retval
= cortex_m_write_debug_halt_mask(target
, 0, C_STEP
| C_MASKINTS
);
795 if (retval
!= ERROR_OK
)
798 /* Enter debug state on reset; restore DEMCR in endreset_event() */
799 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DEMCR
,
800 TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
801 if (retval
!= ERROR_OK
)
804 /* Request a core-only reset */
805 retval
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, NVIC_AIRCR
,
806 AIRCR_VECTKEY
| AIRCR_VECTRESET
);
807 if (retval
!= ERROR_OK
)
809 target
->state
= TARGET_RESET
;
811 /* registers are now invalid */
812 register_cache_invalidate(cortex_m
->armv7m
.arm
.core_cache
);
814 while (timeout
< 100) {
815 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &dcb_dhcsr
);
816 if (retval
== ERROR_OK
) {
817 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, NVIC_DFSR
,
818 &cortex_m
->nvic_dfsr
);
819 if (retval
!= ERROR_OK
)
821 if ((dcb_dhcsr
& S_HALT
)
822 && (cortex_m
->nvic_dfsr
& DFSR_VCATCH
)) {
823 LOG_DEBUG("system reset-halted, DHCSR 0x%08x, "
825 (unsigned) dcb_dhcsr
,
826 (unsigned) cortex_m
->nvic_dfsr
);
827 cortex_m_poll(target
);
828 /* FIXME restore user's vector catch config */
831 LOG_DEBUG("waiting for system reset-halt, "
832 "DHCSR 0x%08x, %d ms",
833 (unsigned) dcb_dhcsr
, timeout
);
842 void cortex_m_enable_breakpoints(struct target
*target
)
844 struct breakpoint
*breakpoint
= target
->breakpoints
;
846 /* set any pending breakpoints */
848 if (!breakpoint
->set
)
849 cortex_m_set_breakpoint(target
, breakpoint
);
850 breakpoint
= breakpoint
->next
;
854 static int cortex_m_resume(struct target
*target
, int current
,
855 target_addr_t address
, int handle_breakpoints
, int debug_execution
)
857 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
858 struct breakpoint
*breakpoint
= NULL
;
862 if (target
->state
!= TARGET_HALTED
) {
863 LOG_WARNING("target not halted");
864 return ERROR_TARGET_NOT_HALTED
;
867 if (!debug_execution
) {
868 target_free_all_working_areas(target
);
869 cortex_m_enable_breakpoints(target
);
870 cortex_m_enable_watchpoints(target
);
873 if (debug_execution
) {
874 r
= armv7m
->arm
.core_cache
->reg_list
+ ARMV7M_PRIMASK
;
876 /* Disable interrupts */
877 /* We disable interrupts in the PRIMASK register instead of
878 * masking with C_MASKINTS. This is probably the same issue
879 * as Cortex-M3 Erratum 377493 (fixed in r1p0): C_MASKINTS
880 * in parallel with disabled interrupts can cause local faults
883 * This breaks non-debug (application) execution if not
884 * called from armv7m_start_algorithm() which saves registers.
886 buf_set_u32(r
->value
, 0, 1, 1);
890 /* Make sure we are in Thumb mode, set xPSR.T bit */
891 /* armv7m_start_algorithm() initializes entire xPSR register.
892 * This duplicity handles the case when cortex_m_resume()
893 * is used with the debug_execution flag directly,
894 * not called through armv7m_start_algorithm().
896 r
= armv7m
->arm
.cpsr
;
897 buf_set_u32(r
->value
, 24, 1, 1);
902 /* current = 1: continue on current pc, otherwise continue at <address> */
905 buf_set_u32(r
->value
, 0, 32, address
);
910 /* if we halted last time due to a bkpt instruction
911 * then we have to manually step over it, otherwise
912 * the core will break again */
914 if (!breakpoint_find(target
, buf_get_u32(r
->value
, 0, 32))
916 armv7m_maybe_skip_bkpt_inst(target
, NULL
);
918 resume_pc
= buf_get_u32(r
->value
, 0, 32);
920 armv7m_restore_context(target
);
922 /* the front-end may request us not to handle breakpoints */
923 if (handle_breakpoints
) {
924 /* Single step past breakpoint at current address */
925 breakpoint
= breakpoint_find(target
, resume_pc
);
927 LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT
" (ID: %" PRIu32
")",
929 breakpoint
->unique_id
);
930 cortex_m_unset_breakpoint(target
, breakpoint
);
931 cortex_m_single_step_core(target
);
932 cortex_m_set_breakpoint(target
, breakpoint
);
937 cortex_m_set_maskints_for_run(target
);
938 cortex_m_write_debug_halt_mask(target
, 0, C_HALT
);
940 target
->debug_reason
= DBG_REASON_NOTHALTED
;
942 /* registers are now invalid */
943 register_cache_invalidate(armv7m
->arm
.core_cache
);
945 if (!debug_execution
) {
946 target
->state
= TARGET_RUNNING
;
947 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
948 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
950 target
->state
= TARGET_DEBUG_RUNNING
;
951 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
952 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
958 /* int irqstepcount = 0; */
959 static int cortex_m_step(struct target
*target
, int current
,
960 target_addr_t address
, int handle_breakpoints
)
962 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
963 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
964 struct breakpoint
*breakpoint
= NULL
;
965 struct reg
*pc
= armv7m
->arm
.pc
;
966 bool bkpt_inst_found
= false;
968 bool isr_timed_out
= false;
970 if (target
->state
!= TARGET_HALTED
) {
971 LOG_WARNING("target not halted");
972 return ERROR_TARGET_NOT_HALTED
;
975 /* current = 1: continue on current pc, otherwise continue at <address> */
977 buf_set_u32(pc
->value
, 0, 32, address
);
982 uint32_t pc_value
= buf_get_u32(pc
->value
, 0, 32);
984 /* the front-end may request us not to handle breakpoints */
985 if (handle_breakpoints
) {
986 breakpoint
= breakpoint_find(target
, pc_value
);
988 cortex_m_unset_breakpoint(target
, breakpoint
);
991 armv7m_maybe_skip_bkpt_inst(target
, &bkpt_inst_found
);
993 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
995 armv7m_restore_context(target
);
997 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
999 /* if no bkpt instruction is found at pc then we can perform
1000 * a normal step, otherwise we have to manually step over the bkpt
1001 * instruction - as such simulate a step */
1002 if (bkpt_inst_found
== false) {
1003 if (cortex_m
->isrmasking_mode
!= CORTEX_M_ISRMASK_AUTO
) {
1004 /* Automatic ISR masking mode off: Just step over the next
1005 * instruction, with interrupts on or off as appropriate. */
1006 cortex_m_set_maskints_for_step(target
);
1007 cortex_m_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
1009 /* Process interrupts during stepping in a way they don't interfere
1014 * Set a temporary break point at the current pc and let the core run
1015 * with interrupts enabled. Pending interrupts get served and we run
1016 * into the breakpoint again afterwards. Then we step over the next
1017 * instruction with interrupts disabled.
1019 * If the pending interrupts don't complete within time, we leave the
1020 * core running. This may happen if the interrupts trigger faster
1021 * than the core can process them or the handler doesn't return.
1023 * If no more breakpoints are available we simply do a step with
1024 * interrupts enabled.
1030 * If a break point is already set on the lower half word then a break point on
1031 * the upper half word will not break again when the core is restarted. So we
1032 * just step over the instruction with interrupts disabled.
1034 * The documentation has no information about this, it was found by observation
1035 * on STM32F1 and STM32F2. Proper explanation welcome. STM32F0 doesn't seem to
1036 * suffer from this problem.
1038 * To add some confusion: pc_value has bit 0 always set, while the breakpoint
1039 * address has it always cleared. The former is done to indicate thumb mode
1043 if ((pc_value
& 0x02) && breakpoint_find(target
, pc_value
& ~0x03)) {
1044 LOG_DEBUG("Stepping over next instruction with interrupts disabled");
1045 cortex_m_write_debug_halt_mask(target
, C_HALT
| C_MASKINTS
, 0);
1046 cortex_m_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
1047 /* Re-enable interrupts if appropriate */
1048 cortex_m_write_debug_halt_mask(target
, C_HALT
, 0);
1049 cortex_m_set_maskints_for_halt(target
);
1052 /* Set a temporary break point */
1054 retval
= cortex_m_set_breakpoint(target
, breakpoint
);
1056 enum breakpoint_type type
= BKPT_HARD
;
1057 if (cortex_m
->fp_rev
== 0 && pc_value
> 0x1FFFFFFF) {
1058 /* FPB rev.1 cannot handle such addr, try BKPT instr */
1061 retval
= breakpoint_add(target
, pc_value
, 2, type
);
1064 bool tmp_bp_set
= (retval
== ERROR_OK
);
1066 /* No more breakpoints left, just do a step */
1068 cortex_m_set_maskints_for_step(target
);
1069 cortex_m_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
1070 /* Re-enable interrupts if appropriate */
1071 cortex_m_write_debug_halt_mask(target
, C_HALT
, 0);
1072 cortex_m_set_maskints_for_halt(target
);
1074 /* Start the core */
1075 LOG_DEBUG("Starting core to serve pending interrupts");
1076 int64_t t_start
= timeval_ms();
1077 cortex_m_set_maskints_for_run(target
);
1078 cortex_m_write_debug_halt_mask(target
, 0, C_HALT
| C_STEP
);
1080 /* Wait for pending handlers to complete or timeout */
1082 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
,
1084 &cortex_m
->dcb_dhcsr
);
1085 if (retval
!= ERROR_OK
) {
1086 target
->state
= TARGET_UNKNOWN
;
1089 isr_timed_out
= ((timeval_ms() - t_start
) > 500);
1090 } while (!((cortex_m
->dcb_dhcsr
& S_HALT
) || isr_timed_out
));
1092 /* only remove breakpoint if we created it */
1094 cortex_m_unset_breakpoint(target
, breakpoint
);
1096 /* Remove the temporary breakpoint */
1097 breakpoint_remove(target
, pc_value
);
1100 if (isr_timed_out
) {
1101 LOG_DEBUG("Interrupt handlers didn't complete within time, "
1102 "leaving target running");
1104 /* Step over next instruction with interrupts disabled */
1105 cortex_m_set_maskints_for_step(target
);
1106 cortex_m_write_debug_halt_mask(target
,
1107 C_HALT
| C_MASKINTS
,
1109 cortex_m_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
1110 /* Re-enable interrupts if appropriate */
1111 cortex_m_write_debug_halt_mask(target
, C_HALT
, 0);
1112 cortex_m_set_maskints_for_halt(target
);
1119 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
1120 if (retval
!= ERROR_OK
)
1123 /* registers are now invalid */
1124 register_cache_invalidate(armv7m
->arm
.core_cache
);
1127 cortex_m_set_breakpoint(target
, breakpoint
);
1129 if (isr_timed_out
) {
1130 /* Leave the core running. The user has to stop execution manually. */
1131 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1132 target
->state
= TARGET_RUNNING
;
1136 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
1137 " nvic_icsr = 0x%" PRIx32
,
1138 cortex_m
->dcb_dhcsr
, cortex_m
->nvic_icsr
);
1140 retval
= cortex_m_debug_entry(target
);
1141 if (retval
!= ERROR_OK
)
1143 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1145 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
1146 " nvic_icsr = 0x%" PRIx32
,
1147 cortex_m
->dcb_dhcsr
, cortex_m
->nvic_icsr
);
1152 static int cortex_m_assert_reset(struct target
*target
)
1154 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1155 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
1156 enum cortex_m_soft_reset_config reset_config
= cortex_m
->soft_reset_config
;
1158 LOG_DEBUG("target->state: %s",
1159 target_state_name(target
));
1161 enum reset_types jtag_reset_config
= jtag_get_reset_config();
1163 if (target_has_event_action(target
, TARGET_EVENT_RESET_ASSERT
)) {
1164 /* allow scripts to override the reset event */
1166 target_handle_event(target
, TARGET_EVENT_RESET_ASSERT
);
1167 register_cache_invalidate(cortex_m
->armv7m
.arm
.core_cache
);
1168 target
->state
= TARGET_RESET
;
1173 /* some cores support connecting while srst is asserted
1174 * use that mode is it has been configured */
1176 bool srst_asserted
= false;
1178 if (!target_was_examined(target
)) {
1179 if (jtag_reset_config
& RESET_HAS_SRST
) {
1180 adapter_assert_reset();
1181 if (target
->reset_halt
)
1182 LOG_ERROR("Target not examined, will not halt after reset!");
1185 LOG_ERROR("Target not examined, reset NOT asserted!");
1190 if ((jtag_reset_config
& RESET_HAS_SRST
) &&
1191 (jtag_reset_config
& RESET_SRST_NO_GATING
)) {
1192 adapter_assert_reset();
1193 srst_asserted
= true;
1196 /* Enable debug requests */
1198 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
1199 /* Store important errors instead of failing and proceed to reset assert */
1201 if (retval
!= ERROR_OK
|| !(cortex_m
->dcb_dhcsr
& C_DEBUGEN
))
1202 retval
= cortex_m_write_debug_halt_mask(target
, 0, C_HALT
| C_STEP
| C_MASKINTS
);
1204 /* If the processor is sleeping in a WFI or WFE instruction, the
1205 * C_HALT bit must be asserted to regain control */
1206 if (retval
== ERROR_OK
&& (cortex_m
->dcb_dhcsr
& S_SLEEP
))
1207 retval
= cortex_m_write_debug_halt_mask(target
, C_HALT
, 0);
1209 mem_ap_write_u32(armv7m
->debug_ap
, DCB_DCRDR
, 0);
1210 /* Ignore less important errors */
1212 if (!target
->reset_halt
) {
1213 /* Set/Clear C_MASKINTS in a separate operation */
1214 cortex_m_set_maskints_for_run(target
);
1216 /* clear any debug flags before resuming */
1217 cortex_m_clear_halt(target
);
1219 /* clear C_HALT in dhcsr reg */
1220 cortex_m_write_debug_halt_mask(target
, 0, C_HALT
);
1222 /* Halt in debug on reset; endreset_event() restores DEMCR.
1224 * REVISIT catching BUSERR presumably helps to defend against
1225 * bad vector table entries. Should this include MMERR or
1229 retval2
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, DCB_DEMCR
,
1230 TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
1231 if (retval
!= ERROR_OK
|| retval2
!= ERROR_OK
)
1232 LOG_INFO("AP write error, reset will not halt");
1235 if (jtag_reset_config
& RESET_HAS_SRST
) {
1236 /* default to asserting srst */
1238 adapter_assert_reset();
1240 /* srst is asserted, ignore AP access errors */
1243 /* Use a standard Cortex-M3 software reset mechanism.
1244 * We default to using VECTRESET as it is supported on all current cores
1245 * (except Cortex-M0, M0+ and M1 which support SYSRESETREQ only!)
1246 * This has the disadvantage of not resetting the peripherals, so a
1247 * reset-init event handler is needed to perform any peripheral resets.
1249 if (!cortex_m
->vectreset_supported
1250 && reset_config
== CORTEX_M_RESET_VECTRESET
) {
1251 reset_config
= CORTEX_M_RESET_SYSRESETREQ
;
1252 LOG_WARNING("VECTRESET is not supported on this Cortex-M core, using SYSRESETREQ instead.");
1253 LOG_WARNING("Set 'cortex_m reset_config sysresetreq'.");
1256 LOG_DEBUG("Using Cortex-M %s", (reset_config
== CORTEX_M_RESET_SYSRESETREQ
)
1257 ? "SYSRESETREQ" : "VECTRESET");
1259 if (reset_config
== CORTEX_M_RESET_VECTRESET
) {
1260 LOG_WARNING("Only resetting the Cortex-M core, use a reset-init event "
1261 "handler to reset any peripherals or configure hardware srst support.");
1265 retval3
= mem_ap_write_atomic_u32(armv7m
->debug_ap
, NVIC_AIRCR
,
1266 AIRCR_VECTKEY
| ((reset_config
== CORTEX_M_RESET_SYSRESETREQ
)
1267 ? AIRCR_SYSRESETREQ
: AIRCR_VECTRESET
));
1268 if (retval3
!= ERROR_OK
)
1269 LOG_DEBUG("Ignoring AP write error right after reset");
1271 retval3
= dap_dp_init_or_reconnect(armv7m
->debug_ap
->dap
);
1272 if (retval3
!= ERROR_OK
) {
1273 LOG_ERROR("DP initialisation failed");
1274 /* The error return value must not be propagated in this case.
1275 * SYSRESETREQ or VECTRESET have been possibly triggered
1276 * so reset processing should continue */
1278 /* I do not know why this is necessary, but it
1279 * fixes strange effects (step/resume cause NMI
1280 * after reset) on LM3S6918 -- Michael Schwingen
1283 mem_ap_read_atomic_u32(armv7m
->debug_ap
, NVIC_AIRCR
, &tmp
);
1287 target
->state
= TARGET_RESET
;
1290 register_cache_invalidate(cortex_m
->armv7m
.arm
.core_cache
);
1292 /* now return stored error code if any */
1293 if (retval
!= ERROR_OK
)
1296 if (target
->reset_halt
) {
1297 retval
= target_halt(target
);
1298 if (retval
!= ERROR_OK
)
1305 static int cortex_m_deassert_reset(struct target
*target
)
1307 struct armv7m_common
*armv7m
= &target_to_cm(target
)->armv7m
;
1309 LOG_DEBUG("target->state: %s",
1310 target_state_name(target
));
1312 /* deassert reset lines */
1313 adapter_deassert_reset();
1315 enum reset_types jtag_reset_config
= jtag_get_reset_config();
1317 if ((jtag_reset_config
& RESET_HAS_SRST
) &&
1318 !(jtag_reset_config
& RESET_SRST_NO_GATING
) &&
1319 target_was_examined(target
)) {
1321 int retval
= dap_dp_init_or_reconnect(armv7m
->debug_ap
->dap
);
1322 if (retval
!= ERROR_OK
) {
1323 LOG_ERROR("DP initialisation failed");
1331 int cortex_m_set_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1334 unsigned int fp_num
= 0;
1335 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1336 struct cortex_m_fp_comparator
*comparator_list
= cortex_m
->fp_comparator_list
;
1338 if (breakpoint
->set
) {
1339 LOG_WARNING("breakpoint (BPID: %" PRIu32
") already set", breakpoint
->unique_id
);
1343 if (breakpoint
->type
== BKPT_HARD
) {
1344 uint32_t fpcr_value
;
1345 while (comparator_list
[fp_num
].used
&& (fp_num
< cortex_m
->fp_num_code
))
1347 if (fp_num
>= cortex_m
->fp_num_code
) {
1348 LOG_ERROR("Can not find free FPB Comparator!");
1349 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1351 breakpoint
->set
= fp_num
+ 1;
1352 fpcr_value
= breakpoint
->address
| 1;
1353 if (cortex_m
->fp_rev
== 0) {
1354 if (breakpoint
->address
> 0x1FFFFFFF) {
1355 LOG_ERROR("Cortex-M Flash Patch Breakpoint rev.1 cannot handle HW breakpoint above address 0x1FFFFFFE");
1359 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
1360 fpcr_value
= (fpcr_value
& 0x1FFFFFFC) | hilo
| 1;
1361 } else if (cortex_m
->fp_rev
> 1) {
1362 LOG_ERROR("Unhandled Cortex-M Flash Patch Breakpoint architecture revision");
1365 comparator_list
[fp_num
].used
= true;
1366 comparator_list
[fp_num
].fpcr_value
= fpcr_value
;
1367 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
,
1368 comparator_list
[fp_num
].fpcr_value
);
1369 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32
"",
1371 comparator_list
[fp_num
].fpcr_value
);
1372 if (!cortex_m
->fpb_enabled
) {
1373 LOG_DEBUG("FPB wasn't enabled, do it now");
1374 retval
= cortex_m_enable_fpb(target
);
1375 if (retval
!= ERROR_OK
) {
1376 LOG_ERROR("Failed to enable the FPB");
1380 cortex_m
->fpb_enabled
= true;
1382 } else if (breakpoint
->type
== BKPT_SOFT
) {
1385 /* NOTE: on ARMv6-M and ARMv7-M, BKPT(0xab) is used for
1386 * semihosting; don't use that. Otherwise the BKPT
1387 * parameter is arbitrary.
1389 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1390 retval
= target_read_memory(target
,
1391 breakpoint
->address
& 0xFFFFFFFE,
1392 breakpoint
->length
, 1,
1393 breakpoint
->orig_instr
);
1394 if (retval
!= ERROR_OK
)
1396 retval
= target_write_memory(target
,
1397 breakpoint
->address
& 0xFFFFFFFE,
1398 breakpoint
->length
, 1,
1400 if (retval
!= ERROR_OK
)
1402 breakpoint
->set
= true;
1405 LOG_DEBUG("BPID: %" PRIu32
", Type: %d, Address: " TARGET_ADDR_FMT
" Length: %d (set=%d)",
1406 breakpoint
->unique_id
,
1407 (int)(breakpoint
->type
),
1408 breakpoint
->address
,
1415 int cortex_m_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1418 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1419 struct cortex_m_fp_comparator
*comparator_list
= cortex_m
->fp_comparator_list
;
1421 if (breakpoint
->set
<= 0) {
1422 LOG_WARNING("breakpoint not set");
1426 LOG_DEBUG("BPID: %" PRIu32
", Type: %d, Address: " TARGET_ADDR_FMT
" Length: %d (set=%d)",
1427 breakpoint
->unique_id
,
1428 (int)(breakpoint
->type
),
1429 breakpoint
->address
,
1433 if (breakpoint
->type
== BKPT_HARD
) {
1434 unsigned int fp_num
= breakpoint
->set
- 1;
1435 if (fp_num
>= cortex_m
->fp_num_code
) {
1436 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
1439 comparator_list
[fp_num
].used
= false;
1440 comparator_list
[fp_num
].fpcr_value
= 0;
1441 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
,
1442 comparator_list
[fp_num
].fpcr_value
);
1444 /* restore original instruction (kept in target endianness) */
1445 retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE,
1446 breakpoint
->length
, 1,
1447 breakpoint
->orig_instr
);
1448 if (retval
!= ERROR_OK
)
1451 breakpoint
->set
= false;
1456 int cortex_m_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1458 if (breakpoint
->length
== 3) {
1459 LOG_DEBUG("Using a two byte breakpoint for 32bit Thumb-2 request");
1460 breakpoint
->length
= 2;
1463 if ((breakpoint
->length
!= 2)) {
1464 LOG_INFO("only breakpoints of two bytes length supported");
1465 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1468 return cortex_m_set_breakpoint(target
, breakpoint
);
1471 int cortex_m_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1473 if (!breakpoint
->set
)
1476 return cortex_m_unset_breakpoint(target
, breakpoint
);
1479 static int cortex_m_set_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1481 unsigned int dwt_num
= 0;
1482 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1484 /* REVISIT Don't fully trust these "not used" records ... users
1485 * may set up breakpoints by hand, e.g. dual-address data value
1486 * watchpoint using comparator #1; comparator #0 matching cycle
1487 * count; send data trace info through ITM and TPIU; etc
1489 struct cortex_m_dwt_comparator
*comparator
;
1491 for (comparator
= cortex_m
->dwt_comparator_list
;
1492 comparator
->used
&& dwt_num
< cortex_m
->dwt_num_comp
;
1493 comparator
++, dwt_num
++)
1495 if (dwt_num
>= cortex_m
->dwt_num_comp
) {
1496 LOG_ERROR("Can not find free DWT Comparator");
1499 comparator
->used
= true;
1500 watchpoint
->set
= dwt_num
+ 1;
1502 comparator
->comp
= watchpoint
->address
;
1503 target_write_u32(target
, comparator
->dwt_comparator_address
+ 0,
1506 if ((cortex_m
->dwt_devarch
& 0x1FFFFF) != DWT_DEVARCH_ARMV8M
) {
1507 uint32_t mask
= 0, temp
;
1509 /* watchpoint params were validated earlier */
1510 temp
= watchpoint
->length
;
1517 comparator
->mask
= mask
;
1518 target_write_u32(target
, comparator
->dwt_comparator_address
+ 4,
1521 switch (watchpoint
->rw
) {
1523 comparator
->function
= 5;
1526 comparator
->function
= 6;
1529 comparator
->function
= 7;
1533 uint32_t data_size
= watchpoint
->length
>> 1;
1534 comparator
->mask
= (watchpoint
->length
>> 1) | 1;
1536 switch (watchpoint
->rw
) {
1538 comparator
->function
= 4;
1541 comparator
->function
= 5;
1544 comparator
->function
= 6;
1547 comparator
->function
= comparator
->function
| (1 << 4) |
1551 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1552 comparator
->function
);
1554 LOG_DEBUG("Watchpoint (ID %d) DWT%d 0x%08x 0x%x 0x%05x",
1555 watchpoint
->unique_id
, dwt_num
,
1556 (unsigned) comparator
->comp
,
1557 (unsigned) comparator
->mask
,
1558 (unsigned) comparator
->function
);
1562 static int cortex_m_unset_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1564 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1565 struct cortex_m_dwt_comparator
*comparator
;
1567 if (watchpoint
->set
<= 0) {
1568 LOG_WARNING("watchpoint (wpid: %d) not set",
1569 watchpoint
->unique_id
);
1573 unsigned int dwt_num
= watchpoint
->set
- 1;
1575 LOG_DEBUG("Watchpoint (ID %d) DWT%d address: 0x%08x clear",
1576 watchpoint
->unique_id
, dwt_num
,
1577 (unsigned) watchpoint
->address
);
1579 if (dwt_num
>= cortex_m
->dwt_num_comp
) {
1580 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1584 comparator
= cortex_m
->dwt_comparator_list
+ dwt_num
;
1585 comparator
->used
= false;
1586 comparator
->function
= 0;
1587 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1588 comparator
->function
);
1590 watchpoint
->set
= false;
1595 int cortex_m_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1597 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1599 if (cortex_m
->dwt_comp_available
< 1) {
1600 LOG_DEBUG("no comparators?");
1601 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1604 /* hardware doesn't support data value masking */
1605 if (watchpoint
->mask
!= ~(uint32_t)0) {
1606 LOG_DEBUG("watchpoint value masks not supported");
1607 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1610 /* hardware allows address masks of up to 32K */
1613 for (mask
= 0; mask
< 16; mask
++) {
1614 if ((1u << mask
) == watchpoint
->length
)
1618 LOG_DEBUG("unsupported watchpoint length");
1619 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1621 if (watchpoint
->address
& ((1 << mask
) - 1)) {
1622 LOG_DEBUG("watchpoint address is unaligned");
1623 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1626 /* Caller doesn't seem to be able to describe watching for data
1627 * values of zero; that flags "no value".
1629 * REVISIT This DWT may well be able to watch for specific data
1630 * values. Requires comparator #1 to set DATAVMATCH and match
1631 * the data, and another comparator (DATAVADDR0) matching addr.
1633 if (watchpoint
->value
) {
1634 LOG_DEBUG("data value watchpoint not YET supported");
1635 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1638 cortex_m
->dwt_comp_available
--;
1639 LOG_DEBUG("dwt_comp_available: %d", cortex_m
->dwt_comp_available
);
1644 int cortex_m_remove_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1646 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1648 /* REVISIT why check? DWT can be updated with core running ... */
1649 if (target
->state
!= TARGET_HALTED
) {
1650 LOG_WARNING("target not halted");
1651 return ERROR_TARGET_NOT_HALTED
;
1654 if (watchpoint
->set
)
1655 cortex_m_unset_watchpoint(target
, watchpoint
);
1657 cortex_m
->dwt_comp_available
++;
1658 LOG_DEBUG("dwt_comp_available: %d", cortex_m
->dwt_comp_available
);
1663 int cortex_m_hit_watchpoint(struct target
*target
, struct watchpoint
**hit_watchpoint
)
1665 if (target
->debug_reason
!= DBG_REASON_WATCHPOINT
)
1668 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1670 for (struct watchpoint
*wp
= target
->watchpoints
; wp
; wp
= wp
->next
) {
1674 unsigned int dwt_num
= wp
->set
- 1;
1675 struct cortex_m_dwt_comparator
*comparator
= cortex_m
->dwt_comparator_list
+ dwt_num
;
1677 uint32_t dwt_function
;
1678 int retval
= target_read_u32(target
, comparator
->dwt_comparator_address
+ 8, &dwt_function
);
1679 if (retval
!= ERROR_OK
)
1682 /* check the MATCHED bit */
1683 if (dwt_function
& BIT(24)) {
1684 *hit_watchpoint
= wp
;
1692 void cortex_m_enable_watchpoints(struct target
*target
)
1694 struct watchpoint
*watchpoint
= target
->watchpoints
;
1696 /* set any pending watchpoints */
1697 while (watchpoint
) {
1698 if (!watchpoint
->set
)
1699 cortex_m_set_watchpoint(target
, watchpoint
);
1700 watchpoint
= watchpoint
->next
;
1704 static int cortex_m_read_memory(struct target
*target
, target_addr_t address
,
1705 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1707 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1709 if (armv7m
->arm
.arch
== ARM_ARCH_V6M
) {
1710 /* armv6m does not handle unaligned memory access */
1711 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1712 return ERROR_TARGET_UNALIGNED_ACCESS
;
1715 return mem_ap_read_buf(armv7m
->debug_ap
, buffer
, size
, count
, address
);
1718 static int cortex_m_write_memory(struct target
*target
, target_addr_t address
,
1719 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
1721 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1723 if (armv7m
->arm
.arch
== ARM_ARCH_V6M
) {
1724 /* armv6m does not handle unaligned memory access */
1725 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1726 return ERROR_TARGET_UNALIGNED_ACCESS
;
1729 return mem_ap_write_buf(armv7m
->debug_ap
, buffer
, size
, count
, address
);
1732 static int cortex_m_init_target(struct command_context
*cmd_ctx
,
1733 struct target
*target
)
1735 armv7m_build_reg_cache(target
);
1736 arm_semihosting_init(target
);
1740 void cortex_m_deinit_target(struct target
*target
)
1742 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1744 free(cortex_m
->fp_comparator_list
);
1746 cortex_m_dwt_free(target
);
1747 armv7m_free_reg_cache(target
);
1749 free(target
->private_config
);
1753 int cortex_m_profiling(struct target
*target
, uint32_t *samples
,
1754 uint32_t max_num_samples
, uint32_t *num_samples
, uint32_t seconds
)
1756 struct timeval timeout
, now
;
1757 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1761 retval
= target_read_u32(target
, DWT_PCSR
, ®_value
);
1762 if (retval
!= ERROR_OK
) {
1763 LOG_ERROR("Error while reading PCSR");
1766 if (reg_value
== 0) {
1767 LOG_INFO("PCSR sampling not supported on this processor.");
1768 return target_profiling_default(target
, samples
, max_num_samples
, num_samples
, seconds
);
1771 gettimeofday(&timeout
, NULL
);
1772 timeval_add_time(&timeout
, seconds
, 0);
1774 LOG_INFO("Starting Cortex-M profiling. Sampling DWT_PCSR as fast as we can...");
1776 /* Make sure the target is running */
1777 target_poll(target
);
1778 if (target
->state
== TARGET_HALTED
)
1779 retval
= target_resume(target
, 1, 0, 0, 0);
1781 if (retval
!= ERROR_OK
) {
1782 LOG_ERROR("Error while resuming target");
1786 uint32_t sample_count
= 0;
1789 if (armv7m
&& armv7m
->debug_ap
) {
1790 uint32_t read_count
= max_num_samples
- sample_count
;
1791 if (read_count
> 1024)
1794 retval
= mem_ap_read_buf_noincr(armv7m
->debug_ap
,
1795 (void *)&samples
[sample_count
],
1796 4, read_count
, DWT_PCSR
);
1797 sample_count
+= read_count
;
1799 target_read_u32(target
, DWT_PCSR
, &samples
[sample_count
++]);
1802 if (retval
!= ERROR_OK
) {
1803 LOG_ERROR("Error while reading PCSR");
1808 gettimeofday(&now
, NULL
);
1809 if (sample_count
>= max_num_samples
|| timeval_compare(&now
, &timeout
) > 0) {
1810 LOG_INFO("Profiling completed. %" PRIu32
" samples.", sample_count
);
1815 *num_samples
= sample_count
;
1820 /* REVISIT cache valid/dirty bits are unmaintained. We could set "valid"
1821 * on r/w if the core is not running, and clear on resume or reset ... or
1822 * at least, in a post_restore_context() method.
1825 struct dwt_reg_state
{
1826 struct target
*target
;
1828 uint8_t value
[4]; /* scratch/cache */
1831 static int cortex_m_dwt_get_reg(struct reg
*reg
)
1833 struct dwt_reg_state
*state
= reg
->arch_info
;
1836 int retval
= target_read_u32(state
->target
, state
->addr
, &tmp
);
1837 if (retval
!= ERROR_OK
)
1840 buf_set_u32(state
->value
, 0, 32, tmp
);
1844 static int cortex_m_dwt_set_reg(struct reg
*reg
, uint8_t *buf
)
1846 struct dwt_reg_state
*state
= reg
->arch_info
;
1848 return target_write_u32(state
->target
, state
->addr
,
1849 buf_get_u32(buf
, 0, reg
->size
));
1858 static const struct dwt_reg dwt_base_regs
[] = {
1859 { DWT_CTRL
, "dwt_ctrl", 32, },
1860 /* NOTE that Erratum 532314 (fixed r2p0) affects CYCCNT: it wrongly
1861 * increments while the core is asleep.
1863 { DWT_CYCCNT
, "dwt_cyccnt", 32, },
1864 /* plus some 8 bit counters, useful for profiling with TPIU */
1867 static const struct dwt_reg dwt_comp
[] = {
1868 #define DWT_COMPARATOR(i) \
1869 { DWT_COMP0 + 0x10 * (i), "dwt_" #i "_comp", 32, }, \
1870 { DWT_MASK0 + 0x10 * (i), "dwt_" #i "_mask", 4, }, \
1871 { DWT_FUNCTION0 + 0x10 * (i), "dwt_" #i "_function", 32, }
1888 #undef DWT_COMPARATOR
1891 static const struct reg_arch_type dwt_reg_type
= {
1892 .get
= cortex_m_dwt_get_reg
,
1893 .set
= cortex_m_dwt_set_reg
,
1896 static void cortex_m_dwt_addreg(struct target
*t
, struct reg
*r
, const struct dwt_reg
*d
)
1898 struct dwt_reg_state
*state
;
1900 state
= calloc(1, sizeof(*state
));
1903 state
->addr
= d
->addr
;
1908 r
->value
= state
->value
;
1909 r
->arch_info
= state
;
1910 r
->type
= &dwt_reg_type
;
1913 static void cortex_m_dwt_setup(struct cortex_m_common
*cm
, struct target
*target
)
1916 struct reg_cache
*cache
;
1917 struct cortex_m_dwt_comparator
*comparator
;
1920 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1921 LOG_DEBUG("DWT_CTRL: 0x%" PRIx32
, dwtcr
);
1923 LOG_DEBUG("no DWT");
1927 target_read_u32(target
, DWT_DEVARCH
, &cm
->dwt_devarch
);
1928 LOG_DEBUG("DWT_DEVARCH: 0x%" PRIx32
, cm
->dwt_devarch
);
1930 cm
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1931 cm
->dwt_comp_available
= cm
->dwt_num_comp
;
1932 cm
->dwt_comparator_list
= calloc(cm
->dwt_num_comp
,
1933 sizeof(struct cortex_m_dwt_comparator
));
1934 if (!cm
->dwt_comparator_list
) {
1936 cm
->dwt_num_comp
= 0;
1937 LOG_ERROR("out of mem");
1941 cache
= calloc(1, sizeof(*cache
));
1944 free(cm
->dwt_comparator_list
);
1947 cache
->name
= "Cortex-M DWT registers";
1948 cache
->num_regs
= 2 + cm
->dwt_num_comp
* 3;
1949 cache
->reg_list
= calloc(cache
->num_regs
, sizeof(*cache
->reg_list
));
1950 if (!cache
->reg_list
) {
1955 for (reg
= 0; reg
< 2; reg
++)
1956 cortex_m_dwt_addreg(target
, cache
->reg_list
+ reg
,
1957 dwt_base_regs
+ reg
);
1959 comparator
= cm
->dwt_comparator_list
;
1960 for (unsigned int i
= 0; i
< cm
->dwt_num_comp
; i
++, comparator
++) {
1963 comparator
->dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1964 for (j
= 0; j
< 3; j
++, reg
++)
1965 cortex_m_dwt_addreg(target
, cache
->reg_list
+ reg
,
1966 dwt_comp
+ 3 * i
+ j
);
1968 /* make sure we clear any watchpoints enabled on the target */
1969 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8, 0);
1972 *register_get_last_cache_p(&target
->reg_cache
) = cache
;
1973 cm
->dwt_cache
= cache
;
1975 LOG_DEBUG("DWT dwtcr 0x%" PRIx32
", comp %d, watch%s",
1976 dwtcr
, cm
->dwt_num_comp
,
1977 (dwtcr
& (0xf << 24)) ? " only" : "/trigger");
1979 /* REVISIT: if num_comp > 1, check whether comparator #1 can
1980 * implement single-address data value watchpoints ... so we
1981 * won't need to check it later, when asked to set one up.
1985 static void cortex_m_dwt_free(struct target
*target
)
1987 struct cortex_m_common
*cm
= target_to_cm(target
);
1988 struct reg_cache
*cache
= cm
->dwt_cache
;
1990 free(cm
->dwt_comparator_list
);
1991 cm
->dwt_comparator_list
= NULL
;
1992 cm
->dwt_num_comp
= 0;
1995 register_unlink_cache(&target
->reg_cache
, cache
);
1997 if (cache
->reg_list
) {
1998 for (size_t i
= 0; i
< cache
->num_regs
; i
++)
1999 free(cache
->reg_list
[i
].arch_info
);
2000 free(cache
->reg_list
);
2004 cm
->dwt_cache
= NULL
;
2007 #define MVFR0 0xe000ef40
2008 #define MVFR1 0xe000ef44
2010 #define MVFR0_DEFAULT_M4 0x10110021
2011 #define MVFR1_DEFAULT_M4 0x11000011
2013 #define MVFR0_DEFAULT_M7_SP 0x10110021
2014 #define MVFR0_DEFAULT_M7_DP 0x10110221
2015 #define MVFR1_DEFAULT_M7_SP 0x11000011
2016 #define MVFR1_DEFAULT_M7_DP 0x12000011
2018 static int cortex_m_find_mem_ap(struct adiv5_dap
*swjdp
,
2019 struct adiv5_ap
**debug_ap
)
2021 if (dap_find_ap(swjdp
, AP_TYPE_AHB3_AP
, debug_ap
) == ERROR_OK
)
2024 return dap_find_ap(swjdp
, AP_TYPE_AHB5_AP
, debug_ap
);
2027 int cortex_m_examine(struct target
*target
)
2030 uint32_t cpuid
, fpcr
, mvfr0
, mvfr1
;
2031 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
2032 struct adiv5_dap
*swjdp
= cortex_m
->armv7m
.arm
.dap
;
2033 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
2035 /* hla_target shares the examine handler but does not support
2037 if (!armv7m
->is_hla_target
) {
2038 if (cortex_m
->apsel
== DP_APSEL_INVALID
) {
2039 /* Search for the MEM-AP */
2040 retval
= cortex_m_find_mem_ap(swjdp
, &armv7m
->debug_ap
);
2041 if (retval
!= ERROR_OK
) {
2042 LOG_ERROR("Could not find MEM-AP to control the core");
2046 armv7m
->debug_ap
= dap_ap(swjdp
, cortex_m
->apsel
);
2049 /* Leave (only) generic DAP stuff for debugport_init(); */
2050 armv7m
->debug_ap
->memaccess_tck
= 8;
2052 retval
= mem_ap_init(armv7m
->debug_ap
);
2053 if (retval
!= ERROR_OK
)
2057 if (!target_was_examined(target
)) {
2058 target_set_examined(target
);
2060 /* Read from Device Identification Registers */
2061 retval
= target_read_u32(target
, CPUID
, &cpuid
);
2062 if (retval
!= ERROR_OK
)
2065 /* Get ARCH and CPU types */
2066 const enum cortex_m_partno core_partno
= (cpuid
& ARM_CPUID_PARTNO_MASK
) >> ARM_CPUID_PARTNO_POS
;
2068 for (unsigned int n
= 0; n
< ARRAY_SIZE(cortex_m_parts
); n
++) {
2069 if (core_partno
== cortex_m_parts
[n
].partno
) {
2070 cortex_m
->core_info
= &cortex_m_parts
[n
];
2075 if (!cortex_m
->core_info
) {
2076 LOG_ERROR("Cortex-M PARTNO 0x%x is unrecognized", core_partno
);
2080 armv7m
->arm
.arch
= cortex_m
->core_info
->arch
;
2082 LOG_INFO("%s: %s r%" PRId8
"p%" PRId8
" processor detected",
2083 target_name(target
),
2084 cortex_m
->core_info
->name
,
2085 (uint8_t)((cpuid
>> 20) & 0xf),
2086 (uint8_t)((cpuid
>> 0) & 0xf));
2088 cortex_m
->maskints_erratum
= false;
2089 if (core_partno
== CORTEX_M7_PARTNO
) {
2091 rev
= (cpuid
>> 20) & 0xf;
2092 patch
= (cpuid
>> 0) & 0xf;
2093 if ((rev
== 0) && (patch
< 2)) {
2094 LOG_WARNING("Silicon bug: single stepping may enter pending exception handler!");
2095 cortex_m
->maskints_erratum
= true;
2098 LOG_DEBUG("cpuid: 0x%8.8" PRIx32
"", cpuid
);
2100 if (cortex_m
->core_info
->flags
& CORTEX_M_F_HAS_FPV4
) {
2101 target_read_u32(target
, MVFR0
, &mvfr0
);
2102 target_read_u32(target
, MVFR1
, &mvfr1
);
2104 /* test for floating point feature on Cortex-M4 */
2105 if ((mvfr0
== MVFR0_DEFAULT_M4
) && (mvfr1
== MVFR1_DEFAULT_M4
)) {
2106 LOG_DEBUG("%s floating point feature FPv4_SP found", cortex_m
->core_info
->name
);
2107 armv7m
->fp_feature
= FPV4_SP
;
2109 } else if (cortex_m
->core_info
->flags
& CORTEX_M_F_HAS_FPV5
) {
2110 target_read_u32(target
, MVFR0
, &mvfr0
);
2111 target_read_u32(target
, MVFR1
, &mvfr1
);
2113 /* test for floating point features on Cortex-M7 */
2114 if ((mvfr0
== MVFR0_DEFAULT_M7_SP
) && (mvfr1
== MVFR1_DEFAULT_M7_SP
)) {
2115 LOG_DEBUG("%s floating point feature FPv5_SP found", cortex_m
->core_info
->name
);
2116 armv7m
->fp_feature
= FPV5_SP
;
2117 } else if ((mvfr0
== MVFR0_DEFAULT_M7_DP
) && (mvfr1
== MVFR1_DEFAULT_M7_DP
)) {
2118 LOG_DEBUG("%s floating point feature FPv5_DP found", cortex_m
->core_info
->name
);
2119 armv7m
->fp_feature
= FPV5_DP
;
2123 /* VECTRESET is supported only on ARMv7-M cores */
2124 cortex_m
->vectreset_supported
= armv7m
->arm
.arch
== ARM_ARCH_V7M
;
2126 /* Check for FPU, otherwise mark FPU register as non-existent */
2127 if (armv7m
->fp_feature
== FP_NONE
)
2128 for (size_t idx
= ARMV7M_FPU_FIRST_REG
; idx
<= ARMV7M_FPU_LAST_REG
; idx
++)
2129 armv7m
->arm
.core_cache
->reg_list
[idx
].exist
= false;
2131 if (armv7m
->arm
.arch
!= ARM_ARCH_V8M
)
2132 for (size_t idx
= ARMV8M_FIRST_REG
; idx
<= ARMV8M_LAST_REG
; idx
++)
2133 armv7m
->arm
.core_cache
->reg_list
[idx
].exist
= false;
2135 if (!armv7m
->is_hla_target
) {
2136 if (cortex_m
->core_info
->flags
& CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K
)
2137 /* Cortex-M3/M4 have 4096 bytes autoincrement range,
2138 * s. ARM IHI 0031C: MEM-AP 7.2.2 */
2139 armv7m
->debug_ap
->tar_autoincr_block
= (1 << 12);
2142 /* Enable debug requests */
2143 retval
= target_read_u32(target
, DCB_DHCSR
, &cortex_m
->dcb_dhcsr
);
2144 if (retval
!= ERROR_OK
)
2146 if (!(cortex_m
->dcb_dhcsr
& C_DEBUGEN
)) {
2147 uint32_t dhcsr
= (cortex_m
->dcb_dhcsr
| C_DEBUGEN
) & ~(C_HALT
| C_STEP
| C_MASKINTS
);
2149 retval
= target_write_u32(target
, DCB_DHCSR
, DBGKEY
| (dhcsr
& 0x0000FFFFUL
));
2150 if (retval
!= ERROR_OK
)
2152 cortex_m
->dcb_dhcsr
= dhcsr
;
2155 /* Configure trace modules */
2156 retval
= target_write_u32(target
, DCB_DEMCR
, TRCENA
| armv7m
->demcr
);
2157 if (retval
!= ERROR_OK
)
2160 if (armv7m
->trace_config
.itm_deferred_config
)
2161 armv7m_trace_itm_config(target
);
2163 /* NOTE: FPB and DWT are both optional. */
2166 target_read_u32(target
, FP_CTRL
, &fpcr
);
2167 /* bits [14:12] and [7:4] */
2168 cortex_m
->fp_num_code
= ((fpcr
>> 8) & 0x70) | ((fpcr
>> 4) & 0xF);
2169 cortex_m
->fp_num_lit
= (fpcr
>> 8) & 0xF;
2170 /* Detect flash patch revision, see RM DDI 0403E.b page C1-817.
2171 Revision is zero base, fp_rev == 1 means Rev.2 ! */
2172 cortex_m
->fp_rev
= (fpcr
>> 28) & 0xf;
2173 free(cortex_m
->fp_comparator_list
);
2174 cortex_m
->fp_comparator_list
= calloc(
2175 cortex_m
->fp_num_code
+ cortex_m
->fp_num_lit
,
2176 sizeof(struct cortex_m_fp_comparator
));
2177 cortex_m
->fpb_enabled
= fpcr
& 1;
2178 for (unsigned int i
= 0; i
< cortex_m
->fp_num_code
+ cortex_m
->fp_num_lit
; i
++) {
2179 cortex_m
->fp_comparator_list
[i
].type
=
2180 (i
< cortex_m
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
2181 cortex_m
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
2183 /* make sure we clear any breakpoints enabled on the target */
2184 target_write_u32(target
, cortex_m
->fp_comparator_list
[i
].fpcr_address
, 0);
2186 LOG_DEBUG("FPB fpcr 0x%" PRIx32
", numcode %i, numlit %i",
2188 cortex_m
->fp_num_code
,
2189 cortex_m
->fp_num_lit
);
2192 cortex_m_dwt_free(target
);
2193 cortex_m_dwt_setup(cortex_m
, target
);
2195 /* These hardware breakpoints only work for code in flash! */
2196 LOG_INFO("%s: target has %d breakpoints, %d watchpoints",
2197 target_name(target
),
2198 cortex_m
->fp_num_code
,
2199 cortex_m
->dwt_num_comp
);
2205 static int cortex_m_dcc_read(struct target
*target
, uint8_t *value
, uint8_t *ctrl
)
2207 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
2212 retval
= mem_ap_read_buf_noincr(armv7m
->debug_ap
, buf
, 2, 1, DCB_DCRDR
);
2213 if (retval
!= ERROR_OK
)
2216 dcrdr
= target_buffer_get_u16(target
, buf
);
2217 *ctrl
= (uint8_t)dcrdr
;
2218 *value
= (uint8_t)(dcrdr
>> 8);
2220 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
2222 /* write ack back to software dcc register
2223 * signify we have read data */
2224 if (dcrdr
& (1 << 0)) {
2225 target_buffer_set_u16(target
, buf
, 0);
2226 retval
= mem_ap_write_buf_noincr(armv7m
->debug_ap
, buf
, 2, 1, DCB_DCRDR
);
2227 if (retval
!= ERROR_OK
)
2234 static int cortex_m_target_request_data(struct target
*target
,
2235 uint32_t size
, uint8_t *buffer
)
2241 for (i
= 0; i
< (size
* 4); i
++) {
2242 int retval
= cortex_m_dcc_read(target
, &data
, &ctrl
);
2243 if (retval
!= ERROR_OK
)
2251 static int cortex_m_handle_target_request(void *priv
)
2253 struct target
*target
= priv
;
2254 if (!target_was_examined(target
))
2257 if (!target
->dbg_msg_enabled
)
2260 if (target
->state
== TARGET_RUNNING
) {
2265 retval
= cortex_m_dcc_read(target
, &data
, &ctrl
);
2266 if (retval
!= ERROR_OK
)
2269 /* check if we have data */
2270 if (ctrl
& (1 << 0)) {
2273 /* we assume target is quick enough */
2275 for (int i
= 1; i
<= 3; i
++) {
2276 retval
= cortex_m_dcc_read(target
, &data
, &ctrl
);
2277 if (retval
!= ERROR_OK
)
2279 request
|= ((uint32_t)data
<< (i
* 8));
2281 target_request(target
, request
);
2288 static int cortex_m_init_arch_info(struct target
*target
,
2289 struct cortex_m_common
*cortex_m
, struct adiv5_dap
*dap
)
2291 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
2293 armv7m_init_arch_info(target
, armv7m
);
2295 /* default reset mode is to use srst if fitted
2296 * if not it will use CORTEX_M3_RESET_VECTRESET */
2297 cortex_m
->soft_reset_config
= CORTEX_M_RESET_VECTRESET
;
2299 armv7m
->arm
.dap
= dap
;
2301 /* register arch-specific functions */
2302 armv7m
->examine_debug_reason
= cortex_m_examine_debug_reason
;
2304 armv7m
->post_debug_entry
= NULL
;
2306 armv7m
->pre_restore_context
= NULL
;
2308 armv7m
->load_core_reg_u32
= cortex_m_load_core_reg_u32
;
2309 armv7m
->store_core_reg_u32
= cortex_m_store_core_reg_u32
;
2311 target_register_timer_callback(cortex_m_handle_target_request
, 1,
2312 TARGET_TIMER_TYPE_PERIODIC
, target
);
2317 static int cortex_m_target_create(struct target
*target
, Jim_Interp
*interp
)
2319 struct adiv5_private_config
*pc
;
2321 pc
= (struct adiv5_private_config
*)target
->private_config
;
2322 if (adiv5_verify_config(pc
) != ERROR_OK
)
2325 struct cortex_m_common
*cortex_m
= calloc(1, sizeof(struct cortex_m_common
));
2327 LOG_ERROR("No memory creating target");
2331 cortex_m
->common_magic
= CORTEX_M_COMMON_MAGIC
;
2332 cortex_m
->apsel
= pc
->ap_num
;
2334 cortex_m_init_arch_info(target
, cortex_m
, pc
->dap
);
2339 /*--------------------------------------------------------------------------*/
2341 static int cortex_m_verify_pointer(struct command_invocation
*cmd
,
2342 struct cortex_m_common
*cm
)
2344 if (cm
->common_magic
!= CORTEX_M_COMMON_MAGIC
) {
2345 command_print(cmd
, "target is not a Cortex-M");
2346 return ERROR_TARGET_INVALID
;
2352 * Only stuff below this line should need to verify that its target
2353 * is a Cortex-M3. Everything else should have indirected through the
2354 * cortexm3_target structure, which is only used with CM3 targets.
2357 COMMAND_HANDLER(handle_cortex_m_vector_catch_command
)
2359 struct target
*target
= get_current_target(CMD_CTX
);
2360 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
2361 struct armv7m_common
*armv7m
= &cortex_m
->armv7m
;
2365 static const struct {
2369 { "hard_err", VC_HARDERR
, },
2370 { "int_err", VC_INTERR
, },
2371 { "bus_err", VC_BUSERR
, },
2372 { "state_err", VC_STATERR
, },
2373 { "chk_err", VC_CHKERR
, },
2374 { "nocp_err", VC_NOCPERR
, },
2375 { "mm_err", VC_MMERR
, },
2376 { "reset", VC_CORERESET
, },
2379 retval
= cortex_m_verify_pointer(CMD
, cortex_m
);
2380 if (retval
!= ERROR_OK
)
2383 if (!target_was_examined(target
)) {
2384 LOG_ERROR("Target not examined yet");
2388 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DEMCR
, &demcr
);
2389 if (retval
!= ERROR_OK
)
2395 if (CMD_ARGC
== 1) {
2396 if (strcmp(CMD_ARGV
[0], "all") == 0) {
2397 catch = VC_HARDERR
| VC_INTERR
| VC_BUSERR
2398 | VC_STATERR
| VC_CHKERR
| VC_NOCPERR
2399 | VC_MMERR
| VC_CORERESET
;
2401 } else if (strcmp(CMD_ARGV
[0], "none") == 0)
2404 while (CMD_ARGC
-- > 0) {
2406 for (i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++) {
2407 if (strcmp(CMD_ARGV
[CMD_ARGC
], vec_ids
[i
].name
) != 0)
2409 catch |= vec_ids
[i
].mask
;
2412 if (i
== ARRAY_SIZE(vec_ids
)) {
2413 LOG_ERROR("No CM3 vector '%s'", CMD_ARGV
[CMD_ARGC
]);
2414 return ERROR_COMMAND_SYNTAX_ERROR
;
2418 /* For now, armv7m->demcr only stores vector catch flags. */
2419 armv7m
->demcr
= catch;
2424 /* write, but don't assume it stuck (why not??) */
2425 retval
= mem_ap_write_u32(armv7m
->debug_ap
, DCB_DEMCR
, demcr
);
2426 if (retval
!= ERROR_OK
)
2428 retval
= mem_ap_read_atomic_u32(armv7m
->debug_ap
, DCB_DEMCR
, &demcr
);
2429 if (retval
!= ERROR_OK
)
2432 /* FIXME be sure to clear DEMCR on clean server shutdown.
2433 * Otherwise the vector catch hardware could fire when there's
2434 * no debugger hooked up, causing much confusion...
2438 for (unsigned i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++) {
2439 command_print(CMD
, "%9s: %s", vec_ids
[i
].name
,
2440 (demcr
& vec_ids
[i
].mask
) ? "catch" : "ignore");
2446 COMMAND_HANDLER(handle_cortex_m_mask_interrupts_command
)
2448 struct target
*target
= get_current_target(CMD_CTX
);
2449 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
2452 static const struct jim_nvp nvp_maskisr_modes
[] = {
2453 { .name
= "auto", .value
= CORTEX_M_ISRMASK_AUTO
},
2454 { .name
= "off", .value
= CORTEX_M_ISRMASK_OFF
},
2455 { .name
= "on", .value
= CORTEX_M_ISRMASK_ON
},
2456 { .name
= "steponly", .value
= CORTEX_M_ISRMASK_STEPONLY
},
2457 { .name
= NULL
, .value
= -1 },
2459 const struct jim_nvp
*n
;
2462 retval
= cortex_m_verify_pointer(CMD
, cortex_m
);
2463 if (retval
!= ERROR_OK
)
2466 if (target
->state
!= TARGET_HALTED
) {
2467 command_print(CMD
, "target must be stopped for \"%s\" command", CMD_NAME
);
2472 n
= jim_nvp_name2value_simple(nvp_maskisr_modes
, CMD_ARGV
[0]);
2474 return ERROR_COMMAND_SYNTAX_ERROR
;
2475 cortex_m
->isrmasking_mode
= n
->value
;
2476 cortex_m_set_maskints_for_halt(target
);
2479 n
= jim_nvp_value2name_simple(nvp_maskisr_modes
, cortex_m
->isrmasking_mode
);
2480 command_print(CMD
, "cortex_m interrupt mask %s", n
->name
);
2485 COMMAND_HANDLER(handle_cortex_m_reset_config_command
)
2487 struct target
*target
= get_current_target(CMD_CTX
);
2488 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
2492 retval
= cortex_m_verify_pointer(CMD
, cortex_m
);
2493 if (retval
!= ERROR_OK
)
2497 if (strcmp(*CMD_ARGV
, "sysresetreq") == 0)
2498 cortex_m
->soft_reset_config
= CORTEX_M_RESET_SYSRESETREQ
;
2500 else if (strcmp(*CMD_ARGV
, "vectreset") == 0) {
2501 if (target_was_examined(target
)
2502 && !cortex_m
->vectreset_supported
)
2503 LOG_WARNING("VECTRESET is not supported on your Cortex-M core!");
2505 cortex_m
->soft_reset_config
= CORTEX_M_RESET_VECTRESET
;
2508 return ERROR_COMMAND_SYNTAX_ERROR
;
2511 switch (cortex_m
->soft_reset_config
) {
2512 case CORTEX_M_RESET_SYSRESETREQ
:
2513 reset_config
= "sysresetreq";
2516 case CORTEX_M_RESET_VECTRESET
:
2517 reset_config
= "vectreset";
2521 reset_config
= "unknown";
2525 command_print(CMD
, "cortex_m reset_config %s", reset_config
);
2530 static const struct command_registration cortex_m_exec_command_handlers
[] = {
2533 .handler
= handle_cortex_m_mask_interrupts_command
,
2534 .mode
= COMMAND_EXEC
,
2535 .help
= "mask cortex_m interrupts",
2536 .usage
= "['auto'|'on'|'off'|'steponly']",
2539 .name
= "vector_catch",
2540 .handler
= handle_cortex_m_vector_catch_command
,
2541 .mode
= COMMAND_EXEC
,
2542 .help
= "configure hardware vectors to trigger debug entry",
2543 .usage
= "['all'|'none'|('bus_err'|'chk_err'|...)*]",
2546 .name
= "reset_config",
2547 .handler
= handle_cortex_m_reset_config_command
,
2548 .mode
= COMMAND_ANY
,
2549 .help
= "configure software reset handling",
2550 .usage
= "['sysresetreq'|'vectreset']",
2552 COMMAND_REGISTRATION_DONE
2554 static const struct command_registration cortex_m_command_handlers
[] = {
2556 .chain
= armv7m_command_handlers
,
2559 .chain
= armv7m_trace_command_handlers
,
2561 /* START_DEPRECATED_TPIU */
2563 .chain
= arm_tpiu_deprecated_command_handlers
,
2565 /* END_DEPRECATED_TPIU */
2568 .mode
= COMMAND_EXEC
,
2569 .help
= "Cortex-M command group",
2571 .chain
= cortex_m_exec_command_handlers
,
2574 .chain
= rtt_target_command_handlers
,
2576 COMMAND_REGISTRATION_DONE
2579 struct target_type cortexm_target
= {
2582 .poll
= cortex_m_poll
,
2583 .arch_state
= armv7m_arch_state
,
2585 .target_request_data
= cortex_m_target_request_data
,
2587 .halt
= cortex_m_halt
,
2588 .resume
= cortex_m_resume
,
2589 .step
= cortex_m_step
,
2591 .assert_reset
= cortex_m_assert_reset
,
2592 .deassert_reset
= cortex_m_deassert_reset
,
2593 .soft_reset_halt
= cortex_m_soft_reset_halt
,
2595 .get_gdb_arch
= arm_get_gdb_arch
,
2596 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
2598 .read_memory
= cortex_m_read_memory
,
2599 .write_memory
= cortex_m_write_memory
,
2600 .checksum_memory
= armv7m_checksum_memory
,
2601 .blank_check_memory
= armv7m_blank_check_memory
,
2603 .run_algorithm
= armv7m_run_algorithm
,
2604 .start_algorithm
= armv7m_start_algorithm
,
2605 .wait_algorithm
= armv7m_wait_algorithm
,
2607 .add_breakpoint
= cortex_m_add_breakpoint
,
2608 .remove_breakpoint
= cortex_m_remove_breakpoint
,
2609 .add_watchpoint
= cortex_m_add_watchpoint
,
2610 .remove_watchpoint
= cortex_m_remove_watchpoint
,
2611 .hit_watchpoint
= cortex_m_hit_watchpoint
,
2613 .commands
= cortex_m_command_handlers
,
2614 .target_create
= cortex_m_target_create
,
2615 .target_jim_configure
= adiv5_jim_configure
,
2616 .init_target
= cortex_m_init_target
,
2617 .examine
= cortex_m_examine
,
2618 .deinit_target
= cortex_m_deinit_target
,
2620 .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)