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"
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 swjdp_common
*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 swjdp
->trans_mode
= TRANS_MODE_COMPOSITE
;
75 /* mem_ap_write_u32(swjdp, DCB_DCRSR, regnum); */
76 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRSR
& 0xFFFFFFF0);
77 dap_ap_write_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRSR
& 0xC), regnum
);
79 /* mem_ap_read_u32(swjdp, DCB_DCRDR, value); */
80 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRDR
& 0xFFFFFFF0);
81 dap_ap_read_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRDR
& 0xC), value
);
83 retval
= swjdp_transaction_endcheck(swjdp
);
85 /* restore DCB_DCRDR - this needs to be in a seperate
86 * transaction otherwise the emulated DCC channel breaks */
87 if (retval
== ERROR_OK
)
88 retval
= mem_ap_write_atomic_u32(swjdp
, DCB_DCRDR
, dcrdr
);
93 static int cortexm3_dap_write_coreregister_u32(struct swjdp_common
*swjdp
,
94 uint32_t value
, int regnum
)
99 /* because the DCB_DCRDR is used for the emulated dcc channel
100 * we have to save/restore the DCB_DCRDR when used */
102 mem_ap_read_u32(swjdp
, DCB_DCRDR
, &dcrdr
);
104 swjdp
->trans_mode
= TRANS_MODE_COMPOSITE
;
106 /* mem_ap_write_u32(swjdp, DCB_DCRDR, core_regs[i]); */
107 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRDR
& 0xFFFFFFF0);
108 dap_ap_write_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRDR
& 0xC), value
);
110 /* mem_ap_write_u32(swjdp, DCB_DCRSR, i | DCRSR_WnR); */
111 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRSR
& 0xFFFFFFF0);
112 dap_ap_write_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRSR
& 0xC), regnum
| DCRSR_WnR
);
114 retval
= swjdp_transaction_endcheck(swjdp
);
116 /* restore DCB_DCRDR - this needs to be in a seperate
117 * transaction otherwise the emulated DCC channel breaks */
118 if (retval
== ERROR_OK
)
119 retval
= mem_ap_write_atomic_u32(swjdp
, DCB_DCRDR
, dcrdr
);
124 static int cortex_m3_write_debug_halt_mask(struct target
*target
,
125 uint32_t mask_on
, uint32_t mask_off
)
127 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
128 struct swjdp_common
*swjdp
= &cortex_m3
->armv7m
.swjdp_info
;
130 /* mask off status bits */
131 cortex_m3
->dcb_dhcsr
&= ~((0xFFFF << 16) | mask_off
);
132 /* create new register mask */
133 cortex_m3
->dcb_dhcsr
|= DBGKEY
| C_DEBUGEN
| mask_on
;
135 return mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, cortex_m3
->dcb_dhcsr
);
138 static int cortex_m3_clear_halt(struct target
*target
)
140 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
141 struct swjdp_common
*swjdp
= &cortex_m3
->armv7m
.swjdp_info
;
143 /* clear step if any */
144 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_STEP
);
146 /* Read Debug Fault Status Register */
147 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
149 /* Clear Debug Fault Status */
150 mem_ap_write_atomic_u32(swjdp
, NVIC_DFSR
, cortex_m3
->nvic_dfsr
);
151 LOG_DEBUG(" NVIC_DFSR 0x%" PRIx32
"", cortex_m3
->nvic_dfsr
);
156 static int cortex_m3_single_step_core(struct target
*target
)
158 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
159 struct swjdp_common
*swjdp
= &cortex_m3
->armv7m
.swjdp_info
;
162 /* backup dhcsr reg */
163 dhcsr_save
= cortex_m3
->dcb_dhcsr
;
165 /* Mask interrupts before clearing halt, if done already. This avoids
166 * Erratum 377497 (fixed in r1p0) where setting MASKINTS while clearing
167 * HALT can put the core into an unknown state.
169 if (!(cortex_m3
->dcb_dhcsr
& C_MASKINTS
))
170 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
,
171 DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
172 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
,
173 DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
176 /* restore dhcsr reg */
177 cortex_m3
->dcb_dhcsr
= dhcsr_save
;
178 cortex_m3_clear_halt(target
);
183 static int cortex_m3_endreset_event(struct target
*target
)
187 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
188 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
189 struct swjdp_common
*swjdp
= &cortex_m3
->armv7m
.swjdp_info
;
190 struct cortex_m3_fp_comparator
*fp_list
= cortex_m3
->fp_comparator_list
;
191 struct cortex_m3_dwt_comparator
*dwt_list
= cortex_m3
->dwt_comparator_list
;
193 /* REVISIT The four debug monitor bits are currently ignored... */
194 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
195 LOG_DEBUG("DCB_DEMCR = 0x%8.8" PRIx32
"",dcb_demcr
);
197 /* this register is used for emulated dcc channel */
198 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
200 /* Enable debug requests */
201 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
202 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
203 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
205 /* clear any interrupt masking */
206 cortex_m3_write_debug_halt_mask(target
, 0, C_MASKINTS
);
208 /* Enable features controlled by ITM and DWT blocks, and catch only
209 * the vectors we were told to pay attention to.
211 * Target firmware is responsible for all fault handling policy
212 * choices *EXCEPT* explicitly scripted overrides like "vector_catch"
213 * or manual updates to the NVIC SHCSR and CCR registers.
215 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| armv7m
->demcr
);
217 /* Paranoia: evidently some (early?) chips don't preserve all the
218 * debug state (including FBP, DWT, etc) across reset...
222 target_write_u32(target
, FP_CTRL
, 3);
223 cortex_m3
->fpb_enabled
= 1;
225 /* Restore FPB registers */
226 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
228 target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
231 /* Restore DWT registers */
232 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
234 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 0,
236 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 4,
238 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 8,
239 dwt_list
[i
].function
);
241 swjdp_transaction_endcheck(swjdp
);
243 register_cache_invalidate(cortex_m3
->armv7m
.core_cache
);
245 /* make sure we have latest dhcsr flags */
246 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
251 static int cortex_m3_examine_debug_reason(struct target
*target
)
253 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
255 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
256 /* only check the debug reason if we don't know it already */
258 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
259 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
261 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
263 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
264 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
265 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
267 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
268 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
269 else if (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
)
270 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
271 else /* EXTERNAL, HALTED */
272 target
->debug_reason
= DBG_REASON_UNDEFINED
;
278 static int cortex_m3_examine_exception_reason(struct target
*target
)
280 uint32_t shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
281 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
282 struct swjdp_common
*swjdp
= &armv7m
->swjdp_info
;
284 mem_ap_read_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
285 switch (armv7m
->exception_number
)
289 case 3: /* Hard Fault */
290 mem_ap_read_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
291 if (except_sr
& 0x40000000)
293 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &cfsr
);
296 case 4: /* Memory Management */
297 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
298 mem_ap_read_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
300 case 5: /* Bus Fault */
301 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
302 mem_ap_read_u32(swjdp
, NVIC_BFAR
, &except_ar
);
304 case 6: /* Usage Fault */
305 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
307 case 11: /* SVCall */
309 case 12: /* Debug Monitor */
310 mem_ap_read_u32(swjdp
, NVIC_DFSR
, &except_sr
);
312 case 14: /* PendSV */
314 case 15: /* SysTick */
320 swjdp_transaction_endcheck(swjdp
);
321 LOG_DEBUG("%s SHCSR 0x%" PRIx32
", SR 0x%" PRIx32
", CFSR 0x%" PRIx32
", AR 0x%" PRIx32
"", armv7m_exception_string(armv7m
->exception_number
), \
322 shcsr
, except_sr
, cfsr
, except_ar
);
326 static int cortex_m3_debug_entry(struct target
*target
)
331 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
332 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
333 struct swjdp_common
*swjdp
= &armv7m
->swjdp_info
;
338 cortex_m3_clear_halt(target
);
339 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
341 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
344 /* Examine target state and mode */
345 /* First load register acessible through core debug port*/
346 int num_regs
= armv7m
->core_cache
->num_regs
;
348 for (i
= 0; i
< num_regs
; i
++)
350 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
351 armv7m
->read_core_reg(target
, i
);
354 r
= armv7m
->core_cache
->reg_list
+ ARMV7M_xPSR
;
355 xPSR
= buf_get_u32(r
->value
, 0, 32);
357 #ifdef ARMV7_GDB_HACKS
358 /* FIXME this breaks on scan chains with more than one Cortex-M3.
359 * Instead, each CM3 should have its own dummy value...
361 /* copy real xpsr reg for gdb, setting thumb bit */
362 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 0, 32, xPSR
);
363 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 5, 1, 1);
364 armv7m_gdb_dummy_cpsr_reg
.valid
= r
->valid
;
365 armv7m_gdb_dummy_cpsr_reg
.dirty
= r
->dirty
;
368 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
372 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
375 /* Are we in an exception handler */
378 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
379 armv7m
->exception_number
= (xPSR
& 0x1FF);
383 armv7m
->core_mode
= buf_get_u32(armv7m
->core_cache
384 ->reg_list
[ARMV7M_CONTROL
].value
, 0, 1);
385 armv7m
->exception_number
= 0;
388 if (armv7m
->exception_number
)
390 cortex_m3_examine_exception_reason(target
);
393 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32
", target->state: %s",
394 armv7m_mode_strings
[armv7m
->core_mode
],
395 *(uint32_t*)(armv7m
->core_cache
->reg_list
[15].value
),
396 target_state_name(target
));
398 if (armv7m
->post_debug_entry
)
399 armv7m
->post_debug_entry(target
);
404 static int cortex_m3_poll(struct target
*target
)
407 enum target_state prev_target_state
= target
->state
;
408 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
409 struct swjdp_common
*swjdp
= &cortex_m3
->armv7m
.swjdp_info
;
411 /* Read from Debug Halting Control and Status Register */
412 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
413 if (retval
!= ERROR_OK
)
415 target
->state
= TARGET_UNKNOWN
;
419 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
421 /* check if still in reset */
422 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
424 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
426 target
->state
= TARGET_RESET
;
431 if (target
->state
== TARGET_RESET
)
433 /* Cannot switch context while running so endreset is
434 * called with target->state == TARGET_RESET
436 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%" PRIx32
,
437 cortex_m3
->dcb_dhcsr
);
438 cortex_m3_endreset_event(target
);
439 target
->state
= TARGET_RUNNING
;
440 prev_target_state
= TARGET_RUNNING
;
443 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
445 target
->state
= TARGET_HALTED
;
447 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
449 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
452 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
454 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
457 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
460 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
464 /* REVISIT when S_SLEEP is set, it's in a Sleep or DeepSleep state.
465 * How best to model low power modes?
468 if (target
->state
== TARGET_UNKNOWN
)
470 /* check if processor is retiring instructions */
471 if (cortex_m3
->dcb_dhcsr
& S_RETIRE_ST
)
473 target
->state
= TARGET_RUNNING
;
481 static int cortex_m3_halt(struct target
*target
)
483 LOG_DEBUG("target->state: %s",
484 target_state_name(target
));
486 if (target
->state
== TARGET_HALTED
)
488 LOG_DEBUG("target was already halted");
492 if (target
->state
== TARGET_UNKNOWN
)
494 LOG_WARNING("target was in unknown state when halt was requested");
497 if (target
->state
== TARGET_RESET
)
499 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst())
501 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
502 return ERROR_TARGET_FAILURE
;
506 /* we came here in a reset_halt or reset_init sequence
507 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
509 target
->debug_reason
= DBG_REASON_DBGRQ
;
515 /* Write to Debug Halting Control and Status Register */
516 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
518 target
->debug_reason
= DBG_REASON_DBGRQ
;
523 static int cortex_m3_soft_reset_halt(struct target
*target
)
525 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
526 struct swjdp_common
*swjdp
= &cortex_m3
->armv7m
.swjdp_info
;
527 uint32_t dcb_dhcsr
= 0;
528 int retval
, timeout
= 0;
530 /* Enter debug state on reset; restore DEMCR in endreset_event() */
531 mem_ap_write_u32(swjdp
, DCB_DEMCR
,
532 TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
534 /* Request a core-only reset */
535 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
,
536 AIRCR_VECTKEY
| AIRCR_VECTRESET
);
537 target
->state
= TARGET_RESET
;
539 /* registers are now invalid */
540 register_cache_invalidate(cortex_m3
->armv7m
.core_cache
);
542 while (timeout
< 100)
544 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
545 if (retval
== ERROR_OK
)
547 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
,
548 &cortex_m3
->nvic_dfsr
);
549 if ((dcb_dhcsr
& S_HALT
)
550 && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
552 LOG_DEBUG("system reset-halted, DHCSR 0x%08x, "
554 (unsigned) dcb_dhcsr
,
555 (unsigned) cortex_m3
->nvic_dfsr
);
556 cortex_m3_poll(target
);
557 /* FIXME restore user's vector catch config */
561 LOG_DEBUG("waiting for system reset-halt, "
562 "DHCSR 0x%08x, %d ms",
563 (unsigned) dcb_dhcsr
, timeout
);
572 static void cortex_m3_enable_breakpoints(struct target
*target
)
574 struct breakpoint
*breakpoint
= target
->breakpoints
;
576 /* set any pending breakpoints */
579 if (!breakpoint
->set
)
580 cortex_m3_set_breakpoint(target
, breakpoint
);
581 breakpoint
= breakpoint
->next
;
585 static int cortex_m3_resume(struct target
*target
, int current
,
586 uint32_t address
, int handle_breakpoints
, int debug_execution
)
588 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
589 struct breakpoint
*breakpoint
= NULL
;
593 if (target
->state
!= TARGET_HALTED
)
595 LOG_WARNING("target not halted");
596 return ERROR_TARGET_NOT_HALTED
;
599 if (!debug_execution
)
601 target_free_all_working_areas(target
);
602 cortex_m3_enable_breakpoints(target
);
603 cortex_m3_enable_watchpoints(target
);
608 r
= armv7m
->core_cache
->reg_list
+ ARMV7M_PRIMASK
;
610 /* Disable interrupts */
611 /* We disable interrupts in the PRIMASK register instead of
612 * masking with C_MASKINTS. This is probably the same issue
613 * as Cortex-M3 Erratum 377493 (fixed in r1p0): C_MASKINTS
614 * in parallel with disabled interrupts can cause local faults
617 * REVISIT this clearly breaks non-debug execution, since the
618 * PRIMASK register state isn't saved/restored... workaround
619 * by never resuming app code after debug execution.
621 buf_set_u32(r
->value
, 0, 1, 1);
625 /* Make sure we are in Thumb mode */
626 r
= armv7m
->core_cache
->reg_list
+ ARMV7M_xPSR
;
627 buf_set_u32(r
->value
, 24, 1, 1);
632 /* current = 1: continue on current pc, otherwise continue at <address> */
633 r
= armv7m
->core_cache
->reg_list
+ 15;
636 buf_set_u32(r
->value
, 0, 32, address
);
641 resume_pc
= buf_get_u32(r
->value
, 0, 32);
643 armv7m_restore_context(target
);
645 /* the front-end may request us not to handle breakpoints */
646 if (handle_breakpoints
)
648 /* Single step past breakpoint at current address */
649 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
651 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
" (ID: %d)",
653 breakpoint
->unique_id
);
654 cortex_m3_unset_breakpoint(target
, breakpoint
);
655 cortex_m3_single_step_core(target
);
656 cortex_m3_set_breakpoint(target
, breakpoint
);
661 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
663 target
->debug_reason
= DBG_REASON_NOTHALTED
;
665 /* registers are now invalid */
666 register_cache_invalidate(armv7m
->core_cache
);
668 if (!debug_execution
)
670 target
->state
= TARGET_RUNNING
;
671 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
672 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
676 target
->state
= TARGET_DEBUG_RUNNING
;
677 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
678 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
684 /* int irqstepcount = 0; */
685 static int cortex_m3_step(struct target
*target
, int current
,
686 uint32_t address
, int handle_breakpoints
)
688 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
689 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
690 struct swjdp_common
*swjdp
= &armv7m
->swjdp_info
;
691 struct breakpoint
*breakpoint
= NULL
;
692 struct reg
*pc
= armv7m
->core_cache
->reg_list
+ 15;
694 if (target
->state
!= TARGET_HALTED
)
696 LOG_WARNING("target not halted");
697 return ERROR_TARGET_NOT_HALTED
;
700 /* current = 1: continue on current pc, otherwise continue at <address> */
702 buf_set_u32(pc
->value
, 0, 32, address
);
704 /* the front-end may request us not to handle breakpoints */
705 if (handle_breakpoints
) {
706 breakpoint
= breakpoint_find(target
,
707 buf_get_u32(pc
->value
, 0, 32));
709 cortex_m3_unset_breakpoint(target
, breakpoint
);
712 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
714 armv7m_restore_context(target
);
716 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
718 /* set step and clear halt */
719 cortex_m3_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
720 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
722 /* registers are now invalid */
723 register_cache_invalidate(cortex_m3
->armv7m
.core_cache
);
726 cortex_m3_set_breakpoint(target
, breakpoint
);
728 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
729 " nvic_icsr = 0x%" PRIx32
,
730 cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
732 cortex_m3_debug_entry(target
);
733 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
735 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
736 " nvic_icsr = 0x%" PRIx32
,
737 cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
741 static int cortex_m3_assert_reset(struct target
*target
)
743 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
744 struct swjdp_common
*swjdp
= &cortex_m3
->armv7m
.swjdp_info
;
747 LOG_DEBUG("target->state: %s",
748 target_state_name(target
));
750 enum reset_types jtag_reset_config
= jtag_get_reset_config();
753 * We can reset Cortex-M3 targets using just the NVIC without
754 * requiring SRST, getting a SoC reset (or a core-only reset)
755 * instead of a system reset.
757 if (!(jtag_reset_config
& RESET_HAS_SRST
))
760 /* Enable debug requests */
761 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
762 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
763 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
765 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
767 if (!target
->reset_halt
)
769 /* Set/Clear C_MASKINTS in a separate operation */
770 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
771 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
,
772 DBGKEY
| C_DEBUGEN
| C_HALT
);
774 /* clear any debug flags before resuming */
775 cortex_m3_clear_halt(target
);
777 /* clear C_HALT in dhcsr reg */
778 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
782 /* Halt in debug on reset; endreset_event() restores DEMCR.
784 * REVISIT catching BUSERR presumably helps to defend against
785 * bad vector table entries. Should this include MMERR or
788 mem_ap_write_atomic_u32(swjdp
, DCB_DEMCR
,
789 TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
793 * When nRST is asserted on most Stellaris devices, it clears some of
794 * the debug state. The ARMv7M and Cortex-M3 TRMs say that's wrong;
795 * and OpenOCD depends on those TRMs. So we won't use SRST on those
796 * chips. (Only power-on reset should affect debug state, beyond a
797 * few specified bits; not the chip's nRST input, wired to SRST.)
799 * REVISIT current errata specs don't seem to cover this issue.
800 * Do we have more details than this email?
801 * https://lists.berlios.de/pipermail
802 * /openocd-development/2008-August/003065.html
804 if (strcmp(target
->variant
, "lm3s") == 0)
806 /* Check for silicon revisions with the issue. */
809 if (target_read_u32(target
, 0x400fe000, &did0
) == ERROR_OK
)
811 switch ((did0
>> 16) & 0xff)
814 /* all Sandstorm suffer issue */
820 /* Fury and DustDevil rev A have
821 * this nRST problem. It should
822 * be fixed in rev B silicon.
824 if (((did0
>> 8) & 0xff) == 0)
828 /* Tempest should be fine. */
836 /* default to asserting srst */
837 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
839 jtag_add_reset(1, 1);
843 jtag_add_reset(0, 1);
848 /* Use a standard Cortex-M3 software reset mechanism.
849 * SYSRESETREQ will reset SoC peripherals outside the
850 * core, like watchdog timers, if the SoC wires it up
851 * correctly. Else VECRESET can reset just the core.
853 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
,
854 AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
855 LOG_DEBUG("Using Cortex-M3 SYSRESETREQ");
858 /* I do not know why this is necessary, but it
859 * fixes strange effects (step/resume cause NMI
860 * after reset) on LM3S6918 -- Michael Schwingen
863 mem_ap_read_atomic_u32(swjdp
, NVIC_AIRCR
, &tmp
);
867 target
->state
= TARGET_RESET
;
868 jtag_add_sleep(50000);
870 register_cache_invalidate(cortex_m3
->armv7m
.core_cache
);
872 if (target
->reset_halt
)
875 if ((retval
= target_halt(target
)) != ERROR_OK
)
882 static int cortex_m3_deassert_reset(struct target
*target
)
884 LOG_DEBUG("target->state: %s",
885 target_state_name(target
));
887 /* deassert reset lines */
888 jtag_add_reset(0, 0);
894 cortex_m3_set_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
899 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
900 struct cortex_m3_fp_comparator
*comparator_list
= cortex_m3
->fp_comparator_list
;
904 LOG_WARNING("breakpoint (BPID: %d) already set", breakpoint
->unique_id
);
908 if (cortex_m3
->auto_bp_type
)
910 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
913 if (breakpoint
->type
== BKPT_HARD
)
915 while (comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
917 if (fp_num
>= cortex_m3
->fp_num_code
)
919 LOG_ERROR("Can not find free FPB Comparator!");
922 breakpoint
->set
= fp_num
+ 1;
923 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
924 comparator_list
[fp_num
].used
= 1;
925 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
926 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
927 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32
"", fp_num
, comparator_list
[fp_num
].fpcr_value
);
928 if (!cortex_m3
->fpb_enabled
)
930 LOG_DEBUG("FPB wasn't enabled, do it now");
931 target_write_u32(target
, FP_CTRL
, 3);
934 else if (breakpoint
->type
== BKPT_SOFT
)
938 /* NOTE: on ARMv6-M and ARMv7-M, BKPT(0xab) is used for
939 * semihosting; don't use that. Otherwise the BKPT
940 * parameter is arbitrary.
942 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
943 retval
= target_read_memory(target
,
944 breakpoint
->address
& 0xFFFFFFFE,
945 breakpoint
->length
, 1,
946 breakpoint
->orig_instr
);
947 if (retval
!= ERROR_OK
)
949 retval
= target_write_memory(target
,
950 breakpoint
->address
& 0xFFFFFFFE,
951 breakpoint
->length
, 1,
953 if (retval
!= ERROR_OK
)
955 breakpoint
->set
= true;
958 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
959 breakpoint
->unique_id
,
960 (int)(breakpoint
->type
),
969 cortex_m3_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
972 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
973 struct cortex_m3_fp_comparator
* comparator_list
= cortex_m3
->fp_comparator_list
;
975 if (!breakpoint
->set
)
977 LOG_WARNING("breakpoint not set");
981 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
982 breakpoint
->unique_id
,
983 (int)(breakpoint
->type
),
988 if (breakpoint
->type
== BKPT_HARD
)
990 int fp_num
= breakpoint
->set
- 1;
991 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
993 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
996 comparator_list
[fp_num
].used
= 0;
997 comparator_list
[fp_num
].fpcr_value
= 0;
998 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
1002 /* restore original instruction (kept in target endianness) */
1003 if (breakpoint
->length
== 4)
1005 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
1012 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
1018 breakpoint
->set
= false;
1024 cortex_m3_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1026 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1028 if (cortex_m3
->auto_bp_type
)
1030 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1031 #ifdef ARMV7_GDB_HACKS
1032 if (breakpoint
->length
!= 2) {
1033 /* XXX Hack: Replace all breakpoints with length != 2 with
1034 * a hardware breakpoint. */
1035 breakpoint
->type
= BKPT_HARD
;
1036 breakpoint
->length
= 2;
1041 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
1043 LOG_INFO("flash patch comparator requested outside code memory region");
1044 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1047 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
1049 LOG_INFO("soft breakpoint requested in code (flash) memory region");
1050 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1053 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
1055 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
1056 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1059 if ((breakpoint
->length
!= 2))
1061 LOG_INFO("only breakpoints of two bytes length supported");
1062 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1065 if (breakpoint
->type
== BKPT_HARD
)
1066 cortex_m3
->fp_code_available
--;
1067 cortex_m3_set_breakpoint(target
, breakpoint
);
1073 cortex_m3_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1075 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1077 /* REVISIT why check? FBP can be updated with core running ... */
1078 if (target
->state
!= TARGET_HALTED
)
1080 LOG_WARNING("target not halted");
1081 return ERROR_TARGET_NOT_HALTED
;
1084 if (cortex_m3
->auto_bp_type
)
1086 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1089 if (breakpoint
->set
)
1091 cortex_m3_unset_breakpoint(target
, breakpoint
);
1094 if (breakpoint
->type
== BKPT_HARD
)
1095 cortex_m3
->fp_code_available
++;
1101 cortex_m3_set_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1104 uint32_t mask
, temp
;
1105 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1107 /* watchpoint params were validated earlier */
1109 temp
= watchpoint
->length
;
1116 /* REVISIT Don't fully trust these "not used" records ... users
1117 * may set up breakpoints by hand, e.g. dual-address data value
1118 * watchpoint using comparator #1; comparator #0 matching cycle
1119 * count; send data trace info through ITM and TPIU; etc
1121 struct cortex_m3_dwt_comparator
*comparator
;
1123 for (comparator
= cortex_m3
->dwt_comparator_list
;
1124 comparator
->used
&& dwt_num
< cortex_m3
->dwt_num_comp
;
1125 comparator
++, dwt_num
++)
1127 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
1129 LOG_ERROR("Can not find free DWT Comparator");
1132 comparator
->used
= 1;
1133 watchpoint
->set
= dwt_num
+ 1;
1135 comparator
->comp
= watchpoint
->address
;
1136 target_write_u32(target
, comparator
->dwt_comparator_address
+ 0,
1139 comparator
->mask
= mask
;
1140 target_write_u32(target
, comparator
->dwt_comparator_address
+ 4,
1143 switch (watchpoint
->rw
) {
1145 comparator
->function
= 5;
1148 comparator
->function
= 6;
1151 comparator
->function
= 7;
1154 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1155 comparator
->function
);
1157 LOG_DEBUG("Watchpoint (ID %d) DWT%d 0x%08x 0x%x 0x%05x",
1158 watchpoint
->unique_id
, dwt_num
,
1159 (unsigned) comparator
->comp
,
1160 (unsigned) comparator
->mask
,
1161 (unsigned) comparator
->function
);
1166 cortex_m3_unset_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1168 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1169 struct cortex_m3_dwt_comparator
*comparator
;
1172 if (!watchpoint
->set
)
1174 LOG_WARNING("watchpoint (wpid: %d) not set",
1175 watchpoint
->unique_id
);
1179 dwt_num
= watchpoint
->set
- 1;
1181 LOG_DEBUG("Watchpoint (ID %d) DWT%d address: 0x%08x clear",
1182 watchpoint
->unique_id
, dwt_num
,
1183 (unsigned) watchpoint
->address
);
1185 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1187 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1191 comparator
= cortex_m3
->dwt_comparator_list
+ dwt_num
;
1192 comparator
->used
= 0;
1193 comparator
->function
= 0;
1194 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1195 comparator
->function
);
1197 watchpoint
->set
= false;
1203 cortex_m3_add_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1205 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1207 if (cortex_m3
->dwt_comp_available
< 1)
1209 LOG_DEBUG("no comparators?");
1210 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1213 /* hardware doesn't support data value masking */
1214 if (watchpoint
->mask
!= ~(uint32_t)0) {
1215 LOG_DEBUG("watchpoint value masks not supported");
1216 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1219 /* hardware allows address masks of up to 32K */
1222 for (mask
= 0; mask
< 16; mask
++) {
1223 if ((1u << mask
) == watchpoint
->length
)
1227 LOG_DEBUG("unsupported watchpoint length");
1228 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1230 if (watchpoint
->address
& ((1 << mask
) - 1)) {
1231 LOG_DEBUG("watchpoint address is unaligned");
1232 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1235 /* Caller doesn't seem to be able to describe watching for data
1236 * values of zero; that flags "no value".
1238 * REVISIT This DWT may well be able to watch for specific data
1239 * values. Requires comparator #1 to set DATAVMATCH and match
1240 * the data, and another comparator (DATAVADDR0) matching addr.
1242 if (watchpoint
->value
) {
1243 LOG_DEBUG("data value watchpoint not YET supported");
1244 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1247 cortex_m3
->dwt_comp_available
--;
1248 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1254 cortex_m3_remove_watchpoint(struct target
*target
, struct watchpoint
*watchpoint
)
1256 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1258 /* REVISIT why check? DWT can be updated with core running ... */
1259 if (target
->state
!= TARGET_HALTED
)
1261 LOG_WARNING("target not halted");
1262 return ERROR_TARGET_NOT_HALTED
;
1265 if (watchpoint
->set
)
1267 cortex_m3_unset_watchpoint(target
, watchpoint
);
1270 cortex_m3
->dwt_comp_available
++;
1271 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1276 static void cortex_m3_enable_watchpoints(struct target
*target
)
1278 struct watchpoint
*watchpoint
= target
->watchpoints
;
1280 /* set any pending watchpoints */
1283 if (!watchpoint
->set
)
1284 cortex_m3_set_watchpoint(target
, watchpoint
);
1285 watchpoint
= watchpoint
->next
;
1289 static int cortex_m3_load_core_reg_u32(struct target
*target
,
1290 enum armv7m_regtype type
, uint32_t num
, uint32_t * value
)
1293 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1294 struct swjdp_common
*swjdp
= &armv7m
->swjdp_info
;
1296 /* NOTE: we "know" here that the register identifiers used
1297 * in the v7m header match the Cortex-M3 Debug Core Register
1298 * Selector values for R0..R15, xPSR, MSP, and PSP.
1302 /* read a normal core register */
1303 retval
= cortexm3_dap_read_coreregister_u32(swjdp
, value
, num
);
1305 if (retval
!= ERROR_OK
)
1307 LOG_ERROR("JTAG failure %i",retval
);
1308 return ERROR_JTAG_DEVICE_ERROR
;
1310 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
"",(int)num
,*value
);
1313 case ARMV7M_PRIMASK
:
1314 case ARMV7M_BASEPRI
:
1315 case ARMV7M_FAULTMASK
:
1316 case ARMV7M_CONTROL
:
1317 /* Cortex-M3 packages these four registers as bitfields
1318 * in one Debug Core register. So say r0 and r2 docs;
1319 * it was removed from r1 docs, but still works.
1321 cortexm3_dap_read_coreregister_u32(swjdp
, value
, 20);
1325 case ARMV7M_PRIMASK
:
1326 *value
= buf_get_u32((uint8_t*)value
, 0, 1);
1329 case ARMV7M_BASEPRI
:
1330 *value
= buf_get_u32((uint8_t*)value
, 8, 8);
1333 case ARMV7M_FAULTMASK
:
1334 *value
= buf_get_u32((uint8_t*)value
, 16, 1);
1337 case ARMV7M_CONTROL
:
1338 *value
= buf_get_u32((uint8_t*)value
, 24, 2);
1342 LOG_DEBUG("load from special reg %i value 0x%" PRIx32
"", (int)num
, *value
);
1346 return ERROR_INVALID_ARGUMENTS
;
1352 static int cortex_m3_store_core_reg_u32(struct target
*target
,
1353 enum armv7m_regtype type
, uint32_t num
, uint32_t value
)
1357 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1358 struct swjdp_common
*swjdp
= &armv7m
->swjdp_info
;
1360 #ifdef ARMV7_GDB_HACKS
1361 /* If the LR register is being modified, make sure it will put us
1362 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1363 * hack to deal with the fact that gdb will sometimes "forge"
1364 * return addresses, and doesn't set the LSB correctly (i.e., when
1365 * printing expressions containing function calls, it sets LR = 0.)
1366 * Valid exception return codes have bit 0 set too.
1368 if (num
== ARMV7M_R14
)
1372 /* NOTE: we "know" here that the register identifiers used
1373 * in the v7m header match the Cortex-M3 Debug Core Register
1374 * Selector values for R0..R15, xPSR, MSP, and PSP.
1378 retval
= cortexm3_dap_write_coreregister_u32(swjdp
, value
, num
);
1379 if (retval
!= ERROR_OK
)
1383 LOG_ERROR("JTAG failure %i", retval
);
1384 r
= armv7m
->core_cache
->reg_list
+ num
;
1385 r
->dirty
= r
->valid
;
1386 return ERROR_JTAG_DEVICE_ERROR
;
1388 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", (int)num
, value
);
1391 case ARMV7M_PRIMASK
:
1392 case ARMV7M_BASEPRI
:
1393 case ARMV7M_FAULTMASK
:
1394 case ARMV7M_CONTROL
:
1395 /* Cortex-M3 packages these four registers as bitfields
1396 * in one Debug Core register. So say r0 and r2 docs;
1397 * it was removed from r1 docs, but still works.
1399 cortexm3_dap_read_coreregister_u32(swjdp
, ®
, 20);
1403 case ARMV7M_PRIMASK
:
1404 buf_set_u32((uint8_t*)®
, 0, 1, value
);
1407 case ARMV7M_BASEPRI
:
1408 buf_set_u32((uint8_t*)®
, 8, 8, value
);
1411 case ARMV7M_FAULTMASK
:
1412 buf_set_u32((uint8_t*)®
, 16, 1, value
);
1415 case ARMV7M_CONTROL
:
1416 buf_set_u32((uint8_t*)®
, 24, 2, value
);
1420 cortexm3_dap_write_coreregister_u32(swjdp
, reg
, 20);
1422 LOG_DEBUG("write special reg %i value 0x%" PRIx32
" ", (int)num
, value
);
1426 return ERROR_INVALID_ARGUMENTS
;
1432 static int cortex_m3_read_memory(struct target
*target
, uint32_t address
,
1433 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1435 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1436 struct swjdp_common
*swjdp
= &armv7m
->swjdp_info
;
1437 int retval
= ERROR_INVALID_ARGUMENTS
;
1439 /* cortex_m3 handles unaligned memory access */
1440 if (count
&& buffer
) {
1443 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1446 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1449 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1457 static int cortex_m3_write_memory(struct target
*target
, uint32_t address
,
1458 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1460 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1461 struct swjdp_common
*swjdp
= &armv7m
->swjdp_info
;
1462 int retval
= ERROR_INVALID_ARGUMENTS
;
1464 if (count
&& buffer
) {
1467 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1470 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1473 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1481 static int cortex_m3_bulk_write_memory(struct target
*target
, uint32_t address
,
1482 uint32_t count
, uint8_t *buffer
)
1484 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1487 static int cortex_m3_init_target(struct command_context
*cmd_ctx
,
1488 struct target
*target
)
1490 armv7m_build_reg_cache(target
);
1494 /* REVISIT cache valid/dirty bits are unmaintained. We could set "valid"
1495 * on r/w if the core is not running, and clear on resume or reset ... or
1496 * at least, in a post_restore_context() method.
1499 struct dwt_reg_state
{
1500 struct target
*target
;
1502 uint32_t value
; /* scratch/cache */
1505 static int cortex_m3_dwt_get_reg(struct reg
*reg
)
1507 struct dwt_reg_state
*state
= reg
->arch_info
;
1509 return target_read_u32(state
->target
, state
->addr
, &state
->value
);
1512 static int cortex_m3_dwt_set_reg(struct reg
*reg
, uint8_t *buf
)
1514 struct dwt_reg_state
*state
= reg
->arch_info
;
1516 return target_write_u32(state
->target
, state
->addr
,
1517 buf_get_u32(buf
, 0, reg
->size
));
1526 static struct dwt_reg dwt_base_regs
[] = {
1527 { DWT_CTRL
, "dwt_ctrl", 32, },
1528 /* NOTE that Erratum 532314 (fixed r2p0) affects CYCCNT: it wrongly
1529 * increments while the core is asleep.
1531 { DWT_CYCCNT
, "dwt_cyccnt", 32, },
1532 /* plus some 8 bit counters, useful for profiling with TPIU */
1535 static struct dwt_reg dwt_comp
[] = {
1536 #define DWT_COMPARATOR(i) \
1537 { DWT_COMP0 + 0x10 * (i), "dwt_" #i "_comp", 32, }, \
1538 { DWT_MASK0 + 0x10 * (i), "dwt_" #i "_mask", 4, }, \
1539 { DWT_FUNCTION0 + 0x10 * (i), "dwt_" #i "_function", 32, }
1544 #undef DWT_COMPARATOR
1547 static const struct reg_arch_type dwt_reg_type
= {
1548 .get
= cortex_m3_dwt_get_reg
,
1549 .set
= cortex_m3_dwt_set_reg
,
1553 cortex_m3_dwt_addreg(struct target
*t
, struct reg
*r
, struct dwt_reg
*d
)
1555 struct dwt_reg_state
*state
;
1557 state
= calloc(1, sizeof *state
);
1560 state
->addr
= d
->addr
;
1565 r
->value
= &state
->value
;
1566 r
->arch_info
= state
;
1567 r
->type
= &dwt_reg_type
;
1571 cortex_m3_dwt_setup(struct cortex_m3_common
*cm3
, struct target
*target
)
1574 struct reg_cache
*cache
;
1575 struct cortex_m3_dwt_comparator
*comparator
;
1578 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1580 LOG_DEBUG("no DWT");
1584 cm3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1585 cm3
->dwt_comp_available
= cm3
->dwt_num_comp
;
1586 cm3
->dwt_comparator_list
= calloc(cm3
->dwt_num_comp
,
1587 sizeof(struct cortex_m3_dwt_comparator
));
1588 if (!cm3
->dwt_comparator_list
) {
1590 cm3
->dwt_num_comp
= 0;
1591 LOG_ERROR("out of mem");
1595 cache
= calloc(1, sizeof *cache
);
1598 free(cm3
->dwt_comparator_list
);
1601 cache
->name
= "cortex-m3 dwt registers";
1602 cache
->num_regs
= 2 + cm3
->dwt_num_comp
* 3;
1603 cache
->reg_list
= calloc(cache
->num_regs
, sizeof *cache
->reg_list
);
1604 if (!cache
->reg_list
) {
1609 for (reg
= 0; reg
< 2; reg
++)
1610 cortex_m3_dwt_addreg(target
, cache
->reg_list
+ reg
,
1611 dwt_base_regs
+ reg
);
1613 comparator
= cm3
->dwt_comparator_list
;
1614 for (i
= 0; i
< cm3
->dwt_num_comp
; i
++, comparator
++) {
1617 comparator
->dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1618 for (j
= 0; j
< 3; j
++, reg
++)
1619 cortex_m3_dwt_addreg(target
, cache
->reg_list
+ reg
,
1620 dwt_comp
+ 3 * i
+ j
);
1623 *register_get_last_cache_p(&target
->reg_cache
) = cache
;
1624 cm3
->dwt_cache
= cache
;
1626 LOG_DEBUG("DWT dwtcr 0x%" PRIx32
", comp %d, watch%s",
1627 dwtcr
, cm3
->dwt_num_comp
,
1628 (dwtcr
& (0xf << 24)) ? " only" : "/trigger");
1630 /* REVISIT: if num_comp > 1, check whether comparator #1 can
1631 * implement single-address data value watchpoints ... so we
1632 * won't need to check it later, when asked to set one up.
1636 static int cortex_m3_examine(struct target
*target
)
1639 uint32_t cpuid
, fpcr
;
1641 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1642 struct swjdp_common
*swjdp
= &cortex_m3
->armv7m
.swjdp_info
;
1644 if ((retval
= ahbap_debugport_init(swjdp
)) != ERROR_OK
)
1647 if (!target_was_examined(target
))
1649 target_set_examined(target
);
1651 /* Read from Device Identification Registers */
1652 retval
= target_read_u32(target
, CPUID
, &cpuid
);
1653 if (retval
!= ERROR_OK
)
1656 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1657 LOG_DEBUG("Cortex-M3 r%dp%d processor detected",
1658 (cpuid
>> 20) & 0xf, (cpuid
>> 0) & 0xf);
1659 LOG_DEBUG("cpuid: 0x%8.8" PRIx32
"", cpuid
);
1661 /* NOTE: FPB and DWT are both optional. */
1664 target_read_u32(target
, FP_CTRL
, &fpcr
);
1665 cortex_m3
->auto_bp_type
= 1;
1666 cortex_m3
->fp_num_code
= ((fpcr
>> 8) & 0x70) | ((fpcr
>> 4) & 0xF); /* bits [14:12] and [7:4] */
1667 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1668 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1669 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(struct cortex_m3_fp_comparator
));
1670 cortex_m3
->fpb_enabled
= fpcr
& 1;
1671 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1673 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1674 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1676 LOG_DEBUG("FPB fpcr 0x%" PRIx32
", numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1679 cortex_m3_dwt_setup(cortex_m3
, target
);
1681 /* These hardware breakpoints only work for code in flash! */
1682 LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints",
1683 target_name(target
),
1684 cortex_m3
->fp_num_code
,
1685 cortex_m3
->dwt_num_comp
);
1691 static int cortex_m3_dcc_read(struct swjdp_common
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1695 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1696 *ctrl
= (uint8_t)dcrdr
;
1697 *value
= (uint8_t)(dcrdr
>> 8);
1699 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1701 /* write ack back to software dcc register
1702 * signify we have read data */
1703 if (dcrdr
& (1 << 0))
1706 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1712 static int cortex_m3_target_request_data(struct target
*target
,
1713 uint32_t size
, uint8_t *buffer
)
1715 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1716 struct swjdp_common
*swjdp
= &armv7m
->swjdp_info
;
1721 for (i
= 0; i
< (size
* 4); i
++)
1723 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1730 static int cortex_m3_handle_target_request(void *priv
)
1732 struct target
*target
= priv
;
1733 if (!target_was_examined(target
))
1735 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
1736 struct swjdp_common
*swjdp
= &armv7m
->swjdp_info
;
1738 if (!target
->dbg_msg_enabled
)
1741 if (target
->state
== TARGET_RUNNING
)
1746 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1748 /* check if we have data */
1749 if (ctrl
& (1 << 0))
1753 /* we assume target is quick enough */
1755 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1756 request
|= (data
<< 8);
1757 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1758 request
|= (data
<< 16);
1759 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1760 request
|= (data
<< 24);
1761 target_request(target
, request
);
1768 static int cortex_m3_init_arch_info(struct target
*target
,
1769 struct cortex_m3_common
*cortex_m3
, struct jtag_tap
*tap
)
1772 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
1774 armv7m_init_arch_info(target
, armv7m
);
1776 /* prepare JTAG information for the new target */
1777 cortex_m3
->jtag_info
.tap
= tap
;
1778 cortex_m3
->jtag_info
.scann_size
= 4;
1780 armv7m
->swjdp_info
.dp_select_value
= -1;
1781 armv7m
->swjdp_info
.ap_csw_value
= -1;
1782 armv7m
->swjdp_info
.ap_tar_value
= -1;
1783 armv7m
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1784 armv7m
->swjdp_info
.memaccess_tck
= 8;
1785 armv7m
->swjdp_info
.tar_autoincr_block
= (1 << 12); /* Cortex-M3 has 4096 bytes autoincrement range */
1787 /* register arch-specific functions */
1788 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1790 armv7m
->post_debug_entry
= NULL
;
1792 armv7m
->pre_restore_context
= NULL
;
1793 armv7m
->post_restore_context
= NULL
;
1795 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1796 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1798 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1800 if ((retval
= arm_jtag_setup_connection(&cortex_m3
->jtag_info
)) != ERROR_OK
)
1808 static int cortex_m3_target_create(struct target
*target
, Jim_Interp
*interp
)
1810 struct cortex_m3_common
*cortex_m3
= calloc(1,sizeof(struct cortex_m3_common
));
1812 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1813 cortex_m3_init_arch_info(target
, cortex_m3
, target
->tap
);
1818 /*--------------------------------------------------------------------------*/
1820 static int cortex_m3_verify_pointer(struct command_context
*cmd_ctx
,
1821 struct cortex_m3_common
*cm3
)
1823 if (cm3
->common_magic
!= CORTEX_M3_COMMON_MAGIC
) {
1824 command_print(cmd_ctx
, "target is not a Cortex-M3");
1825 return ERROR_TARGET_INVALID
;
1831 * Only stuff below this line should need to verify that its target
1832 * is a Cortex-M3. Everything else should have indirected through the
1833 * cortexm3_target structure, which is only used with CM3 targets.
1837 * REVISIT Thumb2 disassembly should work for all ARMv7 cores, as well
1838 * as at least ARM-1156T2. The interesting thing about Cortex-M is
1839 * that *only* Thumb2 disassembly matters. There are also some small
1840 * additions to Thumb2 that are specific to ARMv7-M.
1842 COMMAND_HANDLER(handle_cortex_m3_disassemble_command
)
1845 struct target
*target
= get_current_target(CMD_CTX
);
1846 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1848 unsigned long count
= 1;
1849 struct arm_instruction cur_instruction
;
1851 retval
= cortex_m3_verify_pointer(CMD_CTX
, cortex_m3
);
1852 if (retval
!= ERROR_OK
)
1858 COMMAND_PARSE_NUMBER(ulong
, CMD_ARGV
[1], count
);
1861 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], address
);
1864 command_print(CMD_CTX
,
1865 "usage: cortex_m3 disassemble <address> [<count>]");
1870 retval
= thumb2_opcode(target
, address
, &cur_instruction
);
1871 if (retval
!= ERROR_OK
)
1873 command_print(CMD_CTX
, "%s", cur_instruction
.text
);
1874 address
+= cur_instruction
.instruction_size
;
1880 static const struct {
1884 { "hard_err", VC_HARDERR
, },
1885 { "int_err", VC_INTERR
, },
1886 { "bus_err", VC_BUSERR
, },
1887 { "state_err", VC_STATERR
, },
1888 { "chk_err", VC_CHKERR
, },
1889 { "nocp_err", VC_NOCPERR
, },
1890 { "mm_err", VC_MMERR
, },
1891 { "reset", VC_CORERESET
, },
1894 COMMAND_HANDLER(handle_cortex_m3_vector_catch_command
)
1896 struct target
*target
= get_current_target(CMD_CTX
);
1897 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1898 struct armv7m_common
*armv7m
= &cortex_m3
->armv7m
;
1899 struct swjdp_common
*swjdp
= &armv7m
->swjdp_info
;
1903 retval
= cortex_m3_verify_pointer(CMD_CTX
, cortex_m3
);
1904 if (retval
!= ERROR_OK
)
1907 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &demcr
);
1912 if (CMD_ARGC
== 1) {
1913 if (strcmp(CMD_ARGV
[0], "all") == 0) {
1914 catch = VC_HARDERR
| VC_INTERR
| VC_BUSERR
1915 | VC_STATERR
| VC_CHKERR
| VC_NOCPERR
1916 | VC_MMERR
| VC_CORERESET
;
1918 } else if (strcmp(CMD_ARGV
[0], "none") == 0) {
1922 while (CMD_ARGC
-- > 0) {
1924 for (i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++) {
1925 if (strcmp(CMD_ARGV
[CMD_ARGC
], vec_ids
[i
].name
) != 0)
1927 catch |= vec_ids
[i
].mask
;
1930 if (i
== ARRAY_SIZE(vec_ids
)) {
1931 LOG_ERROR("No CM3 vector '%s'", CMD_ARGV
[CMD_ARGC
]);
1932 return ERROR_INVALID_ARGUMENTS
;
1936 /* For now, armv7m->demcr only stores vector catch flags. */
1937 armv7m
->demcr
= catch;
1942 /* write, but don't assume it stuck (why not??) */
1943 mem_ap_write_u32(swjdp
, DCB_DEMCR
, demcr
);
1944 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &demcr
);
1946 /* FIXME be sure to clear DEMCR on clean server shutdown.
1947 * Otherwise the vector catch hardware could fire when there's
1948 * no debugger hooked up, causing much confusion...
1952 for (unsigned i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++)
1954 command_print(CMD_CTX
, "%9s: %s", vec_ids
[i
].name
,
1955 (demcr
& vec_ids
[i
].mask
) ? "catch" : "ignore");
1961 COMMAND_HANDLER(handle_cortex_m3_mask_interrupts_command
)
1963 struct target
*target
= get_current_target(CMD_CTX
);
1964 struct cortex_m3_common
*cortex_m3
= target_to_cm3(target
);
1967 retval
= cortex_m3_verify_pointer(CMD_CTX
, cortex_m3
);
1968 if (retval
!= ERROR_OK
)
1971 if (target
->state
!= TARGET_HALTED
)
1973 command_print(CMD_CTX
, "target must be stopped for \"%s\" command", CMD_NAME
);
1980 COMMAND_PARSE_ON_OFF(CMD_ARGV
[0], enable
);
1981 uint32_t mask_on
= C_HALT
| (enable
? C_MASKINTS
: 0);
1982 uint32_t mask_off
= enable
? 0 : C_MASKINTS
;
1983 cortex_m3_write_debug_halt_mask(target
, mask_on
, mask_off
);
1986 command_print(CMD_CTX
, "cortex_m3 interrupt mask %s",
1987 (cortex_m3
->dcb_dhcsr
& C_MASKINTS
) ? "on" : "off");
1992 static const struct command_registration cortex_m3_exec_command_handlers
[] = {
1994 .name
= "disassemble",
1995 .handler
= handle_cortex_m3_disassemble_command
,
1996 .mode
= COMMAND_EXEC
,
1997 .help
= "disassemble Thumb2 instructions",
1998 .usage
= "address [count]",
2002 .handler
= handle_cortex_m3_mask_interrupts_command
,
2003 .mode
= COMMAND_EXEC
,
2004 .help
= "mask cortex_m3 interrupts",
2005 .usage
= "['on'|'off']",
2008 .name
= "vector_catch",
2009 .handler
= handle_cortex_m3_vector_catch_command
,
2010 .mode
= COMMAND_EXEC
,
2011 .help
= "configure hardware vectors to trigger debug entry",
2012 .usage
= "['all'|'none'|('bus_err'|'chk_err'|...)*]",
2014 COMMAND_REGISTRATION_DONE
2016 static const struct command_registration cortex_m3_command_handlers
[] = {
2018 .chain
= armv7m_command_handlers
,
2021 .name
= "cortex_m3",
2022 .mode
= COMMAND_EXEC
,
2023 .help
= "Cortex-M3 command group",
2024 .chain
= cortex_m3_exec_command_handlers
,
2026 COMMAND_REGISTRATION_DONE
2029 struct target_type cortexm3_target
=
2031 .name
= "cortex_m3",
2033 .poll
= cortex_m3_poll
,
2034 .arch_state
= armv7m_arch_state
,
2036 .target_request_data
= cortex_m3_target_request_data
,
2038 .halt
= cortex_m3_halt
,
2039 .resume
= cortex_m3_resume
,
2040 .step
= cortex_m3_step
,
2042 .assert_reset
= cortex_m3_assert_reset
,
2043 .deassert_reset
= cortex_m3_deassert_reset
,
2044 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
2046 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
2048 .read_memory
= cortex_m3_read_memory
,
2049 .write_memory
= cortex_m3_write_memory
,
2050 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
2051 .checksum_memory
= armv7m_checksum_memory
,
2052 .blank_check_memory
= armv7m_blank_check_memory
,
2054 .run_algorithm
= armv7m_run_algorithm
,
2056 .add_breakpoint
= cortex_m3_add_breakpoint
,
2057 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
2058 .add_watchpoint
= cortex_m3_add_watchpoint
,
2059 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
2061 .commands
= cortex_m3_command_handlers
,
2062 .target_create
= cortex_m3_target_create
,
2063 .init_target
= cortex_m3_init_target
,
2064 .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)