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.
58 #define swjdp_memoryap 0
59 #define swjdp_debugap 1
60 #define OMAP3530_DEBUG_BASE 0x54011000
63 * Cortex-A8 Basic debug access, very low level assumes state is saved
65 static int cortex_a8_init_debug_access(struct target
*target
)
67 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
68 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
75 /* Unlocking the debug registers for modification */
76 /* The debugport might be uninitialised so try twice */
77 retval
= mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
78 if (retval
!= ERROR_OK
)
79 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
80 /* Clear Sticky Power Down status Bit in PRSR to enable access to
81 the registers in the Core Power Domain */
82 retval
= mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_PRSR
, &dummy
);
83 /* Enabling of instruction execution in debug mode is done in debug_entry code */
85 /* Resync breakpoint registers */
87 /* Since this is likley called from init or reset, update targtet state information*/
88 cortex_a8_poll(target
);
93 /* To reduce needless round-trips, pass in a pointer to the current
94 * DSCR value. Initialize it to zero if you just need to know the
95 * value on return from this function; or DSCR_INSTR_COMP if you
96 * happen to know that no instruction is pending.
98 static int cortex_a8_exec_opcode(struct target
*target
,
99 uint32_t opcode
, uint32_t *dscr_p
)
103 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
104 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
106 dscr
= dscr_p
? *dscr_p
: 0;
108 LOG_DEBUG("exec opcode 0x%08" PRIx32
, opcode
);
110 /* Wait for InstrCompl bit to be set */
111 while ((dscr
& DSCR_INSTR_COMP
) == 0)
113 retval
= mem_ap_read_atomic_u32(swjdp
,
114 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
115 if (retval
!= ERROR_OK
)
117 LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32
, opcode
);
122 mem_ap_write_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_ITR
, opcode
);
126 retval
= mem_ap_read_atomic_u32(swjdp
,
127 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
128 if (retval
!= ERROR_OK
)
130 LOG_ERROR("Could not read DSCR register");
134 while ((dscr
& DSCR_INSTR_COMP
) == 0); /* Wait for InstrCompl bit to be set */
142 /**************************************************************************
143 Read core register with very few exec_opcode, fast but needs work_area.
144 This can cause problems with MMU active.
145 **************************************************************************/
146 static int cortex_a8_read_regs_through_mem(struct target
*target
, uint32_t address
,
149 int retval
= ERROR_OK
;
150 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
151 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
153 cortex_a8_dap_read_coreregister_u32(target
, regfile
, 0);
154 cortex_a8_dap_write_coreregister_u32(target
, address
, 0);
155 cortex_a8_exec_opcode(target
, ARMV4_5_STMIA(0, 0xFFFE, 0, 0), NULL
);
156 dap_ap_select(swjdp
, swjdp_memoryap
);
157 mem_ap_read_buf_u32(swjdp
, (uint8_t *)(®file
[1]), 4*15, address
);
158 dap_ap_select(swjdp
, swjdp_debugap
);
163 static int cortex_a8_dap_read_coreregister_u32(struct target
*target
,
164 uint32_t *value
, int regnum
)
166 int retval
= ERROR_OK
;
167 uint8_t reg
= regnum
&0xFF;
169 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
170 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
177 /* Rn to DCCTX, "MCR p14, 0, Rn, c0, c5, 0" 0xEE00nE15 */
178 cortex_a8_exec_opcode(target
,
179 ARMV4_5_MCR(14, 0, reg
, 0, 5, 0),
184 /* "MOV r0, r15"; then move r0 to DCCTX */
185 cortex_a8_exec_opcode(target
, 0xE1A0000F, &dscr
);
186 cortex_a8_exec_opcode(target
,
187 ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
192 /* "MRS r0, CPSR" or "MRS r0, SPSR"
193 * then move r0 to DCCTX
195 cortex_a8_exec_opcode(target
, ARMV4_5_MRS(0, reg
& 1), &dscr
);
196 cortex_a8_exec_opcode(target
,
197 ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
201 /* Wait for DTRRXfull then read DTRRTX */
202 while ((dscr
& DSCR_DTR_TX_FULL
) == 0)
204 retval
= mem_ap_read_atomic_u32(swjdp
,
205 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
208 retval
= mem_ap_read_atomic_u32(swjdp
,
209 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
210 LOG_DEBUG("read DCC 0x%08" PRIx32
, *value
);
215 static int cortex_a8_dap_write_coreregister_u32(struct target
*target
,
216 uint32_t value
, int regnum
)
218 int retval
= ERROR_OK
;
219 uint8_t Rd
= regnum
&0xFF;
221 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
222 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
224 LOG_DEBUG("register %i, value 0x%08" PRIx32
, regnum
, value
);
226 /* Check that DCCRX is not full */
227 retval
= mem_ap_read_atomic_u32(swjdp
,
228 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
229 if (dscr
& DSCR_DTR_RX_FULL
)
231 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
232 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
233 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
240 /* Write DTRRX ... sets DSCR.DTRRXfull but exec_opcode() won't care */
241 LOG_DEBUG("write DCC 0x%08" PRIx32
, value
);
242 retval
= mem_ap_write_u32(swjdp
,
243 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
247 /* DCCRX to Rn, "MCR p14, 0, Rn, c0, c5, 0", 0xEE00nE15 */
248 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, Rd
, 0, 5, 0),
253 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15
256 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
258 cortex_a8_exec_opcode(target
, 0xE1A0F000, &dscr
);
262 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15
263 * then "MSR CPSR_cxsf, r0" or "MSR SPSR_cxsf, r0" (all fields)
265 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
267 cortex_a8_exec_opcode(target
, ARMV4_5_MSR_GP(0, 0xF, Rd
& 1),
270 /* "Prefetch flush" after modifying execution status in CPSR */
272 cortex_a8_exec_opcode(target
,
273 ARMV4_5_MCR(15, 0, 0, 7, 5, 4),
280 /* Write to memory mapped registers directly with no cache or mmu handling */
281 static int cortex_a8_dap_write_memap_register_u32(struct target
*target
, uint32_t address
, uint32_t value
)
284 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
285 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
287 retval
= mem_ap_write_atomic_u32(swjdp
, address
, value
);
293 * Cortex-A8 implementation of Debug Programmer's Model
295 * NOTE the invariant: these routines return with DSCR_INSTR_COMP set,
296 * so there's no need to poll for it before executing an instruction.
298 * NOTE that in several of these cases the "stall" mode might be useful.
299 * It'd let us queue a few operations together... prepare/finish might
300 * be the places to enable/disable that mode.
303 static inline struct cortex_a8_common
*dpm_to_a8(struct arm_dpm
*dpm
)
305 return container_of(dpm
, struct cortex_a8_common
, armv7a_common
.dpm
);
308 static int cortex_a8_write_dcc(struct cortex_a8_common
*a8
, uint32_t data
)
310 LOG_DEBUG("write DCC 0x%08" PRIx32
, data
);
311 return mem_ap_write_u32(&a8
->armv7a_common
.swjdp_info
,
312 a8
->armv7a_common
.debug_base
+ CPUDBG_DTRRX
, data
);
315 static int cortex_a8_read_dcc(struct cortex_a8_common
*a8
, uint32_t *data
,
318 struct swjdp_common
*swjdp
= &a8
->armv7a_common
.swjdp_info
;
319 uint32_t dscr
= DSCR_INSTR_COMP
;
325 /* Wait for DTRRXfull */
326 while ((dscr
& DSCR_DTR_TX_FULL
) == 0) {
327 retval
= mem_ap_read_atomic_u32(swjdp
,
328 a8
->armv7a_common
.debug_base
+ CPUDBG_DSCR
,
332 retval
= mem_ap_read_atomic_u32(swjdp
,
333 a8
->armv7a_common
.debug_base
+ CPUDBG_DTRTX
, data
);
334 //LOG_DEBUG("read DCC 0x%08" PRIx32, *data);
342 static int cortex_a8_dpm_prepare(struct arm_dpm
*dpm
)
344 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
345 struct swjdp_common
*swjdp
= &a8
->armv7a_common
.swjdp_info
;
349 /* set up invariant: INSTR_COMP is set after ever DPM operation */
351 retval
= mem_ap_read_atomic_u32(swjdp
,
352 a8
->armv7a_common
.debug_base
+ CPUDBG_DSCR
,
354 } while ((dscr
& DSCR_INSTR_COMP
) == 0);
356 /* this "should never happen" ... */
357 if (dscr
& DSCR_DTR_RX_FULL
) {
358 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
360 retval
= cortex_a8_exec_opcode(
361 a8
->armv7a_common
.armv4_5_common
.target
,
362 ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
369 static int cortex_a8_dpm_finish(struct arm_dpm
*dpm
)
371 /* REVISIT what could be done here? */
375 static int cortex_a8_instr_write_data_dcc(struct arm_dpm
*dpm
,
376 uint32_t opcode
, uint32_t data
)
378 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
380 uint32_t dscr
= DSCR_INSTR_COMP
;
382 retval
= cortex_a8_write_dcc(a8
, data
);
384 return cortex_a8_exec_opcode(
385 a8
->armv7a_common
.armv4_5_common
.target
,
390 static int cortex_a8_instr_write_data_r0(struct arm_dpm
*dpm
,
391 uint32_t opcode
, uint32_t data
)
393 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
394 uint32_t dscr
= DSCR_INSTR_COMP
;
397 retval
= cortex_a8_write_dcc(a8
, data
);
399 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15 */
400 retval
= cortex_a8_exec_opcode(
401 a8
->armv7a_common
.armv4_5_common
.target
,
402 ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
405 /* then the opcode, taking data from R0 */
406 retval
= cortex_a8_exec_opcode(
407 a8
->armv7a_common
.armv4_5_common
.target
,
414 static int cortex_a8_instr_cpsr_sync(struct arm_dpm
*dpm
)
416 struct target
*target
= dpm
->arm
->target
;
417 uint32_t dscr
= DSCR_INSTR_COMP
;
419 /* "Prefetch flush" after modifying execution status in CPSR */
420 return cortex_a8_exec_opcode(target
,
421 ARMV4_5_MCR(15, 0, 0, 7, 5, 4),
425 static int cortex_a8_instr_read_data_dcc(struct arm_dpm
*dpm
,
426 uint32_t opcode
, uint32_t *data
)
428 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
430 uint32_t dscr
= DSCR_INSTR_COMP
;
432 /* the opcode, writing data to DCC */
433 retval
= cortex_a8_exec_opcode(
434 a8
->armv7a_common
.armv4_5_common
.target
,
438 return cortex_a8_read_dcc(a8
, data
, &dscr
);
442 static int cortex_a8_instr_read_data_r0(struct arm_dpm
*dpm
,
443 uint32_t opcode
, uint32_t *data
)
445 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
446 uint32_t dscr
= DSCR_INSTR_COMP
;
449 /* the opcode, writing data to R0 */
450 retval
= cortex_a8_exec_opcode(
451 a8
->armv7a_common
.armv4_5_common
.target
,
455 /* write R0 to DCC */
456 retval
= cortex_a8_exec_opcode(
457 a8
->armv7a_common
.armv4_5_common
.target
,
458 ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
461 return cortex_a8_read_dcc(a8
, data
, &dscr
);
464 static int cortex_a8_bpwp_enable(struct arm_dpm
*dpm
, unsigned index
,
465 uint32_t addr
, uint32_t control
)
467 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
468 uint32_t vr
= a8
->armv7a_common
.debug_base
;
469 uint32_t cr
= a8
->armv7a_common
.debug_base
;
473 case 0 ... 15: /* breakpoints */
474 vr
+= CPUDBG_BVR_BASE
;
475 cr
+= CPUDBG_BCR_BASE
;
477 case 16 ... 31: /* watchpoints */
478 vr
+= CPUDBG_WVR_BASE
;
479 cr
+= CPUDBG_WCR_BASE
;
488 LOG_DEBUG("A8: bpwp enable, vr %08x cr %08x",
489 (unsigned) vr
, (unsigned) cr
);
491 retval
= cortex_a8_dap_write_memap_register_u32(dpm
->arm
->target
,
493 if (retval
!= ERROR_OK
)
495 retval
= cortex_a8_dap_write_memap_register_u32(dpm
->arm
->target
,
500 static int cortex_a8_bpwp_disable(struct arm_dpm
*dpm
, unsigned index
)
502 struct cortex_a8_common
*a8
= dpm_to_a8(dpm
);
507 cr
= a8
->armv7a_common
.debug_base
+ CPUDBG_BCR_BASE
;
510 cr
= a8
->armv7a_common
.debug_base
+ CPUDBG_WCR_BASE
;
518 LOG_DEBUG("A8: bpwp disable, cr %08x", (unsigned) cr
);
520 /* clear control register */
521 return cortex_a8_dap_write_memap_register_u32(dpm
->arm
->target
, cr
, 0);
524 static int cortex_a8_dpm_setup(struct cortex_a8_common
*a8
, uint32_t didr
)
526 struct arm_dpm
*dpm
= &a8
->armv7a_common
.dpm
;
529 dpm
->arm
= &a8
->armv7a_common
.armv4_5_common
;
532 dpm
->prepare
= cortex_a8_dpm_prepare
;
533 dpm
->finish
= cortex_a8_dpm_finish
;
535 dpm
->instr_write_data_dcc
= cortex_a8_instr_write_data_dcc
;
536 dpm
->instr_write_data_r0
= cortex_a8_instr_write_data_r0
;
537 dpm
->instr_cpsr_sync
= cortex_a8_instr_cpsr_sync
;
539 dpm
->instr_read_data_dcc
= cortex_a8_instr_read_data_dcc
;
540 dpm
->instr_read_data_r0
= cortex_a8_instr_read_data_r0
;
542 dpm
->bpwp_enable
= cortex_a8_bpwp_enable
;
543 dpm
->bpwp_disable
= cortex_a8_bpwp_disable
;
545 retval
= arm_dpm_setup(dpm
);
546 if (retval
== ERROR_OK
)
547 retval
= arm_dpm_initialize(dpm
);
554 * Cortex-A8 Run control
557 static int cortex_a8_poll(struct target
*target
)
559 int retval
= ERROR_OK
;
561 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
562 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
563 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
564 enum target_state prev_target_state
= target
->state
;
565 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
567 dap_ap_select(swjdp
, swjdp_debugap
);
568 retval
= mem_ap_read_atomic_u32(swjdp
,
569 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
570 if (retval
!= ERROR_OK
)
572 dap_ap_select(swjdp
, saved_apsel
);
575 cortex_a8
->cpudbg_dscr
= dscr
;
577 if ((dscr
& 0x3) == 0x3)
579 if (prev_target_state
!= TARGET_HALTED
)
581 /* We have a halting debug event */
582 LOG_DEBUG("Target halted");
583 target
->state
= TARGET_HALTED
;
584 if ((prev_target_state
== TARGET_RUNNING
)
585 || (prev_target_state
== TARGET_RESET
))
587 retval
= cortex_a8_debug_entry(target
);
588 if (retval
!= ERROR_OK
)
591 target_call_event_callbacks(target
,
592 TARGET_EVENT_HALTED
);
594 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
598 retval
= cortex_a8_debug_entry(target
);
599 if (retval
!= ERROR_OK
)
602 target_call_event_callbacks(target
,
603 TARGET_EVENT_DEBUG_HALTED
);
607 else if ((dscr
& 0x3) == 0x2)
609 target
->state
= TARGET_RUNNING
;
613 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32
, dscr
);
614 target
->state
= TARGET_UNKNOWN
;
617 dap_ap_select(swjdp
, saved_apsel
);
622 static int cortex_a8_halt(struct target
*target
)
624 int retval
= ERROR_OK
;
626 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
627 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
628 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
629 dap_ap_select(swjdp
, swjdp_debugap
);
632 * Tell the core to be halted by writing DRCR with 0x1
633 * and then wait for the core to be halted.
635 retval
= mem_ap_write_atomic_u32(swjdp
,
636 armv7a
->debug_base
+ CPUDBG_DRCR
, 0x1);
639 * enter halting debug mode
641 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
642 retval
= mem_ap_write_atomic_u32(swjdp
,
643 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
| DSCR_HALT_DBG_MODE
);
645 if (retval
!= ERROR_OK
)
649 mem_ap_read_atomic_u32(swjdp
,
650 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
651 } while ((dscr
& DSCR_CORE_HALTED
) == 0);
653 target
->debug_reason
= DBG_REASON_DBGRQ
;
656 dap_ap_select(swjdp
, saved_apsel
);
660 static int cortex_a8_resume(struct target
*target
, int current
,
661 uint32_t address
, int handle_breakpoints
, int debug_execution
)
663 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
664 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
665 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
667 // struct breakpoint *breakpoint = NULL;
668 uint32_t resume_pc
, dscr
;
670 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
671 dap_ap_select(swjdp
, swjdp_debugap
);
673 if (!debug_execution
)
674 target_free_all_working_areas(target
);
679 /* Disable interrupts */
680 /* We disable interrupts in the PRIMASK register instead of
681 * masking with C_MASKINTS,
682 * This is probably the same issue as Cortex-M3 Errata 377493:
683 * C_MASKINTS in parallel with disabled interrupts can cause
684 * local faults to not be taken. */
685 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
686 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
687 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
689 /* Make sure we are in Thumb mode */
690 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
691 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
692 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
693 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
697 /* current = 1: continue on current pc, otherwise continue at <address> */
698 resume_pc
= buf_get_u32(armv4_5
->pc
->value
, 0, 32);
702 /* Make sure that the Armv7 gdb thumb fixups does not
703 * kill the return address
705 switch (armv4_5
->core_state
)
708 resume_pc
&= 0xFFFFFFFC;
710 case ARM_STATE_THUMB
:
711 case ARM_STATE_THUMB_EE
:
712 /* When the return address is loaded into PC
713 * bit 0 must be 1 to stay in Thumb state
717 case ARM_STATE_JAZELLE
:
718 LOG_ERROR("How do I resume into Jazelle state??");
721 LOG_DEBUG("resume pc = 0x%08" PRIx32
, resume_pc
);
722 buf_set_u32(armv4_5
->pc
->value
, 0, 32, resume_pc
);
723 armv4_5
->pc
->dirty
= 1;
724 armv4_5
->pc
->valid
= 1;
726 cortex_a8_restore_context(target
, handle_breakpoints
);
729 /* the front-end may request us not to handle breakpoints */
730 if (handle_breakpoints
)
732 /* Single step past breakpoint at current address */
733 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
735 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
736 cortex_m3_unset_breakpoint(target
, breakpoint
);
737 cortex_m3_single_step_core(target
);
738 cortex_m3_set_breakpoint(target
, breakpoint
);
743 /* Restart core and wait for it to be started
744 * NOTE: this clears DSCR_ITR_EN and other bits.
746 * REVISIT: for single stepping, we probably want to
747 * disable IRQs by default, with optional override...
749 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DRCR
, 0x2);
752 mem_ap_read_atomic_u32(swjdp
,
753 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
754 } while ((dscr
& DSCR_CORE_RESTARTED
) == 0);
756 target
->debug_reason
= DBG_REASON_NOTHALTED
;
757 target
->state
= TARGET_RUNNING
;
759 /* registers are now invalid */
760 register_cache_invalidate(armv4_5
->core_cache
);
762 if (!debug_execution
)
764 target
->state
= TARGET_RUNNING
;
765 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
766 LOG_DEBUG("target resumed at 0x%" PRIx32
, resume_pc
);
770 target
->state
= TARGET_DEBUG_RUNNING
;
771 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
772 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, resume_pc
);
775 dap_ap_select(swjdp
, saved_apsel
);
780 static int cortex_a8_debug_entry(struct target
*target
)
783 uint32_t regfile
[16], cpsr
, dscr
;
784 int retval
= ERROR_OK
;
785 struct working_area
*regfile_working_area
= NULL
;
786 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
787 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
788 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
789 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
792 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
794 /* REVISIT surely we should not re-read DSCR !! */
795 mem_ap_read_atomic_u32(swjdp
,
796 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
798 /* REVISIT see A8 TRM 12.11.4 steps 2..3 -- make sure that any
799 * imprecise data aborts get discarded by issuing a Data
800 * Synchronization Barrier: ARMV4_5_MCR(15, 0, 0, 7, 10, 4).
803 /* Enable the ITR execution once we are in debug mode */
805 retval
= mem_ap_write_atomic_u32(swjdp
,
806 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
);
808 /* Examine debug reason */
809 arm_dpm_report_dscr(&armv7a
->dpm
, cortex_a8
->cpudbg_dscr
);
811 /* save address of instruction that triggered the watchpoint? */
812 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
) {
815 retval
= mem_ap_read_atomic_u32(swjdp
,
816 armv7a
->debug_base
+ CPUDBG_WFAR
,
818 arm_dpm_report_wfar(&armv7a
->dpm
, wfar
);
821 /* REVISIT fast_reg_read is never set ... */
823 /* Examine target state and mode */
824 if (cortex_a8
->fast_reg_read
)
825 target_alloc_working_area(target
, 64, ®file_working_area
);
827 /* First load register acessible through core debug port*/
828 if (!regfile_working_area
)
830 retval
= arm_dpm_read_current_registers(&armv7a
->dpm
);
834 dap_ap_select(swjdp
, swjdp_memoryap
);
835 cortex_a8_read_regs_through_mem(target
,
836 regfile_working_area
->address
, regfile
);
837 dap_ap_select(swjdp
, swjdp_memoryap
);
838 target_free_working_area(target
, regfile_working_area
);
840 /* read Current PSR */
841 cortex_a8_dap_read_coreregister_u32(target
, &cpsr
, 16);
842 dap_ap_select(swjdp
, swjdp_debugap
);
843 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
845 arm_set_cpsr(armv4_5
, cpsr
);
848 for (i
= 0; i
<= ARM_PC
; i
++)
850 reg
= arm_reg_current(armv4_5
, i
);
852 buf_set_u32(reg
->value
, 0, 32, regfile
[i
]);
857 /* Fixup PC Resume Address */
860 // T bit set for Thumb or ThumbEE state
861 regfile
[ARM_PC
] -= 4;
866 regfile
[ARM_PC
] -= 8;
870 buf_set_u32(reg
->value
, 0, 32, regfile
[ARM_PC
]);
871 reg
->dirty
= reg
->valid
;
875 /* TODO, Move this */
876 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
877 cortex_a8_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
878 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
880 cortex_a8_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
881 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
883 cortex_a8_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
884 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
887 /* Are we in an exception handler */
888 // armv4_5->exception_number = 0;
889 if (armv7a
->post_debug_entry
)
890 armv7a
->post_debug_entry(target
);
895 static void cortex_a8_post_debug_entry(struct target
*target
)
897 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
898 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
901 /* MRC p15,0,<Rt>,c1,c0,0 ; Read CP15 System Control Register */
902 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
905 &cortex_a8
->cp15_control_reg
);
906 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
908 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
910 uint32_t cache_type_reg
;
912 /* MRC p15,0,<Rt>,c0,c0,1 ; Read CP15 Cache Type Register */
913 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
917 LOG_DEBUG("cp15 cache type: %8.8x", (unsigned) cache_type_reg
);
919 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
920 armv4_5_identify_cache(cache_type_reg
,
921 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
924 armv7a
->armv4_5_mmu
.mmu_enabled
=
925 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
926 armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
=
927 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
928 armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
=
929 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
934 static int cortex_a8_step(struct target
*target
, int current
, uint32_t address
,
935 int handle_breakpoints
)
937 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
938 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
939 struct breakpoint
*breakpoint
= NULL
;
940 struct breakpoint stepbreakpoint
;
945 if (target
->state
!= TARGET_HALTED
)
947 LOG_WARNING("target not halted");
948 return ERROR_TARGET_NOT_HALTED
;
951 /* current = 1: continue on current pc, otherwise continue at <address> */
955 buf_set_u32(r
->value
, 0, 32, address
);
959 address
= buf_get_u32(r
->value
, 0, 32);
962 /* The front-end may request us not to handle breakpoints.
963 * But since Cortex-A8 uses breakpoint for single step,
964 * we MUST handle breakpoints.
966 handle_breakpoints
= 1;
967 if (handle_breakpoints
) {
968 breakpoint
= breakpoint_find(target
, address
);
970 cortex_a8_unset_breakpoint(target
, breakpoint
);
973 /* Setup single step breakpoint */
974 stepbreakpoint
.address
= address
;
975 stepbreakpoint
.length
= (armv4_5
->core_state
== ARM_STATE_THUMB
)
977 stepbreakpoint
.type
= BKPT_HARD
;
978 stepbreakpoint
.set
= 0;
980 /* Break on IVA mismatch */
981 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
983 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
985 cortex_a8_resume(target
, 1, address
, 0, 0);
987 while (target
->state
!= TARGET_HALTED
)
989 cortex_a8_poll(target
);
992 LOG_WARNING("timeout waiting for target halt");
997 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
999 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1002 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
1004 if (target
->state
!= TARGET_HALTED
)
1005 LOG_DEBUG("target stepped");
1010 static int cortex_a8_restore_context(struct target
*target
, bool bpwp
)
1012 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1016 if (armv7a
->pre_restore_context
)
1017 armv7a
->pre_restore_context(target
);
1019 arm_dpm_write_dirty_registers(&armv7a
->dpm
, bpwp
);
1021 if (armv7a
->post_restore_context
)
1022 armv7a
->post_restore_context(target
);
1029 * Cortex-A8 Breakpoint and watchpoint fuctions
1032 /* Setup hardware Breakpoint Register Pair */
1033 static int cortex_a8_set_breakpoint(struct target
*target
,
1034 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1039 uint8_t byte_addr_select
= 0x0F;
1040 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1041 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1042 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1044 if (breakpoint
->set
)
1046 LOG_WARNING("breakpoint already set");
1050 if (breakpoint
->type
== BKPT_HARD
)
1052 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
1054 if (brp_i
>= cortex_a8
->brp_num
)
1056 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1059 breakpoint
->set
= brp_i
+ 1;
1060 if (breakpoint
->length
== 2)
1062 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1064 control
= ((matchmode
& 0x7) << 20)
1065 | (byte_addr_select
<< 5)
1067 brp_list
[brp_i
].used
= 1;
1068 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1069 brp_list
[brp_i
].control
= control
;
1070 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1071 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1072 brp_list
[brp_i
].value
);
1073 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1074 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1075 brp_list
[brp_i
].control
);
1076 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1077 brp_list
[brp_i
].control
,
1078 brp_list
[brp_i
].value
);
1080 else if (breakpoint
->type
== BKPT_SOFT
)
1083 if (breakpoint
->length
== 2)
1085 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1089 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1091 retval
= target
->type
->read_memory(target
,
1092 breakpoint
->address
& 0xFFFFFFFE,
1093 breakpoint
->length
, 1,
1094 breakpoint
->orig_instr
);
1095 if (retval
!= ERROR_OK
)
1097 retval
= target
->type
->write_memory(target
,
1098 breakpoint
->address
& 0xFFFFFFFE,
1099 breakpoint
->length
, 1, code
);
1100 if (retval
!= ERROR_OK
)
1102 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1108 static int cortex_a8_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1111 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1112 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1113 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1115 if (!breakpoint
->set
)
1117 LOG_WARNING("breakpoint not set");
1121 if (breakpoint
->type
== BKPT_HARD
)
1123 int brp_i
= breakpoint
->set
- 1;
1124 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1126 LOG_DEBUG("Invalid BRP number in breakpoint");
1129 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1130 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1131 brp_list
[brp_i
].used
= 0;
1132 brp_list
[brp_i
].value
= 0;
1133 brp_list
[brp_i
].control
= 0;
1134 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1135 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1136 brp_list
[brp_i
].control
);
1137 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1138 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1139 brp_list
[brp_i
].value
);
1143 /* restore original instruction (kept in target endianness) */
1144 if (breakpoint
->length
== 4)
1146 retval
= target
->type
->write_memory(target
,
1147 breakpoint
->address
& 0xFFFFFFFE,
1148 4, 1, breakpoint
->orig_instr
);
1149 if (retval
!= ERROR_OK
)
1154 retval
= target
->type
->write_memory(target
,
1155 breakpoint
->address
& 0xFFFFFFFE,
1156 2, 1, breakpoint
->orig_instr
);
1157 if (retval
!= ERROR_OK
)
1161 breakpoint
->set
= 0;
1166 static int cortex_a8_add_breakpoint(struct target
*target
,
1167 struct breakpoint
*breakpoint
)
1169 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1171 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1173 LOG_INFO("no hardware breakpoint available");
1174 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1177 if (breakpoint
->type
== BKPT_HARD
)
1178 cortex_a8
->brp_num_available
--;
1179 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1184 static int cortex_a8_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1186 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1189 /* It is perfectly possible to remove brakpoints while the taget is running */
1190 if (target
->state
!= TARGET_HALTED
)
1192 LOG_WARNING("target not halted");
1193 return ERROR_TARGET_NOT_HALTED
;
1197 if (breakpoint
->set
)
1199 cortex_a8_unset_breakpoint(target
, breakpoint
);
1200 if (breakpoint
->type
== BKPT_HARD
)
1201 cortex_a8
->brp_num_available
++ ;
1211 * Cortex-A8 Reset fuctions
1214 static int cortex_a8_assert_reset(struct target
*target
)
1216 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1220 /* FIXME when halt is requested, make it work somehow... */
1222 /* Issue some kind of warm reset. */
1223 if (target_has_event_action(target
, TARGET_EVENT_RESET_ASSERT
)) {
1224 target_handle_event(target
, TARGET_EVENT_RESET_ASSERT
);
1225 } else if (jtag_get_reset_config() & RESET_HAS_SRST
) {
1226 /* REVISIT handle "pulls" cases, if there's
1227 * hardware that needs them to work.
1229 jtag_add_reset(0, 1);
1231 LOG_ERROR("%s: how to reset?", target_name(target
));
1235 /* registers are now invalid */
1236 register_cache_invalidate(armv7a
->armv4_5_common
.core_cache
);
1238 target
->state
= TARGET_RESET
;
1243 static int cortex_a8_deassert_reset(struct target
*target
)
1249 /* be certain SRST is off */
1250 jtag_add_reset(0, 0);
1252 retval
= cortex_a8_poll(target
);
1254 if (target
->reset_halt
) {
1255 if (target
->state
!= TARGET_HALTED
) {
1256 LOG_WARNING("%s: ran after reset and before halt ...",
1257 target_name(target
));
1258 if ((retval
= target_halt(target
)) != ERROR_OK
)
1267 * Cortex-A8 Memory access
1269 * This is same Cortex M3 but we must also use the correct
1270 * ap number for every access.
1273 static int cortex_a8_read_memory(struct target
*target
, uint32_t address
,
1274 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1276 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1277 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1278 int retval
= ERROR_INVALID_ARGUMENTS
;
1280 /* cortex_a8 handles unaligned memory access */
1282 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1284 if (count
&& buffer
) {
1287 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1290 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1293 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1301 static int cortex_a8_write_memory(struct target
*target
, uint32_t address
,
1302 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1304 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1305 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1306 int retval
= ERROR_INVALID_ARGUMENTS
;
1308 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1310 if (count
&& buffer
) {
1313 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1316 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1319 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1324 /* REVISIT this op is generic ARMv7-A/R stuff */
1325 if (retval
== ERROR_OK
&& target
->state
== TARGET_HALTED
)
1327 struct arm_dpm
*dpm
= armv7a
->armv4_5_common
.dpm
;
1329 retval
= dpm
->prepare(dpm
);
1330 if (retval
!= ERROR_OK
)
1333 /* The Cache handling will NOT work with MMU active, the
1334 * wrong addresses will be invalidated!
1336 * For both ICache and DCache, walk all cache lines in the
1337 * address range. Cortex-A8 has fixed 64 byte line length.
1339 * REVISIT per ARMv7, these may trigger watchpoints ...
1342 /* invalidate I-Cache */
1343 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
1345 /* ICIMVAU - Invalidate Cache single entry
1347 * MCR p15, 0, r0, c7, c5, 1
1349 for (uint32_t cacheline
= address
;
1350 cacheline
< address
+ size
* count
;
1352 retval
= dpm
->instr_write_data_r0(dpm
,
1353 ARMV4_5_MCR(15, 0, 0, 7, 5, 1),
1358 /* invalidate D-Cache */
1359 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
1361 /* DCIMVAC - Invalidate data Cache line
1363 * MCR p15, 0, r0, c7, c6, 1
1365 for (uint32_t cacheline
= address
;
1366 cacheline
< address
+ size
* count
;
1368 retval
= dpm
->instr_write_data_r0(dpm
,
1369 ARMV4_5_MCR(15, 0, 0, 7, 6, 1),
1374 /* (void) */ dpm
->finish(dpm
);
1380 static int cortex_a8_bulk_write_memory(struct target
*target
, uint32_t address
,
1381 uint32_t count
, uint8_t *buffer
)
1383 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1387 static int cortex_a8_dcc_read(struct swjdp_common
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1392 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1393 *ctrl
= (uint8_t)dcrdr
;
1394 *value
= (uint8_t)(dcrdr
>> 8);
1396 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1398 /* write ack back to software dcc register
1399 * signify we have read data */
1400 if (dcrdr
& (1 << 0))
1403 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1410 static int cortex_a8_handle_target_request(void *priv
)
1412 struct target
*target
= priv
;
1413 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1414 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1416 if (!target_was_examined(target
))
1418 if (!target
->dbg_msg_enabled
)
1421 if (target
->state
== TARGET_RUNNING
)
1426 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1428 /* check if we have data */
1429 if (ctrl
& (1 << 0))
1433 /* we assume target is quick enough */
1435 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1436 request
|= (data
<< 8);
1437 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1438 request
|= (data
<< 16);
1439 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1440 request
|= (data
<< 24);
1441 target_request(target
, request
);
1449 * Cortex-A8 target information and configuration
1452 static int cortex_a8_examine_first(struct target
*target
)
1454 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1455 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1456 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1458 int retval
= ERROR_OK
;
1459 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1461 /* stop assuming this is an OMAP! */
1462 LOG_DEBUG("TODO - autoconfigure");
1464 /* Here we shall insert a proper ROM Table scan */
1465 armv7a
->debug_base
= OMAP3530_DEBUG_BASE
;
1467 /* We do one extra read to ensure DAP is configured,
1468 * we call ahbap_debugport_init(swjdp) instead
1470 ahbap_debugport_init(swjdp
);
1471 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
1472 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1473 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1475 LOG_DEBUG("Examine %s failed", "CPUID");
1479 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1480 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1482 LOG_DEBUG("Examine %s failed", "CTYPR");
1486 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1487 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1489 LOG_DEBUG("Examine %s failed", "TTYPR");
1493 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1494 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1496 LOG_DEBUG("Examine %s failed", "DIDR");
1500 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1501 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1502 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1503 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1505 armv7a
->armv4_5_common
.core_type
= ARM_MODE_MON
;
1506 cortex_a8_dpm_setup(cortex_a8
, didr
);
1508 /* Setup Breakpoint Register Pairs */
1509 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1510 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1511 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1512 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(struct cortex_a8_brp
));
1513 // cortex_a8->brb_enabled = ????;
1514 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1516 cortex_a8
->brp_list
[i
].used
= 0;
1517 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1518 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1520 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1521 cortex_a8
->brp_list
[i
].value
= 0;
1522 cortex_a8
->brp_list
[i
].control
= 0;
1523 cortex_a8
->brp_list
[i
].BRPn
= i
;
1526 LOG_DEBUG("Configured %i hw breakpoints", cortex_a8
->brp_num
);
1528 target_set_examined(target
);
1532 static int cortex_a8_examine(struct target
*target
)
1534 int retval
= ERROR_OK
;
1536 /* don't re-probe hardware after each reset */
1537 if (!target_was_examined(target
))
1538 retval
= cortex_a8_examine_first(target
);
1540 /* Configure core debug access */
1541 if (retval
== ERROR_OK
)
1542 retval
= cortex_a8_init_debug_access(target
);
1548 * Cortex-A8 target creation and initialization
1551 static int cortex_a8_init_target(struct command_context
*cmd_ctx
,
1552 struct target
*target
)
1554 /* examine_first() does a bunch of this */
1558 static int cortex_a8_init_arch_info(struct target
*target
,
1559 struct cortex_a8_common
*cortex_a8
, struct jtag_tap
*tap
)
1561 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1562 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
1563 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1565 /* Setup struct cortex_a8_common */
1566 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1567 armv4_5
->arch_info
= armv7a
;
1569 /* prepare JTAG information for the new target */
1570 cortex_a8
->jtag_info
.tap
= tap
;
1571 cortex_a8
->jtag_info
.scann_size
= 4;
1573 swjdp
->dp_select_value
= -1;
1574 swjdp
->ap_csw_value
= -1;
1575 swjdp
->ap_tar_value
= -1;
1576 swjdp
->jtag_info
= &cortex_a8
->jtag_info
;
1577 swjdp
->memaccess_tck
= 80;
1579 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1580 swjdp
->tar_autoincr_block
= (1 << 10);
1582 cortex_a8
->fast_reg_read
= 0;
1584 /* register arch-specific functions */
1585 armv7a
->examine_debug_reason
= NULL
;
1587 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1589 armv7a
->pre_restore_context
= NULL
;
1590 armv7a
->post_restore_context
= NULL
;
1591 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1592 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1593 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_memory
;
1594 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_memory
;
1595 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1596 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1597 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1598 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1601 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1603 /* REVISIT v7a setup should be in a v7a-specific routine */
1604 arm_init_arch_info(target
, armv4_5
);
1605 armv7a
->common_magic
= ARMV7_COMMON_MAGIC
;
1607 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1612 static int cortex_a8_target_create(struct target
*target
, Jim_Interp
*interp
)
1614 struct cortex_a8_common
*cortex_a8
= calloc(1, sizeof(struct cortex_a8_common
));
1616 cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1621 COMMAND_HANDLER(cortex_a8_handle_cache_info_command
)
1623 struct target
*target
= get_current_target(CMD_CTX
);
1624 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1626 return armv4_5_handle_cache_info_command(CMD_CTX
,
1627 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1631 COMMAND_HANDLER(cortex_a8_handle_dbginit_command
)
1633 struct target
*target
= get_current_target(CMD_CTX
);
1635 cortex_a8_init_debug_access(target
);
1640 static const struct command_registration cortex_a8_exec_command_handlers
[] = {
1642 .name
= "cache_info",
1643 .handler
= cortex_a8_handle_cache_info_command
,
1644 .mode
= COMMAND_EXEC
,
1645 .help
= "display information about target caches",
1649 .handler
= cortex_a8_handle_dbginit_command
,
1650 .mode
= COMMAND_EXEC
,
1651 .help
= "Initialize core debug",
1653 COMMAND_REGISTRATION_DONE
1655 static const struct command_registration cortex_a8_command_handlers
[] = {
1657 .chain
= arm_command_handlers
,
1660 .chain
= armv7a_command_handlers
,
1663 .name
= "cortex_a8",
1664 .mode
= COMMAND_ANY
,
1665 .help
= "Cortex-A8 command group",
1666 .chain
= cortex_a8_exec_command_handlers
,
1668 COMMAND_REGISTRATION_DONE
1671 struct target_type cortexa8_target
= {
1672 .name
= "cortex_a8",
1674 .poll
= cortex_a8_poll
,
1675 .arch_state
= armv7a_arch_state
,
1677 .target_request_data
= NULL
,
1679 .halt
= cortex_a8_halt
,
1680 .resume
= cortex_a8_resume
,
1681 .step
= cortex_a8_step
,
1683 .assert_reset
= cortex_a8_assert_reset
,
1684 .deassert_reset
= cortex_a8_deassert_reset
,
1685 .soft_reset_halt
= NULL
,
1687 /* REVISIT allow exporting VFP3 registers ... */
1688 .get_gdb_reg_list
= arm_get_gdb_reg_list
,
1690 .read_memory
= cortex_a8_read_memory
,
1691 .write_memory
= cortex_a8_write_memory
,
1692 .bulk_write_memory
= cortex_a8_bulk_write_memory
,
1694 .checksum_memory
= arm_checksum_memory
,
1695 .blank_check_memory
= arm_blank_check_memory
,
1697 .run_algorithm
= armv4_5_run_algorithm
,
1699 .add_breakpoint
= cortex_a8_add_breakpoint
,
1700 .remove_breakpoint
= cortex_a8_remove_breakpoint
,
1701 .add_watchpoint
= NULL
,
1702 .remove_watchpoint
= NULL
,
1704 .commands
= cortex_a8_command_handlers
,
1705 .target_create
= cortex_a8_target_create
,
1706 .init_target
= cortex_a8_init_target
,
1707 .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)