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"
41 #include "arm_opcodes.h"
43 static int cortex_a8_poll(struct target
*target
);
44 static int cortex_a8_debug_entry(struct target
*target
);
45 static int cortex_a8_restore_context(struct target
*target
, bool bpwp
);
46 static int cortex_a8_set_breakpoint(struct target
*target
,
47 struct breakpoint
*breakpoint
, uint8_t matchmode
);
48 static int cortex_a8_unset_breakpoint(struct target
*target
,
49 struct breakpoint
*breakpoint
);
50 static int cortex_a8_dap_read_coreregister_u32(struct target
*target
,
51 uint32_t *value
, int regnum
);
52 static int cortex_a8_dap_write_coreregister_u32(struct target
*target
,
53 uint32_t value
, int regnum
);
55 * FIXME do topology discovery using the ROM; don't
56 * assume this is an OMAP3. Also, allow for multiple ARMv7-A
57 * cores, with different AP numbering ... don't use a #define
58 * for these numbers, use per-core armv7a state.
60 #define swjdp_memoryap 0
61 #define swjdp_debugap 1
62 #define OMAP3530_DEBUG_BASE 0x54011000
65 * Cortex-A8 Basic debug access, very low level assumes state is saved
67 static int cortex_a8_init_debug_access(struct target
*target
)
69 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
70 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
77 /* Unlocking the debug registers for modification */
78 /* The debugport might be uninitialised so try twice */
79 retval
= mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
80 if (retval
!= ERROR_OK
)
81 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
82 /* Clear Sticky Power Down status Bit in PRSR to enable access to
83 the registers in the Core Power Domain */
84 retval
= mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_PRSR
, &dummy
);
85 /* Enabling of instruction execution in debug mode is done in debug_entry code */
87 /* Resync breakpoint registers */
89 /* Since this is likley called from init or reset, update targtet state information*/
90 cortex_a8_poll(target
);
95 /* To reduce needless round-trips, pass in a pointer to the current
96 * DSCR value. Initialize it to zero if you just need to know the
97 * value on return from this function; or DSCR_INSTR_COMP if you
98 * happen to know that no instruction is pending.
100 static int cortex_a8_exec_opcode(struct target
*target
,
101 uint32_t opcode
, uint32_t *dscr_p
)
105 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
106 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
108 dscr
= dscr_p
? *dscr_p
: 0;
110 LOG_DEBUG("exec opcode 0x%08" PRIx32
, opcode
);
112 /* Wait for InstrCompl bit to be set */
113 while ((dscr
& DSCR_INSTR_COMP
) == 0)
115 retval
= mem_ap_read_atomic_u32(swjdp
,
116 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
117 if (retval
!= ERROR_OK
)
119 LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32
, opcode
);
124 mem_ap_write_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_ITR
, opcode
);
128 retval
= mem_ap_read_atomic_u32(swjdp
,
129 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
130 if (retval
!= ERROR_OK
)
132 LOG_ERROR("Could not read DSCR register");
136 while ((dscr
& DSCR_INSTR_COMP
) == 0); /* Wait for InstrCompl bit to be set */
144 /**************************************************************************
145 Read core register with very few exec_opcode, fast but needs work_area.
146 This can cause problems with MMU active.
147 **************************************************************************/
148 static int cortex_a8_read_regs_through_mem(struct target
*target
, uint32_t address
,
151 int retval
= ERROR_OK
;
152 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
153 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
155 cortex_a8_dap_read_coreregister_u32(target
, regfile
, 0);
156 cortex_a8_dap_write_coreregister_u32(target
, address
, 0);
157 cortex_a8_exec_opcode(target
, ARMV4_5_STMIA(0, 0xFFFE, 0, 0), NULL
);
158 dap_ap_select(swjdp
, swjdp_memoryap
);
159 mem_ap_read_buf_u32(swjdp
, (uint8_t *)(®file
[1]), 4*15, address
);
160 dap_ap_select(swjdp
, swjdp_debugap
);
165 static int cortex_a8_dap_read_coreregister_u32(struct target
*target
,
166 uint32_t *value
, int regnum
)
168 int retval
= ERROR_OK
;
169 uint8_t reg
= regnum
&0xFF;
171 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
172 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
179 /* Rn to DCCTX, "MCR p14, 0, Rn, c0, c5, 0" 0xEE00nE15 */
180 cortex_a8_exec_opcode(target
,
181 ARMV4_5_MCR(14, 0, reg
, 0, 5, 0),
186 /* "MOV r0, r15"; then move r0 to DCCTX */
187 cortex_a8_exec_opcode(target
, 0xE1A0000F, &dscr
);
188 cortex_a8_exec_opcode(target
,
189 ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
194 /* "MRS r0, CPSR" or "MRS r0, SPSR"
195 * then move r0 to DCCTX
197 cortex_a8_exec_opcode(target
, ARMV4_5_MRS(0, reg
& 1), &dscr
);
198 cortex_a8_exec_opcode(target
,
199 ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
203 /* Wait for DTRRXfull then read DTRRTX */
204 while ((dscr
& DSCR_DTR_TX_FULL
) == 0)
206 retval
= mem_ap_read_atomic_u32(swjdp
,
207 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
210 retval
= mem_ap_read_atomic_u32(swjdp
,
211 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
212 LOG_DEBUG("read DCC 0x%08" PRIx32
, *value
);
217 static int cortex_a8_dap_write_coreregister_u32(struct target
*target
,
218 uint32_t value
, int regnum
)
220 int retval
= ERROR_OK
;
221 uint8_t Rd
= regnum
&0xFF;
223 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
224 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
226 LOG_DEBUG("register %i, value 0x%08" PRIx32
, regnum
, value
);
228 /* Check that DCCRX is not full */
229 retval
= mem_ap_read_atomic_u32(swjdp
,
230 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
231 if (dscr
& DSCR_DTR_RX_FULL
)
233 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
234 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
235 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
242 /* Write DTRRX ... sets DSCR.DTRRXfull but exec_opcode() won't care */
243 LOG_DEBUG("write DCC 0x%08" PRIx32
, value
);
244 retval
= mem_ap_write_u32(swjdp
,
245 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
249 /* DCCRX to Rn, "MCR p14, 0, Rn, c0, c5, 0", 0xEE00nE15 */
250 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, Rd
, 0, 5, 0),
255 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15
258 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
260 cortex_a8_exec_opcode(target
, 0xE1A0F000, &dscr
);
264 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15
265 * then "MSR CPSR_cxsf, r0" or "MSR SPSR_cxsf, r0" (all fields)
267 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
269 cortex_a8_exec_opcode(target
, ARMV4_5_MSR_GP(0, 0xF, Rd
& 1),
272 /* "Prefetch flush" after modifying execution status in CPSR */
274 cortex_a8_exec_opcode(target
,
275 ARMV4_5_MCR(15, 0, 0, 7, 5, 4),
282 /* Write to memory mapped registers directly with no cache or mmu handling */
283 static int cortex_a8_dap_write_memap_register_u32(struct target
*target
, uint32_t address
, uint32_t value
)
286 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
287 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
289 retval
= mem_ap_write_atomic_u32(swjdp
, address
, value
);
295 * Cortex-A8 implementation of Debug Programmer's Model
297 * NOTE the invariant: these routines return with DSCR_INSTR_COMP set,
298 * so there's no need to poll for it before executing an instruction.
300 * NOTE that in several of these cases the "stall" mode might be useful.
301 * It'd let us queue a few operations together... prepare/finish might
302 * be the places to enable/disable that mode.
305 static inline struct cortex_a8_common
*dpm_to_a8(struct arm_dpm
*dpm
)
307 return container_of(dpm
, struct cortex_a8_common
, armv7a_common
.dpm
);
310 static int cortex_a8_write_dcc(struct cortex_a8_common
*a8
, uint32_t data
)
312 LOG_DEBUG("write DCC 0x%08" PRIx32
, data
);
313 return mem_ap_write_u32(&a8
->armv7a_common
.dap
,
314 a8
->armv7a_common
.debug_base
+ CPUDBG_DTRRX
, data
);
317 static int cortex_a8_read_dcc(struct cortex_a8_common
*a8
, uint32_t *data
,
320 struct adiv5_dap
*swjdp
= &a8
->armv7a_common
.dap
;
321 uint32_t dscr
= DSCR_INSTR_COMP
;
327 /* Wait for DTRRXfull */
328 while ((dscr
& DSCR_DTR_TX_FULL
) == 0) {
329 retval
= mem_ap_read_atomic_u32(swjdp
,
330 a8
->armv7a_common
.debug_base
+ CPUDBG_DSCR
,
334 retval
= mem_ap_read_atomic_u32(swjdp
,
335 a8
->armv7a_common
.debug_base
+ CPUDBG_DTRTX
, data
);
336 //LOG_DEBUG("read DCC 0x%08" PRIx32, *data);
344 static int cortex_a8_dpm_prepare(struct arm_dpm
*dpm
)
346 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
347 struct adiv5_dap
*swjdp
= &a8
->armv7a_common
.dap
;
351 /* set up invariant: INSTR_COMP is set after ever DPM operation */
353 retval
= mem_ap_read_atomic_u32(swjdp
,
354 a8
->armv7a_common
.debug_base
+ CPUDBG_DSCR
,
356 } while ((dscr
& DSCR_INSTR_COMP
) == 0);
358 /* this "should never happen" ... */
359 if (dscr
& DSCR_DTR_RX_FULL
) {
360 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
362 retval
= cortex_a8_exec_opcode(
363 a8
->armv7a_common
.armv4_5_common
.target
,
364 ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
371 static int cortex_a8_dpm_finish(struct arm_dpm
*dpm
)
373 /* REVISIT what could be done here? */
377 static int cortex_a8_instr_write_data_dcc(struct arm_dpm
*dpm
,
378 uint32_t opcode
, uint32_t data
)
380 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
382 uint32_t dscr
= DSCR_INSTR_COMP
;
384 retval
= cortex_a8_write_dcc(a8
, data
);
386 return cortex_a8_exec_opcode(
387 a8
->armv7a_common
.armv4_5_common
.target
,
392 static int cortex_a8_instr_write_data_r0(struct arm_dpm
*dpm
,
393 uint32_t opcode
, uint32_t data
)
395 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
396 uint32_t dscr
= DSCR_INSTR_COMP
;
399 retval
= cortex_a8_write_dcc(a8
, data
);
401 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15 */
402 retval
= cortex_a8_exec_opcode(
403 a8
->armv7a_common
.armv4_5_common
.target
,
404 ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
407 /* then the opcode, taking data from R0 */
408 retval
= cortex_a8_exec_opcode(
409 a8
->armv7a_common
.armv4_5_common
.target
,
416 static int cortex_a8_instr_cpsr_sync(struct arm_dpm
*dpm
)
418 struct target
*target
= dpm
->arm
->target
;
419 uint32_t dscr
= DSCR_INSTR_COMP
;
421 /* "Prefetch flush" after modifying execution status in CPSR */
422 return cortex_a8_exec_opcode(target
,
423 ARMV4_5_MCR(15, 0, 0, 7, 5, 4),
427 static int cortex_a8_instr_read_data_dcc(struct arm_dpm
*dpm
,
428 uint32_t opcode
, uint32_t *data
)
430 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
432 uint32_t dscr
= DSCR_INSTR_COMP
;
434 /* the opcode, writing data to DCC */
435 retval
= cortex_a8_exec_opcode(
436 a8
->armv7a_common
.armv4_5_common
.target
,
440 return cortex_a8_read_dcc(a8
, data
, &dscr
);
444 static int cortex_a8_instr_read_data_r0(struct arm_dpm
*dpm
,
445 uint32_t opcode
, uint32_t *data
)
447 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
448 uint32_t dscr
= DSCR_INSTR_COMP
;
451 /* the opcode, writing data to R0 */
452 retval
= cortex_a8_exec_opcode(
453 a8
->armv7a_common
.armv4_5_common
.target
,
457 /* write R0 to DCC */
458 retval
= cortex_a8_exec_opcode(
459 a8
->armv7a_common
.armv4_5_common
.target
,
460 ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
463 return cortex_a8_read_dcc(a8
, data
, &dscr
);
466 static int cortex_a8_bpwp_enable(struct arm_dpm
*dpm
, unsigned index
,
467 uint32_t addr
, uint32_t control
)
469 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
470 uint32_t vr
= a8
->armv7a_common
.debug_base
;
471 uint32_t cr
= a8
->armv7a_common
.debug_base
;
475 case 0 ... 15: /* breakpoints */
476 vr
+= CPUDBG_BVR_BASE
;
477 cr
+= CPUDBG_BCR_BASE
;
479 case 16 ... 31: /* watchpoints */
480 vr
+= CPUDBG_WVR_BASE
;
481 cr
+= CPUDBG_WCR_BASE
;
490 LOG_DEBUG("A8: bpwp enable, vr %08x cr %08x",
491 (unsigned) vr
, (unsigned) cr
);
493 retval
= cortex_a8_dap_write_memap_register_u32(dpm
->arm
->target
,
495 if (retval
!= ERROR_OK
)
497 retval
= cortex_a8_dap_write_memap_register_u32(dpm
->arm
->target
,
502 static int cortex_a8_bpwp_disable(struct arm_dpm
*dpm
, unsigned index
)
504 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
509 cr
= a8
->armv7a_common
.debug_base
+ CPUDBG_BCR_BASE
;
512 cr
= a8
->armv7a_common
.debug_base
+ CPUDBG_WCR_BASE
;
520 LOG_DEBUG("A8: bpwp disable, cr %08x", (unsigned) cr
);
522 /* clear control register */
523 return cortex_a8_dap_write_memap_register_u32(dpm
->arm
->target
, cr
, 0);
526 static int cortex_a8_dpm_setup(struct cortex_a8_common
*a8
, uint32_t didr
)
528 struct arm_dpm
*dpm
= &a8
->armv7a_common
.dpm
;
531 dpm
->arm
= &a8
->armv7a_common
.armv4_5_common
;
534 dpm
->prepare
= cortex_a8_dpm_prepare
;
535 dpm
->finish
= cortex_a8_dpm_finish
;
537 dpm
->instr_write_data_dcc
= cortex_a8_instr_write_data_dcc
;
538 dpm
->instr_write_data_r0
= cortex_a8_instr_write_data_r0
;
539 dpm
->instr_cpsr_sync
= cortex_a8_instr_cpsr_sync
;
541 dpm
->instr_read_data_dcc
= cortex_a8_instr_read_data_dcc
;
542 dpm
->instr_read_data_r0
= cortex_a8_instr_read_data_r0
;
544 dpm
->bpwp_enable
= cortex_a8_bpwp_enable
;
545 dpm
->bpwp_disable
= cortex_a8_bpwp_disable
;
547 retval
= arm_dpm_setup(dpm
);
548 if (retval
== ERROR_OK
)
549 retval
= arm_dpm_initialize(dpm
);
556 * Cortex-A8 Run control
559 static int cortex_a8_poll(struct target
*target
)
561 int retval
= ERROR_OK
;
563 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
564 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
565 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
566 enum target_state prev_target_state
= target
->state
;
567 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
569 dap_ap_select(swjdp
, swjdp_debugap
);
570 retval
= mem_ap_read_atomic_u32(swjdp
,
571 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
572 if (retval
!= ERROR_OK
)
574 dap_ap_select(swjdp
, saved_apsel
);
577 cortex_a8
->cpudbg_dscr
= dscr
;
579 if ((dscr
& 0x3) == 0x3)
581 if (prev_target_state
!= TARGET_HALTED
)
583 /* We have a halting debug event */
584 LOG_DEBUG("Target halted");
585 target
->state
= TARGET_HALTED
;
586 if ((prev_target_state
== TARGET_RUNNING
)
587 || (prev_target_state
== TARGET_RESET
))
589 retval
= cortex_a8_debug_entry(target
);
590 if (retval
!= ERROR_OK
)
593 target_call_event_callbacks(target
,
594 TARGET_EVENT_HALTED
);
596 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
600 retval
= cortex_a8_debug_entry(target
);
601 if (retval
!= ERROR_OK
)
604 target_call_event_callbacks(target
,
605 TARGET_EVENT_DEBUG_HALTED
);
609 else if ((dscr
& 0x3) == 0x2)
611 target
->state
= TARGET_RUNNING
;
615 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32
, dscr
);
616 target
->state
= TARGET_UNKNOWN
;
619 dap_ap_select(swjdp
, saved_apsel
);
624 static int cortex_a8_halt(struct target
*target
)
626 int retval
= ERROR_OK
;
628 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
629 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
630 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
631 dap_ap_select(swjdp
, swjdp_debugap
);
634 * Tell the core to be halted by writing DRCR with 0x1
635 * and then wait for the core to be halted.
637 retval
= mem_ap_write_atomic_u32(swjdp
,
638 armv7a
->debug_base
+ CPUDBG_DRCR
, 0x1);
641 * enter halting debug mode
643 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
644 retval
= mem_ap_write_atomic_u32(swjdp
,
645 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
| DSCR_HALT_DBG_MODE
);
647 if (retval
!= ERROR_OK
)
651 mem_ap_read_atomic_u32(swjdp
,
652 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
653 } while ((dscr
& DSCR_CORE_HALTED
) == 0);
655 target
->debug_reason
= DBG_REASON_DBGRQ
;
658 dap_ap_select(swjdp
, saved_apsel
);
662 static int cortex_a8_resume(struct target
*target
, int current
,
663 uint32_t address
, int handle_breakpoints
, int debug_execution
)
665 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
666 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
667 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
669 // struct breakpoint *breakpoint = NULL;
670 uint32_t resume_pc
, dscr
;
672 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
673 dap_ap_select(swjdp
, swjdp_debugap
);
675 if (!debug_execution
)
676 target_free_all_working_areas(target
);
681 /* Disable interrupts */
682 /* We disable interrupts in the PRIMASK register instead of
683 * masking with C_MASKINTS,
684 * This is probably the same issue as Cortex-M3 Errata 377493:
685 * C_MASKINTS in parallel with disabled interrupts can cause
686 * local faults to not be taken. */
687 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
688 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
689 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
691 /* Make sure we are in Thumb mode */
692 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
693 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
694 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
695 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
699 /* current = 1: continue on current pc, otherwise continue at <address> */
700 resume_pc
= buf_get_u32(armv4_5
->pc
->value
, 0, 32);
704 /* Make sure that the Armv7 gdb thumb fixups does not
705 * kill the return address
707 switch (armv4_5
->core_state
)
710 resume_pc
&= 0xFFFFFFFC;
712 case ARM_STATE_THUMB
:
713 case ARM_STATE_THUMB_EE
:
714 /* When the return address is loaded into PC
715 * bit 0 must be 1 to stay in Thumb state
719 case ARM_STATE_JAZELLE
:
720 LOG_ERROR("How do I resume into Jazelle state??");
723 LOG_DEBUG("resume pc = 0x%08" PRIx32
, resume_pc
);
724 buf_set_u32(armv4_5
->pc
->value
, 0, 32, resume_pc
);
725 armv4_5
->pc
->dirty
= 1;
726 armv4_5
->pc
->valid
= 1;
728 cortex_a8_restore_context(target
, handle_breakpoints
);
731 /* the front-end may request us not to handle breakpoints */
732 if (handle_breakpoints
)
734 /* Single step past breakpoint at current address */
735 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
737 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
738 cortex_m3_unset_breakpoint(target
, breakpoint
);
739 cortex_m3_single_step_core(target
);
740 cortex_m3_set_breakpoint(target
, breakpoint
);
745 /* Restart core and wait for it to be started
746 * NOTE: this clears DSCR_ITR_EN and other bits.
748 * REVISIT: for single stepping, we probably want to
749 * disable IRQs by default, with optional override...
751 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DRCR
, 0x2);
754 mem_ap_read_atomic_u32(swjdp
,
755 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
756 } while ((dscr
& DSCR_CORE_RESTARTED
) == 0);
758 target
->debug_reason
= DBG_REASON_NOTHALTED
;
759 target
->state
= TARGET_RUNNING
;
761 /* registers are now invalid */
762 register_cache_invalidate(armv4_5
->core_cache
);
764 if (!debug_execution
)
766 target
->state
= TARGET_RUNNING
;
767 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
768 LOG_DEBUG("target resumed at 0x%" PRIx32
, resume_pc
);
772 target
->state
= TARGET_DEBUG_RUNNING
;
773 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
774 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, resume_pc
);
777 dap_ap_select(swjdp
, saved_apsel
);
782 static int cortex_a8_debug_entry(struct target
*target
)
785 uint32_t regfile
[16], cpsr
, dscr
;
786 int retval
= ERROR_OK
;
787 struct working_area
*regfile_working_area
= NULL
;
788 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
789 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
790 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
791 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
794 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
796 /* REVISIT surely we should not re-read DSCR !! */
797 mem_ap_read_atomic_u32(swjdp
,
798 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
800 /* REVISIT see A8 TRM 12.11.4 steps 2..3 -- make sure that any
801 * imprecise data aborts get discarded by issuing a Data
802 * Synchronization Barrier: ARMV4_5_MCR(15, 0, 0, 7, 10, 4).
805 /* Enable the ITR execution once we are in debug mode */
807 retval
= mem_ap_write_atomic_u32(swjdp
,
808 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
);
810 /* Examine debug reason */
811 arm_dpm_report_dscr(&armv7a
->dpm
, cortex_a8
->cpudbg_dscr
);
813 /* save address of instruction that triggered the watchpoint? */
814 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
) {
817 retval
= mem_ap_read_atomic_u32(swjdp
,
818 armv7a
->debug_base
+ CPUDBG_WFAR
,
820 arm_dpm_report_wfar(&armv7a
->dpm
, wfar
);
823 /* REVISIT fast_reg_read is never set ... */
825 /* Examine target state and mode */
826 if (cortex_a8
->fast_reg_read
)
827 target_alloc_working_area(target
, 64, ®file_working_area
);
829 /* First load register acessible through core debug port*/
830 if (!regfile_working_area
)
832 retval
= arm_dpm_read_current_registers(&armv7a
->dpm
);
836 dap_ap_select(swjdp
, swjdp_memoryap
);
837 cortex_a8_read_regs_through_mem(target
,
838 regfile_working_area
->address
, regfile
);
839 dap_ap_select(swjdp
, swjdp_memoryap
);
840 target_free_working_area(target
, regfile_working_area
);
842 /* read Current PSR */
843 cortex_a8_dap_read_coreregister_u32(target
, &cpsr
, 16);
844 dap_ap_select(swjdp
, swjdp_debugap
);
845 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
847 arm_set_cpsr(armv4_5
, cpsr
);
850 for (i
= 0; i
<= ARM_PC
; i
++)
852 reg
= arm_reg_current(armv4_5
, i
);
854 buf_set_u32(reg
->value
, 0, 32, regfile
[i
]);
859 /* Fixup PC Resume Address */
862 // T bit set for Thumb or ThumbEE state
863 regfile
[ARM_PC
] -= 4;
868 regfile
[ARM_PC
] -= 8;
872 buf_set_u32(reg
->value
, 0, 32, regfile
[ARM_PC
]);
873 reg
->dirty
= reg
->valid
;
877 /* TODO, Move this */
878 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
879 cortex_a8_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
880 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
882 cortex_a8_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
883 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
885 cortex_a8_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
886 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
889 /* Are we in an exception handler */
890 // armv4_5->exception_number = 0;
891 if (armv7a
->post_debug_entry
)
892 armv7a
->post_debug_entry(target
);
897 static void cortex_a8_post_debug_entry(struct target
*target
)
899 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
900 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
903 /* MRC p15,0,<Rt>,c1,c0,0 ; Read CP15 System Control Register */
904 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
907 &cortex_a8
->cp15_control_reg
);
908 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
910 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
912 uint32_t cache_type_reg
;
914 /* MRC p15,0,<Rt>,c0,c0,1 ; Read CP15 Cache Type Register */
915 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
919 LOG_DEBUG("cp15 cache type: %8.8x", (unsigned) cache_type_reg
);
921 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
922 armv4_5_identify_cache(cache_type_reg
,
923 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
926 armv7a
->armv4_5_mmu
.mmu_enabled
=
927 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
928 armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
=
929 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
930 armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
=
931 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
936 static int cortex_a8_step(struct target
*target
, int current
, uint32_t address
,
937 int handle_breakpoints
)
939 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
940 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
941 struct breakpoint
*breakpoint
= NULL
;
942 struct breakpoint stepbreakpoint
;
947 if (target
->state
!= TARGET_HALTED
)
949 LOG_WARNING("target not halted");
950 return ERROR_TARGET_NOT_HALTED
;
953 /* current = 1: continue on current pc, otherwise continue at <address> */
957 buf_set_u32(r
->value
, 0, 32, address
);
961 address
= buf_get_u32(r
->value
, 0, 32);
964 /* The front-end may request us not to handle breakpoints.
965 * But since Cortex-A8 uses breakpoint for single step,
966 * we MUST handle breakpoints.
968 handle_breakpoints
= 1;
969 if (handle_breakpoints
) {
970 breakpoint
= breakpoint_find(target
, address
);
972 cortex_a8_unset_breakpoint(target
, breakpoint
);
975 /* Setup single step breakpoint */
976 stepbreakpoint
.address
= address
;
977 stepbreakpoint
.length
= (armv4_5
->core_state
== ARM_STATE_THUMB
)
979 stepbreakpoint
.type
= BKPT_HARD
;
980 stepbreakpoint
.set
= 0;
982 /* Break on IVA mismatch */
983 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
985 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
987 cortex_a8_resume(target
, 1, address
, 0, 0);
989 while (target
->state
!= TARGET_HALTED
)
991 cortex_a8_poll(target
);
994 LOG_WARNING("timeout waiting for target halt");
999 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
1001 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1004 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
1006 if (target
->state
!= TARGET_HALTED
)
1007 LOG_DEBUG("target stepped");
1012 static int cortex_a8_restore_context(struct target
*target
, bool bpwp
)
1014 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1018 if (armv7a
->pre_restore_context
)
1019 armv7a
->pre_restore_context(target
);
1021 arm_dpm_write_dirty_registers(&armv7a
->dpm
, bpwp
);
1023 if (armv7a
->post_restore_context
)
1024 armv7a
->post_restore_context(target
);
1031 * Cortex-A8 Breakpoint and watchpoint fuctions
1034 /* Setup hardware Breakpoint Register Pair */
1035 static int cortex_a8_set_breakpoint(struct target
*target
,
1036 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1041 uint8_t byte_addr_select
= 0x0F;
1042 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1043 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1044 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1046 if (breakpoint
->set
)
1048 LOG_WARNING("breakpoint already set");
1052 if (breakpoint
->type
== BKPT_HARD
)
1054 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
1056 if (brp_i
>= cortex_a8
->brp_num
)
1058 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1061 breakpoint
->set
= brp_i
+ 1;
1062 if (breakpoint
->length
== 2)
1064 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1066 control
= ((matchmode
& 0x7) << 20)
1067 | (byte_addr_select
<< 5)
1069 brp_list
[brp_i
].used
= 1;
1070 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1071 brp_list
[brp_i
].control
= control
;
1072 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1073 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1074 brp_list
[brp_i
].value
);
1075 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1076 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1077 brp_list
[brp_i
].control
);
1078 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1079 brp_list
[brp_i
].control
,
1080 brp_list
[brp_i
].value
);
1082 else if (breakpoint
->type
== BKPT_SOFT
)
1085 if (breakpoint
->length
== 2)
1087 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1091 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1093 retval
= target
->type
->read_memory(target
,
1094 breakpoint
->address
& 0xFFFFFFFE,
1095 breakpoint
->length
, 1,
1096 breakpoint
->orig_instr
);
1097 if (retval
!= ERROR_OK
)
1099 retval
= target
->type
->write_memory(target
,
1100 breakpoint
->address
& 0xFFFFFFFE,
1101 breakpoint
->length
, 1, code
);
1102 if (retval
!= ERROR_OK
)
1104 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1110 static int cortex_a8_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1113 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1114 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1115 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1117 if (!breakpoint
->set
)
1119 LOG_WARNING("breakpoint not set");
1123 if (breakpoint
->type
== BKPT_HARD
)
1125 int brp_i
= breakpoint
->set
- 1;
1126 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1128 LOG_DEBUG("Invalid BRP number in breakpoint");
1131 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1132 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1133 brp_list
[brp_i
].used
= 0;
1134 brp_list
[brp_i
].value
= 0;
1135 brp_list
[brp_i
].control
= 0;
1136 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1137 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1138 brp_list
[brp_i
].control
);
1139 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1140 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1141 brp_list
[brp_i
].value
);
1145 /* restore original instruction (kept in target endianness) */
1146 if (breakpoint
->length
== 4)
1148 retval
= target
->type
->write_memory(target
,
1149 breakpoint
->address
& 0xFFFFFFFE,
1150 4, 1, breakpoint
->orig_instr
);
1151 if (retval
!= ERROR_OK
)
1156 retval
= target
->type
->write_memory(target
,
1157 breakpoint
->address
& 0xFFFFFFFE,
1158 2, 1, breakpoint
->orig_instr
);
1159 if (retval
!= ERROR_OK
)
1163 breakpoint
->set
= 0;
1168 static int cortex_a8_add_breakpoint(struct target
*target
,
1169 struct breakpoint
*breakpoint
)
1171 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1173 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1175 LOG_INFO("no hardware breakpoint available");
1176 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1179 if (breakpoint
->type
== BKPT_HARD
)
1180 cortex_a8
->brp_num_available
--;
1181 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1186 static int cortex_a8_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1188 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1191 /* It is perfectly possible to remove brakpoints while the taget is running */
1192 if (target
->state
!= TARGET_HALTED
)
1194 LOG_WARNING("target not halted");
1195 return ERROR_TARGET_NOT_HALTED
;
1199 if (breakpoint
->set
)
1201 cortex_a8_unset_breakpoint(target
, breakpoint
);
1202 if (breakpoint
->type
== BKPT_HARD
)
1203 cortex_a8
->brp_num_available
++ ;
1213 * Cortex-A8 Reset fuctions
1216 static int cortex_a8_assert_reset(struct target
*target
)
1218 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1222 /* FIXME when halt is requested, make it work somehow... */
1224 /* Issue some kind of warm reset. */
1225 if (target_has_event_action(target
, TARGET_EVENT_RESET_ASSERT
)) {
1226 target_handle_event(target
, TARGET_EVENT_RESET_ASSERT
);
1227 } else if (jtag_get_reset_config() & RESET_HAS_SRST
) {
1228 /* REVISIT handle "pulls" cases, if there's
1229 * hardware that needs them to work.
1231 jtag_add_reset(0, 1);
1233 LOG_ERROR("%s: how to reset?", target_name(target
));
1237 /* registers are now invalid */
1238 register_cache_invalidate(armv7a
->armv4_5_common
.core_cache
);
1240 target
->state
= TARGET_RESET
;
1245 static int cortex_a8_deassert_reset(struct target
*target
)
1251 /* be certain SRST is off */
1252 jtag_add_reset(0, 0);
1254 retval
= cortex_a8_poll(target
);
1256 if (target
->reset_halt
) {
1257 if (target
->state
!= TARGET_HALTED
) {
1258 LOG_WARNING("%s: ran after reset and before halt ...",
1259 target_name(target
));
1260 if ((retval
= target_halt(target
)) != ERROR_OK
)
1269 * Cortex-A8 Memory access
1271 * This is same Cortex M3 but we must also use the correct
1272 * ap number for every access.
1275 static int cortex_a8_read_memory(struct target
*target
, uint32_t address
,
1276 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1278 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1279 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
1280 int retval
= ERROR_INVALID_ARGUMENTS
;
1282 /* cortex_a8 handles unaligned memory access */
1284 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1286 if (count
&& buffer
) {
1289 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1292 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1295 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1303 static int cortex_a8_write_memory(struct target
*target
, uint32_t address
,
1304 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1306 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1307 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
1308 int retval
= ERROR_INVALID_ARGUMENTS
;
1310 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1312 if (count
&& buffer
) {
1315 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1318 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1321 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1326 /* REVISIT this op is generic ARMv7-A/R stuff */
1327 if (retval
== ERROR_OK
&& target
->state
== TARGET_HALTED
)
1329 struct arm_dpm
*dpm
= armv7a
->armv4_5_common
.dpm
;
1331 retval
= dpm
->prepare(dpm
);
1332 if (retval
!= ERROR_OK
)
1335 /* The Cache handling will NOT work with MMU active, the
1336 * wrong addresses will be invalidated!
1338 * For both ICache and DCache, walk all cache lines in the
1339 * address range. Cortex-A8 has fixed 64 byte line length.
1341 * REVISIT per ARMv7, these may trigger watchpoints ...
1344 /* invalidate I-Cache */
1345 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
1347 /* ICIMVAU - Invalidate Cache single entry
1349 * MCR p15, 0, r0, c7, c5, 1
1351 for (uint32_t cacheline
= address
;
1352 cacheline
< address
+ size
* count
;
1354 retval
= dpm
->instr_write_data_r0(dpm
,
1355 ARMV4_5_MCR(15, 0, 0, 7, 5, 1),
1360 /* invalidate D-Cache */
1361 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
1363 /* DCIMVAC - Invalidate data Cache line
1365 * MCR p15, 0, r0, c7, c6, 1
1367 for (uint32_t cacheline
= address
;
1368 cacheline
< address
+ size
* count
;
1370 retval
= dpm
->instr_write_data_r0(dpm
,
1371 ARMV4_5_MCR(15, 0, 0, 7, 6, 1),
1376 /* (void) */ dpm
->finish(dpm
);
1382 static int cortex_a8_bulk_write_memory(struct target
*target
, uint32_t address
,
1383 uint32_t count
, uint8_t *buffer
)
1385 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1389 static int cortex_a8_dcc_read(struct adiv5_dap
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1394 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1395 *ctrl
= (uint8_t)dcrdr
;
1396 *value
= (uint8_t)(dcrdr
>> 8);
1398 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1400 /* write ack back to software dcc register
1401 * signify we have read data */
1402 if (dcrdr
& (1 << 0))
1405 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1412 static int cortex_a8_handle_target_request(void *priv
)
1414 struct target
*target
= priv
;
1415 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1416 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
1418 if (!target_was_examined(target
))
1420 if (!target
->dbg_msg_enabled
)
1423 if (target
->state
== TARGET_RUNNING
)
1428 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1430 /* check if we have data */
1431 if (ctrl
& (1 << 0))
1435 /* we assume target is quick enough */
1437 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1438 request
|= (data
<< 8);
1439 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1440 request
|= (data
<< 16);
1441 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1442 request
|= (data
<< 24);
1443 target_request(target
, request
);
1451 * Cortex-A8 target information and configuration
1454 static int cortex_a8_examine_first(struct target
*target
)
1456 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1457 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1458 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
1460 int retval
= ERROR_OK
;
1461 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1463 /* stop assuming this is an OMAP! */
1464 LOG_DEBUG("TODO - autoconfigure");
1466 /* Here we shall insert a proper ROM Table scan */
1467 armv7a
->debug_base
= OMAP3530_DEBUG_BASE
;
1469 /* We do one extra read to ensure DAP is configured,
1470 * we call ahbap_debugport_init(swjdp) instead
1472 ahbap_debugport_init(swjdp
);
1473 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
1474 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1475 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1477 LOG_DEBUG("Examine %s failed", "CPUID");
1481 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1482 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1484 LOG_DEBUG("Examine %s failed", "CTYPR");
1488 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1489 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1491 LOG_DEBUG("Examine %s failed", "TTYPR");
1495 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1496 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1498 LOG_DEBUG("Examine %s failed", "DIDR");
1502 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1503 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1504 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1505 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1507 armv7a
->armv4_5_common
.core_type
= ARM_MODE_MON
;
1508 cortex_a8_dpm_setup(cortex_a8
, didr
);
1510 /* Setup Breakpoint Register Pairs */
1511 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1512 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1513 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1514 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(struct cortex_a8_brp
));
1515 // cortex_a8->brb_enabled = ????;
1516 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1518 cortex_a8
->brp_list
[i
].used
= 0;
1519 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1520 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1522 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1523 cortex_a8
->brp_list
[i
].value
= 0;
1524 cortex_a8
->brp_list
[i
].control
= 0;
1525 cortex_a8
->brp_list
[i
].BRPn
= i
;
1528 LOG_DEBUG("Configured %i hw breakpoints", cortex_a8
->brp_num
);
1530 target_set_examined(target
);
1534 static int cortex_a8_examine(struct target
*target
)
1536 int retval
= ERROR_OK
;
1538 /* don't re-probe hardware after each reset */
1539 if (!target_was_examined(target
))
1540 retval
= cortex_a8_examine_first(target
);
1542 /* Configure core debug access */
1543 if (retval
== ERROR_OK
)
1544 retval
= cortex_a8_init_debug_access(target
);
1550 * Cortex-A8 target creation and initialization
1553 static int cortex_a8_init_target(struct command_context
*cmd_ctx
,
1554 struct target
*target
)
1556 /* examine_first() does a bunch of this */
1560 static int cortex_a8_init_arch_info(struct target
*target
,
1561 struct cortex_a8_common
*cortex_a8
, struct jtag_tap
*tap
)
1563 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1564 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
1565 struct adiv5_dap
*dap
= &armv7a
->dap
;
1567 armv7a
->armv4_5_common
.dap
= dap
;
1569 /* Setup struct cortex_a8_common */
1570 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1571 armv4_5
->arch_info
= armv7a
;
1573 /* prepare JTAG information for the new target */
1574 cortex_a8
->jtag_info
.tap
= tap
;
1575 cortex_a8
->jtag_info
.scann_size
= 4;
1577 /* Leave (only) generic DAP stuff for debugport_init() */
1578 dap
->jtag_info
= &cortex_a8
->jtag_info
;
1579 dap
->memaccess_tck
= 80;
1581 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1582 dap
->tar_autoincr_block
= (1 << 10);
1584 cortex_a8
->fast_reg_read
= 0;
1586 /* register arch-specific functions */
1587 armv7a
->examine_debug_reason
= NULL
;
1589 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1591 armv7a
->pre_restore_context
= NULL
;
1592 armv7a
->post_restore_context
= NULL
;
1593 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1594 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1595 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_memory
;
1596 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_memory
;
1597 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1598 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1599 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1600 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1603 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1605 /* REVISIT v7a setup should be in a v7a-specific routine */
1606 arm_init_arch_info(target
, armv4_5
);
1607 armv7a
->common_magic
= ARMV7_COMMON_MAGIC
;
1609 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1614 static int cortex_a8_target_create(struct target
*target
, Jim_Interp
*interp
)
1616 struct cortex_a8_common
*cortex_a8
= calloc(1, sizeof(struct cortex_a8_common
));
1618 cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1623 COMMAND_HANDLER(cortex_a8_handle_cache_info_command
)
1625 struct target
*target
= get_current_target(CMD_CTX
);
1626 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1628 return armv4_5_handle_cache_info_command(CMD_CTX
,
1629 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1633 COMMAND_HANDLER(cortex_a8_handle_dbginit_command
)
1635 struct target
*target
= get_current_target(CMD_CTX
);
1637 cortex_a8_init_debug_access(target
);
1642 static const struct command_registration cortex_a8_exec_command_handlers
[] = {
1644 .name
= "cache_info",
1645 .handler
= cortex_a8_handle_cache_info_command
,
1646 .mode
= COMMAND_EXEC
,
1647 .help
= "display information about target caches",
1651 .handler
= cortex_a8_handle_dbginit_command
,
1652 .mode
= COMMAND_EXEC
,
1653 .help
= "Initialize core debug",
1655 COMMAND_REGISTRATION_DONE
1657 static const struct command_registration cortex_a8_command_handlers
[] = {
1659 .chain
= arm_command_handlers
,
1662 .chain
= armv7a_command_handlers
,
1665 .name
= "cortex_a8",
1666 .mode
= COMMAND_ANY
,
1667 .help
= "Cortex-A8 command group",
1668 .chain
= cortex_a8_exec_command_handlers
,
1670 COMMAND_REGISTRATION_DONE
1673 struct target_type cortexa8_target
= {
1674 .name
= "cortex_a8",
1676 .poll
= cortex_a8_poll
,
1677 .arch_state
= armv7a_arch_state
,
1679 .target_request_data
= NULL
,
1681 .halt
= cortex_a8_halt
,
1682 .resume
= cortex_a8_resume
,
1683 .step
= cortex_a8_step
,
1685 .assert_reset
= cortex_a8_assert_reset
,
1686 .deassert_reset
= cortex_a8_deassert_reset
,
1687 .soft_reset_halt
= NULL
,
1689 /* REVISIT allow exporting VFP3 registers ... */
1690 .get_gdb_reg_list
= arm_get_gdb_reg_list
,
1692 .read_memory
= cortex_a8_read_memory
,
1693 .write_memory
= cortex_a8_write_memory
,
1694 .bulk_write_memory
= cortex_a8_bulk_write_memory
,
1696 .checksum_memory
= arm_checksum_memory
,
1697 .blank_check_memory
= arm_blank_check_memory
,
1699 .run_algorithm
= armv4_5_run_algorithm
,
1701 .add_breakpoint
= cortex_a8_add_breakpoint
,
1702 .remove_breakpoint
= cortex_a8_remove_breakpoint
,
1703 .add_watchpoint
= NULL
,
1704 .remove_watchpoint
= NULL
,
1706 .commands
= cortex_a8_command_handlers
,
1707 .target_create
= cortex_a8_target_create
,
1708 .init_target
= cortex_a8_init_target
,
1709 .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)