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
;
938 /* MRC p15,0,<Rt>,c1,c0,0 ; Read CP15 System Control Register */
939 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
942 &cortex_a8
->cp15_control_reg
);
943 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
945 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
947 uint32_t cache_type_reg
;
949 /* MRC p15,0,<Rt>,c0,c0,1 ; Read CP15 Cache Type Register */
950 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
954 LOG_DEBUG("cp15 cache type: %8.8x", (unsigned) cache_type_reg
);
956 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
957 armv4_5_identify_cache(cache_type_reg
,
958 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
961 armv7a
->armv4_5_mmu
.mmu_enabled
=
962 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
963 armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
=
964 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
965 armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
=
966 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
971 static int cortex_a8_step(struct target
*target
, int current
, uint32_t address
,
972 int handle_breakpoints
)
974 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
975 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
976 struct breakpoint
*breakpoint
= NULL
;
977 struct breakpoint stepbreakpoint
;
982 if (target
->state
!= TARGET_HALTED
)
984 LOG_WARNING("target not halted");
985 return ERROR_TARGET_NOT_HALTED
;
988 /* current = 1: continue on current pc, otherwise continue at <address> */
989 r
= armv4_5
->core_cache
->reg_list
+ 15;
992 buf_set_u32(r
->value
, 0, 32, address
);
996 address
= buf_get_u32(r
->value
, 0, 32);
999 /* The front-end may request us not to handle breakpoints.
1000 * But since Cortex-A8 uses breakpoint for single step,
1001 * we MUST handle breakpoints.
1003 handle_breakpoints
= 1;
1004 if (handle_breakpoints
) {
1005 breakpoint
= breakpoint_find(target
, address
);
1007 cortex_a8_unset_breakpoint(target
, breakpoint
);
1010 /* Setup single step breakpoint */
1011 stepbreakpoint
.address
= address
;
1012 stepbreakpoint
.length
= (armv4_5
->core_state
== ARMV4_5_STATE_THUMB
)
1014 stepbreakpoint
.type
= BKPT_HARD
;
1015 stepbreakpoint
.set
= 0;
1017 /* Break on IVA mismatch */
1018 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
1020 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1022 cortex_a8_resume(target
, 1, address
, 0, 0);
1024 while (target
->state
!= TARGET_HALTED
)
1026 cortex_a8_poll(target
);
1029 LOG_WARNING("timeout waiting for target halt");
1034 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
1035 if (timeout
> 0) target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1038 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
1040 if (target
->state
!= TARGET_HALTED
)
1041 LOG_DEBUG("target stepped");
1046 static int cortex_a8_restore_context(struct target
*target
)
1048 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1052 if (armv7a
->pre_restore_context
)
1053 armv7a
->pre_restore_context(target
);
1055 arm_dpm_write_dirty_registers(&armv7a
->dpm
);
1057 if (armv7a
->post_restore_context
)
1058 armv7a
->post_restore_context(target
);
1065 * Cortex-A8 Breakpoint and watchpoint fuctions
1068 /* Setup hardware Breakpoint Register Pair */
1069 static int cortex_a8_set_breakpoint(struct target
*target
,
1070 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1075 uint8_t byte_addr_select
= 0x0F;
1076 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1077 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1078 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1080 if (breakpoint
->set
)
1082 LOG_WARNING("breakpoint already set");
1086 if (breakpoint
->type
== BKPT_HARD
)
1088 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
1090 if (brp_i
>= cortex_a8
->brp_num
)
1092 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1095 breakpoint
->set
= brp_i
+ 1;
1096 if (breakpoint
->length
== 2)
1098 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1100 control
= ((matchmode
& 0x7) << 20)
1101 | (byte_addr_select
<< 5)
1103 brp_list
[brp_i
].used
= 1;
1104 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1105 brp_list
[brp_i
].control
= control
;
1106 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1107 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1108 brp_list
[brp_i
].value
);
1109 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1110 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1111 brp_list
[brp_i
].control
);
1112 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1113 brp_list
[brp_i
].control
,
1114 brp_list
[brp_i
].value
);
1116 else if (breakpoint
->type
== BKPT_SOFT
)
1119 if (breakpoint
->length
== 2)
1121 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1125 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1127 retval
= target
->type
->read_memory(target
,
1128 breakpoint
->address
& 0xFFFFFFFE,
1129 breakpoint
->length
, 1,
1130 breakpoint
->orig_instr
);
1131 if (retval
!= ERROR_OK
)
1133 retval
= target
->type
->write_memory(target
,
1134 breakpoint
->address
& 0xFFFFFFFE,
1135 breakpoint
->length
, 1, code
);
1136 if (retval
!= ERROR_OK
)
1138 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1144 static int cortex_a8_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1147 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1148 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1149 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1151 if (!breakpoint
->set
)
1153 LOG_WARNING("breakpoint not set");
1157 if (breakpoint
->type
== BKPT_HARD
)
1159 int brp_i
= breakpoint
->set
- 1;
1160 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1162 LOG_DEBUG("Invalid BRP number in breakpoint");
1165 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1166 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1167 brp_list
[brp_i
].used
= 0;
1168 brp_list
[brp_i
].value
= 0;
1169 brp_list
[brp_i
].control
= 0;
1170 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1171 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1172 brp_list
[brp_i
].control
);
1173 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1174 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1175 brp_list
[brp_i
].value
);
1179 /* restore original instruction (kept in target endianness) */
1180 if (breakpoint
->length
== 4)
1182 retval
= target
->type
->write_memory(target
,
1183 breakpoint
->address
& 0xFFFFFFFE,
1184 4, 1, breakpoint
->orig_instr
);
1185 if (retval
!= ERROR_OK
)
1190 retval
= target
->type
->write_memory(target
,
1191 breakpoint
->address
& 0xFFFFFFFE,
1192 2, 1, breakpoint
->orig_instr
);
1193 if (retval
!= ERROR_OK
)
1197 breakpoint
->set
= 0;
1202 static int cortex_a8_add_breakpoint(struct target
*target
,
1203 struct breakpoint
*breakpoint
)
1205 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1207 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1209 LOG_INFO("no hardware breakpoint available");
1210 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1213 if (breakpoint
->type
== BKPT_HARD
)
1214 cortex_a8
->brp_num_available
--;
1215 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1220 static int cortex_a8_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1222 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1225 /* It is perfectly possible to remove brakpoints while the taget is running */
1226 if (target
->state
!= TARGET_HALTED
)
1228 LOG_WARNING("target not halted");
1229 return ERROR_TARGET_NOT_HALTED
;
1233 if (breakpoint
->set
)
1235 cortex_a8_unset_breakpoint(target
, breakpoint
);
1236 if (breakpoint
->type
== BKPT_HARD
)
1237 cortex_a8
->brp_num_available
++ ;
1247 * Cortex-A8 Reset fuctions
1250 static int cortex_a8_assert_reset(struct target
*target
)
1252 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1256 /* FIXME when halt is requested, make it work somehow... */
1258 /* Issue some kind of warm reset. */
1259 if (target_has_event_action(target
, TARGET_EVENT_RESET_ASSERT
)) {
1260 target_handle_event(target
, TARGET_EVENT_RESET_ASSERT
);
1261 } else if (jtag_get_reset_config() & RESET_HAS_SRST
) {
1262 /* REVISIT handle "pulls" cases, if there's
1263 * hardware that needs them to work.
1265 jtag_add_reset(0, 1);
1267 LOG_ERROR("%s: how to reset?", target_name(target
));
1271 /* registers are now invalid */
1272 register_cache_invalidate(armv7a
->armv4_5_common
.core_cache
);
1274 target
->state
= TARGET_RESET
;
1279 static int cortex_a8_deassert_reset(struct target
*target
)
1285 /* be certain SRST is off */
1286 jtag_add_reset(0, 0);
1288 retval
= cortex_a8_poll(target
);
1290 if (target
->reset_halt
) {
1291 if (target
->state
!= TARGET_HALTED
) {
1292 LOG_WARNING("%s: ran after reset and before halt ...",
1293 target_name(target
));
1294 if ((retval
= target_halt(target
)) != ERROR_OK
)
1303 * Cortex-A8 Memory access
1305 * This is same Cortex M3 but we must also use the correct
1306 * ap number for every access.
1309 static int cortex_a8_read_memory(struct target
*target
, uint32_t address
,
1310 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1312 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1313 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1314 int retval
= ERROR_INVALID_ARGUMENTS
;
1316 /* cortex_a8 handles unaligned memory access */
1318 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1320 if (count
&& buffer
) {
1323 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1326 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1329 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1337 static int cortex_a8_write_memory(struct target
*target
, uint32_t address
,
1338 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1340 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1341 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1342 int retval
= ERROR_INVALID_ARGUMENTS
;
1344 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1346 if (count
&& buffer
) {
1349 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1352 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1355 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1360 /* REVISIT this op is generic ARMv7-A/R stuff */
1361 if (retval
== ERROR_OK
&& target
->state
== TARGET_HALTED
)
1363 struct arm_dpm
*dpm
= armv7a
->armv4_5_common
.dpm
;
1365 retval
= dpm
->prepare(dpm
);
1366 if (retval
!= ERROR_OK
)
1369 /* The Cache handling will NOT work with MMU active, the
1370 * wrong addresses will be invalidated!
1372 * For both ICache and DCache, walk all cache lines in the
1373 * address range. Cortex-A8 has fixed 64 byte line length.
1376 /* invalidate I-Cache */
1377 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
1379 /* ICIMVAU - Invalidate Cache single entry
1381 * MCR p15, 0, r0, c7, c5, 1
1383 for (uint32_t cacheline
= address
;
1384 cacheline
< address
+ size
* count
;
1386 retval
= dpm
->instr_write_data_r0(dpm
,
1387 ARMV4_5_MCR(15, 0, 0, 7, 5, 1),
1392 /* invalidate D-Cache */
1393 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
1395 /* DCIMVAC - Invalidate data Cache line
1397 * MCR p15, 0, r0, c7, c6, 1
1399 for (uint32_t cacheline
= address
;
1400 cacheline
< address
+ size
* count
;
1402 retval
= dpm
->instr_write_data_r0(dpm
,
1403 ARMV4_5_MCR(15, 0, 0, 7, 6, 1),
1408 /* (void) */ dpm
->finish(dpm
);
1414 static int cortex_a8_bulk_write_memory(struct target
*target
, uint32_t address
,
1415 uint32_t count
, uint8_t *buffer
)
1417 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1421 static int cortex_a8_dcc_read(struct swjdp_common
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1426 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1427 *ctrl
= (uint8_t)dcrdr
;
1428 *value
= (uint8_t)(dcrdr
>> 8);
1430 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1432 /* write ack back to software dcc register
1433 * signify we have read data */
1434 if (dcrdr
& (1 << 0))
1437 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1444 static int cortex_a8_handle_target_request(void *priv
)
1446 struct target
*target
= priv
;
1447 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1448 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1450 if (!target_was_examined(target
))
1452 if (!target
->dbg_msg_enabled
)
1455 if (target
->state
== TARGET_RUNNING
)
1460 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1462 /* check if we have data */
1463 if (ctrl
& (1 << 0))
1467 /* we assume target is quick enough */
1469 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1470 request
|= (data
<< 8);
1471 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1472 request
|= (data
<< 16);
1473 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1474 request
|= (data
<< 24);
1475 target_request(target
, request
);
1483 * Cortex-A8 target information and configuration
1486 static int cortex_a8_examine_first(struct target
*target
)
1488 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1489 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1490 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1492 int retval
= ERROR_OK
;
1493 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1497 /* Here we shall insert a proper ROM Table scan */
1498 armv7a
->debug_base
= OMAP3530_DEBUG_BASE
;
1500 /* We do one extra read to ensure DAP is configured,
1501 * we call ahbap_debugport_init(swjdp) instead
1503 ahbap_debugport_init(swjdp
);
1504 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
1505 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1506 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1508 LOG_DEBUG("Examine failed");
1512 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1513 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1515 LOG_DEBUG("Examine failed");
1519 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1520 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1522 LOG_DEBUG("Examine failed");
1526 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1527 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1529 LOG_DEBUG("Examine failed");
1533 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1534 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1535 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1536 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1538 armv7a
->armv4_5_common
.core_type
= ARM_MODE_MON
;
1539 cortex_a8_dpm_setup(cortex_a8
, didr
);
1541 /* Setup Breakpoint Register Pairs */
1542 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1543 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1544 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1545 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(struct cortex_a8_brp
));
1546 // cortex_a8->brb_enabled = ????;
1547 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1549 cortex_a8
->brp_list
[i
].used
= 0;
1550 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1551 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1553 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1554 cortex_a8
->brp_list
[i
].value
= 0;
1555 cortex_a8
->brp_list
[i
].control
= 0;
1556 cortex_a8
->brp_list
[i
].BRPn
= i
;
1559 /* Setup Watchpoint Register Pairs */
1560 cortex_a8
->wrp_num
= ((didr
>> 28) & 0x0F) + 1;
1561 cortex_a8
->wrp_num_available
= cortex_a8
->wrp_num
;
1562 cortex_a8
->wrp_list
= calloc(cortex_a8
->wrp_num
, sizeof(struct cortex_a8_wrp
));
1563 for (i
= 0; i
< cortex_a8
->wrp_num
; i
++)
1565 cortex_a8
->wrp_list
[i
].used
= 0;
1566 cortex_a8
->wrp_list
[i
].type
= 0;
1567 cortex_a8
->wrp_list
[i
].value
= 0;
1568 cortex_a8
->wrp_list
[i
].control
= 0;
1569 cortex_a8
->wrp_list
[i
].WRPn
= i
;
1571 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1572 cortex_a8
->brp_num
, cortex_a8
->wrp_num
);
1574 target_set_examined(target
);
1578 static int cortex_a8_examine(struct target
*target
)
1580 int retval
= ERROR_OK
;
1582 /* don't re-probe hardware after each reset */
1583 if (!target_was_examined(target
))
1584 retval
= cortex_a8_examine_first(target
);
1586 /* Configure core debug access */
1587 if (retval
== ERROR_OK
)
1588 retval
= cortex_a8_init_debug_access(target
);
1594 * Cortex-A8 target creation and initialization
1597 static int cortex_a8_init_target(struct command_context
*cmd_ctx
,
1598 struct target
*target
)
1600 /* examine_first() does a bunch of this */
1604 static int cortex_a8_init_arch_info(struct target
*target
,
1605 struct cortex_a8_common
*cortex_a8
, struct jtag_tap
*tap
)
1607 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1608 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
1609 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1611 /* Setup struct cortex_a8_common */
1612 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1613 armv4_5
->arch_info
= armv7a
;
1615 armv4_5
->mrc
= cortex_a8_mrc
,
1616 armv4_5
->mcr
= cortex_a8_mcr
,
1618 /* prepare JTAG information for the new target */
1619 cortex_a8
->jtag_info
.tap
= tap
;
1620 cortex_a8
->jtag_info
.scann_size
= 4;
1622 swjdp
->dp_select_value
= -1;
1623 swjdp
->ap_csw_value
= -1;
1624 swjdp
->ap_tar_value
= -1;
1625 swjdp
->jtag_info
= &cortex_a8
->jtag_info
;
1626 swjdp
->memaccess_tck
= 80;
1628 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1629 swjdp
->tar_autoincr_block
= (1 << 10);
1631 cortex_a8
->fast_reg_read
= 0;
1633 /* register arch-specific functions */
1634 armv7a
->examine_debug_reason
= NULL
;
1636 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1638 armv7a
->pre_restore_context
= NULL
;
1639 armv7a
->post_restore_context
= NULL
;
1640 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1641 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1642 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_memory
;
1643 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_memory
;
1644 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1645 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1646 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1647 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1648 armv7a
->read_cp15
= cortex_a8_read_cp15
;
1649 armv7a
->write_cp15
= cortex_a8_write_cp15
;
1652 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1654 /* REVISIT v7a setup should be in a v7a-specific routine */
1655 armv4_5_init_arch_info(target
, armv4_5
);
1656 armv7a
->common_magic
= ARMV7_COMMON_MAGIC
;
1658 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1663 static int cortex_a8_target_create(struct target
*target
, Jim_Interp
*interp
)
1665 struct cortex_a8_common
*cortex_a8
= calloc(1, sizeof(struct cortex_a8_common
));
1667 cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1672 COMMAND_HANDLER(cortex_a8_handle_cache_info_command
)
1674 struct target
*target
= get_current_target(CMD_CTX
);
1675 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1677 return armv4_5_handle_cache_info_command(CMD_CTX
,
1678 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1682 COMMAND_HANDLER(cortex_a8_handle_dbginit_command
)
1684 struct target
*target
= get_current_target(CMD_CTX
);
1686 cortex_a8_init_debug_access(target
);
1691 static const struct command_registration cortex_a8_exec_command_handlers
[] = {
1693 .name
= "cache_info",
1694 .handler
= &cortex_a8_handle_cache_info_command
,
1695 .mode
= COMMAND_EXEC
,
1696 .help
= "display information about target caches",
1700 .handler
= &cortex_a8_handle_dbginit_command
,
1701 .mode
= COMMAND_EXEC
,
1702 .help
= "Initialize core debug",
1704 COMMAND_REGISTRATION_DONE
1706 static const struct command_registration cortex_a8_command_handlers
[] = {
1708 .chain
= arm_command_handlers
,
1711 .chain
= armv7a_command_handlers
,
1714 .name
= "cortex_a8",
1715 .mode
= COMMAND_ANY
,
1716 .help
= "Cortex-A8 command group",
1717 .chain
= cortex_a8_exec_command_handlers
,
1719 COMMAND_REGISTRATION_DONE
1722 struct target_type cortexa8_target
= {
1723 .name
= "cortex_a8",
1725 .poll
= cortex_a8_poll
,
1726 .arch_state
= armv7a_arch_state
,
1728 .target_request_data
= NULL
,
1730 .halt
= cortex_a8_halt
,
1731 .resume
= cortex_a8_resume
,
1732 .step
= cortex_a8_step
,
1734 .assert_reset
= cortex_a8_assert_reset
,
1735 .deassert_reset
= cortex_a8_deassert_reset
,
1736 .soft_reset_halt
= NULL
,
1738 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
1740 .read_memory
= cortex_a8_read_memory
,
1741 .write_memory
= cortex_a8_write_memory
,
1742 .bulk_write_memory
= cortex_a8_bulk_write_memory
,
1744 .checksum_memory
= arm_checksum_memory
,
1745 .blank_check_memory
= arm_blank_check_memory
,
1747 .run_algorithm
= armv4_5_run_algorithm
,
1749 .add_breakpoint
= cortex_a8_add_breakpoint
,
1750 .remove_breakpoint
= cortex_a8_remove_breakpoint
,
1751 .add_watchpoint
= NULL
,
1752 .remove_watchpoint
= NULL
,
1754 .commands
= cortex_a8_command_handlers
,
1755 .target_create
= cortex_a8_target_create
,
1756 .init_target
= cortex_a8_init_target
,
1757 .examine
= cortex_a8_examine
,
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)