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 "cortex_m3.h"
35 #include "target_request.h"
36 #include "target_type.h"
37 #include "arm_disassembler.h"
40 /* NOTE: most of this should work fine for the Cortex-M1 and
41 * Cortex-M0 cores too, although they're ARMv6-M not ARMv7-M.
44 #define ARRAY_SIZE(x) ((int)(sizeof(x)/sizeof((x)[0])))
47 /* forward declarations */
48 static int cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
49 static int cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
50 static void cortex_m3_enable_watchpoints(struct target_s
*target
);
51 static int cortex_m3_store_core_reg_u32(target_t
*target
,
52 enum armv7m_regtype type
, uint32_t num
, uint32_t value
);
54 #ifdef ARMV7_GDB_HACKS
55 extern uint8_t armv7m_gdb_dummy_cpsr_value
[];
56 extern reg_t armv7m_gdb_dummy_cpsr_reg
;
59 static int cortex_m3_has_mmu(struct target_s
*target
, bool *has_mmu
)
65 static int cortexm3_dap_read_coreregister_u32(swjdp_common_t
*swjdp
,
66 uint32_t *value
, int regnum
)
71 /* because the DCB_DCRDR is used for the emulated dcc channel
72 * we have to save/restore the DCB_DCRDR when used */
74 mem_ap_read_u32(swjdp
, DCB_DCRDR
, &dcrdr
);
76 swjdp
->trans_mode
= TRANS_MODE_COMPOSITE
;
78 /* mem_ap_write_u32(swjdp, DCB_DCRSR, regnum); */
79 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRSR
& 0xFFFFFFF0);
80 dap_ap_write_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRSR
& 0xC), regnum
);
82 /* mem_ap_read_u32(swjdp, DCB_DCRDR, value); */
83 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRDR
& 0xFFFFFFF0);
84 dap_ap_read_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRDR
& 0xC), value
);
86 retval
= swjdp_transaction_endcheck(swjdp
);
88 /* restore DCB_DCRDR - this needs to be in a seperate
89 * transaction otherwise the emulated DCC channel breaks */
90 if (retval
== ERROR_OK
)
91 retval
= mem_ap_write_atomic_u32(swjdp
, DCB_DCRDR
, dcrdr
);
96 static int cortexm3_dap_write_coreregister_u32(swjdp_common_t
*swjdp
,
97 uint32_t value
, int regnum
)
102 /* because the DCB_DCRDR is used for the emulated dcc channel
103 * we have to save/restore the DCB_DCRDR when used */
105 mem_ap_read_u32(swjdp
, DCB_DCRDR
, &dcrdr
);
107 swjdp
->trans_mode
= TRANS_MODE_COMPOSITE
;
109 /* mem_ap_write_u32(swjdp, DCB_DCRDR, core_regs[i]); */
110 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRDR
& 0xFFFFFFF0);
111 dap_ap_write_reg_u32(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 dap_ap_write_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRSR
& 0xC), regnum
| DCRSR_WnR
);
117 retval
= swjdp_transaction_endcheck(swjdp
);
119 /* restore DCB_DCRDR - this needs to be in a seperate
120 * transaction otherwise the emulated DCC channel breaks */
121 if (retval
== ERROR_OK
)
122 retval
= mem_ap_write_atomic_u32(swjdp
, DCB_DCRDR
, dcrdr
);
127 static int cortex_m3_write_debug_halt_mask(target_t
*target
,
128 uint32_t mask_on
, uint32_t mask_off
)
130 struct cortex_m3_common_s
*cortex_m3
= target_to_cm3(target
);
131 struct swjdp_common_s
*swjdp
= &cortex_m3
->armv7m
.swjdp_info
;
133 /* mask off status bits */
134 cortex_m3
->dcb_dhcsr
&= ~((0xFFFF << 16) | mask_off
);
135 /* create new register mask */
136 cortex_m3
->dcb_dhcsr
|= DBGKEY
| C_DEBUGEN
| mask_on
;
138 return mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, cortex_m3
->dcb_dhcsr
);
141 static int cortex_m3_clear_halt(target_t
*target
)
143 struct cortex_m3_common_s
*cortex_m3
= target_to_cm3(target
);
144 struct swjdp_common_s
*swjdp
= &cortex_m3
->armv7m
.swjdp_info
;
146 /* clear step if any */
147 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_STEP
);
149 /* Read Debug Fault Status Register */
150 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
151 /* Clear Debug Fault Status */
152 mem_ap_write_atomic_u32(swjdp
, NVIC_DFSR
, cortex_m3
->nvic_dfsr
);
153 LOG_DEBUG(" NVIC_DFSR 0x%" PRIx32
"", cortex_m3
->nvic_dfsr
);
158 static int cortex_m3_single_step_core(target_t
*target
)
160 struct cortex_m3_common_s
*cortex_m3
= target_to_cm3(target
);
161 struct swjdp_common_s
*swjdp
= &cortex_m3
->armv7m
.swjdp_info
;
164 /* backup dhcsr reg */
165 dhcsr_save
= cortex_m3
->dcb_dhcsr
;
167 /* mask interrupts if not done already */
168 if (!(cortex_m3
->dcb_dhcsr
& C_MASKINTS
))
169 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
170 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
173 /* restore dhcsr reg */
174 cortex_m3
->dcb_dhcsr
= dhcsr_save
;
175 cortex_m3_clear_halt(target
);
180 static int cortex_m3_endreset_event(target_t
*target
)
184 struct cortex_m3_common_s
*cortex_m3
= target_to_cm3(target
);
185 struct swjdp_common_s
*swjdp
= &cortex_m3
->armv7m
.swjdp_info
;
186 cortex_m3_fp_comparator_t
*fp_list
= cortex_m3
->fp_comparator_list
;
187 cortex_m3_dwt_comparator_t
*dwt_list
= cortex_m3
->dwt_comparator_list
;
189 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
190 LOG_DEBUG("DCB_DEMCR = 0x%8.8" PRIx32
"",dcb_demcr
);
192 /* this regsiter is used for emulated dcc channel */
193 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
195 /* Enable debug requests */
196 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
197 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
198 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
200 /* clear any interrupt masking */
201 cortex_m3_write_debug_halt_mask(target
, 0, C_MASKINTS
);
203 /* Enable trace and dwt */
204 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
205 /* Monitor bus faults */
206 mem_ap_write_u32(swjdp
, NVIC_SHCSR
, SHCSR_BUSFAULTENA
);
209 target_write_u32(target
, FP_CTRL
, 3);
210 cortex_m3
->fpb_enabled
= 1;
212 /* Restore FPB registers */
213 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
215 target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
218 /* Restore DWT registers */
219 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
221 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 0,
223 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 4,
225 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 8,
226 dwt_list
[i
].function
);
228 swjdp_transaction_endcheck(swjdp
);
230 armv7m_invalidate_core_regs(target
);
232 /* make sure we have latest dhcsr flags */
233 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
238 static int cortex_m3_examine_debug_reason(target_t
*target
)
240 struct cortex_m3_common_s
*cortex_m3
= target_to_cm3(target
);
242 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
243 /* only check the debug reason if we don't know it already */
245 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
246 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
248 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
250 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
251 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
252 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
254 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
255 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
256 else if (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
)
257 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
258 else /* EXTERNAL, HALTED */
259 target
->debug_reason
= DBG_REASON_UNDEFINED
;
265 static int cortex_m3_examine_exception_reason(target_t
*target
)
267 uint32_t shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
268 struct armv7m_common_s
*armv7m
= target_to_armv7m(target
);
269 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
271 mem_ap_read_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
272 switch (armv7m
->exception_number
)
276 case 3: /* Hard Fault */
277 mem_ap_read_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
278 if (except_sr
& 0x40000000)
280 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &cfsr
);
283 case 4: /* Memory Management */
284 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
285 mem_ap_read_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
287 case 5: /* Bus Fault */
288 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
289 mem_ap_read_u32(swjdp
, NVIC_BFAR
, &except_ar
);
291 case 6: /* Usage Fault */
292 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
294 case 11: /* SVCall */
296 case 12: /* Debug Monitor */
297 mem_ap_read_u32(swjdp
, NVIC_DFSR
, &except_sr
);
299 case 14: /* PendSV */
301 case 15: /* SysTick */
307 swjdp_transaction_endcheck(swjdp
);
308 LOG_DEBUG("%s SHCSR 0x%" PRIx32
", SR 0x%" PRIx32
", CFSR 0x%" PRIx32
", AR 0x%" PRIx32
"", armv7m_exception_string(armv7m
->exception_number
), \
309 shcsr
, except_sr
, cfsr
, except_ar
);
313 static int cortex_m3_debug_entry(target_t
*target
)
318 struct cortex_m3_common_s
*cortex_m3
= target_to_cm3(target
);
319 struct armv7m_common_s
*armv7m
= &cortex_m3
->armv7m
;
320 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
324 cortex_m3_clear_halt(target
);
325 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
327 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
330 /* Examine target state and mode */
331 /* First load register acessible through core debug port*/
332 int num_regs
= armv7m
->core_cache
->num_regs
;
334 for (i
= 0; i
< num_regs
; i
++)
336 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
337 armv7m
->read_core_reg(target
, i
);
340 xPSR
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32);
342 #ifdef ARMV7_GDB_HACKS
343 /* copy real xpsr reg for gdb, setting thumb bit */
344 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 0, 32, xPSR
);
345 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 5, 1, 1);
346 armv7m_gdb_dummy_cpsr_reg
.valid
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
347 armv7m_gdb_dummy_cpsr_reg
.dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
;
350 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
353 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
354 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
357 /* Are we in an exception handler */
360 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
361 armv7m
->exception_number
= (xPSR
& 0x1FF);
365 armv7m
->core_mode
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_CONTROL
].value
, 0, 1);
366 armv7m
->exception_number
= 0;
369 if (armv7m
->exception_number
)
371 cortex_m3_examine_exception_reason(target
);
374 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32
", target->state: %s",
375 armv7m_mode_strings
[armv7m
->core_mode
],
376 *(uint32_t*)(armv7m
->core_cache
->reg_list
[15].value
),
377 target_state_name(target
));
379 if (armv7m
->post_debug_entry
)
380 armv7m
->post_debug_entry(target
);
385 static int cortex_m3_poll(target_t
*target
)
388 enum target_state prev_target_state
= target
->state
;
389 struct cortex_m3_common_s
*cortex_m3
= target_to_cm3(target
);
390 struct swjdp_common_s
*swjdp
= &cortex_m3
->armv7m
.swjdp_info
;
392 /* Read from Debug Halting Control and Status Register */
393 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
394 if (retval
!= ERROR_OK
)
396 target
->state
= TARGET_UNKNOWN
;
400 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
402 /* check if still in reset */
403 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
405 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
407 target
->state
= TARGET_RESET
;
412 if (target
->state
== TARGET_RESET
)
414 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
415 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%" PRIx32
"", cortex_m3
->dcb_dhcsr
);
416 cortex_m3_endreset_event(target
);
417 target
->state
= TARGET_RUNNING
;
418 prev_target_state
= TARGET_RUNNING
;
421 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
423 target
->state
= TARGET_HALTED
;
425 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
427 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
430 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
432 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
435 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
438 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
442 /* REVISIT when S_SLEEP is set, it's in a Sleep or DeepSleep state.
443 * How best to model low power modes?
446 if (target
->state
== TARGET_UNKNOWN
)
448 /* check if processor is retiring instructions */
449 if (cortex_m3
->dcb_dhcsr
& S_RETIRE_ST
)
451 target
->state
= TARGET_RUNNING
;
459 static int cortex_m3_halt(target_t
*target
)
461 LOG_DEBUG("target->state: %s",
462 target_state_name(target
));
464 if (target
->state
== TARGET_HALTED
)
466 LOG_DEBUG("target was already halted");
470 if (target
->state
== TARGET_UNKNOWN
)
472 LOG_WARNING("target was in unknown state when halt was requested");
475 if (target
->state
== TARGET_RESET
)
477 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst())
479 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
480 return ERROR_TARGET_FAILURE
;
484 /* we came here in a reset_halt or reset_init sequence
485 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
487 target
->debug_reason
= DBG_REASON_DBGRQ
;
493 /* Write to Debug Halting Control and Status Register */
494 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
496 target
->debug_reason
= DBG_REASON_DBGRQ
;
501 static int cortex_m3_soft_reset_halt(struct target_s
*target
)
503 struct cortex_m3_common_s
*cortex_m3
= target_to_cm3(target
);
504 struct swjdp_common_s
*swjdp
= &cortex_m3
->armv7m
.swjdp_info
;
505 uint32_t dcb_dhcsr
= 0;
506 int retval
, timeout
= 0;
508 /* Enter debug state on reset, cf. end_reset_event() */
509 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
511 /* Request a reset */
512 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_VECTRESET
);
513 target
->state
= TARGET_RESET
;
515 /* registers are now invalid */
516 armv7m_invalidate_core_regs(target
);
518 while (timeout
< 100)
520 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
521 if (retval
== ERROR_OK
)
523 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
524 if ((dcb_dhcsr
& S_HALT
) && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
526 LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%" PRIx32
", nvic_dfsr 0x%" PRIx32
"", dcb_dhcsr
, cortex_m3
->nvic_dfsr
);
527 cortex_m3_poll(target
);
531 LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%" PRIx32
", %i ms", dcb_dhcsr
, timeout
);
540 static void cortex_m3_enable_breakpoints(struct target_s
*target
)
542 breakpoint_t
*breakpoint
= target
->breakpoints
;
544 /* set any pending breakpoints */
547 if (breakpoint
->set
== 0)
548 cortex_m3_set_breakpoint(target
, breakpoint
);
549 breakpoint
= breakpoint
->next
;
553 static int cortex_m3_resume(struct target_s
*target
, int current
,
554 uint32_t address
, int handle_breakpoints
, int debug_execution
)
556 struct armv7m_common_s
*armv7m
= target_to_armv7m(target
);
557 breakpoint_t
*breakpoint
= NULL
;
560 if (target
->state
!= TARGET_HALTED
)
562 LOG_WARNING("target not halted");
563 return ERROR_TARGET_NOT_HALTED
;
566 if (!debug_execution
)
568 target_free_all_working_areas(target
);
569 cortex_m3_enable_breakpoints(target
);
570 cortex_m3_enable_watchpoints(target
);
575 /* Disable interrupts */
576 /* We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
577 * This is probably the same issue as Cortex-M3 Errata 377493:
578 * C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken. */
579 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
580 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
581 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
583 /* Make sure we are in Thumb mode */
584 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
585 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
586 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
587 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
590 /* current = 1: continue on current pc, otherwise continue at <address> */
593 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
594 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
595 armv7m
->core_cache
->reg_list
[15].valid
= 1;
598 resume_pc
= buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32);
600 armv7m_restore_context(target
);
602 /* the front-end may request us not to handle breakpoints */
603 if (handle_breakpoints
)
605 /* Single step past breakpoint at current address */
606 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
608 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
" (ID: %d)",
610 breakpoint
->unique_id
);
611 cortex_m3_unset_breakpoint(target
, breakpoint
);
612 cortex_m3_single_step_core(target
);
613 cortex_m3_set_breakpoint(target
, breakpoint
);
618 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
620 target
->debug_reason
= DBG_REASON_NOTHALTED
;
622 /* registers are now invalid */
623 armv7m_invalidate_core_regs(target
);
624 if (!debug_execution
)
626 target
->state
= TARGET_RUNNING
;
627 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
628 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
632 target
->state
= TARGET_DEBUG_RUNNING
;
633 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
634 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
640 /* int irqstepcount = 0; */
641 static int cortex_m3_step(struct target_s
*target
, int current
,
642 uint32_t address
, int handle_breakpoints
)
644 struct cortex_m3_common_s
*cortex_m3
= target_to_cm3(target
);
645 struct armv7m_common_s
*armv7m
= &cortex_m3
->armv7m
;
646 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
647 breakpoint_t
*breakpoint
= NULL
;
649 if (target
->state
!= TARGET_HALTED
)
651 LOG_WARNING("target not halted");
652 return ERROR_TARGET_NOT_HALTED
;
655 /* current = 1: continue on current pc, otherwise continue at <address> */
657 buf_set_u32(cortex_m3
->armv7m
.core_cache
->reg_list
[15].value
,
660 /* the front-end may request us not to handle breakpoints */
661 if (handle_breakpoints
) {
662 breakpoint
= breakpoint_find(target
, buf_get_u32(armv7m
663 ->core_cache
->reg_list
[15].value
, 0, 32));
665 cortex_m3_unset_breakpoint(target
, breakpoint
);
668 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
670 armv7m_restore_context(target
);
672 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
674 /* set step and clear halt */
675 cortex_m3_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
676 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
678 /* registers are now invalid */
679 armv7m_invalidate_core_regs(target
);
682 cortex_m3_set_breakpoint(target
, breakpoint
);
684 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
" nvic_icsr = 0x%" PRIx32
"", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
686 cortex_m3_debug_entry(target
);
687 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
689 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
" nvic_icsr = 0x%" PRIx32
"", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
693 static int cortex_m3_assert_reset(target_t
*target
)
695 struct cortex_m3_common_s
*cortex_m3
= target_to_cm3(target
);
696 struct swjdp_common_s
*swjdp
= &cortex_m3
->armv7m
.swjdp_info
;
699 LOG_DEBUG("target->state: %s",
700 target_state_name(target
));
702 enum reset_types jtag_reset_config
= jtag_get_reset_config();
705 * We can reset Cortex-M3 targets using just the NVIC without
706 * requiring SRST, getting a SoC reset (or a core-only reset)
707 * instead of a system reset.
709 if (!(jtag_reset_config
& RESET_HAS_SRST
))
712 /* Enable debug requests */
713 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
714 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
715 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
717 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
719 if (!target
->reset_halt
)
721 /* Set/Clear C_MASKINTS in a separate operation */
722 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
723 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
725 /* clear any debug flags before resuming */
726 cortex_m3_clear_halt(target
);
728 /* clear C_HALT in dhcsr reg */
729 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
731 /* Enter debug state on reset, cf. end_reset_event() */
732 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
736 /* Enter debug state on reset, cf. end_reset_event() */
737 mem_ap_write_atomic_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
741 * When nRST is asserted on most Stellaris devices, it clears some of
742 * the debug state. The ARMv7M and Cortex-M3 TRMs say that's wrong;
743 * and OpenOCD depends on those TRMs. So we won't use SRST on those
744 * chips. (Only power-on reset should affect debug state, beyond a
745 * few specified bits; not the chip's nRST input, wired to SRST.)
747 * REVISIT current errata specs don't seem to cover this issue.
748 * Do we have more details than this email?
749 * https://lists.berlios.de/pipermail
750 * /openocd-development/2008-August/003065.html
752 if (strcmp(target
->variant
, "lm3s") == 0)
754 /* Check for silicon revisions with the issue. */
757 if (target_read_u32(target
, 0x400fe000, &did0
) == ERROR_OK
)
759 switch ((did0
>> 16) & 0xff)
762 /* all Sandstorm suffer issue */
768 /* Fury and DustDevil rev A have
769 * this nRST problem. It should
770 * be fixed in rev B silicon.
772 if (((did0
>> 8) & 0xff) == 0)
776 /* Tempest should be fine. */
784 /* default to asserting srst */
785 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
787 jtag_add_reset(1, 1);
791 jtag_add_reset(0, 1);
796 /* Use a standard Cortex-M3 software reset mechanism.
797 * SYSRESETREQ will reset SoC peripherals outside the
798 * core, like watchdog timers, if the SoC wires it up
799 * correctly. Else VECRESET can reset just the core.
801 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
,
802 AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
803 LOG_DEBUG("Using Cortex-M3 SYSRESETREQ");
806 /* I do not know why this is necessary, but it
807 * fixes strange effects (step/resume cause NMI
808 * after reset) on LM3S6918 -- Michael Schwingen
811 mem_ap_read_atomic_u32(swjdp
, NVIC_AIRCR
, &tmp
);
815 target
->state
= TARGET_RESET
;
816 jtag_add_sleep(50000);
818 armv7m_invalidate_core_regs(target
);
820 if (target
->reset_halt
)
823 if ((retval
= target_halt(target
)) != ERROR_OK
)
830 static int cortex_m3_deassert_reset(target_t
*target
)
832 LOG_DEBUG("target->state: %s",
833 target_state_name(target
));
835 /* deassert reset lines */
836 jtag_add_reset(0, 0);
842 cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
847 struct cortex_m3_common_s
*cortex_m3
= target_to_cm3(target
);
848 cortex_m3_fp_comparator_t
*comparator_list
= cortex_m3
->fp_comparator_list
;
852 LOG_WARNING("breakpoint (BPID: %d) already set", breakpoint
->unique_id
);
856 if (cortex_m3
->auto_bp_type
)
858 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
861 if (breakpoint
->type
== BKPT_HARD
)
863 while (comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
865 if (fp_num
>= cortex_m3
->fp_num_code
)
867 LOG_DEBUG("ERROR Can not find free FP Comparator");
868 LOG_WARNING("ERROR Can not find free FP Comparator");
871 breakpoint
->set
= fp_num
+ 1;
872 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
873 comparator_list
[fp_num
].used
= 1;
874 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
875 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
876 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32
"", fp_num
, comparator_list
[fp_num
].fpcr_value
);
877 if (!cortex_m3
->fpb_enabled
)
879 LOG_DEBUG("FPB wasn't enabled, do it now");
880 target_write_u32(target
, FP_CTRL
, 3);
883 else if (breakpoint
->type
== BKPT_SOFT
)
886 buf_set_u32(code
, 0, 32, ARMV7M_T_BKPT(0x11));
887 if ((retval
= target_read_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
891 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, code
)) != ERROR_OK
)
895 breakpoint
->set
= 0x11; /* Any nice value but 0 */
898 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
899 breakpoint
->unique_id
,
900 (int)(breakpoint
->type
),
909 cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
912 struct cortex_m3_common_s
*cortex_m3
= target_to_cm3(target
);
913 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
915 if (!breakpoint
->set
)
917 LOG_WARNING("breakpoint not set");
921 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
922 breakpoint
->unique_id
,
923 (int)(breakpoint
->type
),
928 if (breakpoint
->type
== BKPT_HARD
)
930 int fp_num
= breakpoint
->set
- 1;
931 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
933 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
936 comparator_list
[fp_num
].used
= 0;
937 comparator_list
[fp_num
].fpcr_value
= 0;
938 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
942 /* restore original instruction (kept in target endianness) */
943 if (breakpoint
->length
== 4)
945 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
952 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
964 cortex_m3_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
966 struct cortex_m3_common_s
*cortex_m3
= target_to_cm3(target
);
968 if (cortex_m3
->auto_bp_type
)
970 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
971 #ifdef ARMV7_GDB_HACKS
972 if (breakpoint
->length
!= 2) {
973 /* XXX Hack: Replace all breakpoints with length != 2 with
974 * a hardware breakpoint. */
975 breakpoint
->type
= BKPT_HARD
;
976 breakpoint
->length
= 2;
981 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
983 LOG_INFO("flash patch comparator requested outside code memory region");
984 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
987 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
989 LOG_INFO("soft breakpoint requested in code (flash) memory region");
990 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
993 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
995 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
996 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
999 if ((breakpoint
->length
!= 2))
1001 LOG_INFO("only breakpoints of two bytes length supported");
1002 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1005 if (breakpoint
->type
== BKPT_HARD
)
1006 cortex_m3
->fp_code_available
--;
1007 cortex_m3_set_breakpoint(target
, breakpoint
);
1013 cortex_m3_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1015 struct cortex_m3_common_s
*cortex_m3
= target_to_cm3(target
);
1017 /* REVISIT why check? FBP can be updated with core running ... */
1018 if (target
->state
!= TARGET_HALTED
)
1020 LOG_WARNING("target not halted");
1021 return ERROR_TARGET_NOT_HALTED
;
1024 if (cortex_m3
->auto_bp_type
)
1026 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1029 if (breakpoint
->set
)
1031 cortex_m3_unset_breakpoint(target
, breakpoint
);
1034 if (breakpoint
->type
== BKPT_HARD
)
1035 cortex_m3
->fp_code_available
++;
1041 cortex_m3_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1044 uint32_t mask
, temp
;
1045 struct cortex_m3_common_s
*cortex_m3
= target_to_cm3(target
);
1047 /* watchpoint params were validated earlier */
1049 temp
= watchpoint
->length
;
1056 /* REVISIT Don't fully trust these "not used" records ... users
1057 * may set up breakpoints by hand, e.g. dual-address data value
1058 * watchpoint using comparator #1; comparator #0 matching cycle
1059 * count; send data trace info through ITM and TPIU; etc
1061 cortex_m3_dwt_comparator_t
*comparator
;
1063 for (comparator
= cortex_m3
->dwt_comparator_list
;
1064 comparator
->used
&& dwt_num
< cortex_m3
->dwt_num_comp
;
1065 comparator
++, dwt_num
++)
1067 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
1069 LOG_ERROR("Can not find free DWT Comparator");
1072 comparator
->used
= 1;
1073 watchpoint
->set
= dwt_num
+ 1;
1075 comparator
->comp
= watchpoint
->address
;
1076 target_write_u32(target
, comparator
->dwt_comparator_address
+ 0,
1079 comparator
->mask
= mask
;
1080 target_write_u32(target
, comparator
->dwt_comparator_address
+ 4,
1083 switch (watchpoint
->rw
) {
1085 comparator
->function
= 5;
1088 comparator
->function
= 6;
1091 comparator
->function
= 7;
1094 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1095 comparator
->function
);
1097 LOG_DEBUG("Watchpoint (ID %d) DWT%d 0x%08x 0x%x 0x%05x",
1098 watchpoint
->unique_id
, dwt_num
,
1099 (unsigned) comparator
->comp
,
1100 (unsigned) comparator
->mask
,
1101 (unsigned) comparator
->function
);
1106 cortex_m3_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1108 struct cortex_m3_common_s
*cortex_m3
= target_to_cm3(target
);
1109 cortex_m3_dwt_comparator_t
*comparator
;
1112 if (!watchpoint
->set
)
1114 LOG_WARNING("watchpoint (wpid: %d) not set",
1115 watchpoint
->unique_id
);
1119 dwt_num
= watchpoint
->set
- 1;
1121 LOG_DEBUG("Watchpoint (ID %d) DWT%d address: 0x%08x clear",
1122 watchpoint
->unique_id
, dwt_num
,
1123 (unsigned) watchpoint
->address
);
1125 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1127 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1131 comparator
= cortex_m3
->dwt_comparator_list
+ dwt_num
;
1132 comparator
->used
= 0;
1133 comparator
->function
= 0;
1134 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1135 comparator
->function
);
1137 watchpoint
->set
= 0;
1143 cortex_m3_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1145 struct cortex_m3_common_s
*cortex_m3
= target_to_cm3(target
);
1147 /* REVISIT why check? DWT can be updated with core running ... */
1148 if (target
->state
!= TARGET_HALTED
)
1150 LOG_WARNING("target not halted");
1151 return ERROR_TARGET_NOT_HALTED
;
1154 if (cortex_m3
->dwt_comp_available
< 1)
1156 LOG_DEBUG("no comparators?");
1157 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1160 /* hardware doesn't support data value masking */
1161 if (watchpoint
->mask
!= ~(uint32_t)0) {
1162 LOG_DEBUG("watchpoint value masks not supported");
1163 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1166 /* hardware allows address masks of up to 32K */
1169 for (mask
= 0; mask
< 16; mask
++) {
1170 if ((1u << mask
) == watchpoint
->length
)
1174 LOG_DEBUG("unsupported watchpoint length");
1175 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1177 if (watchpoint
->address
& ((1 << mask
) - 1)) {
1178 LOG_DEBUG("watchpoint address is unaligned");
1179 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1182 /* Caller doesn't seem to be able to describe watching for data
1183 * values of zero; that flags "no value".
1185 * REVISIT This DWT may well be able to watch for specific data
1186 * values. Requires comparator #1 to set DATAVMATCH and match
1187 * the data, and another comparator (DATAVADDR0) matching addr.
1189 if (watchpoint
->value
) {
1190 LOG_DEBUG("data value watchpoint not YET supported");
1191 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1194 cortex_m3
->dwt_comp_available
--;
1195 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1201 cortex_m3_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1203 struct cortex_m3_common_s
*cortex_m3
= target_to_cm3(target
);
1205 /* REVISIT why check? DWT can be updated with core running ... */
1206 if (target
->state
!= TARGET_HALTED
)
1208 LOG_WARNING("target not halted");
1209 return ERROR_TARGET_NOT_HALTED
;
1212 if (watchpoint
->set
)
1214 cortex_m3_unset_watchpoint(target
, watchpoint
);
1217 cortex_m3
->dwt_comp_available
++;
1218 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1223 static void cortex_m3_enable_watchpoints(struct target_s
*target
)
1225 watchpoint_t
*watchpoint
= target
->watchpoints
;
1227 /* set any pending watchpoints */
1230 if (watchpoint
->set
== 0)
1231 cortex_m3_set_watchpoint(target
, watchpoint
);
1232 watchpoint
= watchpoint
->next
;
1236 static int cortex_m3_load_core_reg_u32(struct target_s
*target
,
1237 enum armv7m_regtype type
, uint32_t num
, uint32_t * value
)
1240 struct armv7m_common_s
*armv7m
= target_to_armv7m(target
);
1241 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1243 /* NOTE: we "know" here that the register identifiers used
1244 * in the v7m header match the Cortex-M3 Debug Core Register
1245 * Selector values for R0..R15, xPSR, MSP, and PSP.
1249 /* read a normal core register */
1250 retval
= cortexm3_dap_read_coreregister_u32(swjdp
, value
, num
);
1252 if (retval
!= ERROR_OK
)
1254 LOG_ERROR("JTAG failure %i",retval
);
1255 return ERROR_JTAG_DEVICE_ERROR
;
1257 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
"",(int)num
,*value
);
1260 case ARMV7M_PRIMASK
:
1261 case ARMV7M_BASEPRI
:
1262 case ARMV7M_FAULTMASK
:
1263 case ARMV7M_CONTROL
:
1264 /* Cortex-M3 packages these four registers as bitfields
1265 * in one Debug Core register. So say r0 and r2 docs;
1266 * it was removed from r1 docs, but still works.
1268 cortexm3_dap_read_coreregister_u32(swjdp
, value
, 20);
1272 case ARMV7M_PRIMASK
:
1273 *value
= buf_get_u32((uint8_t*)value
, 0, 1);
1276 case ARMV7M_BASEPRI
:
1277 *value
= buf_get_u32((uint8_t*)value
, 8, 8);
1280 case ARMV7M_FAULTMASK
:
1281 *value
= buf_get_u32((uint8_t*)value
, 16, 1);
1284 case ARMV7M_CONTROL
:
1285 *value
= buf_get_u32((uint8_t*)value
, 24, 2);
1289 LOG_DEBUG("load from special reg %i value 0x%" PRIx32
"", (int)num
, *value
);
1293 return ERROR_INVALID_ARGUMENTS
;
1299 static int cortex_m3_store_core_reg_u32(struct target_s
*target
,
1300 enum armv7m_regtype type
, uint32_t num
, uint32_t value
)
1304 struct armv7m_common_s
*armv7m
= target_to_armv7m(target
);
1305 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1307 #ifdef ARMV7_GDB_HACKS
1308 /* If the LR register is being modified, make sure it will put us
1309 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1310 * hack to deal with the fact that gdb will sometimes "forge"
1311 * return addresses, and doesn't set the LSB correctly (i.e., when
1312 * printing expressions containing function calls, it sets LR = 0.)
1313 * Valid exception return codes have bit 0 set too.
1315 if (num
== ARMV7M_R14
)
1319 /* NOTE: we "know" here that the register identifiers used
1320 * in the v7m header match the Cortex-M3 Debug Core Register
1321 * Selector values for R0..R15, xPSR, MSP, and PSP.
1325 retval
= cortexm3_dap_write_coreregister_u32(swjdp
, value
, num
);
1326 if (retval
!= ERROR_OK
)
1328 LOG_ERROR("JTAG failure %i", retval
);
1329 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
1330 return ERROR_JTAG_DEVICE_ERROR
;
1332 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", (int)num
, value
);
1335 case ARMV7M_PRIMASK
:
1336 case ARMV7M_BASEPRI
:
1337 case ARMV7M_FAULTMASK
:
1338 case ARMV7M_CONTROL
:
1339 /* Cortex-M3 packages these four registers as bitfields
1340 * in one Debug Core register. So say r0 and r2 docs;
1341 * it was removed from r1 docs, but still works.
1343 cortexm3_dap_read_coreregister_u32(swjdp
, ®
, 20);
1347 case ARMV7M_PRIMASK
:
1348 buf_set_u32((uint8_t*)®
, 0, 1, value
);
1351 case ARMV7M_BASEPRI
:
1352 buf_set_u32((uint8_t*)®
, 8, 8, value
);
1355 case ARMV7M_FAULTMASK
:
1356 buf_set_u32((uint8_t*)®
, 16, 1, value
);
1359 case ARMV7M_CONTROL
:
1360 buf_set_u32((uint8_t*)®
, 24, 2, value
);
1364 cortexm3_dap_write_coreregister_u32(swjdp
, reg
, 20);
1366 LOG_DEBUG("write special reg %i value 0x%" PRIx32
" ", (int)num
, value
);
1370 return ERROR_INVALID_ARGUMENTS
;
1376 static int cortex_m3_read_memory(struct target_s
*target
, uint32_t address
,
1377 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1379 struct armv7m_common_s
*armv7m
= target_to_armv7m(target
);
1380 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1383 /* sanitize arguments */
1384 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1385 return ERROR_INVALID_ARGUMENTS
;
1387 /* cortex_m3 handles unaligned memory access */
1392 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1395 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1398 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1401 LOG_ERROR("BUG: we shouldn't get here");
1408 static int cortex_m3_write_memory(struct target_s
*target
, uint32_t address
,
1409 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1411 struct armv7m_common_s
*armv7m
= target_to_armv7m(target
);
1412 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1415 /* sanitize arguments */
1416 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1417 return ERROR_INVALID_ARGUMENTS
;
1422 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1425 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1428 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1431 LOG_ERROR("BUG: we shouldn't get here");
1438 static int cortex_m3_bulk_write_memory(target_t
*target
, uint32_t address
,
1439 uint32_t count
, uint8_t *buffer
)
1441 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1444 static int cortex_m3_init_target(struct command_context_s
*cmd_ctx
,
1445 struct target_s
*target
)
1447 armv7m_build_reg_cache(target
);
1451 /* REVISIT cache valid/dirty bits are unmaintained. We could set "valid"
1452 * on r/w if the core is not running, and clear on resume or reset ... or
1453 * at least, in a post_restore_context() method.
1456 struct dwt_reg_state
{
1457 struct target_s
*target
;
1459 uint32_t value
; /* scratch/cache */
1462 static int cortex_m3_dwt_get_reg(struct reg_s
*reg
)
1464 struct dwt_reg_state
*state
= reg
->arch_info
;
1466 return target_read_u32(state
->target
, state
->addr
, &state
->value
);
1469 static int cortex_m3_dwt_set_reg(struct reg_s
*reg
, uint8_t *buf
)
1471 struct dwt_reg_state
*state
= reg
->arch_info
;
1473 return target_write_u32(state
->target
, state
->addr
,
1474 buf_get_u32(buf
, 0, reg
->size
));
1483 static struct dwt_reg dwt_base_regs
[] = {
1484 { DWT_CTRL
, "dwt_ctrl", 32, },
1485 { DWT_CYCCNT
, "dwt_cyccnt", 32, },
1486 /* plus some 8 bit counters, useful for profiling with TPIU */
1489 static struct dwt_reg dwt_comp
[] = {
1490 #define DWT_COMPARATOR(i) \
1491 { DWT_COMP0 + 0x10 * (i), "dwt_" #i "_comp", 32, }, \
1492 { DWT_MASK0 + 0x10 * (i), "dwt_" #i "_mask", 4, }, \
1493 { DWT_FUNCTION0 + 0x10 * (i), "dwt_" #i "_function", 32, }
1498 #undef DWT_COMPARATOR
1501 static int dwt_reg_type
= -1;
1504 cortex_m3_dwt_addreg(struct target_s
*t
, struct reg_s
*r
, struct dwt_reg
*d
)
1506 struct dwt_reg_state
*state
;
1508 state
= calloc(1, sizeof *state
);
1511 state
->addr
= d
->addr
;
1516 r
->value
= &state
->value
;
1517 r
->arch_info
= state
;
1518 r
->arch_type
= dwt_reg_type
;
1522 cortex_m3_dwt_setup(cortex_m3_common_t
*cm3
, struct target_s
*target
)
1525 struct reg_cache_s
*cache
;
1526 cortex_m3_dwt_comparator_t
*comparator
;
1529 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1531 LOG_DEBUG("no DWT");
1535 if (dwt_reg_type
< 0)
1536 dwt_reg_type
= register_reg_arch_type(cortex_m3_dwt_get_reg
,
1537 cortex_m3_dwt_set_reg
);
1539 cm3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1540 cm3
->dwt_comp_available
= cm3
->dwt_num_comp
;
1541 cm3
->dwt_comparator_list
= calloc(cm3
->dwt_num_comp
,
1542 sizeof(cortex_m3_dwt_comparator_t
));
1543 if (!cm3
->dwt_comparator_list
) {
1545 cm3
->dwt_num_comp
= 0;
1546 LOG_ERROR("out of mem");
1550 cache
= calloc(1, sizeof *cache
);
1553 free(cm3
->dwt_comparator_list
);
1556 cache
->name
= "cortex-m3 dwt registers";
1557 cache
->num_regs
= 2 + cm3
->dwt_num_comp
* 3;
1558 cache
->reg_list
= calloc(cache
->num_regs
, sizeof *cache
->reg_list
);
1559 if (!cache
->reg_list
) {
1564 for (reg
= 0; reg
< 2; reg
++)
1565 cortex_m3_dwt_addreg(target
, cache
->reg_list
+ reg
,
1566 dwt_base_regs
+ reg
);
1568 comparator
= cm3
->dwt_comparator_list
;
1569 for (i
= 0; i
< cm3
->dwt_num_comp
; i
++, comparator
++) {
1572 comparator
->dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1573 for (j
= 0; j
< 3; j
++, reg
++)
1574 cortex_m3_dwt_addreg(target
, cache
->reg_list
+ reg
,
1575 dwt_comp
+ 3 * i
+ j
);
1578 *register_get_last_cache_p(&target
->reg_cache
) = cache
;
1579 cm3
->dwt_cache
= cache
;
1581 LOG_DEBUG("DWT dwtcr 0x%" PRIx32
", comp %d, watch%s",
1582 dwtcr
, cm3
->dwt_num_comp
,
1583 (dwtcr
& (0xf << 24)) ? " only" : "/trigger");
1585 /* REVISIT: if num_comp > 1, check whether comparator #1 can
1586 * implement single-address data value watchpoints ... so we
1587 * won't need to check it later, when asked to set one up.
1591 static int cortex_m3_examine(struct target_s
*target
)
1594 uint32_t cpuid
, fpcr
;
1596 struct cortex_m3_common_s
*cortex_m3
= target_to_cm3(target
);
1597 struct swjdp_common_s
*swjdp
= &cortex_m3
->armv7m
.swjdp_info
;
1599 if ((retval
= ahbap_debugport_init(swjdp
)) != ERROR_OK
)
1602 if (!target_was_examined(target
))
1604 target_set_examined(target
);
1606 /* Read from Device Identification Registers */
1607 retval
= target_read_u32(target
, CPUID
, &cpuid
);
1608 if (retval
!= ERROR_OK
)
1611 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1612 LOG_DEBUG("CORTEX-M3 processor detected");
1613 LOG_DEBUG("cpuid: 0x%8.8" PRIx32
"", cpuid
);
1615 /* NOTE: FPB and DWT are both optional. */
1618 target_read_u32(target
, FP_CTRL
, &fpcr
);
1619 cortex_m3
->auto_bp_type
= 1;
1620 cortex_m3
->fp_num_code
= ((fpcr
>> 8) & 0x70) | ((fpcr
>> 4) & 0xF); /* bits [14:12] and [7:4] */
1621 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1622 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1623 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(cortex_m3_fp_comparator_t
));
1624 cortex_m3
->fpb_enabled
= fpcr
& 1;
1625 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1627 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1628 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1630 LOG_DEBUG("FPB fpcr 0x%" PRIx32
", numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1633 cortex_m3_dwt_setup(cortex_m3
, target
);
1639 static int cortex_m3_dcc_read(swjdp_common_t
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1643 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1644 *ctrl
= (uint8_t)dcrdr
;
1645 *value
= (uint8_t)(dcrdr
>> 8);
1647 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1649 /* write ack back to software dcc register
1650 * signify we have read data */
1651 if (dcrdr
& (1 << 0))
1654 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1660 static int cortex_m3_target_request_data(target_t
*target
,
1661 uint32_t size
, uint8_t *buffer
)
1663 struct armv7m_common_s
*armv7m
= target_to_armv7m(target
);
1664 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1669 for (i
= 0; i
< (size
* 4); i
++)
1671 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1678 static int cortex_m3_handle_target_request(void *priv
)
1680 target_t
*target
= priv
;
1681 if (!target_was_examined(target
))
1683 struct armv7m_common_s
*armv7m
= target_to_armv7m(target
);
1684 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1686 if (!target
->dbg_msg_enabled
)
1689 if (target
->state
== TARGET_RUNNING
)
1694 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1696 /* check if we have data */
1697 if (ctrl
& (1 << 0))
1701 /* we assume target is quick enough */
1703 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1704 request
|= (data
<< 8);
1705 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1706 request
|= (data
<< 16);
1707 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1708 request
|= (data
<< 24);
1709 target_request(target
, request
);
1716 static int cortex_m3_init_arch_info(target_t
*target
,
1717 cortex_m3_common_t
*cortex_m3
, jtag_tap_t
*tap
)
1720 struct armv7m_common_s
*armv7m
= &cortex_m3
->armv7m
;
1722 armv7m_init_arch_info(target
, armv7m
);
1724 /* prepare JTAG information for the new target */
1725 cortex_m3
->jtag_info
.tap
= tap
;
1726 cortex_m3
->jtag_info
.scann_size
= 4;
1728 armv7m
->swjdp_info
.dp_select_value
= -1;
1729 armv7m
->swjdp_info
.ap_csw_value
= -1;
1730 armv7m
->swjdp_info
.ap_tar_value
= -1;
1731 armv7m
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1732 armv7m
->swjdp_info
.memaccess_tck
= 8;
1733 armv7m
->swjdp_info
.tar_autoincr_block
= (1 << 12); /* Cortex-M3 has 4096 bytes autoincrement range */
1735 /* register arch-specific functions */
1736 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1738 armv7m
->post_debug_entry
= NULL
;
1740 armv7m
->pre_restore_context
= NULL
;
1741 armv7m
->post_restore_context
= NULL
;
1743 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1744 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1746 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1748 if ((retval
= arm_jtag_setup_connection(&cortex_m3
->jtag_info
)) != ERROR_OK
)
1756 static int cortex_m3_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1758 cortex_m3_common_t
*cortex_m3
= calloc(1,sizeof(cortex_m3_common_t
));
1760 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1761 cortex_m3_init_arch_info(target
, cortex_m3
, target
->tap
);
1766 /*--------------------------------------------------------------------------*/
1768 static int cortex_m3_verify_pointer(struct command_context_s
*cmd_ctx
,
1769 struct cortex_m3_common_s
*cm3
)
1771 if (cm3
->common_magic
!= CORTEX_M3_COMMON_MAGIC
) {
1772 command_print(cmd_ctx
, "target is not a Cortex-M3");
1773 return ERROR_TARGET_INVALID
;
1779 * Only stuff below this line should need to verify that its target
1780 * is a Cortex-M3. Everything else should have indirected through the
1781 * cortexm3_target structure, which is only used with CM3 targets.
1785 * REVISIT Thumb2 disassembly should work for all ARMv7 cores, as well
1786 * as at least ARM-1156T2. The interesting thing about Cortex-M is
1787 * that *only* Thumb2 disassembly matters. There are also some small
1788 * additions to Thumb2 that are specific to ARMv7-M.
1791 handle_cortex_m3_disassemble_command(struct command_context_s
*cmd_ctx
,
1792 char *cmd
, char **args
, int argc
)
1795 target_t
*target
= get_current_target(cmd_ctx
);
1796 struct cortex_m3_common_s
*cortex_m3
= target_to_cm3(target
);
1798 unsigned long count
= 1;
1799 arm_instruction_t cur_instruction
;
1801 retval
= cortex_m3_verify_pointer(cmd_ctx
, cortex_m3
);
1802 if (retval
!= ERROR_OK
)
1808 COMMAND_PARSE_NUMBER(ulong
, args
[1], count
);
1811 COMMAND_PARSE_NUMBER(u32
, args
[0], address
);
1814 command_print(cmd_ctx
,
1815 "usage: cortex_m3 disassemble <address> [<count>]");
1820 retval
= thumb2_opcode(target
, address
, &cur_instruction
);
1821 if (retval
!= ERROR_OK
)
1823 command_print(cmd_ctx
, "%s", cur_instruction
.text
);
1824 address
+= cur_instruction
.instruction_size
;
1830 static const struct {
1834 { "hard_err", VC_HARDERR
, },
1835 { "int_err", VC_INTERR
, },
1836 { "bus_err", VC_BUSERR
, },
1837 { "state_err", VC_STATERR
, },
1838 { "chk_err", VC_CHKERR
, },
1839 { "nocp_err", VC_NOCPERR
, },
1840 { "mm_err", VC_MMERR
, },
1841 { "reset", VC_CORERESET
, },
1845 handle_cortex_m3_vector_catch_command(struct command_context_s
*cmd_ctx
,
1846 char *cmd
, char **argv
, int argc
)
1848 target_t
*target
= get_current_target(cmd_ctx
);
1849 struct cortex_m3_common_s
*cortex_m3
= target_to_cm3(target
);
1850 struct armv7m_common_s
*armv7m
= &cortex_m3
->armv7m
;
1851 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1856 retval
= cortex_m3_verify_pointer(cmd_ctx
, cortex_m3
);
1857 if (retval
!= ERROR_OK
)
1860 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &demcr
);
1866 if (strcmp(argv
[0], "all") == 0) {
1867 catch = VC_HARDERR
| VC_INTERR
| VC_BUSERR
1868 | VC_STATERR
| VC_CHKERR
| VC_NOCPERR
1869 | VC_MMERR
| VC_CORERESET
;
1871 } else if (strcmp(argv
[0], "none") == 0) {
1875 while (argc
-- > 0) {
1876 for (i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++) {
1877 if (strcmp(argv
[argc
], vec_ids
[i
].name
) != 0)
1879 catch |= vec_ids
[i
].mask
;
1882 if (i
== ARRAY_SIZE(vec_ids
)) {
1883 LOG_ERROR("No CM3 vector '%s'", argv
[argc
]);
1884 return ERROR_INVALID_ARGUMENTS
;
1891 /* write, but don't assume it stuck */
1892 mem_ap_write_u32(swjdp
, DCB_DEMCR
, demcr
);
1893 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &demcr
);
1896 for (i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++)
1897 command_print(cmd_ctx
, "%9s: %s", vec_ids
[i
].name
,
1898 (demcr
& vec_ids
[i
].mask
) ? "catch" : "ignore");
1904 handle_cortex_m3_mask_interrupts_command(struct command_context_s
*cmd_ctx
,
1905 char *cmd
, char **args
, int argc
)
1907 target_t
*target
= get_current_target(cmd_ctx
);
1908 struct cortex_m3_common_s
*cortex_m3
= target_to_cm3(target
);
1911 retval
= cortex_m3_verify_pointer(cmd_ctx
, cortex_m3
);
1912 if (retval
!= ERROR_OK
)
1915 if (target
->state
!= TARGET_HALTED
)
1917 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
1923 if (!strcmp(args
[0], "on"))
1925 cortex_m3_write_debug_halt_mask(target
, C_HALT
| C_MASKINTS
, 0);
1927 else if (!strcmp(args
[0], "off"))
1929 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_MASKINTS
);
1933 command_print(cmd_ctx
, "usage: cortex_m3 maskisr ['on'|'off']");
1937 command_print(cmd_ctx
, "cortex_m3 interrupt mask %s",
1938 (cortex_m3
->dcb_dhcsr
& C_MASKINTS
) ? "on" : "off");
1943 static int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
)
1946 command_t
*cortex_m3_cmd
;
1948 retval
= armv7m_register_commands(cmd_ctx
);
1950 cortex_m3_cmd
= register_command(cmd_ctx
, NULL
, "cortex_m3",
1951 NULL
, COMMAND_ANY
, "cortex_m3 specific commands");
1953 register_command(cmd_ctx
, cortex_m3_cmd
, "disassemble",
1954 handle_cortex_m3_disassemble_command
, COMMAND_EXEC
,
1955 "disassemble Thumb2 instructions <address> [<count>]");
1956 register_command(cmd_ctx
, cortex_m3_cmd
, "maskisr",
1957 handle_cortex_m3_mask_interrupts_command
, COMMAND_EXEC
,
1958 "mask cortex_m3 interrupts ['on'|'off']");
1959 register_command(cmd_ctx
, cortex_m3_cmd
, "vector_catch",
1960 handle_cortex_m3_vector_catch_command
, COMMAND_EXEC
,
1961 "catch hardware vectors ['all'|'none'|<list>]");
1966 target_type_t cortexm3_target
=
1968 .name
= "cortex_m3",
1970 .poll
= cortex_m3_poll
,
1971 .arch_state
= armv7m_arch_state
,
1973 .target_request_data
= cortex_m3_target_request_data
,
1975 .halt
= cortex_m3_halt
,
1976 .resume
= cortex_m3_resume
,
1977 .step
= cortex_m3_step
,
1979 .assert_reset
= cortex_m3_assert_reset
,
1980 .deassert_reset
= cortex_m3_deassert_reset
,
1981 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
1983 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
1985 .read_memory
= cortex_m3_read_memory
,
1986 .write_memory
= cortex_m3_write_memory
,
1987 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
1988 .checksum_memory
= armv7m_checksum_memory
,
1989 .blank_check_memory
= armv7m_blank_check_memory
,
1991 .run_algorithm
= armv7m_run_algorithm
,
1993 .add_breakpoint
= cortex_m3_add_breakpoint
,
1994 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
1995 .add_watchpoint
= cortex_m3_add_watchpoint
,
1996 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
1998 .register_commands
= cortex_m3_register_commands
,
1999 .target_create
= cortex_m3_target_create
,
2000 .init_target
= cortex_m3_init_target
,
2001 .has_mmu
= cortex_m3_has_mmu
,
2002 .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)