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
,
113 * FIXME do topology discovery using the ROM; don't
114 * assume this is an OMAP3.
116 #define swjdp_memoryap 0
117 #define swjdp_debugap 1
118 #define OMAP3530_DEBUG_BASE 0x54011000
121 * Cortex-A8 Basic debug access, very low level assumes state is saved
123 int cortex_a8_init_debug_access(target_t
*target
)
125 /* get pointers to arch-specific information */
126 armv4_5_common_t
*armv4_5
= target
->arch_info
;
127 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
128 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
135 /* Unlocking the debug registers for modification */
136 /* The debugport might be uninitialised so try twice */
137 retval
= mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
138 if (retval
!= ERROR_OK
)
139 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
140 /* Clear Sticky Power Down status Bit in PRSR to enable access to
141 the registers in the Core Power Domain */
142 retval
= mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_PRSR
, &dummy
);
143 /* Enabling of instruction execution in debug mode is done in debug_entry code */
145 /* Resync breakpoint registers */
147 /* Since this is likley called from init or reset, update targtet state information*/
148 cortex_a8_poll(target
);
153 int cortex_a8_exec_opcode(target_t
*target
, uint32_t opcode
)
157 /* get pointers to arch-specific information */
158 armv4_5_common_t
*armv4_5
= target
->arch_info
;
159 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
160 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
162 LOG_DEBUG("exec opcode 0x%08" PRIx32
, opcode
);
165 retval
= mem_ap_read_atomic_u32(swjdp
,
166 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
167 if (retval
!= ERROR_OK
)
169 LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32
, opcode
);
173 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
175 mem_ap_write_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_ITR
, opcode
);
179 retval
= mem_ap_read_atomic_u32(swjdp
,
180 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
181 if (retval
!= ERROR_OK
)
183 LOG_ERROR("Could not read DSCR register");
187 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
192 /**************************************************************************
193 Read core register with very few exec_opcode, fast but needs work_area.
194 This can cause problems with MMU active.
195 **************************************************************************/
196 int cortex_a8_read_regs_through_mem(target_t
*target
, uint32_t address
,
199 int retval
= ERROR_OK
;
200 /* get pointers to arch-specific information */
201 armv4_5_common_t
*armv4_5
= target
->arch_info
;
202 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
203 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
205 cortex_a8_dap_read_coreregister_u32(target
, regfile
, 0);
206 cortex_a8_dap_write_coreregister_u32(target
, address
, 0);
207 cortex_a8_exec_opcode(target
, ARMV4_5_STMIA(0, 0xFFFE, 0, 0));
208 dap_ap_select(swjdp
, swjdp_memoryap
);
209 mem_ap_read_buf_u32(swjdp
, (uint8_t *)(®file
[1]), 4*15, address
);
210 dap_ap_select(swjdp
, swjdp_debugap
);
215 int cortex_a8_read_cp(target_t
*target
, uint32_t *value
, uint8_t CP
,
216 uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
219 /* get pointers to arch-specific information */
220 armv4_5_common_t
*armv4_5
= target
->arch_info
;
221 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
222 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
224 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(CP
, op1
, 0, CRn
, CRm
, op2
));
225 /* Move R0 to DTRTX */
226 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
229 retval
= mem_ap_read_atomic_u32(swjdp
,
230 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
235 int cortex_a8_write_cp(target_t
*target
, uint32_t value
,
236 uint8_t CP
, uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
241 /* get pointers to arch-specific information */
242 armv4_5_common_t
*armv4_5
= target
->arch_info
;
243 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
244 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
246 LOG_DEBUG("CP%i, CRn %i, value 0x%08" PRIx32
, CP
, CRn
, value
);
248 /* Check that DCCRX is not full */
249 retval
= mem_ap_read_atomic_u32(swjdp
,
250 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
251 if (dscr
& (1 << DSCR_DTR_RX_FULL
))
253 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
254 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
255 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
258 retval
= mem_ap_write_u32(swjdp
,
259 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
260 /* Move DTRRX to r0 */
261 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
263 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(CP
, op1
, 0, CRn
, CRm
, op2
));
267 int cortex_a8_read_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
268 uint32_t CRn
, uint32_t CRm
, uint32_t *value
)
270 return cortex_a8_read_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
273 int cortex_a8_write_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
274 uint32_t CRn
, uint32_t CRm
, uint32_t value
)
276 return cortex_a8_write_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
279 int cortex_a8_dap_read_coreregister_u32(target_t
*target
,
280 uint32_t *value
, int regnum
)
282 int retval
= ERROR_OK
;
283 uint8_t reg
= regnum
&0xFF;
286 /* get pointers to arch-specific information */
287 armv4_5_common_t
*armv4_5
= target
->arch_info
;
288 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
289 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
296 /* Rn to DCCTX, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
297 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, reg
, 0, 5, 0));
301 cortex_a8_exec_opcode(target
, 0xE1A0000F);
302 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
306 cortex_a8_exec_opcode(target
, ARMV4_5_MRS(0, 0));
307 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
313 retval
= mem_ap_read_atomic_u32(swjdp
,
314 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
316 while ((dscr
& (1 << DSCR_DTR_TX_FULL
)) == 0); /* Wait for DTRRXfull */
318 retval
= mem_ap_read_atomic_u32(swjdp
,
319 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
324 int cortex_a8_dap_write_coreregister_u32(target_t
*target
, uint32_t value
, int regnum
)
326 int retval
= ERROR_OK
;
327 uint8_t Rd
= regnum
&0xFF;
330 /* get pointers to arch-specific information */
331 armv4_5_common_t
*armv4_5
= target
->arch_info
;
332 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
333 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
335 LOG_DEBUG("register %i, value 0x%08" PRIx32
, regnum
, value
);
337 /* Check that DCCRX is not full */
338 retval
= mem_ap_read_atomic_u32(swjdp
,
339 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
340 if (dscr
& (1 << DSCR_DTR_RX_FULL
))
342 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
343 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
344 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
351 retval
= mem_ap_write_u32(swjdp
,
352 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
356 /* DCCRX to Rd, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
357 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, Rd
, 0, 5, 0));
361 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
362 cortex_a8_exec_opcode(target
, 0xE1A0F000);
366 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
367 cortex_a8_exec_opcode(target
, ARMV4_5_MSR_GP(0, 0xF, 0));
368 /* Execute a PrefetchFlush instruction through the ITR. */
369 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(15, 0, 0, 7, 5, 4));
375 /* Write to memory mapped registers directly with no cache or mmu handling */
376 int cortex_a8_dap_write_memap_register_u32(target_t
*target
, uint32_t address
, uint32_t value
)
380 /* get pointers to arch-specific information */
381 armv4_5_common_t
*armv4_5
= target
->arch_info
;
382 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
383 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
385 retval
= mem_ap_write_atomic_u32(swjdp
, address
, value
);
391 * Cortex-A8 Run control
394 int cortex_a8_poll(target_t
*target
)
396 int retval
= ERROR_OK
;
398 /* get pointers to arch-specific information */
399 armv4_5_common_t
*armv4_5
= target
->arch_info
;
400 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
401 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
402 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
405 enum target_state prev_target_state
= target
->state
;
407 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
408 dap_ap_select(swjdp
, swjdp_debugap
);
409 retval
= mem_ap_read_atomic_u32(swjdp
,
410 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
411 if (retval
!= ERROR_OK
)
413 dap_ap_select(swjdp
, saved_apsel
);
416 cortex_a8
->cpudbg_dscr
= dscr
;
418 if ((dscr
& 0x3) == 0x3)
420 if (prev_target_state
!= TARGET_HALTED
)
422 /* We have a halting debug event */
423 LOG_DEBUG("Target halted");
424 target
->state
= TARGET_HALTED
;
425 if ((prev_target_state
== TARGET_RUNNING
)
426 || (prev_target_state
== TARGET_RESET
))
428 retval
= cortex_a8_debug_entry(target
);
429 if (retval
!= ERROR_OK
)
432 target_call_event_callbacks(target
,
433 TARGET_EVENT_HALTED
);
435 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
439 retval
= cortex_a8_debug_entry(target
);
440 if (retval
!= ERROR_OK
)
443 target_call_event_callbacks(target
,
444 TARGET_EVENT_DEBUG_HALTED
);
448 else if ((dscr
& 0x3) == 0x2)
450 target
->state
= TARGET_RUNNING
;
454 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32
, dscr
);
455 target
->state
= TARGET_UNKNOWN
;
458 dap_ap_select(swjdp
, saved_apsel
);
463 int cortex_a8_halt(target_t
*target
)
465 int retval
= ERROR_OK
;
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 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
474 dap_ap_select(swjdp
, swjdp_debugap
);
477 * Tell the core to be halted by writing DRCR with 0x1
478 * and then wait for the core to be halted.
480 retval
= mem_ap_write_atomic_u32(swjdp
,
481 armv7a
->debug_base
+ CPUDBG_DRCR
, 0x1);
484 * enter halting debug mode
486 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
487 retval
= mem_ap_write_atomic_u32(swjdp
,
488 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
| (1 << DSCR_HALT_DBG_MODE
));
490 if (retval
!= ERROR_OK
)
494 mem_ap_read_atomic_u32(swjdp
,
495 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
496 } while ((dscr
& (1 << DSCR_CORE_HALTED
)) == 0);
498 target
->debug_reason
= DBG_REASON_DBGRQ
;
501 dap_ap_select(swjdp
, saved_apsel
);
505 int cortex_a8_resume(struct target_s
*target
, int current
,
506 uint32_t address
, int handle_breakpoints
, int debug_execution
)
508 /* get pointers to arch-specific information */
509 armv4_5_common_t
*armv4_5
= target
->arch_info
;
510 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
511 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
513 // breakpoint_t *breakpoint = NULL;
514 uint32_t resume_pc
, dscr
;
516 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
517 dap_ap_select(swjdp
, swjdp_debugap
);
519 if (!debug_execution
)
521 target_free_all_working_areas(target
);
522 // cortex_m3_enable_breakpoints(target);
523 // cortex_m3_enable_watchpoints(target);
529 /* Disable interrupts */
530 /* We disable interrupts in the PRIMASK register instead of
531 * masking with C_MASKINTS,
532 * This is probably the same issue as Cortex-M3 Errata 377493:
533 * C_MASKINTS in parallel with disabled interrupts can cause
534 * local faults to not be taken. */
535 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
536 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
537 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
539 /* Make sure we are in Thumb mode */
540 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
541 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
542 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
543 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
547 /* current = 1: continue on current pc, otherwise continue at <address> */
548 resume_pc
= buf_get_u32(
549 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
550 armv4_5
->core_mode
, 15).value
,
555 /* Make sure that the Armv7 gdb thumb fixups does not
556 * kill the return address
558 if (armv7a
->core_state
== ARMV7A_STATE_ARM
)
560 resume_pc
&= 0xFFFFFFFC;
562 /* When the return address is loaded into PC
563 * bit 0 must be 1 to stay in Thumb state
565 if (armv7a
->core_state
== ARMV7A_STATE_THUMB
)
569 LOG_DEBUG("resume pc = 0x%08" PRIx32
, resume_pc
);
570 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
571 armv4_5
->core_mode
, 15).value
,
573 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
574 armv4_5
->core_mode
, 15).dirty
= 1;
575 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
576 armv4_5
->core_mode
, 15).valid
= 1;
578 cortex_a8_restore_context(target
);
579 // arm7_9_restore_context(target); TODO Context is currently NOT Properly restored
581 /* the front-end may request us not to handle breakpoints */
582 if (handle_breakpoints
)
584 /* Single step past breakpoint at current address */
585 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
587 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
588 cortex_m3_unset_breakpoint(target
, breakpoint
);
589 cortex_m3_single_step_core(target
);
590 cortex_m3_set_breakpoint(target
, breakpoint
);
595 /* Restart core and wait for it to be started */
596 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DRCR
, 0x2);
599 mem_ap_read_atomic_u32(swjdp
,
600 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
601 } while ((dscr
& (1 << DSCR_CORE_RESTARTED
)) == 0);
603 target
->debug_reason
= DBG_REASON_NOTHALTED
;
604 target
->state
= TARGET_RUNNING
;
606 /* registers are now invalid */
607 armv4_5_invalidate_core_regs(target
);
609 if (!debug_execution
)
611 target
->state
= TARGET_RUNNING
;
612 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
613 LOG_DEBUG("target resumed at 0x%" PRIx32
, resume_pc
);
617 target
->state
= TARGET_DEBUG_RUNNING
;
618 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
619 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, resume_pc
);
622 dap_ap_select(swjdp
, saved_apsel
);
627 int cortex_a8_debug_entry(target_t
*target
)
630 uint32_t regfile
[16], pc
, cpsr
, dscr
;
631 int retval
= ERROR_OK
;
632 working_area_t
*regfile_working_area
= NULL
;
634 /* get pointers to arch-specific information */
635 armv4_5_common_t
*armv4_5
= target
->arch_info
;
636 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
637 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
638 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
640 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
642 /* Enable the ITR execution once we are in debug mode */
643 mem_ap_read_atomic_u32(swjdp
,
644 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
645 dscr
|= (1 << DSCR_EXT_INT_EN
);
646 retval
= mem_ap_write_atomic_u32(swjdp
,
647 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
);
649 /* Examine debug reason */
650 switch ((cortex_a8
->cpudbg_dscr
>> 2)&0xF)
654 target
->debug_reason
= DBG_REASON_DBGRQ
;
658 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
661 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
664 target
->debug_reason
= DBG_REASON_UNDEFINED
;
668 /* Examine target state and mode */
669 if (cortex_a8
->fast_reg_read
)
670 target_alloc_working_area(target
, 64, ®file_working_area
);
672 /* First load register acessible through core debug port*/
673 if (!regfile_working_area
)
675 for (i
= 0; i
<= 15; i
++)
676 cortex_a8_dap_read_coreregister_u32(target
,
681 dap_ap_select(swjdp
, swjdp_memoryap
);
682 cortex_a8_read_regs_through_mem(target
,
683 regfile_working_area
->address
, regfile
);
684 dap_ap_select(swjdp
, swjdp_memoryap
);
685 target_free_working_area(target
, regfile_working_area
);
688 cortex_a8_dap_read_coreregister_u32(target
, &cpsr
, 16);
690 dap_ap_select(swjdp
, swjdp_debugap
);
691 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
693 armv4_5
->core_mode
= cpsr
& 0x1F;
694 armv7a
->core_state
= (cpsr
& 0x20)?ARMV7A_STATE_THUMB
:ARMV7A_STATE_ARM
;
696 for (i
= 0; i
<= ARM_PC
; i
++)
698 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
699 armv4_5
->core_mode
, i
).value
,
701 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
702 armv4_5
->core_mode
, i
).valid
= 1;
703 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
704 armv4_5
->core_mode
, i
).dirty
= 0;
706 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
707 armv4_5
->core_mode
, 16).value
,
709 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
710 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
712 /* Fixup PC Resume Address */
713 if (armv7a
->core_state
== ARMV7A_STATE_THUMB
)
715 // T bit set for Thumb or ThumbEE state
716 regfile
[ARM_PC
] -= 4;
721 regfile
[ARM_PC
] -= 8;
723 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
724 armv4_5
->core_mode
, ARM_PC
).value
,
725 0, 32, regfile
[ARM_PC
]);
727 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 0)
728 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
729 armv4_5
->core_mode
, 0).valid
;
730 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 15)
731 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
732 armv4_5
->core_mode
, 15).valid
;
735 /* TODO, Move this */
736 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
737 cortex_a8_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
738 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
740 cortex_a8_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
741 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
743 cortex_a8_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
744 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
747 /* Are we in an exception handler */
748 // armv4_5->exception_number = 0;
749 if (armv7a
->post_debug_entry
)
750 armv7a
->post_debug_entry(target
);
758 void cortex_a8_post_debug_entry(target_t
*target
)
760 /* get pointers to arch-specific information */
761 armv4_5_common_t
*armv4_5
= target
->arch_info
;
762 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
763 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
765 // cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
766 /* examine cp15 control reg */
767 armv7a
->read_cp15(target
, 0, 0, 1, 0, &cortex_a8
->cp15_control_reg
);
768 jtag_execute_queue();
769 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
771 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
773 uint32_t cache_type_reg
;
774 /* identify caches */
775 armv7a
->read_cp15(target
, 0, 1, 0, 0, &cache_type_reg
);
776 jtag_execute_queue();
777 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
778 armv4_5_identify_cache(cache_type_reg
,
779 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
782 armv7a
->armv4_5_mmu
.mmu_enabled
=
783 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
784 armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
=
785 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
786 armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
=
787 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
792 int cortex_a8_step(struct target_s
*target
, int current
, uint32_t address
,
793 int handle_breakpoints
)
795 /* get pointers to arch-specific information */
796 armv4_5_common_t
*armv4_5
= target
->arch_info
;
797 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
798 breakpoint_t
*breakpoint
= NULL
;
799 breakpoint_t stepbreakpoint
;
803 if (target
->state
!= TARGET_HALTED
)
805 LOG_WARNING("target not halted");
806 return ERROR_TARGET_NOT_HALTED
;
809 /* current = 1: continue on current pc, otherwise continue at <address> */
812 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
813 armv4_5
->core_mode
, ARM_PC
).value
,
818 address
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
819 armv4_5
->core_mode
, ARM_PC
).value
,
823 /* The front-end may request us not to handle breakpoints.
824 * But since Cortex-A8 uses breakpoint for single step,
825 * we MUST handle breakpoints.
827 handle_breakpoints
= 1;
828 if (handle_breakpoints
) {
829 breakpoint
= breakpoint_find(target
,
830 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
831 armv4_5
->core_mode
, 15).value
,
834 cortex_a8_unset_breakpoint(target
, breakpoint
);
837 /* Setup single step breakpoint */
838 stepbreakpoint
.address
= address
;
839 stepbreakpoint
.length
= (armv7a
->core_state
== ARMV7A_STATE_THUMB
) ? 2 : 4;
840 stepbreakpoint
.type
= BKPT_HARD
;
841 stepbreakpoint
.set
= 0;
843 /* Break on IVA mismatch */
844 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
846 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
848 cortex_a8_resume(target
, 1, address
, 0, 0);
850 while (target
->state
!= TARGET_HALTED
)
852 cortex_a8_poll(target
);
855 LOG_WARNING("timeout waiting for target halt");
860 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
861 if (timeout
> 0) target
->debug_reason
= DBG_REASON_BREAKPOINT
;
864 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
866 if (target
->state
!= TARGET_HALTED
)
867 LOG_DEBUG("target stepped");
872 int cortex_a8_restore_context(target_t
*target
)
877 /* get pointers to arch-specific information */
878 armv4_5_common_t
*armv4_5
= target
->arch_info
;
879 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
883 if (armv7a
->pre_restore_context
)
884 armv7a
->pre_restore_context(target
);
886 for (i
= 15; i
>= 0; i
--)
888 if (ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
889 armv4_5
->core_mode
, i
).dirty
)
891 value
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
892 armv4_5
->core_mode
, i
).value
,
894 /* TODO Check return values */
895 cortex_a8_dap_write_coreregister_u32(target
, value
, i
);
899 if (armv7a
->post_restore_context
)
900 armv7a
->post_restore_context(target
);
907 * Cortex-A8 Core register functions
910 int cortex_a8_load_core_reg_u32(struct target_s
*target
, int num
,
911 armv4_5_mode_t mode
, uint32_t * value
)
914 /* get pointers to arch-specific information */
915 armv4_5_common_t
*armv4_5
= target
->arch_info
;
917 if ((num
<= ARM_CPSR
))
919 /* read a normal core register */
920 retval
= cortex_a8_dap_read_coreregister_u32(target
, value
, num
);
922 if (retval
!= ERROR_OK
)
924 LOG_ERROR("JTAG failure %i", retval
);
925 return ERROR_JTAG_DEVICE_ERROR
;
927 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
, num
, *value
);
931 return ERROR_INVALID_ARGUMENTS
;
934 /* Register other than r0 - r14 uses r0 for access */
936 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
937 armv4_5
->core_mode
, 0).dirty
=
938 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
939 armv4_5
->core_mode
, 0).valid
;
940 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
941 armv4_5
->core_mode
, 15).dirty
=
942 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
943 armv4_5
->core_mode
, 15).valid
;
948 int cortex_a8_store_core_reg_u32(struct target_s
*target
, int num
,
949 armv4_5_mode_t mode
, uint32_t value
)
954 /* get pointers to arch-specific information */
955 armv4_5_common_t
*armv4_5
= target
->arch_info
;
957 #ifdef ARMV7_GDB_HACKS
958 /* If the LR register is being modified, make sure it will put us
959 * in "thumb" mode, or an INVSTATE exception will occur. This is a
960 * hack to deal with the fact that gdb will sometimes "forge"
961 * return addresses, and doesn't set the LSB correctly (i.e., when
962 * printing expressions containing function calls, it sets LR=0.) */
968 if ((num
<= ARM_CPSR
))
970 retval
= cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
971 if (retval
!= ERROR_OK
)
973 LOG_ERROR("JTAG failure %i", retval
);
974 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
975 armv4_5
->core_mode
, num
).dirty
=
976 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
977 armv4_5
->core_mode
, num
).valid
;
978 return ERROR_JTAG_DEVICE_ERROR
;
980 LOG_DEBUG("write core reg %i value 0x%" PRIx32
, num
, value
);
984 return ERROR_INVALID_ARGUMENTS
;
991 int cortex_a8_read_core_reg(struct target_s
*target
, int num
,
992 enum armv4_5_mode mode
)
996 armv4_5_common_t
*armv4_5
= target
->arch_info
;
997 cortex_a8_dap_read_coreregister_u32(target
, &value
, num
);
999 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
1004 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
1005 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
1006 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
1007 mode
, num
).value
, 0, 32, value
);
1012 int cortex_a8_write_core_reg(struct target_s
*target
, int num
,
1013 enum armv4_5_mode mode
, uint32_t value
)
1016 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1018 cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
1019 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
1024 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
1025 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
1032 * Cortex-A8 Breakpoint and watchpoint fuctions
1035 /* Setup hardware Breakpoint Register Pair */
1036 int cortex_a8_set_breakpoint(struct target_s
*target
,
1037 breakpoint_t
*breakpoint
, uint8_t matchmode
)
1042 uint8_t byte_addr_select
= 0x0F;
1045 /* get pointers to arch-specific information */
1046 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1047 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1048 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1049 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
1051 if (breakpoint
->set
)
1053 LOG_WARNING("breakpoint already set");
1057 if (breakpoint
->type
== BKPT_HARD
)
1059 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
1061 if (brp_i
>= cortex_a8
->brp_num
)
1063 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1066 breakpoint
->set
= brp_i
+ 1;
1067 if (breakpoint
->length
== 2)
1069 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1071 control
= ((matchmode
& 0x7) << 20)
1072 | (byte_addr_select
<< 5)
1074 brp_list
[brp_i
].used
= 1;
1075 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1076 brp_list
[brp_i
].control
= control
;
1077 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1078 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1079 brp_list
[brp_i
].value
);
1080 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1081 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1082 brp_list
[brp_i
].control
);
1083 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1084 brp_list
[brp_i
].control
,
1085 brp_list
[brp_i
].value
);
1087 else if (breakpoint
->type
== BKPT_SOFT
)
1090 if (breakpoint
->length
== 2)
1092 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1096 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1098 retval
= target
->type
->read_memory(target
,
1099 breakpoint
->address
& 0xFFFFFFFE,
1100 breakpoint
->length
, 1,
1101 breakpoint
->orig_instr
);
1102 if (retval
!= ERROR_OK
)
1104 retval
= target
->type
->write_memory(target
,
1105 breakpoint
->address
& 0xFFFFFFFE,
1106 breakpoint
->length
, 1, code
);
1107 if (retval
!= ERROR_OK
)
1109 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1115 int cortex_a8_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1118 /* get pointers to arch-specific information */
1119 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1120 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1121 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1122 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
1124 if (!breakpoint
->set
)
1126 LOG_WARNING("breakpoint not set");
1130 if (breakpoint
->type
== BKPT_HARD
)
1132 int brp_i
= breakpoint
->set
- 1;
1133 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1135 LOG_DEBUG("Invalid BRP number in breakpoint");
1138 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1139 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1140 brp_list
[brp_i
].used
= 0;
1141 brp_list
[brp_i
].value
= 0;
1142 brp_list
[brp_i
].control
= 0;
1143 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1144 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1145 brp_list
[brp_i
].control
);
1146 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1147 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1148 brp_list
[brp_i
].value
);
1152 /* restore original instruction (kept in target endianness) */
1153 if (breakpoint
->length
== 4)
1155 retval
= target
->type
->write_memory(target
,
1156 breakpoint
->address
& 0xFFFFFFFE,
1157 4, 1, breakpoint
->orig_instr
);
1158 if (retval
!= ERROR_OK
)
1163 retval
= target
->type
->write_memory(target
,
1164 breakpoint
->address
& 0xFFFFFFFE,
1165 2, 1, breakpoint
->orig_instr
);
1166 if (retval
!= ERROR_OK
)
1170 breakpoint
->set
= 0;
1175 int cortex_a8_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1177 /* get pointers to arch-specific information */
1178 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1179 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1180 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1182 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1184 LOG_INFO("no hardware breakpoint available");
1185 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1188 if (breakpoint
->type
== BKPT_HARD
)
1189 cortex_a8
->brp_num_available
--;
1190 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1195 int cortex_a8_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1197 /* get pointers to arch-specific information */
1198 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1199 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1200 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1203 /* It is perfectly possible to remove brakpoints while the taget is running */
1204 if (target
->state
!= TARGET_HALTED
)
1206 LOG_WARNING("target not halted");
1207 return ERROR_TARGET_NOT_HALTED
;
1211 if (breakpoint
->set
)
1213 cortex_a8_unset_breakpoint(target
, breakpoint
);
1214 if (breakpoint
->type
== BKPT_HARD
)
1215 cortex_a8
->brp_num_available
++ ;
1225 * Cortex-A8 Reset fuctions
1228 int cortex_a8_assert_reset(target_t
*target
)
1233 /* registers are now invalid */
1234 armv4_5_invalidate_core_regs(target
);
1236 target
->state
= TARGET_RESET
;
1241 int cortex_a8_deassert_reset(target_t
*target
)
1246 if (target
->reset_halt
)
1249 if ((retval
= target_halt(target
)) != ERROR_OK
)
1257 * Cortex-A8 Memory access
1259 * This is same Cortex M3 but we must also use the correct
1260 * ap number for every access.
1263 int cortex_a8_read_memory(struct target_s
*target
, uint32_t address
,
1264 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1266 /* get pointers to arch-specific information */
1267 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1268 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1269 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1271 int retval
= ERROR_OK
;
1273 /* sanitize arguments */
1274 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1275 return ERROR_INVALID_ARGUMENTS
;
1277 /* cortex_a8 handles unaligned memory access */
1279 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1284 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1287 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1290 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1293 LOG_ERROR("BUG: we shouldn't get here");
1300 int cortex_a8_write_memory(struct target_s
*target
, uint32_t address
,
1301 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1303 /* get pointers to arch-specific information */
1304 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1305 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1306 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1310 /* sanitize arguments */
1311 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1312 return ERROR_INVALID_ARGUMENTS
;
1314 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1319 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1322 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1325 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1328 LOG_ERROR("BUG: we shouldn't get here");
1332 if (target
->state
== TARGET_HALTED
)
1334 /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */
1335 /* invalidate I-Cache */
1336 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
1338 /* Invalidate ICache single entry with MVA, repeat this for all cache
1339 lines in the address range, Cortex-A8 has fixed 64 byte line length */
1340 /* Invalidate Cache single entry with MVA to PoU */
1341 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1342 armv7a
->write_cp15(target
, 0, 1, 7, 5, cacheline
); /* I-Cache to PoU */
1344 /* invalidate D-Cache */
1345 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
1347 /* Invalidate Cache single entry with MVA to PoC */
1348 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1349 armv7a
->write_cp15(target
, 0, 1, 7, 6, cacheline
); /* U/D cache to PoC */
1356 int cortex_a8_bulk_write_memory(target_t
*target
, uint32_t address
,
1357 uint32_t count
, uint8_t *buffer
)
1359 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1363 int cortex_a8_dcc_read(swjdp_common_t
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1368 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1369 *ctrl
= (uint8_t)dcrdr
;
1370 *value
= (uint8_t)(dcrdr
>> 8);
1372 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1374 /* write ack back to software dcc register
1375 * signify we have read data */
1376 if (dcrdr
& (1 << 0))
1379 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1386 int cortex_a8_handle_target_request(void *priv
)
1388 target_t
*target
= priv
;
1389 if (!target
->type
->examined
)
1391 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1392 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1393 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1396 if (!target
->dbg_msg_enabled
)
1399 if (target
->state
== TARGET_RUNNING
)
1404 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1406 /* check if we have data */
1407 if (ctrl
& (1 << 0))
1411 /* we assume target is quick enough */
1413 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1414 request
|= (data
<< 8);
1415 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1416 request
|= (data
<< 16);
1417 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1418 request
|= (data
<< 24);
1419 target_request(target
, request
);
1427 * Cortex-A8 target information and configuration
1430 int cortex_a8_examine(struct target_s
*target
)
1432 /* get pointers to arch-specific information */
1433 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1434 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1435 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1436 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1440 int retval
= ERROR_OK
;
1441 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1445 /* Here we shall insert a proper ROM Table scan */
1446 armv7a
->debug_base
= OMAP3530_DEBUG_BASE
;
1448 /* We do one extra read to ensure DAP is configured,
1449 * we call ahbap_debugport_init(swjdp) instead
1451 ahbap_debugport_init(swjdp
);
1452 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
1453 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1454 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1456 LOG_DEBUG("Examine failed");
1460 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1461 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1463 LOG_DEBUG("Examine failed");
1467 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1468 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1470 LOG_DEBUG("Examine failed");
1474 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1475 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1477 LOG_DEBUG("Examine failed");
1481 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1482 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1483 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1484 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1486 /* Setup Breakpoint Register Pairs */
1487 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1488 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1489 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1490 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(cortex_a8_brp_t
));
1491 // cortex_a8->brb_enabled = ????;
1492 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1494 cortex_a8
->brp_list
[i
].used
= 0;
1495 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1496 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1498 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1499 cortex_a8
->brp_list
[i
].value
= 0;
1500 cortex_a8
->brp_list
[i
].control
= 0;
1501 cortex_a8
->brp_list
[i
].BRPn
= i
;
1504 /* Setup Watchpoint Register Pairs */
1505 cortex_a8
->wrp_num
= ((didr
>> 28) & 0x0F) + 1;
1506 cortex_a8
->wrp_num_available
= cortex_a8
->wrp_num
;
1507 cortex_a8
->wrp_list
= calloc(cortex_a8
->wrp_num
, sizeof(cortex_a8_wrp_t
));
1508 for (i
= 0; i
< cortex_a8
->wrp_num
; i
++)
1510 cortex_a8
->wrp_list
[i
].used
= 0;
1511 cortex_a8
->wrp_list
[i
].type
= 0;
1512 cortex_a8
->wrp_list
[i
].value
= 0;
1513 cortex_a8
->wrp_list
[i
].control
= 0;
1514 cortex_a8
->wrp_list
[i
].WRPn
= i
;
1516 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1517 cortex_a8
->brp_num
, cortex_a8
->wrp_num
);
1519 /* Configure core debug access */
1520 cortex_a8_init_debug_access(target
);
1522 target
->type
->examined
= 1;
1528 * Cortex-A8 target creation and initialization
1531 void cortex_a8_build_reg_cache(target_t
*target
)
1533 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1534 /* get pointers to arch-specific information */
1535 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1537 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
1538 armv4_5
->core_cache
= (*cache_p
);
1542 int cortex_a8_init_target(struct command_context_s
*cmd_ctx
,
1543 struct target_s
*target
)
1545 cortex_a8_build_reg_cache(target
);
1549 int cortex_a8_init_arch_info(target_t
*target
,
1550 cortex_a8_common_t
*cortex_a8
, jtag_tap_t
*tap
)
1552 armv4_5_common_t
*armv4_5
;
1553 armv7a_common_t
*armv7a
;
1555 armv7a
= &cortex_a8
->armv7a_common
;
1556 armv4_5
= &armv7a
->armv4_5_common
;
1557 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1559 /* Setup cortex_a8_common_t */
1560 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1561 cortex_a8
->arch_info
= NULL
;
1562 armv7a
->arch_info
= cortex_a8
;
1563 armv4_5
->arch_info
= armv7a
;
1565 armv4_5_init_arch_info(target
, armv4_5
);
1567 /* prepare JTAG information for the new target */
1568 cortex_a8
->jtag_info
.tap
= tap
;
1569 cortex_a8
->jtag_info
.scann_size
= 4;
1571 swjdp
->dp_select_value
= -1;
1572 swjdp
->ap_csw_value
= -1;
1573 swjdp
->ap_tar_value
= -1;
1574 swjdp
->jtag_info
= &cortex_a8
->jtag_info
;
1575 swjdp
->memaccess_tck
= 80;
1577 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1578 swjdp
->tar_autoincr_block
= (1 << 10);
1580 cortex_a8
->fast_reg_read
= 0;
1583 /* register arch-specific functions */
1584 armv7a
->examine_debug_reason
= NULL
;
1586 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1588 armv7a
->pre_restore_context
= NULL
;
1589 armv7a
->post_restore_context
= NULL
;
1590 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1591 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1592 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_memory
;
1593 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_memory
;
1594 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1595 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1596 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1597 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1598 armv7a
->read_cp15
= cortex_a8_read_cp15
;
1599 armv7a
->write_cp15
= cortex_a8_write_cp15
;
1602 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1604 armv4_5
->read_core_reg
= cortex_a8_read_core_reg
;
1605 armv4_5
->write_core_reg
= cortex_a8_write_core_reg
;
1606 // armv4_5->full_context = arm7_9_full_context;
1608 // armv4_5->load_core_reg_u32 = cortex_a8_load_core_reg_u32;
1609 // armv4_5->store_core_reg_u32 = cortex_a8_store_core_reg_u32;
1610 // armv4_5->read_core_reg = armv4_5_read_core_reg; /* this is default */
1611 // armv4_5->write_core_reg = armv4_5_write_core_reg;
1613 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1618 int cortex_a8_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1620 cortex_a8_common_t
*cortex_a8
= calloc(1, sizeof(cortex_a8_common_t
));
1622 cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1627 static int cortex_a8_handle_cache_info_command(struct command_context_s
*cmd_ctx
,
1628 char *cmd
, char **args
, int argc
)
1630 target_t
*target
= get_current_target(cmd_ctx
);
1631 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1632 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1634 return armv4_5_handle_cache_info_command(cmd_ctx
,
1635 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1639 static int cortex_a8_handle_dbginit_command(struct command_context_s
*cmd_ctx
,
1640 char *cmd
, char **args
, int argc
)
1642 target_t
*target
= get_current_target(cmd_ctx
);
1644 cortex_a8_init_debug_access(target
);
1650 int cortex_a8_register_commands(struct command_context_s
*cmd_ctx
)
1652 command_t
*cortex_a8_cmd
;
1653 int retval
= ERROR_OK
;
1655 armv4_5_register_commands(cmd_ctx
);
1656 armv7a_register_commands(cmd_ctx
);
1658 cortex_a8_cmd
= register_command(cmd_ctx
, NULL
, "cortex_a8",
1660 "cortex_a8 specific commands");
1662 register_command(cmd_ctx
, cortex_a8_cmd
, "cache_info",
1663 cortex_a8_handle_cache_info_command
, COMMAND_EXEC
,
1664 "display information about target caches");
1666 register_command(cmd_ctx
, cortex_a8_cmd
, "dbginit",
1667 cortex_a8_handle_dbginit_command
, COMMAND_EXEC
,
1668 "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)