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
,
86 .assert_reset
= cortex_a8_assert_reset
,
87 .deassert_reset
= cortex_a8_deassert_reset
,
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
,
112 * FIXME do topology discovery using the ROM; don't
113 * assume this is an OMAP3.
115 #define swjdp_memoryap 0
116 #define swjdp_debugap 1
117 #define OMAP3530_DEBUG_BASE 0x54011000
120 * Cortex-A8 Basic debug access, very low level assumes state is saved
122 int cortex_a8_init_debug_access(target_t
*target
)
124 /* get pointers to arch-specific information */
125 armv4_5_common_t
*armv4_5
= target
->arch_info
;
126 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
127 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
134 /* Unlocking the debug registers for modification */
135 /* The debugport might be uninitialised so try twice */
136 retval
= mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
137 if (retval
!= ERROR_OK
)
138 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
139 /* Clear Sticky Power Down status Bit in PRSR to enable access to
140 the registers in the Core Power Domain */
141 retval
= mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_PRSR
, &dummy
);
142 /* Enabling of instruction execution in debug mode is done in debug_entry code */
144 /* Resync breakpoint registers */
146 /* Since this is likley called from init or reset, update targtet state information*/
147 cortex_a8_poll(target
);
152 int cortex_a8_exec_opcode(target_t
*target
, uint32_t opcode
)
156 /* get pointers to arch-specific information */
157 armv4_5_common_t
*armv4_5
= target
->arch_info
;
158 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
159 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
161 LOG_DEBUG("exec opcode 0x%08" PRIx32
, opcode
);
164 retval
= mem_ap_read_atomic_u32(swjdp
,
165 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
166 if (retval
!= ERROR_OK
)
168 LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32
, opcode
);
172 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
174 mem_ap_write_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_ITR
, opcode
);
178 retval
= mem_ap_read_atomic_u32(swjdp
,
179 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
180 if (retval
!= ERROR_OK
)
182 LOG_ERROR("Could not read DSCR register");
186 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
191 /**************************************************************************
192 Read core register with very few exec_opcode, fast but needs work_area.
193 This can cause problems with MMU active.
194 **************************************************************************/
195 int cortex_a8_read_regs_through_mem(target_t
*target
, uint32_t address
,
198 int retval
= ERROR_OK
;
199 /* get pointers to arch-specific information */
200 armv4_5_common_t
*armv4_5
= target
->arch_info
;
201 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
202 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
204 cortex_a8_dap_read_coreregister_u32(target
, regfile
, 0);
205 cortex_a8_dap_write_coreregister_u32(target
, address
, 0);
206 cortex_a8_exec_opcode(target
, ARMV4_5_STMIA(0, 0xFFFE, 0, 0));
207 dap_ap_select(swjdp
, swjdp_memoryap
);
208 mem_ap_read_buf_u32(swjdp
, (uint8_t *)(®file
[1]), 4*15, address
);
209 dap_ap_select(swjdp
, swjdp_debugap
);
214 int cortex_a8_read_cp(target_t
*target
, uint32_t *value
, uint8_t CP
,
215 uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
218 /* get pointers to arch-specific information */
219 armv4_5_common_t
*armv4_5
= target
->arch_info
;
220 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
221 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
223 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(CP
, op1
, 0, CRn
, CRm
, op2
));
224 /* Move R0 to DTRTX */
225 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
228 retval
= mem_ap_read_atomic_u32(swjdp
,
229 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
234 int cortex_a8_write_cp(target_t
*target
, uint32_t value
,
235 uint8_t CP
, uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
240 /* get pointers to arch-specific information */
241 armv4_5_common_t
*armv4_5
= target
->arch_info
;
242 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
243 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
245 LOG_DEBUG("CP%i, CRn %i, value 0x%08" PRIx32
, CP
, CRn
, value
);
247 /* Check that DCCRX is not full */
248 retval
= mem_ap_read_atomic_u32(swjdp
,
249 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
250 if (dscr
& (1 << DSCR_DTR_RX_FULL
))
252 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
253 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
254 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
257 retval
= mem_ap_write_u32(swjdp
,
258 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
259 /* Move DTRRX to r0 */
260 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
262 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(CP
, op1
, 0, CRn
, CRm
, op2
));
266 int cortex_a8_read_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
267 uint32_t CRn
, uint32_t CRm
, uint32_t *value
)
269 return cortex_a8_read_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
272 int cortex_a8_write_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
273 uint32_t CRn
, uint32_t CRm
, uint32_t value
)
275 return cortex_a8_write_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
278 int cortex_a8_dap_read_coreregister_u32(target_t
*target
,
279 uint32_t *value
, int regnum
)
281 int retval
= ERROR_OK
;
282 uint8_t reg
= regnum
&0xFF;
285 /* get pointers to arch-specific information */
286 armv4_5_common_t
*armv4_5
= target
->arch_info
;
287 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
288 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
295 /* Rn to DCCTX, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
296 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, reg
, 0, 5, 0));
300 cortex_a8_exec_opcode(target
, 0xE1A0000F);
301 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
305 cortex_a8_exec_opcode(target
, ARMV4_5_MRS(0, 0));
306 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
312 retval
= mem_ap_read_atomic_u32(swjdp
,
313 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
315 while ((dscr
& (1 << DSCR_DTR_TX_FULL
)) == 0); /* Wait for DTRRXfull */
317 retval
= mem_ap_read_atomic_u32(swjdp
,
318 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
323 int cortex_a8_dap_write_coreregister_u32(target_t
*target
, uint32_t value
, int regnum
)
325 int retval
= ERROR_OK
;
326 uint8_t Rd
= regnum
&0xFF;
329 /* get pointers to arch-specific information */
330 armv4_5_common_t
*armv4_5
= target
->arch_info
;
331 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
332 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
334 LOG_DEBUG("register %i, value 0x%08" PRIx32
, regnum
, value
);
336 /* Check that DCCRX is not full */
337 retval
= mem_ap_read_atomic_u32(swjdp
,
338 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
339 if (dscr
& (1 << DSCR_DTR_RX_FULL
))
341 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
342 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
343 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
350 retval
= mem_ap_write_u32(swjdp
,
351 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
355 /* DCCRX to Rd, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
356 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, Rd
, 0, 5, 0));
360 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
361 cortex_a8_exec_opcode(target
, 0xE1A0F000);
365 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
366 cortex_a8_exec_opcode(target
, ARMV4_5_MSR_GP(0, 0xF, 0));
367 /* Execute a PrefetchFlush instruction through the ITR. */
368 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(15, 0, 0, 7, 5, 4));
374 /* Write to memory mapped registers directly with no cache or mmu handling */
375 int cortex_a8_dap_write_memap_register_u32(target_t
*target
, uint32_t address
, uint32_t value
)
379 /* get pointers to arch-specific information */
380 armv4_5_common_t
*armv4_5
= target
->arch_info
;
381 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
382 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
384 retval
= mem_ap_write_atomic_u32(swjdp
, address
, value
);
390 * Cortex-A8 Run control
393 int cortex_a8_poll(target_t
*target
)
395 int retval
= ERROR_OK
;
397 /* get pointers to arch-specific information */
398 armv4_5_common_t
*armv4_5
= target
->arch_info
;
399 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
400 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
401 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
404 enum target_state prev_target_state
= target
->state
;
406 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
407 dap_ap_select(swjdp
, swjdp_debugap
);
408 retval
= mem_ap_read_atomic_u32(swjdp
,
409 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
410 if (retval
!= ERROR_OK
)
412 dap_ap_select(swjdp
, saved_apsel
);
415 cortex_a8
->cpudbg_dscr
= dscr
;
417 if ((dscr
& 0x3) == 0x3)
419 if (prev_target_state
!= TARGET_HALTED
)
421 /* We have a halting debug event */
422 LOG_DEBUG("Target halted");
423 target
->state
= TARGET_HALTED
;
424 if ((prev_target_state
== TARGET_RUNNING
)
425 || (prev_target_state
== TARGET_RESET
))
427 retval
= cortex_a8_debug_entry(target
);
428 if (retval
!= ERROR_OK
)
431 target_call_event_callbacks(target
,
432 TARGET_EVENT_HALTED
);
434 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
438 retval
= cortex_a8_debug_entry(target
);
439 if (retval
!= ERROR_OK
)
442 target_call_event_callbacks(target
,
443 TARGET_EVENT_DEBUG_HALTED
);
447 else if ((dscr
& 0x3) == 0x2)
449 target
->state
= TARGET_RUNNING
;
453 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32
, dscr
);
454 target
->state
= TARGET_UNKNOWN
;
457 dap_ap_select(swjdp
, saved_apsel
);
462 int cortex_a8_halt(target_t
*target
)
464 int retval
= ERROR_OK
;
467 /* get pointers to arch-specific information */
468 armv4_5_common_t
*armv4_5
= target
->arch_info
;
469 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
470 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
472 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
473 dap_ap_select(swjdp
, swjdp_debugap
);
476 * Tell the core to be halted by writing DRCR with 0x1
477 * and then wait for the core to be halted.
479 retval
= mem_ap_write_atomic_u32(swjdp
,
480 armv7a
->debug_base
+ CPUDBG_DRCR
, 0x1);
483 * enter halting debug mode
485 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
486 retval
= mem_ap_write_atomic_u32(swjdp
,
487 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
| (1 << DSCR_HALT_DBG_MODE
));
489 if (retval
!= ERROR_OK
)
493 mem_ap_read_atomic_u32(swjdp
,
494 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
495 } while ((dscr
& (1 << DSCR_CORE_HALTED
)) == 0);
497 target
->debug_reason
= DBG_REASON_DBGRQ
;
500 dap_ap_select(swjdp
, saved_apsel
);
504 int cortex_a8_resume(struct target_s
*target
, int current
,
505 uint32_t address
, int handle_breakpoints
, int debug_execution
)
507 /* get pointers to arch-specific information */
508 armv4_5_common_t
*armv4_5
= target
->arch_info
;
509 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
510 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
512 // breakpoint_t *breakpoint = NULL;
513 uint32_t resume_pc
, dscr
;
515 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
516 dap_ap_select(swjdp
, swjdp_debugap
);
518 if (!debug_execution
)
520 target_free_all_working_areas(target
);
521 // cortex_m3_enable_breakpoints(target);
522 // cortex_m3_enable_watchpoints(target);
528 /* Disable interrupts */
529 /* We disable interrupts in the PRIMASK register instead of
530 * masking with C_MASKINTS,
531 * This is probably the same issue as Cortex-M3 Errata 377493:
532 * C_MASKINTS in parallel with disabled interrupts can cause
533 * local faults to not be taken. */
534 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
535 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
536 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
538 /* Make sure we are in Thumb mode */
539 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
540 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
541 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
542 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
546 /* current = 1: continue on current pc, otherwise continue at <address> */
547 resume_pc
= buf_get_u32(
548 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
549 armv4_5
->core_mode
, 15).value
,
554 /* Make sure that the Armv7 gdb thumb fixups does not
555 * kill the return address
557 if (armv7a
->core_state
== ARMV7A_STATE_ARM
)
559 resume_pc
&= 0xFFFFFFFC;
561 /* When the return address is loaded into PC
562 * bit 0 must be 1 to stay in Thumb state
564 if (armv7a
->core_state
== ARMV7A_STATE_THUMB
)
568 LOG_DEBUG("resume pc = 0x%08" PRIx32
, resume_pc
);
569 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
570 armv4_5
->core_mode
, 15).value
,
572 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
573 armv4_5
->core_mode
, 15).dirty
= 1;
574 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
575 armv4_5
->core_mode
, 15).valid
= 1;
577 cortex_a8_restore_context(target
);
578 // arm7_9_restore_context(target); TODO Context is currently NOT Properly restored
580 /* the front-end may request us not to handle breakpoints */
581 if (handle_breakpoints
)
583 /* Single step past breakpoint at current address */
584 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
586 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
587 cortex_m3_unset_breakpoint(target
, breakpoint
);
588 cortex_m3_single_step_core(target
);
589 cortex_m3_set_breakpoint(target
, breakpoint
);
594 /* Restart core and wait for it to be started */
595 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DRCR
, 0x2);
598 mem_ap_read_atomic_u32(swjdp
,
599 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
600 } while ((dscr
& (1 << DSCR_CORE_RESTARTED
)) == 0);
602 target
->debug_reason
= DBG_REASON_NOTHALTED
;
603 target
->state
= TARGET_RUNNING
;
605 /* registers are now invalid */
606 armv4_5_invalidate_core_regs(target
);
608 if (!debug_execution
)
610 target
->state
= TARGET_RUNNING
;
611 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
612 LOG_DEBUG("target resumed at 0x%" PRIx32
, resume_pc
);
616 target
->state
= TARGET_DEBUG_RUNNING
;
617 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
618 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, resume_pc
);
621 dap_ap_select(swjdp
, saved_apsel
);
626 int cortex_a8_debug_entry(target_t
*target
)
629 uint32_t regfile
[16], pc
, cpsr
, dscr
;
630 int retval
= ERROR_OK
;
631 working_area_t
*regfile_working_area
= NULL
;
633 /* get pointers to arch-specific information */
634 armv4_5_common_t
*armv4_5
= target
->arch_info
;
635 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
636 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
637 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
639 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
641 /* Enable the ITR execution once we are in debug mode */
642 mem_ap_read_atomic_u32(swjdp
,
643 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
644 dscr
|= (1 << DSCR_EXT_INT_EN
);
645 retval
= mem_ap_write_atomic_u32(swjdp
,
646 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
);
648 /* Examine debug reason */
649 switch ((cortex_a8
->cpudbg_dscr
>> 2)&0xF)
653 target
->debug_reason
= DBG_REASON_DBGRQ
;
657 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
660 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
663 target
->debug_reason
= DBG_REASON_UNDEFINED
;
667 /* Examine target state and mode */
668 if (cortex_a8
->fast_reg_read
)
669 target_alloc_working_area(target
, 64, ®file_working_area
);
671 /* First load register acessible through core debug port*/
672 if (!regfile_working_area
)
674 for (i
= 0; i
<= 15; i
++)
675 cortex_a8_dap_read_coreregister_u32(target
,
680 dap_ap_select(swjdp
, swjdp_memoryap
);
681 cortex_a8_read_regs_through_mem(target
,
682 regfile_working_area
->address
, regfile
);
683 dap_ap_select(swjdp
, swjdp_memoryap
);
684 target_free_working_area(target
, regfile_working_area
);
687 cortex_a8_dap_read_coreregister_u32(target
, &cpsr
, 16);
689 dap_ap_select(swjdp
, swjdp_debugap
);
690 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
692 armv4_5
->core_mode
= cpsr
& 0x1F;
693 armv7a
->core_state
= (cpsr
& 0x20)?ARMV7A_STATE_THUMB
:ARMV7A_STATE_ARM
;
695 for (i
= 0; i
<= ARM_PC
; i
++)
697 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
698 armv4_5
->core_mode
, i
).value
,
700 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
701 armv4_5
->core_mode
, i
).valid
= 1;
702 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
703 armv4_5
->core_mode
, i
).dirty
= 0;
705 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
706 armv4_5
->core_mode
, 16).value
,
708 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
709 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
711 /* Fixup PC Resume Address */
712 if (armv7a
->core_state
== ARMV7A_STATE_THUMB
)
714 // T bit set for Thumb or ThumbEE state
715 regfile
[ARM_PC
] -= 4;
720 regfile
[ARM_PC
] -= 8;
722 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
723 armv4_5
->core_mode
, ARM_PC
).value
,
724 0, 32, regfile
[ARM_PC
]);
726 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 0)
727 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
728 armv4_5
->core_mode
, 0).valid
;
729 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 15)
730 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
731 armv4_5
->core_mode
, 15).valid
;
734 /* TODO, Move this */
735 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
736 cortex_a8_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
737 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
739 cortex_a8_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
740 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
742 cortex_a8_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
743 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
746 /* Are we in an exception handler */
747 // armv4_5->exception_number = 0;
748 if (armv7a
->post_debug_entry
)
749 armv7a
->post_debug_entry(target
);
757 void cortex_a8_post_debug_entry(target_t
*target
)
759 /* get pointers to arch-specific information */
760 armv4_5_common_t
*armv4_5
= target
->arch_info
;
761 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
762 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
764 // cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
765 /* examine cp15 control reg */
766 armv7a
->read_cp15(target
, 0, 0, 1, 0, &cortex_a8
->cp15_control_reg
);
767 jtag_execute_queue();
768 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
770 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
772 uint32_t cache_type_reg
;
773 /* identify caches */
774 armv7a
->read_cp15(target
, 0, 1, 0, 0, &cache_type_reg
);
775 jtag_execute_queue();
776 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
777 armv4_5_identify_cache(cache_type_reg
,
778 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
781 armv7a
->armv4_5_mmu
.mmu_enabled
=
782 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
783 armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
=
784 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
785 armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
=
786 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
791 int cortex_a8_step(struct target_s
*target
, int current
, uint32_t address
,
792 int handle_breakpoints
)
794 /* get pointers to arch-specific information */
795 armv4_5_common_t
*armv4_5
= target
->arch_info
;
796 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
797 breakpoint_t
*breakpoint
= NULL
;
798 breakpoint_t stepbreakpoint
;
802 if (target
->state
!= TARGET_HALTED
)
804 LOG_WARNING("target not halted");
805 return ERROR_TARGET_NOT_HALTED
;
808 /* current = 1: continue on current pc, otherwise continue at <address> */
811 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
812 armv4_5
->core_mode
, ARM_PC
).value
,
817 address
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
818 armv4_5
->core_mode
, ARM_PC
).value
,
822 /* The front-end may request us not to handle breakpoints.
823 * But since Cortex-A8 uses breakpoint for single step,
824 * we MUST handle breakpoints.
826 handle_breakpoints
= 1;
827 if (handle_breakpoints
) {
828 breakpoint
= breakpoint_find(target
,
829 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
830 armv4_5
->core_mode
, 15).value
,
833 cortex_a8_unset_breakpoint(target
, breakpoint
);
836 /* Setup single step breakpoint */
837 stepbreakpoint
.address
= address
;
838 stepbreakpoint
.length
= (armv7a
->core_state
== ARMV7A_STATE_THUMB
) ? 2 : 4;
839 stepbreakpoint
.type
= BKPT_HARD
;
840 stepbreakpoint
.set
= 0;
842 /* Break on IVA mismatch */
843 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
845 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
847 cortex_a8_resume(target
, 1, address
, 0, 0);
849 while (target
->state
!= TARGET_HALTED
)
851 cortex_a8_poll(target
);
854 LOG_WARNING("timeout waiting for target halt");
859 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
860 if (timeout
> 0) target
->debug_reason
= DBG_REASON_BREAKPOINT
;
863 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
865 if (target
->state
!= TARGET_HALTED
)
866 LOG_DEBUG("target stepped");
871 int cortex_a8_restore_context(target_t
*target
)
876 /* get pointers to arch-specific information */
877 armv4_5_common_t
*armv4_5
= target
->arch_info
;
878 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
882 if (armv7a
->pre_restore_context
)
883 armv7a
->pre_restore_context(target
);
885 for (i
= 15; i
>= 0; i
--)
887 if (ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
888 armv4_5
->core_mode
, i
).dirty
)
890 value
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
891 armv4_5
->core_mode
, i
).value
,
893 /* TODO Check return values */
894 cortex_a8_dap_write_coreregister_u32(target
, value
, i
);
898 if (armv7a
->post_restore_context
)
899 armv7a
->post_restore_context(target
);
906 * Cortex-A8 Core register functions
909 int cortex_a8_load_core_reg_u32(struct target_s
*target
, int num
,
910 armv4_5_mode_t mode
, uint32_t * value
)
913 /* get pointers to arch-specific information */
914 armv4_5_common_t
*armv4_5
= target
->arch_info
;
916 if ((num
<= ARM_CPSR
))
918 /* read a normal core register */
919 retval
= cortex_a8_dap_read_coreregister_u32(target
, value
, num
);
921 if (retval
!= ERROR_OK
)
923 LOG_ERROR("JTAG failure %i", retval
);
924 return ERROR_JTAG_DEVICE_ERROR
;
926 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
, num
, *value
);
930 return ERROR_INVALID_ARGUMENTS
;
933 /* Register other than r0 - r14 uses r0 for access */
935 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
936 armv4_5
->core_mode
, 0).dirty
=
937 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
938 armv4_5
->core_mode
, 0).valid
;
939 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
940 armv4_5
->core_mode
, 15).dirty
=
941 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
942 armv4_5
->core_mode
, 15).valid
;
947 int cortex_a8_store_core_reg_u32(struct target_s
*target
, int num
,
948 armv4_5_mode_t mode
, uint32_t value
)
953 /* get pointers to arch-specific information */
954 armv4_5_common_t
*armv4_5
= target
->arch_info
;
956 #ifdef ARMV7_GDB_HACKS
957 /* If the LR register is being modified, make sure it will put us
958 * in "thumb" mode, or an INVSTATE exception will occur. This is a
959 * hack to deal with the fact that gdb will sometimes "forge"
960 * return addresses, and doesn't set the LSB correctly (i.e., when
961 * printing expressions containing function calls, it sets LR=0.) */
967 if ((num
<= ARM_CPSR
))
969 retval
= cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
970 if (retval
!= ERROR_OK
)
972 LOG_ERROR("JTAG failure %i", retval
);
973 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
974 armv4_5
->core_mode
, num
).dirty
=
975 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
976 armv4_5
->core_mode
, num
).valid
;
977 return ERROR_JTAG_DEVICE_ERROR
;
979 LOG_DEBUG("write core reg %i value 0x%" PRIx32
, num
, value
);
983 return ERROR_INVALID_ARGUMENTS
;
990 int cortex_a8_read_core_reg(struct target_s
*target
, int num
,
991 enum armv4_5_mode mode
)
995 armv4_5_common_t
*armv4_5
= target
->arch_info
;
996 cortex_a8_dap_read_coreregister_u32(target
, &value
, num
);
998 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
1003 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
1004 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
1005 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
1006 mode
, num
).value
, 0, 32, value
);
1011 int cortex_a8_write_core_reg(struct target_s
*target
, int num
,
1012 enum armv4_5_mode mode
, uint32_t value
)
1015 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1017 cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
1018 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
1023 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
1024 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
1031 * Cortex-A8 Breakpoint and watchpoint fuctions
1034 /* Setup hardware Breakpoint Register Pair */
1035 int cortex_a8_set_breakpoint(struct target_s
*target
,
1036 breakpoint_t
*breakpoint
, uint8_t matchmode
)
1041 uint8_t byte_addr_select
= 0x0F;
1044 /* get pointers to arch-specific information */
1045 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1046 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1047 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1048 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
1050 if (breakpoint
->set
)
1052 LOG_WARNING("breakpoint already set");
1056 if (breakpoint
->type
== BKPT_HARD
)
1058 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
1060 if (brp_i
>= cortex_a8
->brp_num
)
1062 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1065 breakpoint
->set
= brp_i
+ 1;
1066 if (breakpoint
->length
== 2)
1068 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1070 control
= ((matchmode
& 0x7) << 20)
1071 | (byte_addr_select
<< 5)
1073 brp_list
[brp_i
].used
= 1;
1074 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1075 brp_list
[brp_i
].control
= control
;
1076 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1077 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1078 brp_list
[brp_i
].value
);
1079 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1080 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1081 brp_list
[brp_i
].control
);
1082 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1083 brp_list
[brp_i
].control
,
1084 brp_list
[brp_i
].value
);
1086 else if (breakpoint
->type
== BKPT_SOFT
)
1089 if (breakpoint
->length
== 2)
1091 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1095 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1097 retval
= target
->type
->read_memory(target
,
1098 breakpoint
->address
& 0xFFFFFFFE,
1099 breakpoint
->length
, 1,
1100 breakpoint
->orig_instr
);
1101 if (retval
!= ERROR_OK
)
1103 retval
= target
->type
->write_memory(target
,
1104 breakpoint
->address
& 0xFFFFFFFE,
1105 breakpoint
->length
, 1, code
);
1106 if (retval
!= ERROR_OK
)
1108 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1114 int cortex_a8_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1117 /* get pointers to arch-specific information */
1118 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1119 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1120 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1121 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
1123 if (!breakpoint
->set
)
1125 LOG_WARNING("breakpoint not set");
1129 if (breakpoint
->type
== BKPT_HARD
)
1131 int brp_i
= breakpoint
->set
- 1;
1132 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1134 LOG_DEBUG("Invalid BRP number in breakpoint");
1137 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1138 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1139 brp_list
[brp_i
].used
= 0;
1140 brp_list
[brp_i
].value
= 0;
1141 brp_list
[brp_i
].control
= 0;
1142 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1143 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1144 brp_list
[brp_i
].control
);
1145 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1146 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1147 brp_list
[brp_i
].value
);
1151 /* restore original instruction (kept in target endianness) */
1152 if (breakpoint
->length
== 4)
1154 retval
= target
->type
->write_memory(target
,
1155 breakpoint
->address
& 0xFFFFFFFE,
1156 4, 1, breakpoint
->orig_instr
);
1157 if (retval
!= ERROR_OK
)
1162 retval
= target
->type
->write_memory(target
,
1163 breakpoint
->address
& 0xFFFFFFFE,
1164 2, 1, breakpoint
->orig_instr
);
1165 if (retval
!= ERROR_OK
)
1169 breakpoint
->set
= 0;
1174 int cortex_a8_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1176 /* get pointers to arch-specific information */
1177 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1178 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1179 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1181 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1183 LOG_INFO("no hardware breakpoint available");
1184 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1187 if (breakpoint
->type
== BKPT_HARD
)
1188 cortex_a8
->brp_num_available
--;
1189 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1194 int cortex_a8_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1196 /* get pointers to arch-specific information */
1197 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1198 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1199 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1202 /* It is perfectly possible to remove brakpoints while the taget is running */
1203 if (target
->state
!= TARGET_HALTED
)
1205 LOG_WARNING("target not halted");
1206 return ERROR_TARGET_NOT_HALTED
;
1210 if (breakpoint
->set
)
1212 cortex_a8_unset_breakpoint(target
, breakpoint
);
1213 if (breakpoint
->type
== BKPT_HARD
)
1214 cortex_a8
->brp_num_available
++ ;
1224 * Cortex-A8 Reset fuctions
1227 int cortex_a8_assert_reset(target_t
*target
)
1232 /* registers are now invalid */
1233 armv4_5_invalidate_core_regs(target
);
1235 target
->state
= TARGET_RESET
;
1240 int cortex_a8_deassert_reset(target_t
*target
)
1245 if (target
->reset_halt
)
1248 if ((retval
= target_halt(target
)) != ERROR_OK
)
1256 * Cortex-A8 Memory access
1258 * This is same Cortex M3 but we must also use the correct
1259 * ap number for every access.
1262 int cortex_a8_read_memory(struct target_s
*target
, uint32_t address
,
1263 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1265 /* get pointers to arch-specific information */
1266 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1267 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1268 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1270 int retval
= ERROR_OK
;
1272 /* sanitize arguments */
1273 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1274 return ERROR_INVALID_ARGUMENTS
;
1276 /* cortex_a8 handles unaligned memory access */
1278 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1283 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1286 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1289 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1292 LOG_ERROR("BUG: we shouldn't get here");
1299 int cortex_a8_write_memory(struct target_s
*target
, uint32_t address
,
1300 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1302 /* get pointers to arch-specific information */
1303 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1304 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1305 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1309 /* sanitize arguments */
1310 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1311 return ERROR_INVALID_ARGUMENTS
;
1313 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1318 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1321 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1324 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1327 LOG_ERROR("BUG: we shouldn't get here");
1331 if (target
->state
== TARGET_HALTED
)
1333 /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */
1334 /* invalidate I-Cache */
1335 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
1337 /* Invalidate ICache single entry with MVA, repeat this for all cache
1338 lines in the address range, Cortex-A8 has fixed 64 byte line length */
1339 /* Invalidate Cache single entry with MVA to PoU */
1340 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1341 armv7a
->write_cp15(target
, 0, 1, 7, 5, cacheline
); /* I-Cache to PoU */
1343 /* invalidate D-Cache */
1344 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
1346 /* Invalidate Cache single entry with MVA to PoC */
1347 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1348 armv7a
->write_cp15(target
, 0, 1, 7, 6, cacheline
); /* U/D cache to PoC */
1355 int cortex_a8_bulk_write_memory(target_t
*target
, uint32_t address
,
1356 uint32_t count
, uint8_t *buffer
)
1358 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1362 int cortex_a8_dcc_read(swjdp_common_t
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1367 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1368 *ctrl
= (uint8_t)dcrdr
;
1369 *value
= (uint8_t)(dcrdr
>> 8);
1371 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1373 /* write ack back to software dcc register
1374 * signify we have read data */
1375 if (dcrdr
& (1 << 0))
1378 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1385 int cortex_a8_handle_target_request(void *priv
)
1387 target_t
*target
= priv
;
1388 if (!target
->type
->examined
)
1390 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1391 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1392 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1395 if (!target
->dbg_msg_enabled
)
1398 if (target
->state
== TARGET_RUNNING
)
1403 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1405 /* check if we have data */
1406 if (ctrl
& (1 << 0))
1410 /* we assume target is quick enough */
1412 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1413 request
|= (data
<< 8);
1414 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1415 request
|= (data
<< 16);
1416 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1417 request
|= (data
<< 24);
1418 target_request(target
, request
);
1426 * Cortex-A8 target information and configuration
1429 int cortex_a8_examine(struct target_s
*target
)
1431 /* get pointers to arch-specific information */
1432 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1433 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1434 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1435 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1439 int retval
= ERROR_OK
;
1440 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1444 /* Here we shall insert a proper ROM Table scan */
1445 armv7a
->debug_base
= OMAP3530_DEBUG_BASE
;
1447 /* We do one extra read to ensure DAP is configured,
1448 * we call ahbap_debugport_init(swjdp) instead
1450 ahbap_debugport_init(swjdp
);
1451 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
1452 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1453 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1455 LOG_DEBUG("Examine failed");
1459 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1460 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1462 LOG_DEBUG("Examine failed");
1466 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1467 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1469 LOG_DEBUG("Examine failed");
1473 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1474 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1476 LOG_DEBUG("Examine failed");
1480 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1481 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1482 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1483 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1485 /* Setup Breakpoint Register Pairs */
1486 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1487 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1488 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1489 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(cortex_a8_brp_t
));
1490 // cortex_a8->brb_enabled = ????;
1491 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1493 cortex_a8
->brp_list
[i
].used
= 0;
1494 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1495 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1497 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1498 cortex_a8
->brp_list
[i
].value
= 0;
1499 cortex_a8
->brp_list
[i
].control
= 0;
1500 cortex_a8
->brp_list
[i
].BRPn
= i
;
1503 /* Setup Watchpoint Register Pairs */
1504 cortex_a8
->wrp_num
= ((didr
>> 28) & 0x0F) + 1;
1505 cortex_a8
->wrp_num_available
= cortex_a8
->wrp_num
;
1506 cortex_a8
->wrp_list
= calloc(cortex_a8
->wrp_num
, sizeof(cortex_a8_wrp_t
));
1507 for (i
= 0; i
< cortex_a8
->wrp_num
; i
++)
1509 cortex_a8
->wrp_list
[i
].used
= 0;
1510 cortex_a8
->wrp_list
[i
].type
= 0;
1511 cortex_a8
->wrp_list
[i
].value
= 0;
1512 cortex_a8
->wrp_list
[i
].control
= 0;
1513 cortex_a8
->wrp_list
[i
].WRPn
= i
;
1515 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1516 cortex_a8
->brp_num
, cortex_a8
->wrp_num
);
1518 /* Configure core debug access */
1519 cortex_a8_init_debug_access(target
);
1521 target
->type
->examined
= 1;
1527 * Cortex-A8 target creation and initialization
1530 void cortex_a8_build_reg_cache(target_t
*target
)
1532 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1533 /* get pointers to arch-specific information */
1534 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1536 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
1537 armv4_5
->core_cache
= (*cache_p
);
1541 int cortex_a8_init_target(struct command_context_s
*cmd_ctx
,
1542 struct target_s
*target
)
1544 cortex_a8_build_reg_cache(target
);
1548 int cortex_a8_init_arch_info(target_t
*target
,
1549 cortex_a8_common_t
*cortex_a8
, jtag_tap_t
*tap
)
1551 armv4_5_common_t
*armv4_5
;
1552 armv7a_common_t
*armv7a
;
1554 armv7a
= &cortex_a8
->armv7a_common
;
1555 armv4_5
= &armv7a
->armv4_5_common
;
1556 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1558 /* Setup cortex_a8_common_t */
1559 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1560 cortex_a8
->arch_info
= NULL
;
1561 armv7a
->arch_info
= cortex_a8
;
1562 armv4_5
->arch_info
= armv7a
;
1564 armv4_5_init_arch_info(target
, armv4_5
);
1566 /* prepare JTAG information for the new target */
1567 cortex_a8
->jtag_info
.tap
= tap
;
1568 cortex_a8
->jtag_info
.scann_size
= 4;
1570 swjdp
->dp_select_value
= -1;
1571 swjdp
->ap_csw_value
= -1;
1572 swjdp
->ap_tar_value
= -1;
1573 swjdp
->jtag_info
= &cortex_a8
->jtag_info
;
1574 swjdp
->memaccess_tck
= 80;
1576 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1577 swjdp
->tar_autoincr_block
= (1 << 10);
1579 cortex_a8
->fast_reg_read
= 0;
1582 /* register arch-specific functions */
1583 armv7a
->examine_debug_reason
= NULL
;
1585 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1587 armv7a
->pre_restore_context
= NULL
;
1588 armv7a
->post_restore_context
= NULL
;
1589 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1590 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1591 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_memory
;
1592 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_memory
;
1593 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1594 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1595 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1596 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1597 armv7a
->read_cp15
= cortex_a8_read_cp15
;
1598 armv7a
->write_cp15
= cortex_a8_write_cp15
;
1601 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1603 armv4_5
->read_core_reg
= cortex_a8_read_core_reg
;
1604 armv4_5
->write_core_reg
= cortex_a8_write_core_reg
;
1605 // armv4_5->full_context = arm7_9_full_context;
1607 // armv4_5->load_core_reg_u32 = cortex_a8_load_core_reg_u32;
1608 // armv4_5->store_core_reg_u32 = cortex_a8_store_core_reg_u32;
1609 // armv4_5->read_core_reg = armv4_5_read_core_reg; /* this is default */
1610 // armv4_5->write_core_reg = armv4_5_write_core_reg;
1612 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1617 int cortex_a8_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1619 cortex_a8_common_t
*cortex_a8
= calloc(1, sizeof(cortex_a8_common_t
));
1621 cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1626 static int cortex_a8_handle_cache_info_command(struct command_context_s
*cmd_ctx
,
1627 char *cmd
, char **args
, int argc
)
1629 target_t
*target
= get_current_target(cmd_ctx
);
1630 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1631 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1633 return armv4_5_handle_cache_info_command(cmd_ctx
,
1634 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1638 static int cortex_a8_handle_dbginit_command(struct command_context_s
*cmd_ctx
,
1639 char *cmd
, char **args
, int argc
)
1641 target_t
*target
= get_current_target(cmd_ctx
);
1643 cortex_a8_init_debug_access(target
);
1649 int cortex_a8_register_commands(struct command_context_s
*cmd_ctx
)
1651 command_t
*cortex_a8_cmd
;
1652 int retval
= ERROR_OK
;
1654 armv4_5_register_commands(cmd_ctx
);
1655 armv7a_register_commands(cmd_ctx
);
1657 cortex_a8_cmd
= register_command(cmd_ctx
, NULL
, "cortex_a8",
1659 "cortex_a8 specific commands");
1661 register_command(cmd_ctx
, cortex_a8_cmd
, "cache_info",
1662 cortex_a8_handle_cache_info_command
, COMMAND_EXEC
,
1663 "display information about target caches");
1665 register_command(cmd_ctx
, cortex_a8_cmd
, "dbginit",
1666 cortex_a8_handle_dbginit_command
, COMMAND_EXEC
,
1667 "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)