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 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRSR
& 0xFFFFFFF0);
75 retval
= dap_queue_ap_write(swjdp
, AP_REG_BD0
| (DCB_DCRSR
& 0xC), regnum
);
76 if (retval
!= ERROR_OK
)
79 /* mem_ap_read_u32(swjdp, DCB_DCRDR, value); */
80 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRDR
& 0xFFFFFFF0);
81 retval
= dap_queue_ap_read(swjdp
, AP_REG_BD0
| (DCB_DCRDR
& 0xC), value
);
82 if (retval
!= ERROR_OK
)
85 retval
= dap_run(swjdp
);
86 if (retval
!= ERROR_OK
)
89 /* restore DCB_DCRDR - this needs to be in a seperate
90 * transaction otherwise the emulated DCC channel breaks */
91 if (retval
== ERROR_OK
)
92 retval
= mem_ap_write_atomic_u32(swjdp
, DCB_DCRDR
, dcrdr
);
97 static int cortexm3_dap_write_coreregister_u32(struct adiv5_dap
*swjdp
,
98 uint32_t value
, int regnum
)
103 /* because the DCB_DCRDR is used for the emulated dcc channel
104 * we have to save/restore the DCB_DCRDR when used */
106 mem_ap_read_u32(swjdp
, DCB_DCRDR
, &dcrdr
);
108 /* mem_ap_write_u32(swjdp, DCB_DCRDR, core_regs[i]); */
109 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRDR
& 0xFFFFFFF0);
110 retval
= dap_queue_ap_write(swjdp
, AP_REG_BD0
| (DCB_DCRDR
& 0xC), value
);
113 /* mem_ap_write_u32(swjdp, DCB_DCRSR, i | DCRSR_WnR); */
114 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRSR
& 0xFFFFFFF0);
115 retval
= dap_queue_ap_write(swjdp
, AP_REG_BD0
| (DCB_DCRSR
& 0xC), regnum
| DCRSR_WnR
);
118 retval
= dap_run(swjdp
);
120 /* restore DCB_DCRDR - this needs to be in a seperate
121 * transaction otherwise the emulated DCC channel breaks */
122 if (retval
== ERROR_OK
)
123 retval
= mem_ap_write_atomic_u32(swjdp
, DCB_DCRDR
, dcrdr
);
128 static int cortex_m3_write_debug_halt_mask(struct target
*target
,
129 uint32_t mask_on
, uint32_t mask_off
)
131 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
132 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
134 /* mask off status bits */
135 cortex_m3
->dcb_dhcsr
&= ~((0xFFFF << 16) | mask_off
);
136 /* create new register mask */
137 cortex_m3
->dcb_dhcsr
|= DBGKEY
| C_DEBUGEN
| mask_on
;
139 return mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, cortex_m3
->dcb_dhcsr
);
142 static int cortex_m3_clear_halt(struct target
*target
)
144 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
145 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
147 /* clear step if any */
148 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_STEP
);
150 /* Read Debug Fault Status Register */
151 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
153 /* Clear Debug Fault Status */
154 mem_ap_write_atomic_u32(swjdp
, NVIC_DFSR
, cortex_m3
->nvic_dfsr
);
155 LOG_DEBUG(" NVIC_DFSR 0x%" PRIx32
"", cortex_m3
->nvic_dfsr
);
160 static int cortex_m3_single_step_core(struct target
*target
)
162 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
163 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
166 /* backup dhcsr reg */
167 dhcsr_save
= cortex_m3
->dcb_dhcsr
;
169 /* Mask interrupts before clearing halt, if done already. This avoids
170 * Erratum 377497 (fixed in r1p0) where setting MASKINTS while clearing
171 * HALT can put the core into an unknown state.
173 if (!(cortex_m3
->dcb_dhcsr
& C_MASKINTS
))
174 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
,
175 DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
176 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
,
177 DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
180 /* restore dhcsr reg */
181 cortex_m3
->dcb_dhcsr
= dhcsr_save
;
182 cortex_m3_clear_halt(target
);
187 static int cortex_m3_endreset_event(struct target
*target
)
192 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
193 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
194 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
195 struct cortex_m3_fp_comparator
*fp_list
= cortex_m3
->fp_comparator_list
;
196 struct cortex_m3_dwt_comparator
*dwt_list
= cortex_m3
->dwt_comparator_list
;
198 /* REVISIT The four debug monitor bits are currently ignored... */
199 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
200 LOG_DEBUG("DCB_DEMCR = 0x%8.8" PRIx32
"",dcb_demcr
);
202 /* this register is used for emulated dcc channel */
203 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
205 /* Enable debug requests */
206 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
207 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
208 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
210 /* clear any interrupt masking */
211 cortex_m3_write_debug_halt_mask(target
, 0, C_MASKINTS
);
213 /* Enable features controlled by ITM and DWT blocks, and catch only
214 * the vectors we were told to pay attention to.
216 * Target firmware is responsible for all fault handling policy
217 * choices *EXCEPT* explicitly scripted overrides like "vector_catch"
218 * or manual updates to the NVIC SHCSR and CCR registers.
220 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| armv7m
->demcr
);
222 /* Paranoia: evidently some (early?) chips don't preserve all the
223 * debug state (including FBP, DWT, etc) across reset...
227 target_write_u32(target
, FP_CTRL
, 3);
228 cortex_m3
->fpb_enabled
= 1;
230 /* Restore FPB registers */
231 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
233 target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
236 /* Restore DWT registers */
237 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
239 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 0,
241 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 4,
243 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 8,
244 dwt_list
[i
].function
);
246 retval
= dap_run(swjdp
);
247 if (retval
!= ERROR_OK
)
250 register_cache_invalidate(cortex_m3
->armv7m
.core_cache
);
252 /* make sure we have latest dhcsr flags */
253 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
258 static int cortex_m3_examine_debug_reason(struct target
*target
)
260 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
262 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
263 /* only check the debug reason if we don't know it already */
265 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
266 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
268 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
270 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
271 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
272 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
274 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
275 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
276 else if (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
)
277 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
278 else /* EXTERNAL, HALTED */
279 target
->debug_reason
= DBG_REASON_UNDEFINED
;
285 static int cortex_m3_examine_exception_reason(struct target
*target
)
287 uint32_t shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
288 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
289 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
292 mem_ap_read_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
293 switch (armv7m
->exception_number
)
297 case 3: /* Hard Fault */
298 mem_ap_read_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
299 if (except_sr
& 0x40000000)
301 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &cfsr
);
304 case 4: /* Memory Management */
305 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
306 mem_ap_read_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
308 case 5: /* Bus Fault */
309 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
310 mem_ap_read_u32(swjdp
, NVIC_BFAR
, &except_ar
);
312 case 6: /* Usage Fault */
313 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
315 case 11: /* SVCall */
317 case 12: /* Debug Monitor */
318 mem_ap_read_u32(swjdp
, NVIC_DFSR
, &except_sr
);
320 case 14: /* PendSV */
322 case 15: /* SysTick */
328 retval
= dap_run(swjdp
);
329 if (retval
== ERROR_OK
)
330 LOG_DEBUG("%s SHCSR 0x%" PRIx32
", SR 0x%" PRIx32
331 ", CFSR 0x%" PRIx32
", AR 0x%" PRIx32
,
332 armv7m_exception_string(armv7m
->exception_number
),
333 shcsr
, except_sr
, cfsr
, except_ar
);
337 /* PSP is used in some thread modes */
338 static const int armv7m_psp_reg_map
[17] = {
339 ARMV7M_R0
, ARMV7M_R1
, ARMV7M_R2
, ARMV7M_R3
,
340 ARMV7M_R4
, ARMV7M_R5
, ARMV7M_R6
, ARMV7M_R7
,
341 ARMV7M_R8
, ARMV7M_R9
, ARMV7M_R10
, ARMV7M_R11
,
342 ARMV7M_R12
, ARMV7M_PSP
, ARMV7M_R14
, ARMV7M_PC
,
346 /* MSP is used in handler and some thread modes */
347 static const int armv7m_msp_reg_map
[17] = {
348 ARMV7M_R0
, ARMV7M_R1
, ARMV7M_R2
, ARMV7M_R3
,
349 ARMV7M_R4
, ARMV7M_R5
, ARMV7M_R6
, ARMV7M_R7
,
350 ARMV7M_R8
, ARMV7M_R9
, ARMV7M_R10
, ARMV7M_R11
,
351 ARMV7M_R12
, ARMV7M_MSP
, ARMV7M_R14
, ARMV7M_PC
,
355 static int cortex_m3_debug_entry(struct target
*target
)
360 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
361 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
362 struct arm
*arm
= &armv7m
->arm
;
363 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
368 cortex_m3_clear_halt(target
);
369 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
371 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
374 /* Examine target state and mode */
375 /* First load register acessible through core debug port*/
376 int num_regs
= armv7m
->core_cache
->num_regs
;
378 for (i
= 0; i
< num_regs
; i
++)
380 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
381 armv7m
->read_core_reg(target
, i
);
384 r
= armv7m
->core_cache
->reg_list
+ ARMV7M_xPSR
;
385 xPSR
= buf_get_u32(r
->value
, 0, 32);
387 #ifdef ARMV7_GDB_HACKS
388 /* FIXME this breaks on scan chains with more than one Cortex-M3.
389 * Instead, each CM3 should have its own dummy value...
391 /* copy real xpsr reg for gdb, setting thumb bit */
392 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 0, 32, xPSR
);
393 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 5, 1, 1);
394 armv7m_gdb_dummy_cpsr_reg
.valid
= r
->valid
;
395 armv7m_gdb_dummy_cpsr_reg
.dirty
= r
->dirty
;
398 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
402 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
405 /* Are we in an exception handler */
408 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
409 armv7m
->exception_number
= (xPSR
& 0x1FF);
411 arm
->core_mode
= ARM_MODE_HANDLER
;
412 arm
->map
= armv7m_msp_reg_map
;
416 unsigned control
= buf_get_u32(armv7m
->core_cache
417 ->reg_list
[ARMV7M_CONTROL
].value
, 0, 2);
419 /* is this thread privileged? */
420 armv7m
->core_mode
= control
& 1;
421 arm
->core_mode
= armv7m
->core_mode
422 ? ARM_MODE_USER_THREAD
425 /* which stack is it using? */
427 arm
->map
= armv7m_psp_reg_map
;
429 arm
->map
= armv7m_msp_reg_map
;
431 armv7m
->exception_number
= 0;
434 if (armv7m
->exception_number
)
436 cortex_m3_examine_exception_reason(target
);
439 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32
", target->state: %s",
440 armv7m_mode_strings
[armv7m
->core_mode
],
441 *(uint32_t*)(arm
->pc
->value
),
442 target_state_name(target
));
444 if (armv7m
->post_debug_entry
)
446 retval
= armv7m
->post_debug_entry(target
);
447 if (retval
!= ERROR_OK
)
454 static int cortex_m3_poll(struct target
*target
)
457 enum target_state prev_target_state
= target
->state
;
458 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
459 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
461 /* Read from Debug Halting Control and Status Register */
462 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
463 if (retval
!= ERROR_OK
)
465 target
->state
= TARGET_UNKNOWN
;
469 /* Recover from lockup. See ARMv7-M architecture spec,
470 * section B1.5.15 "Unrecoverable exception cases".
472 * REVISIT Is there a better way to report and handle this?
474 if (cortex_m3
->dcb_dhcsr
& S_LOCKUP
) {
475 LOG_WARNING("%s -- clearing lockup after double fault",
476 target_name(target
));
477 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
478 target
->debug_reason
= DBG_REASON_DBGRQ
;
480 /* refresh status bits */
481 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
484 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
486 /* check if still in reset */
487 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
489 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
491 target
->state
= TARGET_RESET
;
496 if (target
->state
== TARGET_RESET
)
498 /* Cannot switch context while running so endreset is
499 * called with target->state == TARGET_RESET
501 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%" PRIx32
,
502 cortex_m3
->dcb_dhcsr
);
503 cortex_m3_endreset_event(target
);
504 target
->state
= TARGET_RUNNING
;
505 prev_target_state
= TARGET_RUNNING
;
508 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
510 target
->state
= TARGET_HALTED
;
512 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
514 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
517 if (arm_semihosting(target
, &retval
) != 0)
520 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
522 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
525 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
528 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
532 /* REVISIT when S_SLEEP is set, it's in a Sleep or DeepSleep state.
533 * How best to model low power modes?
536 if (target
->state
== TARGET_UNKNOWN
)
538 /* check if processor is retiring instructions */
539 if (cortex_m3
->dcb_dhcsr
& S_RETIRE_ST
)
541 target
->state
= TARGET_RUNNING
;
549 static int cortex_m3_halt(struct target
*target
)
551 LOG_DEBUG("target->state: %s",
552 target_state_name(target
));
554 if (target
->state
== TARGET_HALTED
)
556 LOG_DEBUG("target was already halted");
560 if (target
->state
== TARGET_UNKNOWN
)
562 LOG_WARNING("target was in unknown state when halt was requested");
565 if (target
->state
== TARGET_RESET
)
567 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst())
569 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
570 return ERROR_TARGET_FAILURE
;
574 /* we came here in a reset_halt or reset_init sequence
575 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
577 target
->debug_reason
= DBG_REASON_DBGRQ
;
583 /* Write to Debug Halting Control and Status Register */
584 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
586 target
->debug_reason
= DBG_REASON_DBGRQ
;
591 static int cortex_m3_soft_reset_halt(struct target
*target
)
593 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
594 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
595 uint32_t dcb_dhcsr
= 0;
596 int retval
, timeout
= 0;
598 /* Enter debug state on reset; restore DEMCR in endreset_event() */
599 mem_ap_write_u32(swjdp
, DCB_DEMCR
,
600 TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
602 /* Request a core-only reset */
603 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
,
604 AIRCR_VECTKEY
| AIRCR_VECTRESET
);
605 target
->state
= TARGET_RESET
;
607 /* registers are now invalid */
608 register_cache_invalidate(cortex_m3
->armv7m
.core_cache
);
610 while (timeout
< 100)
612 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
613 if (retval
== ERROR_OK
)
615 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
,
616 &cortex_m3
->nvic_dfsr
);
617 if ((dcb_dhcsr
& S_HALT
)
618 && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
620 LOG_DEBUG("system reset-halted, DHCSR 0x%08x, "
622 (unsigned) dcb_dhcsr
,
623 (unsigned) cortex_m3
->nvic_dfsr
);
624 cortex_m3_poll(target
);
625 /* FIXME restore user's vector catch config */
629 LOG_DEBUG("waiting for system reset-halt, "
630 "DHCSR 0x%08x, %d ms",
631 (unsigned) dcb_dhcsr
, timeout
);
640 static void cortex_m3_enable_breakpoints(struct target
*target
)
642 struct breakpoint
*breakpoint
= target
->breakpoints
;
644 /* set any pending breakpoints */
647 if (!breakpoint
->set
)
648 cortex_m3_set_breakpoint(target
, breakpoint
);
649 breakpoint
= breakpoint
->next
;
653 static int cortex_m3_resume(struct target
*target
, int current
,
654 uint32_t address
, int handle_breakpoints
, int debug_execution
)
656 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
657 struct breakpoint
*breakpoint
= NULL
;
661 if (target
->state
!= TARGET_HALTED
)
663 LOG_WARNING("target not halted");
664 return ERROR_TARGET_NOT_HALTED
;
667 if (!debug_execution
)
669 target_free_all_working_areas(target
);
670 cortex_m3_enable_breakpoints(target
);
671 cortex_m3_enable_watchpoints(target
);
676 r
= armv7m
->core_cache
->reg_list
+ ARMV7M_PRIMASK
;
678 /* Disable interrupts */
679 /* We disable interrupts in the PRIMASK register instead of
680 * masking with C_MASKINTS. This is probably the same issue
681 * as Cortex-M3 Erratum 377493 (fixed in r1p0): C_MASKINTS
682 * in parallel with disabled interrupts can cause local faults
685 * REVISIT this clearly breaks non-debug execution, since the
686 * PRIMASK register state isn't saved/restored... workaround
687 * by never resuming app code after debug execution.
689 buf_set_u32(r
->value
, 0, 1, 1);
693 /* Make sure we are in Thumb mode */
694 r
= armv7m
->core_cache
->reg_list
+ ARMV7M_xPSR
;
695 buf_set_u32(r
->value
, 24, 1, 1);
700 /* current = 1: continue on current pc, otherwise continue at <address> */
704 buf_set_u32(r
->value
, 0, 32, address
);
709 /* if we halted last time due to a bkpt instruction
710 * then we have to manually step over it, otherwise
711 * the core will break again */
713 if (!breakpoint_find(target
, buf_get_u32(r
->value
, 0, 32))
716 armv7m_maybe_skip_bkpt_inst(target
, NULL
);
719 resume_pc
= buf_get_u32(r
->value
, 0, 32);
721 armv7m_restore_context(target
);
723 /* the front-end may request us not to handle breakpoints */
724 if (handle_breakpoints
)
726 /* Single step past breakpoint at current address */
727 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
729 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
" (ID: %d)",
731 breakpoint
->unique_id
);
732 cortex_m3_unset_breakpoint(target
, breakpoint
);
733 cortex_m3_single_step_core(target
);
734 cortex_m3_set_breakpoint(target
, breakpoint
);
739 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
741 target
->debug_reason
= DBG_REASON_NOTHALTED
;
743 /* registers are now invalid */
744 register_cache_invalidate(armv7m
->core_cache
);
746 if (!debug_execution
)
748 target
->state
= TARGET_RUNNING
;
749 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
750 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
754 target
->state
= TARGET_DEBUG_RUNNING
;
755 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
756 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
762 /* int irqstepcount = 0; */
763 static int cortex_m3_step(struct target
*target
, int current
,
764 uint32_t address
, int handle_breakpoints
)
766 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
767 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
768 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
769 struct breakpoint
*breakpoint
= NULL
;
770 struct reg
*pc
= armv7m
->arm
.pc
;
771 bool bkpt_inst_found
= false;
773 if (target
->state
!= TARGET_HALTED
)
775 LOG_WARNING("target not halted");
776 return ERROR_TARGET_NOT_HALTED
;
779 /* current = 1: continue on current pc, otherwise continue at <address> */
781 buf_set_u32(pc
->value
, 0, 32, address
);
783 /* the front-end may request us not to handle breakpoints */
784 if (handle_breakpoints
) {
785 breakpoint
= breakpoint_find(target
,
786 buf_get_u32(pc
->value
, 0, 32));
788 cortex_m3_unset_breakpoint(target
, breakpoint
);
791 armv7m_maybe_skip_bkpt_inst(target
, &bkpt_inst_found
);
793 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
795 armv7m_restore_context(target
);
797 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
799 /* if no bkpt instruction is found at pc then we can perform
800 * a normal step, otherwise we have to manually step over the bkpt
801 * instruction - as such simulate a step */
802 if (bkpt_inst_found
== false)
804 /* set step and clear halt */
805 cortex_m3_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
808 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
810 /* registers are now invalid */
811 register_cache_invalidate(cortex_m3
->armv7m
.core_cache
);
814 cortex_m3_set_breakpoint(target
, breakpoint
);
816 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
817 " nvic_icsr = 0x%" PRIx32
,
818 cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
821 retval
= cortex_m3_debug_entry(target
);
822 if (retval
!= ERROR_OK
)
824 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
826 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
827 " nvic_icsr = 0x%" PRIx32
,
828 cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
833 static int cortex_m3_assert_reset(struct target
*target
)
835 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
836 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
839 LOG_DEBUG("target->state: %s",
840 target_state_name(target
));
842 enum reset_types jtag_reset_config
= jtag_get_reset_config();
845 * We can reset Cortex-M3 targets using just the NVIC without
846 * requiring SRST, getting a SoC reset (or a core-only reset)
847 * instead of a system reset.
849 if (!(jtag_reset_config
& RESET_HAS_SRST
))
852 /* Enable debug requests */
853 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
854 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
855 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
857 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
859 if (!target
->reset_halt
)
861 /* Set/Clear C_MASKINTS in a separate operation */
862 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
863 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
,
864 DBGKEY
| C_DEBUGEN
| C_HALT
);
866 /* clear any debug flags before resuming */
867 cortex_m3_clear_halt(target
);
869 /* clear C_HALT in dhcsr reg */
870 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
874 /* Halt in debug on reset; endreset_event() restores DEMCR.
876 * REVISIT catching BUSERR presumably helps to defend against
877 * bad vector table entries. Should this include MMERR or
880 mem_ap_write_atomic_u32(swjdp
, DCB_DEMCR
,
881 TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
885 * When nRST is asserted on most Stellaris devices, it clears some of
886 * the debug state. The ARMv7M and Cortex-M3 TRMs say that's wrong;
887 * and OpenOCD depends on those TRMs. So we won't use SRST on those
888 * chips. (Only power-on reset should affect debug state, beyond a
889 * few specified bits; not the chip's nRST input, wired to SRST.)
891 * REVISIT current errata specs don't seem to cover this issue.
892 * Do we have more details than this email?
893 * https://lists.berlios.de/pipermail
894 * /openocd-development/2008-August/003065.html
896 if (strcmp(target
->variant
, "lm3s") == 0)
898 /* Check for silicon revisions with the issue. */
901 if (target_read_u32(target
, 0x400fe000, &did0
) == ERROR_OK
)
903 switch ((did0
>> 16) & 0xff)
906 /* all Sandstorm suffer issue */
912 /* Fury and DustDevil rev A have
913 * this nRST problem. It should
914 * be fixed in rev B silicon.
916 if (((did0
>> 8) & 0xff) == 0)
920 /* Tempest should be fine. */
928 /* default to asserting srst */
929 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
931 jtag_add_reset(1, 1);
935 jtag_add_reset(0, 1);
940 /* Use a standard Cortex-M3 software reset mechanism.
941 * SYSRESETREQ will reset SoC peripherals outside the
942 * core, like watchdog timers, if the SoC wires it up
943 * correctly. Else VECRESET can reset just the core.
945 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
,
946 AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
947 LOG_DEBUG("Using Cortex-M3 SYSRESETREQ");
950 /* I do not know why this is necessary, but it
951 * fixes strange effects (step/resume cause NMI
952 * after reset) on LM3S6918 -- Michael Schwingen
955 mem_ap_read_atomic_u32(swjdp
, NVIC_AIRCR
, &tmp
);
959 target
->state
= TARGET_RESET
;
960 jtag_add_sleep(50000);
962 register_cache_invalidate(cortex_m3
->armv7m
.core_cache
);
964 if (target
->reset_halt
)
967 if ((retval
= target_halt(target
)) != ERROR_OK
)
974 static int cortex_m3_deassert_reset(struct target
*target
)
976 LOG_DEBUG("target->state: %s",
977 target_state_name(target
));
979 /* deassert reset lines */
980 jtag_add_reset(0, 0);
986 cortex_m3_set_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
991 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
992 struct cortex_m3_fp_comparator
*comparator_list
= cortex_m3
->fp_comparator_list
;
996 LOG_WARNING("breakpoint (BPID: %d) already set", breakpoint
->unique_id
);
1000 if (cortex_m3
->auto_bp_type
)
1002 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1005 if (breakpoint
->type
== BKPT_HARD
)
1007 while (comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
1009 if (fp_num
>= cortex_m3
->fp_num_code
)
1011 LOG_ERROR("Can not find free FPB Comparator!");
1014 breakpoint
->set
= fp_num
+ 1;
1015 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
1016 comparator_list
[fp_num
].used
= 1;
1017 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
1018 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
1019 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32
"", fp_num
, comparator_list
[fp_num
].fpcr_value
);
1020 if (!cortex_m3
->fpb_enabled
)
1022 LOG_DEBUG("FPB wasn't enabled, do it now");
1023 target_write_u32(target
, FP_CTRL
, 3);
1026 else if (breakpoint
->type
== BKPT_SOFT
)
1030 /* NOTE: on ARMv6-M and ARMv7-M, BKPT(0xab) is used for
1031 * semihosting; don't use that. Otherwise the BKPT
1032 * parameter is arbitrary.
1034 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1035 retval
= target_read_memory(target
,
1036 breakpoint
->address
& 0xFFFFFFFE,
1037 breakpoint
->length
, 1,
1038 breakpoint
->orig_instr
);
1039 if (retval
!= ERROR_OK
)
1041 retval
= target_write_memory(target
,
1042 breakpoint
->address
& 0xFFFFFFFE,
1043 breakpoint
->length
, 1,
1045 if (retval
!= ERROR_OK
)
1047 breakpoint
->set
= true;
1050 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
1051 breakpoint
->unique_id
,
1052 (int)(breakpoint
->type
),
1053 breakpoint
->address
,
1061 cortex_m3_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1064 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1065 struct cortex_m3_fp_comparator
* comparator_list
= cortex_m3
->fp_comparator_list
;
1067 if (!breakpoint
->set
)
1069 LOG_WARNING("breakpoint not set");
1073 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
1074 breakpoint
->unique_id
,
1075 (int)(breakpoint
->type
),
1076 breakpoint
->address
,
1080 if (breakpoint
->type
== BKPT_HARD
)
1082 int fp_num
= breakpoint
->set
- 1;
1083 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
1085 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
1088 comparator_list
[fp_num
].used
= 0;
1089 comparator_list
[fp_num
].fpcr_value
= 0;
1090 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
1094 /* restore original instruction (kept in target endianness) */
1095 if (breakpoint
->length
== 4)
1097 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
1104 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
1110 breakpoint
->set
= false;
1116 cortex_m3_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1118 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1120 if (cortex_m3
->auto_bp_type
)
1122 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1123 #ifdef ARMV7_GDB_HACKS
1124 if (breakpoint
->length
!= 2) {
1125 /* XXX Hack: Replace all breakpoints with length != 2 with
1126 * a hardware breakpoint. */
1127 breakpoint
->type
= BKPT_HARD
;
1128 breakpoint
->length
= 2;
1133 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
1135 LOG_INFO("flash patch comparator requested outside code memory region");
1136 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1139 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
1141 LOG_INFO("soft breakpoint requested in code (flash) memory region");
1142 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1145 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
1147 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
1148 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1151 if ((breakpoint
->length
!= 2))
1153 LOG_INFO("only breakpoints of two bytes length supported");
1154 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1157 if (breakpoint
->type
== BKPT_HARD
)
1158 cortex_m3
->fp_code_available
--;
1159 cortex_m3_set_breakpoint(target
, breakpoint
);
1165 cortex_m3_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1167 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1169 /* REVISIT why check? FBP can be updated with core running ... */
1170 if (target
->state
!= TARGET_HALTED
)
1172 LOG_WARNING("target not halted");
1173 return ERROR_TARGET_NOT_HALTED
;
1176 if (cortex_m3
->auto_bp_type
)
1178 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1181 if (breakpoint
->set
)
1183 cortex_m3_unset_breakpoint(target
, breakpoint
);
1186 if (breakpoint
->type
== BKPT_HARD
)
1187 cortex_m3
->fp_code_available
++;
1193 cortex_m3_set_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1196 uint32_t mask
, temp
;
1197 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1199 /* watchpoint params were validated earlier */
1201 temp
= watchpoint
->length
;
1208 /* REVISIT Don't fully trust these "not used" records ... users
1209 * may set up breakpoints by hand, e.g. dual-address data value
1210 * watchpoint using comparator #1; comparator #0 matching cycle
1211 * count; send data trace info through ITM and TPIU; etc
1213 struct cortex_m3_dwt_comparator
*comparator
;
1215 for (comparator
= cortex_m3
->dwt_comparator_list
;
1216 comparator
->used
&& dwt_num
< cortex_m3
->dwt_num_comp
;
1217 comparator
++, dwt_num
++)
1219 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
1221 LOG_ERROR("Can not find free DWT Comparator");
1224 comparator
->used
= 1;
1225 watchpoint
->set
= dwt_num
+ 1;
1227 comparator
->comp
= watchpoint
->address
;
1228 target_write_u32(target
, comparator
->dwt_comparator_address
+ 0,
1231 comparator
->mask
= mask
;
1232 target_write_u32(target
, comparator
->dwt_comparator_address
+ 4,
1235 switch (watchpoint
->rw
) {
1237 comparator
->function
= 5;
1240 comparator
->function
= 6;
1243 comparator
->function
= 7;
1246 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1247 comparator
->function
);
1249 LOG_DEBUG("Watchpoint (ID %d) DWT%d 0x%08x 0x%x 0x%05x",
1250 watchpoint
->unique_id
, dwt_num
,
1251 (unsigned) comparator
->comp
,
1252 (unsigned) comparator
->mask
,
1253 (unsigned) comparator
->function
);
1258 cortex_m3_unset_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1260 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1261 struct cortex_m3_dwt_comparator
*comparator
;
1264 if (!watchpoint
->set
)
1266 LOG_WARNING("watchpoint (wpid: %d) not set",
1267 watchpoint
->unique_id
);
1271 dwt_num
= watchpoint
->set
- 1;
1273 LOG_DEBUG("Watchpoint (ID %d) DWT%d address: 0x%08x clear",
1274 watchpoint
->unique_id
, dwt_num
,
1275 (unsigned) watchpoint
->address
);
1277 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1279 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1283 comparator
= cortex_m3
->dwt_comparator_list
+ dwt_num
;
1284 comparator
->used
= 0;
1285 comparator
->function
= 0;
1286 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1287 comparator
->function
);
1289 watchpoint
->set
= false;
1295 cortex_m3_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1297 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1299 if (cortex_m3
->dwt_comp_available
< 1)
1301 LOG_DEBUG("no comparators?");
1302 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1305 /* hardware doesn't support data value masking */
1306 if (watchpoint
->mask
!= ~(uint32_t)0) {
1307 LOG_DEBUG("watchpoint value masks not supported");
1308 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1311 /* hardware allows address masks of up to 32K */
1314 for (mask
= 0; mask
< 16; mask
++) {
1315 if ((1u << mask
) == watchpoint
->length
)
1319 LOG_DEBUG("unsupported watchpoint length");
1320 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1322 if (watchpoint
->address
& ((1 << mask
) - 1)) {
1323 LOG_DEBUG("watchpoint address is unaligned");
1324 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1327 /* Caller doesn't seem to be able to describe watching for data
1328 * values of zero; that flags "no value".
1330 * REVISIT This DWT may well be able to watch for specific data
1331 * values. Requires comparator #1 to set DATAVMATCH and match
1332 * the data, and another comparator (DATAVADDR0) matching addr.
1334 if (watchpoint
->value
) {
1335 LOG_DEBUG("data value watchpoint not YET supported");
1336 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1339 cortex_m3
->dwt_comp_available
--;
1340 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1346 cortex_m3_remove_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1348 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1350 /* REVISIT why check? DWT can be updated with core running ... */
1351 if (target
->state
!= TARGET_HALTED
)
1353 LOG_WARNING("target not halted");
1354 return ERROR_TARGET_NOT_HALTED
;
1357 if (watchpoint
->set
)
1359 cortex_m3_unset_watchpoint(target
, watchpoint
);
1362 cortex_m3
->dwt_comp_available
++;
1363 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1368 static void cortex_m3_enable_watchpoints(struct target
*target
)
1370 struct watchpoint
*watchpoint
= target
->watchpoints
;
1372 /* set any pending watchpoints */
1375 if (!watchpoint
->set
)
1376 cortex_m3_set_watchpoint(target
, watchpoint
);
1377 watchpoint
= watchpoint
->next
;
1381 static int cortex_m3_load_core_reg_u32(struct target
*target
,
1382 enum armv7m_regtype type
, uint32_t num
, uint32_t * value
)
1385 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1386 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1388 /* NOTE: we "know" here that the register identifiers used
1389 * in the v7m header match the Cortex-M3 Debug Core Register
1390 * Selector values for R0..R15, xPSR, MSP, and PSP.
1394 /* read a normal core register */
1395 retval
= cortexm3_dap_read_coreregister_u32(swjdp
, value
, num
);
1397 if (retval
!= ERROR_OK
)
1399 LOG_ERROR("JTAG failure %i",retval
);
1400 return ERROR_JTAG_DEVICE_ERROR
;
1402 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
"",(int)num
,*value
);
1405 case ARMV7M_PRIMASK
:
1406 case ARMV7M_BASEPRI
:
1407 case ARMV7M_FAULTMASK
:
1408 case ARMV7M_CONTROL
:
1409 /* Cortex-M3 packages these four registers as bitfields
1410 * in one Debug Core register. So say r0 and r2 docs;
1411 * it was removed from r1 docs, but still works.
1413 cortexm3_dap_read_coreregister_u32(swjdp
, value
, 20);
1417 case ARMV7M_PRIMASK
:
1418 *value
= buf_get_u32((uint8_t*)value
, 0, 1);
1421 case ARMV7M_BASEPRI
:
1422 *value
= buf_get_u32((uint8_t*)value
, 8, 8);
1425 case ARMV7M_FAULTMASK
:
1426 *value
= buf_get_u32((uint8_t*)value
, 16, 1);
1429 case ARMV7M_CONTROL
:
1430 *value
= buf_get_u32((uint8_t*)value
, 24, 2);
1434 LOG_DEBUG("load from special reg %i value 0x%" PRIx32
"", (int)num
, *value
);
1438 return ERROR_INVALID_ARGUMENTS
;
1444 static int cortex_m3_store_core_reg_u32(struct target
*target
,
1445 enum armv7m_regtype type
, uint32_t num
, uint32_t value
)
1449 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1450 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1452 #ifdef ARMV7_GDB_HACKS
1453 /* If the LR register is being modified, make sure it will put us
1454 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1455 * hack to deal with the fact that gdb will sometimes "forge"
1456 * return addresses, and doesn't set the LSB correctly (i.e., when
1457 * printing expressions containing function calls, it sets LR = 0.)
1458 * Valid exception return codes have bit 0 set too.
1460 if (num
== ARMV7M_R14
)
1464 /* NOTE: we "know" here that the register identifiers used
1465 * in the v7m header match the Cortex-M3 Debug Core Register
1466 * Selector values for R0..R15, xPSR, MSP, and PSP.
1470 retval
= cortexm3_dap_write_coreregister_u32(swjdp
, value
, num
);
1471 if (retval
!= ERROR_OK
)
1475 LOG_ERROR("JTAG failure %i", retval
);
1476 r
= armv7m
->core_cache
->reg_list
+ num
;
1477 r
->dirty
= r
->valid
;
1478 return ERROR_JTAG_DEVICE_ERROR
;
1480 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", (int)num
, value
);
1483 case ARMV7M_PRIMASK
:
1484 case ARMV7M_BASEPRI
:
1485 case ARMV7M_FAULTMASK
:
1486 case ARMV7M_CONTROL
:
1487 /* Cortex-M3 packages these four registers as bitfields
1488 * in one Debug Core register. So say r0 and r2 docs;
1489 * it was removed from r1 docs, but still works.
1491 cortexm3_dap_read_coreregister_u32(swjdp
, ®
, 20);
1495 case ARMV7M_PRIMASK
:
1496 buf_set_u32((uint8_t*)®
, 0, 1, value
);
1499 case ARMV7M_BASEPRI
:
1500 buf_set_u32((uint8_t*)®
, 8, 8, value
);
1503 case ARMV7M_FAULTMASK
:
1504 buf_set_u32((uint8_t*)®
, 16, 1, value
);
1507 case ARMV7M_CONTROL
:
1508 buf_set_u32((uint8_t*)®
, 24, 2, value
);
1512 cortexm3_dap_write_coreregister_u32(swjdp
, reg
, 20);
1514 LOG_DEBUG("write special reg %i value 0x%" PRIx32
" ", (int)num
, value
);
1518 return ERROR_INVALID_ARGUMENTS
;
1524 static int cortex_m3_read_memory(struct target
*target
, uint32_t address
,
1525 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1527 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1528 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1529 int retval
= ERROR_INVALID_ARGUMENTS
;
1531 /* cortex_m3 handles unaligned memory access */
1532 if (count
&& buffer
) {
1535 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1538 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1541 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1549 static int cortex_m3_write_memory(struct target
*target
, uint32_t address
,
1550 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1552 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1553 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1554 int retval
= ERROR_INVALID_ARGUMENTS
;
1556 if (count
&& buffer
) {
1559 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1562 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1565 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1573 static int cortex_m3_bulk_write_memory(struct target
*target
, uint32_t address
,
1574 uint32_t count
, uint8_t *buffer
)
1576 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1579 static int cortex_m3_init_target(struct command_context
*cmd_ctx
,
1580 struct target
*target
)
1582 armv7m_build_reg_cache(target
);
1586 /* REVISIT cache valid/dirty bits are unmaintained. We could set "valid"
1587 * on r/w if the core is not running, and clear on resume or reset ... or
1588 * at least, in a post_restore_context() method.
1591 struct dwt_reg_state
{
1592 struct target
*target
;
1594 uint32_t value
; /* scratch/cache */
1597 static int cortex_m3_dwt_get_reg(struct reg
*reg
)
1599 struct dwt_reg_state
*state
= reg
->arch_info
;
1601 return target_read_u32(state
->target
, state
->addr
, &state
->value
);
1604 static int cortex_m3_dwt_set_reg(struct reg
*reg
, uint8_t *buf
)
1606 struct dwt_reg_state
*state
= reg
->arch_info
;
1608 return target_write_u32(state
->target
, state
->addr
,
1609 buf_get_u32(buf
, 0, reg
->size
));
1618 static struct dwt_reg dwt_base_regs
[] = {
1619 { DWT_CTRL
, "dwt_ctrl", 32, },
1620 /* NOTE that Erratum 532314 (fixed r2p0) affects CYCCNT: it wrongly
1621 * increments while the core is asleep.
1623 { DWT_CYCCNT
, "dwt_cyccnt", 32, },
1624 /* plus some 8 bit counters, useful for profiling with TPIU */
1627 static struct dwt_reg dwt_comp
[] = {
1628 #define DWT_COMPARATOR(i) \
1629 { DWT_COMP0 + 0x10 * (i), "dwt_" #i "_comp", 32, }, \
1630 { DWT_MASK0 + 0x10 * (i), "dwt_" #i "_mask", 4, }, \
1631 { DWT_FUNCTION0 + 0x10 * (i), "dwt_" #i "_function", 32, }
1636 #undef DWT_COMPARATOR
1639 static const struct reg_arch_type dwt_reg_type
= {
1640 .get
= cortex_m3_dwt_get_reg
,
1641 .set
= cortex_m3_dwt_set_reg
,
1645 cortex_m3_dwt_addreg(struct target
*t
, struct reg
*r
, struct dwt_reg
*d
)
1647 struct dwt_reg_state
*state
;
1649 state
= calloc(1, sizeof *state
);
1652 state
->addr
= d
->addr
;
1657 r
->value
= &state
->value
;
1658 r
->arch_info
= state
;
1659 r
->type
= &dwt_reg_type
;
1663 cortex_m3_dwt_setup(struct cortex_m3_common
*cm3
, struct target
*target
)
1666 struct reg_cache
*cache
;
1667 struct cortex_m3_dwt_comparator
*comparator
;
1670 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1672 LOG_DEBUG("no DWT");
1676 cm3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1677 cm3
->dwt_comp_available
= cm3
->dwt_num_comp
;
1678 cm3
->dwt_comparator_list
= calloc(cm3
->dwt_num_comp
,
1679 sizeof(struct cortex_m3_dwt_comparator
));
1680 if (!cm3
->dwt_comparator_list
) {
1682 cm3
->dwt_num_comp
= 0;
1683 LOG_ERROR("out of mem");
1687 cache
= calloc(1, sizeof *cache
);
1690 free(cm3
->dwt_comparator_list
);
1693 cache
->name
= "cortex-m3 dwt registers";
1694 cache
->num_regs
= 2 + cm3
->dwt_num_comp
* 3;
1695 cache
->reg_list
= calloc(cache
->num_regs
, sizeof *cache
->reg_list
);
1696 if (!cache
->reg_list
) {
1701 for (reg
= 0; reg
< 2; reg
++)
1702 cortex_m3_dwt_addreg(target
, cache
->reg_list
+ reg
,
1703 dwt_base_regs
+ reg
);
1705 comparator
= cm3
->dwt_comparator_list
;
1706 for (i
= 0; i
< cm3
->dwt_num_comp
; i
++, comparator
++) {
1709 comparator
->dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1710 for (j
= 0; j
< 3; j
++, reg
++)
1711 cortex_m3_dwt_addreg(target
, cache
->reg_list
+ reg
,
1712 dwt_comp
+ 3 * i
+ j
);
1715 *register_get_last_cache_p(&target
->reg_cache
) = cache
;
1716 cm3
->dwt_cache
= cache
;
1718 LOG_DEBUG("DWT dwtcr 0x%" PRIx32
", comp %d, watch%s",
1719 dwtcr
, cm3
->dwt_num_comp
,
1720 (dwtcr
& (0xf << 24)) ? " only" : "/trigger");
1722 /* REVISIT: if num_comp > 1, check whether comparator #1 can
1723 * implement single-address data value watchpoints ... so we
1724 * won't need to check it later, when asked to set one up.
1728 static int cortex_m3_examine(struct target
*target
)
1731 uint32_t cpuid
, fpcr
;
1733 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1734 struct adiv5_dap
*swjdp
= &cortex_m3
->armv7m
.dap
;
1736 if ((retval
= ahbap_debugport_init(swjdp
)) != ERROR_OK
)
1739 if (!target_was_examined(target
))
1741 target_set_examined(target
);
1743 /* Read from Device Identification Registers */
1744 retval
= target_read_u32(target
, CPUID
, &cpuid
);
1745 if (retval
!= ERROR_OK
)
1748 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1749 LOG_DEBUG("Cortex-M3 r%" PRId8
"p%" PRId8
" processor detected",
1750 (uint8_t)((cpuid
>> 20) & 0xf), (uint8_t)((cpuid
>> 0) & 0xf));
1751 LOG_DEBUG("cpuid: 0x%8.8" PRIx32
"", cpuid
);
1753 /* NOTE: FPB and DWT are both optional. */
1756 target_read_u32(target
, FP_CTRL
, &fpcr
);
1757 cortex_m3
->auto_bp_type
= 1;
1758 cortex_m3
->fp_num_code
= ((fpcr
>> 8) & 0x70) | ((fpcr
>> 4) & 0xF); /* bits [14:12] and [7:4] */
1759 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1760 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1761 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(struct cortex_m3_fp_comparator
));
1762 cortex_m3
->fpb_enabled
= fpcr
& 1;
1763 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1765 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1766 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1768 LOG_DEBUG("FPB fpcr 0x%" PRIx32
", numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1771 cortex_m3_dwt_setup(cortex_m3
, target
);
1773 /* These hardware breakpoints only work for code in flash! */
1774 LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints",
1775 target_name(target
),
1776 cortex_m3
->fp_num_code
,
1777 cortex_m3
->dwt_num_comp
);
1783 static int cortex_m3_dcc_read(struct adiv5_dap
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1787 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1788 *ctrl
= (uint8_t)dcrdr
;
1789 *value
= (uint8_t)(dcrdr
>> 8);
1791 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1793 /* write ack back to software dcc register
1794 * signify we have read data */
1795 if (dcrdr
& (1 << 0))
1798 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1804 static int cortex_m3_target_request_data(struct target
*target
,
1805 uint32_t size
, uint8_t *buffer
)
1807 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1808 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1813 for (i
= 0; i
< (size
* 4); i
++)
1815 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1822 static int cortex_m3_handle_target_request(void *priv
)
1824 struct target
*target
= priv
;
1825 if (!target_was_examined(target
))
1827 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1828 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1830 if (!target
->dbg_msg_enabled
)
1833 if (target
->state
== TARGET_RUNNING
)
1838 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1840 /* check if we have data */
1841 if (ctrl
& (1 << 0))
1845 /* we assume target is quick enough */
1847 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1848 request
|= (data
<< 8);
1849 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1850 request
|= (data
<< 16);
1851 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1852 request
|= (data
<< 24);
1853 target_request(target
, request
);
1860 static int cortex_m3_init_arch_info(struct target
*target
,
1861 struct cortex_m3_common
*cortex_m3
, struct jtag_tap
*tap
)
1864 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
1866 armv7m_init_arch_info(target
, armv7m
);
1868 /* prepare JTAG information for the new target */
1869 cortex_m3
->jtag_info
.tap
= tap
;
1870 cortex_m3
->jtag_info
.scann_size
= 4;
1872 armv7m
->arm
.dap
= &armv7m
->dap
;
1874 /* Leave (only) generic DAP stuff for debugport_init(); */
1875 armv7m
->dap
.jtag_info
= &cortex_m3
->jtag_info
;
1876 armv7m
->dap
.memaccess_tck
= 8;
1877 /* Cortex-M3 has 4096 bytes autoincrement range */
1878 armv7m
->dap
.tar_autoincr_block
= (1 << 12);
1880 /* register arch-specific functions */
1881 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1883 armv7m
->post_debug_entry
= NULL
;
1885 armv7m
->pre_restore_context
= NULL
;
1887 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1888 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1890 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1892 if ((retval
= arm_jtag_setup_connection(&cortex_m3
->jtag_info
)) != ERROR_OK
)
1900 static int cortex_m3_target_create(struct target
*target
, Jim_Interp
*interp
)
1902 struct cortex_m3_common
*cortex_m3
= calloc(1,sizeof(struct cortex_m3_common
));
1904 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1905 cortex_m3_init_arch_info(target
, cortex_m3
, target
->tap
);
1910 /*--------------------------------------------------------------------------*/
1912 static int cortex_m3_verify_pointer(struct command_context
*cmd_ctx
,
1913 struct cortex_m3_common
*cm3
)
1915 if (cm3
->common_magic
!= CORTEX_M3_COMMON_MAGIC
) {
1916 command_print(cmd_ctx
, "target is not a Cortex-M3");
1917 return ERROR_TARGET_INVALID
;
1923 * Only stuff below this line should need to verify that its target
1924 * is a Cortex-M3. Everything else should have indirected through the
1925 * cortexm3_target structure, which is only used with CM3 targets.
1928 static const struct {
1932 { "hard_err", VC_HARDERR
, },
1933 { "int_err", VC_INTERR
, },
1934 { "bus_err", VC_BUSERR
, },
1935 { "state_err", VC_STATERR
, },
1936 { "chk_err", VC_CHKERR
, },
1937 { "nocp_err", VC_NOCPERR
, },
1938 { "mm_err", VC_MMERR
, },
1939 { "reset", VC_CORERESET
, },
1942 COMMAND_HANDLER(handle_cortex_m3_vector_catch_command
)
1944 struct target
*target
= get_current_target(CMD_CTX
);
1945 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1946 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
1947 struct adiv5_dap
*swjdp
= &armv7m
->dap
;
1951 retval
= cortex_m3_verify_pointer(CMD_CTX
, cortex_m3
);
1952 if (retval
!= ERROR_OK
)
1955 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &demcr
);
1960 if (CMD_ARGC
== 1) {
1961 if (strcmp(CMD_ARGV
[0], "all") == 0) {
1962 catch = VC_HARDERR
| VC_INTERR
| VC_BUSERR
1963 | VC_STATERR
| VC_CHKERR
| VC_NOCPERR
1964 | VC_MMERR
| VC_CORERESET
;
1966 } else if (strcmp(CMD_ARGV
[0], "none") == 0) {
1970 while (CMD_ARGC
-- > 0) {
1972 for (i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++) {
1973 if (strcmp(CMD_ARGV
[CMD_ARGC
], vec_ids
[i
].name
) != 0)
1975 catch |= vec_ids
[i
].mask
;
1978 if (i
== ARRAY_SIZE(vec_ids
)) {
1979 LOG_ERROR("No CM3 vector '%s'", CMD_ARGV
[CMD_ARGC
]);
1980 return ERROR_INVALID_ARGUMENTS
;
1984 /* For now, armv7m->demcr only stores vector catch flags. */
1985 armv7m
->demcr
= catch;
1990 /* write, but don't assume it stuck (why not??) */
1991 mem_ap_write_u32(swjdp
, DCB_DEMCR
, demcr
);
1992 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &demcr
);
1994 /* FIXME be sure to clear DEMCR on clean server shutdown.
1995 * Otherwise the vector catch hardware could fire when there's
1996 * no debugger hooked up, causing much confusion...
2000 for (unsigned i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++)
2002 command_print(CMD_CTX
, "%9s: %s", vec_ids
[i
].name
,
2003 (demcr
& vec_ids
[i
].mask
) ? "catch" : "ignore");
2009 COMMAND_HANDLER(handle_cortex_m3_mask_interrupts_command
)
2011 struct target
*target
= get_current_target(CMD_CTX
);
2012 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
2015 retval
= cortex_m3_verify_pointer(CMD_CTX
, cortex_m3
);
2016 if (retval
!= ERROR_OK
)
2019 if (target
->state
!= TARGET_HALTED
)
2021 command_print(CMD_CTX
, "target must be stopped for \"%s\" command", CMD_NAME
);
2028 COMMAND_PARSE_ON_OFF(CMD_ARGV
[0], enable
);
2029 uint32_t mask_on
= C_HALT
| (enable
? C_MASKINTS
: 0);
2030 uint32_t mask_off
= enable
? 0 : C_MASKINTS
;
2031 cortex_m3_write_debug_halt_mask(target
, mask_on
, mask_off
);
2034 command_print(CMD_CTX
, "cortex_m3 interrupt mask %s",
2035 (cortex_m3
->dcb_dhcsr
& C_MASKINTS
) ? "on" : "off");
2040 static const struct command_registration cortex_m3_exec_command_handlers
[] = {
2043 .handler
= handle_cortex_m3_mask_interrupts_command
,
2044 .mode
= COMMAND_EXEC
,
2045 .help
= "mask cortex_m3 interrupts",
2046 .usage
= "['on'|'off']",
2049 .name
= "vector_catch",
2050 .handler
= handle_cortex_m3_vector_catch_command
,
2051 .mode
= COMMAND_EXEC
,
2052 .help
= "configure hardware vectors to trigger debug entry",
2053 .usage
= "['all'|'none'|('bus_err'|'chk_err'|...)*]",
2055 COMMAND_REGISTRATION_DONE
2057 static const struct command_registration cortex_m3_command_handlers
[] = {
2059 .chain
= armv7m_command_handlers
,
2062 .name
= "cortex_m3",
2063 .mode
= COMMAND_EXEC
,
2064 .help
= "Cortex-M3 command group",
2065 .chain
= cortex_m3_exec_command_handlers
,
2067 COMMAND_REGISTRATION_DONE
2070 struct target_type cortexm3_target
=
2072 .name
= "cortex_m3",
2074 .poll
= cortex_m3_poll
,
2075 .arch_state
= armv7m_arch_state
,
2077 .target_request_data
= cortex_m3_target_request_data
,
2079 .halt
= cortex_m3_halt
,
2080 .resume
= cortex_m3_resume
,
2081 .step
= cortex_m3_step
,
2083 .assert_reset
= cortex_m3_assert_reset
,
2084 .deassert_reset
= cortex_m3_deassert_reset
,
2085 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
2087 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
2089 .read_memory
= cortex_m3_read_memory
,
2090 .write_memory
= cortex_m3_write_memory
,
2091 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
2092 .checksum_memory
= armv7m_checksum_memory
,
2093 .blank_check_memory
= armv7m_blank_check_memory
,
2095 .run_algorithm
= armv7m_run_algorithm
,
2097 .add_breakpoint
= cortex_m3_add_breakpoint
,
2098 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
2099 .add_watchpoint
= cortex_m3_add_watchpoint
,
2100 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
2102 .commands
= cortex_m3_command_handlers
,
2103 .target_create
= cortex_m3_target_create
,
2104 .init_target
= cortex_m3_init_target
,
2105 .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)