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 retval
= mem_ap_read_u32(swjdp
, DCB_DCRDR
, &dcrdr
);
72 if (retval
!= ERROR_OK
)
75 /* mem_ap_write_u32(swjdp, DCB_DCRSR, regnum); */
76 retval
= dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRSR
& 0xFFFFFFF0);
77 if (retval
!= ERROR_OK
)
79 retval
= dap_queue_ap_write(swjdp
, AP_REG_BD0
| (DCB_DCRSR
& 0xC), regnum
);
80 if (retval
!= ERROR_OK
)
83 /* mem_ap_read_u32(swjdp, DCB_DCRDR, value); */
84 retval
= dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRDR
& 0xFFFFFFF0);
85 if (retval
!= ERROR_OK
)
87 retval
= dap_queue_ap_read(swjdp
, AP_REG_BD0
| (DCB_DCRDR
& 0xC), value
);
88 if (retval
!= ERROR_OK
)
91 retval
= dap_run(swjdp
);
92 if (retval
!= ERROR_OK
)
95 /* restore DCB_DCRDR - this needs to be in a seperate
96 * transaction otherwise the emulated DCC channel breaks */
97 if (retval
== ERROR_OK
)
98 retval
= mem_ap_write_atomic_u32(swjdp
, DCB_DCRDR
, dcrdr
);
103 static int cortexm3_dap_write_coreregister_u32(struct adiv5_dap
*swjdp
,
104 uint32_t value
, int regnum
)
109 /* because the DCB_DCRDR is used for the emulated dcc channel
110 * we have to save/restore the DCB_DCRDR when used */
112 retval
= mem_ap_read_u32(swjdp
, DCB_DCRDR
, &dcrdr
);
113 if (retval
!= ERROR_OK
)
116 /* mem_ap_write_u32(swjdp, DCB_DCRDR, core_regs[i]); */
117 retval
= dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRDR
& 0xFFFFFFF0);
118 if (retval
!= ERROR_OK
)
120 retval
= dap_queue_ap_write(swjdp
, AP_REG_BD0
| (DCB_DCRDR
& 0xC), value
);
123 /* mem_ap_write_u32(swjdp, DCB_DCRSR, i | DCRSR_WnR); */
124 retval
= dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRSR
& 0xFFFFFFF0);
125 if (retval
!= ERROR_OK
)
127 retval
= dap_queue_ap_write(swjdp
, AP_REG_BD0
| (DCB_DCRSR
& 0xC), regnum
| DCRSR_WnR
);
130 retval
= dap_run(swjdp
);
132 /* restore DCB_DCRDR - this needs to be in a seperate
133 * transaction otherwise the emulated DCC channel breaks */
134 if (retval
== ERROR_OK
)
135 retval
= mem_ap_write_atomic_u32(swjdp
, DCB_DCRDR
, dcrdr
);
140 static int cortex_m3_write_debug_halt_mask(struct target
*target
,
141 uint32_t mask_on
, uint32_t mask_off
)
143 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
144 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
146 /* mask off status bits */
147 cortex_m3
->dcb_dhcsr
&= ~((0xFFFF << 16) | mask_off
);
148 /* create new register mask */
149 cortex_m3
->dcb_dhcsr
|= DBGKEY
| C_DEBUGEN
| mask_on
;
151 return mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, cortex_m3
->dcb_dhcsr
);
154 static int cortex_m3_clear_halt(struct target
*target
)
156 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
157 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
160 /* clear step if any */
161 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_STEP
);
163 /* Read Debug Fault Status Register */
164 retval
= mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
165 if (retval
!= ERROR_OK
)
168 /* Clear Debug Fault Status */
169 mem_ap_write_atomic_u32(swjdp
, NVIC_DFSR
, cortex_m3
->nvic_dfsr
);
170 LOG_DEBUG(" NVIC_DFSR 0x%" PRIx32
"", cortex_m3
->nvic_dfsr
);
175 static int cortex_m3_single_step_core(struct target
*target
)
177 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
178 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
181 /* backup dhcsr reg */
182 dhcsr_save
= cortex_m3
->dcb_dhcsr
;
184 /* Mask interrupts before clearing halt, if done already. This avoids
185 * Erratum 377497 (fixed in r1p0) where setting MASKINTS while clearing
186 * HALT can put the core into an unknown state.
188 if (!(cortex_m3
->dcb_dhcsr
& C_MASKINTS
))
189 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
,
190 DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
191 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
,
192 DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
195 /* restore dhcsr reg */
196 cortex_m3
->dcb_dhcsr
= dhcsr_save
;
197 cortex_m3_clear_halt(target
);
202 static int cortex_m3_endreset_event(struct target
*target
)
207 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
208 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
209 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
210 struct cortex_m3_fp_comparator
*fp_list
= cortex_m3
->fp_comparator_list
;
211 struct cortex_m3_dwt_comparator
*dwt_list
= cortex_m3
->dwt_comparator_list
;
213 /* REVISIT The four debug monitor bits are currently ignored... */
214 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
215 if (retval
!= ERROR_OK
)
217 LOG_DEBUG("DCB_DEMCR = 0x%8.8" PRIx32
"",dcb_demcr
);
219 /* this register is used for emulated dcc channel */
220 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
222 /* Enable debug requests */
223 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
224 if (retval
!= ERROR_OK
)
226 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
227 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
229 /* clear any interrupt masking */
230 cortex_m3_write_debug_halt_mask(target
, 0, C_MASKINTS
);
232 /* Enable features controlled by ITM and DWT blocks, and catch only
233 * the vectors we were told to pay attention to.
235 * Target firmware is responsible for all fault handling policy
236 * choices *EXCEPT* explicitly scripted overrides like "vector_catch"
237 * or manual updates to the NVIC SHCSR and CCR registers.
239 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| armv7m
->demcr
);
241 /* Paranoia: evidently some (early?) chips don't preserve all the
242 * debug state (including FBP, DWT, etc) across reset...
246 target_write_u32(target
, FP_CTRL
, 3);
247 cortex_m3
->fpb_enabled
= 1;
249 /* Restore FPB registers */
250 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
252 target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
255 /* Restore DWT registers */
256 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
258 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 0,
260 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 4,
262 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 8,
263 dwt_list
[i
].function
);
265 retval
= dap_run(swjdp
);
266 if (retval
!= ERROR_OK
)
269 register_cache_invalidate(cortex_m3
->armv7m
.core_cache
);
271 /* make sure we have latest dhcsr flags */
272 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
277 static int cortex_m3_examine_debug_reason(struct target
*target
)
279 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
281 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
282 /* only check the debug reason if we don't know it already */
284 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
285 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
287 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
289 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
290 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
291 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
293 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
294 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
295 else if (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
)
296 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
297 else /* EXTERNAL, HALTED */
298 target
->debug_reason
= DBG_REASON_UNDEFINED
;
304 static int cortex_m3_examine_exception_reason(struct target
*target
)
306 uint32_t shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
307 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
308 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
311 retval
= mem_ap_read_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
312 if (retval
!= ERROR_OK
)
314 switch (armv7m
->exception_number
)
318 case 3: /* Hard Fault */
319 retval
= mem_ap_read_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
320 if (retval
!= ERROR_OK
)
322 if (except_sr
& 0x40000000)
324 retval
= mem_ap_read_u32(swjdp
, NVIC_CFSR
, &cfsr
);
325 if (retval
!= ERROR_OK
)
329 case 4: /* Memory Management */
330 retval
= mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
331 if (retval
!= ERROR_OK
)
333 retval
= mem_ap_read_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
334 if (retval
!= ERROR_OK
)
337 case 5: /* Bus Fault */
338 retval
= mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
339 if (retval
!= ERROR_OK
)
341 retval
= mem_ap_read_u32(swjdp
, NVIC_BFAR
, &except_ar
);
342 if (retval
!= ERROR_OK
)
345 case 6: /* Usage Fault */
346 retval
= mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
347 if (retval
!= ERROR_OK
)
350 case 11: /* SVCall */
352 case 12: /* Debug Monitor */
353 retval
= mem_ap_read_u32(swjdp
, NVIC_DFSR
, &except_sr
);
354 if (retval
!= ERROR_OK
)
357 case 14: /* PendSV */
359 case 15: /* SysTick */
365 retval
= dap_run(swjdp
);
366 if (retval
== ERROR_OK
)
367 LOG_DEBUG("%s SHCSR 0x%" PRIx32
", SR 0x%" PRIx32
368 ", CFSR 0x%" PRIx32
", AR 0x%" PRIx32
,
369 armv7m_exception_string(armv7m
->exception_number
),
370 shcsr
, except_sr
, cfsr
, except_ar
);
374 /* PSP is used in some thread modes */
375 static const int armv7m_psp_reg_map
[17] = {
376 ARMV7M_R0
, ARMV7M_R1
, ARMV7M_R2
, ARMV7M_R3
,
377 ARMV7M_R4
, ARMV7M_R5
, ARMV7M_R6
, ARMV7M_R7
,
378 ARMV7M_R8
, ARMV7M_R9
, ARMV7M_R10
, ARMV7M_R11
,
379 ARMV7M_R12
, ARMV7M_PSP
, ARMV7M_R14
, ARMV7M_PC
,
383 /* MSP is used in handler and some thread modes */
384 static const int armv7m_msp_reg_map
[17] = {
385 ARMV7M_R0
, ARMV7M_R1
, ARMV7M_R2
, ARMV7M_R3
,
386 ARMV7M_R4
, ARMV7M_R5
, ARMV7M_R6
, ARMV7M_R7
,
387 ARMV7M_R8
, ARMV7M_R9
, ARMV7M_R10
, ARMV7M_R11
,
388 ARMV7M_R12
, ARMV7M_MSP
, ARMV7M_R14
, ARMV7M_PC
,
392 static int cortex_m3_debug_entry(struct target
*target
)
397 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
398 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
399 struct arm
*arm
= &armv7m
->arm
;
400 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
405 cortex_m3_clear_halt(target
);
406 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
407 if (retval
!= ERROR_OK
)
410 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
413 /* Examine target state and mode */
414 /* First load register acessible through core debug port*/
415 int num_regs
= armv7m
->core_cache
->num_regs
;
417 for (i
= 0; i
< num_regs
; i
++)
419 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
420 armv7m
->read_core_reg(target
, i
);
423 r
= armv7m
->core_cache
->reg_list
+ ARMV7M_xPSR
;
424 xPSR
= buf_get_u32(r
->value
, 0, 32);
426 #ifdef ARMV7_GDB_HACKS
427 /* FIXME this breaks on scan chains with more than one Cortex-M3.
428 * Instead, each CM3 should have its own dummy value...
430 /* copy real xpsr reg for gdb, setting thumb bit */
431 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 0, 32, xPSR
);
432 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 5, 1, 1);
433 armv7m_gdb_dummy_cpsr_reg
.valid
= r
->valid
;
434 armv7m_gdb_dummy_cpsr_reg
.dirty
= r
->dirty
;
437 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
441 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
444 /* Are we in an exception handler */
447 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
448 armv7m
->exception_number
= (xPSR
& 0x1FF);
450 arm
->core_mode
= ARM_MODE_HANDLER
;
451 arm
->map
= armv7m_msp_reg_map
;
455 unsigned control
= buf_get_u32(armv7m
->core_cache
456 ->reg_list
[ARMV7M_CONTROL
].value
, 0, 2);
458 /* is this thread privileged? */
459 armv7m
->core_mode
= control
& 1;
460 arm
->core_mode
= armv7m
->core_mode
461 ? ARM_MODE_USER_THREAD
464 /* which stack is it using? */
466 arm
->map
= armv7m_psp_reg_map
;
468 arm
->map
= armv7m_msp_reg_map
;
470 armv7m
->exception_number
= 0;
473 if (armv7m
->exception_number
)
475 cortex_m3_examine_exception_reason(target
);
478 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32
", target->state: %s",
479 armv7m_mode_strings
[armv7m
->core_mode
],
480 *(uint32_t*)(arm
->pc
->value
),
481 target_state_name(target
));
483 if (armv7m
->post_debug_entry
)
485 retval
= armv7m
->post_debug_entry(target
);
486 if (retval
!= ERROR_OK
)
493 static int cortex_m3_poll(struct target
*target
)
496 enum target_state prev_target_state
= target
->state
;
497 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
498 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
500 /* Read from Debug Halting Control and Status Register */
501 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
502 if (retval
!= ERROR_OK
)
504 target
->state
= TARGET_UNKNOWN
;
508 /* Recover from lockup. See ARMv7-M architecture spec,
509 * section B1.5.15 "Unrecoverable exception cases".
511 * REVISIT Is there a better way to report and handle this?
513 if (cortex_m3
->dcb_dhcsr
& S_LOCKUP
) {
514 LOG_WARNING("%s -- clearing lockup after double fault",
515 target_name(target
));
516 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
517 target
->debug_reason
= DBG_REASON_DBGRQ
;
519 /* refresh status bits */
520 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
521 if (retval
!= ERROR_OK
)
525 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
527 /* check if still in reset */
528 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
529 if (retval
!= ERROR_OK
)
532 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
534 target
->state
= TARGET_RESET
;
539 if (target
->state
== TARGET_RESET
)
541 /* Cannot switch context while running so endreset is
542 * called with target->state == TARGET_RESET
544 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%" PRIx32
,
545 cortex_m3
->dcb_dhcsr
);
546 cortex_m3_endreset_event(target
);
547 target
->state
= TARGET_RUNNING
;
548 prev_target_state
= TARGET_RUNNING
;
551 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
553 target
->state
= TARGET_HALTED
;
555 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
557 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
560 if (arm_semihosting(target
, &retval
) != 0)
563 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
565 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
568 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
571 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
575 /* REVISIT when S_SLEEP is set, it's in a Sleep or DeepSleep state.
576 * How best to model low power modes?
579 if (target
->state
== TARGET_UNKNOWN
)
581 /* check if processor is retiring instructions */
582 if (cortex_m3
->dcb_dhcsr
& S_RETIRE_ST
)
584 target
->state
= TARGET_RUNNING
;
592 static int cortex_m3_halt(struct target
*target
)
594 LOG_DEBUG("target->state: %s",
595 target_state_name(target
));
597 if (target
->state
== TARGET_HALTED
)
599 LOG_DEBUG("target was already halted");
603 if (target
->state
== TARGET_UNKNOWN
)
605 LOG_WARNING("target was in unknown state when halt was requested");
608 if (target
->state
== TARGET_RESET
)
610 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst())
612 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
613 return ERROR_TARGET_FAILURE
;
617 /* we came here in a reset_halt or reset_init sequence
618 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
620 target
->debug_reason
= DBG_REASON_DBGRQ
;
626 /* Write to Debug Halting Control and Status Register */
627 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
629 target
->debug_reason
= DBG_REASON_DBGRQ
;
634 static int cortex_m3_soft_reset_halt(struct target
*target
)
636 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
637 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
638 uint32_t dcb_dhcsr
= 0;
639 int retval
, timeout
= 0;
641 /* Enter debug state on reset; restore DEMCR in endreset_event() */
642 mem_ap_write_u32(swjdp
, DCB_DEMCR
,
643 TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
645 /* Request a core-only reset */
646 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
,
647 AIRCR_VECTKEY
| AIRCR_VECTRESET
);
648 target
->state
= TARGET_RESET
;
650 /* registers are now invalid */
651 register_cache_invalidate(cortex_m3
->armv7m
.core_cache
);
653 while (timeout
< 100)
655 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
656 if (retval
== ERROR_OK
)
658 retval
= mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
,
659 &cortex_m3
->nvic_dfsr
);
660 if (retval
!= ERROR_OK
)
662 if ((dcb_dhcsr
& S_HALT
)
663 && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
665 LOG_DEBUG("system reset-halted, DHCSR 0x%08x, "
667 (unsigned) dcb_dhcsr
,
668 (unsigned) cortex_m3
->nvic_dfsr
);
669 cortex_m3_poll(target
);
670 /* FIXME restore user's vector catch config */
674 LOG_DEBUG("waiting for system reset-halt, "
675 "DHCSR 0x%08x, %d ms",
676 (unsigned) dcb_dhcsr
, timeout
);
685 static void cortex_m3_enable_breakpoints(struct target
*target
)
687 struct breakpoint
*breakpoint
= target
->breakpoints
;
689 /* set any pending breakpoints */
692 if (!breakpoint
->set
)
693 cortex_m3_set_breakpoint(target
, breakpoint
);
694 breakpoint
= breakpoint
->next
;
698 static int cortex_m3_resume(struct target
*target
, int current
,
699 uint32_t address
, int handle_breakpoints
, int debug_execution
)
701 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
702 struct breakpoint
*breakpoint
= NULL
;
706 if (target
->state
!= TARGET_HALTED
)
708 LOG_WARNING("target not halted");
709 return ERROR_TARGET_NOT_HALTED
;
712 if (!debug_execution
)
714 target_free_all_working_areas(target
);
715 cortex_m3_enable_breakpoints(target
);
716 cortex_m3_enable_watchpoints(target
);
721 r
= armv7m
->core_cache
->reg_list
+ ARMV7M_PRIMASK
;
723 /* Disable interrupts */
724 /* We disable interrupts in the PRIMASK register instead of
725 * masking with C_MASKINTS. This is probably the same issue
726 * as Cortex-M3 Erratum 377493 (fixed in r1p0): C_MASKINTS
727 * in parallel with disabled interrupts can cause local faults
730 * REVISIT this clearly breaks non-debug execution, since the
731 * PRIMASK register state isn't saved/restored... workaround
732 * by never resuming app code after debug execution.
734 buf_set_u32(r
->value
, 0, 1, 1);
738 /* Make sure we are in Thumb mode */
739 r
= armv7m
->core_cache
->reg_list
+ ARMV7M_xPSR
;
740 buf_set_u32(r
->value
, 24, 1, 1);
745 /* current = 1: continue on current pc, otherwise continue at <address> */
749 buf_set_u32(r
->value
, 0, 32, address
);
754 /* if we halted last time due to a bkpt instruction
755 * then we have to manually step over it, otherwise
756 * the core will break again */
758 if (!breakpoint_find(target
, buf_get_u32(r
->value
, 0, 32))
761 armv7m_maybe_skip_bkpt_inst(target
, NULL
);
764 resume_pc
= buf_get_u32(r
->value
, 0, 32);
766 armv7m_restore_context(target
);
768 /* the front-end may request us not to handle breakpoints */
769 if (handle_breakpoints
)
771 /* Single step past breakpoint at current address */
772 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
774 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
" (ID: %d)",
776 breakpoint
->unique_id
);
777 cortex_m3_unset_breakpoint(target
, breakpoint
);
778 cortex_m3_single_step_core(target
);
779 cortex_m3_set_breakpoint(target
, breakpoint
);
784 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
786 target
->debug_reason
= DBG_REASON_NOTHALTED
;
788 /* registers are now invalid */
789 register_cache_invalidate(armv7m
->core_cache
);
791 if (!debug_execution
)
793 target
->state
= TARGET_RUNNING
;
794 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
795 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
799 target
->state
= TARGET_DEBUG_RUNNING
;
800 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
801 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
807 /* int irqstepcount = 0; */
808 static int cortex_m3_step(struct target
*target
, int current
,
809 uint32_t address
, int handle_breakpoints
)
811 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
812 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
813 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
814 struct breakpoint
*breakpoint
= NULL
;
815 struct reg
*pc
= armv7m
->arm
.pc
;
816 bool bkpt_inst_found
= false;
818 if (target
->state
!= TARGET_HALTED
)
820 LOG_WARNING("target not halted");
821 return ERROR_TARGET_NOT_HALTED
;
824 /* current = 1: continue on current pc, otherwise continue at <address> */
826 buf_set_u32(pc
->value
, 0, 32, address
);
828 /* the front-end may request us not to handle breakpoints */
829 if (handle_breakpoints
) {
830 breakpoint
= breakpoint_find(target
,
831 buf_get_u32(pc
->value
, 0, 32));
833 cortex_m3_unset_breakpoint(target
, breakpoint
);
836 armv7m_maybe_skip_bkpt_inst(target
, &bkpt_inst_found
);
838 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
840 armv7m_restore_context(target
);
842 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
844 /* if no bkpt instruction is found at pc then we can perform
845 * a normal step, otherwise we have to manually step over the bkpt
846 * instruction - as such simulate a step */
847 if (bkpt_inst_found
== false)
849 /* set step and clear halt */
850 cortex_m3_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
854 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
855 if (retval
!= ERROR_OK
)
858 /* registers are now invalid */
859 register_cache_invalidate(cortex_m3
->armv7m
.core_cache
);
862 cortex_m3_set_breakpoint(target
, breakpoint
);
864 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
865 " nvic_icsr = 0x%" PRIx32
,
866 cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
868 retval
= cortex_m3_debug_entry(target
);
869 if (retval
!= ERROR_OK
)
871 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
873 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
874 " nvic_icsr = 0x%" PRIx32
,
875 cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
880 static int cortex_m3_assert_reset(struct target
*target
)
882 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
883 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
886 LOG_DEBUG("target->state: %s",
887 target_state_name(target
));
889 enum reset_types jtag_reset_config
= jtag_get_reset_config();
892 * We can reset Cortex-M3 targets using just the NVIC without
893 * requiring SRST, getting a SoC reset (or a core-only reset)
894 * instead of a system reset.
896 if (!(jtag_reset_config
& RESET_HAS_SRST
))
899 /* Enable debug requests */
901 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
902 if (retval
!= ERROR_OK
)
904 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
905 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
907 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
909 if (!target
->reset_halt
)
911 /* Set/Clear C_MASKINTS in a separate operation */
912 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
913 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
,
914 DBGKEY
| C_DEBUGEN
| C_HALT
);
916 /* clear any debug flags before resuming */
917 cortex_m3_clear_halt(target
);
919 /* clear C_HALT in dhcsr reg */
920 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
924 /* Halt in debug on reset; endreset_event() restores DEMCR.
926 * REVISIT catching BUSERR presumably helps to defend against
927 * bad vector table entries. Should this include MMERR or
930 mem_ap_write_atomic_u32(swjdp
, DCB_DEMCR
,
931 TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
935 * When nRST is asserted on most Stellaris devices, it clears some of
936 * the debug state. The ARMv7M and Cortex-M3 TRMs say that's wrong;
937 * and OpenOCD depends on those TRMs. So we won't use SRST on those
938 * chips. (Only power-on reset should affect debug state, beyond a
939 * few specified bits; not the chip's nRST input, wired to SRST.)
941 * REVISIT current errata specs don't seem to cover this issue.
942 * Do we have more details than this email?
943 * https://lists.berlios.de/pipermail
944 * /openocd-development/2008-August/003065.html
946 if (strcmp(target
->variant
, "lm3s") == 0)
948 /* Check for silicon revisions with the issue. */
951 if (target_read_u32(target
, 0x400fe000, &did0
) == ERROR_OK
)
953 switch ((did0
>> 16) & 0xff)
956 /* all Sandstorm suffer issue */
962 /* Fury and DustDevil rev A have
963 * this nRST problem. It should
964 * be fixed in rev B silicon.
966 if (((did0
>> 8) & 0xff) == 0)
970 /* Tempest should be fine. */
978 /* default to asserting srst */
979 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
981 jtag_add_reset(1, 1);
985 jtag_add_reset(0, 1);
990 /* Use a standard Cortex-M3 software reset mechanism.
991 * SYSRESETREQ will reset SoC peripherals outside the
992 * core, like watchdog timers, if the SoC wires it up
993 * correctly. Else VECRESET can reset just the core.
995 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
,
996 AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
997 LOG_DEBUG("Using Cortex-M3 SYSRESETREQ");
1000 /* I do not know why this is necessary, but it
1001 * fixes strange effects (step/resume cause NMI
1002 * after reset) on LM3S6918 -- Michael Schwingen
1005 retval
= mem_ap_read_atomic_u32(swjdp
, NVIC_AIRCR
, &tmp
);
1006 if (retval
!= ERROR_OK
)
1011 target
->state
= TARGET_RESET
;
1012 jtag_add_sleep(50000);
1014 register_cache_invalidate(cortex_m3
->armv7m
.core_cache
);
1016 if (target
->reset_halt
)
1018 if ((retval
= target_halt(target
)) != ERROR_OK
)
1025 static int cortex_m3_deassert_reset(struct target
*target
)
1027 LOG_DEBUG("target->state: %s",
1028 target_state_name(target
));
1030 /* deassert reset lines */
1031 jtag_add_reset(0, 0);
1037 cortex_m3_set_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1042 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1043 struct cortex_m3_fp_comparator
*comparator_list
= cortex_m3
->fp_comparator_list
;
1045 if (breakpoint
->set
)
1047 LOG_WARNING("breakpoint (BPID: %d) already set", breakpoint
->unique_id
);
1051 if (cortex_m3
->auto_bp_type
)
1053 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1056 if (breakpoint
->type
== BKPT_HARD
)
1058 while (comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
1060 if (fp_num
>= cortex_m3
->fp_num_code
)
1062 LOG_ERROR("Can not find free FPB Comparator!");
1065 breakpoint
->set
= fp_num
+ 1;
1066 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
1067 comparator_list
[fp_num
].used
= 1;
1068 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
1069 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
1070 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32
"", fp_num
, comparator_list
[fp_num
].fpcr_value
);
1071 if (!cortex_m3
->fpb_enabled
)
1073 LOG_DEBUG("FPB wasn't enabled, do it now");
1074 target_write_u32(target
, FP_CTRL
, 3);
1077 else if (breakpoint
->type
== BKPT_SOFT
)
1081 /* NOTE: on ARMv6-M and ARMv7-M, BKPT(0xab) is used for
1082 * semihosting; don't use that. Otherwise the BKPT
1083 * parameter is arbitrary.
1085 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1086 retval
= target_read_memory(target
,
1087 breakpoint
->address
& 0xFFFFFFFE,
1088 breakpoint
->length
, 1,
1089 breakpoint
->orig_instr
);
1090 if (retval
!= ERROR_OK
)
1092 retval
= target_write_memory(target
,
1093 breakpoint
->address
& 0xFFFFFFFE,
1094 breakpoint
->length
, 1,
1096 if (retval
!= ERROR_OK
)
1098 breakpoint
->set
= true;
1101 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
1102 breakpoint
->unique_id
,
1103 (int)(breakpoint
->type
),
1104 breakpoint
->address
,
1112 cortex_m3_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1115 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1116 struct cortex_m3_fp_comparator
* comparator_list
= cortex_m3
->fp_comparator_list
;
1118 if (!breakpoint
->set
)
1120 LOG_WARNING("breakpoint not set");
1124 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
1125 breakpoint
->unique_id
,
1126 (int)(breakpoint
->type
),
1127 breakpoint
->address
,
1131 if (breakpoint
->type
== BKPT_HARD
)
1133 int fp_num
= breakpoint
->set
- 1;
1134 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
1136 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
1139 comparator_list
[fp_num
].used
= 0;
1140 comparator_list
[fp_num
].fpcr_value
= 0;
1141 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
1145 /* restore original instruction (kept in target endianness) */
1146 if (breakpoint
->length
== 4)
1148 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
1155 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
1161 breakpoint
->set
= false;
1167 cortex_m3_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1169 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1171 if (cortex_m3
->auto_bp_type
)
1173 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1174 #ifdef ARMV7_GDB_HACKS
1175 if (breakpoint
->length
!= 2) {
1176 /* XXX Hack: Replace all breakpoints with length != 2 with
1177 * a hardware breakpoint. */
1178 breakpoint
->type
= BKPT_HARD
;
1179 breakpoint
->length
= 2;
1184 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
1186 LOG_INFO("flash patch comparator requested outside code memory region");
1187 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1190 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
1192 LOG_INFO("soft breakpoint requested in code (flash) memory region");
1193 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1196 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
1198 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
1199 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1202 if ((breakpoint
->length
!= 2))
1204 LOG_INFO("only breakpoints of two bytes length supported");
1205 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1208 if (breakpoint
->type
== BKPT_HARD
)
1209 cortex_m3
->fp_code_available
--;
1210 cortex_m3_set_breakpoint(target
, breakpoint
);
1216 cortex_m3_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1218 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1220 /* REVISIT why check? FBP can be updated with core running ... */
1221 if (target
->state
!= TARGET_HALTED
)
1223 LOG_WARNING("target not halted");
1224 return ERROR_TARGET_NOT_HALTED
;
1227 if (cortex_m3
->auto_bp_type
)
1229 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1232 if (breakpoint
->set
)
1234 cortex_m3_unset_breakpoint(target
, breakpoint
);
1237 if (breakpoint
->type
== BKPT_HARD
)
1238 cortex_m3
->fp_code_available
++;
1244 cortex_m3_set_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1247 uint32_t mask
, temp
;
1248 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1250 /* watchpoint params were validated earlier */
1252 temp
= watchpoint
->length
;
1259 /* REVISIT Don't fully trust these "not used" records ... users
1260 * may set up breakpoints by hand, e.g. dual-address data value
1261 * watchpoint using comparator #1; comparator #0 matching cycle
1262 * count; send data trace info through ITM and TPIU; etc
1264 struct cortex_m3_dwt_comparator
*comparator
;
1266 for (comparator
= cortex_m3
->dwt_comparator_list
;
1267 comparator
->used
&& dwt_num
< cortex_m3
->dwt_num_comp
;
1268 comparator
++, dwt_num
++)
1270 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
1272 LOG_ERROR("Can not find free DWT Comparator");
1275 comparator
->used
= 1;
1276 watchpoint
->set
= dwt_num
+ 1;
1278 comparator
->comp
= watchpoint
->address
;
1279 target_write_u32(target
, comparator
->dwt_comparator_address
+ 0,
1282 comparator
->mask
= mask
;
1283 target_write_u32(target
, comparator
->dwt_comparator_address
+ 4,
1286 switch (watchpoint
->rw
) {
1288 comparator
->function
= 5;
1291 comparator
->function
= 6;
1294 comparator
->function
= 7;
1297 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1298 comparator
->function
);
1300 LOG_DEBUG("Watchpoint (ID %d) DWT%d 0x%08x 0x%x 0x%05x",
1301 watchpoint
->unique_id
, dwt_num
,
1302 (unsigned) comparator
->comp
,
1303 (unsigned) comparator
->mask
,
1304 (unsigned) comparator
->function
);
1309 cortex_m3_unset_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1311 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1312 struct cortex_m3_dwt_comparator
*comparator
;
1315 if (!watchpoint
->set
)
1317 LOG_WARNING("watchpoint (wpid: %d) not set",
1318 watchpoint
->unique_id
);
1322 dwt_num
= watchpoint
->set
- 1;
1324 LOG_DEBUG("Watchpoint (ID %d) DWT%d address: 0x%08x clear",
1325 watchpoint
->unique_id
, dwt_num
,
1326 (unsigned) watchpoint
->address
);
1328 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1330 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1334 comparator
= cortex_m3
->dwt_comparator_list
+ dwt_num
;
1335 comparator
->used
= 0;
1336 comparator
->function
= 0;
1337 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1338 comparator
->function
);
1340 watchpoint
->set
= false;
1346 cortex_m3_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1348 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1350 if (cortex_m3
->dwt_comp_available
< 1)
1352 LOG_DEBUG("no comparators?");
1353 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1356 /* hardware doesn't support data value masking */
1357 if (watchpoint
->mask
!= ~(uint32_t)0) {
1358 LOG_DEBUG("watchpoint value masks not supported");
1359 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1362 /* hardware allows address masks of up to 32K */
1365 for (mask
= 0; mask
< 16; mask
++) {
1366 if ((1u << mask
) == watchpoint
->length
)
1370 LOG_DEBUG("unsupported watchpoint length");
1371 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1373 if (watchpoint
->address
& ((1 << mask
) - 1)) {
1374 LOG_DEBUG("watchpoint address is unaligned");
1375 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1378 /* Caller doesn't seem to be able to describe watching for data
1379 * values of zero; that flags "no value".
1381 * REVISIT This DWT may well be able to watch for specific data
1382 * values. Requires comparator #1 to set DATAVMATCH and match
1383 * the data, and another comparator (DATAVADDR0) matching addr.
1385 if (watchpoint
->value
) {
1386 LOG_DEBUG("data value watchpoint not YET supported");
1387 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1390 cortex_m3
->dwt_comp_available
--;
1391 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1397 cortex_m3_remove_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1399 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1401 /* REVISIT why check? DWT can be updated with core running ... */
1402 if (target
->state
!= TARGET_HALTED
)
1404 LOG_WARNING("target not halted");
1405 return ERROR_TARGET_NOT_HALTED
;
1408 if (watchpoint
->set
)
1410 cortex_m3_unset_watchpoint(target
, watchpoint
);
1413 cortex_m3
->dwt_comp_available
++;
1414 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1419 static void cortex_m3_enable_watchpoints(struct target
*target
)
1421 struct watchpoint
*watchpoint
= target
->watchpoints
;
1423 /* set any pending watchpoints */
1426 if (!watchpoint
->set
)
1427 cortex_m3_set_watchpoint(target
, watchpoint
);
1428 watchpoint
= watchpoint
->next
;
1432 static int cortex_m3_load_core_reg_u32(struct target
*target
,
1433 enum armv7m_regtype type
, uint32_t num
, uint32_t * value
)
1436 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1437 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1439 /* NOTE: we "know" here that the register identifiers used
1440 * in the v7m header match the Cortex-M3 Debug Core Register
1441 * Selector values for R0..R15, xPSR, MSP, and PSP.
1445 /* read a normal core register */
1446 retval
= cortexm3_dap_read_coreregister_u32(swjdp
, value
, num
);
1448 if (retval
!= ERROR_OK
)
1450 LOG_ERROR("JTAG failure %i",retval
);
1451 return ERROR_JTAG_DEVICE_ERROR
;
1453 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
"",(int)num
,*value
);
1456 case ARMV7M_PRIMASK
:
1457 case ARMV7M_BASEPRI
:
1458 case ARMV7M_FAULTMASK
:
1459 case ARMV7M_CONTROL
:
1460 /* Cortex-M3 packages these four registers as bitfields
1461 * in one Debug Core register. So say r0 and r2 docs;
1462 * it was removed from r1 docs, but still works.
1464 cortexm3_dap_read_coreregister_u32(swjdp
, value
, 20);
1468 case ARMV7M_PRIMASK
:
1469 *value
= buf_get_u32((uint8_t*)value
, 0, 1);
1472 case ARMV7M_BASEPRI
:
1473 *value
= buf_get_u32((uint8_t*)value
, 8, 8);
1476 case ARMV7M_FAULTMASK
:
1477 *value
= buf_get_u32((uint8_t*)value
, 16, 1);
1480 case ARMV7M_CONTROL
:
1481 *value
= buf_get_u32((uint8_t*)value
, 24, 2);
1485 LOG_DEBUG("load from special reg %i value 0x%" PRIx32
"", (int)num
, *value
);
1489 return ERROR_INVALID_ARGUMENTS
;
1495 static int cortex_m3_store_core_reg_u32(struct target
*target
,
1496 enum armv7m_regtype type
, uint32_t num
, uint32_t value
)
1500 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1501 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1503 #ifdef ARMV7_GDB_HACKS
1504 /* If the LR register is being modified, make sure it will put us
1505 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1506 * hack to deal with the fact that gdb will sometimes "forge"
1507 * return addresses, and doesn't set the LSB correctly (i.e., when
1508 * printing expressions containing function calls, it sets LR = 0.)
1509 * Valid exception return codes have bit 0 set too.
1511 if (num
== ARMV7M_R14
)
1515 /* NOTE: we "know" here that the register identifiers used
1516 * in the v7m header match the Cortex-M3 Debug Core Register
1517 * Selector values for R0..R15, xPSR, MSP, and PSP.
1521 retval
= cortexm3_dap_write_coreregister_u32(swjdp
, value
, num
);
1522 if (retval
!= ERROR_OK
)
1526 LOG_ERROR("JTAG failure %i", retval
);
1527 r
= armv7m
->core_cache
->reg_list
+ num
;
1528 r
->dirty
= r
->valid
;
1529 return ERROR_JTAG_DEVICE_ERROR
;
1531 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", (int)num
, value
);
1534 case ARMV7M_PRIMASK
:
1535 case ARMV7M_BASEPRI
:
1536 case ARMV7M_FAULTMASK
:
1537 case ARMV7M_CONTROL
:
1538 /* Cortex-M3 packages these four registers as bitfields
1539 * in one Debug Core register. So say r0 and r2 docs;
1540 * it was removed from r1 docs, but still works.
1542 cortexm3_dap_read_coreregister_u32(swjdp
, ®
, 20);
1546 case ARMV7M_PRIMASK
:
1547 buf_set_u32((uint8_t*)®
, 0, 1, value
);
1550 case ARMV7M_BASEPRI
:
1551 buf_set_u32((uint8_t*)®
, 8, 8, value
);
1554 case ARMV7M_FAULTMASK
:
1555 buf_set_u32((uint8_t*)®
, 16, 1, value
);
1558 case ARMV7M_CONTROL
:
1559 buf_set_u32((uint8_t*)®
, 24, 2, value
);
1563 cortexm3_dap_write_coreregister_u32(swjdp
, reg
, 20);
1565 LOG_DEBUG("write special reg %i value 0x%" PRIx32
" ", (int)num
, value
);
1569 return ERROR_INVALID_ARGUMENTS
;
1575 static int cortex_m3_read_memory(struct target
*target
, uint32_t address
,
1576 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1578 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1579 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1580 int retval
= ERROR_INVALID_ARGUMENTS
;
1582 /* cortex_m3 handles unaligned memory access */
1583 if (count
&& buffer
) {
1586 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1589 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1592 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1600 static int cortex_m3_write_memory(struct target
*target
, uint32_t address
,
1601 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1603 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1604 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1605 int retval
= ERROR_INVALID_ARGUMENTS
;
1607 if (count
&& buffer
) {
1610 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1613 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1616 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1624 static int cortex_m3_bulk_write_memory(struct target
*target
, uint32_t address
,
1625 uint32_t count
, uint8_t *buffer
)
1627 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1630 static int cortex_m3_init_target(struct command_context
*cmd_ctx
,
1631 struct target
*target
)
1633 armv7m_build_reg_cache(target
);
1637 /* REVISIT cache valid/dirty bits are unmaintained. We could set "valid"
1638 * on r/w if the core is not running, and clear on resume or reset ... or
1639 * at least, in a post_restore_context() method.
1642 struct dwt_reg_state
{
1643 struct target
*target
;
1645 uint32_t value
; /* scratch/cache */
1648 static int cortex_m3_dwt_get_reg(struct reg
*reg
)
1650 struct dwt_reg_state
*state
= reg
->arch_info
;
1652 return target_read_u32(state
->target
, state
->addr
, &state
->value
);
1655 static int cortex_m3_dwt_set_reg(struct reg
*reg
, uint8_t *buf
)
1657 struct dwt_reg_state
*state
= reg
->arch_info
;
1659 return target_write_u32(state
->target
, state
->addr
,
1660 buf_get_u32(buf
, 0, reg
->size
));
1669 static struct dwt_reg dwt_base_regs
[] = {
1670 { DWT_CTRL
, "dwt_ctrl", 32, },
1671 /* NOTE that Erratum 532314 (fixed r2p0) affects CYCCNT: it wrongly
1672 * increments while the core is asleep.
1674 { DWT_CYCCNT
, "dwt_cyccnt", 32, },
1675 /* plus some 8 bit counters, useful for profiling with TPIU */
1678 static struct dwt_reg dwt_comp
[] = {
1679 #define DWT_COMPARATOR(i) \
1680 { DWT_COMP0 + 0x10 * (i), "dwt_" #i "_comp", 32, }, \
1681 { DWT_MASK0 + 0x10 * (i), "dwt_" #i "_mask", 4, }, \
1682 { DWT_FUNCTION0 + 0x10 * (i), "dwt_" #i "_function", 32, }
1687 #undef DWT_COMPARATOR
1690 static const struct reg_arch_type dwt_reg_type
= {
1691 .get
= cortex_m3_dwt_get_reg
,
1692 .set
= cortex_m3_dwt_set_reg
,
1696 cortex_m3_dwt_addreg(struct target
*t
, struct reg
*r
, struct dwt_reg
*d
)
1698 struct dwt_reg_state
*state
;
1700 state
= calloc(1, sizeof *state
);
1703 state
->addr
= d
->addr
;
1708 r
->value
= &state
->value
;
1709 r
->arch_info
= state
;
1710 r
->type
= &dwt_reg_type
;
1714 cortex_m3_dwt_setup(struct cortex_m3_common
*cm3
, struct target
*target
)
1717 struct reg_cache
*cache
;
1718 struct cortex_m3_dwt_comparator
*comparator
;
1721 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1723 LOG_DEBUG("no DWT");
1727 cm3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1728 cm3
->dwt_comp_available
= cm3
->dwt_num_comp
;
1729 cm3
->dwt_comparator_list
= calloc(cm3
->dwt_num_comp
,
1730 sizeof(struct cortex_m3_dwt_comparator
));
1731 if (!cm3
->dwt_comparator_list
) {
1733 cm3
->dwt_num_comp
= 0;
1734 LOG_ERROR("out of mem");
1738 cache
= calloc(1, sizeof *cache
);
1741 free(cm3
->dwt_comparator_list
);
1744 cache
->name
= "cortex-m3 dwt registers";
1745 cache
->num_regs
= 2 + cm3
->dwt_num_comp
* 3;
1746 cache
->reg_list
= calloc(cache
->num_regs
, sizeof *cache
->reg_list
);
1747 if (!cache
->reg_list
) {
1752 for (reg
= 0; reg
< 2; reg
++)
1753 cortex_m3_dwt_addreg(target
, cache
->reg_list
+ reg
,
1754 dwt_base_regs
+ reg
);
1756 comparator
= cm3
->dwt_comparator_list
;
1757 for (i
= 0; i
< cm3
->dwt_num_comp
; i
++, comparator
++) {
1760 comparator
->dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1761 for (j
= 0; j
< 3; j
++, reg
++)
1762 cortex_m3_dwt_addreg(target
, cache
->reg_list
+ reg
,
1763 dwt_comp
+ 3 * i
+ j
);
1766 *register_get_last_cache_p(&target
->reg_cache
) = cache
;
1767 cm3
->dwt_cache
= cache
;
1769 LOG_DEBUG("DWT dwtcr 0x%" PRIx32
", comp %d, watch%s",
1770 dwtcr
, cm3
->dwt_num_comp
,
1771 (dwtcr
& (0xf << 24)) ? " only" : "/trigger");
1773 /* REVISIT: if num_comp > 1, check whether comparator #1 can
1774 * implement single-address data value watchpoints ... so we
1775 * won't need to check it later, when asked to set one up.
1779 static int cortex_m3_examine(struct target
*target
)
1782 uint32_t cpuid
, fpcr
;
1784 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1785 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
1787 if ((retval
= ahbap_debugport_init(swjdp
)) != ERROR_OK
)
1790 if (!target_was_examined(target
))
1792 target_set_examined(target
);
1794 /* Read from Device Identification Registers */
1795 retval
= target_read_u32(target
, CPUID
, &cpuid
);
1796 if (retval
!= ERROR_OK
)
1799 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1800 LOG_DEBUG("Cortex-M3 r%" PRId8
"p%" PRId8
" processor detected",
1801 (uint8_t)((cpuid
>> 20) & 0xf), (uint8_t)((cpuid
>> 0) & 0xf));
1802 LOG_DEBUG("cpuid: 0x%8.8" PRIx32
"", cpuid
);
1804 /* NOTE: FPB and DWT are both optional. */
1807 target_read_u32(target
, FP_CTRL
, &fpcr
);
1808 cortex_m3
->auto_bp_type
= 1;
1809 cortex_m3
->fp_num_code
= ((fpcr
>> 8) & 0x70) | ((fpcr
>> 4) & 0xF); /* bits [14:12] and [7:4] */
1810 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1811 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1812 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(struct cortex_m3_fp_comparator
));
1813 cortex_m3
->fpb_enabled
= fpcr
& 1;
1814 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1816 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1817 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1819 LOG_DEBUG("FPB fpcr 0x%" PRIx32
", numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1822 cortex_m3_dwt_setup(cortex_m3
, target
);
1824 /* These hardware breakpoints only work for code in flash! */
1825 LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints",
1826 target_name(target
),
1827 cortex_m3
->fp_num_code
,
1828 cortex_m3
->dwt_num_comp
);
1834 static int cortex_m3_dcc_read(struct adiv5_dap
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1838 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1839 *ctrl
= (uint8_t)dcrdr
;
1840 *value
= (uint8_t)(dcrdr
>> 8);
1842 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1844 /* write ack back to software dcc register
1845 * signify we have read data */
1846 if (dcrdr
& (1 << 0))
1849 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1855 static int cortex_m3_target_request_data(struct target
*target
,
1856 uint32_t size
, uint8_t *buffer
)
1858 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1859 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1864 for (i
= 0; i
< (size
* 4); i
++)
1866 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1873 static int cortex_m3_handle_target_request(void *priv
)
1875 struct target
*target
= priv
;
1876 if (!target_was_examined(target
))
1878 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1879 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1881 if (!target
->dbg_msg_enabled
)
1884 if (target
->state
== TARGET_RUNNING
)
1889 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1891 /* check if we have data */
1892 if (ctrl
& (1 << 0))
1896 /* we assume target is quick enough */
1898 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1899 request
|= (data
<< 8);
1900 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1901 request
|= (data
<< 16);
1902 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1903 request
|= (data
<< 24);
1904 target_request(target
, request
);
1911 static int cortex_m3_init_arch_info(struct target
*target
,
1912 struct cortex_m3_common
*cortex_m3
, struct jtag_tap
*tap
)
1915 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
1917 armv7m_init_arch_info(target
, armv7m
);
1919 /* prepare JTAG information for the new target */
1920 cortex_m3
->jtag_info
.tap
= tap
;
1921 cortex_m3
->jtag_info
.scann_size
= 4;
1923 armv7m
->arm
.dap
= &armv7m
->dap
;
1925 /* Leave (only) generic DAP stuff for debugport_init(); */
1926 armv7m
->dap
.jtag_info
= &cortex_m3
->jtag_info
;
1927 armv7m
->dap
.memaccess_tck
= 8;
1928 /* Cortex-M3 has 4096 bytes autoincrement range */
1929 armv7m
->dap
.tar_autoincr_block
= (1 << 12);
1931 /* register arch-specific functions */
1932 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1934 armv7m
->post_debug_entry
= NULL
;
1936 armv7m
->pre_restore_context
= NULL
;
1938 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1939 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1941 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1943 if ((retval
= arm_jtag_setup_connection(&cortex_m3
->jtag_info
)) != ERROR_OK
)
1951 static int cortex_m3_target_create(struct target
*target
, Jim_Interp
*interp
)
1953 struct cortex_m3_common
*cortex_m3
= calloc(1,sizeof(struct cortex_m3_common
));
1955 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1956 cortex_m3_init_arch_info(target
, cortex_m3
, target
->tap
);
1961 /*--------------------------------------------------------------------------*/
1963 static int cortex_m3_verify_pointer(struct command_context
*cmd_ctx
,
1964 struct cortex_m3_common
*cm3
)
1966 if (cm3
->common_magic
!= CORTEX_M3_COMMON_MAGIC
) {
1967 command_print(cmd_ctx
, "target is not a Cortex-M3");
1968 return ERROR_TARGET_INVALID
;
1974 * Only stuff below this line should need to verify that its target
1975 * is a Cortex-M3. Everything else should have indirected through the
1976 * cortexm3_target structure, which is only used with CM3 targets.
1979 static const struct {
1983 { "hard_err", VC_HARDERR
, },
1984 { "int_err", VC_INTERR
, },
1985 { "bus_err", VC_BUSERR
, },
1986 { "state_err", VC_STATERR
, },
1987 { "chk_err", VC_CHKERR
, },
1988 { "nocp_err", VC_NOCPERR
, },
1989 { "mm_err", VC_MMERR
, },
1990 { "reset", VC_CORERESET
, },
1993 COMMAND_HANDLER(handle_cortex_m3_vector_catch_command
)
1995 struct target
*target
= get_current_target(CMD_CTX
);
1996 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1997 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
1998 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
2002 retval
= cortex_m3_verify_pointer(CMD_CTX
, cortex_m3
);
2003 if (retval
!= ERROR_OK
)
2006 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &demcr
);
2007 if (retval
!= ERROR_OK
)
2013 if (CMD_ARGC
== 1) {
2014 if (strcmp(CMD_ARGV
[0], "all") == 0) {
2015 catch = VC_HARDERR
| VC_INTERR
| VC_BUSERR
2016 | VC_STATERR
| VC_CHKERR
| VC_NOCPERR
2017 | VC_MMERR
| VC_CORERESET
;
2019 } else if (strcmp(CMD_ARGV
[0], "none") == 0) {
2023 while (CMD_ARGC
-- > 0) {
2025 for (i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++) {
2026 if (strcmp(CMD_ARGV
[CMD_ARGC
], vec_ids
[i
].name
) != 0)
2028 catch |= vec_ids
[i
].mask
;
2031 if (i
== ARRAY_SIZE(vec_ids
)) {
2032 LOG_ERROR("No CM3 vector '%s'", CMD_ARGV
[CMD_ARGC
]);
2033 return ERROR_INVALID_ARGUMENTS
;
2037 /* For now, armv7m->demcr only stores vector catch flags. */
2038 armv7m
->demcr
= catch;
2043 /* write, but don't assume it stuck (why not??) */
2044 mem_ap_write_u32(swjdp
, DCB_DEMCR
, demcr
);
2045 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &demcr
);
2046 if (retval
!= ERROR_OK
)
2049 /* FIXME be sure to clear DEMCR on clean server shutdown.
2050 * Otherwise the vector catch hardware could fire when there's
2051 * no debugger hooked up, causing much confusion...
2055 for (unsigned i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++)
2057 command_print(CMD_CTX
, "%9s: %s", vec_ids
[i
].name
,
2058 (demcr
& vec_ids
[i
].mask
) ? "catch" : "ignore");
2064 COMMAND_HANDLER(handle_cortex_m3_mask_interrupts_command
)
2066 struct target
*target
= get_current_target(CMD_CTX
);
2067 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
2070 retval
= cortex_m3_verify_pointer(CMD_CTX
, cortex_m3
);
2071 if (retval
!= ERROR_OK
)
2074 if (target
->state
!= TARGET_HALTED
)
2076 command_print(CMD_CTX
, "target must be stopped for \"%s\" command", CMD_NAME
);
2083 COMMAND_PARSE_ON_OFF(CMD_ARGV
[0], enable
);
2084 uint32_t mask_on
= C_HALT
| (enable
? C_MASKINTS
: 0);
2085 uint32_t mask_off
= enable
? 0 : C_MASKINTS
;
2086 cortex_m3_write_debug_halt_mask(target
, mask_on
, mask_off
);
2089 command_print(CMD_CTX
, "cortex_m3 interrupt mask %s",
2090 (cortex_m3
->dcb_dhcsr
& C_MASKINTS
) ? "on" : "off");
2095 static const struct command_registration cortex_m3_exec_command_handlers
[] = {
2098 .handler
= handle_cortex_m3_mask_interrupts_command
,
2099 .mode
= COMMAND_EXEC
,
2100 .help
= "mask cortex_m3 interrupts",
2101 .usage
= "['on'|'off']",
2104 .name
= "vector_catch",
2105 .handler
= handle_cortex_m3_vector_catch_command
,
2106 .mode
= COMMAND_EXEC
,
2107 .help
= "configure hardware vectors to trigger debug entry",
2108 .usage
= "['all'|'none'|('bus_err'|'chk_err'|...)*]",
2110 COMMAND_REGISTRATION_DONE
2112 static const struct command_registration cortex_m3_command_handlers
[] = {
2114 .chain
= armv7m_command_handlers
,
2117 .name
= "cortex_m3",
2118 .mode
= COMMAND_EXEC
,
2119 .help
= "Cortex-M3 command group",
2120 .chain
= cortex_m3_exec_command_handlers
,
2122 COMMAND_REGISTRATION_DONE
2125 struct target_type cortexm3_target
=
2127 .name
= "cortex_m3",
2129 .poll
= cortex_m3_poll
,
2130 .arch_state
= armv7m_arch_state
,
2132 .target_request_data
= cortex_m3_target_request_data
,
2134 .halt
= cortex_m3_halt
,
2135 .resume
= cortex_m3_resume
,
2136 .step
= cortex_m3_step
,
2138 .assert_reset
= cortex_m3_assert_reset
,
2139 .deassert_reset
= cortex_m3_deassert_reset
,
2140 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
2142 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
2144 .read_memory
= cortex_m3_read_memory
,
2145 .write_memory
= cortex_m3_write_memory
,
2146 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
2147 .checksum_memory
= armv7m_checksum_memory
,
2148 .blank_check_memory
= armv7m_blank_check_memory
,
2150 .run_algorithm
= armv7m_run_algorithm
,
2152 .add_breakpoint
= cortex_m3_add_breakpoint
,
2153 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
2154 .add_watchpoint
= cortex_m3_add_watchpoint
,
2155 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
2157 .commands
= cortex_m3_command_handlers
,
2158 .target_create
= cortex_m3_target_create
,
2159 .init_target
= cortex_m3_init_target
,
2160 .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)