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 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program; if not, write to the *
26 * Free Software Foundation, Inc., *
27 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
29 * Cortex-A8(tm) TRM, ARM DDI 0344H *
31 ***************************************************************************/
36 #include "breakpoints.h"
37 #include "cortex_a8.h"
39 #include "target_request.h"
40 #include "target_type.h"
42 static int cortex_a8_poll(struct target
*target
);
43 static int cortex_a8_debug_entry(struct target
*target
);
44 static int cortex_a8_restore_context(struct target
*target
);
45 static int cortex_a8_set_breakpoint(struct target
*target
,
46 struct breakpoint
*breakpoint
, uint8_t matchmode
);
47 static int cortex_a8_unset_breakpoint(struct target
*target
,
48 struct breakpoint
*breakpoint
);
49 static int cortex_a8_dap_read_coreregister_u32(struct target
*target
,
50 uint32_t *value
, int regnum
);
51 static int cortex_a8_dap_write_coreregister_u32(struct target
*target
,
52 uint32_t value
, int regnum
);
54 * FIXME do topology discovery using the ROM; don't
55 * assume this is an OMAP3.
57 #define swjdp_memoryap 0
58 #define swjdp_debugap 1
59 #define OMAP3530_DEBUG_BASE 0x54011000
62 * Cortex-A8 Basic debug access, very low level assumes state is saved
64 static int cortex_a8_init_debug_access(struct target
*target
)
66 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
67 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
74 /* Unlocking the debug registers for modification */
75 /* The debugport might be uninitialised so try twice */
76 retval
= mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
77 if (retval
!= ERROR_OK
)
78 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
79 /* Clear Sticky Power Down status Bit in PRSR to enable access to
80 the registers in the Core Power Domain */
81 retval
= mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_PRSR
, &dummy
);
82 /* Enabling of instruction execution in debug mode is done in debug_entry code */
84 /* Resync breakpoint registers */
86 /* Since this is likley called from init or reset, update targtet state information*/
87 cortex_a8_poll(target
);
92 /* To reduce needless round-trips, pass in a pointer to the current
93 * DSCR value. Initialize it to zero if you just need to know the
94 * value on return from this function; or (1 << DSCR_INSTR_COMP) if
95 * you happen to know that no instruction is pending.
97 static int cortex_a8_exec_opcode(struct target
*target
,
98 uint32_t opcode
, uint32_t *dscr_p
)
102 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
103 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
105 dscr
= dscr_p
? *dscr_p
: 0;
107 LOG_DEBUG("exec opcode 0x%08" PRIx32
, opcode
);
109 /* Wait for InstrCompl bit to be set */
110 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0)
112 retval
= mem_ap_read_atomic_u32(swjdp
,
113 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
114 if (retval
!= ERROR_OK
)
116 LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32
, opcode
);
121 mem_ap_write_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_ITR
, opcode
);
125 retval
= mem_ap_read_atomic_u32(swjdp
,
126 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
127 if (retval
!= ERROR_OK
)
129 LOG_ERROR("Could not read DSCR register");
133 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
141 /**************************************************************************
142 Read core register with very few exec_opcode, fast but needs work_area.
143 This can cause problems with MMU active.
144 **************************************************************************/
145 static int cortex_a8_read_regs_through_mem(struct target
*target
, uint32_t address
,
148 int retval
= ERROR_OK
;
149 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
150 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
152 cortex_a8_dap_read_coreregister_u32(target
, regfile
, 0);
153 cortex_a8_dap_write_coreregister_u32(target
, address
, 0);
154 cortex_a8_exec_opcode(target
, ARMV4_5_STMIA(0, 0xFFFE, 0, 0), NULL
);
155 dap_ap_select(swjdp
, swjdp_memoryap
);
156 mem_ap_read_buf_u32(swjdp
, (uint8_t *)(®file
[1]), 4*15, address
);
157 dap_ap_select(swjdp
, swjdp_debugap
);
162 static int cortex_a8_read_cp(struct target
*target
, uint32_t *value
, uint8_t CP
,
163 uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
166 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
167 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
170 /* MRC(...) to read coprocessor register into r0 */
171 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(CP
, op1
, 0, CRn
, CRm
, op2
),
174 /* Move R0 to DTRTX */
175 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
179 retval
= mem_ap_read_atomic_u32(swjdp
,
180 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
185 static int cortex_a8_write_cp(struct target
*target
, uint32_t value
,
186 uint8_t CP
, uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
190 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
191 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
193 LOG_DEBUG("CP%i, CRn %i, value 0x%08" PRIx32
, CP
, CRn
, value
);
195 /* Check that DCCRX is not full */
196 retval
= mem_ap_read_atomic_u32(swjdp
,
197 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
198 if (dscr
& (1 << DSCR_DTR_RX_FULL
))
200 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
201 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
202 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
206 /* Write DTRRX ... sets DSCR.DTRRXfull but exec_opcode() won't care */
207 retval
= mem_ap_write_u32(swjdp
,
208 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
210 /* Move DTRRX to r0 */
211 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), &dscr
);
213 /* MCR(...) to write r0 to coprocessor */
214 return cortex_a8_exec_opcode(target
,
215 ARMV4_5_MCR(CP
, op1
, 0, CRn
, CRm
, op2
),
219 static int cortex_a8_read_cp15(struct target
*target
, uint32_t op1
, uint32_t op2
,
220 uint32_t CRn
, uint32_t CRm
, uint32_t *value
)
222 return cortex_a8_read_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
225 static int cortex_a8_write_cp15(struct target
*target
, uint32_t op1
, uint32_t op2
,
226 uint32_t CRn
, uint32_t CRm
, uint32_t value
)
228 return cortex_a8_write_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
231 static int cortex_a8_mrc(struct target
*target
, int cpnum
, uint32_t op1
, uint32_t op2
, uint32_t CRn
, uint32_t CRm
, uint32_t *value
)
235 LOG_ERROR("Only cp15 is supported");
238 return cortex_a8_read_cp15(target
, op1
, op2
, CRn
, CRm
, value
);
241 static int cortex_a8_mcr(struct target
*target
, int cpnum
, uint32_t op1
, uint32_t op2
, uint32_t CRn
, uint32_t CRm
, uint32_t value
)
245 LOG_ERROR("Only cp15 is supported");
248 return cortex_a8_write_cp15(target
, op1
, op2
, CRn
, CRm
, value
);
253 static int cortex_a8_dap_read_coreregister_u32(struct target
*target
,
254 uint32_t *value
, int regnum
)
256 int retval
= ERROR_OK
;
257 uint8_t reg
= regnum
&0xFF;
259 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
260 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
267 /* Rn to DCCTX, "MCR p14, 0, Rn, c0, c5, 0" 0xEE00nE15 */
268 cortex_a8_exec_opcode(target
,
269 ARMV4_5_MCR(14, 0, reg
, 0, 5, 0),
274 /* "MOV r0, r15"; then move r0 to DCCTX */
275 cortex_a8_exec_opcode(target
, 0xE1A0000F, &dscr
);
276 cortex_a8_exec_opcode(target
,
277 ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
282 /* "MRS r0, CPSR" or "MRS r0, SPSR"
283 * then move r0 to DCCTX
285 cortex_a8_exec_opcode(target
, ARMV4_5_MRS(0, reg
& 1), &dscr
);
286 cortex_a8_exec_opcode(target
,
287 ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
291 /* Wait for DTRRXfull then read DTRRTX */
292 while ((dscr
& (1 << DSCR_DTR_TX_FULL
)) == 0)
294 retval
= mem_ap_read_atomic_u32(swjdp
,
295 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
298 retval
= mem_ap_read_atomic_u32(swjdp
,
299 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
300 LOG_DEBUG("read DCC 0x%08" PRIx32
, *value
);
305 static int cortex_a8_dap_write_coreregister_u32(struct target
*target
,
306 uint32_t value
, int regnum
)
308 int retval
= ERROR_OK
;
309 uint8_t Rd
= regnum
&0xFF;
311 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
312 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
314 LOG_DEBUG("register %i, value 0x%08" PRIx32
, regnum
, value
);
316 /* Check that DCCRX is not full */
317 retval
= mem_ap_read_atomic_u32(swjdp
,
318 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
319 if (dscr
& (1 << DSCR_DTR_RX_FULL
))
321 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
322 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
323 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
330 /* Write DTRRX ... sets DSCR.DTRRXfull but exec_opcode() won't care */
331 LOG_DEBUG("write DCC 0x%08" PRIx32
, value
);
332 retval
= mem_ap_write_u32(swjdp
,
333 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
337 /* DCCRX to Rn, "MCR p14, 0, Rn, c0, c5, 0", 0xEE00nE15 */
338 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, Rd
, 0, 5, 0),
343 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15
346 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
348 cortex_a8_exec_opcode(target
, 0xE1A0F000, &dscr
);
352 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15
353 * then "MSR CPSR_cxsf, r0" or "MSR SPSR_cxsf, r0" (all fields)
355 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
357 cortex_a8_exec_opcode(target
, ARMV4_5_MSR_GP(0, 0xF, Rd
& 1),
360 /* "Prefetch flush" after modifying execution status in CPSR */
362 cortex_a8_exec_opcode(target
,
363 ARMV4_5_MCR(15, 0, 0, 7, 5, 4),
370 /* Write to memory mapped registers directly with no cache or mmu handling */
371 static int cortex_a8_dap_write_memap_register_u32(struct target
*target
, uint32_t address
, uint32_t value
)
374 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
375 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
377 retval
= mem_ap_write_atomic_u32(swjdp
, address
, value
);
383 * Cortex-A8 implementation of Debug Programmer's Model
385 * NOTE the invariant: these routines return with DSCR_INSTR_COMP set,
386 * so there's no need to poll for it before executing an instruction.
388 * NOTE that in several of these cases the "stall" mode might be useful.
389 * It'd let us queue a few operations together... prepare/finish might
390 * be the places to enable/disable that mode.
393 static inline struct cortex_a8_common
*dpm_to_a8(struct arm_dpm
*dpm
)
395 return container_of(dpm
, struct cortex_a8_common
, armv7a_common
.dpm
);
398 static int cortex_a8_write_dcc(struct cortex_a8_common
*a8
, uint32_t data
)
400 LOG_DEBUG("write DCC 0x%08" PRIx32
, data
);
401 return mem_ap_write_u32(&a8
->armv7a_common
.swjdp_info
,
402 a8
->armv7a_common
.debug_base
+ CPUDBG_DTRRX
, data
);
405 static int cortex_a8_read_dcc(struct cortex_a8_common
*a8
, uint32_t *data
,
408 struct swjdp_common
*swjdp
= &a8
->armv7a_common
.swjdp_info
;
409 uint32_t dscr
= 1 << DSCR_INSTR_COMP
;
415 /* Wait for DTRRXfull */
416 while ((dscr
& (1 << DSCR_DTR_TX_FULL
)) == 0) {
417 retval
= mem_ap_read_atomic_u32(swjdp
,
418 a8
->armv7a_common
.debug_base
+ CPUDBG_DSCR
,
422 retval
= mem_ap_read_atomic_u32(swjdp
,
423 a8
->armv7a_common
.debug_base
+ CPUDBG_DTRTX
, data
);
424 LOG_DEBUG("read DCC 0x%08" PRIx32
, *data
);
432 static int cortex_a8_dpm_prepare(struct arm_dpm
*dpm
)
434 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
435 struct swjdp_common
*swjdp
= &a8
->armv7a_common
.swjdp_info
;
439 /* set up invariant: INSTR_COMP is set after ever DPM operation */
441 retval
= mem_ap_read_atomic_u32(swjdp
,
442 a8
->armv7a_common
.debug_base
+ CPUDBG_DSCR
,
444 } while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0);
446 /* this "should never happen" ... */
447 if (dscr
& (1 << DSCR_DTR_RX_FULL
)) {
448 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
450 retval
= cortex_a8_exec_opcode(
451 a8
->armv7a_common
.armv4_5_common
.target
,
452 ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
459 static int cortex_a8_dpm_finish(struct arm_dpm
*dpm
)
461 /* REVISIT what could be done here? */
465 static int cortex_a8_instr_write_data_dcc(struct arm_dpm
*dpm
,
466 uint32_t opcode
, uint32_t data
)
468 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
470 uint32_t dscr
= 1 << DSCR_INSTR_COMP
;
472 retval
= cortex_a8_write_dcc(a8
, data
);
474 return cortex_a8_exec_opcode(
475 a8
->armv7a_common
.armv4_5_common
.target
,
480 static int cortex_a8_instr_write_data_r0(struct arm_dpm
*dpm
,
481 uint32_t opcode
, uint32_t data
)
483 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
484 uint32_t dscr
= 1 << DSCR_INSTR_COMP
;
487 retval
= cortex_a8_write_dcc(a8
, data
);
489 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15 */
490 retval
= cortex_a8_exec_opcode(
491 a8
->armv7a_common
.armv4_5_common
.target
,
492 ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
495 /* then the opcode, taking data from R0 */
496 retval
= cortex_a8_exec_opcode(
497 a8
->armv7a_common
.armv4_5_common
.target
,
504 static int cortex_a8_instr_cpsr_sync(struct arm_dpm
*dpm
)
506 struct target
*target
= dpm
->arm
->target
;
507 uint32_t dscr
= 1 << DSCR_INSTR_COMP
;
509 /* "Prefetch flush" after modifying execution status in CPSR */
510 return cortex_a8_exec_opcode(target
,
511 ARMV4_5_MCR(15, 0, 0, 7, 5, 4),
515 static int cortex_a8_instr_read_data_dcc(struct arm_dpm
*dpm
,
516 uint32_t opcode
, uint32_t *data
)
518 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
520 uint32_t dscr
= 1 << DSCR_INSTR_COMP
;
522 /* the opcode, writing data to DCC */
523 retval
= cortex_a8_exec_opcode(
524 a8
->armv7a_common
.armv4_5_common
.target
,
528 return cortex_a8_read_dcc(a8
, data
, &dscr
);
532 static int cortex_a8_instr_read_data_r0(struct arm_dpm
*dpm
,
533 uint32_t opcode
, uint32_t *data
)
535 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
536 uint32_t dscr
= 1 << DSCR_INSTR_COMP
;
539 /* the opcode, writing data to R0 */
540 retval
= cortex_a8_exec_opcode(
541 a8
->armv7a_common
.armv4_5_common
.target
,
545 /* write R0 to DCC */
546 retval
= cortex_a8_exec_opcode(
547 a8
->armv7a_common
.armv4_5_common
.target
,
548 ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
551 return cortex_a8_read_dcc(a8
, data
, &dscr
);
554 static int cortex_a8_dpm_setup(struct cortex_a8_common
*a8
, uint32_t didr
)
556 struct arm_dpm
*dpm
= &a8
->armv7a_common
.dpm
;
558 dpm
->arm
= &a8
->armv7a_common
.armv4_5_common
;
561 dpm
->prepare
= cortex_a8_dpm_prepare
;
562 dpm
->finish
= cortex_a8_dpm_finish
;
564 dpm
->instr_write_data_dcc
= cortex_a8_instr_write_data_dcc
;
565 dpm
->instr_write_data_r0
= cortex_a8_instr_write_data_r0
;
566 dpm
->instr_cpsr_sync
= cortex_a8_instr_cpsr_sync
;
568 dpm
->instr_read_data_dcc
= cortex_a8_instr_read_data_dcc
;
569 dpm
->instr_read_data_r0
= cortex_a8_instr_read_data_r0
;
571 return arm_dpm_setup(dpm
);
576 * Cortex-A8 Run control
579 static int cortex_a8_poll(struct target
*target
)
581 int retval
= ERROR_OK
;
583 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
584 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
585 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
586 enum target_state prev_target_state
= target
->state
;
587 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
589 dap_ap_select(swjdp
, swjdp_debugap
);
590 retval
= mem_ap_read_atomic_u32(swjdp
,
591 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
592 if (retval
!= ERROR_OK
)
594 dap_ap_select(swjdp
, saved_apsel
);
597 cortex_a8
->cpudbg_dscr
= dscr
;
599 if ((dscr
& 0x3) == 0x3)
601 if (prev_target_state
!= TARGET_HALTED
)
603 /* We have a halting debug event */
604 LOG_DEBUG("Target halted");
605 target
->state
= TARGET_HALTED
;
606 if ((prev_target_state
== TARGET_RUNNING
)
607 || (prev_target_state
== TARGET_RESET
))
609 retval
= cortex_a8_debug_entry(target
);
610 if (retval
!= ERROR_OK
)
613 target_call_event_callbacks(target
,
614 TARGET_EVENT_HALTED
);
616 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
620 retval
= cortex_a8_debug_entry(target
);
621 if (retval
!= ERROR_OK
)
624 target_call_event_callbacks(target
,
625 TARGET_EVENT_DEBUG_HALTED
);
629 else if ((dscr
& 0x3) == 0x2)
631 target
->state
= TARGET_RUNNING
;
635 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32
, dscr
);
636 target
->state
= TARGET_UNKNOWN
;
639 dap_ap_select(swjdp
, saved_apsel
);
644 static int cortex_a8_halt(struct target
*target
)
646 int retval
= ERROR_OK
;
648 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
649 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
650 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
651 dap_ap_select(swjdp
, swjdp_debugap
);
654 * Tell the core to be halted by writing DRCR with 0x1
655 * and then wait for the core to be halted.
657 retval
= mem_ap_write_atomic_u32(swjdp
,
658 armv7a
->debug_base
+ CPUDBG_DRCR
, 0x1);
661 * enter halting debug mode
663 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
664 retval
= mem_ap_write_atomic_u32(swjdp
,
665 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
| (1 << DSCR_HALT_DBG_MODE
));
667 if (retval
!= ERROR_OK
)
671 mem_ap_read_atomic_u32(swjdp
,
672 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
673 } while ((dscr
& (1 << DSCR_CORE_HALTED
)) == 0);
675 target
->debug_reason
= DBG_REASON_DBGRQ
;
678 dap_ap_select(swjdp
, saved_apsel
);
682 static int cortex_a8_resume(struct target
*target
, int current
,
683 uint32_t address
, int handle_breakpoints
, int debug_execution
)
685 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
686 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
687 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
689 // struct breakpoint *breakpoint = NULL;
690 uint32_t resume_pc
, dscr
;
692 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
693 dap_ap_select(swjdp
, swjdp_debugap
);
695 if (!debug_execution
)
697 target_free_all_working_areas(target
);
698 // cortex_m3_enable_breakpoints(target);
699 // cortex_m3_enable_watchpoints(target);
705 /* Disable interrupts */
706 /* We disable interrupts in the PRIMASK register instead of
707 * masking with C_MASKINTS,
708 * This is probably the same issue as Cortex-M3 Errata 377493:
709 * C_MASKINTS in parallel with disabled interrupts can cause
710 * local faults to not be taken. */
711 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
712 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
713 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
715 /* Make sure we are in Thumb mode */
716 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
717 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
718 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
719 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
723 /* current = 1: continue on current pc, otherwise continue at <address> */
724 resume_pc
= buf_get_u32(
725 armv4_5
->core_cache
->reg_list
[15].value
,
730 /* Make sure that the Armv7 gdb thumb fixups does not
731 * kill the return address
733 switch (armv4_5
->core_state
)
735 case ARMV4_5_STATE_ARM
:
736 resume_pc
&= 0xFFFFFFFC;
738 case ARMV4_5_STATE_THUMB
:
739 case ARM_STATE_THUMB_EE
:
740 /* When the return address is loaded into PC
741 * bit 0 must be 1 to stay in Thumb state
745 case ARMV4_5_STATE_JAZELLE
:
746 LOG_ERROR("How do I resume into Jazelle state??");
749 LOG_DEBUG("resume pc = 0x%08" PRIx32
, resume_pc
);
750 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
,
752 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
753 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
755 cortex_a8_restore_context(target
);
758 /* the front-end may request us not to handle breakpoints */
759 if (handle_breakpoints
)
761 /* Single step past breakpoint at current address */
762 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
764 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
765 cortex_m3_unset_breakpoint(target
, breakpoint
);
766 cortex_m3_single_step_core(target
);
767 cortex_m3_set_breakpoint(target
, breakpoint
);
772 /* Restart core and wait for it to be started */
773 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DRCR
, 0x2);
776 mem_ap_read_atomic_u32(swjdp
,
777 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
778 } while ((dscr
& (1 << DSCR_CORE_RESTARTED
)) == 0);
780 target
->debug_reason
= DBG_REASON_NOTHALTED
;
781 target
->state
= TARGET_RUNNING
;
783 /* registers are now invalid */
784 register_cache_invalidate(armv4_5
->core_cache
);
786 if (!debug_execution
)
788 target
->state
= TARGET_RUNNING
;
789 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
790 LOG_DEBUG("target resumed at 0x%" PRIx32
, resume_pc
);
794 target
->state
= TARGET_DEBUG_RUNNING
;
795 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
796 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, resume_pc
);
799 dap_ap_select(swjdp
, saved_apsel
);
804 static int cortex_a8_debug_entry(struct target
*target
)
807 uint32_t regfile
[16], pc
, cpsr
, dscr
;
808 int retval
= ERROR_OK
;
809 struct working_area
*regfile_working_area
= NULL
;
810 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
811 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
812 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
813 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
816 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
818 /* Enable the ITR execution once we are in debug mode */
819 mem_ap_read_atomic_u32(swjdp
,
820 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
822 /* REVISIT see A8 TRM 12.11.4 steps 2..3 -- make sure that any
823 * imprecise data aborts get discarded by issuing a Data
824 * Synchronization Barrier: ARMV4_5_MCR(15, 0, 0, 7, 10, 4).
827 dscr
|= (1 << DSCR_EXT_INT_EN
);
828 retval
= mem_ap_write_atomic_u32(swjdp
,
829 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
);
831 /* Examine debug reason */
832 switch ((cortex_a8
->cpudbg_dscr
>> 2)&0xF)
834 case 0: /* DRCR[0] write */
836 target
->debug_reason
= DBG_REASON_DBGRQ
;
838 case 1: /* HW breakpoint */
839 case 3: /* SW BKPT */
840 case 5: /* vector catch */
841 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
843 case 10: /* precise watchpoint */
844 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
845 /* REVISIT could collect WFAR later, to see just
846 * which instruction triggered the watchpoint.
850 target
->debug_reason
= DBG_REASON_UNDEFINED
;
854 /* REVISIT fast_reg_read is never set ... */
856 /* Examine target state and mode */
857 if (cortex_a8
->fast_reg_read
)
858 target_alloc_working_area(target
, 64, ®file_working_area
);
860 /* First load register acessible through core debug port*/
861 if (!regfile_working_area
)
863 retval
= arm_dpm_read_current_registers(&armv7a
->dpm
);
867 dap_ap_select(swjdp
, swjdp_memoryap
);
868 cortex_a8_read_regs_through_mem(target
,
869 regfile_working_area
->address
, regfile
);
870 dap_ap_select(swjdp
, swjdp_memoryap
);
871 target_free_working_area(target
, regfile_working_area
);
873 /* read Current PSR */
874 cortex_a8_dap_read_coreregister_u32(target
, &cpsr
, 16);
876 dap_ap_select(swjdp
, swjdp_debugap
);
877 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
879 arm_set_cpsr(armv4_5
, cpsr
);
882 for (i
= 0; i
<= ARM_PC
; i
++)
884 reg
= arm_reg_current(armv4_5
, i
);
886 buf_set_u32(reg
->value
, 0, 32, regfile
[i
]);
891 /* Fixup PC Resume Address */
894 // T bit set for Thumb or ThumbEE state
895 regfile
[ARM_PC
] -= 4;
900 regfile
[ARM_PC
] -= 8;
903 reg
= armv4_5
->core_cache
->reg_list
+ 15;
904 buf_set_u32(reg
->value
, 0, 32, regfile
[ARM_PC
]);
905 reg
->dirty
= reg
->valid
;
909 /* TODO, Move this */
910 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
911 cortex_a8_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
912 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
914 cortex_a8_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
915 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
917 cortex_a8_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
918 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
921 /* Are we in an exception handler */
922 // armv4_5->exception_number = 0;
923 if (armv7a
->post_debug_entry
)
924 armv7a
->post_debug_entry(target
);
932 static void cortex_a8_post_debug_entry(struct target
*target
)
934 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
935 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
937 // cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
938 /* examine cp15 control reg */
939 armv7a
->read_cp15(target
, 0, 0, 1, 0, &cortex_a8
->cp15_control_reg
);
940 jtag_execute_queue();
941 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
943 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
945 uint32_t cache_type_reg
;
946 /* identify caches */
947 armv7a
->read_cp15(target
, 0, 1, 0, 0, &cache_type_reg
);
948 jtag_execute_queue();
949 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
950 armv4_5_identify_cache(cache_type_reg
,
951 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
954 armv7a
->armv4_5_mmu
.mmu_enabled
=
955 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
956 armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
=
957 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
958 armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
=
959 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
964 static int cortex_a8_step(struct target
*target
, int current
, uint32_t address
,
965 int handle_breakpoints
)
967 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
968 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
969 struct breakpoint
*breakpoint
= NULL
;
970 struct breakpoint stepbreakpoint
;
975 if (target
->state
!= TARGET_HALTED
)
977 LOG_WARNING("target not halted");
978 return ERROR_TARGET_NOT_HALTED
;
981 /* current = 1: continue on current pc, otherwise continue at <address> */
982 r
= armv4_5
->core_cache
->reg_list
+ 15;
985 buf_set_u32(r
->value
, 0, 32, address
);
989 address
= buf_get_u32(r
->value
, 0, 32);
992 /* The front-end may request us not to handle breakpoints.
993 * But since Cortex-A8 uses breakpoint for single step,
994 * we MUST handle breakpoints.
996 handle_breakpoints
= 1;
997 if (handle_breakpoints
) {
998 breakpoint
= breakpoint_find(target
, address
);
1000 cortex_a8_unset_breakpoint(target
, breakpoint
);
1003 /* Setup single step breakpoint */
1004 stepbreakpoint
.address
= address
;
1005 stepbreakpoint
.length
= (armv4_5
->core_state
== ARMV4_5_STATE_THUMB
)
1007 stepbreakpoint
.type
= BKPT_HARD
;
1008 stepbreakpoint
.set
= 0;
1010 /* Break on IVA mismatch */
1011 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
1013 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1015 cortex_a8_resume(target
, 1, address
, 0, 0);
1017 while (target
->state
!= TARGET_HALTED
)
1019 cortex_a8_poll(target
);
1022 LOG_WARNING("timeout waiting for target halt");
1027 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
1028 if (timeout
> 0) target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1031 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
1033 if (target
->state
!= TARGET_HALTED
)
1034 LOG_DEBUG("target stepped");
1039 static int cortex_a8_restore_context(struct target
*target
)
1041 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1045 if (armv7a
->pre_restore_context
)
1046 armv7a
->pre_restore_context(target
);
1048 arm_dpm_write_dirty_registers(&armv7a
->dpm
);
1050 if (armv7a
->post_restore_context
)
1051 armv7a
->post_restore_context(target
);
1058 * Cortex-A8 Breakpoint and watchpoint fuctions
1061 /* Setup hardware Breakpoint Register Pair */
1062 static int cortex_a8_set_breakpoint(struct target
*target
,
1063 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1068 uint8_t byte_addr_select
= 0x0F;
1069 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1070 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1071 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1073 if (breakpoint
->set
)
1075 LOG_WARNING("breakpoint already set");
1079 if (breakpoint
->type
== BKPT_HARD
)
1081 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
1083 if (brp_i
>= cortex_a8
->brp_num
)
1085 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1088 breakpoint
->set
= brp_i
+ 1;
1089 if (breakpoint
->length
== 2)
1091 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1093 control
= ((matchmode
& 0x7) << 20)
1094 | (byte_addr_select
<< 5)
1096 brp_list
[brp_i
].used
= 1;
1097 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1098 brp_list
[brp_i
].control
= control
;
1099 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1100 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1101 brp_list
[brp_i
].value
);
1102 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1103 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1104 brp_list
[brp_i
].control
);
1105 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1106 brp_list
[brp_i
].control
,
1107 brp_list
[brp_i
].value
);
1109 else if (breakpoint
->type
== BKPT_SOFT
)
1112 if (breakpoint
->length
== 2)
1114 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1118 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1120 retval
= target
->type
->read_memory(target
,
1121 breakpoint
->address
& 0xFFFFFFFE,
1122 breakpoint
->length
, 1,
1123 breakpoint
->orig_instr
);
1124 if (retval
!= ERROR_OK
)
1126 retval
= target
->type
->write_memory(target
,
1127 breakpoint
->address
& 0xFFFFFFFE,
1128 breakpoint
->length
, 1, code
);
1129 if (retval
!= ERROR_OK
)
1131 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1137 static int cortex_a8_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1140 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1141 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1142 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1144 if (!breakpoint
->set
)
1146 LOG_WARNING("breakpoint not set");
1150 if (breakpoint
->type
== BKPT_HARD
)
1152 int brp_i
= breakpoint
->set
- 1;
1153 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1155 LOG_DEBUG("Invalid BRP number in breakpoint");
1158 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1159 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1160 brp_list
[brp_i
].used
= 0;
1161 brp_list
[brp_i
].value
= 0;
1162 brp_list
[brp_i
].control
= 0;
1163 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1164 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1165 brp_list
[brp_i
].control
);
1166 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1167 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1168 brp_list
[brp_i
].value
);
1172 /* restore original instruction (kept in target endianness) */
1173 if (breakpoint
->length
== 4)
1175 retval
= target
->type
->write_memory(target
,
1176 breakpoint
->address
& 0xFFFFFFFE,
1177 4, 1, breakpoint
->orig_instr
);
1178 if (retval
!= ERROR_OK
)
1183 retval
= target
->type
->write_memory(target
,
1184 breakpoint
->address
& 0xFFFFFFFE,
1185 2, 1, breakpoint
->orig_instr
);
1186 if (retval
!= ERROR_OK
)
1190 breakpoint
->set
= 0;
1195 static int cortex_a8_add_breakpoint(struct target
*target
,
1196 struct breakpoint
*breakpoint
)
1198 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1200 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1202 LOG_INFO("no hardware breakpoint available");
1203 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1206 if (breakpoint
->type
== BKPT_HARD
)
1207 cortex_a8
->brp_num_available
--;
1208 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1213 static int cortex_a8_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1215 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1218 /* It is perfectly possible to remove brakpoints while the taget is running */
1219 if (target
->state
!= TARGET_HALTED
)
1221 LOG_WARNING("target not halted");
1222 return ERROR_TARGET_NOT_HALTED
;
1226 if (breakpoint
->set
)
1228 cortex_a8_unset_breakpoint(target
, breakpoint
);
1229 if (breakpoint
->type
== BKPT_HARD
)
1230 cortex_a8
->brp_num_available
++ ;
1240 * Cortex-A8 Reset fuctions
1243 static int cortex_a8_assert_reset(struct target
*target
)
1245 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1249 /* registers are now invalid */
1250 register_cache_invalidate(armv7a
->armv4_5_common
.core_cache
);
1252 target
->state
= TARGET_RESET
;
1257 static int cortex_a8_deassert_reset(struct target
*target
)
1262 if (target
->reset_halt
)
1265 if ((retval
= target_halt(target
)) != ERROR_OK
)
1273 * Cortex-A8 Memory access
1275 * This is same Cortex M3 but we must also use the correct
1276 * ap number for every access.
1279 static int cortex_a8_read_memory(struct target
*target
, uint32_t address
,
1280 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1282 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1283 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1284 int retval
= ERROR_INVALID_ARGUMENTS
;
1286 /* cortex_a8 handles unaligned memory access */
1288 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1290 if (count
&& buffer
) {
1293 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1296 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1299 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1307 static int cortex_a8_write_memory(struct target
*target
, uint32_t address
,
1308 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1310 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1311 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1312 int retval
= ERROR_INVALID_ARGUMENTS
;
1314 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1316 if (count
&& buffer
) {
1319 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1322 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1325 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1330 if (retval
== ERROR_OK
&& target
->state
== TARGET_HALTED
)
1332 /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */
1333 /* invalidate I-Cache */
1334 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
1336 /* Invalidate ICache single entry with MVA, repeat this for all cache
1337 lines in the address range, Cortex-A8 has fixed 64 byte line length */
1338 /* Invalidate Cache single entry with MVA to PoU */
1339 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1340 armv7a
->write_cp15(target
, 0, 1, 7, 5, cacheline
); /* I-Cache to PoU */
1342 /* invalidate D-Cache */
1343 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
1345 /* Invalidate Cache single entry with MVA to PoC */
1346 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1347 armv7a
->write_cp15(target
, 0, 1, 7, 6, cacheline
); /* U/D cache to PoC */
1354 static int cortex_a8_bulk_write_memory(struct target
*target
, uint32_t address
,
1355 uint32_t count
, uint8_t *buffer
)
1357 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1361 static int cortex_a8_dcc_read(struct swjdp_common
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1366 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1367 *ctrl
= (uint8_t)dcrdr
;
1368 *value
= (uint8_t)(dcrdr
>> 8);
1370 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1372 /* write ack back to software dcc register
1373 * signify we have read data */
1374 if (dcrdr
& (1 << 0))
1377 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1384 static int cortex_a8_handle_target_request(void *priv
)
1386 struct target
*target
= priv
;
1387 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1388 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1390 if (!target_was_examined(target
))
1392 if (!target
->dbg_msg_enabled
)
1395 if (target
->state
== TARGET_RUNNING
)
1400 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1402 /* check if we have data */
1403 if (ctrl
& (1 << 0))
1407 /* we assume target is quick enough */
1409 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1410 request
|= (data
<< 8);
1411 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1412 request
|= (data
<< 16);
1413 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1414 request
|= (data
<< 24);
1415 target_request(target
, request
);
1423 * Cortex-A8 target information and configuration
1426 static int cortex_a8_examine_first(struct target
*target
)
1428 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1429 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1430 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1432 int retval
= ERROR_OK
;
1433 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1437 /* Here we shall insert a proper ROM Table scan */
1438 armv7a
->debug_base
= OMAP3530_DEBUG_BASE
;
1440 /* We do one extra read to ensure DAP is configured,
1441 * we call ahbap_debugport_init(swjdp) instead
1443 ahbap_debugport_init(swjdp
);
1444 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
1445 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1446 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1448 LOG_DEBUG("Examine failed");
1452 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1453 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1455 LOG_DEBUG("Examine failed");
1459 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1460 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1462 LOG_DEBUG("Examine failed");
1466 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1467 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1469 LOG_DEBUG("Examine failed");
1473 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1474 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1475 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1476 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1478 cortex_a8_dpm_setup(cortex_a8
, didr
);
1480 /* Setup Breakpoint Register Pairs */
1481 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1482 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1483 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1484 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(struct cortex_a8_brp
));
1485 // cortex_a8->brb_enabled = ????;
1486 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1488 cortex_a8
->brp_list
[i
].used
= 0;
1489 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1490 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1492 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1493 cortex_a8
->brp_list
[i
].value
= 0;
1494 cortex_a8
->brp_list
[i
].control
= 0;
1495 cortex_a8
->brp_list
[i
].BRPn
= i
;
1498 /* Setup Watchpoint Register Pairs */
1499 cortex_a8
->wrp_num
= ((didr
>> 28) & 0x0F) + 1;
1500 cortex_a8
->wrp_num_available
= cortex_a8
->wrp_num
;
1501 cortex_a8
->wrp_list
= calloc(cortex_a8
->wrp_num
, sizeof(struct cortex_a8_wrp
));
1502 for (i
= 0; i
< cortex_a8
->wrp_num
; i
++)
1504 cortex_a8
->wrp_list
[i
].used
= 0;
1505 cortex_a8
->wrp_list
[i
].type
= 0;
1506 cortex_a8
->wrp_list
[i
].value
= 0;
1507 cortex_a8
->wrp_list
[i
].control
= 0;
1508 cortex_a8
->wrp_list
[i
].WRPn
= i
;
1510 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1511 cortex_a8
->brp_num
, cortex_a8
->wrp_num
);
1513 target_set_examined(target
);
1517 static int cortex_a8_examine(struct target
*target
)
1519 int retval
= ERROR_OK
;
1521 /* don't re-probe hardware after each reset */
1522 if (!target_was_examined(target
))
1523 retval
= cortex_a8_examine_first(target
);
1525 /* Configure core debug access */
1526 if (retval
== ERROR_OK
)
1527 retval
= cortex_a8_init_debug_access(target
);
1533 * Cortex-A8 target creation and initialization
1536 static int cortex_a8_init_target(struct command_context
*cmd_ctx
,
1537 struct target
*target
)
1539 /* examine_first() does a bunch of this */
1543 static int cortex_a8_init_arch_info(struct target
*target
,
1544 struct cortex_a8_common
*cortex_a8
, struct jtag_tap
*tap
)
1546 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1547 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
1548 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1550 /* Setup struct cortex_a8_common */
1551 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1552 armv4_5
->arch_info
= armv7a
;
1554 /* prepare JTAG information for the new target */
1555 cortex_a8
->jtag_info
.tap
= tap
;
1556 cortex_a8
->jtag_info
.scann_size
= 4;
1558 swjdp
->dp_select_value
= -1;
1559 swjdp
->ap_csw_value
= -1;
1560 swjdp
->ap_tar_value
= -1;
1561 swjdp
->jtag_info
= &cortex_a8
->jtag_info
;
1562 swjdp
->memaccess_tck
= 80;
1564 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1565 swjdp
->tar_autoincr_block
= (1 << 10);
1567 cortex_a8
->fast_reg_read
= 0;
1570 /* register arch-specific functions */
1571 armv7a
->examine_debug_reason
= NULL
;
1573 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1575 armv7a
->pre_restore_context
= NULL
;
1576 armv7a
->post_restore_context
= NULL
;
1577 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1578 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1579 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_memory
;
1580 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_memory
;
1581 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1582 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1583 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1584 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1585 armv7a
->read_cp15
= cortex_a8_read_cp15
;
1586 armv7a
->write_cp15
= cortex_a8_write_cp15
;
1589 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1591 /* REVISIT v7a setup should be in a v7a-specific routine */
1592 armv4_5_init_arch_info(target
, armv4_5
);
1593 armv7a
->common_magic
= ARMV7_COMMON_MAGIC
;
1595 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1600 static int cortex_a8_target_create(struct target
*target
, Jim_Interp
*interp
)
1602 struct cortex_a8_common
*cortex_a8
= calloc(1, sizeof(struct cortex_a8_common
));
1604 cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1609 COMMAND_HANDLER(cortex_a8_handle_cache_info_command
)
1611 struct target
*target
= get_current_target(CMD_CTX
);
1612 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1614 return armv4_5_handle_cache_info_command(CMD_CTX
,
1615 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1619 COMMAND_HANDLER(cortex_a8_handle_dbginit_command
)
1621 struct target
*target
= get_current_target(CMD_CTX
);
1623 cortex_a8_init_debug_access(target
);
1629 static int cortex_a8_register_commands(struct command_context
*cmd_ctx
)
1631 struct command
*cortex_a8_cmd
;
1632 int retval
= ERROR_OK
;
1634 armv4_5_register_commands(cmd_ctx
);
1635 armv7a_register_commands(cmd_ctx
);
1637 cortex_a8_cmd
= register_command(cmd_ctx
, NULL
, "cortex_a8",
1639 "cortex_a8 specific commands");
1641 register_command(cmd_ctx
, cortex_a8_cmd
, "cache_info",
1642 cortex_a8_handle_cache_info_command
, COMMAND_EXEC
,
1643 "display information about target caches");
1645 register_command(cmd_ctx
, cortex_a8_cmd
, "dbginit",
1646 cortex_a8_handle_dbginit_command
, COMMAND_EXEC
,
1647 "Initialize core debug");
1652 struct target_type cortexa8_target
= {
1653 .name
= "cortex_a8",
1655 .poll
= cortex_a8_poll
,
1656 .arch_state
= armv7a_arch_state
,
1658 .target_request_data
= NULL
,
1660 .halt
= cortex_a8_halt
,
1661 .resume
= cortex_a8_resume
,
1662 .step
= cortex_a8_step
,
1664 .assert_reset
= cortex_a8_assert_reset
,
1665 .deassert_reset
= cortex_a8_deassert_reset
,
1666 .soft_reset_halt
= NULL
,
1668 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
1670 .read_memory
= cortex_a8_read_memory
,
1671 .write_memory
= cortex_a8_write_memory
,
1672 .bulk_write_memory
= cortex_a8_bulk_write_memory
,
1674 .checksum_memory
= arm_checksum_memory
,
1675 .blank_check_memory
= arm_blank_check_memory
,
1677 .run_algorithm
= armv4_5_run_algorithm
,
1679 .add_breakpoint
= cortex_a8_add_breakpoint
,
1680 .remove_breakpoint
= cortex_a8_remove_breakpoint
,
1681 .add_watchpoint
= NULL
,
1682 .remove_watchpoint
= NULL
,
1684 .register_commands
= cortex_a8_register_commands
,
1685 .target_create
= cortex_a8_target_create
,
1686 .init_target
= cortex_a8_init_target
,
1687 .examine
= cortex_a8_examine
,
1688 .mrc
= cortex_a8_mrc
,
1689 .mcr
= cortex_a8_mcr
,
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)