1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2006 by Magnus Lundin *
8 * Copyright (C) 2008 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
27 * Cortex-M3(tm) TRM, ARM DDI 0337E (r1p1) and 0337G (r2p0) *
29 ***************************************************************************/
34 #include "breakpoints.h"
35 #include "cortex_m3.h"
36 #include "target_request.h"
37 #include "target_type.h"
38 #include "arm_disassembler.h"
40 #include "arm_opcodes.h"
41 #include "arm_semihosting.h"
43 /* NOTE: most of this should work fine for the Cortex-M1 and
44 * Cortex-M0 cores too, although they're ARMv6-M not ARMv7-M.
45 * Some differences: M0/M1 doesn't have FBP remapping or the
46 * DWT tracing/profiling support. (So the cycle counter will
47 * not be usable; the other stuff isn't currently used here.)
49 * Although there are some workarounds for errata seen only in r0p0
50 * silicon, such old parts are hard to find and thus not much tested
55 /* forward declarations */
56 static int cortex_m3_set_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
);
57 static int cortex_m3_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
);
58 static void cortex_m3_enable_watchpoints(struct target
*target
);
59 static int cortex_m3_store_core_reg_u32(struct target
*target
,
60 enum armv7m_regtype type
, uint32_t num
, uint32_t value
);
62 static int cortexm3_dap_read_coreregister_u32(struct adiv5_dap
*swjdp
,
63 uint32_t *value
, int regnum
)
68 /* because the DCB_DCRDR is used for the emulated dcc channel
69 * we have to save/restore the DCB_DCRDR when used */
71 mem_ap_read_u32(swjdp
, DCB_DCRDR
, &dcrdr
);
73 /* mem_ap_write_u32(swjdp, DCB_DCRSR, regnum); */
74 retval
= dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRSR
& 0xFFFFFFF0);
75 if (retval
!= ERROR_OK
)
77 retval
= dap_queue_ap_write(swjdp
, AP_REG_BD0
| (DCB_DCRSR
& 0xC), regnum
);
78 if (retval
!= ERROR_OK
)
81 /* mem_ap_read_u32(swjdp, DCB_DCRDR, value); */
82 retval
= dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRDR
& 0xFFFFFFF0);
83 if (retval
!= ERROR_OK
)
85 retval
= dap_queue_ap_read(swjdp
, AP_REG_BD0
| (DCB_DCRDR
& 0xC), value
);
86 if (retval
!= ERROR_OK
)
89 retval
= dap_run(swjdp
);
90 if (retval
!= ERROR_OK
)
93 /* restore DCB_DCRDR - this needs to be in a seperate
94 * transaction otherwise the emulated DCC channel breaks */
95 if (retval
== ERROR_OK
)
96 retval
= mem_ap_write_atomic_u32(swjdp
, DCB_DCRDR
, dcrdr
);
101 static int cortexm3_dap_write_coreregister_u32(struct adiv5_dap
*swjdp
,
102 uint32_t value
, int regnum
)
107 /* because the DCB_DCRDR is used for the emulated dcc channel
108 * we have to save/restore the DCB_DCRDR when used */
110 mem_ap_read_u32(swjdp
, DCB_DCRDR
, &dcrdr
);
112 /* mem_ap_write_u32(swjdp, DCB_DCRDR, core_regs[i]); */
113 retval
= dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRDR
& 0xFFFFFFF0);
114 if (retval
!= ERROR_OK
)
116 retval
= dap_queue_ap_write(swjdp
, AP_REG_BD0
| (DCB_DCRDR
& 0xC), value
);
119 /* mem_ap_write_u32(swjdp, DCB_DCRSR, i | DCRSR_WnR); */
120 retval
= dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRSR
& 0xFFFFFFF0);
121 if (retval
!= ERROR_OK
)
123 retval
= dap_queue_ap_write(swjdp
, AP_REG_BD0
| (DCB_DCRSR
& 0xC), regnum
| DCRSR_WnR
);
126 retval
= dap_run(swjdp
);
128 /* restore DCB_DCRDR - this needs to be in a seperate
129 * transaction otherwise the emulated DCC channel breaks */
130 if (retval
== ERROR_OK
)
131 retval
= mem_ap_write_atomic_u32(swjdp
, DCB_DCRDR
, dcrdr
);
136 static int cortex_m3_write_debug_halt_mask(struct target
*target
,
137 uint32_t mask_on
, uint32_t mask_off
)
139 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
140 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
142 /* mask off status bits */
143 cortex_m3
->dcb_dhcsr
&= ~((0xFFFF << 16) | mask_off
);
144 /* create new register mask */
145 cortex_m3
->dcb_dhcsr
|= DBGKEY
| C_DEBUGEN
| mask_on
;
147 return mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, cortex_m3
->dcb_dhcsr
);
150 static int cortex_m3_clear_halt(struct target
*target
)
152 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
153 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
155 /* clear step if any */
156 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_STEP
);
158 /* Read Debug Fault Status Register */
159 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
161 /* Clear Debug Fault Status */
162 mem_ap_write_atomic_u32(swjdp
, NVIC_DFSR
, cortex_m3
->nvic_dfsr
);
163 LOG_DEBUG(" NVIC_DFSR 0x%" PRIx32
"", cortex_m3
->nvic_dfsr
);
168 static int cortex_m3_single_step_core(struct target
*target
)
170 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
171 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
174 /* backup dhcsr reg */
175 dhcsr_save
= cortex_m3
->dcb_dhcsr
;
177 /* Mask interrupts before clearing halt, if done already. This avoids
178 * Erratum 377497 (fixed in r1p0) where setting MASKINTS while clearing
179 * HALT can put the core into an unknown state.
181 if (!(cortex_m3
->dcb_dhcsr
& C_MASKINTS
))
182 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
,
183 DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
184 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
,
185 DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
188 /* restore dhcsr reg */
189 cortex_m3
->dcb_dhcsr
= dhcsr_save
;
190 cortex_m3_clear_halt(target
);
195 static int cortex_m3_endreset_event(struct target
*target
)
200 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
201 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
202 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
203 struct cortex_m3_fp_comparator
*fp_list
= cortex_m3
->fp_comparator_list
;
204 struct cortex_m3_dwt_comparator
*dwt_list
= cortex_m3
->dwt_comparator_list
;
206 /* REVISIT The four debug monitor bits are currently ignored... */
207 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
208 LOG_DEBUG("DCB_DEMCR = 0x%8.8" PRIx32
"",dcb_demcr
);
210 /* this register is used for emulated dcc channel */
211 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
213 /* Enable debug requests */
214 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
215 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
216 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
218 /* clear any interrupt masking */
219 cortex_m3_write_debug_halt_mask(target
, 0, C_MASKINTS
);
221 /* Enable features controlled by ITM and DWT blocks, and catch only
222 * the vectors we were told to pay attention to.
224 * Target firmware is responsible for all fault handling policy
225 * choices *EXCEPT* explicitly scripted overrides like "vector_catch"
226 * or manual updates to the NVIC SHCSR and CCR registers.
228 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| armv7m
->demcr
);
230 /* Paranoia: evidently some (early?) chips don't preserve all the
231 * debug state (including FBP, DWT, etc) across reset...
235 target_write_u32(target
, FP_CTRL
, 3);
236 cortex_m3
->fpb_enabled
= 1;
238 /* Restore FPB registers */
239 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
241 target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
244 /* Restore DWT registers */
245 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
247 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 0,
249 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 4,
251 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 8,
252 dwt_list
[i
].function
);
254 retval
= dap_run(swjdp
);
255 if (retval
!= ERROR_OK
)
258 register_cache_invalidate(cortex_m3
->armv7m
.core_cache
);
260 /* make sure we have latest dhcsr flags */
261 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
266 static int cortex_m3_examine_debug_reason(struct target
*target
)
268 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
270 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
271 /* only check the debug reason if we don't know it already */
273 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
274 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
276 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
278 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
279 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
280 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
282 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
283 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
284 else if (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
)
285 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
286 else /* EXTERNAL, HALTED */
287 target
->debug_reason
= DBG_REASON_UNDEFINED
;
293 static int cortex_m3_examine_exception_reason(struct target
*target
)
295 uint32_t shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
296 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
297 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
300 mem_ap_read_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
301 switch (armv7m
->exception_number
)
305 case 3: /* Hard Fault */
306 mem_ap_read_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
307 if (except_sr
& 0x40000000)
309 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &cfsr
);
312 case 4: /* Memory Management */
313 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
314 mem_ap_read_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
316 case 5: /* Bus Fault */
317 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
318 mem_ap_read_u32(swjdp
, NVIC_BFAR
, &except_ar
);
320 case 6: /* Usage Fault */
321 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
323 case 11: /* SVCall */
325 case 12: /* Debug Monitor */
326 mem_ap_read_u32(swjdp
, NVIC_DFSR
, &except_sr
);
328 case 14: /* PendSV */
330 case 15: /* SysTick */
336 retval
= dap_run(swjdp
);
337 if (retval
== ERROR_OK
)
338 LOG_DEBUG("%s SHCSR 0x%" PRIx32
", SR 0x%" PRIx32
339 ", CFSR 0x%" PRIx32
", AR 0x%" PRIx32
,
340 armv7m_exception_string(armv7m
->exception_number
),
341 shcsr
, except_sr
, cfsr
, except_ar
);
345 /* PSP is used in some thread modes */
346 static const int armv7m_psp_reg_map
[17] = {
347 ARMV7M_R0
, ARMV7M_R1
, ARMV7M_R2
, ARMV7M_R3
,
348 ARMV7M_R4
, ARMV7M_R5
, ARMV7M_R6
, ARMV7M_R7
,
349 ARMV7M_R8
, ARMV7M_R9
, ARMV7M_R10
, ARMV7M_R11
,
350 ARMV7M_R12
, ARMV7M_PSP
, ARMV7M_R14
, ARMV7M_PC
,
354 /* MSP is used in handler and some thread modes */
355 static const int armv7m_msp_reg_map
[17] = {
356 ARMV7M_R0
, ARMV7M_R1
, ARMV7M_R2
, ARMV7M_R3
,
357 ARMV7M_R4
, ARMV7M_R5
, ARMV7M_R6
, ARMV7M_R7
,
358 ARMV7M_R8
, ARMV7M_R9
, ARMV7M_R10
, ARMV7M_R11
,
359 ARMV7M_R12
, ARMV7M_MSP
, ARMV7M_R14
, ARMV7M_PC
,
363 static int cortex_m3_debug_entry(struct target
*target
)
368 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
369 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
370 struct arm
*arm
= &armv7m
->arm
;
371 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
376 cortex_m3_clear_halt(target
);
377 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
379 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
382 /* Examine target state and mode */
383 /* First load register acessible through core debug port*/
384 int num_regs
= armv7m
->core_cache
->num_regs
;
386 for (i
= 0; i
< num_regs
; i
++)
388 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
389 armv7m
->read_core_reg(target
, i
);
392 r
= armv7m
->core_cache
->reg_list
+ ARMV7M_xPSR
;
393 xPSR
= buf_get_u32(r
->value
, 0, 32);
395 #ifdef ARMV7_GDB_HACKS
396 /* FIXME this breaks on scan chains with more than one Cortex-M3.
397 * Instead, each CM3 should have its own dummy value...
399 /* copy real xpsr reg for gdb, setting thumb bit */
400 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 0, 32, xPSR
);
401 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 5, 1, 1);
402 armv7m_gdb_dummy_cpsr_reg
.valid
= r
->valid
;
403 armv7m_gdb_dummy_cpsr_reg
.dirty
= r
->dirty
;
406 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
410 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
413 /* Are we in an exception handler */
416 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
417 armv7m
->exception_number
= (xPSR
& 0x1FF);
419 arm
->core_mode
= ARM_MODE_HANDLER
;
420 arm
->map
= armv7m_msp_reg_map
;
424 unsigned control
= buf_get_u32(armv7m
->core_cache
425 ->reg_list
[ARMV7M_CONTROL
].value
, 0, 2);
427 /* is this thread privileged? */
428 armv7m
->core_mode
= control
& 1;
429 arm
->core_mode
= armv7m
->core_mode
430 ? ARM_MODE_USER_THREAD
433 /* which stack is it using? */
435 arm
->map
= armv7m_psp_reg_map
;
437 arm
->map
= armv7m_msp_reg_map
;
439 armv7m
->exception_number
= 0;
442 if (armv7m
->exception_number
)
444 cortex_m3_examine_exception_reason(target
);
447 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32
", target->state: %s",
448 armv7m_mode_strings
[armv7m
->core_mode
],
449 *(uint32_t*)(arm
->pc
->value
),
450 target_state_name(target
));
452 if (armv7m
->post_debug_entry
)
454 retval
= armv7m
->post_debug_entry(target
);
455 if (retval
!= ERROR_OK
)
462 static int cortex_m3_poll(struct target
*target
)
465 enum target_state prev_target_state
= target
->state
;
466 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
467 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
469 /* Read from Debug Halting Control and Status Register */
470 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
471 if (retval
!= ERROR_OK
)
473 target
->state
= TARGET_UNKNOWN
;
477 /* Recover from lockup. See ARMv7-M architecture spec,
478 * section B1.5.15 "Unrecoverable exception cases".
480 * REVISIT Is there a better way to report and handle this?
482 if (cortex_m3
->dcb_dhcsr
& S_LOCKUP
) {
483 LOG_WARNING("%s -- clearing lockup after double fault",
484 target_name(target
));
485 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
486 target
->debug_reason
= DBG_REASON_DBGRQ
;
488 /* refresh status bits */
489 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
492 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
494 /* check if still in reset */
495 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
497 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
499 target
->state
= TARGET_RESET
;
504 if (target
->state
== TARGET_RESET
)
506 /* Cannot switch context while running so endreset is
507 * called with target->state == TARGET_RESET
509 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%" PRIx32
,
510 cortex_m3
->dcb_dhcsr
);
511 cortex_m3_endreset_event(target
);
512 target
->state
= TARGET_RUNNING
;
513 prev_target_state
= TARGET_RUNNING
;
516 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
518 target
->state
= TARGET_HALTED
;
520 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
522 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
525 if (arm_semihosting(target
, &retval
) != 0)
528 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
530 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
533 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
536 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
540 /* REVISIT when S_SLEEP is set, it's in a Sleep or DeepSleep state.
541 * How best to model low power modes?
544 if (target
->state
== TARGET_UNKNOWN
)
546 /* check if processor is retiring instructions */
547 if (cortex_m3
->dcb_dhcsr
& S_RETIRE_ST
)
549 target
->state
= TARGET_RUNNING
;
557 static int cortex_m3_halt(struct target
*target
)
559 LOG_DEBUG("target->state: %s",
560 target_state_name(target
));
562 if (target
->state
== TARGET_HALTED
)
564 LOG_DEBUG("target was already halted");
568 if (target
->state
== TARGET_UNKNOWN
)
570 LOG_WARNING("target was in unknown state when halt was requested");
573 if (target
->state
== TARGET_RESET
)
575 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst())
577 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
578 return ERROR_TARGET_FAILURE
;
582 /* we came here in a reset_halt or reset_init sequence
583 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
585 target
->debug_reason
= DBG_REASON_DBGRQ
;
591 /* Write to Debug Halting Control and Status Register */
592 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
594 target
->debug_reason
= DBG_REASON_DBGRQ
;
599 static int cortex_m3_soft_reset_halt(struct target
*target
)
601 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
602 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
603 uint32_t dcb_dhcsr
= 0;
604 int retval
, timeout
= 0;
606 /* Enter debug state on reset; restore DEMCR in endreset_event() */
607 mem_ap_write_u32(swjdp
, DCB_DEMCR
,
608 TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
610 /* Request a core-only reset */
611 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
,
612 AIRCR_VECTKEY
| AIRCR_VECTRESET
);
613 target
->state
= TARGET_RESET
;
615 /* registers are now invalid */
616 register_cache_invalidate(cortex_m3
->armv7m
.core_cache
);
618 while (timeout
< 100)
620 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
621 if (retval
== ERROR_OK
)
623 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
,
624 &cortex_m3
->nvic_dfsr
);
625 if ((dcb_dhcsr
& S_HALT
)
626 && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
628 LOG_DEBUG("system reset-halted, DHCSR 0x%08x, "
630 (unsigned) dcb_dhcsr
,
631 (unsigned) cortex_m3
->nvic_dfsr
);
632 cortex_m3_poll(target
);
633 /* FIXME restore user's vector catch config */
637 LOG_DEBUG("waiting for system reset-halt, "
638 "DHCSR 0x%08x, %d ms",
639 (unsigned) dcb_dhcsr
, timeout
);
648 static void cortex_m3_enable_breakpoints(struct target
*target
)
650 struct breakpoint
*breakpoint
= target
->breakpoints
;
652 /* set any pending breakpoints */
655 if (!breakpoint
->set
)
656 cortex_m3_set_breakpoint(target
, breakpoint
);
657 breakpoint
= breakpoint
->next
;
661 static int cortex_m3_resume(struct target
*target
, int current
,
662 uint32_t address
, int handle_breakpoints
, int debug_execution
)
664 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
665 struct breakpoint
*breakpoint
= NULL
;
669 if (target
->state
!= TARGET_HALTED
)
671 LOG_WARNING("target not halted");
672 return ERROR_TARGET_NOT_HALTED
;
675 if (!debug_execution
)
677 target_free_all_working_areas(target
);
678 cortex_m3_enable_breakpoints(target
);
679 cortex_m3_enable_watchpoints(target
);
684 r
= armv7m
->core_cache
->reg_list
+ ARMV7M_PRIMASK
;
686 /* Disable interrupts */
687 /* We disable interrupts in the PRIMASK register instead of
688 * masking with C_MASKINTS. This is probably the same issue
689 * as Cortex-M3 Erratum 377493 (fixed in r1p0): C_MASKINTS
690 * in parallel with disabled interrupts can cause local faults
693 * REVISIT this clearly breaks non-debug execution, since the
694 * PRIMASK register state isn't saved/restored... workaround
695 * by never resuming app code after debug execution.
697 buf_set_u32(r
->value
, 0, 1, 1);
701 /* Make sure we are in Thumb mode */
702 r
= armv7m
->core_cache
->reg_list
+ ARMV7M_xPSR
;
703 buf_set_u32(r
->value
, 24, 1, 1);
708 /* current = 1: continue on current pc, otherwise continue at <address> */
712 buf_set_u32(r
->value
, 0, 32, address
);
717 /* if we halted last time due to a bkpt instruction
718 * then we have to manually step over it, otherwise
719 * the core will break again */
721 if (!breakpoint_find(target
, buf_get_u32(r
->value
, 0, 32))
724 armv7m_maybe_skip_bkpt_inst(target
, NULL
);
727 resume_pc
= buf_get_u32(r
->value
, 0, 32);
729 armv7m_restore_context(target
);
731 /* the front-end may request us not to handle breakpoints */
732 if (handle_breakpoints
)
734 /* Single step past breakpoint at current address */
735 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
737 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
" (ID: %d)",
739 breakpoint
->unique_id
);
740 cortex_m3_unset_breakpoint(target
, breakpoint
);
741 cortex_m3_single_step_core(target
);
742 cortex_m3_set_breakpoint(target
, breakpoint
);
747 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
749 target
->debug_reason
= DBG_REASON_NOTHALTED
;
751 /* registers are now invalid */
752 register_cache_invalidate(armv7m
->core_cache
);
754 if (!debug_execution
)
756 target
->state
= TARGET_RUNNING
;
757 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
758 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
762 target
->state
= TARGET_DEBUG_RUNNING
;
763 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
764 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
770 /* int irqstepcount = 0; */
771 static int cortex_m3_step(struct target
*target
, int current
,
772 uint32_t address
, int handle_breakpoints
)
774 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
775 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
776 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
777 struct breakpoint
*breakpoint
= NULL
;
778 struct reg
*pc
= armv7m
->arm
.pc
;
779 bool bkpt_inst_found
= false;
781 if (target
->state
!= TARGET_HALTED
)
783 LOG_WARNING("target not halted");
784 return ERROR_TARGET_NOT_HALTED
;
787 /* current = 1: continue on current pc, otherwise continue at <address> */
789 buf_set_u32(pc
->value
, 0, 32, address
);
791 /* the front-end may request us not to handle breakpoints */
792 if (handle_breakpoints
) {
793 breakpoint
= breakpoint_find(target
,
794 buf_get_u32(pc
->value
, 0, 32));
796 cortex_m3_unset_breakpoint(target
, breakpoint
);
799 armv7m_maybe_skip_bkpt_inst(target
, &bkpt_inst_found
);
801 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
803 armv7m_restore_context(target
);
805 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
807 /* if no bkpt instruction is found at pc then we can perform
808 * a normal step, otherwise we have to manually step over the bkpt
809 * instruction - as such simulate a step */
810 if (bkpt_inst_found
== false)
812 /* set step and clear halt */
813 cortex_m3_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
816 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
818 /* registers are now invalid */
819 register_cache_invalidate(cortex_m3
->armv7m
.core_cache
);
822 cortex_m3_set_breakpoint(target
, breakpoint
);
824 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
825 " nvic_icsr = 0x%" PRIx32
,
826 cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
829 retval
= cortex_m3_debug_entry(target
);
830 if (retval
!= ERROR_OK
)
832 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
834 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
835 " nvic_icsr = 0x%" PRIx32
,
836 cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
841 static int cortex_m3_assert_reset(struct target
*target
)
843 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
844 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
847 LOG_DEBUG("target->state: %s",
848 target_state_name(target
));
850 enum reset_types jtag_reset_config
= jtag_get_reset_config();
853 * We can reset Cortex-M3 targets using just the NVIC without
854 * requiring SRST, getting a SoC reset (or a core-only reset)
855 * instead of a system reset.
857 if (!(jtag_reset_config
& RESET_HAS_SRST
))
860 /* Enable debug requests */
861 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
862 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
863 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
865 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
867 if (!target
->reset_halt
)
869 /* Set/Clear C_MASKINTS in a separate operation */
870 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
871 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
,
872 DBGKEY
| C_DEBUGEN
| C_HALT
);
874 /* clear any debug flags before resuming */
875 cortex_m3_clear_halt(target
);
877 /* clear C_HALT in dhcsr reg */
878 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
882 /* Halt in debug on reset; endreset_event() restores DEMCR.
884 * REVISIT catching BUSERR presumably helps to defend against
885 * bad vector table entries. Should this include MMERR or
888 mem_ap_write_atomic_u32(swjdp
, DCB_DEMCR
,
889 TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
893 * When nRST is asserted on most Stellaris devices, it clears some of
894 * the debug state. The ARMv7M and Cortex-M3 TRMs say that's wrong;
895 * and OpenOCD depends on those TRMs. So we won't use SRST on those
896 * chips. (Only power-on reset should affect debug state, beyond a
897 * few specified bits; not the chip's nRST input, wired to SRST.)
899 * REVISIT current errata specs don't seem to cover this issue.
900 * Do we have more details than this email?
901 * https://lists.berlios.de/pipermail
902 * /openocd-development/2008-August/003065.html
904 if (strcmp(target
->variant
, "lm3s") == 0)
906 /* Check for silicon revisions with the issue. */
909 if (target_read_u32(target
, 0x400fe000, &did0
) == ERROR_OK
)
911 switch ((did0
>> 16) & 0xff)
914 /* all Sandstorm suffer issue */
920 /* Fury and DustDevil rev A have
921 * this nRST problem. It should
922 * be fixed in rev B silicon.
924 if (((did0
>> 8) & 0xff) == 0)
928 /* Tempest should be fine. */
936 /* default to asserting srst */
937 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
939 jtag_add_reset(1, 1);
943 jtag_add_reset(0, 1);
948 /* Use a standard Cortex-M3 software reset mechanism.
949 * SYSRESETREQ will reset SoC peripherals outside the
950 * core, like watchdog timers, if the SoC wires it up
951 * correctly. Else VECRESET can reset just the core.
953 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
,
954 AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
955 LOG_DEBUG("Using Cortex-M3 SYSRESETREQ");
958 /* I do not know why this is necessary, but it
959 * fixes strange effects (step/resume cause NMI
960 * after reset) on LM3S6918 -- Michael Schwingen
963 mem_ap_read_atomic_u32(swjdp
, NVIC_AIRCR
, &tmp
);
967 target
->state
= TARGET_RESET
;
968 jtag_add_sleep(50000);
970 register_cache_invalidate(cortex_m3
->armv7m
.core_cache
);
972 if (target
->reset_halt
)
975 if ((retval
= target_halt(target
)) != ERROR_OK
)
982 static int cortex_m3_deassert_reset(struct target
*target
)
984 LOG_DEBUG("target->state: %s",
985 target_state_name(target
));
987 /* deassert reset lines */
988 jtag_add_reset(0, 0);
994 cortex_m3_set_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
999 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1000 struct cortex_m3_fp_comparator
*comparator_list
= cortex_m3
->fp_comparator_list
;
1002 if (breakpoint
->set
)
1004 LOG_WARNING("breakpoint (BPID: %d) already set", breakpoint
->unique_id
);
1008 if (cortex_m3
->auto_bp_type
)
1010 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1013 if (breakpoint
->type
== BKPT_HARD
)
1015 while (comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
1017 if (fp_num
>= cortex_m3
->fp_num_code
)
1019 LOG_ERROR("Can not find free FPB Comparator!");
1022 breakpoint
->set
= fp_num
+ 1;
1023 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
1024 comparator_list
[fp_num
].used
= 1;
1025 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
1026 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
1027 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32
"", fp_num
, comparator_list
[fp_num
].fpcr_value
);
1028 if (!cortex_m3
->fpb_enabled
)
1030 LOG_DEBUG("FPB wasn't enabled, do it now");
1031 target_write_u32(target
, FP_CTRL
, 3);
1034 else if (breakpoint
->type
== BKPT_SOFT
)
1038 /* NOTE: on ARMv6-M and ARMv7-M, BKPT(0xab) is used for
1039 * semihosting; don't use that. Otherwise the BKPT
1040 * parameter is arbitrary.
1042 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1043 retval
= target_read_memory(target
,
1044 breakpoint
->address
& 0xFFFFFFFE,
1045 breakpoint
->length
, 1,
1046 breakpoint
->orig_instr
);
1047 if (retval
!= ERROR_OK
)
1049 retval
= target_write_memory(target
,
1050 breakpoint
->address
& 0xFFFFFFFE,
1051 breakpoint
->length
, 1,
1053 if (retval
!= ERROR_OK
)
1055 breakpoint
->set
= true;
1058 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
1059 breakpoint
->unique_id
,
1060 (int)(breakpoint
->type
),
1061 breakpoint
->address
,
1069 cortex_m3_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1072 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1073 struct cortex_m3_fp_comparator
* comparator_list
= cortex_m3
->fp_comparator_list
;
1075 if (!breakpoint
->set
)
1077 LOG_WARNING("breakpoint not set");
1081 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
1082 breakpoint
->unique_id
,
1083 (int)(breakpoint
->type
),
1084 breakpoint
->address
,
1088 if (breakpoint
->type
== BKPT_HARD
)
1090 int fp_num
= breakpoint
->set
- 1;
1091 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
1093 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
1096 comparator_list
[fp_num
].used
= 0;
1097 comparator_list
[fp_num
].fpcr_value
= 0;
1098 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
1102 /* restore original instruction (kept in target endianness) */
1103 if (breakpoint
->length
== 4)
1105 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
1112 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
1118 breakpoint
->set
= false;
1124 cortex_m3_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1126 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1128 if (cortex_m3
->auto_bp_type
)
1130 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1131 #ifdef ARMV7_GDB_HACKS
1132 if (breakpoint
->length
!= 2) {
1133 /* XXX Hack: Replace all breakpoints with length != 2 with
1134 * a hardware breakpoint. */
1135 breakpoint
->type
= BKPT_HARD
;
1136 breakpoint
->length
= 2;
1141 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
1143 LOG_INFO("flash patch comparator requested outside code memory region");
1144 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1147 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
1149 LOG_INFO("soft breakpoint requested in code (flash) memory region");
1150 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1153 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
1155 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
1156 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1159 if ((breakpoint
->length
!= 2))
1161 LOG_INFO("only breakpoints of two bytes length supported");
1162 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1165 if (breakpoint
->type
== BKPT_HARD
)
1166 cortex_m3
->fp_code_available
--;
1167 cortex_m3_set_breakpoint(target
, breakpoint
);
1173 cortex_m3_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1175 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1177 /* REVISIT why check? FBP can be updated with core running ... */
1178 if (target
->state
!= TARGET_HALTED
)
1180 LOG_WARNING("target not halted");
1181 return ERROR_TARGET_NOT_HALTED
;
1184 if (cortex_m3
->auto_bp_type
)
1186 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1189 if (breakpoint
->set
)
1191 cortex_m3_unset_breakpoint(target
, breakpoint
);
1194 if (breakpoint
->type
== BKPT_HARD
)
1195 cortex_m3
->fp_code_available
++;
1201 cortex_m3_set_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1204 uint32_t mask
, temp
;
1205 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1207 /* watchpoint params were validated earlier */
1209 temp
= watchpoint
->length
;
1216 /* REVISIT Don't fully trust these "not used" records ... users
1217 * may set up breakpoints by hand, e.g. dual-address data value
1218 * watchpoint using comparator #1; comparator #0 matching cycle
1219 * count; send data trace info through ITM and TPIU; etc
1221 struct cortex_m3_dwt_comparator
*comparator
;
1223 for (comparator
= cortex_m3
->dwt_comparator_list
;
1224 comparator
->used
&& dwt_num
< cortex_m3
->dwt_num_comp
;
1225 comparator
++, dwt_num
++)
1227 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
1229 LOG_ERROR("Can not find free DWT Comparator");
1232 comparator
->used
= 1;
1233 watchpoint
->set
= dwt_num
+ 1;
1235 comparator
->comp
= watchpoint
->address
;
1236 target_write_u32(target
, comparator
->dwt_comparator_address
+ 0,
1239 comparator
->mask
= mask
;
1240 target_write_u32(target
, comparator
->dwt_comparator_address
+ 4,
1243 switch (watchpoint
->rw
) {
1245 comparator
->function
= 5;
1248 comparator
->function
= 6;
1251 comparator
->function
= 7;
1254 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1255 comparator
->function
);
1257 LOG_DEBUG("Watchpoint (ID %d) DWT%d 0x%08x 0x%x 0x%05x",
1258 watchpoint
->unique_id
, dwt_num
,
1259 (unsigned) comparator
->comp
,
1260 (unsigned) comparator
->mask
,
1261 (unsigned) comparator
->function
);
1266 cortex_m3_unset_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1268 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1269 struct cortex_m3_dwt_comparator
*comparator
;
1272 if (!watchpoint
->set
)
1274 LOG_WARNING("watchpoint (wpid: %d) not set",
1275 watchpoint
->unique_id
);
1279 dwt_num
= watchpoint
->set
- 1;
1281 LOG_DEBUG("Watchpoint (ID %d) DWT%d address: 0x%08x clear",
1282 watchpoint
->unique_id
, dwt_num
,
1283 (unsigned) watchpoint
->address
);
1285 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1287 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1291 comparator
= cortex_m3
->dwt_comparator_list
+ dwt_num
;
1292 comparator
->used
= 0;
1293 comparator
->function
= 0;
1294 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1295 comparator
->function
);
1297 watchpoint
->set
= false;
1303 cortex_m3_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1305 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1307 if (cortex_m3
->dwt_comp_available
< 1)
1309 LOG_DEBUG("no comparators?");
1310 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1313 /* hardware doesn't support data value masking */
1314 if (watchpoint
->mask
!= ~(uint32_t)0) {
1315 LOG_DEBUG("watchpoint value masks not supported");
1316 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1319 /* hardware allows address masks of up to 32K */
1322 for (mask
= 0; mask
< 16; mask
++) {
1323 if ((1u << mask
) == watchpoint
->length
)
1327 LOG_DEBUG("unsupported watchpoint length");
1328 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1330 if (watchpoint
->address
& ((1 << mask
) - 1)) {
1331 LOG_DEBUG("watchpoint address is unaligned");
1332 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1335 /* Caller doesn't seem to be able to describe watching for data
1336 * values of zero; that flags "no value".
1338 * REVISIT This DWT may well be able to watch for specific data
1339 * values. Requires comparator #1 to set DATAVMATCH and match
1340 * the data, and another comparator (DATAVADDR0) matching addr.
1342 if (watchpoint
->value
) {
1343 LOG_DEBUG("data value watchpoint not YET supported");
1344 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1347 cortex_m3
->dwt_comp_available
--;
1348 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1354 cortex_m3_remove_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1356 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1358 /* REVISIT why check? DWT can be updated with core running ... */
1359 if (target
->state
!= TARGET_HALTED
)
1361 LOG_WARNING("target not halted");
1362 return ERROR_TARGET_NOT_HALTED
;
1365 if (watchpoint
->set
)
1367 cortex_m3_unset_watchpoint(target
, watchpoint
);
1370 cortex_m3
->dwt_comp_available
++;
1371 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1376 static void cortex_m3_enable_watchpoints(struct target
*target
)
1378 struct watchpoint
*watchpoint
= target
->watchpoints
;
1380 /* set any pending watchpoints */
1383 if (!watchpoint
->set
)
1384 cortex_m3_set_watchpoint(target
, watchpoint
);
1385 watchpoint
= watchpoint
->next
;
1389 static int cortex_m3_load_core_reg_u32(struct target
*target
,
1390 enum armv7m_regtype type
, uint32_t num
, uint32_t * value
)
1393 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1394 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1396 /* NOTE: we "know" here that the register identifiers used
1397 * in the v7m header match the Cortex-M3 Debug Core Register
1398 * Selector values for R0..R15, xPSR, MSP, and PSP.
1402 /* read a normal core register */
1403 retval
= cortexm3_dap_read_coreregister_u32(swjdp
, value
, num
);
1405 if (retval
!= ERROR_OK
)
1407 LOG_ERROR("JTAG failure %i",retval
);
1408 return ERROR_JTAG_DEVICE_ERROR
;
1410 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
"",(int)num
,*value
);
1413 case ARMV7M_PRIMASK
:
1414 case ARMV7M_BASEPRI
:
1415 case ARMV7M_FAULTMASK
:
1416 case ARMV7M_CONTROL
:
1417 /* Cortex-M3 packages these four registers as bitfields
1418 * in one Debug Core register. So say r0 and r2 docs;
1419 * it was removed from r1 docs, but still works.
1421 cortexm3_dap_read_coreregister_u32(swjdp
, value
, 20);
1425 case ARMV7M_PRIMASK
:
1426 *value
= buf_get_u32((uint8_t*)value
, 0, 1);
1429 case ARMV7M_BASEPRI
:
1430 *value
= buf_get_u32((uint8_t*)value
, 8, 8);
1433 case ARMV7M_FAULTMASK
:
1434 *value
= buf_get_u32((uint8_t*)value
, 16, 1);
1437 case ARMV7M_CONTROL
:
1438 *value
= buf_get_u32((uint8_t*)value
, 24, 2);
1442 LOG_DEBUG("load from special reg %i value 0x%" PRIx32
"", (int)num
, *value
);
1446 return ERROR_INVALID_ARGUMENTS
;
1452 static int cortex_m3_store_core_reg_u32(struct target
*target
,
1453 enum armv7m_regtype type
, uint32_t num
, uint32_t value
)
1457 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1458 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1460 #ifdef ARMV7_GDB_HACKS
1461 /* If the LR register is being modified, make sure it will put us
1462 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1463 * hack to deal with the fact that gdb will sometimes "forge"
1464 * return addresses, and doesn't set the LSB correctly (i.e., when
1465 * printing expressions containing function calls, it sets LR = 0.)
1466 * Valid exception return codes have bit 0 set too.
1468 if (num
== ARMV7M_R14
)
1472 /* NOTE: we "know" here that the register identifiers used
1473 * in the v7m header match the Cortex-M3 Debug Core Register
1474 * Selector values for R0..R15, xPSR, MSP, and PSP.
1478 retval
= cortexm3_dap_write_coreregister_u32(swjdp
, value
, num
);
1479 if (retval
!= ERROR_OK
)
1483 LOG_ERROR("JTAG failure %i", retval
);
1484 r
= armv7m
->core_cache
->reg_list
+ num
;
1485 r
->dirty
= r
->valid
;
1486 return ERROR_JTAG_DEVICE_ERROR
;
1488 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", (int)num
, value
);
1491 case ARMV7M_PRIMASK
:
1492 case ARMV7M_BASEPRI
:
1493 case ARMV7M_FAULTMASK
:
1494 case ARMV7M_CONTROL
:
1495 /* Cortex-M3 packages these four registers as bitfields
1496 * in one Debug Core register. So say r0 and r2 docs;
1497 * it was removed from r1 docs, but still works.
1499 cortexm3_dap_read_coreregister_u32(swjdp
, ®
, 20);
1503 case ARMV7M_PRIMASK
:
1504 buf_set_u32((uint8_t*)®
, 0, 1, value
);
1507 case ARMV7M_BASEPRI
:
1508 buf_set_u32((uint8_t*)®
, 8, 8, value
);
1511 case ARMV7M_FAULTMASK
:
1512 buf_set_u32((uint8_t*)®
, 16, 1, value
);
1515 case ARMV7M_CONTROL
:
1516 buf_set_u32((uint8_t*)®
, 24, 2, value
);
1520 cortexm3_dap_write_coreregister_u32(swjdp
, reg
, 20);
1522 LOG_DEBUG("write special reg %i value 0x%" PRIx32
" ", (int)num
, value
);
1526 return ERROR_INVALID_ARGUMENTS
;
1532 static int cortex_m3_read_memory(struct target
*target
, uint32_t address
,
1533 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1535 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1536 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1537 int retval
= ERROR_INVALID_ARGUMENTS
;
1539 /* cortex_m3 handles unaligned memory access */
1540 if (count
&& buffer
) {
1543 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1546 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1549 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1557 static int cortex_m3_write_memory(struct target
*target
, uint32_t address
,
1558 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1560 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1561 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1562 int retval
= ERROR_INVALID_ARGUMENTS
;
1564 if (count
&& buffer
) {
1567 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1570 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1573 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1581 static int cortex_m3_bulk_write_memory(struct target
*target
, uint32_t address
,
1582 uint32_t count
, uint8_t *buffer
)
1584 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1587 static int cortex_m3_init_target(struct command_context
*cmd_ctx
,
1588 struct target
*target
)
1590 armv7m_build_reg_cache(target
);
1594 /* REVISIT cache valid/dirty bits are unmaintained. We could set "valid"
1595 * on r/w if the core is not running, and clear on resume or reset ... or
1596 * at least, in a post_restore_context() method.
1599 struct dwt_reg_state
{
1600 struct target
*target
;
1602 uint32_t value
; /* scratch/cache */
1605 static int cortex_m3_dwt_get_reg(struct reg
*reg
)
1607 struct dwt_reg_state
*state
= reg
->arch_info
;
1609 return target_read_u32(state
->target
, state
->addr
, &state
->value
);
1612 static int cortex_m3_dwt_set_reg(struct reg
*reg
, uint8_t *buf
)
1614 struct dwt_reg_state
*state
= reg
->arch_info
;
1616 return target_write_u32(state
->target
, state
->addr
,
1617 buf_get_u32(buf
, 0, reg
->size
));
1626 static struct dwt_reg dwt_base_regs
[] = {
1627 { DWT_CTRL
, "dwt_ctrl", 32, },
1628 /* NOTE that Erratum 532314 (fixed r2p0) affects CYCCNT: it wrongly
1629 * increments while the core is asleep.
1631 { DWT_CYCCNT
, "dwt_cyccnt", 32, },
1632 /* plus some 8 bit counters, useful for profiling with TPIU */
1635 static struct dwt_reg dwt_comp
[] = {
1636 #define DWT_COMPARATOR(i) \
1637 { DWT_COMP0 + 0x10 * (i), "dwt_" #i "_comp", 32, }, \
1638 { DWT_MASK0 + 0x10 * (i), "dwt_" #i "_mask", 4, }, \
1639 { DWT_FUNCTION0 + 0x10 * (i), "dwt_" #i "_function", 32, }
1644 #undef DWT_COMPARATOR
1647 static const struct reg_arch_type dwt_reg_type
= {
1648 .get
= cortex_m3_dwt_get_reg
,
1649 .set
= cortex_m3_dwt_set_reg
,
1653 cortex_m3_dwt_addreg(struct target
*t
, struct reg
*r
, struct dwt_reg
*d
)
1655 struct dwt_reg_state
*state
;
1657 state
= calloc(1, sizeof *state
);
1660 state
->addr
= d
->addr
;
1665 r
->value
= &state
->value
;
1666 r
->arch_info
= state
;
1667 r
->type
= &dwt_reg_type
;
1671 cortex_m3_dwt_setup(struct cortex_m3_common
*cm3
, struct target
*target
)
1674 struct reg_cache
*cache
;
1675 struct cortex_m3_dwt_comparator
*comparator
;
1678 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1680 LOG_DEBUG("no DWT");
1684 cm3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1685 cm3
->dwt_comp_available
= cm3
->dwt_num_comp
;
1686 cm3
->dwt_comparator_list
= calloc(cm3
->dwt_num_comp
,
1687 sizeof(struct cortex_m3_dwt_comparator
));
1688 if (!cm3
->dwt_comparator_list
) {
1690 cm3
->dwt_num_comp
= 0;
1691 LOG_ERROR("out of mem");
1695 cache
= calloc(1, sizeof *cache
);
1698 free(cm3
->dwt_comparator_list
);
1701 cache
->name
= "cortex-m3 dwt registers";
1702 cache
->num_regs
= 2 + cm3
->dwt_num_comp
* 3;
1703 cache
->reg_list
= calloc(cache
->num_regs
, sizeof *cache
->reg_list
);
1704 if (!cache
->reg_list
) {
1709 for (reg
= 0; reg
< 2; reg
++)
1710 cortex_m3_dwt_addreg(target
, cache
->reg_list
+ reg
,
1711 dwt_base_regs
+ reg
);
1713 comparator
= cm3
->dwt_comparator_list
;
1714 for (i
= 0; i
< cm3
->dwt_num_comp
; i
++, comparator
++) {
1717 comparator
->dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1718 for (j
= 0; j
< 3; j
++, reg
++)
1719 cortex_m3_dwt_addreg(target
, cache
->reg_list
+ reg
,
1720 dwt_comp
+ 3 * i
+ j
);
1723 *register_get_last_cache_p(&target
->reg_cache
) = cache
;
1724 cm3
->dwt_cache
= cache
;
1726 LOG_DEBUG("DWT dwtcr 0x%" PRIx32
", comp %d, watch%s",
1727 dwtcr
, cm3
->dwt_num_comp
,
1728 (dwtcr
& (0xf << 24)) ? " only" : "/trigger");
1730 /* REVISIT: if num_comp > 1, check whether comparator #1 can
1731 * implement single-address data value watchpoints ... so we
1732 * won't need to check it later, when asked to set one up.
1736 static int cortex_m3_examine(struct target
*target
)
1739 uint32_t cpuid
, fpcr
;
1741 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1742 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
1744 if ((retval
= ahbap_debugport_init(swjdp
)) != ERROR_OK
)
1747 if (!target_was_examined(target
))
1749 target_set_examined(target
);
1751 /* Read from Device Identification Registers */
1752 retval
= target_read_u32(target
, CPUID
, &cpuid
);
1753 if (retval
!= ERROR_OK
)
1756 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1757 LOG_DEBUG("Cortex-M3 r%" PRId8
"p%" PRId8
" processor detected",
1758 (uint8_t)((cpuid
>> 20) & 0xf), (uint8_t)((cpuid
>> 0) & 0xf));
1759 LOG_DEBUG("cpuid: 0x%8.8" PRIx32
"", cpuid
);
1761 /* NOTE: FPB and DWT are both optional. */
1764 target_read_u32(target
, FP_CTRL
, &fpcr
);
1765 cortex_m3
->auto_bp_type
= 1;
1766 cortex_m3
->fp_num_code
= ((fpcr
>> 8) & 0x70) | ((fpcr
>> 4) & 0xF); /* bits [14:12] and [7:4] */
1767 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1768 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1769 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(struct cortex_m3_fp_comparator
));
1770 cortex_m3
->fpb_enabled
= fpcr
& 1;
1771 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1773 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1774 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1776 LOG_DEBUG("FPB fpcr 0x%" PRIx32
", numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1779 cortex_m3_dwt_setup(cortex_m3
, target
);
1781 /* These hardware breakpoints only work for code in flash! */
1782 LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints",
1783 target_name(target
),
1784 cortex_m3
->fp_num_code
,
1785 cortex_m3
->dwt_num_comp
);
1791 static int cortex_m3_dcc_read(struct adiv5_dap
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1795 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1796 *ctrl
= (uint8_t)dcrdr
;
1797 *value
= (uint8_t)(dcrdr
>> 8);
1799 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1801 /* write ack back to software dcc register
1802 * signify we have read data */
1803 if (dcrdr
& (1 << 0))
1806 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1812 static int cortex_m3_target_request_data(struct target
*target
,
1813 uint32_t size
, uint8_t *buffer
)
1815 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1816 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1821 for (i
= 0; i
< (size
* 4); i
++)
1823 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1830 static int cortex_m3_handle_target_request(void *priv
)
1832 struct target
*target
= priv
;
1833 if (!target_was_examined(target
))
1835 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1836 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1838 if (!target
->dbg_msg_enabled
)
1841 if (target
->state
== TARGET_RUNNING
)
1846 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1848 /* check if we have data */
1849 if (ctrl
& (1 << 0))
1853 /* we assume target is quick enough */
1855 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1856 request
|= (data
<< 8);
1857 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1858 request
|= (data
<< 16);
1859 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1860 request
|= (data
<< 24);
1861 target_request(target
, request
);
1868 static int cortex_m3_init_arch_info(struct target
*target
,
1869 struct cortex_m3_common
*cortex_m3
, struct jtag_tap
*tap
)
1872 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
1874 armv7m_init_arch_info(target
, armv7m
);
1876 /* prepare JTAG information for the new target */
1877 cortex_m3
->jtag_info
.tap
= tap
;
1878 cortex_m3
->jtag_info
.scann_size
= 4;
1880 armv7m
->arm
.dap
= &armv7m
->dap
;
1882 /* Leave (only) generic DAP stuff for debugport_init(); */
1883 armv7m
->dap
.jtag_info
= &cortex_m3
->jtag_info
;
1884 armv7m
->dap
.memaccess_tck
= 8;
1885 /* Cortex-M3 has 4096 bytes autoincrement range */
1886 armv7m
->dap
.tar_autoincr_block
= (1 << 12);
1888 /* register arch-specific functions */
1889 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1891 armv7m
->post_debug_entry
= NULL
;
1893 armv7m
->pre_restore_context
= NULL
;
1895 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1896 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1898 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1900 if ((retval
= arm_jtag_setup_connection(&cortex_m3
->jtag_info
)) != ERROR_OK
)
1908 static int cortex_m3_target_create(struct target
*target
, Jim_Interp
*interp
)
1910 struct cortex_m3_common
*cortex_m3
= calloc(1,sizeof(struct cortex_m3_common
));
1912 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1913 cortex_m3_init_arch_info(target
, cortex_m3
, target
->tap
);
1918 /*--------------------------------------------------------------------------*/
1920 static int cortex_m3_verify_pointer(struct command_context
*cmd_ctx
,
1921 struct cortex_m3_common
*cm3
)
1923 if (cm3
->common_magic
!= CORTEX_M3_COMMON_MAGIC
) {
1924 command_print(cmd_ctx
, "target is not a Cortex-M3");
1925 return ERROR_TARGET_INVALID
;
1931 * Only stuff below this line should need to verify that its target
1932 * is a Cortex-M3. Everything else should have indirected through the
1933 * cortexm3_target structure, which is only used with CM3 targets.
1936 static const struct {
1940 { "hard_err", VC_HARDERR
, },
1941 { "int_err", VC_INTERR
, },
1942 { "bus_err", VC_BUSERR
, },
1943 { "state_err", VC_STATERR
, },
1944 { "chk_err", VC_CHKERR
, },
1945 { "nocp_err", VC_NOCPERR
, },
1946 { "mm_err", VC_MMERR
, },
1947 { "reset", VC_CORERESET
, },
1950 COMMAND_HANDLER(handle_cortex_m3_vector_catch_command
)
1952 struct target
*target
= get_current_target(CMD_CTX
);
1953 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1954 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
1955 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1959 retval
= cortex_m3_verify_pointer(CMD_CTX
, cortex_m3
);
1960 if (retval
!= ERROR_OK
)
1963 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &demcr
);
1968 if (CMD_ARGC
== 1) {
1969 if (strcmp(CMD_ARGV
[0], "all") == 0) {
1970 catch = VC_HARDERR
| VC_INTERR
| VC_BUSERR
1971 | VC_STATERR
| VC_CHKERR
| VC_NOCPERR
1972 | VC_MMERR
| VC_CORERESET
;
1974 } else if (strcmp(CMD_ARGV
[0], "none") == 0) {
1978 while (CMD_ARGC
-- > 0) {
1980 for (i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++) {
1981 if (strcmp(CMD_ARGV
[CMD_ARGC
], vec_ids
[i
].name
) != 0)
1983 catch |= vec_ids
[i
].mask
;
1986 if (i
== ARRAY_SIZE(vec_ids
)) {
1987 LOG_ERROR("No CM3 vector '%s'", CMD_ARGV
[CMD_ARGC
]);
1988 return ERROR_INVALID_ARGUMENTS
;
1992 /* For now, armv7m->demcr only stores vector catch flags. */
1993 armv7m
->demcr
= catch;
1998 /* write, but don't assume it stuck (why not??) */
1999 mem_ap_write_u32(swjdp
, DCB_DEMCR
, demcr
);
2000 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &demcr
);
2002 /* FIXME be sure to clear DEMCR on clean server shutdown.
2003 * Otherwise the vector catch hardware could fire when there's
2004 * no debugger hooked up, causing much confusion...
2008 for (unsigned i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++)
2010 command_print(CMD_CTX
, "%9s: %s", vec_ids
[i
].name
,
2011 (demcr
& vec_ids
[i
].mask
) ? "catch" : "ignore");
2017 COMMAND_HANDLER(handle_cortex_m3_mask_interrupts_command
)
2019 struct target
*target
= get_current_target(CMD_CTX
);
2020 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
2023 retval
= cortex_m3_verify_pointer(CMD_CTX
, cortex_m3
);
2024 if (retval
!= ERROR_OK
)
2027 if (target
->state
!= TARGET_HALTED
)
2029 command_print(CMD_CTX
, "target must be stopped for \"%s\" command", CMD_NAME
);
2036 COMMAND_PARSE_ON_OFF(CMD_ARGV
[0], enable
);
2037 uint32_t mask_on
= C_HALT
| (enable
? C_MASKINTS
: 0);
2038 uint32_t mask_off
= enable
? 0 : C_MASKINTS
;
2039 cortex_m3_write_debug_halt_mask(target
, mask_on
, mask_off
);
2042 command_print(CMD_CTX
, "cortex_m3 interrupt mask %s",
2043 (cortex_m3
->dcb_dhcsr
& C_MASKINTS
) ? "on" : "off");
2048 static const struct command_registration cortex_m3_exec_command_handlers
[] = {
2051 .handler
= handle_cortex_m3_mask_interrupts_command
,
2052 .mode
= COMMAND_EXEC
,
2053 .help
= "mask cortex_m3 interrupts",
2054 .usage
= "['on'|'off']",
2057 .name
= "vector_catch",
2058 .handler
= handle_cortex_m3_vector_catch_command
,
2059 .mode
= COMMAND_EXEC
,
2060 .help
= "configure hardware vectors to trigger debug entry",
2061 .usage
= "['all'|'none'|('bus_err'|'chk_err'|...)*]",
2063 COMMAND_REGISTRATION_DONE
2065 static const struct command_registration cortex_m3_command_handlers
[] = {
2067 .chain
= armv7m_command_handlers
,
2070 .name
= "cortex_m3",
2071 .mode
= COMMAND_EXEC
,
2072 .help
= "Cortex-M3 command group",
2073 .chain
= cortex_m3_exec_command_handlers
,
2075 COMMAND_REGISTRATION_DONE
2078 struct target_type cortexm3_target
=
2080 .name
= "cortex_m3",
2082 .poll
= cortex_m3_poll
,
2083 .arch_state
= armv7m_arch_state
,
2085 .target_request_data
= cortex_m3_target_request_data
,
2087 .halt
= cortex_m3_halt
,
2088 .resume
= cortex_m3_resume
,
2089 .step
= cortex_m3_step
,
2091 .assert_reset
= cortex_m3_assert_reset
,
2092 .deassert_reset
= cortex_m3_deassert_reset
,
2093 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
2095 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
2097 .read_memory
= cortex_m3_read_memory
,
2098 .write_memory
= cortex_m3_write_memory
,
2099 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
2100 .checksum_memory
= armv7m_checksum_memory
,
2101 .blank_check_memory
= armv7m_blank_check_memory
,
2103 .run_algorithm
= armv7m_run_algorithm
,
2105 .add_breakpoint
= cortex_m3_add_breakpoint
,
2106 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
2107 .add_watchpoint
= cortex_m3_add_watchpoint
,
2108 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
2110 .commands
= cortex_m3_command_handlers
,
2111 .target_create
= cortex_m3_target_create
,
2112 .init_target
= cortex_m3_init_target
,
2113 .examine
= cortex_m3_examine
,
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)