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 * Copyright (C) ST-Ericsson SA 2011 *
18 * michel.jaouen@stericsson.com : smp minimum support *
20 * This program is free software; you can redistribute it and/or modify *
21 * it under the terms of the GNU General Public License as published by *
22 * the Free Software Foundation; either version 2 of the License, or *
23 * (at your option) any later version. *
25 * This program is distributed in the hope that it will be useful, *
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
28 * GNU General Public License for more details. *
30 * You should have received a copy of the GNU General Public License *
31 * along with this program; if not, write to the *
32 * Free Software Foundation, Inc., *
33 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
35 * Cortex-A8(tm) TRM, ARM DDI 0344H *
36 * Cortex-A9(tm) TRM, ARM DDI 0407F *
38 ***************************************************************************/
43 #include "breakpoints.h"
46 #include "target_request.h"
47 #include "target_type.h"
48 #include "arm_opcodes.h"
49 #include <helper/time_support.h>
51 static int cortex_a8_poll(struct target
*target
);
52 static int cortex_a8_debug_entry(struct target
*target
);
53 static int cortex_a8_restore_context(struct target
*target
, bool bpwp
);
54 static int cortex_a8_set_breakpoint(struct target
*target
,
55 struct breakpoint
*breakpoint
, uint8_t matchmode
);
56 static int cortex_a8_set_context_breakpoint(struct target
*target
,
57 struct breakpoint
*breakpoint
, uint8_t matchmode
);
58 static int cortex_a8_set_hybrid_breakpoint(struct target
*target
,
59 struct breakpoint
*breakpoint
);
60 static int cortex_a8_unset_breakpoint(struct target
*target
,
61 struct breakpoint
*breakpoint
);
62 static int cortex_a8_dap_read_coreregister_u32(struct target
*target
,
63 uint32_t *value
, int regnum
);
64 static int cortex_a8_dap_write_coreregister_u32(struct target
*target
,
65 uint32_t value
, int regnum
);
66 static int cortex_a8_mmu(struct target
*target
, int *enabled
);
67 static int cortex_a8_virt2phys(struct target
*target
,
68 uint32_t virt
, uint32_t *phys
);
71 * FIXME do topology discovery using the ROM; don't
72 * assume this is an OMAP3. Also, allow for multiple ARMv7-A
73 * cores, with different AP numbering ... don't use a #define
74 * for these numbers, use per-core armv7a state.
76 #define swjdp_memoryap 0
77 #define swjdp_debugap 1
79 /* restore cp15_control_reg at resume */
80 static int cortex_a8_restore_cp15_control_reg(struct target
* target
)
82 int retval
= ERROR_OK
;
83 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
84 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
86 if (cortex_a8
->cp15_control_reg
!=cortex_a8
->cp15_control_reg_curr
)
88 cortex_a8
->cp15_control_reg_curr
= cortex_a8
->cp15_control_reg
;
89 //LOG_INFO("cp15_control_reg: %8.8" PRIx32, cortex_a8->cp15_control_reg);
90 retval
= armv7a
->arm
.mcr(target
, 15,
93 cortex_a8
->cp15_control_reg
);
98 /* check address before cortex_a8_apb read write access with mmu on
99 * remove apb predictible data abort */
100 static int cortex_a8_check_address(struct target
*target
, uint32_t address
)
102 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
103 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
104 uint32_t os_border
= armv7a
->armv7a_mmu
.os_border
;
105 if ((address
< os_border
) &&
106 (armv7a
->arm
.core_mode
== ARM_MODE_SVC
)) {
107 LOG_ERROR("%x access in userspace and target in supervisor",address
);
110 if ((address
>= os_border
) &&
111 (cortex_a8
->curr_mode
!= ARM_MODE_SVC
)) {
112 dpm_modeswitch(&armv7a
->dpm
, ARM_MODE_SVC
);
113 cortex_a8
->curr_mode
= ARM_MODE_SVC
;
114 LOG_INFO("%x access in kernel space and target not in supervisor",
118 if ((address
< os_border
) &&
119 (cortex_a8
->curr_mode
== ARM_MODE_SVC
)) {
120 dpm_modeswitch(&armv7a
->dpm
, ARM_MODE_ANY
);
121 cortex_a8
->curr_mode
= ARM_MODE_ANY
;
125 /* modify cp15_control_reg in order to enable or disable mmu for :
126 * - virt2phys address conversion
127 * - read or write memory in phys or virt address */
128 static int cortex_a8_mmu_modify(struct target
*target
, int enable
)
130 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
131 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
132 int retval
= ERROR_OK
;
135 /* if mmu enabled at target stop and mmu not enable */
136 if (!(cortex_a8
->cp15_control_reg
& 0x1U
))
138 LOG_ERROR("trying to enable mmu on target stopped with mmu disable");
141 if (!(cortex_a8
->cp15_control_reg_curr
& 0x1U
))
143 cortex_a8
->cp15_control_reg_curr
|= 0x1U
;
144 retval
= armv7a
->arm
.mcr(target
, 15,
147 cortex_a8
->cp15_control_reg_curr
);
152 if (cortex_a8
->cp15_control_reg_curr
& 0x4U
)
154 /* data cache is active */
155 cortex_a8
->cp15_control_reg_curr
&= ~0x4U
;
156 /* flush data cache armv7 function to be called */
157 if (armv7a
->armv7a_mmu
.armv7a_cache
.flush_all_data_cache
)
158 armv7a
->armv7a_mmu
.armv7a_cache
.flush_all_data_cache(target
);
160 if ( (cortex_a8
->cp15_control_reg_curr
& 0x1U
))
162 cortex_a8
->cp15_control_reg_curr
&= ~0x1U
;
163 retval
= armv7a
->arm
.mcr(target
, 15,
166 cortex_a8
->cp15_control_reg_curr
);
173 * Cortex-A8 Basic debug access, very low level assumes state is saved
175 static int cortex_a8_init_debug_access(struct target
*target
)
177 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
178 struct adiv5_dap
*swjdp
= armv7a
->arm
.dap
;
184 /* Unlocking the debug registers for modification */
185 /* The debugport might be uninitialised so try twice */
186 retval
= mem_ap_sel_write_atomic_u32(swjdp
, swjdp_debugap
,
187 armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
188 if (retval
!= ERROR_OK
)
191 retval
= mem_ap_sel_write_atomic_u32(swjdp
, swjdp_debugap
,
192 armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
193 if (retval
== ERROR_OK
)
195 LOG_USER("Locking debug access failed on first, but succeeded on second try.");
198 if (retval
!= ERROR_OK
)
200 /* Clear Sticky Power Down status Bit in PRSR to enable access to
201 the registers in the Core Power Domain */
202 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
203 armv7a
->debug_base
+ CPUDBG_PRSR
, &dummy
);
204 if (retval
!= ERROR_OK
)
207 /* Enabling of instruction execution in debug mode is done in debug_entry code */
209 /* Resync breakpoint registers */
211 /* Since this is likely called from init or reset, update target state information*/
212 return cortex_a8_poll(target
);
215 /* To reduce needless round-trips, pass in a pointer to the current
216 * DSCR value. Initialize it to zero if you just need to know the
217 * value on return from this function; or DSCR_INSTR_COMP if you
218 * happen to know that no instruction is pending.
220 static int cortex_a8_exec_opcode(struct target
*target
,
221 uint32_t opcode
, uint32_t *dscr_p
)
225 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
226 struct adiv5_dap
*swjdp
= armv7a
->arm
.dap
;
228 dscr
= dscr_p
? *dscr_p
: 0;
230 LOG_DEBUG("exec opcode 0x%08" PRIx32
, opcode
);
232 /* Wait for InstrCompl bit to be set */
233 long long then
= timeval_ms();
234 while ((dscr
& DSCR_INSTR_COMP
) == 0)
236 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
237 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
238 if (retval
!= ERROR_OK
)
240 LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32
, opcode
);
243 if (timeval_ms() > then
+ 1000)
245 LOG_ERROR("Timeout waiting for cortex_a8_exec_opcode");
250 retval
= mem_ap_sel_write_u32(swjdp
, swjdp_debugap
,
251 armv7a
->debug_base
+ CPUDBG_ITR
, opcode
);
252 if (retval
!= ERROR_OK
)
258 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
259 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
260 if (retval
!= ERROR_OK
)
262 LOG_ERROR("Could not read DSCR register");
265 if (timeval_ms() > then
+ 1000)
267 LOG_ERROR("Timeout waiting for cortex_a8_exec_opcode");
271 while ((dscr
& DSCR_INSTR_COMP
) == 0); /* Wait for InstrCompl bit to be set */
279 /**************************************************************************
280 Read core register with very few exec_opcode, fast but needs work_area.
281 This can cause problems with MMU active.
282 **************************************************************************/
283 static int cortex_a8_read_regs_through_mem(struct target
*target
, uint32_t address
,
286 int retval
= ERROR_OK
;
287 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
288 struct adiv5_dap
*swjdp
= armv7a
->arm
.dap
;
290 retval
= cortex_a8_dap_read_coreregister_u32(target
, regfile
, 0);
291 if (retval
!= ERROR_OK
)
293 retval
= cortex_a8_dap_write_coreregister_u32(target
, address
, 0);
294 if (retval
!= ERROR_OK
)
296 retval
= cortex_a8_exec_opcode(target
, ARMV4_5_STMIA(0, 0xFFFE, 0, 0), NULL
);
297 if (retval
!= ERROR_OK
)
300 retval
= mem_ap_sel_read_buf_u32(swjdp
, swjdp_memoryap
,
301 (uint8_t *)(®file
[1]), 4*15, address
);
306 static int cortex_a8_dap_read_coreregister_u32(struct target
*target
,
307 uint32_t *value
, int regnum
)
309 int retval
= ERROR_OK
;
310 uint8_t reg
= regnum
&0xFF;
312 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
313 struct adiv5_dap
*swjdp
= armv7a
->arm
.dap
;
320 /* Rn to DCCTX, "MCR p14, 0, Rn, c0, c5, 0" 0xEE00nE15 */
321 retval
= cortex_a8_exec_opcode(target
,
322 ARMV4_5_MCR(14, 0, reg
, 0, 5, 0),
324 if (retval
!= ERROR_OK
)
329 /* "MOV r0, r15"; then move r0 to DCCTX */
330 retval
= cortex_a8_exec_opcode(target
, 0xE1A0000F, &dscr
);
331 if (retval
!= ERROR_OK
)
333 retval
= cortex_a8_exec_opcode(target
,
334 ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
336 if (retval
!= ERROR_OK
)
341 /* "MRS r0, CPSR" or "MRS r0, SPSR"
342 * then move r0 to DCCTX
344 retval
= cortex_a8_exec_opcode(target
, ARMV4_5_MRS(0, reg
& 1), &dscr
);
345 if (retval
!= ERROR_OK
)
347 retval
= cortex_a8_exec_opcode(target
,
348 ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
350 if (retval
!= ERROR_OK
)
354 /* Wait for DTRRXfull then read DTRRTX */
355 long long then
= timeval_ms();
356 while ((dscr
& DSCR_DTR_TX_FULL
) == 0)
358 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
359 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
360 if (retval
!= ERROR_OK
)
362 if (timeval_ms() > then
+ 1000)
364 LOG_ERROR("Timeout waiting for cortex_a8_exec_opcode");
369 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
370 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
371 LOG_DEBUG("read DCC 0x%08" PRIx32
, *value
);
376 static int cortex_a8_dap_write_coreregister_u32(struct target
*target
,
377 uint32_t value
, int regnum
)
379 int retval
= ERROR_OK
;
380 uint8_t Rd
= regnum
&0xFF;
382 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
383 struct adiv5_dap
*swjdp
= armv7a
->arm
.dap
;
385 LOG_DEBUG("register %i, value 0x%08" PRIx32
, regnum
, value
);
387 /* Check that DCCRX is not full */
388 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
389 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
390 if (retval
!= ERROR_OK
)
392 if (dscr
& DSCR_DTR_RX_FULL
)
394 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
395 /* Clear DCCRX with MRC(p14, 0, Rd, c0, c5, 0), opcode 0xEE100E15 */
396 retval
= cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
398 if (retval
!= ERROR_OK
)
405 /* Write DTRRX ... sets DSCR.DTRRXfull but exec_opcode() won't care */
406 LOG_DEBUG("write DCC 0x%08" PRIx32
, value
);
407 retval
= mem_ap_sel_write_u32(swjdp
, swjdp_debugap
,
408 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
409 if (retval
!= ERROR_OK
)
414 /* DCCRX to Rn, "MRC p14, 0, Rn, c0, c5, 0", 0xEE10nE15 */
415 retval
= cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, Rd
, 0, 5, 0),
418 if (retval
!= ERROR_OK
)
423 /* DCCRX to R0, "MRC p14, 0, R0, c0, c5, 0", 0xEE100E15
426 retval
= cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
428 if (retval
!= ERROR_OK
)
430 retval
= cortex_a8_exec_opcode(target
, 0xE1A0F000, &dscr
);
431 if (retval
!= ERROR_OK
)
436 /* DCCRX to R0, "MRC p14, 0, R0, c0, c5, 0", 0xEE100E15
437 * then "MSR CPSR_cxsf, r0" or "MSR SPSR_cxsf, r0" (all fields)
439 retval
= cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
441 if (retval
!= ERROR_OK
)
443 retval
= cortex_a8_exec_opcode(target
, ARMV4_5_MSR_GP(0, 0xF, Rd
& 1),
445 if (retval
!= ERROR_OK
)
448 /* "Prefetch flush" after modifying execution status in CPSR */
451 retval
= cortex_a8_exec_opcode(target
,
452 ARMV4_5_MCR(15, 0, 0, 7, 5, 4),
454 if (retval
!= ERROR_OK
)
462 /* Write to memory mapped registers directly with no cache or mmu handling */
463 static int cortex_a8_dap_write_memap_register_u32(struct target
*target
, uint32_t address
, uint32_t value
)
466 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
467 struct adiv5_dap
*swjdp
= armv7a
->arm
.dap
;
469 retval
= mem_ap_sel_write_atomic_u32(swjdp
, swjdp_debugap
, address
, value
);
475 * Cortex-A8 implementation of Debug Programmer's Model
477 * NOTE the invariant: these routines return with DSCR_INSTR_COMP set,
478 * so there's no need to poll for it before executing an instruction.
480 * NOTE that in several of these cases the "stall" mode might be useful.
481 * It'd let us queue a few operations together... prepare/finish might
482 * be the places to enable/disable that mode.
485 static inline struct cortex_a8_common
*dpm_to_a8(struct arm_dpm
*dpm
)
487 return container_of(dpm
, struct cortex_a8_common
, armv7a_common
.dpm
);
490 static int cortex_a8_write_dcc(struct cortex_a8_common
*a8
, uint32_t data
)
492 LOG_DEBUG("write DCC 0x%08" PRIx32
, data
);
493 return mem_ap_sel_write_u32(a8
->armv7a_common
.arm
.dap
,
494 swjdp_debugap
,a8
->armv7a_common
.debug_base
+ CPUDBG_DTRRX
, data
);
497 static int cortex_a8_read_dcc(struct cortex_a8_common
*a8
, uint32_t *data
,
500 struct adiv5_dap
*swjdp
= a8
->armv7a_common
.arm
.dap
;
501 uint32_t dscr
= DSCR_INSTR_COMP
;
507 /* Wait for DTRRXfull */
508 long long then
= timeval_ms();
509 while ((dscr
& DSCR_DTR_TX_FULL
) == 0) {
510 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
511 a8
->armv7a_common
.debug_base
+ CPUDBG_DSCR
,
513 if (retval
!= ERROR_OK
)
515 if (timeval_ms() > then
+ 1000)
517 LOG_ERROR("Timeout waiting for read dcc");
522 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
523 a8
->armv7a_common
.debug_base
+ CPUDBG_DTRTX
, data
);
524 if (retval
!= ERROR_OK
)
526 //LOG_DEBUG("read DCC 0x%08" PRIx32, *data);
534 static int cortex_a8_dpm_prepare(struct arm_dpm
*dpm
)
536 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
537 struct adiv5_dap
*swjdp
= a8
->armv7a_common
.arm
.dap
;
541 /* set up invariant: INSTR_COMP is set after ever DPM operation */
542 long long then
= timeval_ms();
545 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
546 a8
->armv7a_common
.debug_base
+ CPUDBG_DSCR
,
548 if (retval
!= ERROR_OK
)
550 if ((dscr
& DSCR_INSTR_COMP
) != 0)
552 if (timeval_ms() > then
+ 1000)
554 LOG_ERROR("Timeout waiting for dpm prepare");
559 /* this "should never happen" ... */
560 if (dscr
& DSCR_DTR_RX_FULL
) {
561 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
563 retval
= cortex_a8_exec_opcode(
564 a8
->armv7a_common
.arm
.target
,
565 ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
567 if (retval
!= ERROR_OK
)
574 static int cortex_a8_dpm_finish(struct arm_dpm
*dpm
)
576 /* REVISIT what could be done here? */
580 static int cortex_a8_instr_write_data_dcc(struct arm_dpm
*dpm
,
581 uint32_t opcode
, uint32_t data
)
583 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
585 uint32_t dscr
= DSCR_INSTR_COMP
;
587 retval
= cortex_a8_write_dcc(a8
, data
);
588 if (retval
!= ERROR_OK
)
591 return cortex_a8_exec_opcode(
592 a8
->armv7a_common
.arm
.target
,
597 static int cortex_a8_instr_write_data_r0(struct arm_dpm
*dpm
,
598 uint32_t opcode
, uint32_t data
)
600 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
601 uint32_t dscr
= DSCR_INSTR_COMP
;
604 retval
= cortex_a8_write_dcc(a8
, data
);
605 if (retval
!= ERROR_OK
)
608 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15 */
609 retval
= cortex_a8_exec_opcode(
610 a8
->armv7a_common
.arm
.target
,
611 ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
613 if (retval
!= ERROR_OK
)
616 /* then the opcode, taking data from R0 */
617 retval
= cortex_a8_exec_opcode(
618 a8
->armv7a_common
.arm
.target
,
625 static int cortex_a8_instr_cpsr_sync(struct arm_dpm
*dpm
)
627 struct target
*target
= dpm
->arm
->target
;
628 uint32_t dscr
= DSCR_INSTR_COMP
;
630 /* "Prefetch flush" after modifying execution status in CPSR */
631 return cortex_a8_exec_opcode(target
,
632 ARMV4_5_MCR(15, 0, 0, 7, 5, 4),
636 static int cortex_a8_instr_read_data_dcc(struct arm_dpm
*dpm
,
637 uint32_t opcode
, uint32_t *data
)
639 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
641 uint32_t dscr
= DSCR_INSTR_COMP
;
643 /* the opcode, writing data to DCC */
644 retval
= cortex_a8_exec_opcode(
645 a8
->armv7a_common
.arm
.target
,
648 if (retval
!= ERROR_OK
)
651 return cortex_a8_read_dcc(a8
, data
, &dscr
);
655 static int cortex_a8_instr_read_data_r0(struct arm_dpm
*dpm
,
656 uint32_t opcode
, uint32_t *data
)
658 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
659 uint32_t dscr
= DSCR_INSTR_COMP
;
662 /* the opcode, writing data to R0 */
663 retval
= cortex_a8_exec_opcode(
664 a8
->armv7a_common
.arm
.target
,
667 if (retval
!= ERROR_OK
)
670 /* write R0 to DCC */
671 retval
= cortex_a8_exec_opcode(
672 a8
->armv7a_common
.arm
.target
,
673 ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
675 if (retval
!= ERROR_OK
)
678 return cortex_a8_read_dcc(a8
, data
, &dscr
);
681 static int cortex_a8_bpwp_enable(struct arm_dpm
*dpm
, unsigned index_t
,
682 uint32_t addr
, uint32_t control
)
684 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
685 uint32_t vr
= a8
->armv7a_common
.debug_base
;
686 uint32_t cr
= a8
->armv7a_common
.debug_base
;
690 case 0 ... 15: /* breakpoints */
691 vr
+= CPUDBG_BVR_BASE
;
692 cr
+= CPUDBG_BCR_BASE
;
694 case 16 ... 31: /* watchpoints */
695 vr
+= CPUDBG_WVR_BASE
;
696 cr
+= CPUDBG_WCR_BASE
;
705 LOG_DEBUG("A8: bpwp enable, vr %08x cr %08x",
706 (unsigned) vr
, (unsigned) cr
);
708 retval
= cortex_a8_dap_write_memap_register_u32(dpm
->arm
->target
,
710 if (retval
!= ERROR_OK
)
712 retval
= cortex_a8_dap_write_memap_register_u32(dpm
->arm
->target
,
717 static int cortex_a8_bpwp_disable(struct arm_dpm
*dpm
, unsigned index_t
)
719 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
724 cr
= a8
->armv7a_common
.debug_base
+ CPUDBG_BCR_BASE
;
727 cr
= a8
->armv7a_common
.debug_base
+ CPUDBG_WCR_BASE
;
735 LOG_DEBUG("A8: bpwp disable, cr %08x", (unsigned) cr
);
737 /* clear control register */
738 return cortex_a8_dap_write_memap_register_u32(dpm
->arm
->target
, cr
, 0);
741 static int cortex_a8_dpm_setup(struct cortex_a8_common
*a8
, uint32_t didr
)
743 struct arm_dpm
*dpm
= &a8
->armv7a_common
.dpm
;
746 dpm
->arm
= &a8
->armv7a_common
.arm
;
749 dpm
->prepare
= cortex_a8_dpm_prepare
;
750 dpm
->finish
= cortex_a8_dpm_finish
;
752 dpm
->instr_write_data_dcc
= cortex_a8_instr_write_data_dcc
;
753 dpm
->instr_write_data_r0
= cortex_a8_instr_write_data_r0
;
754 dpm
->instr_cpsr_sync
= cortex_a8_instr_cpsr_sync
;
756 dpm
->instr_read_data_dcc
= cortex_a8_instr_read_data_dcc
;
757 dpm
->instr_read_data_r0
= cortex_a8_instr_read_data_r0
;
759 dpm
->bpwp_enable
= cortex_a8_bpwp_enable
;
760 dpm
->bpwp_disable
= cortex_a8_bpwp_disable
;
762 retval
= arm_dpm_setup(dpm
);
763 if (retval
== ERROR_OK
)
764 retval
= arm_dpm_initialize(dpm
);
768 static struct target
*get_cortex_a8(struct target
*target
, int32_t coreid
)
770 struct target_list
*head
;
774 while(head
!= (struct target_list
*)NULL
)
777 if ((curr
->coreid
== coreid
) && (curr
->state
== TARGET_HALTED
))
785 static int cortex_a8_halt(struct target
*target
);
787 static int cortex_a8_halt_smp(struct target
*target
)
790 struct target_list
*head
;
793 while(head
!= (struct target_list
*)NULL
)
796 if ((curr
!= target
) && (curr
->state
!= TARGET_HALTED
))
798 retval
+= cortex_a8_halt(curr
);
805 static int update_halt_gdb(struct target
*target
)
808 if (target
->gdb_service
->core
[0]==-1)
810 target
->gdb_service
->target
= target
;
811 target
->gdb_service
->core
[0] = target
->coreid
;
812 retval
+= cortex_a8_halt_smp(target
);
818 * Cortex-A8 Run control
821 static int cortex_a8_poll(struct target
*target
)
823 int retval
= ERROR_OK
;
825 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
826 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
827 struct adiv5_dap
*swjdp
= armv7a
->arm
.dap
;
828 enum target_state prev_target_state
= target
->state
;
829 // toggle to another core is done by gdb as follow
830 // maint packet J core_id
832 // the next polling trigger an halt event sent to gdb
833 if ((target
->state
== TARGET_HALTED
) && (target
->smp
) &&
834 (target
->gdb_service
) &&
835 (target
->gdb_service
->target
==NULL
) )
837 target
->gdb_service
->target
=
838 get_cortex_a8(target
, target
->gdb_service
->core
[1]);
839 target_call_event_callbacks(target
,
840 TARGET_EVENT_HALTED
);
843 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
844 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
845 if (retval
!= ERROR_OK
)
849 cortex_a8
->cpudbg_dscr
= dscr
;
851 if (DSCR_RUN_MODE(dscr
) == (DSCR_CORE_HALTED
| DSCR_CORE_RESTARTED
))
853 if (prev_target_state
!= TARGET_HALTED
)
855 /* We have a halting debug event */
856 LOG_DEBUG("Target halted");
857 target
->state
= TARGET_HALTED
;
858 if ((prev_target_state
== TARGET_RUNNING
)
859 || (prev_target_state
== TARGET_RESET
))
861 retval
= cortex_a8_debug_entry(target
);
862 if (retval
!= ERROR_OK
)
866 retval
= update_halt_gdb(target
);
867 if (retval
!= ERROR_OK
)
870 target_call_event_callbacks(target
,
871 TARGET_EVENT_HALTED
);
873 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
877 retval
= cortex_a8_debug_entry(target
);
878 if (retval
!= ERROR_OK
)
882 retval
= update_halt_gdb(target
);
883 if (retval
!= ERROR_OK
)
887 target_call_event_callbacks(target
,
888 TARGET_EVENT_DEBUG_HALTED
);
892 else if (DSCR_RUN_MODE(dscr
) == DSCR_CORE_RESTARTED
)
894 target
->state
= TARGET_RUNNING
;
898 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32
, dscr
);
899 target
->state
= TARGET_UNKNOWN
;
905 static int cortex_a8_halt(struct target
*target
)
907 int retval
= ERROR_OK
;
909 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
910 struct adiv5_dap
*swjdp
= armv7a
->arm
.dap
;
913 * Tell the core to be halted by writing DRCR with 0x1
914 * and then wait for the core to be halted.
916 retval
= mem_ap_sel_write_atomic_u32(swjdp
, swjdp_debugap
,
917 armv7a
->debug_base
+ CPUDBG_DRCR
, DRCR_HALT
);
918 if (retval
!= ERROR_OK
)
922 * enter halting debug mode
924 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
925 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
926 if (retval
!= ERROR_OK
)
929 retval
= mem_ap_sel_write_atomic_u32(swjdp
, swjdp_debugap
,
930 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
| DSCR_HALT_DBG_MODE
);
931 if (retval
!= ERROR_OK
)
934 long long then
= timeval_ms();
937 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
938 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
939 if (retval
!= ERROR_OK
)
941 if ((dscr
& DSCR_CORE_HALTED
) != 0)
945 if (timeval_ms() > then
+ 1000)
947 LOG_ERROR("Timeout waiting for halt");
952 target
->debug_reason
= DBG_REASON_DBGRQ
;
957 static int cortex_a8_internal_restore(struct target
*target
, int current
,
958 uint32_t *address
, int handle_breakpoints
, int debug_execution
)
960 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
961 struct arm
*arm
= &armv7a
->arm
;
965 if (!debug_execution
)
966 target_free_all_working_areas(target
);
971 /* Disable interrupts */
972 /* We disable interrupts in the PRIMASK register instead of
973 * masking with C_MASKINTS,
974 * This is probably the same issue as Cortex-M3 Errata 377493:
975 * C_MASKINTS in parallel with disabled interrupts can cause
976 * local faults to not be taken. */
977 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
978 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
979 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
981 /* Make sure we are in Thumb mode */
982 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
983 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
984 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
985 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
989 /* current = 1: continue on current pc, otherwise continue at <address> */
990 resume_pc
= buf_get_u32(arm
->pc
->value
, 0, 32);
992 resume_pc
= *address
;
994 *address
= resume_pc
;
996 /* Make sure that the Armv7 gdb thumb fixups does not
997 * kill the return address
999 switch (arm
->core_state
)
1002 resume_pc
&= 0xFFFFFFFC;
1004 case ARM_STATE_THUMB
:
1005 case ARM_STATE_THUMB_EE
:
1006 /* When the return address is loaded into PC
1007 * bit 0 must be 1 to stay in Thumb state
1011 case ARM_STATE_JAZELLE
:
1012 LOG_ERROR("How do I resume into Jazelle state??");
1015 LOG_DEBUG("resume pc = 0x%08" PRIx32
, resume_pc
);
1016 buf_set_u32(arm
->pc
->value
, 0, 32, resume_pc
);
1019 /* restore dpm_mode at system halt */
1020 dpm_modeswitch(&armv7a
->dpm
, ARM_MODE_ANY
);
1021 /* called it now before restoring context because it uses cpu
1022 * register r0 for restoring cp15 control register */
1023 retval
= cortex_a8_restore_cp15_control_reg(target
);
1024 if (retval
!= ERROR_OK
)
1026 retval
= cortex_a8_restore_context(target
, handle_breakpoints
);
1027 if (retval
!= ERROR_OK
)
1029 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1030 target
->state
= TARGET_RUNNING
;
1032 /* registers are now invalid */
1033 register_cache_invalidate(arm
->core_cache
);
1036 /* the front-end may request us not to handle breakpoints */
1037 if (handle_breakpoints
)
1039 /* Single step past breakpoint at current address */
1040 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
1042 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
1043 cortex_m3_unset_breakpoint(target
, breakpoint
);
1044 cortex_m3_single_step_core(target
);
1045 cortex_m3_set_breakpoint(target
, breakpoint
);
1053 static int cortex_a8_internal_restart(struct target
*target
)
1055 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1056 struct arm
*arm
= &armv7a
->arm
;
1057 struct adiv5_dap
*swjdp
= arm
->dap
;
1061 * Restart core and wait for it to be started. Clear ITRen and sticky
1062 * exception flags: see ARMv7 ARM, C5.9.
1064 * REVISIT: for single stepping, we probably want to
1065 * disable IRQs by default, with optional override...
1068 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
1069 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
1070 if (retval
!= ERROR_OK
)
1073 if ((dscr
& DSCR_INSTR_COMP
) == 0)
1074 LOG_ERROR("DSCR InstrCompl must be set before leaving debug!");
1076 retval
= mem_ap_sel_write_atomic_u32(swjdp
, swjdp_debugap
,
1077 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
& ~DSCR_ITR_EN
);
1078 if (retval
!= ERROR_OK
)
1081 retval
= mem_ap_sel_write_atomic_u32(swjdp
, swjdp_debugap
,
1082 armv7a
->debug_base
+ CPUDBG_DRCR
, DRCR_RESTART
|
1083 DRCR_CLEAR_EXCEPTIONS
);
1084 if (retval
!= ERROR_OK
)
1087 long long then
= timeval_ms();
1090 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
1091 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
1092 if (retval
!= ERROR_OK
)
1094 if ((dscr
& DSCR_CORE_RESTARTED
) != 0)
1096 if (timeval_ms() > then
+ 1000)
1098 LOG_ERROR("Timeout waiting for resume");
1103 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1104 target
->state
= TARGET_RUNNING
;
1106 /* registers are now invalid */
1107 register_cache_invalidate(arm
->core_cache
);
1112 static int cortex_a8_restore_smp(struct target
*target
,int handle_breakpoints
)
1115 struct target_list
*head
;
1116 struct target
*curr
;
1118 head
= target
->head
;
1119 while(head
!= (struct target_list
*)NULL
)
1121 curr
= head
->target
;
1122 if ((curr
!= target
) && (curr
->state
!= TARGET_RUNNING
))
1124 /* resume current address , not in step mode */
1125 retval
+= cortex_a8_internal_restore(curr
, 1, &address
,
1126 handle_breakpoints
, 0);
1127 retval
+= cortex_a8_internal_restart(curr
);
1135 static int cortex_a8_resume(struct target
*target
, int current
,
1136 uint32_t address
, int handle_breakpoints
, int debug_execution
)
1139 /* dummy resume for smp toggle in order to reduce gdb impact */
1140 if ((target
->smp
) && (target
->gdb_service
->core
[1]!=-1))
1142 /* simulate a start and halt of target */
1143 target
->gdb_service
->target
= NULL
;
1144 target
->gdb_service
->core
[0] = target
->gdb_service
->core
[1];
1145 /* fake resume at next poll we play the target core[1], see poll*/
1146 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1149 cortex_a8_internal_restore(target
, current
, &address
, handle_breakpoints
, debug_execution
);
1151 { target
->gdb_service
->core
[0] = -1;
1152 retval
= cortex_a8_restore_smp(target
, handle_breakpoints
);
1153 if (retval
!= ERROR_OK
)
1156 cortex_a8_internal_restart(target
);
1158 if (!debug_execution
)
1160 target
->state
= TARGET_RUNNING
;
1161 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1162 LOG_DEBUG("target resumed at 0x%" PRIx32
, address
);
1166 target
->state
= TARGET_DEBUG_RUNNING
;
1167 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1168 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, address
);
1174 static int cortex_a8_debug_entry(struct target
*target
)
1177 uint32_t regfile
[16], cpsr
, dscr
;
1178 int retval
= ERROR_OK
;
1179 struct working_area
*regfile_working_area
= NULL
;
1180 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1181 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1182 struct arm
*arm
= &armv7a
->arm
;
1183 struct adiv5_dap
*swjdp
= armv7a
->arm
.dap
;
1186 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
1188 /* REVISIT surely we should not re-read DSCR !! */
1189 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
1190 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
1191 if (retval
!= ERROR_OK
)
1194 /* REVISIT see A8 TRM 12.11.4 steps 2..3 -- make sure that any
1195 * imprecise data aborts get discarded by issuing a Data
1196 * Synchronization Barrier: ARMV4_5_MCR(15, 0, 0, 7, 10, 4).
1199 /* Enable the ITR execution once we are in debug mode */
1200 dscr
|= DSCR_ITR_EN
;
1201 retval
= mem_ap_sel_write_atomic_u32(swjdp
, swjdp_debugap
,
1202 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
);
1203 if (retval
!= ERROR_OK
)
1206 /* Examine debug reason */
1207 arm_dpm_report_dscr(&armv7a
->dpm
, cortex_a8
->cpudbg_dscr
);
1209 /* save address of instruction that triggered the watchpoint? */
1210 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
) {
1213 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
1214 armv7a
->debug_base
+ CPUDBG_WFAR
,
1216 if (retval
!= ERROR_OK
)
1218 arm_dpm_report_wfar(&armv7a
->dpm
, wfar
);
1221 /* REVISIT fast_reg_read is never set ... */
1223 /* Examine target state and mode */
1224 if (cortex_a8
->fast_reg_read
)
1225 target_alloc_working_area(target
, 64, ®file_working_area
);
1227 /* First load register acessible through core debug port*/
1228 if (!regfile_working_area
)
1230 retval
= arm_dpm_read_current_registers(&armv7a
->dpm
);
1234 retval
= cortex_a8_read_regs_through_mem(target
,
1235 regfile_working_area
->address
, regfile
);
1237 target_free_working_area(target
, regfile_working_area
);
1238 if (retval
!= ERROR_OK
)
1243 /* read Current PSR */
1244 retval
= cortex_a8_dap_read_coreregister_u32(target
, &cpsr
, 16);
1245 /* store current cpsr */
1246 if (retval
!= ERROR_OK
)
1249 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
1251 arm_set_cpsr(arm
, cpsr
);
1254 for (i
= 0; i
<= ARM_PC
; i
++)
1256 reg
= arm_reg_current(arm
, i
);
1258 buf_set_u32(reg
->value
, 0, 32, regfile
[i
]);
1263 /* Fixup PC Resume Address */
1264 if (cpsr
& (1 << 5))
1266 // T bit set for Thumb or ThumbEE state
1267 regfile
[ARM_PC
] -= 4;
1272 regfile
[ARM_PC
] -= 8;
1276 buf_set_u32(reg
->value
, 0, 32, regfile
[ARM_PC
]);
1277 reg
->dirty
= reg
->valid
;
1281 /* TODO, Move this */
1282 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
1283 cortex_a8_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
1284 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
1286 cortex_a8_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
1287 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
1289 cortex_a8_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
1290 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
1293 /* Are we in an exception handler */
1294 // armv4_5->exception_number = 0;
1295 if (armv7a
->post_debug_entry
)
1297 retval
= armv7a
->post_debug_entry(target
);
1298 if (retval
!= ERROR_OK
)
1305 static int cortex_a8_post_debug_entry(struct target
*target
)
1307 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1308 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1311 /* MRC p15,0,<Rt>,c1,c0,0 ; Read CP15 System Control Register */
1312 retval
= armv7a
->arm
.mrc(target
, 15,
1313 0, 0, /* op1, op2 */
1314 1, 0, /* CRn, CRm */
1315 &cortex_a8
->cp15_control_reg
);
1316 if (retval
!= ERROR_OK
)
1318 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
1319 cortex_a8
->cp15_control_reg_curr
= cortex_a8
->cp15_control_reg
;
1321 if (armv7a
->armv7a_mmu
.armv7a_cache
.ctype
== -1)
1323 armv7a_identify_cache(target
);
1326 armv7a
->armv7a_mmu
.mmu_enabled
=
1327 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
1328 armv7a
->armv7a_mmu
.armv7a_cache
.d_u_cache_enabled
=
1329 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
1330 armv7a
->armv7a_mmu
.armv7a_cache
.i_cache_enabled
=
1331 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
1332 cortex_a8
->curr_mode
= armv7a
->arm
.core_mode
;
1337 static int cortex_a8_step(struct target
*target
, int current
, uint32_t address
,
1338 int handle_breakpoints
)
1340 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1341 struct arm
*arm
= &armv7a
->arm
;
1342 struct breakpoint
*breakpoint
= NULL
;
1343 struct breakpoint stepbreakpoint
;
1347 if (target
->state
!= TARGET_HALTED
)
1349 LOG_WARNING("target not halted");
1350 return ERROR_TARGET_NOT_HALTED
;
1353 /* current = 1: continue on current pc, otherwise continue at <address> */
1357 buf_set_u32(r
->value
, 0, 32, address
);
1361 address
= buf_get_u32(r
->value
, 0, 32);
1364 /* The front-end may request us not to handle breakpoints.
1365 * But since Cortex-A8 uses breakpoint for single step,
1366 * we MUST handle breakpoints.
1368 handle_breakpoints
= 1;
1369 if (handle_breakpoints
) {
1370 breakpoint
= breakpoint_find(target
, address
);
1372 cortex_a8_unset_breakpoint(target
, breakpoint
);
1375 /* Setup single step breakpoint */
1376 stepbreakpoint
.address
= address
;
1377 stepbreakpoint
.length
= (arm
->core_state
== ARM_STATE_THUMB
)
1379 stepbreakpoint
.type
= BKPT_HARD
;
1380 stepbreakpoint
.set
= 0;
1382 /* Break on IVA mismatch */
1383 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
1385 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1387 retval
= cortex_a8_resume(target
, 1, address
, 0, 0);
1388 if (retval
!= ERROR_OK
)
1391 long long then
= timeval_ms();
1392 while (target
->state
!= TARGET_HALTED
)
1394 retval
= cortex_a8_poll(target
);
1395 if (retval
!= ERROR_OK
)
1397 if (timeval_ms() > then
+ 1000)
1399 LOG_ERROR("timeout waiting for target halt");
1404 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
1406 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1409 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
1411 if (target
->state
!= TARGET_HALTED
)
1412 LOG_DEBUG("target stepped");
1417 static int cortex_a8_restore_context(struct target
*target
, bool bpwp
)
1419 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1423 if (armv7a
->pre_restore_context
)
1424 armv7a
->pre_restore_context(target
);
1426 return arm_dpm_write_dirty_registers(&armv7a
->dpm
, bpwp
);
1431 * Cortex-A8 Breakpoint and watchpoint functions
1434 /* Setup hardware Breakpoint Register Pair */
1435 static int cortex_a8_set_breakpoint(struct target
*target
,
1436 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1441 uint8_t byte_addr_select
= 0x0F;
1442 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1443 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1444 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1446 if (breakpoint
->set
)
1448 LOG_WARNING("breakpoint already set");
1452 if (breakpoint
->type
== BKPT_HARD
)
1454 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
1456 if (brp_i
>= cortex_a8
->brp_num
)
1458 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1459 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1461 breakpoint
->set
= brp_i
+ 1;
1462 if (breakpoint
->length
== 2)
1464 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1466 control
= ((matchmode
& 0x7) << 20)
1467 | (byte_addr_select
<< 5)
1469 brp_list
[brp_i
].used
= 1;
1470 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1471 brp_list
[brp_i
].control
= control
;
1472 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1473 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1474 brp_list
[brp_i
].value
);
1475 if (retval
!= ERROR_OK
)
1477 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1478 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1479 brp_list
[brp_i
].control
);
1480 if (retval
!= ERROR_OK
)
1482 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1483 brp_list
[brp_i
].control
,
1484 brp_list
[brp_i
].value
);
1486 else if (breakpoint
->type
== BKPT_SOFT
)
1489 if (breakpoint
->length
== 2)
1491 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1495 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1497 retval
= target
->type
->read_memory(target
,
1498 breakpoint
->address
& 0xFFFFFFFE,
1499 breakpoint
->length
, 1,
1500 breakpoint
->orig_instr
);
1501 if (retval
!= ERROR_OK
)
1503 retval
= target
->type
->write_memory(target
,
1504 breakpoint
->address
& 0xFFFFFFFE,
1505 breakpoint
->length
, 1, code
);
1506 if (retval
!= ERROR_OK
)
1508 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1514 static int cortex_a8_set_context_breakpoint(struct target
*target
,
1515 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1517 int retval
= ERROR_FAIL
;
1520 uint8_t byte_addr_select
= 0x0F;
1521 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1522 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1523 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1525 if (breakpoint
->set
)
1527 LOG_WARNING("breakpoint already set");
1530 /*check available context BRPs*/
1531 while ((brp_list
[brp_i
].used
|| (brp_list
[brp_i
].type
!=BRP_CONTEXT
)) && (brp_i
< cortex_a8
->brp_num
))
1534 if (brp_i
>= cortex_a8
->brp_num
)
1536 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1540 breakpoint
->set
= brp_i
+ 1;
1541 control
= ((matchmode
& 0x7) << 20)
1542 | (byte_addr_select
<< 5)
1544 brp_list
[brp_i
].used
= 1;
1545 brp_list
[brp_i
].value
= (breakpoint
->asid
);
1546 brp_list
[brp_i
].control
= control
;
1547 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1548 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1549 brp_list
[brp_i
].value
);
1550 if(retval
!= ERROR_OK
)
1552 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1553 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1554 brp_list
[brp_i
].control
);
1555 if(retval
!= ERROR_OK
)
1557 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1558 brp_list
[brp_i
].control
,
1559 brp_list
[brp_i
].value
);
1564 static int cortex_a8_set_hybrid_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1566 int retval
= ERROR_FAIL
;
1567 int brp_1
=0; //holds the contextID pair
1568 int brp_2
=0; // holds the IVA pair
1569 uint32_t control_CTX
, control_IVA
;
1570 uint8_t CTX_byte_addr_select
= 0x0F;
1571 uint8_t IVA_byte_addr_select
= 0x0F;
1572 uint8_t CTX_machmode
= 0x03;
1573 uint8_t IVA_machmode
= 0x01;
1574 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1575 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1576 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1580 if (breakpoint
->set
)
1582 LOG_WARNING("breakpoint already set");
1585 /*check available context BRPs*/
1586 while ((brp_list
[brp_1
].used
|| (brp_list
[brp_1
].type
!=BRP_CONTEXT
)) && (brp_1
< cortex_a8
->brp_num
))
1589 printf("brp(CTX) found num: %d \n",brp_1
);
1590 if (brp_1
>= cortex_a8
->brp_num
)
1592 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1596 while ((brp_list
[brp_2
].used
|| (brp_list
[brp_2
].type
!=BRP_NORMAL
)) && (brp_2
< cortex_a8
->brp_num
))
1599 printf("brp(IVA) found num: %d \n",brp_2
);
1600 if (brp_2
>= cortex_a8
->brp_num
)
1602 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1606 breakpoint
->set
= brp_1
+ 1;
1607 breakpoint
->linked_BRP
= brp_2
;
1608 control_CTX
= ((CTX_machmode
& 0x7) << 20)
1611 | (CTX_byte_addr_select
<< 5)
1613 brp_list
[brp_1
].used
= 1;
1614 brp_list
[brp_1
].value
= (breakpoint
->asid
);
1615 brp_list
[brp_1
].control
= control_CTX
;
1616 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1617 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_1
].BRPn
,
1618 brp_list
[brp_1
].value
);
1619 if (retval
!= ERROR_OK
)
1621 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1622 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_1
].BRPn
,
1623 brp_list
[brp_1
].control
);
1624 if( retval
!= ERROR_OK
)
1627 control_IVA
= ((IVA_machmode
& 0x7) << 20)
1629 | (IVA_byte_addr_select
<< 5)
1631 brp_list
[brp_2
].used
= 1;
1632 brp_list
[brp_2
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1633 brp_list
[brp_2
].control
= control_IVA
;
1634 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1635 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_2
].BRPn
,
1636 brp_list
[brp_2
].value
);
1637 if (retval
!= ERROR_OK
)
1639 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1640 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_2
].BRPn
,
1641 brp_list
[brp_2
].control
);
1642 if (retval
!= ERROR_OK
)
1649 static int cortex_a8_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1652 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1653 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1654 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1656 if (!breakpoint
->set
)
1658 LOG_WARNING("breakpoint not set");
1662 if (breakpoint
->type
== BKPT_HARD
)
1664 if ((breakpoint
->address
!= 0) && (breakpoint
->asid
!= 0))
1666 int brp_i
= breakpoint
->set
- 1;
1667 int brp_j
= breakpoint
->linked_BRP
;
1668 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1670 LOG_DEBUG("Invalid BRP number in breakpoint");
1673 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1674 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1675 brp_list
[brp_i
].used
= 0;
1676 brp_list
[brp_i
].value
= 0;
1677 brp_list
[brp_i
].control
= 0;
1678 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1679 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1680 brp_list
[brp_i
].control
);
1681 if (retval
!= ERROR_OK
)
1683 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1684 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1685 brp_list
[brp_i
].value
);
1686 if (retval
!= ERROR_OK
)
1688 if ((brp_j
< 0) || (brp_j
>= cortex_a8
->brp_num
))
1690 LOG_DEBUG("Invalid BRP number in breakpoint");
1693 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_j
,
1694 brp_list
[brp_j
].control
, brp_list
[brp_j
].value
);
1695 brp_list
[brp_j
].used
= 0;
1696 brp_list
[brp_j
].value
= 0;
1697 brp_list
[brp_j
].control
= 0;
1698 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1699 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_j
].BRPn
,
1700 brp_list
[brp_j
].control
);
1701 if (retval
!= ERROR_OK
)
1703 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1704 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_j
].BRPn
,
1705 brp_list
[brp_j
].value
);
1706 if (retval
!= ERROR_OK
)
1708 breakpoint
->linked_BRP
= 0;
1709 breakpoint
->set
= 0;
1715 int brp_i
= breakpoint
->set
- 1;
1716 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1718 LOG_DEBUG("Invalid BRP number in breakpoint");
1721 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1722 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1723 brp_list
[brp_i
].used
= 0;
1724 brp_list
[brp_i
].value
= 0;
1725 brp_list
[brp_i
].control
= 0;
1726 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1727 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1728 brp_list
[brp_i
].control
);
1729 if (retval
!= ERROR_OK
)
1731 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1732 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1733 brp_list
[brp_i
].value
);
1734 if (retval
!= ERROR_OK
)
1736 breakpoint
->set
= 0;
1742 /* restore original instruction (kept in target endianness) */
1743 if (breakpoint
->length
== 4)
1745 retval
= target
->type
->write_memory(target
,
1746 breakpoint
->address
& 0xFFFFFFFE,
1747 4, 1, breakpoint
->orig_instr
);
1748 if (retval
!= ERROR_OK
)
1753 retval
= target
->type
->write_memory(target
,
1754 breakpoint
->address
& 0xFFFFFFFE,
1755 2, 1, breakpoint
->orig_instr
);
1756 if (retval
!= ERROR_OK
)
1760 breakpoint
->set
= 0;
1765 static int cortex_a8_add_breakpoint(struct target
*target
,
1766 struct breakpoint
*breakpoint
)
1768 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1770 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1772 LOG_INFO("no hardware breakpoint available");
1773 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1776 if (breakpoint
->type
== BKPT_HARD
)
1777 cortex_a8
->brp_num_available
--;
1779 return cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1782 static int cortex_a8_add_context_breakpoint(struct target
*target
,
1783 struct breakpoint
*breakpoint
)
1785 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1787 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1789 LOG_INFO("no hardware breakpoint available");
1790 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1793 if (breakpoint
->type
== BKPT_HARD
)
1794 cortex_a8
->brp_num_available
--;
1796 return cortex_a8_set_context_breakpoint(target
, breakpoint
, 0x02); /* asid match */
1799 static int cortex_a8_add_hybrid_breakpoint(struct target
*target
,
1800 struct breakpoint
*breakpoint
)
1802 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1804 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1806 LOG_INFO("no hardware breakpoint available");
1807 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1810 if (breakpoint
->type
== BKPT_HARD
)
1811 cortex_a8
->brp_num_available
--;
1813 return cortex_a8_set_hybrid_breakpoint(target
, breakpoint
); /* ??? */
1817 static int cortex_a8_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1819 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1822 /* It is perfectly possible to remove breakpoints while the target is running */
1823 if (target
->state
!= TARGET_HALTED
)
1825 LOG_WARNING("target not halted");
1826 return ERROR_TARGET_NOT_HALTED
;
1830 if (breakpoint
->set
)
1832 cortex_a8_unset_breakpoint(target
, breakpoint
);
1833 if (breakpoint
->type
== BKPT_HARD
)
1834 cortex_a8
->brp_num_available
++ ;
1844 * Cortex-A8 Reset functions
1847 static int cortex_a8_assert_reset(struct target
*target
)
1849 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1853 /* FIXME when halt is requested, make it work somehow... */
1855 /* Issue some kind of warm reset. */
1856 if (target_has_event_action(target
, TARGET_EVENT_RESET_ASSERT
)) {
1857 target_handle_event(target
, TARGET_EVENT_RESET_ASSERT
);
1858 } else if (jtag_get_reset_config() & RESET_HAS_SRST
) {
1859 /* REVISIT handle "pulls" cases, if there's
1860 * hardware that needs them to work.
1862 jtag_add_reset(0, 1);
1864 LOG_ERROR("%s: how to reset?", target_name(target
));
1868 /* registers are now invalid */
1869 register_cache_invalidate(armv7a
->arm
.core_cache
);
1871 target
->state
= TARGET_RESET
;
1876 static int cortex_a8_deassert_reset(struct target
*target
)
1882 /* be certain SRST is off */
1883 jtag_add_reset(0, 0);
1885 retval
= cortex_a8_poll(target
);
1886 if (retval
!= ERROR_OK
)
1889 if (target
->reset_halt
) {
1890 if (target
->state
!= TARGET_HALTED
) {
1891 LOG_WARNING("%s: ran after reset and before halt ...",
1892 target_name(target
));
1893 if ((retval
= target_halt(target
)) != ERROR_OK
)
1902 static int cortex_a8_write_apb_ab_memory(struct target
*target
,
1903 uint32_t address
, uint32_t size
,
1904 uint32_t count
, const uint8_t *buffer
)
1907 /* write memory through APB-AP */
1909 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
1910 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1911 struct arm
*arm
= &armv7a
->arm
;
1912 int total_bytes
= count
* size
;
1913 int start_byte
, nbytes_to_write
, i
;
1920 if (target
->state
!= TARGET_HALTED
)
1922 LOG_WARNING("target not halted");
1923 return ERROR_TARGET_NOT_HALTED
;
1926 reg
= arm_reg_current(arm
, 0);
1928 reg
= arm_reg_current(arm
, 1);
1931 retval
= cortex_a8_dap_write_coreregister_u32(target
, address
& 0xFFFFFFFC, 0);
1932 if (retval
!= ERROR_OK
)
1935 start_byte
= address
& 0x3;
1937 while (total_bytes
> 0) {
1939 nbytes_to_write
= 4 - start_byte
;
1940 if (total_bytes
< nbytes_to_write
)
1941 nbytes_to_write
= total_bytes
;
1943 if ( nbytes_to_write
!= 4 ) {
1945 /* execute instruction LDR r1, [r0] */
1946 retval
= cortex_a8_exec_opcode(target
, ARMV4_5_LDR(1, 0), NULL
);
1947 if (retval
!= ERROR_OK
)
1950 retval
= cortex_a8_dap_read_coreregister_u32(target
, &data
.ui
, 1);
1951 if (retval
!= ERROR_OK
)
1955 for (i
= 0; i
< nbytes_to_write
; ++i
)
1956 data
.uc_a
[i
+ start_byte
] = *buffer
++;
1958 retval
= cortex_a8_dap_write_coreregister_u32(target
, data
.ui
, 1);
1959 if (retval
!= ERROR_OK
)
1962 /* execute instruction STRW r1, [r0], 1 (0xe4801004) */
1963 retval
= cortex_a8_exec_opcode(target
, ARMV4_5_STRW_IP(1, 0) , NULL
);
1964 if (retval
!= ERROR_OK
)
1967 total_bytes
-= nbytes_to_write
;
1975 static int cortex_a8_read_apb_ab_memory(struct target
*target
,
1976 uint32_t address
, uint32_t size
,
1977 uint32_t count
, uint8_t *buffer
)
1980 /* read memory through APB-AP */
1982 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
1983 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1984 struct arm
*arm
= &armv7a
->arm
;
1985 int total_bytes
= count
* size
;
1986 int start_byte
, nbytes_to_read
, i
;
1993 if (target
->state
!= TARGET_HALTED
)
1995 LOG_WARNING("target not halted");
1996 return ERROR_TARGET_NOT_HALTED
;
1999 reg
= arm_reg_current(arm
, 0);
2001 reg
= arm_reg_current(arm
, 1);
2004 retval
= cortex_a8_dap_write_coreregister_u32(target
, address
& 0xFFFFFFFC, 0);
2005 if (retval
!= ERROR_OK
)
2008 start_byte
= address
& 0x3;
2010 while (total_bytes
> 0) {
2012 /* execute instruction LDRW r1, [r0], 4 (0xe4901004) */
2013 retval
= cortex_a8_exec_opcode(target
, ARMV4_5_LDRW_IP(1, 0), NULL
);
2014 if (retval
!= ERROR_OK
)
2017 retval
= cortex_a8_dap_read_coreregister_u32(target
, &data
.ui
, 1);
2018 if (retval
!= ERROR_OK
)
2021 nbytes_to_read
= 4 - start_byte
;
2022 if (total_bytes
< nbytes_to_read
)
2023 nbytes_to_read
= total_bytes
;
2025 for (i
= 0; i
< nbytes_to_read
; ++i
)
2026 *buffer
++ = data
.uc_a
[i
+ start_byte
];
2028 total_bytes
-= nbytes_to_read
;
2038 * Cortex-A8 Memory access
2040 * This is same Cortex M3 but we must also use the correct
2041 * ap number for every access.
2044 static int cortex_a8_read_phys_memory(struct target
*target
,
2045 uint32_t address
, uint32_t size
,
2046 uint32_t count
, uint8_t *buffer
)
2048 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
2049 struct adiv5_dap
*swjdp
= armv7a
->arm
.dap
;
2050 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
2051 uint8_t apsel
= swjdp
->apsel
;
2052 LOG_DEBUG("Reading memory at real address 0x%x; size %d; count %d",
2053 address
, size
, count
);
2055 if (count
&& buffer
) {
2057 if ( apsel
== swjdp_memoryap
) {
2059 /* read memory through AHB-AP */
2063 retval
= mem_ap_sel_read_buf_u32(swjdp
, swjdp_memoryap
,
2064 buffer
, 4 * count
, address
);
2067 retval
= mem_ap_sel_read_buf_u16(swjdp
, swjdp_memoryap
,
2068 buffer
, 2 * count
, address
);
2071 retval
= mem_ap_sel_read_buf_u8(swjdp
, swjdp_memoryap
,
2072 buffer
, count
, address
);
2077 /* read memory through APB-AP */
2079 retval
= cortex_a8_mmu_modify(target
, 0);
2080 if (retval
!= ERROR_OK
) return retval
;
2081 retval
= cortex_a8_read_apb_ab_memory(target
, address
, size
, count
, buffer
);
2087 static int cortex_a8_read_memory(struct target
*target
, uint32_t address
,
2088 uint32_t size
, uint32_t count
, uint8_t *buffer
)
2091 uint32_t virt
, phys
;
2093 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
2094 struct adiv5_dap
*swjdp
= armv7a
->arm
.dap
;
2095 uint8_t apsel
= swjdp
->apsel
;
2097 /* cortex_a8 handles unaligned memory access */
2098 LOG_DEBUG("Reading memory at address 0x%x; size %d; count %d", address
,
2100 if (apsel
== swjdp_memoryap
) {
2101 retval
= cortex_a8_mmu(target
, &enabled
);
2102 if (retval
!= ERROR_OK
)
2109 retval
= cortex_a8_virt2phys(target
, virt
, &phys
);
2110 if (retval
!= ERROR_OK
)
2113 LOG_DEBUG("Reading at virtual address. Translating v:0x%x to r:0x%x",
2117 retval
= cortex_a8_read_phys_memory(target
, address
, size
, count
, buffer
);
2119 retval
= cortex_a8_check_address(target
, address
);
2120 if (retval
!= ERROR_OK
) return retval
;
2122 retval
= cortex_a8_mmu_modify(target
, 1);
2123 if (retval
!= ERROR_OK
) return retval
;
2124 retval
= cortex_a8_read_apb_ab_memory(target
, address
, size
, count
, buffer
);
2129 static int cortex_a8_write_phys_memory(struct target
*target
,
2130 uint32_t address
, uint32_t size
,
2131 uint32_t count
, const uint8_t *buffer
)
2133 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
2134 struct adiv5_dap
*swjdp
= armv7a
->arm
.dap
;
2135 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
2136 uint8_t apsel
= swjdp
->apsel
;
2138 LOG_DEBUG("Writing memory to real address 0x%x; size %d; count %d", address
,
2141 if (count
&& buffer
) {
2143 if ( apsel
== swjdp_memoryap
) {
2145 /* write memory through AHB-AP */
2149 retval
= mem_ap_sel_write_buf_u32(swjdp
, swjdp_memoryap
,
2150 buffer
, 4 * count
, address
);
2153 retval
= mem_ap_sel_write_buf_u16(swjdp
, swjdp_memoryap
,
2154 buffer
, 2 * count
, address
);
2157 retval
= mem_ap_sel_write_buf_u8(swjdp
, swjdp_memoryap
,
2158 buffer
, count
, address
);
2164 /* write memory through APB-AP */
2165 retval
= cortex_a8_mmu_modify(target
, 0);
2166 if (retval
!= ERROR_OK
)
2168 return cortex_a8_write_apb_ab_memory(target
, address
, size
, count
, buffer
);
2173 /* REVISIT this op is generic ARMv7-A/R stuff */
2174 if (retval
== ERROR_OK
&& target
->state
== TARGET_HALTED
)
2176 struct arm_dpm
*dpm
= armv7a
->arm
.dpm
;
2178 retval
= dpm
->prepare(dpm
);
2179 if (retval
!= ERROR_OK
)
2182 /* The Cache handling will NOT work with MMU active, the
2183 * wrong addresses will be invalidated!
2185 * For both ICache and DCache, walk all cache lines in the
2186 * address range. Cortex-A8 has fixed 64 byte line length.
2188 * REVISIT per ARMv7, these may trigger watchpoints ...
2191 /* invalidate I-Cache */
2192 if (armv7a
->armv7a_mmu
.armv7a_cache
.i_cache_enabled
)
2194 /* ICIMVAU - Invalidate Cache single entry
2196 * MCR p15, 0, r0, c7, c5, 1
2198 for (uint32_t cacheline
= address
;
2199 cacheline
< address
+ size
* count
;
2201 retval
= dpm
->instr_write_data_r0(dpm
,
2202 ARMV4_5_MCR(15, 0, 0, 7, 5, 1),
2204 if (retval
!= ERROR_OK
)
2209 /* invalidate D-Cache */
2210 if (armv7a
->armv7a_mmu
.armv7a_cache
.d_u_cache_enabled
)
2212 /* DCIMVAC - Invalidate data Cache line
2214 * MCR p15, 0, r0, c7, c6, 1
2216 for (uint32_t cacheline
= address
;
2217 cacheline
< address
+ size
* count
;
2219 retval
= dpm
->instr_write_data_r0(dpm
,
2220 ARMV4_5_MCR(15, 0, 0, 7, 6, 1),
2222 if (retval
!= ERROR_OK
)
2227 /* (void) */ dpm
->finish(dpm
);
2233 static int cortex_a8_write_memory(struct target
*target
, uint32_t address
,
2234 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
2237 uint32_t virt
, phys
;
2239 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
2240 struct adiv5_dap
*swjdp
= armv7a
->arm
.dap
;
2241 uint8_t apsel
= swjdp
->apsel
;
2242 /* cortex_a8 handles unaligned memory access */
2243 LOG_DEBUG("Reading memory at address 0x%x; size %d; count %d", address
,
2245 if (apsel
== swjdp_memoryap
) {
2247 LOG_DEBUG("Writing memory to address 0x%x; size %d; count %d", address
, size
, count
);
2248 retval
= cortex_a8_mmu(target
, &enabled
);
2249 if (retval
!= ERROR_OK
)
2255 retval
= cortex_a8_virt2phys(target
, virt
, &phys
);
2256 if (retval
!= ERROR_OK
)
2258 LOG_DEBUG("Writing to virtual address. Translating v:0x%x to r:0x%x", virt
, phys
);
2262 retval
= cortex_a8_write_phys_memory(target
, address
, size
,
2266 retval
= cortex_a8_check_address(target
, address
);
2267 if (retval
!= ERROR_OK
) return retval
;
2269 retval
= cortex_a8_mmu_modify(target
, 1);
2270 if (retval
!= ERROR_OK
) return retval
;
2271 retval
= cortex_a8_write_apb_ab_memory(target
, address
, size
, count
, buffer
);
2276 static int cortex_a8_bulk_write_memory(struct target
*target
, uint32_t address
,
2277 uint32_t count
, const uint8_t *buffer
)
2279 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
2283 static int cortex_a8_handle_target_request(void *priv
)
2285 struct target
*target
= priv
;
2286 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
2287 struct adiv5_dap
*swjdp
= armv7a
->arm
.dap
;
2290 if (!target_was_examined(target
))
2292 if (!target
->dbg_msg_enabled
)
2295 if (target
->state
== TARGET_RUNNING
)
2299 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
2300 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
2302 /* check if we have data */
2303 while ((dscr
& DSCR_DTR_TX_FULL
) && (retval
==ERROR_OK
))
2305 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
2306 armv7a
->debug_base
+ CPUDBG_DTRTX
, &request
);
2307 if (retval
== ERROR_OK
)
2309 target_request(target
, request
);
2310 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
2311 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
2320 * Cortex-A8 target information and configuration
2323 static int cortex_a8_examine_first(struct target
*target
)
2325 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
2326 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
2327 struct adiv5_dap
*swjdp
= armv7a
->arm
.dap
;
2329 int retval
= ERROR_OK
;
2330 uint32_t didr
, ctypr
, ttypr
, cpuid
;
2332 /* We do one extra read to ensure DAP is configured,
2333 * we call ahbap_debugport_init(swjdp) instead
2335 retval
= ahbap_debugport_init(swjdp
);
2336 if (retval
!= ERROR_OK
)
2339 if (!target
->dbgbase_set
)
2342 /* Get ROM Table base */
2344 retval
= dap_get_debugbase(swjdp
, 1, &dbgbase
, &apid
);
2345 if (retval
!= ERROR_OK
)
2347 /* Lookup 0x15 -- Processor DAP */
2348 retval
= dap_lookup_cs_component(swjdp
, 1, dbgbase
, 0x15,
2349 &armv7a
->debug_base
);
2350 if (retval
!= ERROR_OK
)
2355 armv7a
->debug_base
= target
->dbgbase
;
2358 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
2359 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
2360 if (retval
!= ERROR_OK
)
2363 if ((retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
2364 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
2366 LOG_DEBUG("Examine %s failed", "CPUID");
2370 if ((retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
2371 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
2373 LOG_DEBUG("Examine %s failed", "CTYPR");
2377 if ((retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
2378 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
2380 LOG_DEBUG("Examine %s failed", "TTYPR");
2384 if ((retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
2385 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
2387 LOG_DEBUG("Examine %s failed", "DIDR");
2391 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
2392 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
2393 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
2394 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
2396 armv7a
->arm
.core_type
= ARM_MODE_MON
;
2397 retval
= cortex_a8_dpm_setup(cortex_a8
, didr
);
2398 if (retval
!= ERROR_OK
)
2401 /* Setup Breakpoint Register Pairs */
2402 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
2403 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
2404 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
2405 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(struct cortex_a8_brp
));
2406 // cortex_a8->brb_enabled = ????;
2407 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
2409 cortex_a8
->brp_list
[i
].used
= 0;
2410 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
2411 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
2413 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
2414 cortex_a8
->brp_list
[i
].value
= 0;
2415 cortex_a8
->brp_list
[i
].control
= 0;
2416 cortex_a8
->brp_list
[i
].BRPn
= i
;
2419 LOG_DEBUG("Configured %i hw breakpoints", cortex_a8
->brp_num
);
2421 target_set_examined(target
);
2425 static int cortex_a8_examine(struct target
*target
)
2427 int retval
= ERROR_OK
;
2429 /* don't re-probe hardware after each reset */
2430 if (!target_was_examined(target
))
2431 retval
= cortex_a8_examine_first(target
);
2433 /* Configure core debug access */
2434 if (retval
== ERROR_OK
)
2435 retval
= cortex_a8_init_debug_access(target
);
2441 * Cortex-A8 target creation and initialization
2444 static int cortex_a8_init_target(struct command_context
*cmd_ctx
,
2445 struct target
*target
)
2447 /* examine_first() does a bunch of this */
2451 static int cortex_a8_init_arch_info(struct target
*target
,
2452 struct cortex_a8_common
*cortex_a8
, struct jtag_tap
*tap
)
2454 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
2455 struct adiv5_dap
*dap
= &armv7a
->dap
;
2457 armv7a
->arm
.dap
= dap
;
2459 /* Setup struct cortex_a8_common */
2460 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
2461 /* tap has no dap initialized */
2464 armv7a
->arm
.dap
= dap
;
2465 /* Setup struct cortex_a8_common */
2467 /* prepare JTAG information for the new target */
2468 cortex_a8
->jtag_info
.tap
= tap
;
2469 cortex_a8
->jtag_info
.scann_size
= 4;
2471 /* Leave (only) generic DAP stuff for debugport_init() */
2472 dap
->jtag_info
= &cortex_a8
->jtag_info
;
2474 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
2475 dap
->tar_autoincr_block
= (1 << 10);
2476 dap
->memaccess_tck
= 80;
2480 armv7a
->arm
.dap
= tap
->dap
;
2482 cortex_a8
->fast_reg_read
= 0;
2484 /* register arch-specific functions */
2485 armv7a
->examine_debug_reason
= NULL
;
2487 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
2489 armv7a
->pre_restore_context
= NULL
;
2491 armv7a
->armv7a_mmu
.read_physical_memory
= cortex_a8_read_phys_memory
;
2494 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
2496 /* REVISIT v7a setup should be in a v7a-specific routine */
2497 armv7a_init_arch_info(target
, armv7a
);
2498 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
2503 static int cortex_a8_target_create(struct target
*target
, Jim_Interp
*interp
)
2505 struct cortex_a8_common
*cortex_a8
= calloc(1, sizeof(struct cortex_a8_common
));
2507 return cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
2512 static int cortex_a8_mmu(struct target
*target
, int *enabled
)
2514 if (target
->state
!= TARGET_HALTED
) {
2515 LOG_ERROR("%s: target not halted", __func__
);
2516 return ERROR_TARGET_INVALID
;
2519 *enabled
= target_to_cortex_a8(target
)->armv7a_common
.armv7a_mmu
.mmu_enabled
;
2523 static int cortex_a8_virt2phys(struct target
*target
,
2524 uint32_t virt
, uint32_t *phys
)
2526 int retval
= ERROR_FAIL
;
2527 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
2528 struct adiv5_dap
*swjdp
= armv7a
->arm
.dap
;
2529 uint8_t apsel
= swjdp
->apsel
;
2530 if (apsel
== swjdp_memoryap
)
2533 retval
= armv7a_mmu_translate_va(target
,
2535 if (retval
!= ERROR_OK
)
2540 { /* use this method if swjdp_memoryap not selected */
2541 /* mmu must be enable in order to get a correct translation */
2542 retval
= cortex_a8_mmu_modify(target
, 1);
2543 if (retval
!= ERROR_OK
) goto done
;
2544 retval
= armv7a_mmu_translate_va_pa(target
, virt
, phys
, 1);
2550 COMMAND_HANDLER(cortex_a8_handle_cache_info_command
)
2552 struct target
*target
= get_current_target(CMD_CTX
);
2553 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
2555 return armv7a_handle_cache_info_command(CMD_CTX
,
2556 &armv7a
->armv7a_mmu
.armv7a_cache
);
2560 COMMAND_HANDLER(cortex_a8_handle_dbginit_command
)
2562 struct target
*target
= get_current_target(CMD_CTX
);
2563 if (!target_was_examined(target
))
2565 LOG_ERROR("target not examined yet");
2569 return cortex_a8_init_debug_access(target
);
2571 COMMAND_HANDLER(cortex_a8_handle_smp_off_command
)
2573 struct target
*target
= get_current_target(CMD_CTX
);
2574 /* check target is an smp target */
2575 struct target_list
*head
;
2576 struct target
*curr
;
2577 head
= target
->head
;
2579 if (head
!= (struct target_list
*)NULL
)
2581 while (head
!= (struct target_list
*)NULL
)
2583 curr
= head
->target
;
2587 /* fixes the target display to the debugger */
2588 target
->gdb_service
->target
= target
;
2593 COMMAND_HANDLER(cortex_a8_handle_smp_on_command
)
2595 struct target
*target
= get_current_target(CMD_CTX
);
2596 struct target_list
*head
;
2597 struct target
*curr
;
2598 head
= target
->head
;
2599 if (head
!= (struct target_list
*)NULL
)
2601 while (head
!= (struct target_list
*)NULL
)
2603 curr
= head
->target
;
2611 COMMAND_HANDLER(cortex_a8_handle_smp_gdb_command
)
2613 struct target
*target
= get_current_target(CMD_CTX
);
2614 int retval
= ERROR_OK
;
2615 struct target_list
*head
;
2616 head
= target
->head
;
2617 if (head
!= (struct target_list
*)NULL
)
2622 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], coreid
);
2623 if (ERROR_OK
!= retval
)
2625 target
->gdb_service
->core
[1]=coreid
;
2628 command_print(CMD_CTX
, "gdb coreid %d -> %d", target
->gdb_service
->core
[0]
2629 , target
->gdb_service
->core
[1]);
2634 static const struct command_registration cortex_a8_exec_command_handlers
[] = {
2636 .name
= "cache_info",
2637 .handler
= cortex_a8_handle_cache_info_command
,
2638 .mode
= COMMAND_EXEC
,
2639 .help
= "display information about target caches",
2644 .handler
= cortex_a8_handle_dbginit_command
,
2645 .mode
= COMMAND_EXEC
,
2646 .help
= "Initialize core debug",
2650 .handler
= cortex_a8_handle_smp_off_command
,
2651 .mode
= COMMAND_EXEC
,
2652 .help
= "Stop smp handling",
2657 .handler
= cortex_a8_handle_smp_on_command
,
2658 .mode
= COMMAND_EXEC
,
2659 .help
= "Restart smp handling",
2664 .handler
= cortex_a8_handle_smp_gdb_command
,
2665 .mode
= COMMAND_EXEC
,
2666 .help
= "display/fix current core played to gdb",
2671 COMMAND_REGISTRATION_DONE
2673 static const struct command_registration cortex_a8_command_handlers
[] = {
2675 .chain
= arm_command_handlers
,
2678 .chain
= armv7a_command_handlers
,
2681 .name
= "cortex_a8",
2682 .mode
= COMMAND_ANY
,
2683 .help
= "Cortex-A8 command group",
2685 .chain
= cortex_a8_exec_command_handlers
,
2687 COMMAND_REGISTRATION_DONE
2690 struct target_type cortexa8_target
= {
2691 .name
= "cortex_a8",
2693 .poll
= cortex_a8_poll
,
2694 .arch_state
= armv7a_arch_state
,
2696 .target_request_data
= NULL
,
2698 .halt
= cortex_a8_halt
,
2699 .resume
= cortex_a8_resume
,
2700 .step
= cortex_a8_step
,
2702 .assert_reset
= cortex_a8_assert_reset
,
2703 .deassert_reset
= cortex_a8_deassert_reset
,
2704 .soft_reset_halt
= NULL
,
2706 /* REVISIT allow exporting VFP3 registers ... */
2707 .get_gdb_reg_list
= arm_get_gdb_reg_list
,
2709 .read_memory
= cortex_a8_read_memory
,
2710 .write_memory
= cortex_a8_write_memory
,
2711 .bulk_write_memory
= cortex_a8_bulk_write_memory
,
2713 .checksum_memory
= arm_checksum_memory
,
2714 .blank_check_memory
= arm_blank_check_memory
,
2716 .run_algorithm
= armv4_5_run_algorithm
,
2718 .add_breakpoint
= cortex_a8_add_breakpoint
,
2719 .add_context_breakpoint
= cortex_a8_add_context_breakpoint
,
2720 .add_hybrid_breakpoint
= cortex_a8_add_hybrid_breakpoint
,
2721 .remove_breakpoint
= cortex_a8_remove_breakpoint
,
2722 .add_watchpoint
= NULL
,
2723 .remove_watchpoint
= NULL
,
2725 .commands
= cortex_a8_command_handlers
,
2726 .target_create
= cortex_a8_target_create
,
2727 .init_target
= cortex_a8_init_target
,
2728 .examine
= cortex_a8_examine
,
2730 .read_phys_memory
= cortex_a8_read_phys_memory
,
2731 .write_phys_memory
= cortex_a8_write_phys_memory
,
2732 .mmu
= cortex_a8_mmu
,
2733 .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)