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 /* FIXME when halt is requested, make it work somehow... */
1251 /* Issue some kind of warm reset. */
1252 if (target_has_event_action(target
, TARGET_EVENT_RESET_ASSERT
)) {
1253 target_handle_event(target
, TARGET_EVENT_RESET_ASSERT
);
1254 } else if (jtag_get_reset_config() & RESET_HAS_SRST
) {
1255 /* REVISIT handle "pulls" cases, if there's
1256 * hardware that needs them to work.
1258 jtag_add_reset(0, 1);
1260 LOG_ERROR("%s: how to reset?", target_name(target
));
1264 /* registers are now invalid */
1265 register_cache_invalidate(armv7a
->armv4_5_common
.core_cache
);
1267 target
->state
= TARGET_RESET
;
1272 static int cortex_a8_deassert_reset(struct target
*target
)
1278 /* be certain SRST is off */
1279 jtag_add_reset(0, 0);
1281 retval
= cortex_a8_poll(target
);
1283 if (target
->reset_halt
) {
1284 if (target
->state
!= TARGET_HALTED
) {
1285 LOG_WARNING("%s: ran after reset and before halt ...",
1286 target_name(target
));
1287 if ((retval
= target_halt(target
)) != ERROR_OK
)
1296 * Cortex-A8 Memory access
1298 * This is same Cortex M3 but we must also use the correct
1299 * ap number for every access.
1302 static int cortex_a8_read_memory(struct target
*target
, uint32_t address
,
1303 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1305 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1306 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1307 int retval
= ERROR_INVALID_ARGUMENTS
;
1309 /* cortex_a8 handles unaligned memory access */
1311 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1313 if (count
&& buffer
) {
1316 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1319 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1322 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1330 static int cortex_a8_write_memory(struct target
*target
, uint32_t address
,
1331 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1333 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1334 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1335 int retval
= ERROR_INVALID_ARGUMENTS
;
1337 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1339 if (count
&& buffer
) {
1342 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1345 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1348 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1353 if (retval
== ERROR_OK
&& target
->state
== TARGET_HALTED
)
1355 /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */
1356 /* invalidate I-Cache */
1357 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
1359 /* Invalidate ICache single entry with MVA, repeat this for all cache
1360 lines in the address range, Cortex-A8 has fixed 64 byte line length */
1361 /* Invalidate Cache single entry with MVA to PoU */
1362 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1363 armv7a
->write_cp15(target
, 0, 1, 7, 5, cacheline
); /* I-Cache to PoU */
1365 /* invalidate D-Cache */
1366 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
1368 /* Invalidate Cache single entry with MVA to PoC */
1369 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1370 armv7a
->write_cp15(target
, 0, 1, 7, 6, cacheline
); /* U/D cache to PoC */
1377 static int cortex_a8_bulk_write_memory(struct target
*target
, uint32_t address
,
1378 uint32_t count
, uint8_t *buffer
)
1380 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1384 static int cortex_a8_dcc_read(struct swjdp_common
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1389 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1390 *ctrl
= (uint8_t)dcrdr
;
1391 *value
= (uint8_t)(dcrdr
>> 8);
1393 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1395 /* write ack back to software dcc register
1396 * signify we have read data */
1397 if (dcrdr
& (1 << 0))
1400 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1407 static int cortex_a8_handle_target_request(void *priv
)
1409 struct target
*target
= priv
;
1410 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1411 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1413 if (!target_was_examined(target
))
1415 if (!target
->dbg_msg_enabled
)
1418 if (target
->state
== TARGET_RUNNING
)
1423 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1425 /* check if we have data */
1426 if (ctrl
& (1 << 0))
1430 /* we assume target is quick enough */
1432 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1433 request
|= (data
<< 8);
1434 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1435 request
|= (data
<< 16);
1436 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1437 request
|= (data
<< 24);
1438 target_request(target
, request
);
1446 * Cortex-A8 target information and configuration
1449 static int cortex_a8_examine_first(struct target
*target
)
1451 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1452 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1453 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1455 int retval
= ERROR_OK
;
1456 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1460 /* Here we shall insert a proper ROM Table scan */
1461 armv7a
->debug_base
= OMAP3530_DEBUG_BASE
;
1463 /* We do one extra read to ensure DAP is configured,
1464 * we call ahbap_debugport_init(swjdp) instead
1466 ahbap_debugport_init(swjdp
);
1467 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
1468 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1469 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1471 LOG_DEBUG("Examine failed");
1475 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1476 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1478 LOG_DEBUG("Examine failed");
1482 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1483 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1485 LOG_DEBUG("Examine failed");
1489 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1490 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1492 LOG_DEBUG("Examine failed");
1496 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1497 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1498 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1499 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1501 cortex_a8_dpm_setup(cortex_a8
, didr
);
1503 /* Setup Breakpoint Register Pairs */
1504 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1505 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1506 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1507 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(struct cortex_a8_brp
));
1508 // cortex_a8->brb_enabled = ????;
1509 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1511 cortex_a8
->brp_list
[i
].used
= 0;
1512 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1513 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1515 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1516 cortex_a8
->brp_list
[i
].value
= 0;
1517 cortex_a8
->brp_list
[i
].control
= 0;
1518 cortex_a8
->brp_list
[i
].BRPn
= i
;
1521 /* Setup Watchpoint Register Pairs */
1522 cortex_a8
->wrp_num
= ((didr
>> 28) & 0x0F) + 1;
1523 cortex_a8
->wrp_num_available
= cortex_a8
->wrp_num
;
1524 cortex_a8
->wrp_list
= calloc(cortex_a8
->wrp_num
, sizeof(struct cortex_a8_wrp
));
1525 for (i
= 0; i
< cortex_a8
->wrp_num
; i
++)
1527 cortex_a8
->wrp_list
[i
].used
= 0;
1528 cortex_a8
->wrp_list
[i
].type
= 0;
1529 cortex_a8
->wrp_list
[i
].value
= 0;
1530 cortex_a8
->wrp_list
[i
].control
= 0;
1531 cortex_a8
->wrp_list
[i
].WRPn
= i
;
1533 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1534 cortex_a8
->brp_num
, cortex_a8
->wrp_num
);
1536 target_set_examined(target
);
1540 static int cortex_a8_examine(struct target
*target
)
1542 int retval
= ERROR_OK
;
1544 /* don't re-probe hardware after each reset */
1545 if (!target_was_examined(target
))
1546 retval
= cortex_a8_examine_first(target
);
1548 /* Configure core debug access */
1549 if (retval
== ERROR_OK
)
1550 retval
= cortex_a8_init_debug_access(target
);
1556 * Cortex-A8 target creation and initialization
1559 static int cortex_a8_init_target(struct command_context
*cmd_ctx
,
1560 struct target
*target
)
1562 /* examine_first() does a bunch of this */
1566 static int cortex_a8_init_arch_info(struct target
*target
,
1567 struct cortex_a8_common
*cortex_a8
, struct jtag_tap
*tap
)
1569 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1570 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
1571 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1573 /* Setup struct cortex_a8_common */
1574 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1575 armv4_5
->arch_info
= armv7a
;
1577 /* prepare JTAG information for the new target */
1578 cortex_a8
->jtag_info
.tap
= tap
;
1579 cortex_a8
->jtag_info
.scann_size
= 4;
1581 swjdp
->dp_select_value
= -1;
1582 swjdp
->ap_csw_value
= -1;
1583 swjdp
->ap_tar_value
= -1;
1584 swjdp
->jtag_info
= &cortex_a8
->jtag_info
;
1585 swjdp
->memaccess_tck
= 80;
1587 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1588 swjdp
->tar_autoincr_block
= (1 << 10);
1590 cortex_a8
->fast_reg_read
= 0;
1593 /* register arch-specific functions */
1594 armv7a
->examine_debug_reason
= NULL
;
1596 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1598 armv7a
->pre_restore_context
= NULL
;
1599 armv7a
->post_restore_context
= NULL
;
1600 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1601 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1602 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_memory
;
1603 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_memory
;
1604 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1605 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1606 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1607 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1608 armv7a
->read_cp15
= cortex_a8_read_cp15
;
1609 armv7a
->write_cp15
= cortex_a8_write_cp15
;
1612 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1614 /* REVISIT v7a setup should be in a v7a-specific routine */
1615 armv4_5_init_arch_info(target
, armv4_5
);
1616 armv7a
->common_magic
= ARMV7_COMMON_MAGIC
;
1618 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1623 static int cortex_a8_target_create(struct target
*target
, Jim_Interp
*interp
)
1625 struct cortex_a8_common
*cortex_a8
= calloc(1, sizeof(struct cortex_a8_common
));
1627 cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1632 COMMAND_HANDLER(cortex_a8_handle_cache_info_command
)
1634 struct target
*target
= get_current_target(CMD_CTX
);
1635 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1637 return armv4_5_handle_cache_info_command(CMD_CTX
,
1638 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1642 COMMAND_HANDLER(cortex_a8_handle_dbginit_command
)
1644 struct target
*target
= get_current_target(CMD_CTX
);
1646 cortex_a8_init_debug_access(target
);
1651 static const struct command_registration cortex_a8_exec_command_handlers
[] = {
1653 .name
= "cache_info",
1654 .handler
= &cortex_a8_handle_cache_info_command
,
1655 .mode
= COMMAND_EXEC
,
1656 .help
= "display information about target caches",
1660 .handler
= &cortex_a8_handle_dbginit_command
,
1661 .mode
= COMMAND_EXEC
,
1662 .help
= "Initialize core debug",
1664 COMMAND_REGISTRATION_DONE
1666 static const struct command_registration cortex_a8_command_handlers
[] = {
1668 .chain
= arm_command_handlers
,
1671 .chain
= armv7a_command_handlers
,
1674 .name
= "cortex_a8",
1675 .mode
= COMMAND_ANY
,
1676 .help
= "Cortex-A8 command group",
1677 .chain
= cortex_a8_exec_command_handlers
,
1679 COMMAND_REGISTRATION_DONE
1682 struct target_type cortexa8_target
= {
1683 .name
= "cortex_a8",
1685 .poll
= cortex_a8_poll
,
1686 .arch_state
= armv7a_arch_state
,
1688 .target_request_data
= NULL
,
1690 .halt
= cortex_a8_halt
,
1691 .resume
= cortex_a8_resume
,
1692 .step
= cortex_a8_step
,
1694 .assert_reset
= cortex_a8_assert_reset
,
1695 .deassert_reset
= cortex_a8_deassert_reset
,
1696 .soft_reset_halt
= NULL
,
1698 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
1700 .read_memory
= cortex_a8_read_memory
,
1701 .write_memory
= cortex_a8_write_memory
,
1702 .bulk_write_memory
= cortex_a8_bulk_write_memory
,
1704 .checksum_memory
= arm_checksum_memory
,
1705 .blank_check_memory
= arm_blank_check_memory
,
1707 .run_algorithm
= armv4_5_run_algorithm
,
1709 .add_breakpoint
= cortex_a8_add_breakpoint
,
1710 .remove_breakpoint
= cortex_a8_remove_breakpoint
,
1711 .add_watchpoint
= NULL
,
1712 .remove_watchpoint
= NULL
,
1714 .commands
= cortex_a8_command_handlers
,
1715 .target_create
= cortex_a8_target_create
,
1716 .init_target
= cortex_a8_init_target
,
1717 .examine
= cortex_a8_examine
,
1718 .mrc
= cortex_a8_mrc
,
1719 .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)