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
);
1028 * Cortex-A8 Breakpoint and watchpoint fuctions
1031 /* Setup hardware Breakpoint Register Pair */
1032 static int cortex_a8_set_breakpoint(struct target
*target
,
1033 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1038 uint8_t byte_addr_select
= 0x0F;
1039 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1040 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1041 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1043 if (breakpoint
->set
)
1045 LOG_WARNING("breakpoint already set");
1049 if (breakpoint
->type
== BKPT_HARD
)
1051 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
1053 if (brp_i
>= cortex_a8
->brp_num
)
1055 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1058 breakpoint
->set
= brp_i
+ 1;
1059 if (breakpoint
->length
== 2)
1061 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1063 control
= ((matchmode
& 0x7) << 20)
1064 | (byte_addr_select
<< 5)
1066 brp_list
[brp_i
].used
= 1;
1067 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1068 brp_list
[brp_i
].control
= control
;
1069 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1070 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1071 brp_list
[brp_i
].value
);
1072 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1073 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1074 brp_list
[brp_i
].control
);
1075 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1076 brp_list
[brp_i
].control
,
1077 brp_list
[brp_i
].value
);
1079 else if (breakpoint
->type
== BKPT_SOFT
)
1082 if (breakpoint
->length
== 2)
1084 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1088 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1090 retval
= target
->type
->read_memory(target
,
1091 breakpoint
->address
& 0xFFFFFFFE,
1092 breakpoint
->length
, 1,
1093 breakpoint
->orig_instr
);
1094 if (retval
!= ERROR_OK
)
1096 retval
= target
->type
->write_memory(target
,
1097 breakpoint
->address
& 0xFFFFFFFE,
1098 breakpoint
->length
, 1, code
);
1099 if (retval
!= ERROR_OK
)
1101 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1107 static int cortex_a8_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1110 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1111 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1112 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1114 if (!breakpoint
->set
)
1116 LOG_WARNING("breakpoint not set");
1120 if (breakpoint
->type
== BKPT_HARD
)
1122 int brp_i
= breakpoint
->set
- 1;
1123 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1125 LOG_DEBUG("Invalid BRP number in breakpoint");
1128 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1129 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1130 brp_list
[brp_i
].used
= 0;
1131 brp_list
[brp_i
].value
= 0;
1132 brp_list
[brp_i
].control
= 0;
1133 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1134 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1135 brp_list
[brp_i
].control
);
1136 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1137 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1138 brp_list
[brp_i
].value
);
1142 /* restore original instruction (kept in target endianness) */
1143 if (breakpoint
->length
== 4)
1145 retval
= target
->type
->write_memory(target
,
1146 breakpoint
->address
& 0xFFFFFFFE,
1147 4, 1, breakpoint
->orig_instr
);
1148 if (retval
!= ERROR_OK
)
1153 retval
= target
->type
->write_memory(target
,
1154 breakpoint
->address
& 0xFFFFFFFE,
1155 2, 1, breakpoint
->orig_instr
);
1156 if (retval
!= ERROR_OK
)
1160 breakpoint
->set
= 0;
1165 static int cortex_a8_add_breakpoint(struct target
*target
,
1166 struct breakpoint
*breakpoint
)
1168 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1170 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1172 LOG_INFO("no hardware breakpoint available");
1173 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1176 if (breakpoint
->type
== BKPT_HARD
)
1177 cortex_a8
->brp_num_available
--;
1178 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1183 static int cortex_a8_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1185 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1188 /* It is perfectly possible to remove brakpoints while the taget is running */
1189 if (target
->state
!= TARGET_HALTED
)
1191 LOG_WARNING("target not halted");
1192 return ERROR_TARGET_NOT_HALTED
;
1196 if (breakpoint
->set
)
1198 cortex_a8_unset_breakpoint(target
, breakpoint
);
1199 if (breakpoint
->type
== BKPT_HARD
)
1200 cortex_a8
->brp_num_available
++ ;
1210 * Cortex-A8 Reset fuctions
1213 static int cortex_a8_assert_reset(struct target
*target
)
1215 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1219 /* FIXME when halt is requested, make it work somehow... */
1221 /* Issue some kind of warm reset. */
1222 if (target_has_event_action(target
, TARGET_EVENT_RESET_ASSERT
)) {
1223 target_handle_event(target
, TARGET_EVENT_RESET_ASSERT
);
1224 } else if (jtag_get_reset_config() & RESET_HAS_SRST
) {
1225 /* REVISIT handle "pulls" cases, if there's
1226 * hardware that needs them to work.
1228 jtag_add_reset(0, 1);
1230 LOG_ERROR("%s: how to reset?", target_name(target
));
1234 /* registers are now invalid */
1235 register_cache_invalidate(armv7a
->armv4_5_common
.core_cache
);
1237 target
->state
= TARGET_RESET
;
1242 static int cortex_a8_deassert_reset(struct target
*target
)
1248 /* be certain SRST is off */
1249 jtag_add_reset(0, 0);
1251 retval
= cortex_a8_poll(target
);
1253 if (target
->reset_halt
) {
1254 if (target
->state
!= TARGET_HALTED
) {
1255 LOG_WARNING("%s: ran after reset and before halt ...",
1256 target_name(target
));
1257 if ((retval
= target_halt(target
)) != ERROR_OK
)
1266 * Cortex-A8 Memory access
1268 * This is same Cortex M3 but we must also use the correct
1269 * ap number for every access.
1272 static int cortex_a8_read_memory(struct target
*target
, uint32_t address
,
1273 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1275 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1276 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
1277 int retval
= ERROR_INVALID_ARGUMENTS
;
1279 /* cortex_a8 handles unaligned memory access */
1281 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1283 if (count
&& buffer
) {
1286 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1289 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1292 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1300 static int cortex_a8_write_memory(struct target
*target
, uint32_t address
,
1301 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1303 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1304 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
1305 int retval
= ERROR_INVALID_ARGUMENTS
;
1307 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1309 if (count
&& buffer
) {
1312 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1315 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1318 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1323 /* REVISIT this op is generic ARMv7-A/R stuff */
1324 if (retval
== ERROR_OK
&& target
->state
== TARGET_HALTED
)
1326 struct arm_dpm
*dpm
= armv7a
->armv4_5_common
.dpm
;
1328 retval
= dpm
->prepare(dpm
);
1329 if (retval
!= ERROR_OK
)
1332 /* The Cache handling will NOT work with MMU active, the
1333 * wrong addresses will be invalidated!
1335 * For both ICache and DCache, walk all cache lines in the
1336 * address range. Cortex-A8 has fixed 64 byte line length.
1338 * REVISIT per ARMv7, these may trigger watchpoints ...
1341 /* invalidate I-Cache */
1342 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
1344 /* ICIMVAU - Invalidate Cache single entry
1346 * MCR p15, 0, r0, c7, c5, 1
1348 for (uint32_t cacheline
= address
;
1349 cacheline
< address
+ size
* count
;
1351 retval
= dpm
->instr_write_data_r0(dpm
,
1352 ARMV4_5_MCR(15, 0, 0, 7, 5, 1),
1357 /* invalidate D-Cache */
1358 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
1360 /* DCIMVAC - Invalidate data Cache line
1362 * MCR p15, 0, r0, c7, c6, 1
1364 for (uint32_t cacheline
= address
;
1365 cacheline
< address
+ size
* count
;
1367 retval
= dpm
->instr_write_data_r0(dpm
,
1368 ARMV4_5_MCR(15, 0, 0, 7, 6, 1),
1373 /* (void) */ dpm
->finish(dpm
);
1379 static int cortex_a8_bulk_write_memory(struct target
*target
, uint32_t address
,
1380 uint32_t count
, uint8_t *buffer
)
1382 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1386 static int cortex_a8_dcc_read(struct adiv5_dap
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1391 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1392 *ctrl
= (uint8_t)dcrdr
;
1393 *value
= (uint8_t)(dcrdr
>> 8);
1395 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1397 /* write ack back to software dcc register
1398 * signify we have read data */
1399 if (dcrdr
& (1 << 0))
1402 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1409 static int cortex_a8_handle_target_request(void *priv
)
1411 struct target
*target
= priv
;
1412 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1413 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
1415 if (!target_was_examined(target
))
1417 if (!target
->dbg_msg_enabled
)
1420 if (target
->state
== TARGET_RUNNING
)
1425 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1427 /* check if we have data */
1428 if (ctrl
& (1 << 0))
1432 /* we assume target is quick enough */
1434 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1435 request
|= (data
<< 8);
1436 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1437 request
|= (data
<< 16);
1438 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1439 request
|= (data
<< 24);
1440 target_request(target
, request
);
1448 * Cortex-A8 target information and configuration
1451 static int cortex_a8_examine_first(struct target
*target
)
1453 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1454 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1455 struct adiv5_dap
*swjdp
= &armv7a
->dap
;
1457 int retval
= ERROR_OK
;
1458 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1460 /* stop assuming this is an OMAP! */
1461 LOG_DEBUG("TODO - autoconfigure");
1463 /* Here we shall insert a proper ROM Table scan */
1464 armv7a
->debug_base
= OMAP3530_DEBUG_BASE
;
1466 /* We do one extra read to ensure DAP is configured,
1467 * we call ahbap_debugport_init(swjdp) instead
1469 ahbap_debugport_init(swjdp
);
1470 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
1471 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1472 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1474 LOG_DEBUG("Examine %s failed", "CPUID");
1478 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1479 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1481 LOG_DEBUG("Examine %s failed", "CTYPR");
1485 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1486 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1488 LOG_DEBUG("Examine %s failed", "TTYPR");
1492 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1493 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1495 LOG_DEBUG("Examine %s failed", "DIDR");
1499 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1500 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1501 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1502 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1504 armv7a
->armv4_5_common
.core_type
= ARM_MODE_MON
;
1505 cortex_a8_dpm_setup(cortex_a8
, didr
);
1507 /* Setup Breakpoint Register Pairs */
1508 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1509 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1510 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1511 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(struct cortex_a8_brp
));
1512 // cortex_a8->brb_enabled = ????;
1513 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1515 cortex_a8
->brp_list
[i
].used
= 0;
1516 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1517 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1519 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1520 cortex_a8
->brp_list
[i
].value
= 0;
1521 cortex_a8
->brp_list
[i
].control
= 0;
1522 cortex_a8
->brp_list
[i
].BRPn
= i
;
1525 LOG_DEBUG("Configured %i hw breakpoints", cortex_a8
->brp_num
);
1527 target_set_examined(target
);
1531 static int cortex_a8_examine(struct target
*target
)
1533 int retval
= ERROR_OK
;
1535 /* don't re-probe hardware after each reset */
1536 if (!target_was_examined(target
))
1537 retval
= cortex_a8_examine_first(target
);
1539 /* Configure core debug access */
1540 if (retval
== ERROR_OK
)
1541 retval
= cortex_a8_init_debug_access(target
);
1547 * Cortex-A8 target creation and initialization
1550 static int cortex_a8_init_target(struct command_context
*cmd_ctx
,
1551 struct target
*target
)
1553 /* examine_first() does a bunch of this */
1557 static int cortex_a8_init_arch_info(struct target
*target
,
1558 struct cortex_a8_common
*cortex_a8
, struct jtag_tap
*tap
)
1560 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1561 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
1562 struct adiv5_dap
*dap
= &armv7a
->dap
;
1564 armv7a
->armv4_5_common
.dap
= dap
;
1566 /* Setup struct cortex_a8_common */
1567 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1568 armv4_5
->arch_info
= armv7a
;
1570 /* prepare JTAG information for the new target */
1571 cortex_a8
->jtag_info
.tap
= tap
;
1572 cortex_a8
->jtag_info
.scann_size
= 4;
1574 /* Leave (only) generic DAP stuff for debugport_init() */
1575 dap
->jtag_info
= &cortex_a8
->jtag_info
;
1576 dap
->memaccess_tck
= 80;
1578 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1579 dap
->tar_autoincr_block
= (1 << 10);
1581 cortex_a8
->fast_reg_read
= 0;
1583 /* register arch-specific functions */
1584 armv7a
->examine_debug_reason
= NULL
;
1586 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1588 armv7a
->pre_restore_context
= NULL
;
1589 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1590 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1591 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_memory
;
1592 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_memory
;
1593 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1594 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1595 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1596 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1599 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1601 /* REVISIT v7a setup should be in a v7a-specific routine */
1602 arm_init_arch_info(target
, armv4_5
);
1603 armv7a
->common_magic
= ARMV7_COMMON_MAGIC
;
1605 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1610 static int cortex_a8_target_create(struct target
*target
, Jim_Interp
*interp
)
1612 struct cortex_a8_common
*cortex_a8
= calloc(1, sizeof(struct cortex_a8_common
));
1614 cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1619 COMMAND_HANDLER(cortex_a8_handle_cache_info_command
)
1621 struct target
*target
= get_current_target(CMD_CTX
);
1622 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1624 return armv4_5_handle_cache_info_command(CMD_CTX
,
1625 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1629 COMMAND_HANDLER(cortex_a8_handle_dbginit_command
)
1631 struct target
*target
= get_current_target(CMD_CTX
);
1633 cortex_a8_init_debug_access(target
);
1638 static const struct command_registration cortex_a8_exec_command_handlers
[] = {
1640 .name
= "cache_info",
1641 .handler
= cortex_a8_handle_cache_info_command
,
1642 .mode
= COMMAND_EXEC
,
1643 .help
= "display information about target caches",
1647 .handler
= cortex_a8_handle_dbginit_command
,
1648 .mode
= COMMAND_EXEC
,
1649 .help
= "Initialize core debug",
1651 COMMAND_REGISTRATION_DONE
1653 static const struct command_registration cortex_a8_command_handlers
[] = {
1655 .chain
= arm_command_handlers
,
1658 .chain
= armv7a_command_handlers
,
1661 .name
= "cortex_a8",
1662 .mode
= COMMAND_ANY
,
1663 .help
= "Cortex-A8 command group",
1664 .chain
= cortex_a8_exec_command_handlers
,
1666 COMMAND_REGISTRATION_DONE
1669 struct target_type cortexa8_target
= {
1670 .name
= "cortex_a8",
1672 .poll
= cortex_a8_poll
,
1673 .arch_state
= armv7a_arch_state
,
1675 .target_request_data
= NULL
,
1677 .halt
= cortex_a8_halt
,
1678 .resume
= cortex_a8_resume
,
1679 .step
= cortex_a8_step
,
1681 .assert_reset
= cortex_a8_assert_reset
,
1682 .deassert_reset
= cortex_a8_deassert_reset
,
1683 .soft_reset_halt
= NULL
,
1685 /* REVISIT allow exporting VFP3 registers ... */
1686 .get_gdb_reg_list
= arm_get_gdb_reg_list
,
1688 .read_memory
= cortex_a8_read_memory
,
1689 .write_memory
= cortex_a8_write_memory
,
1690 .bulk_write_memory
= cortex_a8_bulk_write_memory
,
1692 .checksum_memory
= arm_checksum_memory
,
1693 .blank_check_memory
= arm_blank_check_memory
,
1695 .run_algorithm
= armv4_5_run_algorithm
,
1697 .add_breakpoint
= cortex_a8_add_breakpoint
,
1698 .remove_breakpoint
= cortex_a8_remove_breakpoint
,
1699 .add_watchpoint
= NULL
,
1700 .remove_watchpoint
= NULL
,
1702 .commands
= cortex_a8_command_handlers
,
1703 .target_create
= cortex_a8_target_create
,
1704 .init_target
= cortex_a8_init_target
,
1705 .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)