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(
699 armv4_5
->core_cache
->reg_list
[15].value
,
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
->core_cache
->reg_list
[15].value
,
726 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
727 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
729 cortex_a8_restore_context(target
, handle_breakpoints
);
732 /* the front-end may request us not to handle breakpoints */
733 if (handle_breakpoints
)
735 /* Single step past breakpoint at current address */
736 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
738 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
739 cortex_m3_unset_breakpoint(target
, breakpoint
);
740 cortex_m3_single_step_core(target
);
741 cortex_m3_set_breakpoint(target
, breakpoint
);
746 /* Restart core and wait for it to be started
747 * NOTE: this clears DSCR_ITR_EN and other bits.
749 * REVISIT: for single stepping, we probably want to
750 * disable IRQs by default, with optional override...
752 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DRCR
, 0x2);
755 mem_ap_read_atomic_u32(swjdp
,
756 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
757 } while ((dscr
& DSCR_CORE_RESTARTED
) == 0);
759 target
->debug_reason
= DBG_REASON_NOTHALTED
;
760 target
->state
= TARGET_RUNNING
;
762 /* registers are now invalid */
763 register_cache_invalidate(armv4_5
->core_cache
);
765 if (!debug_execution
)
767 target
->state
= TARGET_RUNNING
;
768 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
769 LOG_DEBUG("target resumed at 0x%" PRIx32
, resume_pc
);
773 target
->state
= TARGET_DEBUG_RUNNING
;
774 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
775 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, resume_pc
);
778 dap_ap_select(swjdp
, saved_apsel
);
783 static int cortex_a8_debug_entry(struct target
*target
)
786 uint32_t regfile
[16], cpsr
, dscr
;
787 int retval
= ERROR_OK
;
788 struct working_area
*regfile_working_area
= NULL
;
789 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
790 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
791 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
792 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
795 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
797 /* REVISIT surely we should not re-read DSCR !! */
798 mem_ap_read_atomic_u32(swjdp
,
799 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
801 /* REVISIT see A8 TRM 12.11.4 steps 2..3 -- make sure that any
802 * imprecise data aborts get discarded by issuing a Data
803 * Synchronization Barrier: ARMV4_5_MCR(15, 0, 0, 7, 10, 4).
806 /* Enable the ITR execution once we are in debug mode */
808 retval
= mem_ap_write_atomic_u32(swjdp
,
809 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
);
811 /* Examine debug reason */
812 arm_dpm_report_dscr(&armv7a
->dpm
, cortex_a8
->cpudbg_dscr
);
814 /* save address of instruction that triggered the watchpoint? */
815 if (target
->debug_reason
== DBG_REASON_WATCHPOINT
) {
818 retval
= mem_ap_read_atomic_u32(swjdp
,
819 armv7a
->debug_base
+ CPUDBG_WFAR
,
821 arm_dpm_report_wfar(&armv7a
->dpm
, wfar
);
824 /* REVISIT fast_reg_read is never set ... */
826 /* Examine target state and mode */
827 if (cortex_a8
->fast_reg_read
)
828 target_alloc_working_area(target
, 64, ®file_working_area
);
830 /* First load register acessible through core debug port*/
831 if (!regfile_working_area
)
833 retval
= arm_dpm_read_current_registers(&armv7a
->dpm
);
837 dap_ap_select(swjdp
, swjdp_memoryap
);
838 cortex_a8_read_regs_through_mem(target
,
839 regfile_working_area
->address
, regfile
);
840 dap_ap_select(swjdp
, swjdp_memoryap
);
841 target_free_working_area(target
, regfile_working_area
);
843 /* read Current PSR */
844 cortex_a8_dap_read_coreregister_u32(target
, &cpsr
, 16);
845 dap_ap_select(swjdp
, swjdp_debugap
);
846 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
848 arm_set_cpsr(armv4_5
, cpsr
);
851 for (i
= 0; i
<= ARM_PC
; i
++)
853 reg
= arm_reg_current(armv4_5
, i
);
855 buf_set_u32(reg
->value
, 0, 32, regfile
[i
]);
860 /* Fixup PC Resume Address */
863 // T bit set for Thumb or ThumbEE state
864 regfile
[ARM_PC
] -= 4;
869 regfile
[ARM_PC
] -= 8;
872 reg
= armv4_5
->core_cache
->reg_list
+ 15;
873 buf_set_u32(reg
->value
, 0, 32, regfile
[ARM_PC
]);
874 reg
->dirty
= reg
->valid
;
878 /* TODO, Move this */
879 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
880 cortex_a8_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
881 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
883 cortex_a8_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
884 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
886 cortex_a8_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
887 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
890 /* Are we in an exception handler */
891 // armv4_5->exception_number = 0;
892 if (armv7a
->post_debug_entry
)
893 armv7a
->post_debug_entry(target
);
898 static void cortex_a8_post_debug_entry(struct target
*target
)
900 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
901 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
904 /* MRC p15,0,<Rt>,c1,c0,0 ; Read CP15 System Control Register */
905 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
908 &cortex_a8
->cp15_control_reg
);
909 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
911 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
913 uint32_t cache_type_reg
;
915 /* MRC p15,0,<Rt>,c0,c0,1 ; Read CP15 Cache Type Register */
916 retval
= armv7a
->armv4_5_common
.mrc(target
, 15,
920 LOG_DEBUG("cp15 cache type: %8.8x", (unsigned) cache_type_reg
);
922 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
923 armv4_5_identify_cache(cache_type_reg
,
924 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
927 armv7a
->armv4_5_mmu
.mmu_enabled
=
928 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
929 armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
=
930 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
931 armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
=
932 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
937 static int cortex_a8_step(struct target
*target
, int current
, uint32_t address
,
938 int handle_breakpoints
)
940 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
941 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
942 struct breakpoint
*breakpoint
= NULL
;
943 struct breakpoint stepbreakpoint
;
948 if (target
->state
!= TARGET_HALTED
)
950 LOG_WARNING("target not halted");
951 return ERROR_TARGET_NOT_HALTED
;
954 /* current = 1: continue on current pc, otherwise continue at <address> */
955 r
= armv4_5
->core_cache
->reg_list
+ 15;
958 buf_set_u32(r
->value
, 0, 32, address
);
962 address
= buf_get_u32(r
->value
, 0, 32);
965 /* The front-end may request us not to handle breakpoints.
966 * But since Cortex-A8 uses breakpoint for single step,
967 * we MUST handle breakpoints.
969 handle_breakpoints
= 1;
970 if (handle_breakpoints
) {
971 breakpoint
= breakpoint_find(target
, address
);
973 cortex_a8_unset_breakpoint(target
, breakpoint
);
976 /* Setup single step breakpoint */
977 stepbreakpoint
.address
= address
;
978 stepbreakpoint
.length
= (armv4_5
->core_state
== ARM_STATE_THUMB
)
980 stepbreakpoint
.type
= BKPT_HARD
;
981 stepbreakpoint
.set
= 0;
983 /* Break on IVA mismatch */
984 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
986 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
988 cortex_a8_resume(target
, 1, address
, 0, 0);
990 while (target
->state
!= TARGET_HALTED
)
992 cortex_a8_poll(target
);
995 LOG_WARNING("timeout waiting for target halt");
1000 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
1002 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1005 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
1007 if (target
->state
!= TARGET_HALTED
)
1008 LOG_DEBUG("target stepped");
1013 static int cortex_a8_restore_context(struct target
*target
, bool bpwp
)
1015 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1019 if (armv7a
->pre_restore_context
)
1020 armv7a
->pre_restore_context(target
);
1022 arm_dpm_write_dirty_registers(&armv7a
->dpm
, bpwp
);
1024 if (armv7a
->post_restore_context
)
1025 armv7a
->post_restore_context(target
);
1032 * Cortex-A8 Breakpoint and watchpoint fuctions
1035 /* Setup hardware Breakpoint Register Pair */
1036 static int cortex_a8_set_breakpoint(struct target
*target
,
1037 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1042 uint8_t byte_addr_select
= 0x0F;
1043 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1044 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1045 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1047 if (breakpoint
->set
)
1049 LOG_WARNING("breakpoint already set");
1053 if (breakpoint
->type
== BKPT_HARD
)
1055 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
1057 if (brp_i
>= cortex_a8
->brp_num
)
1059 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1062 breakpoint
->set
= brp_i
+ 1;
1063 if (breakpoint
->length
== 2)
1065 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1067 control
= ((matchmode
& 0x7) << 20)
1068 | (byte_addr_select
<< 5)
1070 brp_list
[brp_i
].used
= 1;
1071 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1072 brp_list
[brp_i
].control
= control
;
1073 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1074 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1075 brp_list
[brp_i
].value
);
1076 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1077 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1078 brp_list
[brp_i
].control
);
1079 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1080 brp_list
[brp_i
].control
,
1081 brp_list
[brp_i
].value
);
1083 else if (breakpoint
->type
== BKPT_SOFT
)
1086 if (breakpoint
->length
== 2)
1088 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1092 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1094 retval
= target
->type
->read_memory(target
,
1095 breakpoint
->address
& 0xFFFFFFFE,
1096 breakpoint
->length
, 1,
1097 breakpoint
->orig_instr
);
1098 if (retval
!= ERROR_OK
)
1100 retval
= target
->type
->write_memory(target
,
1101 breakpoint
->address
& 0xFFFFFFFE,
1102 breakpoint
->length
, 1, code
);
1103 if (retval
!= ERROR_OK
)
1105 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1111 static int cortex_a8_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1114 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1115 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1116 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1118 if (!breakpoint
->set
)
1120 LOG_WARNING("breakpoint not set");
1124 if (breakpoint
->type
== BKPT_HARD
)
1126 int brp_i
= breakpoint
->set
- 1;
1127 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1129 LOG_DEBUG("Invalid BRP number in breakpoint");
1132 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1133 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1134 brp_list
[brp_i
].used
= 0;
1135 brp_list
[brp_i
].value
= 0;
1136 brp_list
[brp_i
].control
= 0;
1137 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1138 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1139 brp_list
[brp_i
].control
);
1140 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1141 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1142 brp_list
[brp_i
].value
);
1146 /* restore original instruction (kept in target endianness) */
1147 if (breakpoint
->length
== 4)
1149 retval
= target
->type
->write_memory(target
,
1150 breakpoint
->address
& 0xFFFFFFFE,
1151 4, 1, breakpoint
->orig_instr
);
1152 if (retval
!= ERROR_OK
)
1157 retval
= target
->type
->write_memory(target
,
1158 breakpoint
->address
& 0xFFFFFFFE,
1159 2, 1, breakpoint
->orig_instr
);
1160 if (retval
!= ERROR_OK
)
1164 breakpoint
->set
= 0;
1169 static int cortex_a8_add_breakpoint(struct target
*target
,
1170 struct breakpoint
*breakpoint
)
1172 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1174 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1176 LOG_INFO("no hardware breakpoint available");
1177 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1180 if (breakpoint
->type
== BKPT_HARD
)
1181 cortex_a8
->brp_num_available
--;
1182 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1187 static int cortex_a8_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1189 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1192 /* It is perfectly possible to remove brakpoints while the taget is running */
1193 if (target
->state
!= TARGET_HALTED
)
1195 LOG_WARNING("target not halted");
1196 return ERROR_TARGET_NOT_HALTED
;
1200 if (breakpoint
->set
)
1202 cortex_a8_unset_breakpoint(target
, breakpoint
);
1203 if (breakpoint
->type
== BKPT_HARD
)
1204 cortex_a8
->brp_num_available
++ ;
1214 * Cortex-A8 Reset fuctions
1217 static int cortex_a8_assert_reset(struct target
*target
)
1219 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1223 /* FIXME when halt is requested, make it work somehow... */
1225 /* Issue some kind of warm reset. */
1226 if (target_has_event_action(target
, TARGET_EVENT_RESET_ASSERT
)) {
1227 target_handle_event(target
, TARGET_EVENT_RESET_ASSERT
);
1228 } else if (jtag_get_reset_config() & RESET_HAS_SRST
) {
1229 /* REVISIT handle "pulls" cases, if there's
1230 * hardware that needs them to work.
1232 jtag_add_reset(0, 1);
1234 LOG_ERROR("%s: how to reset?", target_name(target
));
1238 /* registers are now invalid */
1239 register_cache_invalidate(armv7a
->armv4_5_common
.core_cache
);
1241 target
->state
= TARGET_RESET
;
1246 static int cortex_a8_deassert_reset(struct target
*target
)
1252 /* be certain SRST is off */
1253 jtag_add_reset(0, 0);
1255 retval
= cortex_a8_poll(target
);
1257 if (target
->reset_halt
) {
1258 if (target
->state
!= TARGET_HALTED
) {
1259 LOG_WARNING("%s: ran after reset and before halt ...",
1260 target_name(target
));
1261 if ((retval
= target_halt(target
)) != ERROR_OK
)
1270 * Cortex-A8 Memory access
1272 * This is same Cortex M3 but we must also use the correct
1273 * ap number for every access.
1276 static int cortex_a8_read_memory(struct target
*target
, uint32_t address
,
1277 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1279 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1280 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1281 int retval
= ERROR_INVALID_ARGUMENTS
;
1283 /* cortex_a8 handles unaligned memory access */
1285 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1287 if (count
&& buffer
) {
1290 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1293 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1296 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1304 static int cortex_a8_write_memory(struct target
*target
, uint32_t address
,
1305 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1307 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1308 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1309 int retval
= ERROR_INVALID_ARGUMENTS
;
1311 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1313 if (count
&& buffer
) {
1316 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1319 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1322 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1327 /* REVISIT this op is generic ARMv7-A/R stuff */
1328 if (retval
== ERROR_OK
&& target
->state
== TARGET_HALTED
)
1330 struct arm_dpm
*dpm
= armv7a
->armv4_5_common
.dpm
;
1332 retval
= dpm
->prepare(dpm
);
1333 if (retval
!= ERROR_OK
)
1336 /* The Cache handling will NOT work with MMU active, the
1337 * wrong addresses will be invalidated!
1339 * For both ICache and DCache, walk all cache lines in the
1340 * address range. Cortex-A8 has fixed 64 byte line length.
1342 * REVISIT per ARMv7, these may trigger watchpoints ...
1345 /* invalidate I-Cache */
1346 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
1348 /* ICIMVAU - Invalidate Cache single entry
1350 * MCR p15, 0, r0, c7, c5, 1
1352 for (uint32_t cacheline
= address
;
1353 cacheline
< address
+ size
* count
;
1355 retval
= dpm
->instr_write_data_r0(dpm
,
1356 ARMV4_5_MCR(15, 0, 0, 7, 5, 1),
1361 /* invalidate D-Cache */
1362 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
1364 /* DCIMVAC - Invalidate data Cache line
1366 * MCR p15, 0, r0, c7, c6, 1
1368 for (uint32_t cacheline
= address
;
1369 cacheline
< address
+ size
* count
;
1371 retval
= dpm
->instr_write_data_r0(dpm
,
1372 ARMV4_5_MCR(15, 0, 0, 7, 6, 1),
1377 /* (void) */ dpm
->finish(dpm
);
1383 static int cortex_a8_bulk_write_memory(struct target
*target
, uint32_t address
,
1384 uint32_t count
, uint8_t *buffer
)
1386 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1390 static int cortex_a8_dcc_read(struct swjdp_common
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1395 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1396 *ctrl
= (uint8_t)dcrdr
;
1397 *value
= (uint8_t)(dcrdr
>> 8);
1399 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1401 /* write ack back to software dcc register
1402 * signify we have read data */
1403 if (dcrdr
& (1 << 0))
1406 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1413 static int cortex_a8_handle_target_request(void *priv
)
1415 struct target
*target
= priv
;
1416 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1417 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1419 if (!target_was_examined(target
))
1421 if (!target
->dbg_msg_enabled
)
1424 if (target
->state
== TARGET_RUNNING
)
1429 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1431 /* check if we have data */
1432 if (ctrl
& (1 << 0))
1436 /* we assume target is quick enough */
1438 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1439 request
|= (data
<< 8);
1440 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1441 request
|= (data
<< 16);
1442 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1443 request
|= (data
<< 24);
1444 target_request(target
, request
);
1452 * Cortex-A8 target information and configuration
1455 static int cortex_a8_examine_first(struct target
*target
)
1457 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1458 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1459 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1461 int retval
= ERROR_OK
;
1462 uint32_t didr
, ctypr
, ttypr
, cpuid
;
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 failed");
1481 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1482 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1484 LOG_DEBUG("Examine failed");
1488 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1489 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1491 LOG_DEBUG("Examine failed");
1495 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1496 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1498 LOG_DEBUG("Examine failed");
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 swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1567 /* Setup struct cortex_a8_common */
1568 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1569 armv4_5
->arch_info
= armv7a
;
1571 /* prepare JTAG information for the new target */
1572 cortex_a8
->jtag_info
.tap
= tap
;
1573 cortex_a8
->jtag_info
.scann_size
= 4;
1575 swjdp
->dp_select_value
= -1;
1576 swjdp
->ap_csw_value
= -1;
1577 swjdp
->ap_tar_value
= -1;
1578 swjdp
->jtag_info
= &cortex_a8
->jtag_info
;
1579 swjdp
->memaccess_tck
= 80;
1581 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1582 swjdp
->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)