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
->armv4_5_common
.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
->armv4_5_common
.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
->armv4_5_common
.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
->armv4_5_common
.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
->armv4_5_common
.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
->armv4_5_common
.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
->armv4_5_common
.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
->armv4_5_common
.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
->armv4_5_common
.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
->armv4_5_common
.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
.armv4_5_common
.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
.armv4_5_common
.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
.armv4_5_common
.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
.armv4_5_common
.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
.armv4_5_common
.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
.armv4_5_common
.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
.armv4_5_common
.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
.armv4_5_common
.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
.armv4_5_common
.target
,
667 if (retval
!= ERROR_OK
)
670 /* write R0 to DCC */
671 retval
= cortex_a8_exec_opcode(
672 a8
->armv7a_common
.armv4_5_common
.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
.armv4_5_common
;
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
->armv4_5_common
.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
->armv4_5_common
.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
*armv4_5
= &armv7a
->armv4_5_common
;
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(armv4_5
->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 (armv4_5
->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(armv4_5
->pc
->value
, 0, 32, resume_pc
);
1017 armv4_5
->pc
->dirty
= 1;
1018 armv4_5
->pc
->valid
= 1;
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 retval
= cortex_a8_restore_context(target
, handle_breakpoints
);
1025 if (retval
!= ERROR_OK
)
1027 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1028 target
->state
= TARGET_RUNNING
;
1030 /* registers are now invalid */
1031 register_cache_invalidate(armv4_5
->core_cache
);
1034 /* the front-end may request us not to handle breakpoints */
1035 if (handle_breakpoints
)
1037 /* Single step past breakpoint at current address */
1038 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
1040 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
1041 cortex_m3_unset_breakpoint(target
, breakpoint
);
1042 cortex_m3_single_step_core(target
);
1043 cortex_m3_set_breakpoint(target
, breakpoint
);
1051 static int cortex_a8_internal_restart(struct target
*target
)
1053 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1054 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
1055 struct adiv5_dap
*swjdp
= armv4_5
->dap
;
1059 * Restart core and wait for it to be started. Clear ITRen and sticky
1060 * exception flags: see ARMv7 ARM, C5.9.
1062 * REVISIT: for single stepping, we probably want to
1063 * disable IRQs by default, with optional override...
1066 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
1067 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
1068 if (retval
!= ERROR_OK
)
1071 if ((dscr
& DSCR_INSTR_COMP
) == 0)
1072 LOG_ERROR("DSCR InstrCompl must be set before leaving debug!");
1074 retval
= mem_ap_sel_write_atomic_u32(swjdp
, swjdp_debugap
,
1075 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
& ~DSCR_ITR_EN
);
1076 if (retval
!= ERROR_OK
)
1079 retval
= mem_ap_sel_write_atomic_u32(swjdp
, swjdp_debugap
,
1080 armv7a
->debug_base
+ CPUDBG_DRCR
, DRCR_RESTART
|
1081 DRCR_CLEAR_EXCEPTIONS
);
1082 if (retval
!= ERROR_OK
)
1085 long long then
= timeval_ms();
1088 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
1089 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
1090 if (retval
!= ERROR_OK
)
1092 if ((dscr
& DSCR_CORE_RESTARTED
) != 0)
1094 if (timeval_ms() > then
+ 1000)
1096 LOG_ERROR("Timeout waiting for resume");
1101 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1102 target
->state
= TARGET_RUNNING
;
1104 /* registers are now invalid */
1105 register_cache_invalidate(armv4_5
->core_cache
);
1110 static int cortex_a8_restore_smp(struct target
*target
,int handle_breakpoints
)
1113 struct target_list
*head
;
1114 struct target
*curr
;
1116 head
= target
->head
;
1117 while(head
!= (struct target_list
*)NULL
)
1119 curr
= head
->target
;
1120 if ((curr
!= target
) && (curr
->state
!= TARGET_RUNNING
))
1122 /* resume current address , not in step mode */
1123 retval
+= cortex_a8_internal_restore(curr
, 1, &address
,
1124 handle_breakpoints
, 0);
1125 retval
+= cortex_a8_internal_restart(curr
);
1133 static int cortex_a8_resume(struct target
*target
, int current
,
1134 uint32_t address
, int handle_breakpoints
, int debug_execution
)
1137 /* dummy resume for smp toggle in order to reduce gdb impact */
1138 if ((target
->smp
) && (target
->gdb_service
->core
[1]!=-1))
1140 /* simulate a start and halt of target */
1141 target
->gdb_service
->target
= NULL
;
1142 target
->gdb_service
->core
[0] = target
->gdb_service
->core
[1];
1143 /* fake resume at next poll we play the target core[1], see poll*/
1144 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1147 cortex_a8_internal_restore(target
, current
, &address
, handle_breakpoints
, debug_execution
);
1149 { target
->gdb_service
->core
[0] = -1;
1150 retval
+= cortex_a8_restore_smp(target
, handle_breakpoints
);
1152 cortex_a8_internal_restart(target
);
1154 if (!debug_execution
)
1156 target
->state
= TARGET_RUNNING
;
1157 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1158 LOG_DEBUG("target resumed at 0x%" PRIx32
, address
);
1162 target
->state
= TARGET_DEBUG_RUNNING
;
1163 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1164 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, address
);
1170 static int cortex_a8_debug_entry(struct target
*target
)
1173 uint32_t regfile
[16], cpsr
, dscr
;
1174 int retval
= ERROR_OK
;
1175 struct working_area
*regfile_working_area
= NULL
;
1176 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1177 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1178 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
1179 struct adiv5_dap
*swjdp
= armv7a
->armv4_5_common
.dap
;
1182 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
1184 /* REVISIT surely we should not re-read DSCR !! */
1185 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
1186 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
1187 if (retval
!= ERROR_OK
)
1190 /* REVISIT see A8 TRM 12.11.4 steps 2..3 -- make sure that any
1191 * imprecise data aborts get discarded by issuing a Data
1192 * Synchronization Barrier: ARMV4_5_MCR(15, 0, 0, 7, 10, 4).
1195 /* Enable the ITR execution once we are in debug mode */
1196 dscr
|= DSCR_ITR_EN
;
1197 retval
= mem_ap_sel_write_atomic_u32(swjdp
, swjdp_debugap
,
1198 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
);
1199 if (retval
!= ERROR_OK
)
1202 /* Examine debug reason */
1203 arm_dpm_report_dscr(&armv7a
->dpm
, cortex_a8
->cpudbg_dscr
);
1205 /* save address of instruction that triggered the watchpoint? */
1206 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
) {
1209 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
1210 armv7a
->debug_base
+ CPUDBG_WFAR
,
1212 if (retval
!= ERROR_OK
)
1214 arm_dpm_report_wfar(&armv7a
->dpm
, wfar
);
1217 /* REVISIT fast_reg_read is never set ... */
1219 /* Examine target state and mode */
1220 if (cortex_a8
->fast_reg_read
)
1221 target_alloc_working_area(target
, 64, ®file_working_area
);
1223 /* First load register acessible through core debug port*/
1224 if (!regfile_working_area
)
1226 retval
= arm_dpm_read_current_registers(&armv7a
->dpm
);
1230 retval
= cortex_a8_read_regs_through_mem(target
,
1231 regfile_working_area
->address
, regfile
);
1233 target_free_working_area(target
, regfile_working_area
);
1234 if (retval
!= ERROR_OK
)
1239 /* read Current PSR */
1240 retval
= cortex_a8_dap_read_coreregister_u32(target
, &cpsr
, 16);
1241 /* store current cpsr */
1242 if (retval
!= ERROR_OK
)
1245 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
1247 arm_set_cpsr(armv4_5
, cpsr
);
1250 for (i
= 0; i
<= ARM_PC
; i
++)
1252 reg
= arm_reg_current(armv4_5
, i
);
1254 buf_set_u32(reg
->value
, 0, 32, regfile
[i
]);
1259 /* Fixup PC Resume Address */
1260 if (cpsr
& (1 << 5))
1262 // T bit set for Thumb or ThumbEE state
1263 regfile
[ARM_PC
] -= 4;
1268 regfile
[ARM_PC
] -= 8;
1272 buf_set_u32(reg
->value
, 0, 32, regfile
[ARM_PC
]);
1273 reg
->dirty
= reg
->valid
;
1277 /* TODO, Move this */
1278 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
1279 cortex_a8_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
1280 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
1282 cortex_a8_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
1283 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
1285 cortex_a8_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
1286 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
1289 /* Are we in an exception handler */
1290 // armv4_5->exception_number = 0;
1291 if (armv7a
->post_debug_entry
)
1293 retval
= armv7a
->post_debug_entry(target
);
1294 if (retval
!= ERROR_OK
)
1301 static int cortex_a8_post_debug_entry(struct target
*target
)
1303 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1304 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1307 /* MRC p15,0,<Rt>,c1,c0,0 ; Read CP15 System Control Register */
1308 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
1309 0, 0, /* op1, op2 */
1310 1, 0, /* CRn, CRm */
1311 &cortex_a8
->cp15_control_reg
);
1312 if (retval
!= ERROR_OK
)
1314 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
1315 cortex_a8
->cp15_control_reg_curr
= cortex_a8
->cp15_control_reg
;
1317 if (armv7a
->armv7a_mmu
.armv7a_cache
.ctype
== -1)
1319 armv7a_identify_cache(target
);
1322 armv7a
->armv7a_mmu
.mmu_enabled
=
1323 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
1324 armv7a
->armv7a_mmu
.armv7a_cache
.d_u_cache_enabled
=
1325 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
1326 armv7a
->armv7a_mmu
.armv7a_cache
.i_cache_enabled
=
1327 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
1328 cortex_a8
->curr_mode
= armv7a
->armv4_5_common
.core_mode
;
1333 static int cortex_a8_step(struct target
*target
, int current
, uint32_t address
,
1334 int handle_breakpoints
)
1336 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1337 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
1338 struct breakpoint
*breakpoint
= NULL
;
1339 struct breakpoint stepbreakpoint
;
1343 if (target
->state
!= TARGET_HALTED
)
1345 LOG_WARNING("target not halted");
1346 return ERROR_TARGET_NOT_HALTED
;
1349 /* current = 1: continue on current pc, otherwise continue at <address> */
1353 buf_set_u32(r
->value
, 0, 32, address
);
1357 address
= buf_get_u32(r
->value
, 0, 32);
1360 /* The front-end may request us not to handle breakpoints.
1361 * But since Cortex-A8 uses breakpoint for single step,
1362 * we MUST handle breakpoints.
1364 handle_breakpoints
= 1;
1365 if (handle_breakpoints
) {
1366 breakpoint
= breakpoint_find(target
, address
);
1368 cortex_a8_unset_breakpoint(target
, breakpoint
);
1371 /* Setup single step breakpoint */
1372 stepbreakpoint
.address
= address
;
1373 stepbreakpoint
.length
= (armv4_5
->core_state
== ARM_STATE_THUMB
)
1375 stepbreakpoint
.type
= BKPT_HARD
;
1376 stepbreakpoint
.set
= 0;
1378 /* Break on IVA mismatch */
1379 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
1381 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1383 retval
= cortex_a8_resume(target
, 1, address
, 0, 0);
1384 if (retval
!= ERROR_OK
)
1387 long long then
= timeval_ms();
1388 while (target
->state
!= TARGET_HALTED
)
1390 retval
= cortex_a8_poll(target
);
1391 if (retval
!= ERROR_OK
)
1393 if (timeval_ms() > then
+ 1000)
1395 LOG_ERROR("timeout waiting for target halt");
1400 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
1402 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1405 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
1407 if (target
->state
!= TARGET_HALTED
)
1408 LOG_DEBUG("target stepped");
1413 static int cortex_a8_restore_context(struct target
*target
, bool bpwp
)
1415 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1419 if (armv7a
->pre_restore_context
)
1420 armv7a
->pre_restore_context(target
);
1422 return arm_dpm_write_dirty_registers(&armv7a
->dpm
, bpwp
);
1427 * Cortex-A8 Breakpoint and watchpoint functions
1430 /* Setup hardware Breakpoint Register Pair */
1431 static int cortex_a8_set_breakpoint(struct target
*target
,
1432 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1437 uint8_t byte_addr_select
= 0x0F;
1438 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1439 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1440 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1442 if (breakpoint
->set
)
1444 LOG_WARNING("breakpoint already set");
1448 if (breakpoint
->type
== BKPT_HARD
)
1450 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
1452 if (brp_i
>= cortex_a8
->brp_num
)
1454 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1455 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1457 breakpoint
->set
= brp_i
+ 1;
1458 if (breakpoint
->length
== 2)
1460 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1462 control
= ((matchmode
& 0x7) << 20)
1463 | (byte_addr_select
<< 5)
1465 brp_list
[brp_i
].used
= 1;
1466 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1467 brp_list
[brp_i
].control
= control
;
1468 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1469 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1470 brp_list
[brp_i
].value
);
1471 if (retval
!= ERROR_OK
)
1473 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1474 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1475 brp_list
[brp_i
].control
);
1476 if (retval
!= ERROR_OK
)
1478 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1479 brp_list
[brp_i
].control
,
1480 brp_list
[brp_i
].value
);
1482 else if (breakpoint
->type
== BKPT_SOFT
)
1485 if (breakpoint
->length
== 2)
1487 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1491 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1493 retval
= target
->type
->read_memory(target
,
1494 breakpoint
->address
& 0xFFFFFFFE,
1495 breakpoint
->length
, 1,
1496 breakpoint
->orig_instr
);
1497 if (retval
!= ERROR_OK
)
1499 retval
= target
->type
->write_memory(target
,
1500 breakpoint
->address
& 0xFFFFFFFE,
1501 breakpoint
->length
, 1, code
);
1502 if (retval
!= ERROR_OK
)
1504 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1510 static int cortex_a8_set_context_breakpoint(struct target
*target
,
1511 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1513 int retval
= ERROR_FAIL
;
1516 uint8_t byte_addr_select
= 0x0F;
1517 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1518 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1519 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1521 if (breakpoint
->set
)
1523 LOG_WARNING("breakpoint already set");
1526 /*check available context BRPs*/
1527 while ((brp_list
[brp_i
].used
|| (brp_list
[brp_i
].type
!=BRP_CONTEXT
)) && (brp_i
< cortex_a8
->brp_num
))
1530 if (brp_i
>= cortex_a8
->brp_num
)
1532 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1536 breakpoint
->set
= brp_i
+ 1;
1537 control
= ((matchmode
& 0x7) << 20)
1538 | (byte_addr_select
<< 5)
1540 brp_list
[brp_i
].used
= 1;
1541 brp_list
[brp_i
].value
= (breakpoint
->asid
);
1542 brp_list
[brp_i
].control
= control
;
1543 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1544 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1545 brp_list
[brp_i
].value
);
1546 if(retval
!= ERROR_OK
)
1548 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1549 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1550 brp_list
[brp_i
].control
);
1551 if(retval
!= ERROR_OK
)
1553 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1554 brp_list
[brp_i
].control
,
1555 brp_list
[brp_i
].value
);
1560 static int cortex_a8_set_hybrid_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1562 int retval
= ERROR_FAIL
;
1563 int brp_1
=0; //holds the contextID pair
1564 int brp_2
=0; // holds the IVA pair
1565 uint32_t control_CTX
, control_IVA
;
1566 uint8_t CTX_byte_addr_select
= 0x0F;
1567 uint8_t IVA_byte_addr_select
= 0x0F;
1568 uint8_t CTX_machmode
= 0x03;
1569 uint8_t IVA_machmode
= 0x01;
1570 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1571 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1572 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1576 if (breakpoint
->set
)
1578 LOG_WARNING("breakpoint already set");
1581 /*check available context BRPs*/
1582 while ((brp_list
[brp_1
].used
|| (brp_list
[brp_1
].type
!=BRP_CONTEXT
)) && (brp_1
< cortex_a8
->brp_num
))
1585 printf("brp(CTX) found num: %d \n",brp_1
);
1586 if (brp_1
>= cortex_a8
->brp_num
)
1588 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1592 while ((brp_list
[brp_2
].used
|| (brp_list
[brp_2
].type
!=BRP_NORMAL
)) && (brp_2
< cortex_a8
->brp_num
))
1595 printf("brp(IVA) found num: %d \n",brp_2
);
1596 if (brp_2
>= cortex_a8
->brp_num
)
1598 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1602 breakpoint
->set
= brp_1
+ 1;
1603 breakpoint
->linked_BRP
= brp_2
;
1604 control_CTX
= ((CTX_machmode
& 0x7) << 20)
1607 | (CTX_byte_addr_select
<< 5)
1609 brp_list
[brp_1
].used
= 1;
1610 brp_list
[brp_1
].value
= (breakpoint
->asid
);
1611 brp_list
[brp_1
].control
= control_CTX
;
1612 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1613 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_1
].BRPn
,
1614 brp_list
[brp_1
].value
);
1615 if (retval
!= ERROR_OK
)
1617 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1618 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_1
].BRPn
,
1619 brp_list
[brp_1
].control
);
1620 if( retval
!= ERROR_OK
)
1623 control_IVA
= ((IVA_machmode
& 0x7) << 20)
1625 | (IVA_byte_addr_select
<< 5)
1627 brp_list
[brp_2
].used
= 1;
1628 brp_list
[brp_2
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1629 brp_list
[brp_2
].control
= control_IVA
;
1630 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1631 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_2
].BRPn
,
1632 brp_list
[brp_2
].value
);
1633 if (retval
!= ERROR_OK
)
1635 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1636 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_2
].BRPn
,
1637 brp_list
[brp_2
].control
);
1638 if (retval
!= ERROR_OK
)
1645 static int cortex_a8_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1648 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1649 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1650 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1652 if (!breakpoint
->set
)
1654 LOG_WARNING("breakpoint not set");
1658 if (breakpoint
->type
== BKPT_HARD
)
1660 if ((breakpoint
->address
!= 0) && (breakpoint
->asid
!= 0))
1662 int brp_i
= breakpoint
->set
- 1;
1663 int brp_j
= breakpoint
->linked_BRP
;
1664 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1666 LOG_DEBUG("Invalid BRP number in breakpoint");
1669 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1670 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1671 brp_list
[brp_i
].used
= 0;
1672 brp_list
[brp_i
].value
= 0;
1673 brp_list
[brp_i
].control
= 0;
1674 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1675 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1676 brp_list
[brp_i
].control
);
1677 if (retval
!= ERROR_OK
)
1679 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1680 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1681 brp_list
[brp_i
].value
);
1682 if (retval
!= ERROR_OK
)
1684 if ((brp_j
< 0) || (brp_j
>= cortex_a8
->brp_num
))
1686 LOG_DEBUG("Invalid BRP number in breakpoint");
1689 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_j
,
1690 brp_list
[brp_j
].control
, brp_list
[brp_j
].value
);
1691 brp_list
[brp_j
].used
= 0;
1692 brp_list
[brp_j
].value
= 0;
1693 brp_list
[brp_j
].control
= 0;
1694 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1695 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_j
].BRPn
,
1696 brp_list
[brp_j
].control
);
1697 if (retval
!= ERROR_OK
)
1699 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1700 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_j
].BRPn
,
1701 brp_list
[brp_j
].value
);
1702 if (retval
!= ERROR_OK
)
1704 breakpoint
->linked_BRP
= 0;
1705 breakpoint
->set
= 0;
1711 int brp_i
= breakpoint
->set
- 1;
1712 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1714 LOG_DEBUG("Invalid BRP number in breakpoint");
1717 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1718 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1719 brp_list
[brp_i
].used
= 0;
1720 brp_list
[brp_i
].value
= 0;
1721 brp_list
[brp_i
].control
= 0;
1722 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1723 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1724 brp_list
[brp_i
].control
);
1725 if (retval
!= ERROR_OK
)
1727 retval
= cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1728 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1729 brp_list
[brp_i
].value
);
1730 if (retval
!= ERROR_OK
)
1732 breakpoint
->set
= 0;
1738 /* restore original instruction (kept in target endianness) */
1739 if (breakpoint
->length
== 4)
1741 retval
= target
->type
->write_memory(target
,
1742 breakpoint
->address
& 0xFFFFFFFE,
1743 4, 1, breakpoint
->orig_instr
);
1744 if (retval
!= ERROR_OK
)
1749 retval
= target
->type
->write_memory(target
,
1750 breakpoint
->address
& 0xFFFFFFFE,
1751 2, 1, breakpoint
->orig_instr
);
1752 if (retval
!= ERROR_OK
)
1756 breakpoint
->set
= 0;
1761 static int cortex_a8_add_breakpoint(struct target
*target
,
1762 struct breakpoint
*breakpoint
)
1764 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1766 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1768 LOG_INFO("no hardware breakpoint available");
1769 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1772 if (breakpoint
->type
== BKPT_HARD
)
1773 cortex_a8
->brp_num_available
--;
1775 return cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1778 static int cortex_a8_add_context_breakpoint(struct target
*target
,
1779 struct breakpoint
*breakpoint
)
1781 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1783 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1785 LOG_INFO("no hardware breakpoint available");
1786 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1789 if (breakpoint
->type
== BKPT_HARD
)
1790 cortex_a8
->brp_num_available
--;
1792 return cortex_a8_set_context_breakpoint(target
, breakpoint
, 0x02); /* asid match */
1795 static int cortex_a8_add_hybrid_breakpoint(struct target
*target
,
1796 struct breakpoint
*breakpoint
)
1798 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1800 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1802 LOG_INFO("no hardware breakpoint available");
1803 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1806 if (breakpoint
->type
== BKPT_HARD
)
1807 cortex_a8
->brp_num_available
--;
1809 return cortex_a8_set_hybrid_breakpoint(target
, breakpoint
); /* ??? */
1813 static int cortex_a8_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1815 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1818 /* It is perfectly possible to remove breakpoints while the target is running */
1819 if (target
->state
!= TARGET_HALTED
)
1821 LOG_WARNING("target not halted");
1822 return ERROR_TARGET_NOT_HALTED
;
1826 if (breakpoint
->set
)
1828 cortex_a8_unset_breakpoint(target
, breakpoint
);
1829 if (breakpoint
->type
== BKPT_HARD
)
1830 cortex_a8
->brp_num_available
++ ;
1840 * Cortex-A8 Reset functions
1843 static int cortex_a8_assert_reset(struct target
*target
)
1845 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1849 /* FIXME when halt is requested, make it work somehow... */
1851 /* Issue some kind of warm reset. */
1852 if (target_has_event_action(target
, TARGET_EVENT_RESET_ASSERT
)) {
1853 target_handle_event(target
, TARGET_EVENT_RESET_ASSERT
);
1854 } else if (jtag_get_reset_config() & RESET_HAS_SRST
) {
1855 /* REVISIT handle "pulls" cases, if there's
1856 * hardware that needs them to work.
1858 jtag_add_reset(0, 1);
1860 LOG_ERROR("%s: how to reset?", target_name(target
));
1864 /* registers are now invalid */
1865 register_cache_invalidate(armv7a
->armv4_5_common
.core_cache
);
1867 target
->state
= TARGET_RESET
;
1872 static int cortex_a8_deassert_reset(struct target
*target
)
1878 /* be certain SRST is off */
1879 jtag_add_reset(0, 0);
1881 retval
= cortex_a8_poll(target
);
1882 if (retval
!= ERROR_OK
)
1885 if (target
->reset_halt
) {
1886 if (target
->state
!= TARGET_HALTED
) {
1887 LOG_WARNING("%s: ran after reset and before halt ...",
1888 target_name(target
));
1889 if ((retval
= target_halt(target
)) != ERROR_OK
)
1898 static int cortex_a8_write_apb_ab_memory(struct target
*target
,
1899 uint32_t address
, uint32_t size
,
1900 uint32_t count
, const uint8_t *buffer
)
1903 /* write memory through APB-AP */
1905 int retval
= ERROR_INVALID_ARGUMENTS
;
1906 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1907 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
1908 int total_bytes
= count
* size
;
1909 int start_byte
, nbytes_to_write
, i
;
1916 if (target
->state
!= TARGET_HALTED
)
1918 LOG_WARNING("target not halted");
1919 return ERROR_TARGET_NOT_HALTED
;
1922 reg
= arm_reg_current(armv4_5
, 0);
1924 reg
= arm_reg_current(armv4_5
, 1);
1927 retval
= cortex_a8_dap_write_coreregister_u32(target
, address
& 0xFFFFFFFC, 0);
1928 if (retval
!= ERROR_OK
)
1931 start_byte
= address
& 0x3;
1933 while (total_bytes
> 0) {
1935 nbytes_to_write
= 4 - start_byte
;
1936 if (total_bytes
< nbytes_to_write
)
1937 nbytes_to_write
= total_bytes
;
1939 if ( nbytes_to_write
!= 4 ) {
1941 /* execute instruction LDR r1, [r0] */
1942 retval
= cortex_a8_exec_opcode(target
, ARMV4_5_LDR(1, 0), NULL
);
1943 if (retval
!= ERROR_OK
)
1946 retval
= cortex_a8_dap_read_coreregister_u32(target
, &data
.ui
, 1);
1947 if (retval
!= ERROR_OK
)
1951 for (i
= 0; i
< nbytes_to_write
; ++i
)
1952 data
.uc_a
[i
+ start_byte
] = *buffer
++;
1954 retval
= cortex_a8_dap_write_coreregister_u32(target
, data
.ui
, 1);
1955 if (retval
!= ERROR_OK
)
1958 /* execute instruction STRW r1, [r0], 1 (0xe4801004) */
1959 retval
= cortex_a8_exec_opcode(target
, ARMV4_5_STRW_IP(1, 0) , NULL
);
1960 if (retval
!= ERROR_OK
)
1963 total_bytes
-= nbytes_to_write
;
1971 static int cortex_a8_read_apb_ab_memory(struct target
*target
,
1972 uint32_t address
, uint32_t size
,
1973 uint32_t count
, uint8_t *buffer
)
1976 /* read memory through APB-AP */
1978 int retval
= ERROR_INVALID_ARGUMENTS
;
1979 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1980 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
1981 int total_bytes
= count
* size
;
1982 int start_byte
, nbytes_to_read
, i
;
1989 if (target
->state
!= TARGET_HALTED
)
1991 LOG_WARNING("target not halted");
1992 return ERROR_TARGET_NOT_HALTED
;
1995 reg
= arm_reg_current(armv4_5
, 0);
1997 reg
= arm_reg_current(armv4_5
, 1);
2000 retval
= cortex_a8_dap_write_coreregister_u32(target
, address
& 0xFFFFFFFC, 0);
2001 if (retval
!= ERROR_OK
)
2004 start_byte
= address
& 0x3;
2006 while (total_bytes
> 0) {
2008 /* execute instruction LDRW r1, [r0], 4 (0xe4901004) */
2009 retval
= cortex_a8_exec_opcode(target
, ARMV4_5_LDRW_IP(1, 0), NULL
);
2010 if (retval
!= ERROR_OK
)
2013 retval
= cortex_a8_dap_read_coreregister_u32(target
, &data
.ui
, 1);
2014 if (retval
!= ERROR_OK
)
2017 nbytes_to_read
= 4 - start_byte
;
2018 if (total_bytes
< nbytes_to_read
)
2019 nbytes_to_read
= total_bytes
;
2021 for (i
= 0; i
< nbytes_to_read
; ++i
)
2022 *buffer
++ = data
.uc_a
[i
+ start_byte
];
2024 total_bytes
-= nbytes_to_read
;
2034 * Cortex-A8 Memory access
2036 * This is same Cortex M3 but we must also use the correct
2037 * ap number for every access.
2040 static int cortex_a8_read_phys_memory(struct target
*target
,
2041 uint32_t address
, uint32_t size
,
2042 uint32_t count
, uint8_t *buffer
)
2044 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
2045 struct adiv5_dap
*swjdp
= armv7a
->armv4_5_common
.dap
;
2046 int retval
= ERROR_INVALID_ARGUMENTS
;
2047 uint8_t apsel
= swjdp
->apsel
;
2048 LOG_DEBUG("Reading memory at real address 0x%x; size %d; count %d",
2049 address
, size
, count
);
2051 if (count
&& buffer
) {
2053 if ( apsel
== swjdp_memoryap
) {
2055 /* read memory through AHB-AP */
2059 retval
= mem_ap_sel_read_buf_u32(swjdp
, swjdp_memoryap
,
2060 buffer
, 4 * count
, address
);
2063 retval
= mem_ap_sel_read_buf_u16(swjdp
, swjdp_memoryap
,
2064 buffer
, 2 * count
, address
);
2067 retval
= mem_ap_sel_read_buf_u8(swjdp
, swjdp_memoryap
,
2068 buffer
, count
, address
);
2073 /* read memory through APB-AP */
2075 retval
= cortex_a8_mmu_modify(target
, 0);
2076 if (retval
!= ERROR_OK
) return retval
;
2077 retval
= cortex_a8_read_apb_ab_memory(target
, address
, size
, count
, buffer
);
2083 static int cortex_a8_read_memory(struct target
*target
, uint32_t address
,
2084 uint32_t size
, uint32_t count
, uint8_t *buffer
)
2087 uint32_t virt
, phys
;
2089 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
2090 struct adiv5_dap
*swjdp
= armv7a
->armv4_5_common
.dap
;
2091 uint8_t apsel
= swjdp
->apsel
;
2093 /* cortex_a8 handles unaligned memory access */
2094 LOG_DEBUG("Reading memory at address 0x%x; size %d; count %d", address
,
2096 if (apsel
== swjdp_memoryap
) {
2097 retval
= cortex_a8_mmu(target
, &enabled
);
2098 if (retval
!= ERROR_OK
)
2105 retval
= cortex_a8_virt2phys(target
, virt
, &phys
);
2106 if (retval
!= ERROR_OK
)
2109 LOG_DEBUG("Reading at virtual address. Translating v:0x%x to r:0x%x",
2113 retval
= cortex_a8_read_phys_memory(target
, address
, size
, count
, buffer
);
2115 retval
= cortex_a8_check_address(target
, address
);
2116 if (retval
!= ERROR_OK
) return retval
;
2118 retval
= cortex_a8_mmu_modify(target
, 1);
2119 if (retval
!= ERROR_OK
) return retval
;
2120 retval
= cortex_a8_read_apb_ab_memory(target
, address
, size
, count
, buffer
);
2125 static int cortex_a8_write_phys_memory(struct target
*target
,
2126 uint32_t address
, uint32_t size
,
2127 uint32_t count
, const uint8_t *buffer
)
2129 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
2130 struct adiv5_dap
*swjdp
= armv7a
->armv4_5_common
.dap
;
2131 int retval
= ERROR_INVALID_ARGUMENTS
;
2132 uint8_t apsel
= swjdp
->apsel
;
2134 LOG_DEBUG("Writing memory to real address 0x%x; size %d; count %d", address
,
2137 if (count
&& buffer
) {
2139 if ( apsel
== swjdp_memoryap
) {
2141 /* write memory through AHB-AP */
2145 retval
= mem_ap_sel_write_buf_u32(swjdp
, swjdp_memoryap
,
2146 buffer
, 4 * count
, address
);
2149 retval
= mem_ap_sel_write_buf_u16(swjdp
, swjdp_memoryap
,
2150 buffer
, 2 * count
, address
);
2153 retval
= mem_ap_sel_write_buf_u8(swjdp
, swjdp_memoryap
,
2154 buffer
, count
, address
);
2160 /* write memory through APB-AP */
2161 retval
= cortex_a8_mmu_modify(target
, 0);
2162 if (retval
!= ERROR_OK
)
2164 return cortex_a8_write_apb_ab_memory(target
, address
, size
, count
, buffer
);
2169 /* REVISIT this op is generic ARMv7-A/R stuff */
2170 if (retval
== ERROR_OK
&& target
->state
== TARGET_HALTED
)
2172 struct arm_dpm
*dpm
= armv7a
->armv4_5_common
.dpm
;
2174 retval
= dpm
->prepare(dpm
);
2175 if (retval
!= ERROR_OK
)
2178 /* The Cache handling will NOT work with MMU active, the
2179 * wrong addresses will be invalidated!
2181 * For both ICache and DCache, walk all cache lines in the
2182 * address range. Cortex-A8 has fixed 64 byte line length.
2184 * REVISIT per ARMv7, these may trigger watchpoints ...
2187 /* invalidate I-Cache */
2188 if (armv7a
->armv7a_mmu
.armv7a_cache
.i_cache_enabled
)
2190 /* ICIMVAU - Invalidate Cache single entry
2192 * MCR p15, 0, r0, c7, c5, 1
2194 for (uint32_t cacheline
= address
;
2195 cacheline
< address
+ size
* count
;
2197 retval
= dpm
->instr_write_data_r0(dpm
,
2198 ARMV4_5_MCR(15, 0, 0, 7, 5, 1),
2200 if (retval
!= ERROR_OK
)
2205 /* invalidate D-Cache */
2206 if (armv7a
->armv7a_mmu
.armv7a_cache
.d_u_cache_enabled
)
2208 /* DCIMVAC - Invalidate data Cache line
2210 * MCR p15, 0, r0, c7, c6, 1
2212 for (uint32_t cacheline
= address
;
2213 cacheline
< address
+ size
* count
;
2215 retval
= dpm
->instr_write_data_r0(dpm
,
2216 ARMV4_5_MCR(15, 0, 0, 7, 6, 1),
2218 if (retval
!= ERROR_OK
)
2223 /* (void) */ dpm
->finish(dpm
);
2229 static int cortex_a8_write_memory(struct target
*target
, uint32_t address
,
2230 uint32_t size
, uint32_t count
, const uint8_t *buffer
)
2233 uint32_t virt
, phys
;
2235 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
2236 struct adiv5_dap
*swjdp
= armv7a
->armv4_5_common
.dap
;
2237 uint8_t apsel
= swjdp
->apsel
;
2238 /* cortex_a8 handles unaligned memory access */
2239 LOG_DEBUG("Reading memory at address 0x%x; size %d; count %d", address
,
2241 if (apsel
== swjdp_memoryap
) {
2243 LOG_DEBUG("Writing memory to address 0x%x; size %d; count %d", address
, size
, count
);
2244 retval
= cortex_a8_mmu(target
, &enabled
);
2245 if (retval
!= ERROR_OK
)
2251 retval
= cortex_a8_virt2phys(target
, virt
, &phys
);
2252 if (retval
!= ERROR_OK
)
2254 LOG_DEBUG("Writing to virtual address. Translating v:0x%x to r:0x%x", virt
, phys
);
2258 retval
= cortex_a8_write_phys_memory(target
, address
, size
,
2262 retval
= cortex_a8_check_address(target
, address
);
2263 if (retval
!= ERROR_OK
) return retval
;
2265 retval
= cortex_a8_mmu_modify(target
, 1);
2266 if (retval
!= ERROR_OK
) return retval
;
2267 retval
= cortex_a8_write_apb_ab_memory(target
, address
, size
, count
, buffer
);
2272 static int cortex_a8_bulk_write_memory(struct target
*target
, uint32_t address
,
2273 uint32_t count
, const uint8_t *buffer
)
2275 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
2279 static int cortex_a8_handle_target_request(void *priv
)
2281 struct target
*target
= priv
;
2282 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
2283 struct adiv5_dap
*swjdp
= armv7a
->armv4_5_common
.dap
;
2286 if (!target_was_examined(target
))
2288 if (!target
->dbg_msg_enabled
)
2291 if (target
->state
== TARGET_RUNNING
)
2295 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
2296 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
2298 /* check if we have data */
2299 while ((dscr
& DSCR_DTR_TX_FULL
) && (retval
==ERROR_OK
))
2301 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
2302 armv7a
->debug_base
+ CPUDBG_DTRTX
, &request
);
2303 if (retval
== ERROR_OK
)
2305 target_request(target
, request
);
2306 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
2307 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
2316 * Cortex-A8 target information and configuration
2319 static int cortex_a8_examine_first(struct target
*target
)
2321 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
2322 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
2323 struct adiv5_dap
*swjdp
= armv7a
->armv4_5_common
.dap
;
2325 int retval
= ERROR_OK
;
2326 uint32_t didr
, ctypr
, ttypr
, cpuid
;
2328 /* We do one extra read to ensure DAP is configured,
2329 * we call ahbap_debugport_init(swjdp) instead
2331 retval
= ahbap_debugport_init(swjdp
);
2332 if (retval
!= ERROR_OK
)
2335 if (!target
->dbgbase_set
)
2338 /* Get ROM Table base */
2340 retval
= dap_get_debugbase(swjdp
, 1, &dbgbase
, &apid
);
2341 if (retval
!= ERROR_OK
)
2343 /* Lookup 0x15 -- Processor DAP */
2344 retval
= dap_lookup_cs_component(swjdp
, 1, dbgbase
, 0x15,
2345 &armv7a
->debug_base
);
2346 if (retval
!= ERROR_OK
)
2351 armv7a
->debug_base
= target
->dbgbase
;
2354 retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
2355 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
2356 if (retval
!= ERROR_OK
)
2359 if ((retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
2360 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
2362 LOG_DEBUG("Examine %s failed", "CPUID");
2366 if ((retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
2367 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
2369 LOG_DEBUG("Examine %s failed", "CTYPR");
2373 if ((retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
2374 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
2376 LOG_DEBUG("Examine %s failed", "TTYPR");
2380 if ((retval
= mem_ap_sel_read_atomic_u32(swjdp
, swjdp_debugap
,
2381 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
2383 LOG_DEBUG("Examine %s failed", "DIDR");
2387 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
2388 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
2389 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
2390 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
2392 armv7a
->armv4_5_common
.core_type
= ARM_MODE_MON
;
2393 retval
= cortex_a8_dpm_setup(cortex_a8
, didr
);
2394 if (retval
!= ERROR_OK
)
2397 /* Setup Breakpoint Register Pairs */
2398 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
2399 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
2400 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
2401 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(struct cortex_a8_brp
));
2402 // cortex_a8->brb_enabled = ????;
2403 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
2405 cortex_a8
->brp_list
[i
].used
= 0;
2406 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
2407 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
2409 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
2410 cortex_a8
->brp_list
[i
].value
= 0;
2411 cortex_a8
->brp_list
[i
].control
= 0;
2412 cortex_a8
->brp_list
[i
].BRPn
= i
;
2415 LOG_DEBUG("Configured %i hw breakpoints", cortex_a8
->brp_num
);
2417 target_set_examined(target
);
2421 static int cortex_a8_examine(struct target
*target
)
2423 int retval
= ERROR_OK
;
2425 /* don't re-probe hardware after each reset */
2426 if (!target_was_examined(target
))
2427 retval
= cortex_a8_examine_first(target
);
2429 /* Configure core debug access */
2430 if (retval
== ERROR_OK
)
2431 retval
= cortex_a8_init_debug_access(target
);
2437 * Cortex-A8 target creation and initialization
2440 static int cortex_a8_init_target(struct command_context
*cmd_ctx
,
2441 struct target
*target
)
2443 /* examine_first() does a bunch of this */
2447 static int cortex_a8_init_arch_info(struct target
*target
,
2448 struct cortex_a8_common
*cortex_a8
, struct jtag_tap
*tap
)
2450 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
2451 struct adiv5_dap
*dap
= &armv7a
->dap
;
2453 armv7a
->armv4_5_common
.dap
= dap
;
2455 /* Setup struct cortex_a8_common */
2456 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
2457 /* tap has no dap initialized */
2460 armv7a
->armv4_5_common
.dap
= dap
;
2461 /* Setup struct cortex_a8_common */
2463 /* prepare JTAG information for the new target */
2464 cortex_a8
->jtag_info
.tap
= tap
;
2465 cortex_a8
->jtag_info
.scann_size
= 4;
2467 /* Leave (only) generic DAP stuff for debugport_init() */
2468 dap
->jtag_info
= &cortex_a8
->jtag_info
;
2470 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
2471 dap
->tar_autoincr_block
= (1 << 10);
2472 dap
->memaccess_tck
= 80;
2476 armv7a
->armv4_5_common
.dap
= tap
->dap
;
2478 cortex_a8
->fast_reg_read
= 0;
2480 /* register arch-specific functions */
2481 armv7a
->examine_debug_reason
= NULL
;
2483 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
2485 armv7a
->pre_restore_context
= NULL
;
2487 armv7a
->armv7a_mmu
.read_physical_memory
= cortex_a8_read_phys_memory
;
2490 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
2492 /* REVISIT v7a setup should be in a v7a-specific routine */
2493 armv7a_init_arch_info(target
, armv7a
);
2494 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
2499 static int cortex_a8_target_create(struct target
*target
, Jim_Interp
*interp
)
2501 struct cortex_a8_common
*cortex_a8
= calloc(1, sizeof(struct cortex_a8_common
));
2503 return cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
2508 static int cortex_a8_mmu(struct target
*target
, int *enabled
)
2510 if (target
->state
!= TARGET_HALTED
) {
2511 LOG_ERROR("%s: target not halted", __func__
);
2512 return ERROR_TARGET_INVALID
;
2515 *enabled
= target_to_cortex_a8(target
)->armv7a_common
.armv7a_mmu
.mmu_enabled
;
2519 static int cortex_a8_virt2phys(struct target
*target
,
2520 uint32_t virt
, uint32_t *phys
)
2522 int retval
= ERROR_FAIL
;
2523 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
2524 struct adiv5_dap
*swjdp
= armv7a
->armv4_5_common
.dap
;
2525 uint8_t apsel
= swjdp
->apsel
;
2526 if (apsel
== swjdp_memoryap
)
2529 retval
= armv7a_mmu_translate_va(target
,
2531 if (retval
!= ERROR_OK
)
2536 { /* use this method if swjdp_memoryap not selected */
2537 /* mmu must be enable in order to get a correct translation */
2538 retval
= cortex_a8_mmu_modify(target
, 1);
2539 if (retval
!= ERROR_OK
) goto done
;
2540 retval
= armv7a_mmu_translate_va_pa(target
, virt
, phys
, 1);
2546 COMMAND_HANDLER(cortex_a8_handle_cache_info_command
)
2548 struct target
*target
= get_current_target(CMD_CTX
);
2549 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
2551 return armv7a_handle_cache_info_command(CMD_CTX
,
2552 &armv7a
->armv7a_mmu
.armv7a_cache
);
2556 COMMAND_HANDLER(cortex_a8_handle_dbginit_command
)
2558 struct target
*target
= get_current_target(CMD_CTX
);
2559 if (!target_was_examined(target
))
2561 LOG_ERROR("target not examined yet");
2565 return cortex_a8_init_debug_access(target
);
2567 COMMAND_HANDLER(cortex_a8_handle_smp_off_command
)
2569 struct target
*target
= get_current_target(CMD_CTX
);
2570 /* check target is an smp target */
2571 struct target_list
*head
;
2572 struct target
*curr
;
2573 head
= target
->head
;
2575 if (head
!= (struct target_list
*)NULL
)
2577 while (head
!= (struct target_list
*)NULL
)
2579 curr
= head
->target
;
2583 /* fixes the target display to the debugger */
2584 target
->gdb_service
->target
= target
;
2589 COMMAND_HANDLER(cortex_a8_handle_smp_on_command
)
2591 struct target
*target
= get_current_target(CMD_CTX
);
2592 struct target_list
*head
;
2593 struct target
*curr
;
2594 head
= target
->head
;
2595 if (head
!= (struct target_list
*)NULL
)
2597 while (head
!= (struct target_list
*)NULL
)
2599 curr
= head
->target
;
2607 COMMAND_HANDLER(cortex_a8_handle_smp_gdb_command
)
2609 struct target
*target
= get_current_target(CMD_CTX
);
2610 int retval
= ERROR_OK
;
2611 struct target_list
*head
;
2612 head
= target
->head
;
2613 if (head
!= (struct target_list
*)NULL
)
2618 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], coreid
);
2619 if (ERROR_OK
!= retval
)
2621 target
->gdb_service
->core
[1]=coreid
;
2624 command_print(CMD_CTX
, "gdb coreid %d -> %d", target
->gdb_service
->core
[0]
2625 , target
->gdb_service
->core
[1]);
2630 static const struct command_registration cortex_a8_exec_command_handlers
[] = {
2632 .name
= "cache_info",
2633 .handler
= cortex_a8_handle_cache_info_command
,
2634 .mode
= COMMAND_EXEC
,
2635 .help
= "display information about target caches",
2639 .handler
= cortex_a8_handle_dbginit_command
,
2640 .mode
= COMMAND_EXEC
,
2641 .help
= "Initialize core debug",
2644 .handler
= cortex_a8_handle_smp_off_command
,
2645 .mode
= COMMAND_EXEC
,
2646 .help
= "Stop smp handling",
2650 .handler
= cortex_a8_handle_smp_on_command
,
2651 .mode
= COMMAND_EXEC
,
2652 .help
= "Restart smp handling",
2656 .handler
= cortex_a8_handle_smp_gdb_command
,
2657 .mode
= COMMAND_EXEC
,
2658 .help
= "display/fix current core played to gdb",
2662 COMMAND_REGISTRATION_DONE
2664 static const struct command_registration cortex_a8_command_handlers
[] = {
2666 .chain
= arm_command_handlers
,
2669 .chain
= armv7a_command_handlers
,
2672 .name
= "cortex_a8",
2673 .mode
= COMMAND_ANY
,
2674 .help
= "Cortex-A8 command group",
2675 .chain
= cortex_a8_exec_command_handlers
,
2677 COMMAND_REGISTRATION_DONE
2680 struct target_type cortexa8_target
= {
2681 .name
= "cortex_a8",
2683 .poll
= cortex_a8_poll
,
2684 .arch_state
= armv7a_arch_state
,
2686 .target_request_data
= NULL
,
2688 .halt
= cortex_a8_halt
,
2689 .resume
= cortex_a8_resume
,
2690 .step
= cortex_a8_step
,
2692 .assert_reset
= cortex_a8_assert_reset
,
2693 .deassert_reset
= cortex_a8_deassert_reset
,
2694 .soft_reset_halt
= NULL
,
2696 /* REVISIT allow exporting VFP3 registers ... */
2697 .get_gdb_reg_list
= arm_get_gdb_reg_list
,
2699 .read_memory
= cortex_a8_read_memory
,
2700 .write_memory
= cortex_a8_write_memory
,
2701 .bulk_write_memory
= cortex_a8_bulk_write_memory
,
2703 .checksum_memory
= arm_checksum_memory
,
2704 .blank_check_memory
= arm_blank_check_memory
,
2706 .run_algorithm
= armv4_5_run_algorithm
,
2708 .add_breakpoint
= cortex_a8_add_breakpoint
,
2709 .add_context_breakpoint
= cortex_a8_add_context_breakpoint
,
2710 .add_hybrid_breakpoint
= cortex_a8_add_hybrid_breakpoint
,
2711 .remove_breakpoint
= cortex_a8_remove_breakpoint
,
2712 .add_watchpoint
= NULL
,
2713 .remove_watchpoint
= NULL
,
2715 .commands
= cortex_a8_command_handlers
,
2716 .target_create
= cortex_a8_target_create
,
2717 .init_target
= cortex_a8_init_target
,
2718 .examine
= cortex_a8_examine
,
2720 .read_phys_memory
= cortex_a8_read_phys_memory
,
2721 .write_phys_memory
= cortex_a8_write_phys_memory
,
2722 .mmu
= cortex_a8_mmu
,
2723 .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)