1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2006 by Magnus Lundin *
8 * Copyright (C) 2008 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
11 * Copyright (C) 2009 by Dirk Behme *
12 * dirk.behme@gmail.com - copy from cortex_m3 *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program; if not, write to the *
26 * Free Software Foundation, Inc., *
27 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
29 * Cortex-A8(tm) TRM, ARM DDI 0344H *
31 ***************************************************************************/
36 #include "breakpoints.h"
37 #include "cortex_a8.h"
39 #include "target_request.h"
40 #include "target_type.h"
42 static int cortex_a8_poll(struct target
*target
);
43 static int cortex_a8_debug_entry(struct target
*target
);
44 static int cortex_a8_restore_context(struct target
*target
);
45 static int cortex_a8_set_breakpoint(struct target
*target
,
46 struct breakpoint
*breakpoint
, uint8_t matchmode
);
47 static int cortex_a8_unset_breakpoint(struct target
*target
,
48 struct breakpoint
*breakpoint
);
49 static int cortex_a8_dap_read_coreregister_u32(struct target
*target
,
50 uint32_t *value
, int regnum
);
51 static int cortex_a8_dap_write_coreregister_u32(struct target
*target
,
52 uint32_t value
, int regnum
);
54 * FIXME do topology discovery using the ROM; don't
55 * assume this is an OMAP3.
57 #define swjdp_memoryap 0
58 #define swjdp_debugap 1
59 #define OMAP3530_DEBUG_BASE 0x54011000
62 * Cortex-A8 Basic debug access, very low level assumes state is saved
64 static int cortex_a8_init_debug_access(struct target
*target
)
66 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
67 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
74 /* Unlocking the debug registers for modification */
75 /* The debugport might be uninitialised so try twice */
76 retval
= mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
77 if (retval
!= ERROR_OK
)
78 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
79 /* Clear Sticky Power Down status Bit in PRSR to enable access to
80 the registers in the Core Power Domain */
81 retval
= mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_PRSR
, &dummy
);
82 /* Enabling of instruction execution in debug mode is done in debug_entry code */
84 /* Resync breakpoint registers */
86 /* Since this is likley called from init or reset, update targtet state information*/
87 cortex_a8_poll(target
);
92 /* FIXME we waste a *LOT* of round-trips with needless DSCR reads, which
93 * slows down operations considerably. One good way to start reducing
94 * them would pass current values into and out of this routine. That
95 * should also help synch DCC read/write.
97 static int cortex_a8_exec_opcode(struct target
*target
, uint32_t opcode
)
101 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
102 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
104 LOG_DEBUG("exec opcode 0x%08" PRIx32
, opcode
);
107 retval
= mem_ap_read_atomic_u32(swjdp
,
108 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
109 if (retval
!= ERROR_OK
)
111 LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32
, opcode
);
115 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
117 mem_ap_write_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_ITR
, opcode
);
121 retval
= mem_ap_read_atomic_u32(swjdp
,
122 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
123 if (retval
!= ERROR_OK
)
125 LOG_ERROR("Could not read DSCR register");
129 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
134 /**************************************************************************
135 Read core register with very few exec_opcode, fast but needs work_area.
136 This can cause problems with MMU active.
137 **************************************************************************/
138 static int cortex_a8_read_regs_through_mem(struct target
*target
, uint32_t address
,
141 int retval
= ERROR_OK
;
142 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
143 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
145 cortex_a8_dap_read_coreregister_u32(target
, regfile
, 0);
146 cortex_a8_dap_write_coreregister_u32(target
, address
, 0);
147 cortex_a8_exec_opcode(target
, ARMV4_5_STMIA(0, 0xFFFE, 0, 0));
148 dap_ap_select(swjdp
, swjdp_memoryap
);
149 mem_ap_read_buf_u32(swjdp
, (uint8_t *)(®file
[1]), 4*15, address
);
150 dap_ap_select(swjdp
, swjdp_debugap
);
155 static int cortex_a8_read_cp(struct target
*target
, uint32_t *value
, uint8_t CP
,
156 uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
159 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
160 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
162 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(CP
, op1
, 0, CRn
, CRm
, op2
));
163 /* Move R0 to DTRTX */
164 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
167 retval
= mem_ap_read_atomic_u32(swjdp
,
168 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
173 static int cortex_a8_write_cp(struct target
*target
, uint32_t value
,
174 uint8_t CP
, uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
178 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
179 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
181 LOG_DEBUG("CP%i, CRn %i, value 0x%08" PRIx32
, CP
, CRn
, value
);
183 /* Check that DCCRX is not full */
184 retval
= mem_ap_read_atomic_u32(swjdp
,
185 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
186 if (dscr
& (1 << DSCR_DTR_RX_FULL
))
188 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
189 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
190 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
193 retval
= mem_ap_write_u32(swjdp
,
194 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
195 /* Move DTRRX to r0 */
196 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
198 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(CP
, op1
, 0, CRn
, CRm
, op2
));
202 static int cortex_a8_read_cp15(struct target
*target
, uint32_t op1
, uint32_t op2
,
203 uint32_t CRn
, uint32_t CRm
, uint32_t *value
)
205 return cortex_a8_read_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
208 static int cortex_a8_write_cp15(struct target
*target
, uint32_t op1
, uint32_t op2
,
209 uint32_t CRn
, uint32_t CRm
, uint32_t value
)
211 return cortex_a8_write_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
214 static int cortex_a8_mrc(struct target
*target
, int cpnum
, uint32_t op1
, uint32_t op2
, uint32_t CRn
, uint32_t CRm
, uint32_t *value
)
218 LOG_ERROR("Only cp15 is supported");
221 return cortex_a8_read_cp15(target
, op1
, op2
, CRn
, CRm
, value
);
224 static int cortex_a8_mcr(struct target
*target
, int cpnum
, uint32_t op1
, uint32_t op2
, uint32_t CRn
, uint32_t CRm
, uint32_t value
)
228 LOG_ERROR("Only cp15 is supported");
231 return cortex_a8_write_cp15(target
, op1
, op2
, CRn
, CRm
, value
);
236 static int cortex_a8_dap_read_coreregister_u32(struct target
*target
,
237 uint32_t *value
, int regnum
)
239 int retval
= ERROR_OK
;
240 uint8_t reg
= regnum
&0xFF;
242 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
243 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
250 /* Rn to DCCTX, "MCR p14, 0, Rn, c0, c5, 0" 0xEE00nE15 */
251 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, reg
, 0, 5, 0));
255 /* "MOV r0, r15"; then move r0 to DCCTX */
256 cortex_a8_exec_opcode(target
, 0xE1A0000F);
257 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
261 /* "MRS r0, CPSR" or "MRS r0, SPSR"
262 * then move r0 to DCCTX
264 cortex_a8_exec_opcode(target
, ARMV4_5_MRS(0, reg
& 1));
265 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
271 retval
= mem_ap_read_atomic_u32(swjdp
,
272 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
274 while ((dscr
& (1 << DSCR_DTR_TX_FULL
)) == 0); /* Wait for DTRRXfull */
276 retval
= mem_ap_read_atomic_u32(swjdp
,
277 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
278 LOG_DEBUG("read DCC 0x%08" PRIx32
, *value
);
283 static int cortex_a8_dap_write_coreregister_u32(struct target
*target
,
284 uint32_t value
, int regnum
)
286 int retval
= ERROR_OK
;
287 uint8_t Rd
= regnum
&0xFF;
289 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
290 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
292 LOG_DEBUG("register %i, value 0x%08" PRIx32
, regnum
, value
);
294 /* Check that DCCRX is not full */
295 retval
= mem_ap_read_atomic_u32(swjdp
,
296 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
297 if (dscr
& (1 << DSCR_DTR_RX_FULL
))
299 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
300 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
301 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
308 LOG_DEBUG("write DCC 0x%08" PRIx32
, value
);
309 retval
= mem_ap_write_u32(swjdp
,
310 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
314 /* DCCRX to Rn, "MCR p14, 0, Rn, c0, c5, 0", 0xEE00nE15 */
315 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, Rd
, 0, 5, 0));
319 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15
322 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
323 cortex_a8_exec_opcode(target
, 0xE1A0F000);
327 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15
328 * then "MSR CPSR_cxsf, r0" or "MSR SPSR_cxsf, r0" (all fields)
330 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
331 cortex_a8_exec_opcode(target
, ARMV4_5_MSR_GP(0, 0xF, Rd
& 1));
333 /* "Prefetch flush" after modifying execution status in CPSR */
335 cortex_a8_exec_opcode(target
,
336 ARMV4_5_MCR(15, 0, 0, 7, 5, 4));
342 /* Write to memory mapped registers directly with no cache or mmu handling */
343 static int cortex_a8_dap_write_memap_register_u32(struct target
*target
, uint32_t address
, uint32_t value
)
346 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
347 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
349 retval
= mem_ap_write_atomic_u32(swjdp
, address
, value
);
355 * Cortex-A8 Run control
358 static int cortex_a8_poll(struct target
*target
)
360 int retval
= ERROR_OK
;
362 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
363 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
364 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
365 enum target_state prev_target_state
= target
->state
;
366 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
368 dap_ap_select(swjdp
, swjdp_debugap
);
369 retval
= mem_ap_read_atomic_u32(swjdp
,
370 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
371 if (retval
!= ERROR_OK
)
373 dap_ap_select(swjdp
, saved_apsel
);
376 cortex_a8
->cpudbg_dscr
= dscr
;
378 if ((dscr
& 0x3) == 0x3)
380 if (prev_target_state
!= TARGET_HALTED
)
382 /* We have a halting debug event */
383 LOG_DEBUG("Target halted");
384 target
->state
= TARGET_HALTED
;
385 if ((prev_target_state
== TARGET_RUNNING
)
386 || (prev_target_state
== TARGET_RESET
))
388 retval
= cortex_a8_debug_entry(target
);
389 if (retval
!= ERROR_OK
)
392 target_call_event_callbacks(target
,
393 TARGET_EVENT_HALTED
);
395 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
399 retval
= cortex_a8_debug_entry(target
);
400 if (retval
!= ERROR_OK
)
403 target_call_event_callbacks(target
,
404 TARGET_EVENT_DEBUG_HALTED
);
408 else if ((dscr
& 0x3) == 0x2)
410 target
->state
= TARGET_RUNNING
;
414 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32
, dscr
);
415 target
->state
= TARGET_UNKNOWN
;
418 dap_ap_select(swjdp
, saved_apsel
);
423 static int cortex_a8_halt(struct target
*target
)
425 int retval
= ERROR_OK
;
427 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
428 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
429 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
430 dap_ap_select(swjdp
, swjdp_debugap
);
433 * Tell the core to be halted by writing DRCR with 0x1
434 * and then wait for the core to be halted.
436 retval
= mem_ap_write_atomic_u32(swjdp
,
437 armv7a
->debug_base
+ CPUDBG_DRCR
, 0x1);
440 * enter halting debug mode
442 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
443 retval
= mem_ap_write_atomic_u32(swjdp
,
444 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
| (1 << DSCR_HALT_DBG_MODE
));
446 if (retval
!= ERROR_OK
)
450 mem_ap_read_atomic_u32(swjdp
,
451 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
452 } while ((dscr
& (1 << DSCR_CORE_HALTED
)) == 0);
454 target
->debug_reason
= DBG_REASON_DBGRQ
;
457 dap_ap_select(swjdp
, saved_apsel
);
461 static int cortex_a8_resume(struct target
*target
, int current
,
462 uint32_t address
, int handle_breakpoints
, int debug_execution
)
464 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
465 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
466 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
468 // struct breakpoint *breakpoint = NULL;
469 uint32_t resume_pc
, dscr
;
471 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
472 dap_ap_select(swjdp
, swjdp_debugap
);
474 if (!debug_execution
)
476 target_free_all_working_areas(target
);
477 // cortex_m3_enable_breakpoints(target);
478 // cortex_m3_enable_watchpoints(target);
484 /* Disable interrupts */
485 /* We disable interrupts in the PRIMASK register instead of
486 * masking with C_MASKINTS,
487 * This is probably the same issue as Cortex-M3 Errata 377493:
488 * C_MASKINTS in parallel with disabled interrupts can cause
489 * local faults to not be taken. */
490 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
491 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
492 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
494 /* Make sure we are in Thumb mode */
495 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
496 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
497 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
498 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
502 /* current = 1: continue on current pc, otherwise continue at <address> */
503 resume_pc
= buf_get_u32(
504 armv4_5
->core_cache
->reg_list
[15].value
,
509 /* Make sure that the Armv7 gdb thumb fixups does not
510 * kill the return address
512 switch (armv4_5
->core_state
)
514 case ARMV4_5_STATE_ARM
:
515 resume_pc
&= 0xFFFFFFFC;
517 case ARMV4_5_STATE_THUMB
:
518 case ARM_STATE_THUMB_EE
:
519 /* When the return address is loaded into PC
520 * bit 0 must be 1 to stay in Thumb state
524 case ARMV4_5_STATE_JAZELLE
:
525 LOG_ERROR("How do I resume into Jazelle state??");
528 LOG_DEBUG("resume pc = 0x%08" PRIx32
, resume_pc
);
529 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
,
531 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
532 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
534 cortex_a8_restore_context(target
);
537 /* the front-end may request us not to handle breakpoints */
538 if (handle_breakpoints
)
540 /* Single step past breakpoint at current address */
541 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
543 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
544 cortex_m3_unset_breakpoint(target
, breakpoint
);
545 cortex_m3_single_step_core(target
);
546 cortex_m3_set_breakpoint(target
, breakpoint
);
551 /* Restart core and wait for it to be started */
552 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DRCR
, 0x2);
555 mem_ap_read_atomic_u32(swjdp
,
556 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
557 } while ((dscr
& (1 << DSCR_CORE_RESTARTED
)) == 0);
559 target
->debug_reason
= DBG_REASON_NOTHALTED
;
560 target
->state
= TARGET_RUNNING
;
562 /* registers are now invalid */
563 register_cache_invalidate(armv4_5
->core_cache
);
565 if (!debug_execution
)
567 target
->state
= TARGET_RUNNING
;
568 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
569 LOG_DEBUG("target resumed at 0x%" PRIx32
, resume_pc
);
573 target
->state
= TARGET_DEBUG_RUNNING
;
574 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
575 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, resume_pc
);
578 dap_ap_select(swjdp
, saved_apsel
);
583 static int cortex_a8_debug_entry(struct target
*target
)
586 uint32_t regfile
[16], pc
, cpsr
, dscr
;
587 int retval
= ERROR_OK
;
588 struct working_area
*regfile_working_area
= NULL
;
589 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
590 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
591 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
592 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
595 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
597 /* Enable the ITR execution once we are in debug mode */
598 mem_ap_read_atomic_u32(swjdp
,
599 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
601 /* REVISIT see A8 TRM 12.11.4 steps 2..3 -- make sure that any
602 * imprecise data aborts get discarded by issuing a Data
603 * Synchronization Barrier: ARMV4_5_MCR(15, 0, 0, 7, 10, 4).
606 dscr
|= (1 << DSCR_EXT_INT_EN
);
607 retval
= mem_ap_write_atomic_u32(swjdp
,
608 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
);
610 /* Examine debug reason */
611 switch ((cortex_a8
->cpudbg_dscr
>> 2)&0xF)
613 case 0: /* DRCR[0] write */
615 target
->debug_reason
= DBG_REASON_DBGRQ
;
617 case 1: /* HW breakpoint */
618 case 3: /* SW BKPT */
619 case 5: /* vector catch */
620 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
622 case 10: /* precise watchpoint */
623 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
624 /* REVISIT could collect WFAR later, to see just
625 * which instruction triggered the watchpoint.
629 target
->debug_reason
= DBG_REASON_UNDEFINED
;
633 /* REVISIT fast_reg_read is never set ... */
635 /* Examine target state and mode */
636 if (cortex_a8
->fast_reg_read
)
637 target_alloc_working_area(target
, 64, ®file_working_area
);
639 /* First load register acessible through core debug port*/
640 if (!regfile_working_area
)
642 /* FIXME we don't actually need all these registers;
643 * reading them slows us down. Just R0, PC, CPSR...
645 for (i
= 0; i
<= 15; i
++)
646 cortex_a8_dap_read_coreregister_u32(target
,
651 dap_ap_select(swjdp
, swjdp_memoryap
);
652 cortex_a8_read_regs_through_mem(target
,
653 regfile_working_area
->address
, regfile
);
654 dap_ap_select(swjdp
, swjdp_memoryap
);
655 target_free_working_area(target
, regfile_working_area
);
658 /* read Current PSR */
659 cortex_a8_dap_read_coreregister_u32(target
, &cpsr
, 16);
661 dap_ap_select(swjdp
, swjdp_debugap
);
662 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
664 arm_set_cpsr(armv4_5
, cpsr
);
667 for (i
= 0; i
<= ARM_PC
; i
++)
669 reg
= arm_reg_current(armv4_5
, i
);
671 buf_set_u32(reg
->value
, 0, 32, regfile
[i
]);
676 /* Fixup PC Resume Address */
679 // T bit set for Thumb or ThumbEE state
680 regfile
[ARM_PC
] -= 4;
685 regfile
[ARM_PC
] -= 8;
688 reg
= armv4_5
->core_cache
->reg_list
+ 15;
689 buf_set_u32(reg
->value
, 0, 32, regfile
[ARM_PC
]);
690 reg
->dirty
= reg
->valid
;
691 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 15)
692 .dirty
= ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
,
693 armv4_5
->core_mode
, 15).valid
;
696 /* TODO, Move this */
697 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
698 cortex_a8_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
699 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
701 cortex_a8_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
702 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
704 cortex_a8_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
705 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
708 /* Are we in an exception handler */
709 // armv4_5->exception_number = 0;
710 if (armv7a
->post_debug_entry
)
711 armv7a
->post_debug_entry(target
);
719 static void cortex_a8_post_debug_entry(struct target
*target
)
721 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
722 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
724 // cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
725 /* examine cp15 control reg */
726 armv7a
->read_cp15(target
, 0, 0, 1, 0, &cortex_a8
->cp15_control_reg
);
727 jtag_execute_queue();
728 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
730 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
732 uint32_t cache_type_reg
;
733 /* identify caches */
734 armv7a
->read_cp15(target
, 0, 1, 0, 0, &cache_type_reg
);
735 jtag_execute_queue();
736 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
737 armv4_5_identify_cache(cache_type_reg
,
738 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
741 armv7a
->armv4_5_mmu
.mmu_enabled
=
742 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
743 armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
=
744 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
745 armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
=
746 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
751 static int cortex_a8_step(struct target
*target
, int current
, uint32_t address
,
752 int handle_breakpoints
)
754 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
755 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
756 struct breakpoint
*breakpoint
= NULL
;
757 struct breakpoint stepbreakpoint
;
762 if (target
->state
!= TARGET_HALTED
)
764 LOG_WARNING("target not halted");
765 return ERROR_TARGET_NOT_HALTED
;
768 /* current = 1: continue on current pc, otherwise continue at <address> */
769 r
= armv4_5
->core_cache
->reg_list
+ 15;
772 buf_set_u32(r
->value
, 0, 32, address
);
776 address
= buf_get_u32(r
->value
, 0, 32);
779 /* The front-end may request us not to handle breakpoints.
780 * But since Cortex-A8 uses breakpoint for single step,
781 * we MUST handle breakpoints.
783 handle_breakpoints
= 1;
784 if (handle_breakpoints
) {
785 breakpoint
= breakpoint_find(target
, address
);
787 cortex_a8_unset_breakpoint(target
, breakpoint
);
790 /* Setup single step breakpoint */
791 stepbreakpoint
.address
= address
;
792 stepbreakpoint
.length
= (armv4_5
->core_state
== ARMV4_5_STATE_THUMB
)
794 stepbreakpoint
.type
= BKPT_HARD
;
795 stepbreakpoint
.set
= 0;
797 /* Break on IVA mismatch */
798 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
800 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
802 cortex_a8_resume(target
, 1, address
, 0, 0);
804 while (target
->state
!= TARGET_HALTED
)
806 cortex_a8_poll(target
);
809 LOG_WARNING("timeout waiting for target halt");
814 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
815 if (timeout
> 0) target
->debug_reason
= DBG_REASON_BREAKPOINT
;
818 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
820 if (target
->state
!= TARGET_HALTED
)
821 LOG_DEBUG("target stepped");
826 static int cortex_a8_restore_context(struct target
*target
)
829 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
830 struct reg_cache
*cache
= armv7a
->armv4_5_common
.core_cache
;
831 unsigned max
= cache
->num_regs
;
833 bool flushed
, flush_cpsr
= false;
837 if (armv7a
->pre_restore_context
)
838 armv7a
->pre_restore_context(target
);
840 /* Flush all dirty registers from the cache, one mode at a time so
841 * that we write CPSR as little as possible. Save CPSR and R0 for
842 * last; they're used to change modes and write other registers.
844 * REVISIT be smarter: save eventual mode for last loop, don't
845 * need to write CPSR an extra time.
848 enum armv4_5_mode mode
= ARMV4_5_MODE_ANY
;
853 /* write dirty non-{R0,CPSR} registers sharing the same mode */
854 for (i
= max
- 1, r
= cache
->reg_list
+ 1; i
> 0; i
--, r
++) {
857 if (!r
->dirty
|| r
== armv7a
->armv4_5_common
.cpsr
)
861 /* TODO Check return values */
863 /* Pick a mode and update CPSR; else ignore this
864 * register if it's for a different mode than what
865 * we're handling on this pass.
867 * REVISIT don't distinguish SYS and USR modes.
869 * FIXME if we restore from FIQ mode, R8..R12 will
870 * get wrongly flushed onto FIQ shadows...
872 if (mode
== ARMV4_5_MODE_ANY
) {
874 if (mode
!= ARMV4_5_MODE_ANY
) {
875 cortex_a8_dap_write_coreregister_u32(
879 } else if (mode
!= reg
->mode
)
882 /* Write this register */
883 value
= buf_get_u32(r
->value
, 0, 32);
884 cortex_a8_dap_write_coreregister_u32(target
, value
,
885 (reg
->num
== 16) ? 17 : reg
->num
);
892 /* now flush CPSR if needed ... */
893 r
= armv7a
->armv4_5_common
.cpsr
;
894 if (flush_cpsr
|| r
->dirty
) {
895 value
= buf_get_u32(r
->value
, 0, 32);
896 cortex_a8_dap_write_coreregister_u32(target
, value
, 16);
900 /* ... and R0 always (it was dirtied when we saved context) */
901 r
= cache
->reg_list
+ 0;
902 value
= buf_get_u32(r
->value
, 0, 32);
903 cortex_a8_dap_write_coreregister_u32(target
, value
, 0);
906 if (armv7a
->post_restore_context
)
907 armv7a
->post_restore_context(target
);
915 * Cortex-A8 Core register functions
917 static int cortex_a8_load_core_reg_u32(struct target
*target
, int num
,
918 armv4_5_mode_t mode
, uint32_t * value
)
921 struct arm
*armv4_5
= target_to_armv4_5(target
);
923 if ((num
<= ARM_CPSR
))
925 /* read a normal core register */
926 retval
= cortex_a8_dap_read_coreregister_u32(target
, value
, num
);
928 if (retval
!= ERROR_OK
)
930 LOG_ERROR("JTAG failure %i", retval
);
931 return ERROR_JTAG_DEVICE_ERROR
;
933 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
, num
, *value
);
937 return ERROR_INVALID_ARGUMENTS
;
940 /* Register other than r0 - r14 uses r0 for access */
942 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
,
943 armv4_5
->core_mode
, 0).dirty
=
944 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
,
945 armv4_5
->core_mode
, 0).valid
;
946 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
,
947 armv4_5
->core_mode
, 15).dirty
=
948 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
,
949 armv4_5
->core_mode
, 15).valid
;
954 static int cortex_a8_store_core_reg_u32(struct target
*target
, int num
,
955 armv4_5_mode_t mode
, uint32_t value
)
959 struct arm
*armv4_5
= target_to_armv4_5(target
);
961 #ifdef ARMV7_GDB_HACKS
962 /* If the LR register is being modified, make sure it will put us
963 * in "thumb" mode, or an INVSTATE exception will occur. This is a
964 * hack to deal with the fact that gdb will sometimes "forge"
965 * return addresses, and doesn't set the LSB correctly (i.e., when
966 * printing expressions containing function calls, it sets LR=0.) */
972 if ((num
<= ARM_CPSR
))
974 retval
= cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
975 if (retval
!= ERROR_OK
)
977 LOG_ERROR("JTAG failure %i", retval
);
978 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
,
979 armv4_5
->core_mode
, num
).dirty
=
980 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
,
981 armv4_5
->core_mode
, num
).valid
;
982 return ERROR_JTAG_DEVICE_ERROR
;
984 LOG_DEBUG("write core reg %i value 0x%" PRIx32
, num
, value
);
988 return ERROR_INVALID_ARGUMENTS
;
996 static int cortex_a8_write_core_reg(struct target
*target
, struct reg
*r
,
997 int num
, enum armv4_5_mode mode
, uint32_t value
);
999 static int cortex_a8_read_core_reg(struct target
*target
, struct reg
*r
,
1000 int num
, enum armv4_5_mode mode
)
1004 struct arm
*armv4_5
= target_to_armv4_5(target
);
1005 struct reg
*cpsr_r
= NULL
;
1007 unsigned cookie
= num
;
1009 /* avoid some needless mode changes
1010 * FIXME move some of these to shared ARM code...
1012 if (mode
!= armv4_5
->core_mode
) {
1013 if ((armv4_5
->core_mode
== ARMV4_5_MODE_SYS
)
1014 && (mode
== ARMV4_5_MODE_USR
))
1015 mode
= ARMV4_5_MODE_ANY
;
1016 else if ((mode
!= ARMV4_5_MODE_FIQ
) && (num
<= 12))
1017 mode
= ARMV4_5_MODE_ANY
;
1019 if (mode
!= ARMV4_5_MODE_ANY
) {
1020 cpsr_r
= armv4_5
->cpsr
;
1021 cpsr
= buf_get_u32(cpsr_r
->value
, 0, 32);
1022 cortex_a8_write_core_reg(target
, cpsr_r
,
1023 16, ARMV4_5_MODE_ANY
, mode
);
1029 case ARMV4_5_MODE_USR
:
1030 case ARMV4_5_MODE_SYS
:
1031 case ARMV4_5_MODE_ANY
:
1041 cortex_a8_dap_read_coreregister_u32(target
, &value
, cookie
);
1042 retval
= jtag_execute_queue();
1043 if (retval
== ERROR_OK
) {
1046 buf_set_u32(r
->value
, 0, 32, value
);
1050 cortex_a8_write_core_reg(target
, cpsr_r
,
1051 16, ARMV4_5_MODE_ANY
, cpsr
);
1055 static int cortex_a8_write_core_reg(struct target
*target
, struct reg
*r
,
1056 int num
, enum armv4_5_mode mode
, uint32_t value
)
1059 struct arm
*armv4_5
= target_to_armv4_5(target
);
1060 struct reg
*cpsr_r
= NULL
;
1062 unsigned cookie
= num
;
1064 /* avoid some needless mode changes
1065 * FIXME move some of these to shared ARM code...
1067 if (mode
!= armv4_5
->core_mode
) {
1068 if ((armv4_5
->core_mode
== ARMV4_5_MODE_SYS
)
1069 && (mode
== ARMV4_5_MODE_USR
))
1070 mode
= ARMV4_5_MODE_ANY
;
1071 else if ((mode
!= ARMV4_5_MODE_FIQ
) && (num
<= 12))
1072 mode
= ARMV4_5_MODE_ANY
;
1074 if (mode
!= ARMV4_5_MODE_ANY
) {
1075 cpsr_r
= armv4_5
->cpsr
;
1076 cpsr
= buf_get_u32(cpsr_r
->value
, 0, 32);
1077 cortex_a8_write_core_reg(target
, cpsr_r
,
1078 16, ARMV4_5_MODE_ANY
, mode
);
1085 case ARMV4_5_MODE_USR
:
1086 case ARMV4_5_MODE_SYS
:
1087 case ARMV4_5_MODE_ANY
:
1097 cortex_a8_dap_write_coreregister_u32(target
, value
, cookie
);
1098 if ((retval
= jtag_execute_queue()) == ERROR_OK
) {
1099 buf_set_u32(r
->value
, 0, 32, value
);
1105 cortex_a8_write_core_reg(target
, cpsr_r
,
1106 16, ARMV4_5_MODE_ANY
, cpsr
);
1112 * Cortex-A8 Breakpoint and watchpoint fuctions
1115 /* Setup hardware Breakpoint Register Pair */
1116 static int cortex_a8_set_breakpoint(struct target
*target
,
1117 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1122 uint8_t byte_addr_select
= 0x0F;
1123 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1124 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1125 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1127 if (breakpoint
->set
)
1129 LOG_WARNING("breakpoint already set");
1133 if (breakpoint
->type
== BKPT_HARD
)
1135 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
1137 if (brp_i
>= cortex_a8
->brp_num
)
1139 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1142 breakpoint
->set
= brp_i
+ 1;
1143 if (breakpoint
->length
== 2)
1145 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1147 control
= ((matchmode
& 0x7) << 20)
1148 | (byte_addr_select
<< 5)
1150 brp_list
[brp_i
].used
= 1;
1151 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1152 brp_list
[brp_i
].control
= control
;
1153 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1154 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1155 brp_list
[brp_i
].value
);
1156 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1157 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1158 brp_list
[brp_i
].control
);
1159 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1160 brp_list
[brp_i
].control
,
1161 brp_list
[brp_i
].value
);
1163 else if (breakpoint
->type
== BKPT_SOFT
)
1166 if (breakpoint
->length
== 2)
1168 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1172 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1174 retval
= target
->type
->read_memory(target
,
1175 breakpoint
->address
& 0xFFFFFFFE,
1176 breakpoint
->length
, 1,
1177 breakpoint
->orig_instr
);
1178 if (retval
!= ERROR_OK
)
1180 retval
= target
->type
->write_memory(target
,
1181 breakpoint
->address
& 0xFFFFFFFE,
1182 breakpoint
->length
, 1, code
);
1183 if (retval
!= ERROR_OK
)
1185 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1191 static int cortex_a8_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1194 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1195 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1196 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1198 if (!breakpoint
->set
)
1200 LOG_WARNING("breakpoint not set");
1204 if (breakpoint
->type
== BKPT_HARD
)
1206 int brp_i
= breakpoint
->set
- 1;
1207 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1209 LOG_DEBUG("Invalid BRP number in breakpoint");
1212 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1213 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1214 brp_list
[brp_i
].used
= 0;
1215 brp_list
[brp_i
].value
= 0;
1216 brp_list
[brp_i
].control
= 0;
1217 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1218 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1219 brp_list
[brp_i
].control
);
1220 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1221 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1222 brp_list
[brp_i
].value
);
1226 /* restore original instruction (kept in target endianness) */
1227 if (breakpoint
->length
== 4)
1229 retval
= target
->type
->write_memory(target
,
1230 breakpoint
->address
& 0xFFFFFFFE,
1231 4, 1, breakpoint
->orig_instr
);
1232 if (retval
!= ERROR_OK
)
1237 retval
= target
->type
->write_memory(target
,
1238 breakpoint
->address
& 0xFFFFFFFE,
1239 2, 1, breakpoint
->orig_instr
);
1240 if (retval
!= ERROR_OK
)
1244 breakpoint
->set
= 0;
1249 static int cortex_a8_add_breakpoint(struct target
*target
,
1250 struct breakpoint
*breakpoint
)
1252 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1254 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1256 LOG_INFO("no hardware breakpoint available");
1257 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1260 if (breakpoint
->type
== BKPT_HARD
)
1261 cortex_a8
->brp_num_available
--;
1262 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1267 static int cortex_a8_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1269 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1272 /* It is perfectly possible to remove brakpoints while the taget is running */
1273 if (target
->state
!= TARGET_HALTED
)
1275 LOG_WARNING("target not halted");
1276 return ERROR_TARGET_NOT_HALTED
;
1280 if (breakpoint
->set
)
1282 cortex_a8_unset_breakpoint(target
, breakpoint
);
1283 if (breakpoint
->type
== BKPT_HARD
)
1284 cortex_a8
->brp_num_available
++ ;
1294 * Cortex-A8 Reset fuctions
1297 static int cortex_a8_assert_reset(struct target
*target
)
1299 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1303 /* registers are now invalid */
1304 register_cache_invalidate(armv7a
->armv4_5_common
.core_cache
);
1306 target
->state
= TARGET_RESET
;
1311 static int cortex_a8_deassert_reset(struct target
*target
)
1316 if (target
->reset_halt
)
1319 if ((retval
= target_halt(target
)) != ERROR_OK
)
1327 * Cortex-A8 Memory access
1329 * This is same Cortex M3 but we must also use the correct
1330 * ap number for every access.
1333 static int cortex_a8_read_memory(struct target
*target
, uint32_t address
,
1334 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1336 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1337 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1338 int retval
= ERROR_INVALID_ARGUMENTS
;
1340 /* cortex_a8 handles unaligned memory access */
1342 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1344 if (count
&& buffer
) {
1347 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1350 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1353 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1361 static int cortex_a8_write_memory(struct target
*target
, uint32_t address
,
1362 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1364 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1365 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1366 int retval
= ERROR_INVALID_ARGUMENTS
;
1368 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1370 if (count
&& buffer
) {
1373 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1376 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1379 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1384 if (retval
== ERROR_OK
&& target
->state
== TARGET_HALTED
)
1386 /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */
1387 /* invalidate I-Cache */
1388 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
1390 /* Invalidate ICache single entry with MVA, repeat this for all cache
1391 lines in the address range, Cortex-A8 has fixed 64 byte line length */
1392 /* Invalidate Cache single entry with MVA to PoU */
1393 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1394 armv7a
->write_cp15(target
, 0, 1, 7, 5, cacheline
); /* I-Cache to PoU */
1396 /* invalidate D-Cache */
1397 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
1399 /* Invalidate Cache single entry with MVA to PoC */
1400 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1401 armv7a
->write_cp15(target
, 0, 1, 7, 6, cacheline
); /* U/D cache to PoC */
1408 static int cortex_a8_bulk_write_memory(struct target
*target
, uint32_t address
,
1409 uint32_t count
, uint8_t *buffer
)
1411 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1415 static int cortex_a8_dcc_read(struct swjdp_common
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1420 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1421 *ctrl
= (uint8_t)dcrdr
;
1422 *value
= (uint8_t)(dcrdr
>> 8);
1424 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1426 /* write ack back to software dcc register
1427 * signify we have read data */
1428 if (dcrdr
& (1 << 0))
1431 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1438 static int cortex_a8_handle_target_request(void *priv
)
1440 struct target
*target
= priv
;
1441 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1442 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1444 if (!target_was_examined(target
))
1446 if (!target
->dbg_msg_enabled
)
1449 if (target
->state
== TARGET_RUNNING
)
1454 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1456 /* check if we have data */
1457 if (ctrl
& (1 << 0))
1461 /* we assume target is quick enough */
1463 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1464 request
|= (data
<< 8);
1465 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1466 request
|= (data
<< 16);
1467 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1468 request
|= (data
<< 24);
1469 target_request(target
, request
);
1477 * Cortex-A8 target information and configuration
1480 static int cortex_a8_examine_first(struct target
*target
)
1482 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1483 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1484 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1486 int retval
= ERROR_OK
;
1487 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1491 /* Here we shall insert a proper ROM Table scan */
1492 armv7a
->debug_base
= OMAP3530_DEBUG_BASE
;
1494 /* We do one extra read to ensure DAP is configured,
1495 * we call ahbap_debugport_init(swjdp) instead
1497 ahbap_debugport_init(swjdp
);
1498 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
1499 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1500 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1502 LOG_DEBUG("Examine failed");
1506 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1507 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1509 LOG_DEBUG("Examine failed");
1513 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1514 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1516 LOG_DEBUG("Examine failed");
1520 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1521 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1523 LOG_DEBUG("Examine failed");
1527 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1528 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1529 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1530 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1532 /* Setup Breakpoint Register Pairs */
1533 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1534 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1535 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1536 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(struct cortex_a8_brp
));
1537 // cortex_a8->brb_enabled = ????;
1538 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1540 cortex_a8
->brp_list
[i
].used
= 0;
1541 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1542 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1544 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1545 cortex_a8
->brp_list
[i
].value
= 0;
1546 cortex_a8
->brp_list
[i
].control
= 0;
1547 cortex_a8
->brp_list
[i
].BRPn
= i
;
1550 /* Setup Watchpoint Register Pairs */
1551 cortex_a8
->wrp_num
= ((didr
>> 28) & 0x0F) + 1;
1552 cortex_a8
->wrp_num_available
= cortex_a8
->wrp_num
;
1553 cortex_a8
->wrp_list
= calloc(cortex_a8
->wrp_num
, sizeof(struct cortex_a8_wrp
));
1554 for (i
= 0; i
< cortex_a8
->wrp_num
; i
++)
1556 cortex_a8
->wrp_list
[i
].used
= 0;
1557 cortex_a8
->wrp_list
[i
].type
= 0;
1558 cortex_a8
->wrp_list
[i
].value
= 0;
1559 cortex_a8
->wrp_list
[i
].control
= 0;
1560 cortex_a8
->wrp_list
[i
].WRPn
= i
;
1562 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1563 cortex_a8
->brp_num
, cortex_a8
->wrp_num
);
1565 target_set_examined(target
);
1569 static int cortex_a8_examine(struct target
*target
)
1571 int retval
= ERROR_OK
;
1573 /* don't re-probe hardware after each reset */
1574 if (!target_was_examined(target
))
1575 retval
= cortex_a8_examine_first(target
);
1577 /* Configure core debug access */
1578 if (retval
== ERROR_OK
)
1579 retval
= cortex_a8_init_debug_access(target
);
1585 * Cortex-A8 target creation and initialization
1588 static void cortex_a8_build_reg_cache(struct target
*target
)
1590 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1591 struct arm
*armv4_5
= target_to_armv4_5(target
);
1593 armv4_5
->core_type
= ARM_MODE_MON
;
1595 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
1599 static int cortex_a8_init_target(struct command_context
*cmd_ctx
,
1600 struct target
*target
)
1602 cortex_a8_build_reg_cache(target
);
1606 static int cortex_a8_init_arch_info(struct target
*target
,
1607 struct cortex_a8_common
*cortex_a8
, struct jtag_tap
*tap
)
1609 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1610 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
1611 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1613 /* Setup struct cortex_a8_common */
1614 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1615 armv4_5
->arch_info
= armv7a
;
1617 /* prepare JTAG information for the new target */
1618 cortex_a8
->jtag_info
.tap
= tap
;
1619 cortex_a8
->jtag_info
.scann_size
= 4;
1621 swjdp
->dp_select_value
= -1;
1622 swjdp
->ap_csw_value
= -1;
1623 swjdp
->ap_tar_value
= -1;
1624 swjdp
->jtag_info
= &cortex_a8
->jtag_info
;
1625 swjdp
->memaccess_tck
= 80;
1627 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1628 swjdp
->tar_autoincr_block
= (1 << 10);
1630 cortex_a8
->fast_reg_read
= 0;
1633 /* register arch-specific functions */
1634 armv7a
->examine_debug_reason
= NULL
;
1636 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1638 armv7a
->pre_restore_context
= NULL
;
1639 armv7a
->post_restore_context
= NULL
;
1640 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1641 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1642 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_memory
;
1643 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_memory
;
1644 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1645 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1646 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1647 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1648 armv7a
->read_cp15
= cortex_a8_read_cp15
;
1649 armv7a
->write_cp15
= cortex_a8_write_cp15
;
1652 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1654 armv4_5
->read_core_reg
= cortex_a8_read_core_reg
;
1655 armv4_5
->write_core_reg
= cortex_a8_write_core_reg
;
1657 /* REVISIT v7a setup should be in a v7a-specific routine */
1658 armv4_5_init_arch_info(target
, armv4_5
);
1659 armv7a
->common_magic
= ARMV7_COMMON_MAGIC
;
1661 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1666 static int cortex_a8_target_create(struct target
*target
, Jim_Interp
*interp
)
1668 struct cortex_a8_common
*cortex_a8
= calloc(1, sizeof(struct cortex_a8_common
));
1670 cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1675 COMMAND_HANDLER(cortex_a8_handle_cache_info_command
)
1677 struct target
*target
= get_current_target(CMD_CTX
);
1678 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1680 return armv4_5_handle_cache_info_command(CMD_CTX
,
1681 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1685 COMMAND_HANDLER(cortex_a8_handle_dbginit_command
)
1687 struct target
*target
= get_current_target(CMD_CTX
);
1689 cortex_a8_init_debug_access(target
);
1695 static int cortex_a8_register_commands(struct command_context
*cmd_ctx
)
1697 struct command
*cortex_a8_cmd
;
1698 int retval
= ERROR_OK
;
1700 armv4_5_register_commands(cmd_ctx
);
1701 armv7a_register_commands(cmd_ctx
);
1703 cortex_a8_cmd
= register_command(cmd_ctx
, NULL
, "cortex_a8",
1705 "cortex_a8 specific commands");
1707 register_command(cmd_ctx
, cortex_a8_cmd
, "cache_info",
1708 cortex_a8_handle_cache_info_command
, COMMAND_EXEC
,
1709 "display information about target caches");
1711 register_command(cmd_ctx
, cortex_a8_cmd
, "dbginit",
1712 cortex_a8_handle_dbginit_command
, COMMAND_EXEC
,
1713 "Initialize core debug");
1718 struct target_type cortexa8_target
= {
1719 .name
= "cortex_a8",
1721 .poll
= cortex_a8_poll
,
1722 .arch_state
= armv7a_arch_state
,
1724 .target_request_data
= NULL
,
1726 .halt
= cortex_a8_halt
,
1727 .resume
= cortex_a8_resume
,
1728 .step
= cortex_a8_step
,
1730 .assert_reset
= cortex_a8_assert_reset
,
1731 .deassert_reset
= cortex_a8_deassert_reset
,
1732 .soft_reset_halt
= NULL
,
1734 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
1736 .read_memory
= cortex_a8_read_memory
,
1737 .write_memory
= cortex_a8_write_memory
,
1738 .bulk_write_memory
= cortex_a8_bulk_write_memory
,
1740 .checksum_memory
= arm_checksum_memory
,
1741 .blank_check_memory
= arm_blank_check_memory
,
1743 .run_algorithm
= armv4_5_run_algorithm
,
1745 .add_breakpoint
= cortex_a8_add_breakpoint
,
1746 .remove_breakpoint
= cortex_a8_remove_breakpoint
,
1747 .add_watchpoint
= NULL
,
1748 .remove_watchpoint
= NULL
,
1750 .register_commands
= cortex_a8_register_commands
,
1751 .target_create
= cortex_a8_target_create
,
1752 .init_target
= cortex_a8_init_target
,
1753 .examine
= cortex_a8_examine
,
1754 .mrc
= cortex_a8_mrc
,
1755 .mcr
= cortex_a8_mcr
,
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)