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-A9(tm) TRM, ARM DDI 0407F *
34 ***************************************************************************/
39 #include "breakpoints.h"
40 #include "cortex_a9.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_a9_poll(struct target
*target
);
48 static int cortex_a9_debug_entry(struct target
*target
);
49 static int cortex_a9_restore_context(struct target
*target
, bool bpwp
);
50 static int cortex_a9_set_breakpoint(struct target
*target
,
51 struct breakpoint
*breakpoint
, uint8_t matchmode
);
52 static int cortex_a9_unset_breakpoint(struct target
*target
,
53 struct breakpoint
*breakpoint
);
54 static int cortex_a9_dap_read_coreregister_u32(struct target
*target
,
55 uint32_t *value
, int regnum
);
56 static int cortex_a9_dap_write_coreregister_u32(struct target
*target
,
57 uint32_t value
, int regnum
);
58 static int cortex_a9_mmu(struct target
*target
, int *enabled
);
59 static int cortex_a9_virt2phys(struct target
*target
,
60 uint32_t virt
, uint32_t *phys
);
61 static int cortex_a9_disable_mmu_caches(struct target
*target
, int mmu
,
62 int d_u_cache
, int i_cache
);
63 static int cortex_a9_enable_mmu_caches(struct target
*target
, int mmu
,
64 int d_u_cache
, int i_cache
);
65 static int cortex_a9_get_ttb(struct target
*target
, uint32_t *result
);
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
78 * Cortex-A9 Basic debug access, very low level assumes state is saved
80 static int cortex_a9_init_debug_access(struct target
*target
)
82 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
83 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
90 /* Unlocking the debug registers for modification */
91 /* The debugport might be uninitialised so try twice */
92 retval
= mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
93 if (retval
!= ERROR_OK
)
96 retval
= mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
97 if (retval
== ERROR_OK
)
99 LOG_USER("Locking debug access failed on first, but succeeded on second try.");
102 if (retval
!= ERROR_OK
)
104 /* Clear Sticky Power Down status Bit in PRSR to enable access to
105 the registers in the Core Power Domain */
106 retval
= mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_PRSR
, &dummy
);
107 if (retval
!= ERROR_OK
)
110 /* Enabling of instruction execution in debug mode is done in debug_entry code */
112 /* Resync breakpoint registers */
114 /* Since this is likely called from init or reset, update target state information*/
115 retval
= cortex_a9_poll(target
);
120 /* To reduce needless round-trips, pass in a pointer to the current
121 * DSCR value. Initialize it to zero if you just need to know the
122 * value on return from this function; or DSCR_INSTR_COMP if you
123 * happen to know that no instruction is pending.
125 static int cortex_a9_exec_opcode(struct target
*target
,
126 uint32_t opcode
, uint32_t *dscr_p
)
130 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
131 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
133 dscr
= dscr_p
? *dscr_p
: 0;
135 LOG_DEBUG("exec opcode 0x%08" PRIx32
, opcode
);
137 /* Wait for InstrCompl bit to be set */
138 long long then
= timeval_ms();
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
);
148 if (timeval_ms() > then
+ 1000)
150 LOG_ERROR("Timeout waiting for cortex_a9_exec_opcode");
155 retval
= mem_ap_write_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_ITR
, opcode
);
156 if (retval
!= ERROR_OK
)
162 retval
= mem_ap_read_atomic_u32(swjdp
,
163 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
164 if (retval
!= ERROR_OK
)
166 LOG_ERROR("Could not read DSCR register");
169 if (timeval_ms() > then
+ 1000)
171 LOG_ERROR("Timeout waiting for cortex_a9_exec_opcode");
175 while ((dscr
& DSCR_INSTR_COMP
) == 0); /* Wait for InstrCompl bit to be set */
183 /**************************************************************************
184 Read core register with very few exec_opcode, fast but needs work_area.
185 This can cause problems with MMU active.
186 **************************************************************************/
187 static int cortex_a9_read_regs_through_mem(struct target
*target
, uint32_t address
,
190 int retval
= ERROR_OK
;
191 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
192 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
194 retval
= cortex_a9_dap_read_coreregister_u32(target
, regfile
, 0);
195 if (retval
!= ERROR_OK
)
197 retval
= cortex_a9_dap_write_coreregister_u32(target
, address
, 0);
198 if (retval
!= ERROR_OK
)
200 retval
= cortex_a9_exec_opcode(target
, ARMV4_5_STMIA(0, 0xFFFE, 0, 0), NULL
);
201 if (retval
!= ERROR_OK
)
204 dap_ap_select(swjdp
, swjdp_memoryap
);
205 retval
= mem_ap_read_buf_u32(swjdp
, (uint8_t *)(®file
[1]), 4*15, address
);
206 if (retval
!= ERROR_OK
)
208 dap_ap_select(swjdp
, swjdp_debugap
);
213 static int cortex_a9_dap_read_coreregister_u32(struct target
*target
,
214 uint32_t *value
, int regnum
)
216 int retval
= ERROR_OK
;
217 uint8_t reg
= regnum
&0xFF;
219 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
220 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
227 /* Rn to DCCTX, "MCR p14, 0, Rn, c0, c5, 0" 0xEE00nE15 */
228 retval
= cortex_a9_exec_opcode(target
,
229 ARMV4_5_MCR(14, 0, reg
, 0, 5, 0),
231 if (retval
!= ERROR_OK
)
236 /* "MOV r0, r15"; then move r0 to DCCTX */
237 retval
= cortex_a9_exec_opcode(target
, 0xE1A0000F, &dscr
);
238 if (retval
!= ERROR_OK
)
240 retval
= cortex_a9_exec_opcode(target
,
241 ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
243 if (retval
!= ERROR_OK
)
248 /* "MRS r0, CPSR" or "MRS r0, SPSR"
249 * then move r0 to DCCTX
251 retval
= cortex_a9_exec_opcode(target
, ARMV4_5_MRS(0, reg
& 1), &dscr
);
252 if (retval
!= ERROR_OK
)
254 retval
= cortex_a9_exec_opcode(target
,
255 ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
257 if (retval
!= ERROR_OK
)
261 /* Wait for DTRRXfull then read DTRRTX */
262 long long then
= timeval_ms();
263 while ((dscr
& DSCR_DTR_TX_FULL
) == 0)
265 retval
= mem_ap_read_atomic_u32(swjdp
,
266 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
267 if (retval
!= ERROR_OK
)
269 if (timeval_ms() > then
+ 1000)
271 LOG_ERROR("Timeout waiting for cortex_a9_exec_opcode");
276 retval
= mem_ap_read_atomic_u32(swjdp
,
277 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
278 LOG_DEBUG("read DCC 0x%08" PRIx32
, *value
);
283 static int cortex_a9_dap_write_coreregister_u32(struct target
*target
,
284 uint32_t value
, int regnum
)
286 int retval
= ERROR_OK
;
287 uint8_t Rd
= regnum
&0xFF;
289 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
290 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
292 LOG_DEBUG("register %i, value 0x%08" PRIx32
, regnum
, value
);
294 /* Check that DCCRX is not full */
295 retval
= mem_ap_read_atomic_u32(swjdp
,
296 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
297 if (retval
!= ERROR_OK
)
299 if (dscr
& DSCR_DTR_RX_FULL
)
301 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
302 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
303 retval
= cortex_a9_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
305 if (retval
!= ERROR_OK
)
312 /* Write DTRRX ... sets DSCR.DTRRXfull but exec_opcode() won't care */
313 LOG_DEBUG("write DCC 0x%08" PRIx32
, value
);
314 retval
= mem_ap_write_u32(swjdp
,
315 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
316 if (retval
!= ERROR_OK
)
321 /* DCCRX to Rn, "MCR p14, 0, Rn, c0, c5, 0", 0xEE00nE15 */
322 retval
= cortex_a9_exec_opcode(target
, ARMV4_5_MRC(14, 0, Rd
, 0, 5, 0),
324 if (retval
!= ERROR_OK
)
329 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15
332 retval
= cortex_a9_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
334 if (retval
!= ERROR_OK
)
336 retval
= cortex_a9_exec_opcode(target
, 0xE1A0F000, &dscr
);
337 if (retval
!= ERROR_OK
)
342 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15
343 * then "MSR CPSR_cxsf, r0" or "MSR SPSR_cxsf, r0" (all fields)
345 retval
= cortex_a9_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
347 if (retval
!= ERROR_OK
)
349 retval
= cortex_a9_exec_opcode(target
, ARMV4_5_MSR_GP(0, 0xF, Rd
& 1),
351 if (retval
!= ERROR_OK
)
354 /* "Prefetch flush" after modifying execution status in CPSR */
357 retval
= cortex_a9_exec_opcode(target
,
358 ARMV4_5_MCR(15, 0, 0, 7, 5, 4),
360 if (retval
!= ERROR_OK
)
368 /* Write to memory mapped registers directly with no cache or mmu handling */
369 static int cortex_a9_dap_write_memap_register_u32(struct target
*target
, uint32_t address
, uint32_t value
)
372 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
373 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
375 retval
= mem_ap_write_atomic_u32(swjdp
, address
, value
);
381 * Cortex-A9 implementation of Debug Programmer's Model
383 * NOTE the invariant: these routines return with DSCR_INSTR_COMP set,
384 * so there's no need to poll for it before executing an instruction.
386 * NOTE that in several of these cases the "stall" mode might be useful.
387 * It'd let us queue a few operations together... prepare/finish might
388 * be the places to enable/disable that mode.
391 static inline struct cortex_a9_common
*dpm_to_a9(struct arm_dpm
*dpm
)
393 return container_of(dpm
, struct cortex_a9_common
, armv7a_common
.dpm
);
396 static int cortex_a9_write_dcc(struct cortex_a9_common
*a9
, uint32_t data
)
398 LOG_DEBUG("write DCC 0x%08" PRIx32
, data
);
399 return mem_ap_write_u32(&a9
->armv7a_common
.dap
,
400 a9
->armv7a_common
.debug_base
+ CPUDBG_DTRRX
, data
);
403 static int cortex_a9_read_dcc(struct cortex_a9_common
*a9
, uint32_t *data
,
406 struct adiv5_dap
*swjdp
= &a9
->armv7a_common
.dap
;
407 uint32_t dscr
= DSCR_INSTR_COMP
;
413 /* Wait for DTRRXfull */
414 long long then
= timeval_ms();
415 while ((dscr
& DSCR_DTR_TX_FULL
) == 0) {
416 retval
= mem_ap_read_atomic_u32(swjdp
,
417 a9
->armv7a_common
.debug_base
+ CPUDBG_DSCR
,
419 if (retval
!= ERROR_OK
)
421 if (timeval_ms() > then
+ 1000)
423 LOG_ERROR("Timeout waiting for read dcc");
428 retval
= mem_ap_read_atomic_u32(swjdp
,
429 a9
->armv7a_common
.debug_base
+ CPUDBG_DTRTX
, data
);
430 if (retval
!= ERROR_OK
)
432 //LOG_DEBUG("read DCC 0x%08" PRIx32, *data);
440 static int cortex_a9_dpm_prepare(struct arm_dpm
*dpm
)
442 struct cortex_a9_common
*a9
= dpm_to_a9(dpm
);
443 struct adiv5_dap
*swjdp
= &a9
->armv7a_common
.dap
;
447 /* set up invariant: INSTR_COMP is set after ever DPM operation */
448 long long then
= timeval_ms();
451 retval
= mem_ap_read_atomic_u32(swjdp
,
452 a9
->armv7a_common
.debug_base
+ CPUDBG_DSCR
,
454 if (retval
!= ERROR_OK
)
456 if ((dscr
& DSCR_INSTR_COMP
) != 0)
458 if (timeval_ms() > then
+ 1000)
460 LOG_ERROR("Timeout waiting for dpm prepare");
465 /* this "should never happen" ... */
466 if (dscr
& DSCR_DTR_RX_FULL
) {
467 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
469 retval
= cortex_a9_exec_opcode(
470 a9
->armv7a_common
.armv4_5_common
.target
,
471 ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
473 if (retval
!= ERROR_OK
)
480 static int cortex_a9_dpm_finish(struct arm_dpm
*dpm
)
482 /* REVISIT what could be done here? */
486 static int cortex_a9_instr_write_data_dcc(struct arm_dpm
*dpm
,
487 uint32_t opcode
, uint32_t data
)
489 struct cortex_a9_common
*a9
= dpm_to_a9(dpm
);
491 uint32_t dscr
= DSCR_INSTR_COMP
;
493 retval
= cortex_a9_write_dcc(a9
, data
);
494 if (retval
!= ERROR_OK
)
497 return cortex_a9_exec_opcode(
498 a9
->armv7a_common
.armv4_5_common
.target
,
503 static int cortex_a9_instr_write_data_r0(struct arm_dpm
*dpm
,
504 uint32_t opcode
, uint32_t data
)
506 struct cortex_a9_common
*a9
= dpm_to_a9(dpm
);
507 uint32_t dscr
= DSCR_INSTR_COMP
;
510 retval
= cortex_a9_write_dcc(a9
, data
);
511 if (retval
!= ERROR_OK
)
514 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15 */
515 retval
= cortex_a9_exec_opcode(
516 a9
->armv7a_common
.armv4_5_common
.target
,
517 ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
519 if (retval
!= ERROR_OK
)
522 /* then the opcode, taking data from R0 */
523 retval
= cortex_a9_exec_opcode(
524 a9
->armv7a_common
.armv4_5_common
.target
,
531 static int cortex_a9_instr_cpsr_sync(struct arm_dpm
*dpm
)
533 struct target
*target
= dpm
->arm
->target
;
534 uint32_t dscr
= DSCR_INSTR_COMP
;
536 /* "Prefetch flush" after modifying execution status in CPSR */
537 return cortex_a9_exec_opcode(target
,
538 ARMV4_5_MCR(15, 0, 0, 7, 5, 4),
542 static int cortex_a9_instr_read_data_dcc(struct arm_dpm
*dpm
,
543 uint32_t opcode
, uint32_t *data
)
545 struct cortex_a9_common
*a9
= dpm_to_a9(dpm
);
547 uint32_t dscr
= DSCR_INSTR_COMP
;
549 /* the opcode, writing data to DCC */
550 retval
= cortex_a9_exec_opcode(
551 a9
->armv7a_common
.armv4_5_common
.target
,
554 if (retval
!= ERROR_OK
)
557 return cortex_a9_read_dcc(a9
, data
, &dscr
);
561 static int cortex_a9_instr_read_data_r0(struct arm_dpm
*dpm
,
562 uint32_t opcode
, uint32_t *data
)
564 struct cortex_a9_common
*a9
= dpm_to_a9(dpm
);
565 uint32_t dscr
= DSCR_INSTR_COMP
;
568 /* the opcode, writing data to R0 */
569 retval
= cortex_a9_exec_opcode(
570 a9
->armv7a_common
.armv4_5_common
.target
,
573 if (retval
!= ERROR_OK
)
576 /* write R0 to DCC */
577 retval
= cortex_a9_exec_opcode(
578 a9
->armv7a_common
.armv4_5_common
.target
,
579 ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
581 if (retval
!= ERROR_OK
)
584 return cortex_a9_read_dcc(a9
, data
, &dscr
);
587 static int cortex_a9_bpwp_enable(struct arm_dpm
*dpm
, unsigned index_t
,
588 uint32_t addr
, uint32_t control
)
590 struct cortex_a9_common
*a9
= dpm_to_a9(dpm
);
591 uint32_t vr
= a9
->armv7a_common
.debug_base
;
592 uint32_t cr
= a9
->armv7a_common
.debug_base
;
596 case 0 ... 15: /* breakpoints */
597 vr
+= CPUDBG_BVR_BASE
;
598 cr
+= CPUDBG_BCR_BASE
;
600 case 16 ... 31: /* watchpoints */
601 vr
+= CPUDBG_WVR_BASE
;
602 cr
+= CPUDBG_WCR_BASE
;
611 LOG_DEBUG("A9: bpwp enable, vr %08x cr %08x",
612 (unsigned) vr
, (unsigned) cr
);
614 retval
= cortex_a9_dap_write_memap_register_u32(dpm
->arm
->target
,
616 if (retval
!= ERROR_OK
)
618 retval
= cortex_a9_dap_write_memap_register_u32(dpm
->arm
->target
,
623 static int cortex_a9_bpwp_disable(struct arm_dpm
*dpm
, unsigned index_t
)
625 struct cortex_a9_common
*a9
= dpm_to_a9(dpm
);
630 cr
= a9
->armv7a_common
.debug_base
+ CPUDBG_BCR_BASE
;
633 cr
= a9
->armv7a_common
.debug_base
+ CPUDBG_WCR_BASE
;
641 LOG_DEBUG("A9: bpwp disable, cr %08x", (unsigned) cr
);
643 /* clear control register */
644 return cortex_a9_dap_write_memap_register_u32(dpm
->arm
->target
, cr
, 0);
647 static int cortex_a9_dpm_setup(struct cortex_a9_common
*a9
, uint32_t didr
)
649 struct arm_dpm
*dpm
= &a9
->armv7a_common
.dpm
;
652 dpm
->arm
= &a9
->armv7a_common
.armv4_5_common
;
655 dpm
->prepare
= cortex_a9_dpm_prepare
;
656 dpm
->finish
= cortex_a9_dpm_finish
;
658 dpm
->instr_write_data_dcc
= cortex_a9_instr_write_data_dcc
;
659 dpm
->instr_write_data_r0
= cortex_a9_instr_write_data_r0
;
660 dpm
->instr_cpsr_sync
= cortex_a9_instr_cpsr_sync
;
662 dpm
->instr_read_data_dcc
= cortex_a9_instr_read_data_dcc
;
663 dpm
->instr_read_data_r0
= cortex_a9_instr_read_data_r0
;
665 dpm
->bpwp_enable
= cortex_a9_bpwp_enable
;
666 dpm
->bpwp_disable
= cortex_a9_bpwp_disable
;
668 retval
= arm_dpm_setup(dpm
);
669 if (retval
== ERROR_OK
)
670 retval
= arm_dpm_initialize(dpm
);
677 * Cortex-A9 Run control
680 static int cortex_a9_poll(struct target
*target
)
682 int retval
= ERROR_OK
;
684 struct cortex_a9_common
*cortex_a9
= target_to_cortex_a9(target
);
685 struct armv7a_common
*armv7a
= &cortex_a9
->armv7a_common
;
686 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
687 enum target_state prev_target_state
= target
->state
;
688 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
690 dap_ap_select(swjdp
, swjdp_debugap
);
691 retval
= mem_ap_read_atomic_u32(swjdp
,
692 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
693 if (retval
!= ERROR_OK
)
695 dap_ap_select(swjdp
, saved_apsel
);
698 cortex_a9
->cpudbg_dscr
= dscr
;
700 if (DSCR_RUN_MODE(dscr
) == (DSCR_CORE_HALTED
| DSCR_CORE_RESTARTED
))
702 if (prev_target_state
!= TARGET_HALTED
)
704 /* We have a halting debug event */
705 LOG_DEBUG("Target halted");
706 target
->state
= TARGET_HALTED
;
707 if ((prev_target_state
== TARGET_RUNNING
)
708 || (prev_target_state
== TARGET_RESET
))
710 retval
= cortex_a9_debug_entry(target
);
711 if (retval
!= ERROR_OK
)
714 target_call_event_callbacks(target
,
715 TARGET_EVENT_HALTED
);
717 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
721 retval
= cortex_a9_debug_entry(target
);
722 if (retval
!= ERROR_OK
)
725 target_call_event_callbacks(target
,
726 TARGET_EVENT_DEBUG_HALTED
);
730 else if (DSCR_RUN_MODE(dscr
) == DSCR_CORE_RESTARTED
)
732 target
->state
= TARGET_RUNNING
;
736 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32
, dscr
);
737 target
->state
= TARGET_UNKNOWN
;
740 dap_ap_select(swjdp
, saved_apsel
);
745 static int cortex_a9_halt(struct target
*target
)
747 int retval
= ERROR_OK
;
749 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
750 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
751 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
752 dap_ap_select(swjdp
, swjdp_debugap
);
755 * Tell the core to be halted by writing DRCR with 0x1
756 * and then wait for the core to be halted.
758 retval
= mem_ap_write_atomic_u32(swjdp
,
759 armv7a
->debug_base
+ CPUDBG_DRCR
, DRCR_HALT
);
760 if (retval
!= ERROR_OK
)
764 * enter halting debug mode
766 retval
= mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
767 if (retval
!= ERROR_OK
)
770 retval
= mem_ap_write_atomic_u32(swjdp
,
771 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
| DSCR_HALT_DBG_MODE
);
772 if (retval
!= ERROR_OK
)
775 long long then
= timeval_ms();
778 retval
= mem_ap_read_atomic_u32(swjdp
,
779 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
780 if (retval
!= ERROR_OK
)
782 if ((dscr
& DSCR_CORE_HALTED
) != 0)
786 if (timeval_ms() > then
+ 1000)
788 LOG_ERROR("Timeout waiting for halt");
793 target
->debug_reason
= DBG_REASON_DBGRQ
;
796 dap_ap_select(swjdp
, saved_apsel
);
800 static int cortex_a9_resume(struct target
*target
, int current
,
801 uint32_t address
, int handle_breakpoints
, int debug_execution
)
803 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
804 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
805 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
808 // struct breakpoint *breakpoint = NULL;
809 uint32_t resume_pc
, dscr
;
811 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
812 dap_ap_select(swjdp
, swjdp_debugap
);
814 if (!debug_execution
)
815 target_free_all_working_areas(target
);
820 /* Disable interrupts */
821 /* We disable interrupts in the PRIMASK register instead of
822 * masking with C_MASKINTS,
823 * This is probably the same issue as Cortex-M3 Errata 377493:
824 * C_MASKINTS in parallel with disabled interrupts can cause
825 * local faults to not be taken. */
826 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
827 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
828 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
830 /* Make sure we are in Thumb mode */
831 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
832 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
833 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
834 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
838 /* current = 1: continue on current pc, otherwise continue at <address> */
839 resume_pc
= buf_get_u32(armv4_5
->pc
->value
, 0, 32);
843 /* Make sure that the Armv7 gdb thumb fixups does not
844 * kill the return address
846 switch (armv4_5
->core_state
)
849 resume_pc
&= 0xFFFFFFFC;
851 case ARM_STATE_THUMB
:
852 case ARM_STATE_THUMB_EE
:
853 /* When the return address is loaded into PC
854 * bit 0 must be 1 to stay in Thumb state
858 case ARM_STATE_JAZELLE
:
859 LOG_ERROR("How do I resume into Jazelle state??");
862 LOG_DEBUG("resume pc = 0x%08" PRIx32
, resume_pc
);
863 buf_set_u32(armv4_5
->pc
->value
, 0, 32, resume_pc
);
864 armv4_5
->pc
->dirty
= 1;
865 armv4_5
->pc
->valid
= 1;
867 retval
= cortex_a9_restore_context(target
, handle_breakpoints
);
868 if (retval
!= ERROR_OK
)
872 /* the front-end may request us not to handle breakpoints */
873 if (handle_breakpoints
)
875 /* Single step past breakpoint at current address */
876 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
878 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
879 cortex_m3_unset_breakpoint(target
, breakpoint
);
880 cortex_m3_single_step_core(target
);
881 cortex_m3_set_breakpoint(target
, breakpoint
);
888 * Restart core and wait for it to be started. Clear ITRen and sticky
889 * exception flags: see ARMv7 ARM, C5.9.
891 * REVISIT: for single stepping, we probably want to
892 * disable IRQs by default, with optional override...
895 retval
= mem_ap_read_atomic_u32(swjdp
,
896 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
897 if (retval
!= ERROR_OK
)
900 if ((dscr
& DSCR_INSTR_COMP
) == 0)
901 LOG_ERROR("DSCR InstrCompl must be set before leaving debug!");
903 retval
= mem_ap_write_atomic_u32(swjdp
,
904 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
& ~DSCR_ITR_EN
);
905 if (retval
!= ERROR_OK
)
908 retval
= mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DRCR
,
909 DRCR_RESTART
| DRCR_CLEAR_EXCEPTIONS
);
910 if (retval
!= ERROR_OK
)
913 long long then
= timeval_ms();
916 retval
= mem_ap_read_atomic_u32(swjdp
,
917 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
918 if (retval
!= ERROR_OK
)
920 if ((dscr
& DSCR_CORE_RESTARTED
) != 0)
922 if (timeval_ms() > then
+ 1000)
924 LOG_ERROR("Timeout waiting for resume");
929 target
->debug_reason
= DBG_REASON_NOTHALTED
;
930 target
->state
= TARGET_RUNNING
;
932 /* registers are now invalid */
933 register_cache_invalidate(armv4_5
->core_cache
);
935 if (!debug_execution
)
937 target
->state
= TARGET_RUNNING
;
938 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
939 LOG_DEBUG("target resumed at 0x%" PRIx32
, resume_pc
);
943 target
->state
= TARGET_DEBUG_RUNNING
;
944 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
945 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, resume_pc
);
948 dap_ap_select(swjdp
, saved_apsel
);
953 static int cortex_a9_debug_entry(struct target
*target
)
956 uint32_t regfile
[16], cpsr
, dscr
;
957 int retval
= ERROR_OK
;
958 struct working_area
*regfile_working_area
= NULL
;
959 struct cortex_a9_common
*cortex_a9
= target_to_cortex_a9(target
);
960 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
961 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
962 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
965 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a9
->cpudbg_dscr
);
967 /* REVISIT surely we should not re-read DSCR !! */
968 retval
= mem_ap_read_atomic_u32(swjdp
,
969 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
970 if (retval
!= ERROR_OK
)
973 /* REVISIT see A9 TRM 12.11.4 steps 2..3 -- make sure that any
974 * imprecise data aborts get discarded by issuing a Data
975 * Synchronization Barrier: ARMV4_5_MCR(15, 0, 0, 7, 10, 4).
978 /* Enable the ITR execution once we are in debug mode */
980 retval
= mem_ap_write_atomic_u32(swjdp
,
981 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
);
982 if (retval
!= ERROR_OK
)
985 /* Examine debug reason */
986 arm_dpm_report_dscr(&armv7a
->dpm
, cortex_a9
->cpudbg_dscr
);
988 /* save address of instruction that triggered the watchpoint? */
989 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
) {
992 retval
= mem_ap_read_atomic_u32(swjdp
,
993 armv7a
->debug_base
+ CPUDBG_WFAR
,
995 if (retval
!= ERROR_OK
)
997 arm_dpm_report_wfar(&armv7a
->dpm
, wfar
);
1000 /* REVISIT fast_reg_read is never set ... */
1002 /* Examine target state and mode */
1003 if (cortex_a9
->fast_reg_read
)
1004 target_alloc_working_area(target
, 64, ®file_working_area
);
1006 /* First load register acessible through core debug port*/
1007 if (!regfile_working_area
)
1009 retval
= arm_dpm_read_current_registers(&armv7a
->dpm
);
1013 dap_ap_select(swjdp
, swjdp_memoryap
);
1014 retval
= cortex_a9_read_regs_through_mem(target
,
1015 regfile_working_area
->address
, regfile
);
1016 dap_ap_select(swjdp
, swjdp_memoryap
);
1017 target_free_working_area(target
, regfile_working_area
);
1018 if (retval
!= ERROR_OK
)
1023 /* read Current PSR */
1024 retval
= cortex_a9_dap_read_coreregister_u32(target
, &cpsr
, 16);
1025 if (retval
!= ERROR_OK
)
1027 dap_ap_select(swjdp
, swjdp_debugap
);
1028 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
1030 arm_set_cpsr(armv4_5
, cpsr
);
1033 for (i
= 0; i
<= ARM_PC
; i
++)
1035 reg
= arm_reg_current(armv4_5
, i
);
1037 buf_set_u32(reg
->value
, 0, 32, regfile
[i
]);
1042 /* Fixup PC Resume Address */
1043 if (cpsr
& (1 << 5))
1045 // T bit set for Thumb or ThumbEE state
1046 regfile
[ARM_PC
] -= 4;
1051 regfile
[ARM_PC
] -= 8;
1055 buf_set_u32(reg
->value
, 0, 32, regfile
[ARM_PC
]);
1056 reg
->dirty
= reg
->valid
;
1060 /* TODO, Move this */
1061 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
1062 cortex_a9_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
1063 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
1065 cortex_a9_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
1066 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
1068 cortex_a9_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
1069 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
1072 /* Are we in an exception handler */
1073 // armv4_5->exception_number = 0;
1074 if (armv7a
->post_debug_entry
)
1076 retval
= armv7a
->post_debug_entry(target
);
1077 if (retval
!= ERROR_OK
)
1084 static int cortex_a9_post_debug_entry(struct target
*target
)
1086 struct cortex_a9_common
*cortex_a9
= target_to_cortex_a9(target
);
1087 struct armv7a_common
*armv7a
= &cortex_a9
->armv7a_common
;
1090 /* MRC p15,0,<Rt>,c1,c0,0 ; Read CP15 System Control Register */
1091 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
1092 0, 0, /* op1, op2 */
1093 1, 0, /* CRn, CRm */
1094 &cortex_a9
->cp15_control_reg
);
1095 if (retval
!= ERROR_OK
)
1097 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a9
->cp15_control_reg
);
1099 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
1101 uint32_t cache_type_reg
;
1103 /* MRC p15,0,<Rt>,c0,c0,1 ; Read CP15 Cache Type Register */
1104 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
1105 0, 1, /* op1, op2 */
1106 0, 0, /* CRn, CRm */
1108 if (retval
!= ERROR_OK
)
1110 LOG_DEBUG("cp15 cache type: %8.8x", (unsigned) cache_type_reg
);
1112 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A9 */
1113 armv4_5_identify_cache(cache_type_reg
,
1114 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1117 armv7a
->armv4_5_mmu
.mmu_enabled
=
1118 (cortex_a9
->cp15_control_reg
& 0x1U
) ? 1 : 0;
1119 armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
=
1120 (cortex_a9
->cp15_control_reg
& 0x4U
) ? 1 : 0;
1121 armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
=
1122 (cortex_a9
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
1127 static int cortex_a9_step(struct target
*target
, int current
, uint32_t address
,
1128 int handle_breakpoints
)
1130 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1131 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
1132 struct breakpoint
*breakpoint
= NULL
;
1133 struct breakpoint stepbreakpoint
;
1137 if (target
->state
!= TARGET_HALTED
)
1139 LOG_WARNING("target not halted");
1140 return ERROR_TARGET_NOT_HALTED
;
1143 /* current = 1: continue on current pc, otherwise continue at <address> */
1147 buf_set_u32(r
->value
, 0, 32, address
);
1151 address
= buf_get_u32(r
->value
, 0, 32);
1154 /* The front-end may request us not to handle breakpoints.
1155 * But since Cortex-A9 uses breakpoint for single step,
1156 * we MUST handle breakpoints.
1158 handle_breakpoints
= 1;
1159 if (handle_breakpoints
) {
1160 breakpoint
= breakpoint_find(target
, address
);
1162 cortex_a9_unset_breakpoint(target
, breakpoint
);
1165 /* Setup single step breakpoint */
1166 stepbreakpoint
.address
= address
;
1167 stepbreakpoint
.length
= (armv4_5
->core_state
== ARM_STATE_THUMB
)
1169 stepbreakpoint
.type
= BKPT_HARD
;
1170 stepbreakpoint
.set
= 0;
1172 /* Break on IVA mismatch */
1173 cortex_a9_set_breakpoint(target
, &stepbreakpoint
, 0x04);
1175 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1177 retval
= cortex_a9_resume(target
, 1, address
, 0, 0);
1178 if (retval
!= ERROR_OK
)
1181 long long then
= timeval_ms();
1182 while (target
->state
!= TARGET_HALTED
)
1184 retval
= cortex_a9_poll(target
);
1185 if (retval
!= ERROR_OK
)
1187 if (timeval_ms() > then
+ 1000)
1189 LOG_ERROR("timeout waiting for target halt");
1194 cortex_a9_unset_breakpoint(target
, &stepbreakpoint
);
1196 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1199 cortex_a9_set_breakpoint(target
, breakpoint
, 0);
1201 if (target
->state
!= TARGET_HALTED
)
1202 LOG_DEBUG("target stepped");
1207 static int cortex_a9_restore_context(struct target
*target
, bool bpwp
)
1209 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1213 if (armv7a
->pre_restore_context
)
1214 armv7a
->pre_restore_context(target
);
1216 return arm_dpm_write_dirty_registers(&armv7a
->dpm
, bpwp
);
1221 * Cortex-A9 Breakpoint and watchpoint functions
1224 /* Setup hardware Breakpoint Register Pair */
1225 static int cortex_a9_set_breakpoint(struct target
*target
,
1226 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1231 uint8_t byte_addr_select
= 0x0F;
1232 struct cortex_a9_common
*cortex_a9
= target_to_cortex_a9(target
);
1233 struct armv7a_common
*armv7a
= &cortex_a9
->armv7a_common
;
1234 struct cortex_a9_brp
* brp_list
= cortex_a9
->brp_list
;
1236 if (breakpoint
->set
)
1238 LOG_WARNING("breakpoint already set");
1242 if (breakpoint
->type
== BKPT_HARD
)
1244 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a9
->brp_num
))
1246 if (brp_i
>= cortex_a9
->brp_num
)
1248 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1249 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1251 breakpoint
->set
= brp_i
+ 1;
1252 if (breakpoint
->length
== 2)
1254 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1256 control
= ((matchmode
& 0x7) << 20)
1257 | (byte_addr_select
<< 5)
1259 brp_list
[brp_i
].used
= 1;
1260 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1261 brp_list
[brp_i
].control
= control
;
1262 retval
= cortex_a9_dap_write_memap_register_u32(target
, armv7a
->debug_base
1263 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1264 brp_list
[brp_i
].value
);
1265 if (retval
!= ERROR_OK
)
1267 retval
= cortex_a9_dap_write_memap_register_u32(target
, armv7a
->debug_base
1268 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1269 brp_list
[brp_i
].control
);
1270 if (retval
!= ERROR_OK
)
1272 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1273 brp_list
[brp_i
].control
,
1274 brp_list
[brp_i
].value
);
1276 else if (breakpoint
->type
== BKPT_SOFT
)
1279 if (breakpoint
->length
== 2)
1281 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1285 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1287 retval
= target
->type
->read_memory(target
,
1288 breakpoint
->address
& 0xFFFFFFFE,
1289 breakpoint
->length
, 1,
1290 breakpoint
->orig_instr
);
1291 if (retval
!= ERROR_OK
)
1293 retval
= target
->type
->write_memory(target
,
1294 breakpoint
->address
& 0xFFFFFFFE,
1295 breakpoint
->length
, 1, code
);
1296 if (retval
!= ERROR_OK
)
1298 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1304 static int cortex_a9_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1307 struct cortex_a9_common
*cortex_a9
= target_to_cortex_a9(target
);
1308 struct armv7a_common
*armv7a
= &cortex_a9
->armv7a_common
;
1309 struct cortex_a9_brp
* brp_list
= cortex_a9
->brp_list
;
1311 if (!breakpoint
->set
)
1313 LOG_WARNING("breakpoint not set");
1317 if (breakpoint
->type
== BKPT_HARD
)
1319 int brp_i
= breakpoint
->set
- 1;
1320 if ((brp_i
< 0) || (brp_i
>= cortex_a9
->brp_num
))
1322 LOG_DEBUG("Invalid BRP number in breakpoint");
1325 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1326 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1327 brp_list
[brp_i
].used
= 0;
1328 brp_list
[brp_i
].value
= 0;
1329 brp_list
[brp_i
].control
= 0;
1330 retval
= cortex_a9_dap_write_memap_register_u32(target
, armv7a
->debug_base
1331 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1332 brp_list
[brp_i
].control
);
1333 if (retval
!= ERROR_OK
)
1335 retval
= cortex_a9_dap_write_memap_register_u32(target
, armv7a
->debug_base
1336 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1337 brp_list
[brp_i
].value
);
1338 if (retval
!= ERROR_OK
)
1343 /* restore original instruction (kept in target endianness) */
1344 if (breakpoint
->length
== 4)
1346 retval
= target
->type
->write_memory(target
,
1347 breakpoint
->address
& 0xFFFFFFFE,
1348 4, 1, breakpoint
->orig_instr
);
1349 if (retval
!= ERROR_OK
)
1354 retval
= target
->type
->write_memory(target
,
1355 breakpoint
->address
& 0xFFFFFFFE,
1356 2, 1, breakpoint
->orig_instr
);
1357 if (retval
!= ERROR_OK
)
1361 breakpoint
->set
= 0;
1366 static int cortex_a9_add_breakpoint(struct target
*target
,
1367 struct breakpoint
*breakpoint
)
1369 struct cortex_a9_common
*cortex_a9
= target_to_cortex_a9(target
);
1371 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a9
->brp_num_available
< 1))
1373 LOG_INFO("no hardware breakpoint available");
1374 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1377 if (breakpoint
->type
== BKPT_HARD
)
1378 cortex_a9
->brp_num_available
--;
1380 return cortex_a9_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1383 static int cortex_a9_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1385 struct cortex_a9_common
*cortex_a9
= target_to_cortex_a9(target
);
1388 /* It is perfectly possible to remove breakpoints while the target is running */
1389 if (target
->state
!= TARGET_HALTED
)
1391 LOG_WARNING("target not halted");
1392 return ERROR_TARGET_NOT_HALTED
;
1396 if (breakpoint
->set
)
1398 cortex_a9_unset_breakpoint(target
, breakpoint
);
1399 if (breakpoint
->type
== BKPT_HARD
)
1400 cortex_a9
->brp_num_available
++ ;
1410 * Cortex-A9 Reset functions
1413 static int cortex_a9_assert_reset(struct target
*target
)
1415 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1419 /* FIXME when halt is requested, make it work somehow... */
1421 /* Issue some kind of warm reset. */
1422 if (target_has_event_action(target
, TARGET_EVENT_RESET_ASSERT
)) {
1423 target_handle_event(target
, TARGET_EVENT_RESET_ASSERT
);
1424 } else if (jtag_get_reset_config() & RESET_HAS_SRST
) {
1425 /* REVISIT handle "pulls" cases, if there's
1426 * hardware that needs them to work.
1428 jtag_add_reset(0, 1);
1430 LOG_ERROR("%s: how to reset?", target_name(target
));
1434 /* registers are now invalid */
1435 register_cache_invalidate(armv7a
->armv4_5_common
.core_cache
);
1437 target
->state
= TARGET_RESET
;
1442 static int cortex_a9_deassert_reset(struct target
*target
)
1448 /* be certain SRST is off */
1449 jtag_add_reset(0, 0);
1451 retval
= cortex_a9_poll(target
);
1452 if (retval
!= ERROR_OK
)
1455 if (target
->reset_halt
) {
1456 if (target
->state
!= TARGET_HALTED
) {
1457 LOG_WARNING("%s: ran after reset and before halt ...",
1458 target_name(target
));
1459 if ((retval
= target_halt(target
)) != ERROR_OK
)
1468 * Cortex-A9 Memory access
1470 * This is same Cortex M3 but we must also use the correct
1471 * ap number for every access.
1474 static int cortex_a9_read_phys_memory(struct target
*target
,
1475 uint32_t address
, uint32_t size
,
1476 uint32_t count
, uint8_t *buffer
)
1478 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1479 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
1480 int retval
= ERROR_INVALID_ARGUMENTS
;
1481 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
1483 /* cortex_a9 handles unaligned memory access */
1485 dap_ap_select(swjdp
, swjdp_memoryap
);
1487 LOG_DEBUG("Reading memory at real address 0x%x; size %d; count %d", address
, size
, count
);
1488 if (count
&& buffer
) {
1491 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1494 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1497 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1502 dap_ap_select(swjdp
, saved_apsel
);
1507 static int cortex_a9_read_memory(struct target
*target
, uint32_t address
,
1508 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1511 uint32_t virt
, phys
;
1514 /* cortex_a9 handles unaligned memory access */
1516 LOG_DEBUG("Reading memory at address 0x%x; size %d; count %d", address
, size
, count
);
1517 retval
= cortex_a9_mmu(target
, &enabled
);
1518 if (retval
!= ERROR_OK
)
1524 retval
= cortex_a9_virt2phys(target
, virt
, &phys
);
1525 if (retval
!= ERROR_OK
)
1528 LOG_DEBUG("Reading at virtual address. Translating v:0x%x to r:0x%x", virt
, phys
);
1532 return cortex_a9_read_phys_memory(target
, address
, size
, count
, buffer
);
1535 static int cortex_a9_write_phys_memory(struct target
*target
,
1536 uint32_t address
, uint32_t size
,
1537 uint32_t count
, uint8_t *buffer
)
1539 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1540 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
1541 int retval
= ERROR_INVALID_ARGUMENTS
;
1543 LOG_DEBUG("Writing memory to real address 0x%x; size %d; count %d", address
, size
, count
);
1545 if (count
&& buffer
) {
1546 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
1547 dap_ap_select(swjdp
, swjdp_memoryap
);
1551 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1554 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1557 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1561 dap_ap_select(swjdp
, saved_apsel
);
1565 /* REVISIT this op is generic ARMv7-A/R stuff */
1566 if (retval
== ERROR_OK
&& target
->state
== TARGET_HALTED
)
1568 struct arm_dpm
*dpm
= armv7a
->armv4_5_common
.dpm
;
1570 retval
= dpm
->prepare(dpm
);
1571 if (retval
!= ERROR_OK
)
1574 /* The Cache handling will NOT work with MMU active, the
1575 * wrong addresses will be invalidated!
1577 * For both ICache and DCache, walk all cache lines in the
1578 * address range. Cortex-A9 has fixed 64 byte line length.
1580 * REVISIT per ARMv7, these may trigger watchpoints ...
1583 /* invalidate I-Cache */
1584 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
1586 /* ICIMVAU - Invalidate Cache single entry
1588 * MCR p15, 0, r0, c7, c5, 1
1590 for (uint32_t cacheline
= address
;
1591 cacheline
< address
+ size
* count
;
1593 retval
= dpm
->instr_write_data_r0(dpm
,
1594 ARMV4_5_MCR(15, 0, 0, 7, 5, 1),
1596 if (retval
!= ERROR_OK
)
1601 /* invalidate D-Cache */
1602 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
1604 /* DCIMVAC - Invalidate data Cache line
1606 * MCR p15, 0, r0, c7, c6, 1
1608 for (uint32_t cacheline
= address
;
1609 cacheline
< address
+ size
* count
;
1611 retval
= dpm
->instr_write_data_r0(dpm
,
1612 ARMV4_5_MCR(15, 0, 0, 7, 6, 1),
1614 if (retval
!= ERROR_OK
)
1619 /* (void) */ dpm
->finish(dpm
);
1625 static int cortex_a9_write_memory(struct target
*target
, uint32_t address
,
1626 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1629 uint32_t virt
, phys
;
1632 LOG_DEBUG("Writing memory to address 0x%x; size %d; count %d", address
, size
, count
);
1633 retval
= cortex_a9_mmu(target
, &enabled
);
1634 if (retval
!= ERROR_OK
)
1640 retval
= cortex_a9_virt2phys(target
, virt
, &phys
);
1641 if (retval
!= ERROR_OK
)
1643 LOG_DEBUG("Writing to virtual address. Translating v:0x%x to r:0x%x", virt
, phys
);
1647 return cortex_a9_write_phys_memory(target
, address
, size
,
1651 static int cortex_a9_bulk_write_memory(struct target
*target
, uint32_t address
,
1652 uint32_t count
, uint8_t *buffer
)
1654 return cortex_a9_write_memory(target
, address
, 4, count
, buffer
);
1657 static int cortex_a9_dcc_read(struct adiv5_dap
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1662 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1663 *ctrl
= (uint8_t)dcrdr
;
1664 *value
= (uint8_t)(dcrdr
>> 8);
1666 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1668 /* write ack back to software dcc register
1669 * signify we have read data */
1670 if (dcrdr
& (1 << 0))
1673 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1680 static int cortex_a9_handle_target_request(void *priv
)
1682 struct target
*target
= priv
;
1683 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1684 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
1687 if (!target_was_examined(target
))
1689 if (!target
->dbg_msg_enabled
)
1692 if (target
->state
== TARGET_RUNNING
)
1697 retval
= cortex_a9_dcc_read(swjdp
, &data
, &ctrl
);
1698 if (retval
!= ERROR_OK
)
1701 /* check if we have data */
1702 if (ctrl
& (1 << 0))
1706 /* we assume target is quick enough */
1708 retval
= cortex_a9_dcc_read(swjdp
, &data
, &ctrl
);
1709 if (retval
!= ERROR_OK
)
1711 request
|= (data
<< 8);
1712 retval
= cortex_a9_dcc_read(swjdp
, &data
, &ctrl
);
1713 if (retval
!= ERROR_OK
)
1715 request
|= (data
<< 16);
1716 retval
= cortex_a9_dcc_read(swjdp
, &data
, &ctrl
);
1717 if (retval
!= ERROR_OK
)
1719 request
|= (data
<< 24);
1720 target_request(target
, request
);
1728 * Cortex-A9 target information and configuration
1731 static int cortex_a9_examine_first(struct target
*target
)
1733 struct cortex_a9_common
*cortex_a9
= target_to_cortex_a9(target
);
1734 struct armv7a_common
*armv7a
= &cortex_a9
->armv7a_common
;
1735 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
1737 int retval
= ERROR_OK
;
1738 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1740 /* We do one extra read to ensure DAP is configured,
1741 * we call ahbap_debugport_init(swjdp) instead
1743 retval
= ahbap_debugport_init(swjdp
);
1744 if (retval
!= ERROR_OK
)
1747 dap_ap_select(swjdp
, swjdp_debugap
);
1750 * FIXME: assuming omap4430
1752 * APB DBGBASE reads 0x80040000, but this points to an empty ROM table.
1753 * 0x80000000 is cpu0 coresight region
1755 if (target
->coreid
> 3) {
1756 LOG_ERROR("cortex_a9 supports up to 4 cores");
1757 return ERROR_INVALID_ARGUMENTS
;
1759 armv7a
->debug_base
= 0x80000000 |
1760 ((target
->coreid
& 0x3) << CORTEX_A9_PADDRDBG_CPU_SHIFT
);
1762 retval
= mem_ap_read_atomic_u32(swjdp
,
1763 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
1764 if (retval
!= ERROR_OK
)
1767 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1768 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1770 LOG_DEBUG("Examine %s failed", "CPUID");
1774 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1775 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1777 LOG_DEBUG("Examine %s failed", "CTYPR");
1781 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1782 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1784 LOG_DEBUG("Examine %s failed", "TTYPR");
1788 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1789 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1791 LOG_DEBUG("Examine %s failed", "DIDR");
1795 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1796 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1797 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1798 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1800 armv7a
->armv4_5_common
.core_type
= ARM_MODE_MON
;
1801 retval
= cortex_a9_dpm_setup(cortex_a9
, didr
);
1802 if (retval
!= ERROR_OK
)
1805 /* Setup Breakpoint Register Pairs */
1806 cortex_a9
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1807 cortex_a9
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1808 cortex_a9
->brp_num_available
= cortex_a9
->brp_num
;
1809 cortex_a9
->brp_list
= calloc(cortex_a9
->brp_num
, sizeof(struct cortex_a9_brp
));
1810 // cortex_a9->brb_enabled = ????;
1811 for (i
= 0; i
< cortex_a9
->brp_num
; i
++)
1813 cortex_a9
->brp_list
[i
].used
= 0;
1814 if (i
< (cortex_a9
->brp_num
-cortex_a9
->brp_num_context
))
1815 cortex_a9
->brp_list
[i
].type
= BRP_NORMAL
;
1817 cortex_a9
->brp_list
[i
].type
= BRP_CONTEXT
;
1818 cortex_a9
->brp_list
[i
].value
= 0;
1819 cortex_a9
->brp_list
[i
].control
= 0;
1820 cortex_a9
->brp_list
[i
].BRPn
= i
;
1823 LOG_DEBUG("Configured %i hw breakpoints", cortex_a9
->brp_num
);
1825 target_set_examined(target
);
1829 static int cortex_a9_examine(struct target
*target
)
1831 int retval
= ERROR_OK
;
1833 /* don't re-probe hardware after each reset */
1834 if (!target_was_examined(target
))
1835 retval
= cortex_a9_examine_first(target
);
1837 /* Configure core debug access */
1838 if (retval
== ERROR_OK
)
1839 retval
= cortex_a9_init_debug_access(target
);
1845 * Cortex-A9 target creation and initialization
1848 static int cortex_a9_init_target(struct command_context
*cmd_ctx
,
1849 struct target
*target
)
1851 /* examine_first() does a bunch of this */
1855 static int cortex_a9_init_arch_info(struct target
*target
,
1856 struct cortex_a9_common
*cortex_a9
, struct jtag_tap
*tap
)
1858 struct armv7a_common
*armv7a
= &cortex_a9
->armv7a_common
;
1859 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
1860 struct adiv5_dap
*dap
= &armv7a
->dap
;
1862 armv7a
->armv4_5_common
.dap
= dap
;
1864 /* Setup struct cortex_a9_common */
1865 cortex_a9
->common_magic
= CORTEX_A9_COMMON_MAGIC
;
1866 armv4_5
->arch_info
= armv7a
;
1868 /* prepare JTAG information for the new target */
1869 cortex_a9
->jtag_info
.tap
= tap
;
1870 cortex_a9
->jtag_info
.scann_size
= 4;
1872 /* Leave (only) generic DAP stuff for debugport_init() */
1873 dap
->jtag_info
= &cortex_a9
->jtag_info
;
1874 dap
->memaccess_tck
= 80;
1876 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1877 dap
->tar_autoincr_block
= (1 << 10);
1879 cortex_a9
->fast_reg_read
= 0;
1881 /* Set default value */
1882 cortex_a9
->current_address_mode
= ARM_MODE_ANY
;
1884 /* register arch-specific functions */
1885 armv7a
->examine_debug_reason
= NULL
;
1887 armv7a
->post_debug_entry
= cortex_a9_post_debug_entry
;
1889 armv7a
->pre_restore_context
= NULL
;
1890 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1891 armv7a
->armv4_5_mmu
.get_ttb
= cortex_a9_get_ttb
;
1892 armv7a
->armv4_5_mmu
.read_memory
= cortex_a9_read_phys_memory
;
1893 armv7a
->armv4_5_mmu
.write_memory
= cortex_a9_write_phys_memory
;
1894 armv7a
->armv4_5_mmu
.disable_mmu_caches
= cortex_a9_disable_mmu_caches
;
1895 armv7a
->armv4_5_mmu
.enable_mmu_caches
= cortex_a9_enable_mmu_caches
;
1896 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1897 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1900 // arm7_9->handle_target_request = cortex_a9_handle_target_request;
1902 /* REVISIT v7a setup should be in a v7a-specific routine */
1903 arm_init_arch_info(target
, armv4_5
);
1904 armv7a
->common_magic
= ARMV7_COMMON_MAGIC
;
1906 target_register_timer_callback(cortex_a9_handle_target_request
, 1, 1, target
);
1911 static int cortex_a9_target_create(struct target
*target
, Jim_Interp
*interp
)
1913 struct cortex_a9_common
*cortex_a9
= calloc(1, sizeof(struct cortex_a9_common
));
1915 return cortex_a9_init_arch_info(target
, cortex_a9
, target
->tap
);
1918 static int cortex_a9_get_ttb(struct target
*target
, uint32_t *result
)
1920 struct cortex_a9_common
*cortex_a9
= target_to_cortex_a9(target
);
1921 struct armv7a_common
*armv7a
= &cortex_a9
->armv7a_common
;
1922 uint32_t ttb
= 0, retval
= ERROR_OK
;
1924 /* current_address_mode is set inside cortex_a9_virt2phys()
1925 where we can determine if address belongs to user or kernel */
1926 if(cortex_a9
->current_address_mode
== ARM_MODE_SVC
)
1928 /* MRC p15,0,<Rt>,c1,c0,0 ; Read CP15 System Control Register */
1929 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
1930 0, 1, /* op1, op2 */
1931 2, 0, /* CRn, CRm */
1933 if (retval
!= ERROR_OK
)
1936 else if(cortex_a9
->current_address_mode
== ARM_MODE_USR
)
1938 /* MRC p15,0,<Rt>,c1,c0,0 ; Read CP15 System Control Register */
1939 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
1940 0, 0, /* op1, op2 */
1941 2, 0, /* CRn, CRm */
1943 if (retval
!= ERROR_OK
)
1946 /* we don't know whose address is: user or kernel
1947 we assume that if we are in kernel mode then
1948 address belongs to kernel else if in user mode
1950 else if(armv7a
->armv4_5_common
.core_mode
== ARM_MODE_SVC
)
1952 /* MRC p15,0,<Rt>,c1,c0,0 ; Read CP15 System Control Register */
1953 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
1954 0, 1, /* op1, op2 */
1955 2, 0, /* CRn, CRm */
1957 if (retval
!= ERROR_OK
)
1960 else if(armv7a
->armv4_5_common
.core_mode
== ARM_MODE_USR
)
1962 /* MRC p15,0,<Rt>,c1,c0,0 ; Read CP15 System Control Register */
1963 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
1964 0, 0, /* op1, op2 */
1965 2, 0, /* CRn, CRm */
1967 if (retval
!= ERROR_OK
)
1970 /* finally we don't know whose ttb to use: user or kernel */
1972 LOG_ERROR("Don't know how to get ttb for current mode!!!");
1981 static int cortex_a9_disable_mmu_caches(struct target
*target
, int mmu
,
1982 int d_u_cache
, int i_cache
)
1984 struct cortex_a9_common
*cortex_a9
= target_to_cortex_a9(target
);
1985 struct armv7a_common
*armv7a
= &cortex_a9
->armv7a_common
;
1986 uint32_t cp15_control
;
1989 /* read cp15 control register */
1990 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
1991 0, 0, /* op1, op2 */
1992 1, 0, /* CRn, CRm */
1994 if (retval
!= ERROR_OK
)
1999 cp15_control
&= ~0x1U
;
2002 cp15_control
&= ~0x4U
;
2005 cp15_control
&= ~0x1000U
;
2007 retval
= armv7a
->armv4_5_common
.mcr(target
, 15,
2008 0, 0, /* op1, op2 */
2009 1, 0, /* CRn, CRm */
2014 static int cortex_a9_enable_mmu_caches(struct target
*target
, int mmu
,
2015 int d_u_cache
, int i_cache
)
2017 struct cortex_a9_common
*cortex_a9
= target_to_cortex_a9(target
);
2018 struct armv7a_common
*armv7a
= &cortex_a9
->armv7a_common
;
2019 uint32_t cp15_control
;
2022 /* read cp15 control register */
2023 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
2024 0, 0, /* op1, op2 */
2025 1, 0, /* CRn, CRm */
2027 if (retval
!= ERROR_OK
)
2031 cp15_control
|= 0x1U
;
2034 cp15_control
|= 0x4U
;
2037 cp15_control
|= 0x1000U
;
2039 retval
= armv7a
->armv4_5_common
.mcr(target
, 15,
2040 0, 0, /* op1, op2 */
2041 1, 0, /* CRn, CRm */
2047 static int cortex_a9_mmu(struct target
*target
, int *enabled
)
2049 if (target
->state
!= TARGET_HALTED
) {
2050 LOG_ERROR("%s: target not halted", __func__
);
2051 return ERROR_TARGET_INVALID
;
2054 *enabled
= target_to_cortex_a9(target
)->armv7a_common
.armv4_5_mmu
.mmu_enabled
;
2058 static int cortex_a9_virt2phys(struct target
*target
,
2059 uint32_t virt
, uint32_t *phys
)
2062 struct cortex_a9_common
*cortex_a9
= target_to_cortex_a9(target
);
2063 // struct armv7a_common *armv7a = &cortex_a9->armv7a_common;
2064 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
2066 /* We assume that virtual address is separated
2067 between user and kernel in Linux style:
2068 0x00000000-0xbfffffff - User space
2069 0xc0000000-0xffffffff - Kernel space */
2070 if( virt
< 0xc0000000 ) /* Linux user space */
2071 cortex_a9
->current_address_mode
= ARM_MODE_USR
;
2072 else /* Linux kernel */
2073 cortex_a9
->current_address_mode
= ARM_MODE_SVC
;
2075 int retval
= armv4_5_mmu_translate_va(target
,
2076 &armv7a
->armv4_5_mmu
, virt
, &cb
, &ret
);
2077 if (retval
!= ERROR_OK
)
2079 /* Reset the flag. We don't want someone else to use it by error */
2080 cortex_a9
->current_address_mode
= ARM_MODE_ANY
;
2086 COMMAND_HANDLER(cortex_a9_handle_cache_info_command
)
2088 struct target
*target
= get_current_target(CMD_CTX
);
2089 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
2091 return armv4_5_handle_cache_info_command(CMD_CTX
,
2092 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
2096 COMMAND_HANDLER(cortex_a9_handle_dbginit_command
)
2098 struct target
*target
= get_current_target(CMD_CTX
);
2099 if (!target_was_examined(target
))
2101 LOG_ERROR("target not examined yet");
2105 return cortex_a9_init_debug_access(target
);
2108 static const struct command_registration cortex_a9_exec_command_handlers
[] = {
2110 .name
= "cache_info",
2111 .handler
= cortex_a9_handle_cache_info_command
,
2112 .mode
= COMMAND_EXEC
,
2113 .help
= "display information about target caches",
2117 .handler
= cortex_a9_handle_dbginit_command
,
2118 .mode
= COMMAND_EXEC
,
2119 .help
= "Initialize core debug",
2121 COMMAND_REGISTRATION_DONE
2123 static const struct command_registration cortex_a9_command_handlers
[] = {
2125 .chain
= arm_command_handlers
,
2128 .chain
= armv7a_command_handlers
,
2131 .name
= "cortex_a9",
2132 .mode
= COMMAND_ANY
,
2133 .help
= "Cortex-A9 command group",
2134 .chain
= cortex_a9_exec_command_handlers
,
2136 COMMAND_REGISTRATION_DONE
2139 struct target_type cortexa9_target
= {
2140 .name
= "cortex_a9",
2142 .poll
= cortex_a9_poll
,
2143 .arch_state
= armv7a_arch_state
,
2145 .target_request_data
= NULL
,
2147 .halt
= cortex_a9_halt
,
2148 .resume
= cortex_a9_resume
,
2149 .step
= cortex_a9_step
,
2151 .assert_reset
= cortex_a9_assert_reset
,
2152 .deassert_reset
= cortex_a9_deassert_reset
,
2153 .soft_reset_halt
= NULL
,
2155 /* REVISIT allow exporting VFP3 registers ... */
2156 .get_gdb_reg_list
= arm_get_gdb_reg_list
,
2158 .read_memory
= cortex_a9_read_memory
,
2159 .write_memory
= cortex_a9_write_memory
,
2160 .bulk_write_memory
= cortex_a9_bulk_write_memory
,
2162 .checksum_memory
= arm_checksum_memory
,
2163 .blank_check_memory
= arm_blank_check_memory
,
2165 .run_algorithm
= armv4_5_run_algorithm
,
2167 .add_breakpoint
= cortex_a9_add_breakpoint
,
2168 .remove_breakpoint
= cortex_a9_remove_breakpoint
,
2169 .add_watchpoint
= NULL
,
2170 .remove_watchpoint
= NULL
,
2172 .commands
= cortex_a9_command_handlers
,
2173 .target_create
= cortex_a9_target_create
,
2174 .init_target
= cortex_a9_init_target
,
2175 .examine
= cortex_a9_examine
,
2177 .read_phys_memory
= cortex_a9_read_phys_memory
,
2178 .write_phys_memory
= cortex_a9_write_phys_memory
,
2179 .mmu
= cortex_a9_mmu
,
2180 .virt2phys
= cortex_a9_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)