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 * Copyright (C) 2009 by Dirk Behme *
12 * dirk.behme@gmail.com - copy from cortex_m3 *
14 * Copyright (C) 2010 Øyvind Harboe *
15 * oyvind.harboe@zylin.com *
17 * This program is free software; you can redistribute it and/or modify *
18 * it under the terms of the GNU General Public License as published by *
19 * the Free Software Foundation; either version 2 of the License, or *
20 * (at your option) any later version. *
22 * This program is distributed in the hope that it will be useful, *
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
25 * GNU General Public License for more details. *
27 * You should have received a copy of the GNU General Public License *
28 * along with this program; if not, write to the *
29 * Free Software Foundation, Inc., *
30 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
32 * Cortex-A8(tm) TRM, ARM DDI 0344H *
34 ***************************************************************************/
39 #include "breakpoints.h"
40 #include "cortex_a8.h"
42 #include "target_request.h"
43 #include "target_type.h"
44 #include "arm_opcodes.h"
45 #include <helper/time_support.h>
47 static int cortex_a8_poll(struct target
*target
);
48 static int cortex_a8_debug_entry(struct target
*target
);
49 static int cortex_a8_restore_context(struct target
*target
, bool bpwp
);
50 static int cortex_a8_set_breakpoint(struct target
*target
,
51 struct breakpoint
*breakpoint
, uint8_t matchmode
);
52 static int cortex_a8_unset_breakpoint(struct target
*target
,
53 struct breakpoint
*breakpoint
);
54 static int cortex_a8_dap_read_coreregister_u32(struct target
*target
,
55 uint32_t *value
, int regnum
);
56 static int cortex_a8_dap_write_coreregister_u32(struct target
*target
,
57 uint32_t value
, int regnum
);
58 static int cortex_a8_mmu(struct target
*target
, int *enabled
);
59 static int cortex_a8_virt2phys(struct target
*target
,
60 uint32_t virt
, uint32_t *phys
);
61 static void cortex_a8_disable_mmu_caches(struct target
*target
, int mmu
,
62 int d_u_cache
, int i_cache
);
63 static void cortex_a8_enable_mmu_caches(struct target
*target
, int mmu
,
64 int d_u_cache
, int i_cache
);
65 static uint32_t cortex_a8_get_ttb(struct target
*target
);
69 * FIXME do topology discovery using the ROM; don't
70 * assume this is an OMAP3. Also, allow for multiple ARMv7-A
71 * cores, with different AP numbering ... don't use a #define
72 * for these numbers, use per-core armv7a state.
74 #define swjdp_memoryap 0
75 #define swjdp_debugap 1
76 #define OMAP3530_DEBUG_BASE 0x54011000
79 * Cortex-A8 Basic debug access, very low level assumes state is saved
81 static int cortex_a8_init_debug_access(struct target
*target
)
83 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
84 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
91 /* Unlocking the debug registers for modification */
92 /* The debugport might be uninitialised so try twice */
93 retval
= mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
94 if (retval
!= ERROR_OK
)
97 retval
= mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
98 if (retval
== ERROR_OK
)
100 LOG_USER("Locking debug access failed on first, but succeeded on second try.");
103 if (retval
!= ERROR_OK
)
105 /* Clear Sticky Power Down status Bit in PRSR to enable access to
106 the registers in the Core Power Domain */
107 retval
= mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_PRSR
, &dummy
);
108 if (retval
!= ERROR_OK
)
111 /* Enabling of instruction execution in debug mode is done in debug_entry code */
113 /* Resync breakpoint registers */
115 /* Since this is likely called from init or reset, update target state information*/
116 retval
= cortex_a8_poll(target
);
121 /* To reduce needless round-trips, pass in a pointer to the current
122 * DSCR value. Initialize it to zero if you just need to know the
123 * value on return from this function; or DSCR_INSTR_COMP if you
124 * happen to know that no instruction is pending.
126 static int cortex_a8_exec_opcode(struct target
*target
,
127 uint32_t opcode
, uint32_t *dscr_p
)
131 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
132 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
134 dscr
= dscr_p
? *dscr_p
: 0;
136 LOG_DEBUG("exec opcode 0x%08" PRIx32
, opcode
);
138 /* Wait for InstrCompl bit to be set */
139 while ((dscr
& DSCR_INSTR_COMP
) == 0)
141 retval
= mem_ap_read_atomic_u32(swjdp
,
142 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
143 if (retval
!= ERROR_OK
)
145 LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32
, opcode
);
150 retval
= mem_ap_write_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_ITR
, opcode
);
151 if (retval
!= ERROR_OK
)
156 retval
= mem_ap_read_atomic_u32(swjdp
,
157 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
158 if (retval
!= ERROR_OK
)
160 LOG_ERROR("Could not read DSCR register");
164 while ((dscr
& DSCR_INSTR_COMP
) == 0); /* Wait for InstrCompl bit to be set */
172 /**************************************************************************
173 Read core register with very few exec_opcode, fast but needs work_area.
174 This can cause problems with MMU active.
175 **************************************************************************/
176 static int cortex_a8_read_regs_through_mem(struct target
*target
, uint32_t address
,
179 int retval
= ERROR_OK
;
180 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
181 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
183 retval
= cortex_a8_dap_read_coreregister_u32(target
, regfile
, 0);
184 if (retval
!= ERROR_OK
)
186 retval
= cortex_a8_dap_write_coreregister_u32(target
, address
, 0);
187 if (retval
!= ERROR_OK
)
189 retval
= cortex_a8_exec_opcode(target
, ARMV4_5_STMIA(0, 0xFFFE, 0, 0), NULL
);
190 if (retval
!= ERROR_OK
)
193 dap_ap_select(swjdp
, swjdp_memoryap
);
194 retval
= mem_ap_read_buf_u32(swjdp
, (uint8_t *)(®file
[1]), 4*15, address
);
195 if (retval
!= ERROR_OK
)
197 dap_ap_select(swjdp
, swjdp_debugap
);
202 static int cortex_a8_dap_read_coreregister_u32(struct target
*target
,
203 uint32_t *value
, int regnum
)
205 int retval
= ERROR_OK
;
206 uint8_t reg
= regnum
&0xFF;
208 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
209 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
216 /* Rn to DCCTX, "MCR p14, 0, Rn, c0, c5, 0" 0xEE00nE15 */
217 retval
= cortex_a8_exec_opcode(target
,
218 ARMV4_5_MCR(14, 0, reg
, 0, 5, 0),
220 if (retval
!= ERROR_OK
)
225 /* "MOV r0, r15"; then move r0 to DCCTX */
226 retval
= cortex_a8_exec_opcode(target
, 0xE1A0000F, &dscr
);
227 if (retval
!= ERROR_OK
)
229 retval
= cortex_a8_exec_opcode(target
,
230 ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
232 if (retval
!= ERROR_OK
)
237 /* "MRS r0, CPSR" or "MRS r0, SPSR"
238 * then move r0 to DCCTX
240 retval
= cortex_a8_exec_opcode(target
, ARMV4_5_MRS(0, reg
& 1), &dscr
);
241 if (retval
!= ERROR_OK
)
243 retval
= cortex_a8_exec_opcode(target
,
244 ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
246 if (retval
!= ERROR_OK
)
250 /* Wait for DTRRXfull then read DTRRTX */
251 while ((dscr
& DSCR_DTR_TX_FULL
) == 0)
253 retval
= mem_ap_read_atomic_u32(swjdp
,
254 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
255 if (retval
!= ERROR_OK
)
259 retval
= mem_ap_read_atomic_u32(swjdp
,
260 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
261 LOG_DEBUG("read DCC 0x%08" PRIx32
, *value
);
266 static int cortex_a8_dap_write_coreregister_u32(struct target
*target
,
267 uint32_t value
, int regnum
)
269 int retval
= ERROR_OK
;
270 uint8_t Rd
= regnum
&0xFF;
272 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
273 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
275 LOG_DEBUG("register %i, value 0x%08" PRIx32
, regnum
, value
);
277 /* Check that DCCRX is not full */
278 retval
= mem_ap_read_atomic_u32(swjdp
,
279 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
280 if (retval
!= ERROR_OK
)
282 if (dscr
& DSCR_DTR_RX_FULL
)
284 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
285 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
286 retval
= cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
288 if (retval
!= ERROR_OK
)
295 /* Write DTRRX ... sets DSCR.DTRRXfull but exec_opcode() won't care */
296 LOG_DEBUG("write DCC 0x%08" PRIx32
, value
);
297 retval
= mem_ap_write_u32(swjdp
,
298 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
299 if (retval
!= ERROR_OK
)
304 /* DCCRX to Rn, "MCR p14, 0, Rn, c0, c5, 0", 0xEE00nE15 */
305 retval
= cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, Rd
, 0, 5, 0),
307 if (retval
!= ERROR_OK
)
312 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15
315 retval
= cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
317 if (retval
!= ERROR_OK
)
319 retval
= cortex_a8_exec_opcode(target
, 0xE1A0F000, &dscr
);
320 if (retval
!= ERROR_OK
)
325 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15
326 * then "MSR CPSR_cxsf, r0" or "MSR SPSR_cxsf, r0" (all fields)
328 retval
= cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
330 if (retval
!= ERROR_OK
)
332 retval
= cortex_a8_exec_opcode(target
, ARMV4_5_MSR_GP(0, 0xF, Rd
& 1),
334 if (retval
!= ERROR_OK
)
337 /* "Prefetch flush" after modifying execution status in CPSR */
340 retval
= cortex_a8_exec_opcode(target
,
341 ARMV4_5_MCR(15, 0, 0, 7, 5, 4),
343 if (retval
!= ERROR_OK
)
351 /* Write to memory mapped registers directly with no cache or mmu handling */
352 static int cortex_a8_dap_write_memap_register_u32(struct target
*target
, uint32_t address
, uint32_t value
)
355 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
356 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
358 retval
= mem_ap_write_atomic_u32(swjdp
, address
, value
);
364 * Cortex-A8 implementation of Debug Programmer's Model
366 * NOTE the invariant: these routines return with DSCR_INSTR_COMP set,
367 * so there's no need to poll for it before executing an instruction.
369 * NOTE that in several of these cases the "stall" mode might be useful.
370 * It'd let us queue a few operations together... prepare/finish might
371 * be the places to enable/disable that mode.
374 static inline struct cortex_a8_common
*dpm_to_a8(struct arm_dpm
*dpm
)
376 return container_of(dpm
, struct cortex_a8_common
, armv7a_common
.dpm
);
379 static int cortex_a8_write_dcc(struct cortex_a8_common
*a8
, uint32_t data
)
381 LOG_DEBUG("write DCC 0x%08" PRIx32
, data
);
382 return mem_ap_write_u32(&a8
->armv7a_common
.dap
,
383 a8
->armv7a_common
.debug_base
+ CPUDBG_DTRRX
, data
);
386 static int cortex_a8_read_dcc(struct cortex_a8_common
*a8
, uint32_t *data
,
389 struct adiv5_dap
*swjdp
= &a8
->armv7a_common
.dap
;
390 uint32_t dscr
= DSCR_INSTR_COMP
;
396 /* Wait for DTRRXfull */
397 while ((dscr
& DSCR_DTR_TX_FULL
) == 0) {
398 retval
= mem_ap_read_atomic_u32(swjdp
,
399 a8
->armv7a_common
.debug_base
+ CPUDBG_DSCR
,
401 if (retval
!= ERROR_OK
)
405 retval
= mem_ap_read_atomic_u32(swjdp
,
406 a8
->armv7a_common
.debug_base
+ CPUDBG_DTRTX
, data
);
407 if (retval
!= ERROR_OK
)
409 //LOG_DEBUG("read DCC 0x%08" PRIx32, *data);
417 static int cortex_a8_dpm_prepare(struct arm_dpm
*dpm
)
419 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
420 struct adiv5_dap
*swjdp
= &a8
->armv7a_common
.dap
;
424 /* set up invariant: INSTR_COMP is set after ever DPM operation */
425 long long then
= timeval_ms();
428 retval
= mem_ap_read_atomic_u32(swjdp
,
429 a8
->armv7a_common
.debug_base
+ CPUDBG_DSCR
,
431 if (retval
!= ERROR_OK
)
433 if ((dscr
& DSCR_INSTR_COMP
) != 0)
435 if (timeval_ms() > then
+ 1000)
437 LOG_ERROR("Timeout waiting for dpm prepare");
442 /* this "should never happen" ... */
443 if (dscr
& DSCR_DTR_RX_FULL
) {
444 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
446 retval
= cortex_a8_exec_opcode(
447 a8
->armv7a_common
.armv4_5_common
.target
,
448 ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
450 if (retval
!= ERROR_OK
)
457 static int cortex_a8_dpm_finish(struct arm_dpm
*dpm
)
459 /* REVISIT what could be done here? */
463 static int cortex_a8_instr_write_data_dcc(struct arm_dpm
*dpm
,
464 uint32_t opcode
, uint32_t data
)
466 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
468 uint32_t dscr
= DSCR_INSTR_COMP
;
470 retval
= cortex_a8_write_dcc(a8
, data
);
471 if (retval
!= ERROR_OK
)
474 return cortex_a8_exec_opcode(
475 a8
->armv7a_common
.armv4_5_common
.target
,
480 static int cortex_a8_instr_write_data_r0(struct arm_dpm
*dpm
,
481 uint32_t opcode
, uint32_t data
)
483 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
484 uint32_t dscr
= DSCR_INSTR_COMP
;
487 retval
= cortex_a8_write_dcc(a8
, data
);
488 if (retval
!= ERROR_OK
)
491 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15 */
492 retval
= cortex_a8_exec_opcode(
493 a8
->armv7a_common
.armv4_5_common
.target
,
494 ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
496 if (retval
!= ERROR_OK
)
499 /* then the opcode, taking data from R0 */
500 retval
= cortex_a8_exec_opcode(
501 a8
->armv7a_common
.armv4_5_common
.target
,
508 static int cortex_a8_instr_cpsr_sync(struct arm_dpm
*dpm
)
510 struct target
*target
= dpm
->arm
->target
;
511 uint32_t dscr
= DSCR_INSTR_COMP
;
513 /* "Prefetch flush" after modifying execution status in CPSR */
514 return cortex_a8_exec_opcode(target
,
515 ARMV4_5_MCR(15, 0, 0, 7, 5, 4),
519 static int cortex_a8_instr_read_data_dcc(struct arm_dpm
*dpm
,
520 uint32_t opcode
, uint32_t *data
)
522 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
524 uint32_t dscr
= DSCR_INSTR_COMP
;
526 /* the opcode, writing data to DCC */
527 retval
= cortex_a8_exec_opcode(
528 a8
->armv7a_common
.armv4_5_common
.target
,
531 if (retval
!= ERROR_OK
)
534 return cortex_a8_read_dcc(a8
, data
, &dscr
);
538 static int cortex_a8_instr_read_data_r0(struct arm_dpm
*dpm
,
539 uint32_t opcode
, uint32_t *data
)
541 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
542 uint32_t dscr
= DSCR_INSTR_COMP
;
545 /* the opcode, writing data to R0 */
546 retval
= cortex_a8_exec_opcode(
547 a8
->armv7a_common
.armv4_5_common
.target
,
550 if (retval
!= ERROR_OK
)
553 /* write R0 to DCC */
554 retval
= cortex_a8_exec_opcode(
555 a8
->armv7a_common
.armv4_5_common
.target
,
556 ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
558 if (retval
!= ERROR_OK
)
561 return cortex_a8_read_dcc(a8
, data
, &dscr
);
564 static int cortex_a8_bpwp_enable(struct arm_dpm
*dpm
, unsigned index_t
,
565 uint32_t addr
, uint32_t control
)
567 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
568 uint32_t vr
= a8
->armv7a_common
.debug_base
;
569 uint32_t cr
= a8
->armv7a_common
.debug_base
;
573 case 0 ... 15: /* breakpoints */
574 vr
+= CPUDBG_BVR_BASE
;
575 cr
+= CPUDBG_BCR_BASE
;
577 case 16 ... 31: /* watchpoints */
578 vr
+= CPUDBG_WVR_BASE
;
579 cr
+= CPUDBG_WCR_BASE
;
588 LOG_DEBUG("A8: bpwp enable, vr %08x cr %08x",
589 (unsigned) vr
, (unsigned) cr
);
591 retval
= cortex_a8_dap_write_memap_register_u32(dpm
->arm
->target
,
593 if (retval
!= ERROR_OK
)
595 retval
= cortex_a8_dap_write_memap_register_u32(dpm
->arm
->target
,
600 static int cortex_a8_bpwp_disable(struct arm_dpm
*dpm
, unsigned index_t
)
602 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
607 cr
= a8
->armv7a_common
.debug_base
+ CPUDBG_BCR_BASE
;
610 cr
= a8
->armv7a_common
.debug_base
+ CPUDBG_WCR_BASE
;
618 LOG_DEBUG("A8: bpwp disable, cr %08x", (unsigned) cr
);
620 /* clear control register */
621 return cortex_a8_dap_write_memap_register_u32(dpm
->arm
->target
, cr
, 0);
624 static int cortex_a8_dpm_setup(struct cortex_a8_common
*a8
, uint32_t didr
)
626 struct arm_dpm
*dpm
= &a8
->armv7a_common
.dpm
;
629 dpm
->arm
= &a8
->armv7a_common
.armv4_5_common
;
632 dpm
->prepare
= cortex_a8_dpm_prepare
;
633 dpm
->finish
= cortex_a8_dpm_finish
;
635 dpm
->instr_write_data_dcc
= cortex_a8_instr_write_data_dcc
;
636 dpm
->instr_write_data_r0
= cortex_a8_instr_write_data_r0
;
637 dpm
->instr_cpsr_sync
= cortex_a8_instr_cpsr_sync
;
639 dpm
->instr_read_data_dcc
= cortex_a8_instr_read_data_dcc
;
640 dpm
->instr_read_data_r0
= cortex_a8_instr_read_data_r0
;
642 dpm
->bpwp_enable
= cortex_a8_bpwp_enable
;
643 dpm
->bpwp_disable
= cortex_a8_bpwp_disable
;
645 retval
= arm_dpm_setup(dpm
);
646 if (retval
== ERROR_OK
)
647 retval
= arm_dpm_initialize(dpm
);
654 * Cortex-A8 Run control
657 static int cortex_a8_poll(struct target
*target
)
659 int retval
= ERROR_OK
;
661 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
662 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
663 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
664 enum target_state prev_target_state
= target
->state
;
665 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
667 dap_ap_select(swjdp
, swjdp_debugap
);
668 retval
= mem_ap_read_atomic_u32(swjdp
,
669 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
670 if (retval
!= ERROR_OK
)
672 dap_ap_select(swjdp
, saved_apsel
);
675 cortex_a8
->cpudbg_dscr
= dscr
;
677 if ((dscr
& 0x3) == 0x3)
679 if (prev_target_state
!= TARGET_HALTED
)
681 /* We have a halting debug event */
682 LOG_DEBUG("Target halted");
683 target
->state
= TARGET_HALTED
;
684 if ((prev_target_state
== TARGET_RUNNING
)
685 || (prev_target_state
== TARGET_RESET
))
687 retval
= cortex_a8_debug_entry(target
);
688 if (retval
!= ERROR_OK
)
691 target_call_event_callbacks(target
,
692 TARGET_EVENT_HALTED
);
694 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
698 retval
= cortex_a8_debug_entry(target
);
699 if (retval
!= ERROR_OK
)
702 target_call_event_callbacks(target
,
703 TARGET_EVENT_DEBUG_HALTED
);
707 else if ((dscr
& 0x3) == 0x2)
709 target
->state
= TARGET_RUNNING
;
713 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32
, dscr
);
714 target
->state
= TARGET_UNKNOWN
;
717 dap_ap_select(swjdp
, saved_apsel
);
722 static int cortex_a8_halt(struct target
*target
)
724 int retval
= ERROR_OK
;
726 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
727 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
728 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
729 dap_ap_select(swjdp
, swjdp_debugap
);
732 * Tell the core to be halted by writing DRCR with 0x1
733 * and then wait for the core to be halted.
735 retval
= mem_ap_write_atomic_u32(swjdp
,
736 armv7a
->debug_base
+ CPUDBG_DRCR
, 0x1);
737 if (retval
!= ERROR_OK
)
741 * enter halting debug mode
743 retval
= mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
744 if (retval
!= ERROR_OK
)
747 retval
= mem_ap_write_atomic_u32(swjdp
,
748 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
| DSCR_HALT_DBG_MODE
);
749 if (retval
!= ERROR_OK
)
752 long long then
= timeval_ms();
755 retval
= mem_ap_read_atomic_u32(swjdp
,
756 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
757 if (retval
!= ERROR_OK
)
759 if ((dscr
& DSCR_CORE_HALTED
) != 0)
763 if (timeval_ms() > then
+ 1000)
765 LOG_ERROR("Timeout waiting for halt");
770 target
->debug_reason
= DBG_REASON_DBGRQ
;
773 dap_ap_select(swjdp
, saved_apsel
);
777 static int cortex_a8_resume(struct target
*target
, int current
,
778 uint32_t address
, int handle_breakpoints
, int debug_execution
)
780 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
781 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
782 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
785 // struct breakpoint *breakpoint = NULL;
786 uint32_t resume_pc
, dscr
;
788 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
789 dap_ap_select(swjdp
, swjdp_debugap
);
791 if (!debug_execution
)
792 target_free_all_working_areas(target
);
797 /* Disable interrupts */
798 /* We disable interrupts in the PRIMASK register instead of
799 * masking with C_MASKINTS,
800 * This is probably the same issue as Cortex-M3 Errata 377493:
801 * C_MASKINTS in parallel with disabled interrupts can cause
802 * local faults to not be taken. */
803 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
804 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
805 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
807 /* Make sure we are in Thumb mode */
808 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
809 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
810 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
811 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
815 /* current = 1: continue on current pc, otherwise continue at <address> */
816 resume_pc
= buf_get_u32(armv4_5
->pc
->value
, 0, 32);
820 /* Make sure that the Armv7 gdb thumb fixups does not
821 * kill the return address
823 switch (armv4_5
->core_state
)
826 resume_pc
&= 0xFFFFFFFC;
828 case ARM_STATE_THUMB
:
829 case ARM_STATE_THUMB_EE
:
830 /* When the return address is loaded into PC
831 * bit 0 must be 1 to stay in Thumb state
835 case ARM_STATE_JAZELLE
:
836 LOG_ERROR("How do I resume into Jazelle state??");
839 LOG_DEBUG("resume pc = 0x%08" PRIx32
, resume_pc
);
840 buf_set_u32(armv4_5
->pc
->value
, 0, 32, resume_pc
);
841 armv4_5
->pc
->dirty
= 1;
842 armv4_5
->pc
->valid
= 1;
844 retval
= cortex_a8_restore_context(target
, handle_breakpoints
);
845 if (retval
!= ERROR_OK
)
849 /* the front-end may request us not to handle breakpoints */
850 if (handle_breakpoints
)
852 /* Single step past breakpoint at current address */
853 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
855 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
856 cortex_m3_unset_breakpoint(target
, breakpoint
);
857 cortex_m3_single_step_core(target
);
858 cortex_m3_set_breakpoint(target
, breakpoint
);
863 /* Restart core and wait for it to be started
864 * NOTE: this clears DSCR_ITR_EN and other bits.
866 * REVISIT: for single stepping, we probably want to
867 * disable IRQs by default, with optional override...
869 retval
= mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DRCR
, 0x2);
870 if (retval
!= ERROR_OK
)
873 long long then
= timeval_ms();
876 retval
= mem_ap_read_atomic_u32(swjdp
,
877 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
878 if (retval
!= ERROR_OK
)
880 if ((dscr
& DSCR_CORE_RESTARTED
) != 0)
882 if (timeval_ms() > then
+ 1000)
884 LOG_ERROR("Timeout waiting for resume");
889 target
->debug_reason
= DBG_REASON_NOTHALTED
;
890 target
->state
= TARGET_RUNNING
;
892 /* registers are now invalid */
893 register_cache_invalidate(armv4_5
->core_cache
);
895 if (!debug_execution
)
897 target
->state
= TARGET_RUNNING
;
898 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
899 LOG_DEBUG("target resumed at 0x%" PRIx32
, resume_pc
);
903 target
->state
= TARGET_DEBUG_RUNNING
;
904 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
905 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, resume_pc
);
908 dap_ap_select(swjdp
, saved_apsel
);
913 static int cortex_a8_debug_entry(struct target
*target
)
916 uint32_t regfile
[16], cpsr
, dscr
;
917 int retval
= ERROR_OK
;
918 struct working_area
*regfile_working_area
= NULL
;
919 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
920 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
921 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
922 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
925 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
927 /* REVISIT surely we should not re-read DSCR !! */
928 retval
= mem_ap_read_atomic_u32(swjdp
,
929 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
930 if (retval
!= ERROR_OK
)
933 /* REVISIT see A8 TRM 12.11.4 steps 2..3 -- make sure that any
934 * imprecise data aborts get discarded by issuing a Data
935 * Synchronization Barrier: ARMV4_5_MCR(15, 0, 0, 7, 10, 4).
938 /* Enable the ITR execution once we are in debug mode */
940 retval
= mem_ap_write_atomic_u32(swjdp
,
941 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
);
942 if (retval
!= ERROR_OK
)
945 /* Examine debug reason */
946 arm_dpm_report_dscr(&armv7a
->dpm
, cortex_a8
->cpudbg_dscr
);
948 /* save address of instruction that triggered the watchpoint? */
949 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
) {
952 retval
= mem_ap_read_atomic_u32(swjdp
,
953 armv7a
->debug_base
+ CPUDBG_WFAR
,
955 if (retval
!= ERROR_OK
)
957 arm_dpm_report_wfar(&armv7a
->dpm
, wfar
);
960 /* REVISIT fast_reg_read is never set ... */
962 /* Examine target state and mode */
963 if (cortex_a8
->fast_reg_read
)
964 target_alloc_working_area(target
, 64, ®file_working_area
);
966 /* First load register acessible through core debug port*/
967 if (!regfile_working_area
)
969 retval
= arm_dpm_read_current_registers(&armv7a
->dpm
);
973 dap_ap_select(swjdp
, swjdp_memoryap
);
974 retval
= cortex_a8_read_regs_through_mem(target
,
975 regfile_working_area
->address
, regfile
);
976 dap_ap_select(swjdp
, swjdp_memoryap
);
977 target_free_working_area(target
, regfile_working_area
);
978 if (retval
!= ERROR_OK
)
983 /* read Current PSR */
984 retval
= cortex_a8_dap_read_coreregister_u32(target
, &cpsr
, 16);
985 if (retval
!= ERROR_OK
)
987 dap_ap_select(swjdp
, swjdp_debugap
);
988 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
990 arm_set_cpsr(armv4_5
, cpsr
);
993 for (i
= 0; i
<= ARM_PC
; i
++)
995 reg
= arm_reg_current(armv4_5
, i
);
997 buf_set_u32(reg
->value
, 0, 32, regfile
[i
]);
1002 /* Fixup PC Resume Address */
1003 if (cpsr
& (1 << 5))
1005 // T bit set for Thumb or ThumbEE state
1006 regfile
[ARM_PC
] -= 4;
1011 regfile
[ARM_PC
] -= 8;
1015 buf_set_u32(reg
->value
, 0, 32, regfile
[ARM_PC
]);
1016 reg
->dirty
= reg
->valid
;
1020 /* TODO, Move this */
1021 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
1022 cortex_a8_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
1023 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
1025 cortex_a8_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
1026 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
1028 cortex_a8_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
1029 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
1032 /* Are we in an exception handler */
1033 // armv4_5->exception_number = 0;
1034 if (armv7a
->post_debug_entry
)
1035 armv7a
->post_debug_entry(target
);
1040 static void cortex_a8_post_debug_entry(struct target
*target
)
1042 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1043 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1046 /* MRC p15,0,<Rt>,c1,c0,0 ; Read CP15 System Control Register */
1047 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
1048 0, 0, /* op1, op2 */
1049 1, 0, /* CRn, CRm */
1050 &cortex_a8
->cp15_control_reg
);
1051 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
1053 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
1055 uint32_t cache_type_reg
;
1057 /* MRC p15,0,<Rt>,c0,c0,1 ; Read CP15 Cache Type Register */
1058 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
1059 0, 1, /* op1, op2 */
1060 0, 0, /* CRn, CRm */
1062 LOG_DEBUG("cp15 cache type: %8.8x", (unsigned) cache_type_reg
);
1064 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
1065 armv4_5_identify_cache(cache_type_reg
,
1066 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1069 armv7a
->armv4_5_mmu
.mmu_enabled
=
1070 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
1071 armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
=
1072 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
1073 armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
=
1074 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
1079 static int cortex_a8_step(struct target
*target
, int current
, uint32_t address
,
1080 int handle_breakpoints
)
1082 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1083 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
1084 struct breakpoint
*breakpoint
= NULL
;
1085 struct breakpoint stepbreakpoint
;
1091 if (target
->state
!= TARGET_HALTED
)
1093 LOG_WARNING("target not halted");
1094 return ERROR_TARGET_NOT_HALTED
;
1097 /* current = 1: continue on current pc, otherwise continue at <address> */
1101 buf_set_u32(r
->value
, 0, 32, address
);
1105 address
= buf_get_u32(r
->value
, 0, 32);
1108 /* The front-end may request us not to handle breakpoints.
1109 * But since Cortex-A8 uses breakpoint for single step,
1110 * we MUST handle breakpoints.
1112 handle_breakpoints
= 1;
1113 if (handle_breakpoints
) {
1114 breakpoint
= breakpoint_find(target
, address
);
1116 cortex_a8_unset_breakpoint(target
, breakpoint
);
1119 /* Setup single step breakpoint */
1120 stepbreakpoint
.address
= address
;
1121 stepbreakpoint
.length
= (armv4_5
->core_state
== ARM_STATE_THUMB
)
1123 stepbreakpoint
.type
= BKPT_HARD
;
1124 stepbreakpoint
.set
= 0;
1126 /* Break on IVA mismatch */
1127 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
1129 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1131 retval
= cortex_a8_resume(target
, 1, address
, 0, 0);
1132 if (retval
!= ERROR_OK
)
1135 while (target
->state
!= TARGET_HALTED
)
1137 retval
= cortex_a8_poll(target
);
1138 if (retval
!= ERROR_OK
)
1142 LOG_ERROR("timeout waiting for target halt");
1147 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
1149 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1152 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
1154 if (target
->state
!= TARGET_HALTED
)
1155 LOG_DEBUG("target stepped");
1160 static int cortex_a8_restore_context(struct target
*target
, bool bpwp
)
1162 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1166 if (armv7a
->pre_restore_context
)
1167 armv7a
->pre_restore_context(target
);
1169 return arm_dpm_write_dirty_registers(&armv7a
->dpm
, bpwp
);
1174 * Cortex-A8 Breakpoint and watchpoint functions
1177 /* Setup hardware Breakpoint Register Pair */
1178 static int cortex_a8_set_breakpoint(struct target
*target
,
1179 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1184 uint8_t byte_addr_select
= 0x0F;
1185 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1186 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1187 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1189 if (breakpoint
->set
)
1191 LOG_WARNING("breakpoint already set");
1195 if (breakpoint
->type
== BKPT_HARD
)
1197 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
1199 if (brp_i
>= cortex_a8
->brp_num
)
1201 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1204 breakpoint
->set
= brp_i
+ 1;
1205 if (breakpoint
->length
== 2)
1207 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1209 control
= ((matchmode
& 0x7) << 20)
1210 | (byte_addr_select
<< 5)
1212 brp_list
[brp_i
].used
= 1;
1213 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1214 brp_list
[brp_i
].control
= control
;
1215 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1216 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1217 brp_list
[brp_i
].value
);
1218 if (retval
!= ERROR_OK
)
1220 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1221 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1222 brp_list
[brp_i
].control
);
1223 if (retval
!= ERROR_OK
)
1225 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1226 brp_list
[brp_i
].control
,
1227 brp_list
[brp_i
].value
);
1229 else if (breakpoint
->type
== BKPT_SOFT
)
1232 if (breakpoint
->length
== 2)
1234 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1238 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1240 retval
= target
->type
->read_memory(target
,
1241 breakpoint
->address
& 0xFFFFFFFE,
1242 breakpoint
->length
, 1,
1243 breakpoint
->orig_instr
);
1244 if (retval
!= ERROR_OK
)
1246 retval
= target
->type
->write_memory(target
,
1247 breakpoint
->address
& 0xFFFFFFFE,
1248 breakpoint
->length
, 1, code
);
1249 if (retval
!= ERROR_OK
)
1251 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1257 static int cortex_a8_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1260 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1261 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1262 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1264 if (!breakpoint
->set
)
1266 LOG_WARNING("breakpoint not set");
1270 if (breakpoint
->type
== BKPT_HARD
)
1272 int brp_i
= breakpoint
->set
- 1;
1273 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1275 LOG_DEBUG("Invalid BRP number in breakpoint");
1278 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1279 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1280 brp_list
[brp_i
].used
= 0;
1281 brp_list
[brp_i
].value
= 0;
1282 brp_list
[brp_i
].control
= 0;
1283 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1284 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1285 brp_list
[brp_i
].control
);
1286 if (retval
!= ERROR_OK
)
1288 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1289 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1290 brp_list
[brp_i
].value
);
1291 if (retval
!= ERROR_OK
)
1296 /* restore original instruction (kept in target endianness) */
1297 if (breakpoint
->length
== 4)
1299 retval
= target
->type
->write_memory(target
,
1300 breakpoint
->address
& 0xFFFFFFFE,
1301 4, 1, breakpoint
->orig_instr
);
1302 if (retval
!= ERROR_OK
)
1307 retval
= target
->type
->write_memory(target
,
1308 breakpoint
->address
& 0xFFFFFFFE,
1309 2, 1, breakpoint
->orig_instr
);
1310 if (retval
!= ERROR_OK
)
1314 breakpoint
->set
= 0;
1319 static int cortex_a8_add_breakpoint(struct target
*target
,
1320 struct breakpoint
*breakpoint
)
1322 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1324 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1326 LOG_INFO("no hardware breakpoint available");
1327 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1330 if (breakpoint
->type
== BKPT_HARD
)
1331 cortex_a8
->brp_num_available
--;
1332 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1337 static int cortex_a8_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1339 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1342 /* It is perfectly possible to remove breakpoints while the target is running */
1343 if (target
->state
!= TARGET_HALTED
)
1345 LOG_WARNING("target not halted");
1346 return ERROR_TARGET_NOT_HALTED
;
1350 if (breakpoint
->set
)
1352 cortex_a8_unset_breakpoint(target
, breakpoint
);
1353 if (breakpoint
->type
== BKPT_HARD
)
1354 cortex_a8
->brp_num_available
++ ;
1364 * Cortex-A8 Reset functions
1367 static int cortex_a8_assert_reset(struct target
*target
)
1369 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1373 /* FIXME when halt is requested, make it work somehow... */
1375 /* Issue some kind of warm reset. */
1376 if (target_has_event_action(target
, TARGET_EVENT_RESET_ASSERT
)) {
1377 target_handle_event(target
, TARGET_EVENT_RESET_ASSERT
);
1378 } else if (jtag_get_reset_config() & RESET_HAS_SRST
) {
1379 /* REVISIT handle "pulls" cases, if there's
1380 * hardware that needs them to work.
1382 jtag_add_reset(0, 1);
1384 LOG_ERROR("%s: how to reset?", target_name(target
));
1388 /* registers are now invalid */
1389 register_cache_invalidate(armv7a
->armv4_5_common
.core_cache
);
1391 target
->state
= TARGET_RESET
;
1396 static int cortex_a8_deassert_reset(struct target
*target
)
1402 /* be certain SRST is off */
1403 jtag_add_reset(0, 0);
1405 retval
= cortex_a8_poll(target
);
1406 if (retval
!= ERROR_OK
)
1409 if (target
->reset_halt
) {
1410 if (target
->state
!= TARGET_HALTED
) {
1411 LOG_WARNING("%s: ran after reset and before halt ...",
1412 target_name(target
));
1413 if ((retval
= target_halt(target
)) != ERROR_OK
)
1422 * Cortex-A8 Memory access
1424 * This is same Cortex M3 but we must also use the correct
1425 * ap number for every access.
1428 static int cortex_a8_read_phys_memory(struct target
*target
,
1429 uint32_t address
, uint32_t size
,
1430 uint32_t count
, uint8_t *buffer
)
1432 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1433 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
1434 int retval
= ERROR_INVALID_ARGUMENTS
;
1436 /* cortex_a8 handles unaligned memory access */
1438 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1439 LOG_DEBUG("Reading memory at real address 0x%x; size %d; count %d", address
, size
, count
);
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_a8_read_memory(struct target
*target
, uint32_t address
,
1458 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1461 uint32_t virt
, phys
;
1464 /* cortex_a8 handles unaligned memory access */
1466 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1467 LOG_DEBUG("Reading memory at address 0x%x; size %d; count %d", address
, size
, count
);
1468 retval
= cortex_a8_mmu(target
, &enabled
);
1469 if (retval
!= ERROR_OK
)
1475 retval
= cortex_a8_virt2phys(target
, virt
, &phys
);
1476 if (retval
!= ERROR_OK
)
1479 LOG_DEBUG("Reading at virtual address. Translating v:0x%x to r:0x%x", virt
, phys
);
1483 return cortex_a8_read_phys_memory(target
, address
, size
, count
, buffer
);
1486 static int cortex_a8_write_phys_memory(struct target
*target
,
1487 uint32_t address
, uint32_t size
,
1488 uint32_t count
, uint8_t *buffer
)
1490 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1491 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
1492 int retval
= ERROR_INVALID_ARGUMENTS
;
1494 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1496 LOG_DEBUG("Writing memory to real address 0x%x; size %d; count %d", address
, size
, count
);
1497 if (count
&& buffer
) {
1500 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1503 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1506 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1511 /* REVISIT this op is generic ARMv7-A/R stuff */
1512 if (retval
== ERROR_OK
&& target
->state
== TARGET_HALTED
)
1514 struct arm_dpm
*dpm
= armv7a
->armv4_5_common
.dpm
;
1516 retval
= dpm
->prepare(dpm
);
1517 if (retval
!= ERROR_OK
)
1520 /* The Cache handling will NOT work with MMU active, the
1521 * wrong addresses will be invalidated!
1523 * For both ICache and DCache, walk all cache lines in the
1524 * address range. Cortex-A8 has fixed 64 byte line length.
1526 * REVISIT per ARMv7, these may trigger watchpoints ...
1529 /* invalidate I-Cache */
1530 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
1532 /* ICIMVAU - Invalidate Cache single entry
1534 * MCR p15, 0, r0, c7, c5, 1
1536 for (uint32_t cacheline
= address
;
1537 cacheline
< address
+ size
* count
;
1539 retval
= dpm
->instr_write_data_r0(dpm
,
1540 ARMV4_5_MCR(15, 0, 0, 7, 5, 1),
1542 if (retval
!= ERROR_OK
)
1547 /* invalidate D-Cache */
1548 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
1550 /* DCIMVAC - Invalidate data Cache line
1552 * MCR p15, 0, r0, c7, c6, 1
1554 for (uint32_t cacheline
= address
;
1555 cacheline
< address
+ size
* count
;
1557 retval
= dpm
->instr_write_data_r0(dpm
,
1558 ARMV4_5_MCR(15, 0, 0, 7, 6, 1),
1560 if (retval
!= ERROR_OK
)
1565 /* (void) */ dpm
->finish(dpm
);
1571 static int cortex_a8_write_memory(struct target
*target
, uint32_t address
,
1572 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1575 uint32_t virt
, phys
;
1578 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1580 LOG_DEBUG("Writing memory to address 0x%x; size %d; count %d", address
, size
, count
);
1581 retval
= cortex_a8_mmu(target
, &enabled
);
1582 if (retval
!= ERROR_OK
)
1587 retval
= cortex_a8_virt2phys(target
, virt
, &phys
);
1588 if (retval
!= ERROR_OK
)
1590 LOG_DEBUG("Writing to virtual address. Translating v:0x%x to r:0x%x", virt
, phys
);
1594 return cortex_a8_write_phys_memory(target
, address
, size
,
1598 static int cortex_a8_bulk_write_memory(struct target
*target
, uint32_t address
,
1599 uint32_t count
, uint8_t *buffer
)
1601 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1605 static int cortex_a8_dcc_read(struct adiv5_dap
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1610 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1611 *ctrl
= (uint8_t)dcrdr
;
1612 *value
= (uint8_t)(dcrdr
>> 8);
1614 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1616 /* write ack back to software dcc register
1617 * signify we have read data */
1618 if (dcrdr
& (1 << 0))
1621 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1628 static int cortex_a8_handle_target_request(void *priv
)
1630 struct target
*target
= priv
;
1631 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1632 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
1635 if (!target_was_examined(target
))
1637 if (!target
->dbg_msg_enabled
)
1640 if (target
->state
== TARGET_RUNNING
)
1645 retval
= cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1646 if (retval
!= ERROR_OK
)
1649 /* check if we have data */
1650 if (ctrl
& (1 << 0))
1654 /* we assume target is quick enough */
1656 retval
= cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1657 if (retval
!= ERROR_OK
)
1659 request
|= (data
<< 8);
1660 retval
= cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1661 if (retval
!= ERROR_OK
)
1663 request
|= (data
<< 16);
1664 retval
= cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1665 if (retval
!= ERROR_OK
)
1667 request
|= (data
<< 24);
1668 target_request(target
, request
);
1676 * Cortex-A8 target information and configuration
1679 static int cortex_a8_examine_first(struct target
*target
)
1681 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1682 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1683 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
1685 int retval
= ERROR_OK
;
1686 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1688 /* stop assuming this is an OMAP! */
1689 LOG_DEBUG("TODO - autoconfigure");
1691 /* Here we shall insert a proper ROM Table scan */
1692 armv7a
->debug_base
= OMAP3530_DEBUG_BASE
;
1694 /* We do one extra read to ensure DAP is configured,
1695 * we call ahbap_debugport_init(swjdp) instead
1697 retval
= ahbap_debugport_init(swjdp
);
1698 if (retval
!= ERROR_OK
)
1701 retval
= mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
1702 if (retval
!= ERROR_OK
)
1705 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1706 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1708 LOG_DEBUG("Examine %s failed", "CPUID");
1712 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1713 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1715 LOG_DEBUG("Examine %s failed", "CTYPR");
1719 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1720 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1722 LOG_DEBUG("Examine %s failed", "TTYPR");
1726 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1727 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1729 LOG_DEBUG("Examine %s failed", "DIDR");
1733 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1734 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1735 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1736 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1738 armv7a
->armv4_5_common
.core_type
= ARM_MODE_MON
;
1739 retval
= cortex_a8_dpm_setup(cortex_a8
, didr
);
1740 if (retval
!= ERROR_OK
)
1743 /* Setup Breakpoint Register Pairs */
1744 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1745 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1746 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1747 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(struct cortex_a8_brp
));
1748 // cortex_a8->brb_enabled = ????;
1749 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1751 cortex_a8
->brp_list
[i
].used
= 0;
1752 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1753 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1755 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1756 cortex_a8
->brp_list
[i
].value
= 0;
1757 cortex_a8
->brp_list
[i
].control
= 0;
1758 cortex_a8
->brp_list
[i
].BRPn
= i
;
1761 LOG_DEBUG("Configured %i hw breakpoints", cortex_a8
->brp_num
);
1763 target_set_examined(target
);
1767 static int cortex_a8_examine(struct target
*target
)
1769 int retval
= ERROR_OK
;
1771 /* don't re-probe hardware after each reset */
1772 if (!target_was_examined(target
))
1773 retval
= cortex_a8_examine_first(target
);
1775 /* Configure core debug access */
1776 if (retval
== ERROR_OK
)
1777 retval
= cortex_a8_init_debug_access(target
);
1783 * Cortex-A8 target creation and initialization
1786 static int cortex_a8_init_target(struct command_context
*cmd_ctx
,
1787 struct target
*target
)
1789 /* examine_first() does a bunch of this */
1793 static int cortex_a8_init_arch_info(struct target
*target
,
1794 struct cortex_a8_common
*cortex_a8
, struct jtag_tap
*tap
)
1796 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1797 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
1798 struct adiv5_dap
*dap
= &armv7a
->dap
;
1800 armv7a
->armv4_5_common
.dap
= dap
;
1802 /* Setup struct cortex_a8_common */
1803 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1804 armv4_5
->arch_info
= armv7a
;
1806 /* prepare JTAG information for the new target */
1807 cortex_a8
->jtag_info
.tap
= tap
;
1808 cortex_a8
->jtag_info
.scann_size
= 4;
1810 /* Leave (only) generic DAP stuff for debugport_init() */
1811 dap
->jtag_info
= &cortex_a8
->jtag_info
;
1812 dap
->memaccess_tck
= 80;
1814 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1815 dap
->tar_autoincr_block
= (1 << 10);
1817 cortex_a8
->fast_reg_read
= 0;
1819 /* Set default value */
1820 cortex_a8
->current_address_mode
= ARM_MODE_ANY
;
1822 /* register arch-specific functions */
1823 armv7a
->examine_debug_reason
= NULL
;
1825 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1827 armv7a
->pre_restore_context
= NULL
;
1828 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1829 armv7a
->armv4_5_mmu
.get_ttb
= cortex_a8_get_ttb
;
1830 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_phys_memory
;
1831 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_phys_memory
;
1832 armv7a
->armv4_5_mmu
.disable_mmu_caches
= cortex_a8_disable_mmu_caches
;
1833 armv7a
->armv4_5_mmu
.enable_mmu_caches
= cortex_a8_enable_mmu_caches
;
1834 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1835 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1838 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1840 /* REVISIT v7a setup should be in a v7a-specific routine */
1841 arm_init_arch_info(target
, armv4_5
);
1842 armv7a
->common_magic
= ARMV7_COMMON_MAGIC
;
1844 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1849 static int cortex_a8_target_create(struct target
*target
, Jim_Interp
*interp
)
1851 struct cortex_a8_common
*cortex_a8
= calloc(1, sizeof(struct cortex_a8_common
));
1853 return cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1856 /* FIX! error propagation missing from this fn */
1857 static uint32_t cortex_a8_get_ttb(struct target
*target
)
1859 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1860 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1861 uint32_t ttb
= 0, retval
= ERROR_OK
;
1863 /* current_address_mode is set inside cortex_a8_virt2phys()
1864 where we can determine if address belongs to user or kernel */
1865 if(cortex_a8
->current_address_mode
== ARM_MODE_SVC
)
1867 /* MRC p15,0,<Rt>,c1,c0,0 ; Read CP15 System Control Register */
1868 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
1869 0, 1, /* op1, op2 */
1870 2, 0, /* CRn, CRm */
1873 else if(cortex_a8
->current_address_mode
== ARM_MODE_USR
)
1875 /* MRC p15,0,<Rt>,c1,c0,0 ; Read CP15 System Control Register */
1876 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
1877 0, 0, /* op1, op2 */
1878 2, 0, /* CRn, CRm */
1881 /* we don't know whose address is: user or kernel
1882 we assume that if we are in kernel mode then
1883 address belongs to kernel else if in user mode
1885 else if(armv7a
->armv4_5_common
.core_mode
== ARM_MODE_SVC
)
1887 /* MRC p15,0,<Rt>,c1,c0,0 ; Read CP15 System Control Register */
1888 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
1889 0, 1, /* op1, op2 */
1890 2, 0, /* CRn, CRm */
1893 else if(armv7a
->armv4_5_common
.core_mode
== ARM_MODE_USR
)
1895 /* MRC p15,0,<Rt>,c1,c0,0 ; Read CP15 System Control Register */
1896 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
1897 0, 0, /* op1, op2 */
1898 2, 0, /* CRn, CRm */
1901 /* finally we don't know whose ttb to use: user or kernel */
1903 LOG_ERROR("Don't know how to get ttb for current mode!!!");
1910 /* FIX! error propagation missing from this fn */
1911 static void cortex_a8_disable_mmu_caches(struct target
*target
, int mmu
,
1912 int d_u_cache
, int i_cache
)
1914 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1915 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1916 uint32_t cp15_control
;
1918 /* read cp15 control register */
1919 armv7a
->armv4_5_common
.mrc(target
, 15,
1920 0, 0, /* op1, op2 */
1921 1, 0, /* CRn, CRm */
1926 cp15_control
&= ~0x1U
;
1929 cp15_control
&= ~0x4U
;
1932 cp15_control
&= ~0x1000U
;
1934 armv7a
->armv4_5_common
.mcr(target
, 15,
1935 0, 0, /* op1, op2 */
1936 1, 0, /* CRn, CRm */
1940 /* FIX! error propagation missing from this fn */
1941 static void cortex_a8_enable_mmu_caches(struct target
*target
, int mmu
,
1942 int d_u_cache
, int i_cache
)
1944 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1945 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1946 uint32_t cp15_control
;
1948 /* read cp15 control register */
1949 armv7a
->armv4_5_common
.mrc(target
, 15,
1950 0, 0, /* op1, op2 */
1951 1, 0, /* CRn, CRm */
1955 cp15_control
|= 0x1U
;
1958 cp15_control
|= 0x4U
;
1961 cp15_control
|= 0x1000U
;
1963 armv7a
->armv4_5_common
.mcr(target
, 15,
1964 0, 0, /* op1, op2 */
1965 1, 0, /* CRn, CRm */
1970 static int cortex_a8_mmu(struct target
*target
, int *enabled
)
1972 if (target
->state
!= TARGET_HALTED
) {
1973 LOG_ERROR("%s: target not halted", __func__
);
1974 return ERROR_TARGET_INVALID
;
1977 *enabled
= target_to_cortex_a8(target
)->armv7a_common
.armv4_5_mmu
.mmu_enabled
;
1981 static int cortex_a8_virt2phys(struct target
*target
,
1982 uint32_t virt
, uint32_t *phys
)
1985 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1986 // struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
1987 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1989 /* We assume that virtual address is separated
1990 between user and kernel in Linux style:
1991 0x00000000-0xbfffffff - User space
1992 0xc0000000-0xffffffff - Kernel space */
1993 if( virt
< 0xc0000000 ) /* Linux user space */
1994 cortex_a8
->current_address_mode
= ARM_MODE_USR
;
1995 else /* Linux kernel */
1996 cortex_a8
->current_address_mode
= ARM_MODE_SVC
;
1998 int retval
= armv4_5_mmu_translate_va(target
,
1999 &armv7a
->armv4_5_mmu
, virt
, &cb
, &ret
);
2000 if (retval
!= ERROR_OK
)
2002 /* Reset the flag. We don't want someone else to use it by error */
2003 cortex_a8
->current_address_mode
= ARM_MODE_ANY
;
2009 COMMAND_HANDLER(cortex_a8_handle_cache_info_command
)
2011 struct target
*target
= get_current_target(CMD_CTX
);
2012 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
2014 return armv4_5_handle_cache_info_command(CMD_CTX
,
2015 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
2019 COMMAND_HANDLER(cortex_a8_handle_dbginit_command
)
2021 struct target
*target
= get_current_target(CMD_CTX
);
2022 if (!target_was_examined(target
))
2024 LOG_ERROR("target not examined yet");
2028 return cortex_a8_init_debug_access(target
);
2031 static const struct command_registration cortex_a8_exec_command_handlers
[] = {
2033 .name
= "cache_info",
2034 .handler
= cortex_a8_handle_cache_info_command
,
2035 .mode
= COMMAND_EXEC
,
2036 .help
= "display information about target caches",
2040 .handler
= cortex_a8_handle_dbginit_command
,
2041 .mode
= COMMAND_EXEC
,
2042 .help
= "Initialize core debug",
2044 COMMAND_REGISTRATION_DONE
2046 static const struct command_registration cortex_a8_command_handlers
[] = {
2048 .chain
= arm_command_handlers
,
2051 .chain
= armv7a_command_handlers
,
2054 .name
= "cortex_a8",
2055 .mode
= COMMAND_ANY
,
2056 .help
= "Cortex-A8 command group",
2057 .chain
= cortex_a8_exec_command_handlers
,
2059 COMMAND_REGISTRATION_DONE
2062 struct target_type cortexa8_target
= {
2063 .name
= "cortex_a8",
2065 .poll
= cortex_a8_poll
,
2066 .arch_state
= armv7a_arch_state
,
2068 .target_request_data
= NULL
,
2070 .halt
= cortex_a8_halt
,
2071 .resume
= cortex_a8_resume
,
2072 .step
= cortex_a8_step
,
2074 .assert_reset
= cortex_a8_assert_reset
,
2075 .deassert_reset
= cortex_a8_deassert_reset
,
2076 .soft_reset_halt
= NULL
,
2078 /* REVISIT allow exporting VFP3 registers ... */
2079 .get_gdb_reg_list
= arm_get_gdb_reg_list
,
2081 .read_memory
= cortex_a8_read_memory
,
2082 .write_memory
= cortex_a8_write_memory
,
2083 .bulk_write_memory
= cortex_a8_bulk_write_memory
,
2085 .checksum_memory
= arm_checksum_memory
,
2086 .blank_check_memory
= arm_blank_check_memory
,
2088 .run_algorithm
= armv4_5_run_algorithm
,
2090 .add_breakpoint
= cortex_a8_add_breakpoint
,
2091 .remove_breakpoint
= cortex_a8_remove_breakpoint
,
2092 .add_watchpoint
= NULL
,
2093 .remove_watchpoint
= NULL
,
2095 .commands
= cortex_a8_command_handlers
,
2096 .target_create
= cortex_a8_target_create
,
2097 .init_target
= cortex_a8_init_target
,
2098 .examine
= cortex_a8_examine
,
2100 .read_phys_memory
= cortex_a8_read_phys_memory
,
2101 .write_phys_memory
= cortex_a8_write_phys_memory
,
2102 .mmu
= cortex_a8_mmu
,
2103 .virt2phys
= cortex_a8_virt2phys
,
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)