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
);
71 target_type_t cortexa8_target
=
75 .poll
= cortex_a8_poll
,
76 .arch_state
= armv7a_arch_state
,
78 .target_request_data
= NULL
,
80 .halt
= cortex_a8_halt
,
81 .resume
= cortex_a8_resume
,
82 .step
= cortex_a8_step
,
85 .deassert_reset
= NULL
,
86 .soft_reset_halt
= NULL
,
88 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
90 .read_memory
= cortex_a8_read_memory
,
91 .write_memory
= cortex_a8_write_memory
,
92 .bulk_write_memory
= cortex_a8_bulk_write_memory
,
93 .checksum_memory
= arm7_9_checksum_memory
,
94 .blank_check_memory
= arm7_9_blank_check_memory
,
96 .run_algorithm
= armv4_5_run_algorithm
,
98 .add_breakpoint
= cortex_a8_add_breakpoint
,
99 .remove_breakpoint
= cortex_a8_remove_breakpoint
,
100 .add_watchpoint
= NULL
,
101 .remove_watchpoint
= NULL
,
103 .register_commands
= cortex_a8_register_commands
,
104 .target_create
= cortex_a8_target_create
,
105 .init_target
= cortex_a8_init_target
,
106 .examine
= cortex_a8_examine
,
111 * FIXME do topology discovery using the ROM; don't
112 * assume this is an OMAP3.
114 #define swjdp_memoryap 0
115 #define swjdp_debugap 1
116 #define OMAP3530_DEBUG_BASE 0x54011000
119 * Cortex-A8 Basic debug access, very low level assumes state is saved
121 int cortex_a8_init_debug_access(target_t
*target
)
123 /* get pointers to arch-specific information */
124 armv4_5_common_t
*armv4_5
= target
->arch_info
;
125 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
126 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
133 /* Unlocking the debug registers for modification */
134 /* The debugport might be uninitialised so try twice */
135 retval
= mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
136 if (retval
!= ERROR_OK
)
137 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
138 /* Clear Sticky Power Down status Bit in PRSR to enable access to
139 the registers in the Core Power Domain */
140 retval
= mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_PRSR
, &dummy
);
141 /* Enabling of instruction execution in debug mode is done in debug_entry code */
146 int cortex_a8_exec_opcode(target_t
*target
, uint32_t opcode
)
150 /* get pointers to arch-specific information */
151 armv4_5_common_t
*armv4_5
= target
->arch_info
;
152 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
153 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
155 LOG_DEBUG("exec opcode 0x%08" PRIx32
, opcode
);
158 retval
= mem_ap_read_atomic_u32(swjdp
,
159 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
160 if (retval
!= ERROR_OK
)
163 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
165 mem_ap_write_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_ITR
, opcode
);
169 retval
= mem_ap_read_atomic_u32(swjdp
,
170 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
171 if (retval
!= ERROR_OK
)
174 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
179 /**************************************************************************
180 Read core register with very few exec_opcode, fast but needs work_area.
181 This can cause problems with MMU active.
182 **************************************************************************/
183 int cortex_a8_read_regs_through_mem(target_t
*target
, uint32_t address
,
186 int retval
= ERROR_OK
;
187 /* get pointers to arch-specific information */
188 armv4_5_common_t
*armv4_5
= target
->arch_info
;
189 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
190 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
192 cortex_a8_dap_read_coreregister_u32(target
, regfile
, 0);
193 cortex_a8_dap_write_coreregister_u32(target
, address
, 0);
194 cortex_a8_exec_opcode(target
, ARMV4_5_STMIA(0, 0xFFFE, 0, 0));
195 dap_ap_select(swjdp
, swjdp_memoryap
);
196 mem_ap_read_buf_u32(swjdp
, (uint8_t *)(®file
[1]), 4*15, address
);
197 dap_ap_select(swjdp
, swjdp_debugap
);
202 int cortex_a8_read_cp(target_t
*target
, uint32_t *value
, uint8_t CP
,
203 uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
206 /* get pointers to arch-specific information */
207 armv4_5_common_t
*armv4_5
= target
->arch_info
;
208 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
209 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
211 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(CP
, op1
, 0, CRn
, CRm
, op2
));
212 /* Move R0 to DTRTX */
213 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
216 retval
= mem_ap_read_atomic_u32(swjdp
,
217 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
222 int cortex_a8_write_cp(target_t
*target
, uint32_t value
,
223 uint8_t CP
, uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
226 /* get pointers to arch-specific information */
227 armv4_5_common_t
*armv4_5
= target
->arch_info
;
228 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
229 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
231 retval
= mem_ap_write_u32(swjdp
,
232 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
233 /* Move DTRRX to r0 */
234 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
236 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(CP
, op1
, 0, CRn
, CRm
, op2
));
240 int cortex_a8_read_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
241 uint32_t CRn
, uint32_t CRm
, uint32_t *value
)
243 return cortex_a8_read_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
246 int cortex_a8_write_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
247 uint32_t CRn
, uint32_t CRm
, uint32_t value
)
249 return cortex_a8_write_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
252 int cortex_a8_dap_read_coreregister_u32(target_t
*target
,
253 uint32_t *value
, int regnum
)
255 int retval
= ERROR_OK
;
256 uint8_t reg
= regnum
&0xFF;
259 /* get pointers to arch-specific information */
260 armv4_5_common_t
*armv4_5
= target
->arch_info
;
261 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
262 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
269 /* Rn to DCCTX, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
270 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, reg
, 0, 5, 0));
274 cortex_a8_exec_opcode(target
, 0xE1A0000F);
275 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
279 cortex_a8_exec_opcode(target
, ARMV4_5_MRS(0, 0));
280 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
286 retval
= mem_ap_read_atomic_u32(swjdp
,
287 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
289 while ((dscr
& (1 << DSCR_DTR_TX_FULL
)) == 0); /* Wait for DTRRXfull */
291 retval
= mem_ap_read_atomic_u32(swjdp
,
292 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
297 int cortex_a8_dap_write_coreregister_u32(target_t
*target
, uint32_t value
, int regnum
)
299 int retval
= ERROR_OK
;
300 uint8_t Rd
= regnum
&0xFF;
302 /* get pointers to arch-specific information */
303 armv4_5_common_t
*armv4_5
= target
->arch_info
;
304 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
305 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
311 retval
= mem_ap_write_u32(swjdp
,
312 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
316 /* DCCRX to Rd, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
317 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, Rd
, 0, 5, 0));
321 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
322 cortex_a8_exec_opcode(target
, 0xE1A0F000);
326 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
327 cortex_a8_exec_opcode(target
, ARMV4_5_MSR_GP(0, 0xF, 0));
328 /* Execute a PrefetchFlush instruction through the ITR. */
329 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(15, 0, 0, 7, 5, 4));
335 /* Write to memory mapped registers directly with no cache or mmu handling */
336 int cortex_a8_dap_write_memap_register_u32(target_t
*target
, uint32_t address
, uint32_t value
)
340 /* get pointers to arch-specific information */
341 armv4_5_common_t
*armv4_5
= target
->arch_info
;
342 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
343 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
345 retval
= mem_ap_write_atomic_u32(swjdp
, address
, value
);
351 * Cortex-A8 Run control
354 int cortex_a8_poll(target_t
*target
)
356 int retval
= ERROR_OK
;
358 /* get pointers to arch-specific information */
359 armv4_5_common_t
*armv4_5
= target
->arch_info
;
360 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
361 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
362 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
365 enum target_state prev_target_state
= target
->state
;
367 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 int cortex_a8_halt(target_t
*target
)
425 int retval
= ERROR_OK
;
428 /* get pointers to arch-specific information */
429 armv4_5_common_t
*armv4_5
= target
->arch_info
;
430 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
431 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
433 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
434 dap_ap_select(swjdp
, swjdp_debugap
);
437 * Tell the core to be halted by writing DRCR with 0x1
438 * and then wait for the core to be halted.
440 retval
= mem_ap_write_atomic_u32(swjdp
,
441 armv7a
->debug_base
+ CPUDBG_DRCR
, 0x1);
444 * enter halting debug mode
446 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
447 retval
= mem_ap_write_atomic_u32(swjdp
,
448 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
| (1 << DSCR_HALT_DBG_MODE
));
450 if (retval
!= ERROR_OK
)
454 mem_ap_read_atomic_u32(swjdp
,
455 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
456 } while ((dscr
& (1 << DSCR_CORE_HALTED
)) == 0);
458 target
->debug_reason
= DBG_REASON_DBGRQ
;
461 dap_ap_select(swjdp
, saved_apsel
);
465 int cortex_a8_resume(struct target_s
*target
, int current
,
466 uint32_t address
, int handle_breakpoints
, int debug_execution
)
468 /* get pointers to arch-specific information */
469 armv4_5_common_t
*armv4_5
= target
->arch_info
;
470 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
471 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
473 // breakpoint_t *breakpoint = NULL;
474 uint32_t resume_pc
, dscr
;
476 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
477 dap_ap_select(swjdp
, swjdp_debugap
);
479 if (!debug_execution
)
481 target_free_all_working_areas(target
);
482 // cortex_m3_enable_breakpoints(target);
483 // cortex_m3_enable_watchpoints(target);
489 /* Disable interrupts */
490 /* We disable interrupts in the PRIMASK register instead of
491 * masking with C_MASKINTS,
492 * This is probably the same issue as Cortex-M3 Errata 377493:
493 * C_MASKINTS in parallel with disabled interrupts can cause
494 * local faults to not be taken. */
495 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
496 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
497 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
499 /* Make sure we are in Thumb mode */
500 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
501 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
502 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
503 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
507 /* current = 1: continue on current pc, otherwise continue at <address> */
508 resume_pc
= buf_get_u32(
509 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
510 armv4_5
->core_mode
, 15).value
,
515 /* Make sure that the Armv7 gdb thumb fixups does not
516 * kill the return address
518 if (armv7a
->core_state
== ARMV7A_STATE_ARM
)
520 resume_pc
&= 0xFFFFFFFC;
522 /* When the return address is loaded into PC
523 * bit 0 must be 1 to stay in Thumb state
525 if (armv7a
->core_state
== ARMV7A_STATE_THUMB
)
529 LOG_DEBUG("resume pc = 0x%08" PRIx32
, resume_pc
);
530 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
531 armv4_5
->core_mode
, 15).value
,
533 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
534 armv4_5
->core_mode
, 15).dirty
= 1;
535 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
536 armv4_5
->core_mode
, 15).valid
= 1;
538 cortex_a8_restore_context(target
);
539 // arm7_9_restore_context(target); TODO Context is currently NOT Properly restored
541 /* the front-end may request us not to handle breakpoints */
542 if (handle_breakpoints
)
544 /* Single step past breakpoint at current address */
545 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
547 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
548 cortex_m3_unset_breakpoint(target
, breakpoint
);
549 cortex_m3_single_step_core(target
);
550 cortex_m3_set_breakpoint(target
, breakpoint
);
555 /* Restart core and wait for it to be started */
556 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DRCR
, 0x2);
559 mem_ap_read_atomic_u32(swjdp
,
560 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
561 } while ((dscr
& (1 << DSCR_CORE_RESTARTED
)) == 0);
563 target
->debug_reason
= DBG_REASON_NOTHALTED
;
564 target
->state
= TARGET_RUNNING
;
566 /* registers are now invalid */
567 armv4_5_invalidate_core_regs(target
);
569 if (!debug_execution
)
571 target
->state
= TARGET_RUNNING
;
572 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
573 LOG_DEBUG("target resumed at 0x%" PRIx32
, resume_pc
);
577 target
->state
= TARGET_DEBUG_RUNNING
;
578 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
579 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, resume_pc
);
582 dap_ap_select(swjdp
, saved_apsel
);
587 int cortex_a8_debug_entry(target_t
*target
)
590 uint32_t regfile
[16], pc
, cpsr
, dscr
;
591 int retval
= ERROR_OK
;
592 working_area_t
*regfile_working_area
= NULL
;
594 /* get pointers to arch-specific information */
595 armv4_5_common_t
*armv4_5
= target
->arch_info
;
596 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
597 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
598 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
600 if (armv7a
->pre_debug_entry
)
601 armv7a
->pre_debug_entry(target
);
603 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
605 /* Enable the ITR execution once we are in debug mode */
606 mem_ap_read_atomic_u32(swjdp
,
607 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
608 dscr
|= (1 << DSCR_EXT_INT_EN
);
609 retval
= mem_ap_write_atomic_u32(swjdp
,
610 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
);
612 /* Examine debug reason */
613 switch ((cortex_a8
->cpudbg_dscr
>> 2)&0xF)
617 target
->debug_reason
= DBG_REASON_DBGRQ
;
621 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
624 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
627 target
->debug_reason
= DBG_REASON_UNDEFINED
;
631 /* Examine target state and mode */
632 if (cortex_a8
->fast_reg_read
)
633 target_alloc_working_area(target
, 64, ®file_working_area
);
635 /* First load register acessible through core debug port*/
636 if (!regfile_working_area
)
638 for (i
= 0; i
<= 15; i
++)
639 cortex_a8_dap_read_coreregister_u32(target
,
644 dap_ap_select(swjdp
, swjdp_memoryap
);
645 cortex_a8_read_regs_through_mem(target
,
646 regfile_working_area
->address
, regfile
);
647 dap_ap_select(swjdp
, swjdp_memoryap
);
648 target_free_working_area(target
, regfile_working_area
);
651 cortex_a8_dap_read_coreregister_u32(target
, &cpsr
, 16);
653 dap_ap_select(swjdp
, swjdp_debugap
);
654 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
656 armv4_5
->core_mode
= cpsr
& 0x1F;
657 armv7a
->core_state
= (cpsr
& 0x20)?ARMV7A_STATE_THUMB
:ARMV7A_STATE_ARM
;
659 for (i
= 0; i
<= ARM_PC
; i
++)
661 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
662 armv4_5
->core_mode
, i
).value
,
664 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
665 armv4_5
->core_mode
, i
).valid
= 1;
666 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
667 armv4_5
->core_mode
, i
).dirty
= 0;
669 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
670 armv4_5
->core_mode
, 16).value
,
672 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
673 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
675 /* Fixup PC Resume Address */
676 if (armv7a
->core_state
== ARMV7A_STATE_THUMB
)
678 // T bit set for Thumb or ThumbEE state
679 regfile
[ARM_PC
] -= 4;
684 regfile
[ARM_PC
] -= 8;
686 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
687 armv4_5
->core_mode
, ARM_PC
).value
,
688 0, 32, regfile
[ARM_PC
]);
690 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 0)
691 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
692 armv4_5
->core_mode
, 0).valid
;
693 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 15)
694 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
695 armv4_5
->core_mode
, 15).valid
;
698 /* TODO, Move this */
699 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
700 cortex_a8_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
701 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
703 cortex_a8_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
704 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
706 cortex_a8_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
707 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
710 /* Are we in an exception handler */
711 // armv4_5->exception_number = 0;
712 if (armv7a
->post_debug_entry
)
713 armv7a
->post_debug_entry(target
);
721 void cortex_a8_post_debug_entry(target_t
*target
)
723 /* get pointers to arch-specific information */
724 armv4_5_common_t
*armv4_5
= target
->arch_info
;
725 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
726 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
728 // cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
729 /* examine cp15 control reg */
730 armv7a
->read_cp15(target
, 0, 0, 1, 0, &cortex_a8
->cp15_control_reg
);
731 jtag_execute_queue();
732 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
734 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
736 uint32_t cache_type_reg
;
737 /* identify caches */
738 armv7a
->read_cp15(target
, 0, 1, 0, 0, &cache_type_reg
);
739 jtag_execute_queue();
740 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
741 armv4_5_identify_cache(cache_type_reg
,
742 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
745 armv7a
->armv4_5_mmu
.mmu_enabled
=
746 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
747 armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
=
748 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
749 armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
=
750 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
755 int cortex_a8_step(struct target_s
*target
, int current
, uint32_t address
,
756 int handle_breakpoints
)
758 /* get pointers to arch-specific information */
759 armv4_5_common_t
*armv4_5
= target
->arch_info
;
760 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
761 breakpoint_t
*breakpoint
= NULL
;
762 breakpoint_t stepbreakpoint
;
766 if (target
->state
!= TARGET_HALTED
)
768 LOG_WARNING("target not halted");
769 return ERROR_TARGET_NOT_HALTED
;
772 /* current = 1: continue on current pc, otherwise continue at <address> */
775 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
776 armv4_5
->core_mode
, ARM_PC
).value
,
781 address
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
782 armv4_5
->core_mode
, ARM_PC
).value
,
786 /* The front-end may request us not to handle breakpoints.
787 * But since Cortex-A8 uses breakpoint for single step,
788 * we MUST handle breakpoints.
790 handle_breakpoints
= 1;
791 if (handle_breakpoints
) {
792 breakpoint
= breakpoint_find(target
,
793 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
794 armv4_5
->core_mode
, 15).value
,
797 cortex_a8_unset_breakpoint(target
, breakpoint
);
800 /* Setup single step breakpoint */
801 stepbreakpoint
.address
= address
;
802 stepbreakpoint
.length
= (armv7a
->core_state
== ARMV7A_STATE_THUMB
) ? 2 : 4;
803 stepbreakpoint
.type
= BKPT_HARD
;
804 stepbreakpoint
.set
= 0;
806 /* Break on IVA mismatch */
807 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
809 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
811 cortex_a8_resume(target
, 1, address
, 0, 0);
813 while (target
->state
!= TARGET_HALTED
)
815 cortex_a8_poll(target
);
818 LOG_WARNING("timeout waiting for target halt");
823 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
824 if (timeout
> 0) target
->debug_reason
= DBG_REASON_BREAKPOINT
;
827 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
829 if (target
->state
!= TARGET_HALTED
)
830 LOG_DEBUG("target stepped");
835 int cortex_a8_restore_context(target_t
*target
)
840 /* get pointers to arch-specific information */
841 armv4_5_common_t
*armv4_5
= target
->arch_info
;
842 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
846 if (armv7a
->pre_restore_context
)
847 armv7a
->pre_restore_context(target
);
849 for (i
= 15; i
>= 0; i
--)
851 if (ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
852 armv4_5
->core_mode
, i
).dirty
)
854 value
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
855 armv4_5
->core_mode
, i
).value
,
857 /* TODO Check return values */
858 cortex_a8_dap_write_coreregister_u32(target
, value
, i
);
862 if (armv7a
->post_restore_context
)
863 armv7a
->post_restore_context(target
);
870 * Cortex-A8 Core register functions
873 int cortex_a8_load_core_reg_u32(struct target_s
*target
, int num
,
874 armv4_5_mode_t mode
, uint32_t * value
)
877 /* get pointers to arch-specific information */
878 armv4_5_common_t
*armv4_5
= target
->arch_info
;
880 if ((num
<= ARM_CPSR
))
882 /* read a normal core register */
883 retval
= cortex_a8_dap_read_coreregister_u32(target
, value
, num
);
885 if (retval
!= ERROR_OK
)
887 LOG_ERROR("JTAG failure %i", retval
);
888 return ERROR_JTAG_DEVICE_ERROR
;
890 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
, num
, *value
);
894 return ERROR_INVALID_ARGUMENTS
;
897 /* Register other than r0 - r14 uses r0 for access */
899 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
900 armv4_5
->core_mode
, 0).dirty
=
901 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
902 armv4_5
->core_mode
, 0).valid
;
903 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
904 armv4_5
->core_mode
, 15).dirty
=
905 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
906 armv4_5
->core_mode
, 15).valid
;
911 int cortex_a8_store_core_reg_u32(struct target_s
*target
, int num
,
912 armv4_5_mode_t mode
, uint32_t value
)
917 /* get pointers to arch-specific information */
918 armv4_5_common_t
*armv4_5
= target
->arch_info
;
920 #ifdef ARMV7_GDB_HACKS
921 /* If the LR register is being modified, make sure it will put us
922 * in "thumb" mode, or an INVSTATE exception will occur. This is a
923 * hack to deal with the fact that gdb will sometimes "forge"
924 * return addresses, and doesn't set the LSB correctly (i.e., when
925 * printing expressions containing function calls, it sets LR=0.) */
931 if ((num
<= ARM_CPSR
))
933 retval
= cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
934 if (retval
!= ERROR_OK
)
936 LOG_ERROR("JTAG failure %i", retval
);
937 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
938 armv4_5
->core_mode
, num
).dirty
=
939 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
940 armv4_5
->core_mode
, num
).valid
;
941 return ERROR_JTAG_DEVICE_ERROR
;
943 LOG_DEBUG("write core reg %i value 0x%" PRIx32
, num
, value
);
947 return ERROR_INVALID_ARGUMENTS
;
954 int cortex_a8_read_core_reg(struct target_s
*target
, int num
,
955 enum armv4_5_mode mode
)
959 armv4_5_common_t
*armv4_5
= target
->arch_info
;
960 cortex_a8_dap_read_coreregister_u32(target
, &value
, num
);
962 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
967 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
968 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
969 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
970 mode
, num
).value
, 0, 32, value
);
975 int cortex_a8_write_core_reg(struct target_s
*target
, int num
,
976 enum armv4_5_mode mode
, uint32_t value
)
979 armv4_5_common_t
*armv4_5
= target
->arch_info
;
981 cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
982 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
987 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
988 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
995 * Cortex-A8 Breakpoint and watchpoint fuctions
998 /* Setup hardware Breakpoint Register Pair */
999 int cortex_a8_set_breakpoint(struct target_s
*target
,
1000 breakpoint_t
*breakpoint
, uint8_t matchmode
)
1005 uint8_t byte_addr_select
= 0x0F;
1008 /* get pointers to arch-specific information */
1009 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1010 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1011 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1012 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
1014 if (breakpoint
->set
)
1016 LOG_WARNING("breakpoint already set");
1020 if (breakpoint
->type
== BKPT_HARD
)
1022 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
1024 if (brp_i
>= cortex_a8
->brp_num
)
1026 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1029 breakpoint
->set
= brp_i
+ 1;
1030 if (breakpoint
->length
== 2)
1032 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1034 control
= ((matchmode
& 0x7) << 20)
1035 | (byte_addr_select
<< 5)
1037 brp_list
[brp_i
].used
= 1;
1038 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1039 brp_list
[brp_i
].control
= control
;
1040 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1041 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1042 brp_list
[brp_i
].value
);
1043 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1044 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1045 brp_list
[brp_i
].control
);
1046 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1047 brp_list
[brp_i
].control
,
1048 brp_list
[brp_i
].value
);
1050 else if (breakpoint
->type
== BKPT_SOFT
)
1053 if (breakpoint
->length
== 2)
1055 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1059 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1061 retval
= target
->type
->read_memory(target
,
1062 breakpoint
->address
& 0xFFFFFFFE,
1063 breakpoint
->length
, 1,
1064 breakpoint
->orig_instr
);
1065 if (retval
!= ERROR_OK
)
1067 retval
= target
->type
->write_memory(target
,
1068 breakpoint
->address
& 0xFFFFFFFE,
1069 breakpoint
->length
, 1, code
);
1070 if (retval
!= ERROR_OK
)
1072 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1078 int cortex_a8_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1081 /* get pointers to arch-specific information */
1082 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1083 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1084 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1085 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
1087 if (!breakpoint
->set
)
1089 LOG_WARNING("breakpoint not set");
1093 if (breakpoint
->type
== BKPT_HARD
)
1095 int brp_i
= breakpoint
->set
- 1;
1096 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1098 LOG_DEBUG("Invalid BRP number in breakpoint");
1101 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1102 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1103 brp_list
[brp_i
].used
= 0;
1104 brp_list
[brp_i
].value
= 0;
1105 brp_list
[brp_i
].control
= 0;
1106 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1107 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1108 brp_list
[brp_i
].control
);
1109 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1110 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1111 brp_list
[brp_i
].value
);
1115 /* restore original instruction (kept in target endianness) */
1116 if (breakpoint
->length
== 4)
1118 retval
= target
->type
->write_memory(target
,
1119 breakpoint
->address
& 0xFFFFFFFE,
1120 4, 1, breakpoint
->orig_instr
);
1121 if (retval
!= ERROR_OK
)
1126 retval
= target
->type
->write_memory(target
,
1127 breakpoint
->address
& 0xFFFFFFFE,
1128 2, 1, breakpoint
->orig_instr
);
1129 if (retval
!= ERROR_OK
)
1133 breakpoint
->set
= 0;
1138 int cortex_a8_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1140 /* get pointers to arch-specific information */
1141 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1142 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1143 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1145 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1147 LOG_INFO("no hardware breakpoint available");
1148 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1151 if (breakpoint
->type
== BKPT_HARD
)
1152 cortex_a8
->brp_num_available
--;
1153 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1158 int cortex_a8_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1160 /* get pointers to arch-specific information */
1161 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1162 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1163 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1166 /* It is perfectly possible to remove brakpoints while the taget is running */
1167 if (target
->state
!= TARGET_HALTED
)
1169 LOG_WARNING("target not halted");
1170 return ERROR_TARGET_NOT_HALTED
;
1174 if (breakpoint
->set
)
1176 cortex_a8_unset_breakpoint(target
, breakpoint
);
1177 if (breakpoint
->type
== BKPT_HARD
)
1178 cortex_a8
->brp_num_available
++ ;
1188 * Cortex-A8 Reset fuctions
1193 * Cortex-A8 Memory access
1195 * This is same Cortex M3 but we must also use the correct
1196 * ap number for every access.
1199 int cortex_a8_read_memory(struct target_s
*target
, uint32_t address
,
1200 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1202 /* get pointers to arch-specific information */
1203 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1204 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1205 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1207 int retval
= ERROR_OK
;
1209 /* sanitize arguments */
1210 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1211 return ERROR_INVALID_ARGUMENTS
;
1213 /* cortex_a8 handles unaligned memory access */
1215 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1220 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1223 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1226 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1229 LOG_ERROR("BUG: we shouldn't get here");
1236 int cortex_a8_write_memory(struct target_s
*target
, uint32_t address
,
1237 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1239 /* get pointers to arch-specific information */
1240 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1241 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1242 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1246 /* sanitize arguments */
1247 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1248 return ERROR_INVALID_ARGUMENTS
;
1250 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1255 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1258 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1261 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1264 LOG_ERROR("BUG: we shouldn't get here");
1268 /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */
1269 /* invalidate I-Cache */
1270 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
1272 /* Invalidate ICache single entry with MVA, repeat this for all cache
1273 lines in the address range, Cortex-A8 has fixed 64 byte line length */
1274 /* Invalidate Cache single entry with MVA to PoU */
1275 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1276 armv7a
->write_cp15(target
, 0, 1, 7, 5, cacheline
); /* I-Cache to PoU */
1278 /* invalidate D-Cache */
1279 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
1281 /* Invalidate Cache single entry with MVA to PoC */
1282 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1283 armv7a
->write_cp15(target
, 0, 1, 7, 6, cacheline
); /* U/D cache to PoC */
1289 int cortex_a8_bulk_write_memory(target_t
*target
, uint32_t address
,
1290 uint32_t count
, uint8_t *buffer
)
1292 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1296 int cortex_a8_dcc_read(swjdp_common_t
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1301 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1302 *ctrl
= (uint8_t)dcrdr
;
1303 *value
= (uint8_t)(dcrdr
>> 8);
1305 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1307 /* write ack back to software dcc register
1308 * signify we have read data */
1309 if (dcrdr
& (1 << 0))
1312 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1319 int cortex_a8_handle_target_request(void *priv
)
1321 target_t
*target
= priv
;
1322 if (!target
->type
->examined
)
1324 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1325 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1326 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1329 if (!target
->dbg_msg_enabled
)
1332 if (target
->state
== TARGET_RUNNING
)
1337 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1339 /* check if we have data */
1340 if (ctrl
& (1 << 0))
1344 /* we assume target is quick enough */
1346 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1347 request
|= (data
<< 8);
1348 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1349 request
|= (data
<< 16);
1350 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1351 request
|= (data
<< 24);
1352 target_request(target
, request
);
1360 * Cortex-A8 target information and configuration
1363 int cortex_a8_examine(struct target_s
*target
)
1365 /* get pointers to arch-specific information */
1366 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1367 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1368 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1369 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1373 int retval
= ERROR_OK
;
1374 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1378 /* Here we shall insert a proper ROM Table scan */
1379 armv7a
->debug_base
= OMAP3530_DEBUG_BASE
;
1381 /* We do one extra read to ensure DAP is configured,
1382 * we call ahbap_debugport_init(swjdp) instead
1384 ahbap_debugport_init(swjdp
);
1385 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
1386 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1387 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1389 LOG_DEBUG("Examine failed");
1393 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1394 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1396 LOG_DEBUG("Examine failed");
1400 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1401 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1403 LOG_DEBUG("Examine failed");
1407 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1408 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1410 LOG_DEBUG("Examine failed");
1414 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1415 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1416 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1417 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1419 /* Setup Breakpoint Register Pairs */
1420 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1421 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1422 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1423 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(cortex_a8_brp_t
));
1424 // cortex_a8->brb_enabled = ????;
1425 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1427 cortex_a8
->brp_list
[i
].used
= 0;
1428 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1429 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1431 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1432 cortex_a8
->brp_list
[i
].value
= 0;
1433 cortex_a8
->brp_list
[i
].control
= 0;
1434 cortex_a8
->brp_list
[i
].BRPn
= i
;
1437 /* Setup Watchpoint Register Pairs */
1438 cortex_a8
->wrp_num
= ((didr
>> 28) & 0x0F) + 1;
1439 cortex_a8
->wrp_num_available
= cortex_a8
->wrp_num
;
1440 cortex_a8
->wrp_list
= calloc(cortex_a8
->wrp_num
, sizeof(cortex_a8_wrp_t
));
1441 for (i
= 0; i
< cortex_a8
->wrp_num
; i
++)
1443 cortex_a8
->wrp_list
[i
].used
= 0;
1444 cortex_a8
->wrp_list
[i
].type
= 0;
1445 cortex_a8
->wrp_list
[i
].value
= 0;
1446 cortex_a8
->wrp_list
[i
].control
= 0;
1447 cortex_a8
->wrp_list
[i
].WRPn
= i
;
1449 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1450 cortex_a8
->brp_num
, cortex_a8
->wrp_num
);
1452 /* Configure core debug access */
1453 cortex_a8_init_debug_access(target
);
1455 target
->type
->examined
= 1;
1461 * Cortex-A8 target creation and initialization
1464 void cortex_a8_build_reg_cache(target_t
*target
)
1466 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1467 /* get pointers to arch-specific information */
1468 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1470 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
1471 armv4_5
->core_cache
= (*cache_p
);
1475 int cortex_a8_init_target(struct command_context_s
*cmd_ctx
,
1476 struct target_s
*target
)
1478 cortex_a8_build_reg_cache(target
);
1482 int cortex_a8_init_arch_info(target_t
*target
,
1483 cortex_a8_common_t
*cortex_a8
, jtag_tap_t
*tap
)
1485 armv4_5_common_t
*armv4_5
;
1486 armv7a_common_t
*armv7a
;
1488 armv7a
= &cortex_a8
->armv7a_common
;
1489 armv4_5
= &armv7a
->armv4_5_common
;
1490 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1492 /* Setup cortex_a8_common_t */
1493 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1494 cortex_a8
->arch_info
= NULL
;
1495 armv7a
->arch_info
= cortex_a8
;
1496 armv4_5
->arch_info
= armv7a
;
1498 armv4_5_init_arch_info(target
, armv4_5
);
1500 /* prepare JTAG information for the new target */
1501 cortex_a8
->jtag_info
.tap
= tap
;
1502 cortex_a8
->jtag_info
.scann_size
= 4;
1504 swjdp
->dp_select_value
= -1;
1505 swjdp
->ap_csw_value
= -1;
1506 swjdp
->ap_tar_value
= -1;
1507 swjdp
->jtag_info
= &cortex_a8
->jtag_info
;
1508 swjdp
->memaccess_tck
= 80;
1510 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1511 swjdp
->tar_autoincr_block
= (1 << 10);
1513 cortex_a8
->fast_reg_read
= 0;
1516 /* register arch-specific functions */
1517 armv7a
->examine_debug_reason
= NULL
;
1519 armv7a
->pre_debug_entry
= NULL
;
1520 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1522 armv7a
->pre_restore_context
= NULL
;
1523 armv7a
->post_restore_context
= NULL
;
1524 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1525 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1526 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_memory
;
1527 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_memory
;
1528 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1529 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1530 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1531 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1532 armv7a
->read_cp15
= cortex_a8_read_cp15
;
1533 armv7a
->write_cp15
= cortex_a8_write_cp15
;
1536 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1538 armv4_5
->read_core_reg
= cortex_a8_read_core_reg
;
1539 armv4_5
->write_core_reg
= cortex_a8_write_core_reg
;
1540 // armv4_5->full_context = arm7_9_full_context;
1542 // armv4_5->load_core_reg_u32 = cortex_a8_load_core_reg_u32;
1543 // armv4_5->store_core_reg_u32 = cortex_a8_store_core_reg_u32;
1544 // armv4_5->read_core_reg = armv4_5_read_core_reg; /* this is default */
1545 // armv4_5->write_core_reg = armv4_5_write_core_reg;
1547 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1552 int cortex_a8_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1554 cortex_a8_common_t
*cortex_a8
= calloc(1, sizeof(cortex_a8_common_t
));
1556 cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1561 static int cortex_a8_handle_cache_info_command(struct command_context_s
*cmd_ctx
,
1562 char *cmd
, char **args
, int argc
)
1564 target_t
*target
= get_current_target(cmd_ctx
);
1565 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1566 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1568 return armv4_5_handle_cache_info_command(cmd_ctx
,
1569 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1573 static int cortex_a8_handle_dbginit_command(struct command_context_s
*cmd_ctx
,
1574 char *cmd
, char **args
, int argc
)
1576 target_t
*target
= get_current_target(cmd_ctx
);
1578 cortex_a8_init_debug_access(target
);
1584 int cortex_a8_register_commands(struct command_context_s
*cmd_ctx
)
1586 command_t
*cortex_a8_cmd
;
1587 int retval
= ERROR_OK
;
1589 armv4_5_register_commands(cmd_ctx
);
1590 armv7a_register_commands(cmd_ctx
);
1592 cortex_a8_cmd
= register_command(cmd_ctx
, NULL
, "cortex_a8",
1594 "cortex_a8 specific commands");
1596 register_command(cmd_ctx
, cortex_a8_cmd
, "cache_info",
1597 cortex_a8_handle_cache_info_command
, COMMAND_EXEC
,
1598 "display information about target caches");
1600 register_command(cmd_ctx
, cortex_a8_cmd
, "dbginit",
1601 cortex_a8_handle_dbginit_command
, COMMAND_EXEC
,
1602 "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)