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 cortex_a8_dap_read_coreregister_u32(target
, regfile
, 0);
184 cortex_a8_dap_write_coreregister_u32(target
, address
, 0);
185 cortex_a8_exec_opcode(target
, ARMV4_5_STMIA(0, 0xFFFE, 0, 0), NULL
);
186 dap_ap_select(swjdp
, swjdp_memoryap
);
187 mem_ap_read_buf_u32(swjdp
, (uint8_t *)(®file
[1]), 4*15, address
);
188 dap_ap_select(swjdp
, swjdp_debugap
);
193 static int cortex_a8_dap_read_coreregister_u32(struct target
*target
,
194 uint32_t *value
, int regnum
)
196 int retval
= ERROR_OK
;
197 uint8_t reg
= regnum
&0xFF;
199 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
200 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
207 /* Rn to DCCTX, "MCR p14, 0, Rn, c0, c5, 0" 0xEE00nE15 */
208 cortex_a8_exec_opcode(target
,
209 ARMV4_5_MCR(14, 0, reg
, 0, 5, 0),
214 /* "MOV r0, r15"; then move r0 to DCCTX */
215 cortex_a8_exec_opcode(target
, 0xE1A0000F, &dscr
);
216 cortex_a8_exec_opcode(target
,
217 ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
222 /* "MRS r0, CPSR" or "MRS r0, SPSR"
223 * then move r0 to DCCTX
225 cortex_a8_exec_opcode(target
, ARMV4_5_MRS(0, reg
& 1), &dscr
);
226 cortex_a8_exec_opcode(target
,
227 ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
231 /* Wait for DTRRXfull then read DTRRTX */
232 while ((dscr
& DSCR_DTR_TX_FULL
) == 0)
234 retval
= mem_ap_read_atomic_u32(swjdp
,
235 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
236 if (retval
!= ERROR_OK
)
240 retval
= mem_ap_read_atomic_u32(swjdp
,
241 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
242 LOG_DEBUG("read DCC 0x%08" PRIx32
, *value
);
247 static int cortex_a8_dap_write_coreregister_u32(struct target
*target
,
248 uint32_t value
, int regnum
)
250 int retval
= ERROR_OK
;
251 uint8_t Rd
= regnum
&0xFF;
253 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
254 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
256 LOG_DEBUG("register %i, value 0x%08" PRIx32
, regnum
, value
);
258 /* Check that DCCRX is not full */
259 retval
= mem_ap_read_atomic_u32(swjdp
,
260 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
261 if (retval
!= ERROR_OK
)
263 if (dscr
& DSCR_DTR_RX_FULL
)
265 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
266 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
267 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
274 /* Write DTRRX ... sets DSCR.DTRRXfull but exec_opcode() won't care */
275 LOG_DEBUG("write DCC 0x%08" PRIx32
, value
);
276 retval
= mem_ap_write_u32(swjdp
,
277 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
278 if (retval
!= ERROR_OK
)
283 /* DCCRX to Rn, "MCR p14, 0, Rn, c0, c5, 0", 0xEE00nE15 */
284 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, Rd
, 0, 5, 0),
289 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15
292 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
294 cortex_a8_exec_opcode(target
, 0xE1A0F000, &dscr
);
298 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15
299 * then "MSR CPSR_cxsf, r0" or "MSR SPSR_cxsf, r0" (all fields)
301 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
303 cortex_a8_exec_opcode(target
, ARMV4_5_MSR_GP(0, 0xF, Rd
& 1),
306 /* "Prefetch flush" after modifying execution status in CPSR */
308 cortex_a8_exec_opcode(target
,
309 ARMV4_5_MCR(15, 0, 0, 7, 5, 4),
316 /* Write to memory mapped registers directly with no cache or mmu handling */
317 static int cortex_a8_dap_write_memap_register_u32(struct target
*target
, uint32_t address
, uint32_t value
)
320 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
321 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
323 retval
= mem_ap_write_atomic_u32(swjdp
, address
, value
);
329 * Cortex-A8 implementation of Debug Programmer's Model
331 * NOTE the invariant: these routines return with DSCR_INSTR_COMP set,
332 * so there's no need to poll for it before executing an instruction.
334 * NOTE that in several of these cases the "stall" mode might be useful.
335 * It'd let us queue a few operations together... prepare/finish might
336 * be the places to enable/disable that mode.
339 static inline struct cortex_a8_common
*dpm_to_a8(struct arm_dpm
*dpm
)
341 return container_of(dpm
, struct cortex_a8_common
, armv7a_common
.dpm
);
344 static int cortex_a8_write_dcc(struct cortex_a8_common
*a8
, uint32_t data
)
346 LOG_DEBUG("write DCC 0x%08" PRIx32
, data
);
347 return mem_ap_write_u32(&a8
->armv7a_common
.dap
,
348 a8
->armv7a_common
.debug_base
+ CPUDBG_DTRRX
, data
);
351 static int cortex_a8_read_dcc(struct cortex_a8_common
*a8
, uint32_t *data
,
354 struct adiv5_dap
*swjdp
= &a8
->armv7a_common
.dap
;
355 uint32_t dscr
= DSCR_INSTR_COMP
;
361 /* Wait for DTRRXfull */
362 while ((dscr
& DSCR_DTR_TX_FULL
) == 0) {
363 retval
= mem_ap_read_atomic_u32(swjdp
,
364 a8
->armv7a_common
.debug_base
+ CPUDBG_DSCR
,
366 if (retval
!= ERROR_OK
)
370 retval
= mem_ap_read_atomic_u32(swjdp
,
371 a8
->armv7a_common
.debug_base
+ CPUDBG_DTRTX
, data
);
372 if (retval
!= ERROR_OK
)
374 //LOG_DEBUG("read DCC 0x%08" PRIx32, *data);
382 static int cortex_a8_dpm_prepare(struct arm_dpm
*dpm
)
384 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
385 struct adiv5_dap
*swjdp
= &a8
->armv7a_common
.dap
;
389 /* set up invariant: INSTR_COMP is set after ever DPM operation */
390 long long then
= timeval_ms();
393 retval
= mem_ap_read_atomic_u32(swjdp
,
394 a8
->armv7a_common
.debug_base
+ CPUDBG_DSCR
,
396 if (retval
!= ERROR_OK
)
398 if ((dscr
& DSCR_INSTR_COMP
) != 0)
400 if (timeval_ms() > then
+ 1000)
402 LOG_ERROR("Timeout waiting for dpm prepare");
407 /* this "should never happen" ... */
408 if (dscr
& DSCR_DTR_RX_FULL
) {
409 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
411 retval
= cortex_a8_exec_opcode(
412 a8
->armv7a_common
.armv4_5_common
.target
,
413 ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
420 static int cortex_a8_dpm_finish(struct arm_dpm
*dpm
)
422 /* REVISIT what could be done here? */
426 static int cortex_a8_instr_write_data_dcc(struct arm_dpm
*dpm
,
427 uint32_t opcode
, uint32_t data
)
429 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
431 uint32_t dscr
= DSCR_INSTR_COMP
;
433 retval
= cortex_a8_write_dcc(a8
, data
);
435 return cortex_a8_exec_opcode(
436 a8
->armv7a_common
.armv4_5_common
.target
,
441 static int cortex_a8_instr_write_data_r0(struct arm_dpm
*dpm
,
442 uint32_t opcode
, uint32_t data
)
444 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
445 uint32_t dscr
= DSCR_INSTR_COMP
;
448 retval
= cortex_a8_write_dcc(a8
, data
);
450 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15 */
451 retval
= cortex_a8_exec_opcode(
452 a8
->armv7a_common
.armv4_5_common
.target
,
453 ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
456 /* then the opcode, taking data from R0 */
457 retval
= cortex_a8_exec_opcode(
458 a8
->armv7a_common
.armv4_5_common
.target
,
465 static int cortex_a8_instr_cpsr_sync(struct arm_dpm
*dpm
)
467 struct target
*target
= dpm
->arm
->target
;
468 uint32_t dscr
= DSCR_INSTR_COMP
;
470 /* "Prefetch flush" after modifying execution status in CPSR */
471 return cortex_a8_exec_opcode(target
,
472 ARMV4_5_MCR(15, 0, 0, 7, 5, 4),
476 static int cortex_a8_instr_read_data_dcc(struct arm_dpm
*dpm
,
477 uint32_t opcode
, uint32_t *data
)
479 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
481 uint32_t dscr
= DSCR_INSTR_COMP
;
483 /* the opcode, writing data to DCC */
484 retval
= cortex_a8_exec_opcode(
485 a8
->armv7a_common
.armv4_5_common
.target
,
489 return cortex_a8_read_dcc(a8
, data
, &dscr
);
493 static int cortex_a8_instr_read_data_r0(struct arm_dpm
*dpm
,
494 uint32_t opcode
, uint32_t *data
)
496 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
497 uint32_t dscr
= DSCR_INSTR_COMP
;
500 /* the opcode, writing data to R0 */
501 retval
= cortex_a8_exec_opcode(
502 a8
->armv7a_common
.armv4_5_common
.target
,
506 /* write R0 to DCC */
507 retval
= cortex_a8_exec_opcode(
508 a8
->armv7a_common
.armv4_5_common
.target
,
509 ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
512 return cortex_a8_read_dcc(a8
, data
, &dscr
);
515 static int cortex_a8_bpwp_enable(struct arm_dpm
*dpm
, unsigned index_t
,
516 uint32_t addr
, uint32_t control
)
518 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
519 uint32_t vr
= a8
->armv7a_common
.debug_base
;
520 uint32_t cr
= a8
->armv7a_common
.debug_base
;
524 case 0 ... 15: /* breakpoints */
525 vr
+= CPUDBG_BVR_BASE
;
526 cr
+= CPUDBG_BCR_BASE
;
528 case 16 ... 31: /* watchpoints */
529 vr
+= CPUDBG_WVR_BASE
;
530 cr
+= CPUDBG_WCR_BASE
;
539 LOG_DEBUG("A8: bpwp enable, vr %08x cr %08x",
540 (unsigned) vr
, (unsigned) cr
);
542 retval
= cortex_a8_dap_write_memap_register_u32(dpm
->arm
->target
,
544 if (retval
!= ERROR_OK
)
546 retval
= cortex_a8_dap_write_memap_register_u32(dpm
->arm
->target
,
551 static int cortex_a8_bpwp_disable(struct arm_dpm
*dpm
, unsigned index_t
)
553 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
558 cr
= a8
->armv7a_common
.debug_base
+ CPUDBG_BCR_BASE
;
561 cr
= a8
->armv7a_common
.debug_base
+ CPUDBG_WCR_BASE
;
569 LOG_DEBUG("A8: bpwp disable, cr %08x", (unsigned) cr
);
571 /* clear control register */
572 return cortex_a8_dap_write_memap_register_u32(dpm
->arm
->target
, cr
, 0);
575 static int cortex_a8_dpm_setup(struct cortex_a8_common
*a8
, uint32_t didr
)
577 struct arm_dpm
*dpm
= &a8
->armv7a_common
.dpm
;
580 dpm
->arm
= &a8
->armv7a_common
.armv4_5_common
;
583 dpm
->prepare
= cortex_a8_dpm_prepare
;
584 dpm
->finish
= cortex_a8_dpm_finish
;
586 dpm
->instr_write_data_dcc
= cortex_a8_instr_write_data_dcc
;
587 dpm
->instr_write_data_r0
= cortex_a8_instr_write_data_r0
;
588 dpm
->instr_cpsr_sync
= cortex_a8_instr_cpsr_sync
;
590 dpm
->instr_read_data_dcc
= cortex_a8_instr_read_data_dcc
;
591 dpm
->instr_read_data_r0
= cortex_a8_instr_read_data_r0
;
593 dpm
->bpwp_enable
= cortex_a8_bpwp_enable
;
594 dpm
->bpwp_disable
= cortex_a8_bpwp_disable
;
596 retval
= arm_dpm_setup(dpm
);
597 if (retval
== ERROR_OK
)
598 retval
= arm_dpm_initialize(dpm
);
605 * Cortex-A8 Run control
608 static int cortex_a8_poll(struct target
*target
)
610 int retval
= ERROR_OK
;
612 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
613 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
614 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
615 enum target_state prev_target_state
= target
->state
;
616 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
618 dap_ap_select(swjdp
, swjdp_debugap
);
619 retval
= mem_ap_read_atomic_u32(swjdp
,
620 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
621 if (retval
!= ERROR_OK
)
623 dap_ap_select(swjdp
, saved_apsel
);
626 cortex_a8
->cpudbg_dscr
= dscr
;
628 if ((dscr
& 0x3) == 0x3)
630 if (prev_target_state
!= TARGET_HALTED
)
632 /* We have a halting debug event */
633 LOG_DEBUG("Target halted");
634 target
->state
= TARGET_HALTED
;
635 if ((prev_target_state
== TARGET_RUNNING
)
636 || (prev_target_state
== TARGET_RESET
))
638 retval
= cortex_a8_debug_entry(target
);
639 if (retval
!= ERROR_OK
)
642 target_call_event_callbacks(target
,
643 TARGET_EVENT_HALTED
);
645 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
649 retval
= cortex_a8_debug_entry(target
);
650 if (retval
!= ERROR_OK
)
653 target_call_event_callbacks(target
,
654 TARGET_EVENT_DEBUG_HALTED
);
658 else if ((dscr
& 0x3) == 0x2)
660 target
->state
= TARGET_RUNNING
;
664 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32
, dscr
);
665 target
->state
= TARGET_UNKNOWN
;
668 dap_ap_select(swjdp
, saved_apsel
);
673 static int cortex_a8_halt(struct target
*target
)
675 int retval
= ERROR_OK
;
677 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
678 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
679 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
680 dap_ap_select(swjdp
, swjdp_debugap
);
683 * Tell the core to be halted by writing DRCR with 0x1
684 * and then wait for the core to be halted.
686 retval
= mem_ap_write_atomic_u32(swjdp
,
687 armv7a
->debug_base
+ CPUDBG_DRCR
, 0x1);
688 if (retval
!= ERROR_OK
)
692 * enter halting debug mode
694 retval
= mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
695 if (retval
!= ERROR_OK
)
698 retval
= mem_ap_write_atomic_u32(swjdp
,
699 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
| DSCR_HALT_DBG_MODE
);
700 if (retval
!= ERROR_OK
)
703 long long then
= timeval_ms();
706 retval
= mem_ap_read_atomic_u32(swjdp
,
707 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
708 if (retval
!= ERROR_OK
)
710 if ((dscr
& DSCR_CORE_HALTED
) != 0)
714 if (timeval_ms() > then
+ 1000)
716 LOG_ERROR("Timeout waiting for halt");
721 target
->debug_reason
= DBG_REASON_DBGRQ
;
724 dap_ap_select(swjdp
, saved_apsel
);
728 static int cortex_a8_resume(struct target
*target
, int current
,
729 uint32_t address
, int handle_breakpoints
, int debug_execution
)
731 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
732 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
733 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
736 // struct breakpoint *breakpoint = NULL;
737 uint32_t resume_pc
, dscr
;
739 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
740 dap_ap_select(swjdp
, swjdp_debugap
);
742 if (!debug_execution
)
743 target_free_all_working_areas(target
);
748 /* Disable interrupts */
749 /* We disable interrupts in the PRIMASK register instead of
750 * masking with C_MASKINTS,
751 * This is probably the same issue as Cortex-M3 Errata 377493:
752 * C_MASKINTS in parallel with disabled interrupts can cause
753 * local faults to not be taken. */
754 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
755 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
756 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
758 /* Make sure we are in Thumb mode */
759 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
760 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
761 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
762 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
766 /* current = 1: continue on current pc, otherwise continue at <address> */
767 resume_pc
= buf_get_u32(armv4_5
->pc
->value
, 0, 32);
771 /* Make sure that the Armv7 gdb thumb fixups does not
772 * kill the return address
774 switch (armv4_5
->core_state
)
777 resume_pc
&= 0xFFFFFFFC;
779 case ARM_STATE_THUMB
:
780 case ARM_STATE_THUMB_EE
:
781 /* When the return address is loaded into PC
782 * bit 0 must be 1 to stay in Thumb state
786 case ARM_STATE_JAZELLE
:
787 LOG_ERROR("How do I resume into Jazelle state??");
790 LOG_DEBUG("resume pc = 0x%08" PRIx32
, resume_pc
);
791 buf_set_u32(armv4_5
->pc
->value
, 0, 32, resume_pc
);
792 armv4_5
->pc
->dirty
= 1;
793 armv4_5
->pc
->valid
= 1;
795 cortex_a8_restore_context(target
, handle_breakpoints
);
798 /* the front-end may request us not to handle breakpoints */
799 if (handle_breakpoints
)
801 /* Single step past breakpoint at current address */
802 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
804 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
805 cortex_m3_unset_breakpoint(target
, breakpoint
);
806 cortex_m3_single_step_core(target
);
807 cortex_m3_set_breakpoint(target
, breakpoint
);
812 /* Restart core and wait for it to be started
813 * NOTE: this clears DSCR_ITR_EN and other bits.
815 * REVISIT: for single stepping, we probably want to
816 * disable IRQs by default, with optional override...
818 retval
= mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DRCR
, 0x2);
819 if (retval
!= ERROR_OK
)
822 long long then
= timeval_ms();
825 retval
= mem_ap_read_atomic_u32(swjdp
,
826 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
827 if (retval
!= ERROR_OK
)
829 if ((dscr
& DSCR_CORE_RESTARTED
) != 0)
831 if (timeval_ms() > then
+ 1000)
833 LOG_ERROR("Timeout waiting for resume");
838 target
->debug_reason
= DBG_REASON_NOTHALTED
;
839 target
->state
= TARGET_RUNNING
;
841 /* registers are now invalid */
842 register_cache_invalidate(armv4_5
->core_cache
);
844 if (!debug_execution
)
846 target
->state
= TARGET_RUNNING
;
847 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
848 LOG_DEBUG("target resumed at 0x%" PRIx32
, resume_pc
);
852 target
->state
= TARGET_DEBUG_RUNNING
;
853 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
854 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, resume_pc
);
857 dap_ap_select(swjdp
, saved_apsel
);
862 static int cortex_a8_debug_entry(struct target
*target
)
865 uint32_t regfile
[16], cpsr
, dscr
;
866 int retval
= ERROR_OK
;
867 struct working_area
*regfile_working_area
= NULL
;
868 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
869 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
870 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
871 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
874 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
876 /* REVISIT surely we should not re-read DSCR !! */
877 retval
= mem_ap_read_atomic_u32(swjdp
,
878 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
879 if (retval
!= ERROR_OK
)
882 /* REVISIT see A8 TRM 12.11.4 steps 2..3 -- make sure that any
883 * imprecise data aborts get discarded by issuing a Data
884 * Synchronization Barrier: ARMV4_5_MCR(15, 0, 0, 7, 10, 4).
887 /* Enable the ITR execution once we are in debug mode */
889 retval
= mem_ap_write_atomic_u32(swjdp
,
890 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
);
891 if (retval
!= ERROR_OK
)
894 /* Examine debug reason */
895 arm_dpm_report_dscr(&armv7a
->dpm
, cortex_a8
->cpudbg_dscr
);
897 /* save address of instruction that triggered the watchpoint? */
898 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
) {
901 retval
= mem_ap_read_atomic_u32(swjdp
,
902 armv7a
->debug_base
+ CPUDBG_WFAR
,
904 if (retval
!= ERROR_OK
)
906 arm_dpm_report_wfar(&armv7a
->dpm
, wfar
);
909 /* REVISIT fast_reg_read is never set ... */
911 /* Examine target state and mode */
912 if (cortex_a8
->fast_reg_read
)
913 target_alloc_working_area(target
, 64, ®file_working_area
);
915 /* First load register acessible through core debug port*/
916 if (!regfile_working_area
)
918 retval
= arm_dpm_read_current_registers(&armv7a
->dpm
);
922 dap_ap_select(swjdp
, swjdp_memoryap
);
923 cortex_a8_read_regs_through_mem(target
,
924 regfile_working_area
->address
, regfile
);
925 dap_ap_select(swjdp
, swjdp_memoryap
);
926 target_free_working_area(target
, regfile_working_area
);
928 /* read Current PSR */
929 cortex_a8_dap_read_coreregister_u32(target
, &cpsr
, 16);
930 dap_ap_select(swjdp
, swjdp_debugap
);
931 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
933 arm_set_cpsr(armv4_5
, cpsr
);
936 for (i
= 0; i
<= ARM_PC
; i
++)
938 reg
= arm_reg_current(armv4_5
, i
);
940 buf_set_u32(reg
->value
, 0, 32, regfile
[i
]);
945 /* Fixup PC Resume Address */
948 // T bit set for Thumb or ThumbEE state
949 regfile
[ARM_PC
] -= 4;
954 regfile
[ARM_PC
] -= 8;
958 buf_set_u32(reg
->value
, 0, 32, regfile
[ARM_PC
]);
959 reg
->dirty
= reg
->valid
;
963 /* TODO, Move this */
964 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
965 cortex_a8_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
966 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
968 cortex_a8_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
969 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
971 cortex_a8_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
972 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
975 /* Are we in an exception handler */
976 // armv4_5->exception_number = 0;
977 if (armv7a
->post_debug_entry
)
978 armv7a
->post_debug_entry(target
);
983 static void cortex_a8_post_debug_entry(struct target
*target
)
985 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
986 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
989 /* MRC p15,0,<Rt>,c1,c0,0 ; Read CP15 System Control Register */
990 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
993 &cortex_a8
->cp15_control_reg
);
994 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
996 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
998 uint32_t cache_type_reg
;
1000 /* MRC p15,0,<Rt>,c0,c0,1 ; Read CP15 Cache Type Register */
1001 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
1002 0, 1, /* op1, op2 */
1003 0, 0, /* CRn, CRm */
1005 LOG_DEBUG("cp15 cache type: %8.8x", (unsigned) cache_type_reg
);
1007 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
1008 armv4_5_identify_cache(cache_type_reg
,
1009 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1012 armv7a
->armv4_5_mmu
.mmu_enabled
=
1013 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
1014 armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
=
1015 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
1016 armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
=
1017 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
1022 static int cortex_a8_step(struct target
*target
, int current
, uint32_t address
,
1023 int handle_breakpoints
)
1025 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1026 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
1027 struct breakpoint
*breakpoint
= NULL
;
1028 struct breakpoint stepbreakpoint
;
1034 if (target
->state
!= TARGET_HALTED
)
1036 LOG_WARNING("target not halted");
1037 return ERROR_TARGET_NOT_HALTED
;
1040 /* current = 1: continue on current pc, otherwise continue at <address> */
1044 buf_set_u32(r
->value
, 0, 32, address
);
1048 address
= buf_get_u32(r
->value
, 0, 32);
1051 /* The front-end may request us not to handle breakpoints.
1052 * But since Cortex-A8 uses breakpoint for single step,
1053 * we MUST handle breakpoints.
1055 handle_breakpoints
= 1;
1056 if (handle_breakpoints
) {
1057 breakpoint
= breakpoint_find(target
, address
);
1059 cortex_a8_unset_breakpoint(target
, breakpoint
);
1062 /* Setup single step breakpoint */
1063 stepbreakpoint
.address
= address
;
1064 stepbreakpoint
.length
= (armv4_5
->core_state
== ARM_STATE_THUMB
)
1066 stepbreakpoint
.type
= BKPT_HARD
;
1067 stepbreakpoint
.set
= 0;
1069 /* Break on IVA mismatch */
1070 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
1072 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1074 retval
= cortex_a8_resume(target
, 1, address
, 0, 0);
1075 if (retval
!= ERROR_OK
)
1078 while (target
->state
!= TARGET_HALTED
)
1080 retval
= cortex_a8_poll(target
);
1081 if (retval
!= ERROR_OK
)
1085 LOG_ERROR("timeout waiting for target halt");
1090 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
1092 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1095 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
1097 if (target
->state
!= TARGET_HALTED
)
1098 LOG_DEBUG("target stepped");
1103 static int cortex_a8_restore_context(struct target
*target
, bool bpwp
)
1105 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1109 if (armv7a
->pre_restore_context
)
1110 armv7a
->pre_restore_context(target
);
1112 arm_dpm_write_dirty_registers(&armv7a
->dpm
, bpwp
);
1119 * Cortex-A8 Breakpoint and watchpoint functions
1122 /* Setup hardware Breakpoint Register Pair */
1123 static int cortex_a8_set_breakpoint(struct target
*target
,
1124 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1129 uint8_t byte_addr_select
= 0x0F;
1130 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1131 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1132 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1134 if (breakpoint
->set
)
1136 LOG_WARNING("breakpoint already set");
1140 if (breakpoint
->type
== BKPT_HARD
)
1142 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
1144 if (brp_i
>= cortex_a8
->brp_num
)
1146 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1149 breakpoint
->set
= brp_i
+ 1;
1150 if (breakpoint
->length
== 2)
1152 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1154 control
= ((matchmode
& 0x7) << 20)
1155 | (byte_addr_select
<< 5)
1157 brp_list
[brp_i
].used
= 1;
1158 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1159 brp_list
[brp_i
].control
= control
;
1160 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1161 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1162 brp_list
[brp_i
].value
);
1163 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1164 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1165 brp_list
[brp_i
].control
);
1166 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1167 brp_list
[brp_i
].control
,
1168 brp_list
[brp_i
].value
);
1170 else if (breakpoint
->type
== BKPT_SOFT
)
1173 if (breakpoint
->length
== 2)
1175 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1179 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1181 retval
= target
->type
->read_memory(target
,
1182 breakpoint
->address
& 0xFFFFFFFE,
1183 breakpoint
->length
, 1,
1184 breakpoint
->orig_instr
);
1185 if (retval
!= ERROR_OK
)
1187 retval
= target
->type
->write_memory(target
,
1188 breakpoint
->address
& 0xFFFFFFFE,
1189 breakpoint
->length
, 1, code
);
1190 if (retval
!= ERROR_OK
)
1192 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1198 static int cortex_a8_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1201 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1202 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1203 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1205 if (!breakpoint
->set
)
1207 LOG_WARNING("breakpoint not set");
1211 if (breakpoint
->type
== BKPT_HARD
)
1213 int brp_i
= breakpoint
->set
- 1;
1214 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1216 LOG_DEBUG("Invalid BRP number in breakpoint");
1219 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1220 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1221 brp_list
[brp_i
].used
= 0;
1222 brp_list
[brp_i
].value
= 0;
1223 brp_list
[brp_i
].control
= 0;
1224 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1225 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1226 brp_list
[brp_i
].control
);
1227 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1228 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1229 brp_list
[brp_i
].value
);
1233 /* restore original instruction (kept in target endianness) */
1234 if (breakpoint
->length
== 4)
1236 retval
= target
->type
->write_memory(target
,
1237 breakpoint
->address
& 0xFFFFFFFE,
1238 4, 1, breakpoint
->orig_instr
);
1239 if (retval
!= ERROR_OK
)
1244 retval
= target
->type
->write_memory(target
,
1245 breakpoint
->address
& 0xFFFFFFFE,
1246 2, 1, breakpoint
->orig_instr
);
1247 if (retval
!= ERROR_OK
)
1251 breakpoint
->set
= 0;
1256 static int cortex_a8_add_breakpoint(struct target
*target
,
1257 struct breakpoint
*breakpoint
)
1259 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1261 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1263 LOG_INFO("no hardware breakpoint available");
1264 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1267 if (breakpoint
->type
== BKPT_HARD
)
1268 cortex_a8
->brp_num_available
--;
1269 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1274 static int cortex_a8_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1276 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1279 /* It is perfectly possible to remove breakpoints while the target is running */
1280 if (target
->state
!= TARGET_HALTED
)
1282 LOG_WARNING("target not halted");
1283 return ERROR_TARGET_NOT_HALTED
;
1287 if (breakpoint
->set
)
1289 cortex_a8_unset_breakpoint(target
, breakpoint
);
1290 if (breakpoint
->type
== BKPT_HARD
)
1291 cortex_a8
->brp_num_available
++ ;
1301 * Cortex-A8 Reset functions
1304 static int cortex_a8_assert_reset(struct target
*target
)
1306 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1310 /* FIXME when halt is requested, make it work somehow... */
1312 /* Issue some kind of warm reset. */
1313 if (target_has_event_action(target
, TARGET_EVENT_RESET_ASSERT
)) {
1314 target_handle_event(target
, TARGET_EVENT_RESET_ASSERT
);
1315 } else if (jtag_get_reset_config() & RESET_HAS_SRST
) {
1316 /* REVISIT handle "pulls" cases, if there's
1317 * hardware that needs them to work.
1319 jtag_add_reset(0, 1);
1321 LOG_ERROR("%s: how to reset?", target_name(target
));
1325 /* registers are now invalid */
1326 register_cache_invalidate(armv7a
->armv4_5_common
.core_cache
);
1328 target
->state
= TARGET_RESET
;
1333 static int cortex_a8_deassert_reset(struct target
*target
)
1339 /* be certain SRST is off */
1340 jtag_add_reset(0, 0);
1342 retval
= cortex_a8_poll(target
);
1343 if (retval
!= ERROR_OK
)
1346 if (target
->reset_halt
) {
1347 if (target
->state
!= TARGET_HALTED
) {
1348 LOG_WARNING("%s: ran after reset and before halt ...",
1349 target_name(target
));
1350 if ((retval
= target_halt(target
)) != ERROR_OK
)
1359 * Cortex-A8 Memory access
1361 * This is same Cortex M3 but we must also use the correct
1362 * ap number for every access.
1365 static int cortex_a8_read_phys_memory(struct target
*target
,
1366 uint32_t address
, uint32_t size
,
1367 uint32_t count
, uint8_t *buffer
)
1369 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1370 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
1371 int retval
= ERROR_INVALID_ARGUMENTS
;
1373 /* cortex_a8 handles unaligned memory access */
1375 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1376 LOG_DEBUG("Reading memory at real address 0x%x; size %d; count %d", address
, size
, count
);
1377 if (count
&& buffer
) {
1380 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1383 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1386 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1394 static int cortex_a8_read_memory(struct target
*target
, uint32_t address
,
1395 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1398 uint32_t virt
, phys
;
1401 /* cortex_a8 handles unaligned memory access */
1403 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1404 LOG_DEBUG("Reading memory at address 0x%x; size %d; count %d", address
, size
, count
);
1405 retval
= cortex_a8_mmu(target
, &enabled
);
1406 if (retval
!= ERROR_OK
)
1412 cortex_a8_virt2phys(target
, virt
, &phys
);
1413 LOG_DEBUG("Reading at virtual address. Translating v:0x%x to r:0x%x", virt
, phys
);
1417 return cortex_a8_read_phys_memory(target
, address
, size
, count
, buffer
);
1420 static int cortex_a8_write_phys_memory(struct target
*target
,
1421 uint32_t address
, uint32_t size
,
1422 uint32_t count
, uint8_t *buffer
)
1424 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1425 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
1426 int retval
= ERROR_INVALID_ARGUMENTS
;
1428 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1430 LOG_DEBUG("Writing memory to real address 0x%x; size %d; count %d", address
, size
, count
);
1431 if (count
&& buffer
) {
1434 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1437 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1440 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1445 /* REVISIT this op is generic ARMv7-A/R stuff */
1446 if (retval
== ERROR_OK
&& target
->state
== TARGET_HALTED
)
1448 struct arm_dpm
*dpm
= armv7a
->armv4_5_common
.dpm
;
1450 retval
= dpm
->prepare(dpm
);
1451 if (retval
!= ERROR_OK
)
1454 /* The Cache handling will NOT work with MMU active, the
1455 * wrong addresses will be invalidated!
1457 * For both ICache and DCache, walk all cache lines in the
1458 * address range. Cortex-A8 has fixed 64 byte line length.
1460 * REVISIT per ARMv7, these may trigger watchpoints ...
1463 /* invalidate I-Cache */
1464 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
1466 /* ICIMVAU - Invalidate Cache single entry
1468 * MCR p15, 0, r0, c7, c5, 1
1470 for (uint32_t cacheline
= address
;
1471 cacheline
< address
+ size
* count
;
1473 retval
= dpm
->instr_write_data_r0(dpm
,
1474 ARMV4_5_MCR(15, 0, 0, 7, 5, 1),
1479 /* invalidate D-Cache */
1480 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
1482 /* DCIMVAC - Invalidate data Cache line
1484 * MCR p15, 0, r0, c7, c6, 1
1486 for (uint32_t cacheline
= address
;
1487 cacheline
< address
+ size
* count
;
1489 retval
= dpm
->instr_write_data_r0(dpm
,
1490 ARMV4_5_MCR(15, 0, 0, 7, 6, 1),
1495 /* (void) */ dpm
->finish(dpm
);
1501 static int cortex_a8_write_memory(struct target
*target
, uint32_t address
,
1502 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1505 uint32_t virt
, phys
;
1508 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1510 LOG_DEBUG("Writing memory to address 0x%x; size %d; count %d", address
, size
, count
);
1511 retval
= cortex_a8_mmu(target
, &enabled
);
1512 if (retval
!= ERROR_OK
)
1517 cortex_a8_virt2phys(target
, virt
, &phys
);
1518 LOG_DEBUG("Writing to virtual address. Translating v:0x%x to r:0x%x", virt
, phys
);
1522 return cortex_a8_write_phys_memory(target
, address
, size
,
1526 static int cortex_a8_bulk_write_memory(struct target
*target
, uint32_t address
,
1527 uint32_t count
, uint8_t *buffer
)
1529 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1533 static int cortex_a8_dcc_read(struct adiv5_dap
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1538 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1539 *ctrl
= (uint8_t)dcrdr
;
1540 *value
= (uint8_t)(dcrdr
>> 8);
1542 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1544 /* write ack back to software dcc register
1545 * signify we have read data */
1546 if (dcrdr
& (1 << 0))
1549 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1556 static int cortex_a8_handle_target_request(void *priv
)
1558 struct target
*target
= priv
;
1559 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1560 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
1562 if (!target_was_examined(target
))
1564 if (!target
->dbg_msg_enabled
)
1567 if (target
->state
== TARGET_RUNNING
)
1572 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1574 /* check if we have data */
1575 if (ctrl
& (1 << 0))
1579 /* we assume target is quick enough */
1581 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1582 request
|= (data
<< 8);
1583 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1584 request
|= (data
<< 16);
1585 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1586 request
|= (data
<< 24);
1587 target_request(target
, request
);
1595 * Cortex-A8 target information and configuration
1598 static int cortex_a8_examine_first(struct target
*target
)
1600 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1601 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1602 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
1604 int retval
= ERROR_OK
;
1605 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1607 /* stop assuming this is an OMAP! */
1608 LOG_DEBUG("TODO - autoconfigure");
1610 /* Here we shall insert a proper ROM Table scan */
1611 armv7a
->debug_base
= OMAP3530_DEBUG_BASE
;
1613 /* We do one extra read to ensure DAP is configured,
1614 * we call ahbap_debugport_init(swjdp) instead
1616 retval
= ahbap_debugport_init(swjdp
);
1617 if (retval
!= ERROR_OK
)
1620 retval
= mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
1621 if (retval
!= ERROR_OK
)
1624 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1625 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1627 LOG_DEBUG("Examine %s failed", "CPUID");
1631 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1632 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1634 LOG_DEBUG("Examine %s failed", "CTYPR");
1638 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1639 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1641 LOG_DEBUG("Examine %s failed", "TTYPR");
1645 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1646 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1648 LOG_DEBUG("Examine %s failed", "DIDR");
1652 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1653 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1654 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1655 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1657 armv7a
->armv4_5_common
.core_type
= ARM_MODE_MON
;
1658 retval
= cortex_a8_dpm_setup(cortex_a8
, didr
);
1659 if (retval
!= ERROR_OK
)
1662 /* Setup Breakpoint Register Pairs */
1663 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1664 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1665 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1666 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(struct cortex_a8_brp
));
1667 // cortex_a8->brb_enabled = ????;
1668 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1670 cortex_a8
->brp_list
[i
].used
= 0;
1671 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1672 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1674 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1675 cortex_a8
->brp_list
[i
].value
= 0;
1676 cortex_a8
->brp_list
[i
].control
= 0;
1677 cortex_a8
->brp_list
[i
].BRPn
= i
;
1680 LOG_DEBUG("Configured %i hw breakpoints", cortex_a8
->brp_num
);
1682 target_set_examined(target
);
1686 static int cortex_a8_examine(struct target
*target
)
1688 int retval
= ERROR_OK
;
1690 /* don't re-probe hardware after each reset */
1691 if (!target_was_examined(target
))
1692 retval
= cortex_a8_examine_first(target
);
1694 /* Configure core debug access */
1695 if (retval
== ERROR_OK
)
1696 retval
= cortex_a8_init_debug_access(target
);
1702 * Cortex-A8 target creation and initialization
1705 static int cortex_a8_init_target(struct command_context
*cmd_ctx
,
1706 struct target
*target
)
1708 /* examine_first() does a bunch of this */
1712 static int cortex_a8_init_arch_info(struct target
*target
,
1713 struct cortex_a8_common
*cortex_a8
, struct jtag_tap
*tap
)
1715 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1716 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
1717 struct adiv5_dap
*dap
= &armv7a
->dap
;
1719 armv7a
->armv4_5_common
.dap
= dap
;
1721 /* Setup struct cortex_a8_common */
1722 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1723 armv4_5
->arch_info
= armv7a
;
1725 /* prepare JTAG information for the new target */
1726 cortex_a8
->jtag_info
.tap
= tap
;
1727 cortex_a8
->jtag_info
.scann_size
= 4;
1729 /* Leave (only) generic DAP stuff for debugport_init() */
1730 dap
->jtag_info
= &cortex_a8
->jtag_info
;
1731 dap
->memaccess_tck
= 80;
1733 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1734 dap
->tar_autoincr_block
= (1 << 10);
1736 cortex_a8
->fast_reg_read
= 0;
1738 /* Set default value */
1739 cortex_a8
->current_address_mode
= ARM_MODE_ANY
;
1741 /* register arch-specific functions */
1742 armv7a
->examine_debug_reason
= NULL
;
1744 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1746 armv7a
->pre_restore_context
= NULL
;
1747 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1748 armv7a
->armv4_5_mmu
.get_ttb
= cortex_a8_get_ttb
;
1749 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_phys_memory
;
1750 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_phys_memory
;
1751 armv7a
->armv4_5_mmu
.disable_mmu_caches
= cortex_a8_disable_mmu_caches
;
1752 armv7a
->armv4_5_mmu
.enable_mmu_caches
= cortex_a8_enable_mmu_caches
;
1753 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1754 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1757 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1759 /* REVISIT v7a setup should be in a v7a-specific routine */
1760 arm_init_arch_info(target
, armv4_5
);
1761 armv7a
->common_magic
= ARMV7_COMMON_MAGIC
;
1763 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1768 static int cortex_a8_target_create(struct target
*target
, Jim_Interp
*interp
)
1770 struct cortex_a8_common
*cortex_a8
= calloc(1, sizeof(struct cortex_a8_common
));
1772 cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1777 static uint32_t cortex_a8_get_ttb(struct target
*target
)
1779 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1780 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1781 uint32_t ttb
= 0, retval
= ERROR_OK
;
1783 /* current_address_mode is set inside cortex_a8_virt2phys()
1784 where we can determine if address belongs to user or kernel */
1785 if(cortex_a8
->current_address_mode
== ARM_MODE_SVC
)
1787 /* MRC p15,0,<Rt>,c1,c0,0 ; Read CP15 System Control Register */
1788 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
1789 0, 1, /* op1, op2 */
1790 2, 0, /* CRn, CRm */
1793 else if(cortex_a8
->current_address_mode
== ARM_MODE_USR
)
1795 /* MRC p15,0,<Rt>,c1,c0,0 ; Read CP15 System Control Register */
1796 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
1797 0, 0, /* op1, op2 */
1798 2, 0, /* CRn, CRm */
1801 /* we don't know whose address is: user or kernel
1802 we assume that if we are in kernel mode then
1803 address belongs to kernel else if in user mode
1805 else if(armv7a
->armv4_5_common
.core_mode
== ARM_MODE_SVC
)
1807 /* MRC p15,0,<Rt>,c1,c0,0 ; Read CP15 System Control Register */
1808 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
1809 0, 1, /* op1, op2 */
1810 2, 0, /* CRn, CRm */
1813 else if(armv7a
->armv4_5_common
.core_mode
== ARM_MODE_USR
)
1815 /* MRC p15,0,<Rt>,c1,c0,0 ; Read CP15 System Control Register */
1816 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
1817 0, 0, /* op1, op2 */
1818 2, 0, /* CRn, CRm */
1821 /* finally we don't know whose ttb to use: user or kernel */
1823 LOG_ERROR("Don't know how to get ttb for current mode!!!");
1830 static void cortex_a8_disable_mmu_caches(struct target
*target
, int mmu
,
1831 int d_u_cache
, int i_cache
)
1833 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1834 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1835 uint32_t cp15_control
;
1837 /* read cp15 control register */
1838 armv7a
->armv4_5_common
.mrc(target
, 15,
1839 0, 0, /* op1, op2 */
1840 1, 0, /* CRn, CRm */
1845 cp15_control
&= ~0x1U
;
1848 cp15_control
&= ~0x4U
;
1851 cp15_control
&= ~0x1000U
;
1853 armv7a
->armv4_5_common
.mcr(target
, 15,
1854 0, 0, /* op1, op2 */
1855 1, 0, /* CRn, CRm */
1859 static void cortex_a8_enable_mmu_caches(struct target
*target
, int mmu
,
1860 int d_u_cache
, int i_cache
)
1862 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1863 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1864 uint32_t cp15_control
;
1866 /* read cp15 control register */
1867 armv7a
->armv4_5_common
.mrc(target
, 15,
1868 0, 0, /* op1, op2 */
1869 1, 0, /* CRn, CRm */
1873 cp15_control
|= 0x1U
;
1876 cp15_control
|= 0x4U
;
1879 cp15_control
|= 0x1000U
;
1881 armv7a
->armv4_5_common
.mcr(target
, 15,
1882 0, 0, /* op1, op2 */
1883 1, 0, /* CRn, CRm */
1888 static int cortex_a8_mmu(struct target
*target
, int *enabled
)
1890 if (target
->state
!= TARGET_HALTED
) {
1891 LOG_ERROR("%s: target not halted", __func__
);
1892 return ERROR_TARGET_INVALID
;
1895 *enabled
= target_to_cortex_a8(target
)->armv7a_common
.armv4_5_mmu
.mmu_enabled
;
1899 static int cortex_a8_virt2phys(struct target
*target
,
1900 uint32_t virt
, uint32_t *phys
)
1903 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1904 // struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
1905 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1907 /* We assume that virtual address is separated
1908 between user and kernel in Linux style:
1909 0x00000000-0xbfffffff - User space
1910 0xc0000000-0xffffffff - Kernel space */
1911 if( virt
< 0xc0000000 ) /* Linux user space */
1912 cortex_a8
->current_address_mode
= ARM_MODE_USR
;
1913 else /* Linux kernel */
1914 cortex_a8
->current_address_mode
= ARM_MODE_SVC
;
1916 int retval
= armv4_5_mmu_translate_va(target
,
1917 &armv7a
->armv4_5_mmu
, virt
, &cb
, &ret
);
1918 if (retval
!= ERROR_OK
)
1920 /* Reset the flag. We don't want someone else to use it by error */
1921 cortex_a8
->current_address_mode
= ARM_MODE_ANY
;
1927 COMMAND_HANDLER(cortex_a8_handle_cache_info_command
)
1929 struct target
*target
= get_current_target(CMD_CTX
);
1930 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1932 return armv4_5_handle_cache_info_command(CMD_CTX
,
1933 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1937 COMMAND_HANDLER(cortex_a8_handle_dbginit_command
)
1939 struct target
*target
= get_current_target(CMD_CTX
);
1940 if (!target_was_examined(target
))
1942 LOG_ERROR("target not examined yet");
1946 return cortex_a8_init_debug_access(target
);
1949 static const struct command_registration cortex_a8_exec_command_handlers
[] = {
1951 .name
= "cache_info",
1952 .handler
= cortex_a8_handle_cache_info_command
,
1953 .mode
= COMMAND_EXEC
,
1954 .help
= "display information about target caches",
1958 .handler
= cortex_a8_handle_dbginit_command
,
1959 .mode
= COMMAND_EXEC
,
1960 .help
= "Initialize core debug",
1962 COMMAND_REGISTRATION_DONE
1964 static const struct command_registration cortex_a8_command_handlers
[] = {
1966 .chain
= arm_command_handlers
,
1969 .chain
= armv7a_command_handlers
,
1972 .name
= "cortex_a8",
1973 .mode
= COMMAND_ANY
,
1974 .help
= "Cortex-A8 command group",
1975 .chain
= cortex_a8_exec_command_handlers
,
1977 COMMAND_REGISTRATION_DONE
1980 struct target_type cortexa8_target
= {
1981 .name
= "cortex_a8",
1983 .poll
= cortex_a8_poll
,
1984 .arch_state
= armv7a_arch_state
,
1986 .target_request_data
= NULL
,
1988 .halt
= cortex_a8_halt
,
1989 .resume
= cortex_a8_resume
,
1990 .step
= cortex_a8_step
,
1992 .assert_reset
= cortex_a8_assert_reset
,
1993 .deassert_reset
= cortex_a8_deassert_reset
,
1994 .soft_reset_halt
= NULL
,
1996 /* REVISIT allow exporting VFP3 registers ... */
1997 .get_gdb_reg_list
= arm_get_gdb_reg_list
,
1999 .read_memory
= cortex_a8_read_memory
,
2000 .write_memory
= cortex_a8_write_memory
,
2001 .bulk_write_memory
= cortex_a8_bulk_write_memory
,
2003 .checksum_memory
= arm_checksum_memory
,
2004 .blank_check_memory
= arm_blank_check_memory
,
2006 .run_algorithm
= armv4_5_run_algorithm
,
2008 .add_breakpoint
= cortex_a8_add_breakpoint
,
2009 .remove_breakpoint
= cortex_a8_remove_breakpoint
,
2010 .add_watchpoint
= NULL
,
2011 .remove_watchpoint
= NULL
,
2013 .commands
= cortex_a8_command_handlers
,
2014 .target_create
= cortex_a8_target_create
,
2015 .init_target
= cortex_a8_init_target
,
2016 .examine
= cortex_a8_examine
,
2018 .read_phys_memory
= cortex_a8_read_phys_memory
,
2019 .write_phys_memory
= cortex_a8_write_phys_memory
,
2020 .mmu
= cortex_a8_mmu
,
2021 .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)