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 "cortex_a8.h"
40 #include "target_request.h"
41 #include "target_type.h"
44 int cortex_a8_register_commands(struct command_context_s
*cmd_ctx
);
46 /* forward declarations */
47 int cortex_a8_target_create(struct target_s
*target
, Jim_Interp
*interp
);
48 int cortex_a8_init_target(struct command_context_s
*cmd_ctx
,
49 struct target_s
*target
);
50 int cortex_a8_examine(struct target_s
*target
);
51 int cortex_a8_poll(target_t
*target
);
52 int cortex_a8_halt(target_t
*target
);
53 int cortex_a8_resume(struct target_s
*target
, int current
, uint32_t address
,
54 int handle_breakpoints
, int debug_execution
);
55 int cortex_a8_step(struct target_s
*target
, int current
, uint32_t address
,
56 int handle_breakpoints
);
57 int cortex_a8_debug_entry(target_t
*target
);
58 int cortex_a8_restore_context(target_t
*target
);
59 int cortex_a8_bulk_write_memory(target_t
*target
, uint32_t address
,
60 uint32_t count
, uint8_t *buffer
);
61 int cortex_a8_set_breakpoint(struct target_s
*target
,
62 breakpoint_t
*breakpoint
, uint8_t matchmode
);
63 int cortex_a8_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
64 int cortex_a8_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
65 int cortex_a8_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
66 int cortex_a8_dap_read_coreregister_u32(target_t
*target
,
67 uint32_t *value
, int regnum
);
68 int cortex_a8_dap_write_coreregister_u32(target_t
*target
,
69 uint32_t value
, int regnum
);
70 int cortex_a8_assert_reset(target_t
*target
);
71 int cortex_a8_deassert_reset(target_t
*target
);
73 target_type_t cortexa8_target
=
77 .poll
= cortex_a8_poll
,
78 .arch_state
= armv7a_arch_state
,
80 .target_request_data
= NULL
,
82 .halt
= cortex_a8_halt
,
83 .resume
= cortex_a8_resume
,
84 .step
= cortex_a8_step
,
87 .deassert_reset
= NULL
,
88 .soft_reset_halt
= NULL
,
90 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
92 .read_memory
= cortex_a8_read_memory
,
93 .write_memory
= cortex_a8_write_memory
,
94 .bulk_write_memory
= cortex_a8_bulk_write_memory
,
95 .checksum_memory
= arm7_9_checksum_memory
,
96 .blank_check_memory
= arm7_9_blank_check_memory
,
98 .run_algorithm
= armv4_5_run_algorithm
,
100 .add_breakpoint
= cortex_a8_add_breakpoint
,
101 .remove_breakpoint
= cortex_a8_remove_breakpoint
,
102 .add_watchpoint
= NULL
,
103 .remove_watchpoint
= NULL
,
105 .register_commands
= cortex_a8_register_commands
,
106 .target_create
= cortex_a8_target_create
,
107 .init_target
= cortex_a8_init_target
,
108 .examine
= cortex_a8_examine
,
113 * FIXME do topology discovery using the ROM; don't
114 * assume this is an OMAP3.
116 #define swjdp_memoryap 0
117 #define swjdp_debugap 1
118 #define OMAP3530_DEBUG_BASE 0x54011000
121 * Cortex-A8 Basic debug access, very low level assumes state is saved
123 int cortex_a8_init_debug_access(target_t
*target
)
125 /* get pointers to arch-specific information */
126 armv4_5_common_t
*armv4_5
= target
->arch_info
;
127 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
128 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
135 /* Unlocking the debug registers for modification */
136 /* The debugport might be uninitialised so try twice */
137 retval
= mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
138 if (retval
!= ERROR_OK
)
139 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
140 /* Clear Sticky Power Down status Bit in PRSR to enable access to
141 the registers in the Core Power Domain */
142 retval
= mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_PRSR
, &dummy
);
143 /* Enabling of instruction execution in debug mode is done in debug_entry code */
145 /* Resync breakpoint registers */
147 /* Since this is likley called from init or reset, update targtet state information*/
148 cortex_a8_poll(target
);
153 int cortex_a8_exec_opcode(target_t
*target
, uint32_t opcode
)
157 /* get pointers to arch-specific information */
158 armv4_5_common_t
*armv4_5
= target
->arch_info
;
159 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
160 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
162 LOG_DEBUG("exec opcode 0x%08" PRIx32
, opcode
);
165 retval
= mem_ap_read_atomic_u32(swjdp
,
166 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
167 if (retval
!= ERROR_OK
)
170 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
172 mem_ap_write_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_ITR
, opcode
);
176 retval
= mem_ap_read_atomic_u32(swjdp
,
177 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
178 if (retval
!= ERROR_OK
)
181 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
186 /**************************************************************************
187 Read core register with very few exec_opcode, fast but needs work_area.
188 This can cause problems with MMU active.
189 **************************************************************************/
190 int cortex_a8_read_regs_through_mem(target_t
*target
, uint32_t address
,
193 int retval
= ERROR_OK
;
194 /* get pointers to arch-specific information */
195 armv4_5_common_t
*armv4_5
= target
->arch_info
;
196 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
197 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
199 cortex_a8_dap_read_coreregister_u32(target
, regfile
, 0);
200 cortex_a8_dap_write_coreregister_u32(target
, address
, 0);
201 cortex_a8_exec_opcode(target
, ARMV4_5_STMIA(0, 0xFFFE, 0, 0));
202 dap_ap_select(swjdp
, swjdp_memoryap
);
203 mem_ap_read_buf_u32(swjdp
, (uint8_t *)(®file
[1]), 4*15, address
);
204 dap_ap_select(swjdp
, swjdp_debugap
);
209 int cortex_a8_read_cp(target_t
*target
, uint32_t *value
, uint8_t CP
,
210 uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
213 /* get pointers to arch-specific information */
214 armv4_5_common_t
*armv4_5
= target
->arch_info
;
215 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
216 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
218 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(CP
, op1
, 0, CRn
, CRm
, op2
));
219 /* Move R0 to DTRTX */
220 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
223 retval
= mem_ap_read_atomic_u32(swjdp
,
224 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
229 int cortex_a8_write_cp(target_t
*target
, uint32_t value
,
230 uint8_t CP
, uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
233 /* get pointers to arch-specific information */
234 armv4_5_common_t
*armv4_5
= target
->arch_info
;
235 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
236 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
238 retval
= mem_ap_write_u32(swjdp
,
239 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
240 /* Move DTRRX to r0 */
241 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
243 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(CP
, op1
, 0, CRn
, CRm
, op2
));
247 int cortex_a8_read_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
248 uint32_t CRn
, uint32_t CRm
, uint32_t *value
)
250 return cortex_a8_read_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
253 int cortex_a8_write_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
254 uint32_t CRn
, uint32_t CRm
, uint32_t value
)
256 return cortex_a8_write_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
259 int cortex_a8_dap_read_coreregister_u32(target_t
*target
,
260 uint32_t *value
, int regnum
)
262 int retval
= ERROR_OK
;
263 uint8_t reg
= regnum
&0xFF;
266 /* get pointers to arch-specific information */
267 armv4_5_common_t
*armv4_5
= target
->arch_info
;
268 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
269 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
276 /* Rn to DCCTX, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
277 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, reg
, 0, 5, 0));
281 cortex_a8_exec_opcode(target
, 0xE1A0000F);
282 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
286 cortex_a8_exec_opcode(target
, ARMV4_5_MRS(0, 0));
287 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
293 retval
= mem_ap_read_atomic_u32(swjdp
,
294 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
296 while ((dscr
& (1 << DSCR_DTR_TX_FULL
)) == 0); /* Wait for DTRRXfull */
298 retval
= mem_ap_read_atomic_u32(swjdp
,
299 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
304 int cortex_a8_dap_write_coreregister_u32(target_t
*target
, uint32_t value
, int regnum
)
306 int retval
= ERROR_OK
;
307 uint8_t Rd
= regnum
&0xFF;
309 /* get pointers to arch-specific information */
310 armv4_5_common_t
*armv4_5
= target
->arch_info
;
311 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
312 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
318 retval
= mem_ap_write_u32(swjdp
,
319 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
323 /* DCCRX to Rd, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
324 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, Rd
, 0, 5, 0));
328 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
329 cortex_a8_exec_opcode(target
, 0xE1A0F000);
333 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
334 cortex_a8_exec_opcode(target
, ARMV4_5_MSR_GP(0, 0xF, 0));
335 /* Execute a PrefetchFlush instruction through the ITR. */
336 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(15, 0, 0, 7, 5, 4));
342 /* Write to memory mapped registers directly with no cache or mmu handling */
343 int cortex_a8_dap_write_memap_register_u32(target_t
*target
, uint32_t address
, uint32_t value
)
347 /* get pointers to arch-specific information */
348 armv4_5_common_t
*armv4_5
= target
->arch_info
;
349 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
350 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
352 retval
= mem_ap_write_atomic_u32(swjdp
, address
, value
);
358 * Cortex-A8 Run control
361 int cortex_a8_poll(target_t
*target
)
363 int retval
= ERROR_OK
;
365 /* get pointers to arch-specific information */
366 armv4_5_common_t
*armv4_5
= target
->arch_info
;
367 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
368 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
369 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
372 enum target_state prev_target_state
= target
->state
;
374 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
375 dap_ap_select(swjdp
, swjdp_debugap
);
376 retval
= mem_ap_read_atomic_u32(swjdp
,
377 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
378 if (retval
!= ERROR_OK
)
380 dap_ap_select(swjdp
, saved_apsel
);
383 cortex_a8
->cpudbg_dscr
= dscr
;
385 if ((dscr
& 0x3) == 0x3)
387 if (prev_target_state
!= TARGET_HALTED
)
389 /* We have a halting debug event */
390 LOG_DEBUG("Target halted");
391 target
->state
= TARGET_HALTED
;
392 if ((prev_target_state
== TARGET_RUNNING
)
393 || (prev_target_state
== TARGET_RESET
))
395 retval
= cortex_a8_debug_entry(target
);
396 if (retval
!= ERROR_OK
)
399 target_call_event_callbacks(target
,
400 TARGET_EVENT_HALTED
);
402 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
406 retval
= cortex_a8_debug_entry(target
);
407 if (retval
!= ERROR_OK
)
410 target_call_event_callbacks(target
,
411 TARGET_EVENT_DEBUG_HALTED
);
415 else if ((dscr
& 0x3) == 0x2)
417 target
->state
= TARGET_RUNNING
;
421 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32
, dscr
);
422 target
->state
= TARGET_UNKNOWN
;
425 dap_ap_select(swjdp
, saved_apsel
);
430 int cortex_a8_halt(target_t
*target
)
432 int retval
= ERROR_OK
;
435 /* get pointers to arch-specific information */
436 armv4_5_common_t
*armv4_5
= target
->arch_info
;
437 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
438 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
440 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
441 dap_ap_select(swjdp
, swjdp_debugap
);
444 * Tell the core to be halted by writing DRCR with 0x1
445 * and then wait for the core to be halted.
447 retval
= mem_ap_write_atomic_u32(swjdp
,
448 armv7a
->debug_base
+ CPUDBG_DRCR
, 0x1);
451 * enter halting debug mode
453 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
454 retval
= mem_ap_write_atomic_u32(swjdp
,
455 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
| (1 << DSCR_HALT_DBG_MODE
));
457 if (retval
!= ERROR_OK
)
461 mem_ap_read_atomic_u32(swjdp
,
462 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
463 } while ((dscr
& (1 << DSCR_CORE_HALTED
)) == 0);
465 target
->debug_reason
= DBG_REASON_DBGRQ
;
468 dap_ap_select(swjdp
, saved_apsel
);
472 int cortex_a8_resume(struct target_s
*target
, int current
,
473 uint32_t address
, int handle_breakpoints
, int debug_execution
)
475 /* get pointers to arch-specific information */
476 armv4_5_common_t
*armv4_5
= target
->arch_info
;
477 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
478 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
480 // breakpoint_t *breakpoint = NULL;
481 uint32_t resume_pc
, dscr
;
483 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
484 dap_ap_select(swjdp
, swjdp_debugap
);
486 if (!debug_execution
)
488 target_free_all_working_areas(target
);
489 // cortex_m3_enable_breakpoints(target);
490 // cortex_m3_enable_watchpoints(target);
496 /* Disable interrupts */
497 /* We disable interrupts in the PRIMASK register instead of
498 * masking with C_MASKINTS,
499 * This is probably the same issue as Cortex-M3 Errata 377493:
500 * C_MASKINTS in parallel with disabled interrupts can cause
501 * local faults to not be taken. */
502 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
503 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
504 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
506 /* Make sure we are in Thumb mode */
507 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
508 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
509 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
510 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
514 /* current = 1: continue on current pc, otherwise continue at <address> */
515 resume_pc
= buf_get_u32(
516 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
517 armv4_5
->core_mode
, 15).value
,
522 /* Make sure that the Armv7 gdb thumb fixups does not
523 * kill the return address
525 if (armv7a
->core_state
== ARMV7A_STATE_ARM
)
527 resume_pc
&= 0xFFFFFFFC;
529 /* When the return address is loaded into PC
530 * bit 0 must be 1 to stay in Thumb state
532 if (armv7a
->core_state
== ARMV7A_STATE_THUMB
)
536 LOG_DEBUG("resume pc = 0x%08" PRIx32
, resume_pc
);
537 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
538 armv4_5
->core_mode
, 15).value
,
540 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
541 armv4_5
->core_mode
, 15).dirty
= 1;
542 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
543 armv4_5
->core_mode
, 15).valid
= 1;
545 cortex_a8_restore_context(target
);
546 // arm7_9_restore_context(target); TODO Context is currently NOT Properly restored
548 /* the front-end may request us not to handle breakpoints */
549 if (handle_breakpoints
)
551 /* Single step past breakpoint at current address */
552 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
554 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
555 cortex_m3_unset_breakpoint(target
, breakpoint
);
556 cortex_m3_single_step_core(target
);
557 cortex_m3_set_breakpoint(target
, breakpoint
);
562 /* Restart core and wait for it to be started */
563 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DRCR
, 0x2);
566 mem_ap_read_atomic_u32(swjdp
,
567 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
568 } while ((dscr
& (1 << DSCR_CORE_RESTARTED
)) == 0);
570 target
->debug_reason
= DBG_REASON_NOTHALTED
;
571 target
->state
= TARGET_RUNNING
;
573 /* registers are now invalid */
574 armv4_5_invalidate_core_regs(target
);
576 if (!debug_execution
)
578 target
->state
= TARGET_RUNNING
;
579 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
580 LOG_DEBUG("target resumed at 0x%" PRIx32
, resume_pc
);
584 target
->state
= TARGET_DEBUG_RUNNING
;
585 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
586 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, resume_pc
);
589 dap_ap_select(swjdp
, saved_apsel
);
594 int cortex_a8_debug_entry(target_t
*target
)
597 uint32_t regfile
[16], pc
, cpsr
, dscr
;
598 int retval
= ERROR_OK
;
599 working_area_t
*regfile_working_area
= NULL
;
601 /* get pointers to arch-specific information */
602 armv4_5_common_t
*armv4_5
= target
->arch_info
;
603 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
604 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
605 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
607 if (armv7a
->pre_debug_entry
)
608 armv7a
->pre_debug_entry(target
);
610 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
612 /* Enable the ITR execution once we are in debug mode */
613 mem_ap_read_atomic_u32(swjdp
,
614 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
615 dscr
|= (1 << DSCR_EXT_INT_EN
);
616 retval
= mem_ap_write_atomic_u32(swjdp
,
617 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
);
619 /* Examine debug reason */
620 switch ((cortex_a8
->cpudbg_dscr
>> 2)&0xF)
624 target
->debug_reason
= DBG_REASON_DBGRQ
;
628 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
631 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
634 target
->debug_reason
= DBG_REASON_UNDEFINED
;
638 /* Examine target state and mode */
639 if (cortex_a8
->fast_reg_read
)
640 target_alloc_working_area(target
, 64, ®file_working_area
);
642 /* First load register acessible through core debug port*/
643 if (!regfile_working_area
)
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 cortex_a8_dap_read_coreregister_u32(target
, &cpsr
, 16);
660 dap_ap_select(swjdp
, swjdp_debugap
);
661 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
663 armv4_5
->core_mode
= cpsr
& 0x1F;
664 armv7a
->core_state
= (cpsr
& 0x20)?ARMV7A_STATE_THUMB
:ARMV7A_STATE_ARM
;
666 for (i
= 0; i
<= ARM_PC
; i
++)
668 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
669 armv4_5
->core_mode
, i
).value
,
671 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
672 armv4_5
->core_mode
, i
).valid
= 1;
673 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
674 armv4_5
->core_mode
, i
).dirty
= 0;
676 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
677 armv4_5
->core_mode
, 16).value
,
679 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
680 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
682 /* Fixup PC Resume Address */
683 if (armv7a
->core_state
== ARMV7A_STATE_THUMB
)
685 // T bit set for Thumb or ThumbEE state
686 regfile
[ARM_PC
] -= 4;
691 regfile
[ARM_PC
] -= 8;
693 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
694 armv4_5
->core_mode
, ARM_PC
).value
,
695 0, 32, regfile
[ARM_PC
]);
697 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 0)
698 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
699 armv4_5
->core_mode
, 0).valid
;
700 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 15)
701 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
702 armv4_5
->core_mode
, 15).valid
;
705 /* TODO, Move this */
706 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
707 cortex_a8_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
708 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
710 cortex_a8_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
711 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
713 cortex_a8_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
714 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
717 /* Are we in an exception handler */
718 // armv4_5->exception_number = 0;
719 if (armv7a
->post_debug_entry
)
720 armv7a
->post_debug_entry(target
);
728 void cortex_a8_post_debug_entry(target_t
*target
)
730 /* get pointers to arch-specific information */
731 armv4_5_common_t
*armv4_5
= target
->arch_info
;
732 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
733 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
735 // cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
736 /* examine cp15 control reg */
737 armv7a
->read_cp15(target
, 0, 0, 1, 0, &cortex_a8
->cp15_control_reg
);
738 jtag_execute_queue();
739 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
741 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
743 uint32_t cache_type_reg
;
744 /* identify caches */
745 armv7a
->read_cp15(target
, 0, 1, 0, 0, &cache_type_reg
);
746 jtag_execute_queue();
747 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
748 armv4_5_identify_cache(cache_type_reg
,
749 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
752 armv7a
->armv4_5_mmu
.mmu_enabled
=
753 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
754 armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
=
755 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
756 armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
=
757 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
762 int cortex_a8_step(struct target_s
*target
, int current
, uint32_t address
,
763 int handle_breakpoints
)
765 /* get pointers to arch-specific information */
766 armv4_5_common_t
*armv4_5
= target
->arch_info
;
767 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
768 breakpoint_t
*breakpoint
= NULL
;
769 breakpoint_t stepbreakpoint
;
773 if (target
->state
!= TARGET_HALTED
)
775 LOG_WARNING("target not halted");
776 return ERROR_TARGET_NOT_HALTED
;
779 /* current = 1: continue on current pc, otherwise continue at <address> */
782 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
783 armv4_5
->core_mode
, ARM_PC
).value
,
788 address
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
789 armv4_5
->core_mode
, ARM_PC
).value
,
793 /* The front-end may request us not to handle breakpoints.
794 * But since Cortex-A8 uses breakpoint for single step,
795 * we MUST handle breakpoints.
797 handle_breakpoints
= 1;
798 if (handle_breakpoints
) {
799 breakpoint
= breakpoint_find(target
,
800 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
801 armv4_5
->core_mode
, 15).value
,
804 cortex_a8_unset_breakpoint(target
, breakpoint
);
807 /* Setup single step breakpoint */
808 stepbreakpoint
.address
= address
;
809 stepbreakpoint
.length
= (armv7a
->core_state
== ARMV7A_STATE_THUMB
) ? 2 : 4;
810 stepbreakpoint
.type
= BKPT_HARD
;
811 stepbreakpoint
.set
= 0;
813 /* Break on IVA mismatch */
814 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
816 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
818 cortex_a8_resume(target
, 1, address
, 0, 0);
820 while (target
->state
!= TARGET_HALTED
)
822 cortex_a8_poll(target
);
825 LOG_WARNING("timeout waiting for target halt");
830 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
831 if (timeout
> 0) target
->debug_reason
= DBG_REASON_BREAKPOINT
;
834 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
836 if (target
->state
!= TARGET_HALTED
)
837 LOG_DEBUG("target stepped");
842 int cortex_a8_restore_context(target_t
*target
)
847 /* get pointers to arch-specific information */
848 armv4_5_common_t
*armv4_5
= target
->arch_info
;
849 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
853 if (armv7a
->pre_restore_context
)
854 armv7a
->pre_restore_context(target
);
856 for (i
= 15; i
>= 0; i
--)
858 if (ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
859 armv4_5
->core_mode
, i
).dirty
)
861 value
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
862 armv4_5
->core_mode
, i
).value
,
864 /* TODO Check return values */
865 cortex_a8_dap_write_coreregister_u32(target
, value
, i
);
869 if (armv7a
->post_restore_context
)
870 armv7a
->post_restore_context(target
);
877 * Cortex-A8 Core register functions
880 int cortex_a8_load_core_reg_u32(struct target_s
*target
, int num
,
881 armv4_5_mode_t mode
, uint32_t * value
)
884 /* get pointers to arch-specific information */
885 armv4_5_common_t
*armv4_5
= target
->arch_info
;
887 if ((num
<= ARM_CPSR
))
889 /* read a normal core register */
890 retval
= cortex_a8_dap_read_coreregister_u32(target
, value
, num
);
892 if (retval
!= ERROR_OK
)
894 LOG_ERROR("JTAG failure %i", retval
);
895 return ERROR_JTAG_DEVICE_ERROR
;
897 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
, num
, *value
);
901 return ERROR_INVALID_ARGUMENTS
;
904 /* Register other than r0 - r14 uses r0 for access */
906 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
907 armv4_5
->core_mode
, 0).dirty
=
908 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
909 armv4_5
->core_mode
, 0).valid
;
910 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
911 armv4_5
->core_mode
, 15).dirty
=
912 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
913 armv4_5
->core_mode
, 15).valid
;
918 int cortex_a8_store_core_reg_u32(struct target_s
*target
, int num
,
919 armv4_5_mode_t mode
, uint32_t value
)
924 /* get pointers to arch-specific information */
925 armv4_5_common_t
*armv4_5
= target
->arch_info
;
927 #ifdef ARMV7_GDB_HACKS
928 /* If the LR register is being modified, make sure it will put us
929 * in "thumb" mode, or an INVSTATE exception will occur. This is a
930 * hack to deal with the fact that gdb will sometimes "forge"
931 * return addresses, and doesn't set the LSB correctly (i.e., when
932 * printing expressions containing function calls, it sets LR=0.) */
938 if ((num
<= ARM_CPSR
))
940 retval
= cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
941 if (retval
!= ERROR_OK
)
943 LOG_ERROR("JTAG failure %i", retval
);
944 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
945 armv4_5
->core_mode
, num
).dirty
=
946 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
947 armv4_5
->core_mode
, num
).valid
;
948 return ERROR_JTAG_DEVICE_ERROR
;
950 LOG_DEBUG("write core reg %i value 0x%" PRIx32
, num
, value
);
954 return ERROR_INVALID_ARGUMENTS
;
961 int cortex_a8_read_core_reg(struct target_s
*target
, int num
,
962 enum armv4_5_mode mode
)
966 armv4_5_common_t
*armv4_5
= target
->arch_info
;
967 cortex_a8_dap_read_coreregister_u32(target
, &value
, num
);
969 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
974 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
975 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
976 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
977 mode
, num
).value
, 0, 32, value
);
982 int cortex_a8_write_core_reg(struct target_s
*target
, int num
,
983 enum armv4_5_mode mode
, uint32_t value
)
986 armv4_5_common_t
*armv4_5
= target
->arch_info
;
988 cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
989 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
994 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
995 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
1002 * Cortex-A8 Breakpoint and watchpoint fuctions
1005 /* Setup hardware Breakpoint Register Pair */
1006 int cortex_a8_set_breakpoint(struct target_s
*target
,
1007 breakpoint_t
*breakpoint
, uint8_t matchmode
)
1012 uint8_t byte_addr_select
= 0x0F;
1015 /* get pointers to arch-specific information */
1016 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1017 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1018 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1019 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
1021 if (breakpoint
->set
)
1023 LOG_WARNING("breakpoint already set");
1027 if (breakpoint
->type
== BKPT_HARD
)
1029 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
1031 if (brp_i
>= cortex_a8
->brp_num
)
1033 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1036 breakpoint
->set
= brp_i
+ 1;
1037 if (breakpoint
->length
== 2)
1039 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1041 control
= ((matchmode
& 0x7) << 20)
1042 | (byte_addr_select
<< 5)
1044 brp_list
[brp_i
].used
= 1;
1045 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1046 brp_list
[brp_i
].control
= control
;
1047 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1048 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1049 brp_list
[brp_i
].value
);
1050 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1051 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1052 brp_list
[brp_i
].control
);
1053 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1054 brp_list
[brp_i
].control
,
1055 brp_list
[brp_i
].value
);
1057 else if (breakpoint
->type
== BKPT_SOFT
)
1060 if (breakpoint
->length
== 2)
1062 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1066 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1068 retval
= target
->type
->read_memory(target
,
1069 breakpoint
->address
& 0xFFFFFFFE,
1070 breakpoint
->length
, 1,
1071 breakpoint
->orig_instr
);
1072 if (retval
!= ERROR_OK
)
1074 retval
= target
->type
->write_memory(target
,
1075 breakpoint
->address
& 0xFFFFFFFE,
1076 breakpoint
->length
, 1, code
);
1077 if (retval
!= ERROR_OK
)
1079 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1085 int cortex_a8_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1088 /* get pointers to arch-specific information */
1089 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1090 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1091 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1092 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
1094 if (!breakpoint
->set
)
1096 LOG_WARNING("breakpoint not set");
1100 if (breakpoint
->type
== BKPT_HARD
)
1102 int brp_i
= breakpoint
->set
- 1;
1103 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1105 LOG_DEBUG("Invalid BRP number in breakpoint");
1108 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1109 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1110 brp_list
[brp_i
].used
= 0;
1111 brp_list
[brp_i
].value
= 0;
1112 brp_list
[brp_i
].control
= 0;
1113 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1114 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1115 brp_list
[brp_i
].control
);
1116 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1117 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1118 brp_list
[brp_i
].value
);
1122 /* restore original instruction (kept in target endianness) */
1123 if (breakpoint
->length
== 4)
1125 retval
= target
->type
->write_memory(target
,
1126 breakpoint
->address
& 0xFFFFFFFE,
1127 4, 1, breakpoint
->orig_instr
);
1128 if (retval
!= ERROR_OK
)
1133 retval
= target
->type
->write_memory(target
,
1134 breakpoint
->address
& 0xFFFFFFFE,
1135 2, 1, breakpoint
->orig_instr
);
1136 if (retval
!= ERROR_OK
)
1140 breakpoint
->set
= 0;
1145 int cortex_a8_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1147 /* get pointers to arch-specific information */
1148 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1149 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1150 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1152 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1154 LOG_INFO("no hardware breakpoint available");
1155 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1158 if (breakpoint
->type
== BKPT_HARD
)
1159 cortex_a8
->brp_num_available
--;
1160 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1165 int cortex_a8_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1167 /* get pointers to arch-specific information */
1168 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1169 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1170 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1173 /* It is perfectly possible to remove brakpoints while the taget is running */
1174 if (target
->state
!= TARGET_HALTED
)
1176 LOG_WARNING("target not halted");
1177 return ERROR_TARGET_NOT_HALTED
;
1181 if (breakpoint
->set
)
1183 cortex_a8_unset_breakpoint(target
, breakpoint
);
1184 if (breakpoint
->type
== BKPT_HARD
)
1185 cortex_a8
->brp_num_available
++ ;
1195 * Cortex-A8 Reset fuctions
1198 int cortex_a8_assert_reset(target_t
*target
)
1203 /* registers are now invalid */
1204 armv4_5_invalidate_core_regs(target
);
1206 target
->state
= TARGET_RESET
;
1211 int cortex_a8_deassert_reset(target_t
*target
)
1216 if (target
->reset_halt
)
1219 if ((retval
= target_halt(target
)) != ERROR_OK
)
1227 * Cortex-A8 Memory access
1229 * This is same Cortex M3 but we must also use the correct
1230 * ap number for every access.
1233 int cortex_a8_read_memory(struct target_s
*target
, uint32_t address
,
1234 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1236 /* get pointers to arch-specific information */
1237 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1238 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1239 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1241 int retval
= ERROR_OK
;
1243 /* sanitize arguments */
1244 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1245 return ERROR_INVALID_ARGUMENTS
;
1247 /* cortex_a8 handles unaligned memory access */
1249 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1254 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1257 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1260 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1263 LOG_ERROR("BUG: we shouldn't get here");
1270 int cortex_a8_write_memory(struct target_s
*target
, uint32_t address
,
1271 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1273 /* get pointers to arch-specific information */
1274 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1275 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1276 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1280 /* sanitize arguments */
1281 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1282 return ERROR_INVALID_ARGUMENTS
;
1284 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1289 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1292 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1295 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1298 LOG_ERROR("BUG: we shouldn't get here");
1302 /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */
1303 /* invalidate I-Cache */
1304 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
1306 /* Invalidate ICache single entry with MVA, repeat this for all cache
1307 lines in the address range, Cortex-A8 has fixed 64 byte line length */
1308 /* Invalidate Cache single entry with MVA to PoU */
1309 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1310 armv7a
->write_cp15(target
, 0, 1, 7, 5, cacheline
); /* I-Cache to PoU */
1312 /* invalidate D-Cache */
1313 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
1315 /* Invalidate Cache single entry with MVA to PoC */
1316 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1317 armv7a
->write_cp15(target
, 0, 1, 7, 6, cacheline
); /* U/D cache to PoC */
1323 int cortex_a8_bulk_write_memory(target_t
*target
, uint32_t address
,
1324 uint32_t count
, uint8_t *buffer
)
1326 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1330 int cortex_a8_dcc_read(swjdp_common_t
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1335 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1336 *ctrl
= (uint8_t)dcrdr
;
1337 *value
= (uint8_t)(dcrdr
>> 8);
1339 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1341 /* write ack back to software dcc register
1342 * signify we have read data */
1343 if (dcrdr
& (1 << 0))
1346 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1353 int cortex_a8_handle_target_request(void *priv
)
1355 target_t
*target
= priv
;
1356 if (!target
->type
->examined
)
1358 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1359 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1360 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1363 if (!target
->dbg_msg_enabled
)
1366 if (target
->state
== TARGET_RUNNING
)
1371 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1373 /* check if we have data */
1374 if (ctrl
& (1 << 0))
1378 /* we assume target is quick enough */
1380 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1381 request
|= (data
<< 8);
1382 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1383 request
|= (data
<< 16);
1384 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1385 request
|= (data
<< 24);
1386 target_request(target
, request
);
1394 * Cortex-A8 target information and configuration
1397 int cortex_a8_examine(struct target_s
*target
)
1399 /* get pointers to arch-specific information */
1400 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1401 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1402 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1403 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1407 int retval
= ERROR_OK
;
1408 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1412 /* Here we shall insert a proper ROM Table scan */
1413 armv7a
->debug_base
= OMAP3530_DEBUG_BASE
;
1415 /* We do one extra read to ensure DAP is configured,
1416 * we call ahbap_debugport_init(swjdp) instead
1418 ahbap_debugport_init(swjdp
);
1419 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
1420 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1421 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1423 LOG_DEBUG("Examine failed");
1427 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1428 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1430 LOG_DEBUG("Examine failed");
1434 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1435 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1437 LOG_DEBUG("Examine failed");
1441 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1442 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1444 LOG_DEBUG("Examine failed");
1448 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1449 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1450 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1451 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1453 /* Setup Breakpoint Register Pairs */
1454 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1455 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1456 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1457 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(cortex_a8_brp_t
));
1458 // cortex_a8->brb_enabled = ????;
1459 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1461 cortex_a8
->brp_list
[i
].used
= 0;
1462 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1463 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1465 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1466 cortex_a8
->brp_list
[i
].value
= 0;
1467 cortex_a8
->brp_list
[i
].control
= 0;
1468 cortex_a8
->brp_list
[i
].BRPn
= i
;
1471 /* Setup Watchpoint Register Pairs */
1472 cortex_a8
->wrp_num
= ((didr
>> 28) & 0x0F) + 1;
1473 cortex_a8
->wrp_num_available
= cortex_a8
->wrp_num
;
1474 cortex_a8
->wrp_list
= calloc(cortex_a8
->wrp_num
, sizeof(cortex_a8_wrp_t
));
1475 for (i
= 0; i
< cortex_a8
->wrp_num
; i
++)
1477 cortex_a8
->wrp_list
[i
].used
= 0;
1478 cortex_a8
->wrp_list
[i
].type
= 0;
1479 cortex_a8
->wrp_list
[i
].value
= 0;
1480 cortex_a8
->wrp_list
[i
].control
= 0;
1481 cortex_a8
->wrp_list
[i
].WRPn
= i
;
1483 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1484 cortex_a8
->brp_num
, cortex_a8
->wrp_num
);
1486 /* Configure core debug access */
1487 cortex_a8_init_debug_access(target
);
1489 target
->type
->examined
= 1;
1495 * Cortex-A8 target creation and initialization
1498 void cortex_a8_build_reg_cache(target_t
*target
)
1500 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1501 /* get pointers to arch-specific information */
1502 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1504 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
1505 armv4_5
->core_cache
= (*cache_p
);
1509 int cortex_a8_init_target(struct command_context_s
*cmd_ctx
,
1510 struct target_s
*target
)
1512 cortex_a8_build_reg_cache(target
);
1516 int cortex_a8_init_arch_info(target_t
*target
,
1517 cortex_a8_common_t
*cortex_a8
, jtag_tap_t
*tap
)
1519 armv4_5_common_t
*armv4_5
;
1520 armv7a_common_t
*armv7a
;
1522 armv7a
= &cortex_a8
->armv7a_common
;
1523 armv4_5
= &armv7a
->armv4_5_common
;
1524 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1526 /* Setup cortex_a8_common_t */
1527 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1528 cortex_a8
->arch_info
= NULL
;
1529 armv7a
->arch_info
= cortex_a8
;
1530 armv4_5
->arch_info
= armv7a
;
1532 armv4_5_init_arch_info(target
, armv4_5
);
1534 /* prepare JTAG information for the new target */
1535 cortex_a8
->jtag_info
.tap
= tap
;
1536 cortex_a8
->jtag_info
.scann_size
= 4;
1538 swjdp
->dp_select_value
= -1;
1539 swjdp
->ap_csw_value
= -1;
1540 swjdp
->ap_tar_value
= -1;
1541 swjdp
->jtag_info
= &cortex_a8
->jtag_info
;
1542 swjdp
->memaccess_tck
= 80;
1544 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1545 swjdp
->tar_autoincr_block
= (1 << 10);
1547 cortex_a8
->fast_reg_read
= 0;
1550 /* register arch-specific functions */
1551 armv7a
->examine_debug_reason
= NULL
;
1553 armv7a
->pre_debug_entry
= NULL
;
1554 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1556 armv7a
->pre_restore_context
= NULL
;
1557 armv7a
->post_restore_context
= NULL
;
1558 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1559 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1560 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_memory
;
1561 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_memory
;
1562 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1563 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1564 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1565 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1566 armv7a
->read_cp15
= cortex_a8_read_cp15
;
1567 armv7a
->write_cp15
= cortex_a8_write_cp15
;
1570 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1572 armv4_5
->read_core_reg
= cortex_a8_read_core_reg
;
1573 armv4_5
->write_core_reg
= cortex_a8_write_core_reg
;
1574 // armv4_5->full_context = arm7_9_full_context;
1576 // armv4_5->load_core_reg_u32 = cortex_a8_load_core_reg_u32;
1577 // armv4_5->store_core_reg_u32 = cortex_a8_store_core_reg_u32;
1578 // armv4_5->read_core_reg = armv4_5_read_core_reg; /* this is default */
1579 // armv4_5->write_core_reg = armv4_5_write_core_reg;
1581 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1586 int cortex_a8_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1588 cortex_a8_common_t
*cortex_a8
= calloc(1, sizeof(cortex_a8_common_t
));
1590 cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1595 static int cortex_a8_handle_cache_info_command(struct command_context_s
*cmd_ctx
,
1596 char *cmd
, char **args
, int argc
)
1598 target_t
*target
= get_current_target(cmd_ctx
);
1599 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1600 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1602 return armv4_5_handle_cache_info_command(cmd_ctx
,
1603 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1607 static int cortex_a8_handle_dbginit_command(struct command_context_s
*cmd_ctx
,
1608 char *cmd
, char **args
, int argc
)
1610 target_t
*target
= get_current_target(cmd_ctx
);
1612 cortex_a8_init_debug_access(target
);
1618 int cortex_a8_register_commands(struct command_context_s
*cmd_ctx
)
1620 command_t
*cortex_a8_cmd
;
1621 int retval
= ERROR_OK
;
1623 armv4_5_register_commands(cmd_ctx
);
1624 armv7a_register_commands(cmd_ctx
);
1626 cortex_a8_cmd
= register_command(cmd_ctx
, NULL
, "cortex_a8",
1628 "cortex_a8 specific commands");
1630 register_command(cmd_ctx
, cortex_a8_cmd
, "cache_info",
1631 cortex_a8_handle_cache_info_command
, COMMAND_EXEC
,
1632 "display information about target caches");
1634 register_command(cmd_ctx
, cortex_a8_cmd
, "dbginit",
1635 cortex_a8_handle_dbginit_command
, COMMAND_EXEC
,
1636 "Initialize core debug");
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)