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 static int cortex_a8_mrc(target_t
*target
, int cpnum
, uint32_t op1
,
74 uint32_t op2
, uint32_t CRn
, uint32_t CRm
, uint32_t *value
);
75 static int cortex_a8_mcr(target_t
*target
, int cpnum
, uint32_t op1
,
76 uint32_t op2
, uint32_t CRn
, uint32_t CRm
, uint32_t value
);
78 target_type_t cortexa8_target
=
82 .poll
= cortex_a8_poll
,
83 .arch_state
= armv7a_arch_state
,
85 .target_request_data
= NULL
,
87 .halt
= cortex_a8_halt
,
88 .resume
= cortex_a8_resume
,
89 .step
= cortex_a8_step
,
91 .assert_reset
= cortex_a8_assert_reset
,
92 .deassert_reset
= cortex_a8_deassert_reset
,
93 .soft_reset_halt
= NULL
,
95 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
97 .read_memory
= cortex_a8_read_memory
,
98 .write_memory
= cortex_a8_write_memory
,
99 .bulk_write_memory
= cortex_a8_bulk_write_memory
,
100 .checksum_memory
= arm7_9_checksum_memory
,
101 .blank_check_memory
= arm7_9_blank_check_memory
,
103 .run_algorithm
= armv4_5_run_algorithm
,
105 .add_breakpoint
= cortex_a8_add_breakpoint
,
106 .remove_breakpoint
= cortex_a8_remove_breakpoint
,
107 .add_watchpoint
= NULL
,
108 .remove_watchpoint
= NULL
,
110 .register_commands
= cortex_a8_register_commands
,
111 .target_create
= cortex_a8_target_create
,
112 .init_target
= cortex_a8_init_target
,
113 .examine
= cortex_a8_examine
,
114 .mrc
= cortex_a8_mrc
,
115 .mcr
= cortex_a8_mcr
,
119 * FIXME do topology discovery using the ROM; don't
120 * assume this is an OMAP3.
122 #define swjdp_memoryap 0
123 #define swjdp_debugap 1
124 #define OMAP3530_DEBUG_BASE 0x54011000
127 * Cortex-A8 Basic debug access, very low level assumes state is saved
129 int cortex_a8_init_debug_access(target_t
*target
)
131 /* get pointers to arch-specific information */
132 armv4_5_common_t
*armv4_5
= target
->arch_info
;
133 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
134 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
141 /* Unlocking the debug registers for modification */
142 /* The debugport might be uninitialised so try twice */
143 retval
= mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
144 if (retval
!= ERROR_OK
)
145 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
146 /* Clear Sticky Power Down status Bit in PRSR to enable access to
147 the registers in the Core Power Domain */
148 retval
= mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_PRSR
, &dummy
);
149 /* Enabling of instruction execution in debug mode is done in debug_entry code */
151 /* Resync breakpoint registers */
153 /* Since this is likley called from init or reset, update targtet state information*/
154 cortex_a8_poll(target
);
159 int cortex_a8_exec_opcode(target_t
*target
, uint32_t opcode
)
163 /* get pointers to arch-specific information */
164 armv4_5_common_t
*armv4_5
= target
->arch_info
;
165 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
166 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
168 LOG_DEBUG("exec opcode 0x%08" PRIx32
, opcode
);
171 retval
= mem_ap_read_atomic_u32(swjdp
,
172 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
173 if (retval
!= ERROR_OK
)
175 LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32
, opcode
);
179 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
181 mem_ap_write_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_ITR
, opcode
);
185 retval
= mem_ap_read_atomic_u32(swjdp
,
186 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
187 if (retval
!= ERROR_OK
)
189 LOG_ERROR("Could not read DSCR register");
193 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
198 /**************************************************************************
199 Read core register with very few exec_opcode, fast but needs work_area.
200 This can cause problems with MMU active.
201 **************************************************************************/
202 int cortex_a8_read_regs_through_mem(target_t
*target
, uint32_t address
,
205 int retval
= ERROR_OK
;
206 /* get pointers to arch-specific information */
207 armv4_5_common_t
*armv4_5
= target
->arch_info
;
208 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
209 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
211 cortex_a8_dap_read_coreregister_u32(target
, regfile
, 0);
212 cortex_a8_dap_write_coreregister_u32(target
, address
, 0);
213 cortex_a8_exec_opcode(target
, ARMV4_5_STMIA(0, 0xFFFE, 0, 0));
214 dap_ap_select(swjdp
, swjdp_memoryap
);
215 mem_ap_read_buf_u32(swjdp
, (uint8_t *)(®file
[1]), 4*15, address
);
216 dap_ap_select(swjdp
, swjdp_debugap
);
221 int cortex_a8_read_cp(target_t
*target
, uint32_t *value
, uint8_t CP
,
222 uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
225 /* get pointers to arch-specific information */
226 armv4_5_common_t
*armv4_5
= target
->arch_info
;
227 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
228 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
230 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(CP
, op1
, 0, CRn
, CRm
, op2
));
231 /* Move R0 to DTRTX */
232 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
235 retval
= mem_ap_read_atomic_u32(swjdp
,
236 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
241 int cortex_a8_write_cp(target_t
*target
, uint32_t value
,
242 uint8_t CP
, uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
247 /* get pointers to arch-specific information */
248 armv4_5_common_t
*armv4_5
= target
->arch_info
;
249 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
250 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
252 LOG_DEBUG("CP%i, CRn %i, value 0x%08" PRIx32
, CP
, CRn
, value
);
254 /* Check that DCCRX is not full */
255 retval
= mem_ap_read_atomic_u32(swjdp
,
256 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
257 if (dscr
& (1 << DSCR_DTR_RX_FULL
))
259 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
260 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
261 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
264 retval
= mem_ap_write_u32(swjdp
,
265 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
266 /* Move DTRRX to r0 */
267 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
269 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(CP
, op1
, 0, CRn
, CRm
, op2
));
273 int cortex_a8_read_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
274 uint32_t CRn
, uint32_t CRm
, uint32_t *value
)
276 return cortex_a8_read_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
279 int cortex_a8_write_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
280 uint32_t CRn
, uint32_t CRm
, uint32_t value
)
282 return cortex_a8_write_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
285 static int cortex_a8_mrc(target_t
*target
, int cpnum
, uint32_t op1
, uint32_t op2
, uint32_t CRn
, uint32_t CRm
, uint32_t *value
)
289 LOG_ERROR("Only cp15 is supported");
292 return cortex_a8_read_cp15(target
, op1
, op2
, CRn
, CRm
, value
);
295 static int cortex_a8_mcr(target_t
*target
, int cpnum
, uint32_t op1
, uint32_t op2
, uint32_t CRn
, uint32_t CRm
, uint32_t value
)
299 LOG_ERROR("Only cp15 is supported");
302 return cortex_a8_write_cp15(target
, op1
, op2
, CRn
, CRm
, value
);
307 int cortex_a8_dap_read_coreregister_u32(target_t
*target
,
308 uint32_t *value
, int regnum
)
310 int retval
= ERROR_OK
;
311 uint8_t reg
= regnum
&0xFF;
314 /* get pointers to arch-specific information */
315 armv4_5_common_t
*armv4_5
= target
->arch_info
;
316 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
317 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
324 /* Rn to DCCTX, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
325 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, reg
, 0, 5, 0));
329 cortex_a8_exec_opcode(target
, 0xE1A0000F);
330 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
334 cortex_a8_exec_opcode(target
, ARMV4_5_MRS(0, 0));
335 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
341 retval
= mem_ap_read_atomic_u32(swjdp
,
342 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
344 while ((dscr
& (1 << DSCR_DTR_TX_FULL
)) == 0); /* Wait for DTRRXfull */
346 retval
= mem_ap_read_atomic_u32(swjdp
,
347 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
352 int cortex_a8_dap_write_coreregister_u32(target_t
*target
, uint32_t value
, int regnum
)
354 int retval
= ERROR_OK
;
355 uint8_t Rd
= regnum
&0xFF;
358 /* get pointers to arch-specific information */
359 armv4_5_common_t
*armv4_5
= target
->arch_info
;
360 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
361 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
363 LOG_DEBUG("register %i, value 0x%08" PRIx32
, regnum
, value
);
365 /* Check that DCCRX is not full */
366 retval
= mem_ap_read_atomic_u32(swjdp
,
367 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
368 if (dscr
& (1 << DSCR_DTR_RX_FULL
))
370 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
371 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
372 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
379 retval
= mem_ap_write_u32(swjdp
,
380 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
384 /* DCCRX to Rd, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
385 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, Rd
, 0, 5, 0));
389 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
390 cortex_a8_exec_opcode(target
, 0xE1A0F000);
394 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
395 cortex_a8_exec_opcode(target
, ARMV4_5_MSR_GP(0, 0xF, 0));
396 /* Execute a PrefetchFlush instruction through the ITR. */
397 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(15, 0, 0, 7, 5, 4));
403 /* Write to memory mapped registers directly with no cache or mmu handling */
404 int cortex_a8_dap_write_memap_register_u32(target_t
*target
, uint32_t address
, uint32_t value
)
408 /* get pointers to arch-specific information */
409 armv4_5_common_t
*armv4_5
= target
->arch_info
;
410 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
411 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
413 retval
= mem_ap_write_atomic_u32(swjdp
, address
, value
);
419 * Cortex-A8 Run control
422 int cortex_a8_poll(target_t
*target
)
424 int retval
= ERROR_OK
;
426 /* get pointers to arch-specific information */
427 armv4_5_common_t
*armv4_5
= target
->arch_info
;
428 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
429 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
430 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
433 enum target_state prev_target_state
= target
->state
;
435 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
436 dap_ap_select(swjdp
, swjdp_debugap
);
437 retval
= mem_ap_read_atomic_u32(swjdp
,
438 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
439 if (retval
!= ERROR_OK
)
441 dap_ap_select(swjdp
, saved_apsel
);
444 cortex_a8
->cpudbg_dscr
= dscr
;
446 if ((dscr
& 0x3) == 0x3)
448 if (prev_target_state
!= TARGET_HALTED
)
450 /* We have a halting debug event */
451 LOG_DEBUG("Target halted");
452 target
->state
= TARGET_HALTED
;
453 if ((prev_target_state
== TARGET_RUNNING
)
454 || (prev_target_state
== TARGET_RESET
))
456 retval
= cortex_a8_debug_entry(target
);
457 if (retval
!= ERROR_OK
)
460 target_call_event_callbacks(target
,
461 TARGET_EVENT_HALTED
);
463 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
467 retval
= cortex_a8_debug_entry(target
);
468 if (retval
!= ERROR_OK
)
471 target_call_event_callbacks(target
,
472 TARGET_EVENT_DEBUG_HALTED
);
476 else if ((dscr
& 0x3) == 0x2)
478 target
->state
= TARGET_RUNNING
;
482 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32
, dscr
);
483 target
->state
= TARGET_UNKNOWN
;
486 dap_ap_select(swjdp
, saved_apsel
);
491 int cortex_a8_halt(target_t
*target
)
493 int retval
= ERROR_OK
;
496 /* get pointers to arch-specific information */
497 armv4_5_common_t
*armv4_5
= target
->arch_info
;
498 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
499 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
501 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
502 dap_ap_select(swjdp
, swjdp_debugap
);
505 * Tell the core to be halted by writing DRCR with 0x1
506 * and then wait for the core to be halted.
508 retval
= mem_ap_write_atomic_u32(swjdp
,
509 armv7a
->debug_base
+ CPUDBG_DRCR
, 0x1);
512 * enter halting debug mode
514 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
515 retval
= mem_ap_write_atomic_u32(swjdp
,
516 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
| (1 << DSCR_HALT_DBG_MODE
));
518 if (retval
!= ERROR_OK
)
522 mem_ap_read_atomic_u32(swjdp
,
523 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
524 } while ((dscr
& (1 << DSCR_CORE_HALTED
)) == 0);
526 target
->debug_reason
= DBG_REASON_DBGRQ
;
529 dap_ap_select(swjdp
, saved_apsel
);
533 int cortex_a8_resume(struct target_s
*target
, int current
,
534 uint32_t address
, int handle_breakpoints
, int debug_execution
)
536 /* get pointers to arch-specific information */
537 armv4_5_common_t
*armv4_5
= target
->arch_info
;
538 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
539 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
541 // breakpoint_t *breakpoint = NULL;
542 uint32_t resume_pc
, dscr
;
544 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
545 dap_ap_select(swjdp
, swjdp_debugap
);
547 if (!debug_execution
)
549 target_free_all_working_areas(target
);
550 // cortex_m3_enable_breakpoints(target);
551 // cortex_m3_enable_watchpoints(target);
557 /* Disable interrupts */
558 /* We disable interrupts in the PRIMASK register instead of
559 * masking with C_MASKINTS,
560 * This is probably the same issue as Cortex-M3 Errata 377493:
561 * C_MASKINTS in parallel with disabled interrupts can cause
562 * local faults to not be taken. */
563 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
564 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
565 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
567 /* Make sure we are in Thumb mode */
568 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
569 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
570 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
571 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
575 /* current = 1: continue on current pc, otherwise continue at <address> */
576 resume_pc
= buf_get_u32(
577 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
578 armv4_5
->core_mode
, 15).value
,
583 /* Make sure that the Armv7 gdb thumb fixups does not
584 * kill the return address
586 if (armv7a
->core_state
== ARMV7A_STATE_ARM
)
588 resume_pc
&= 0xFFFFFFFC;
590 /* When the return address is loaded into PC
591 * bit 0 must be 1 to stay in Thumb state
593 if (armv7a
->core_state
== ARMV7A_STATE_THUMB
)
597 LOG_DEBUG("resume pc = 0x%08" PRIx32
, resume_pc
);
598 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
599 armv4_5
->core_mode
, 15).value
,
601 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
602 armv4_5
->core_mode
, 15).dirty
= 1;
603 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
604 armv4_5
->core_mode
, 15).valid
= 1;
606 cortex_a8_restore_context(target
);
607 // arm7_9_restore_context(target); TODO Context is currently NOT Properly restored
609 /* the front-end may request us not to handle breakpoints */
610 if (handle_breakpoints
)
612 /* Single step past breakpoint at current address */
613 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
615 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
616 cortex_m3_unset_breakpoint(target
, breakpoint
);
617 cortex_m3_single_step_core(target
);
618 cortex_m3_set_breakpoint(target
, breakpoint
);
623 /* Restart core and wait for it to be started */
624 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DRCR
, 0x2);
627 mem_ap_read_atomic_u32(swjdp
,
628 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
629 } while ((dscr
& (1 << DSCR_CORE_RESTARTED
)) == 0);
631 target
->debug_reason
= DBG_REASON_NOTHALTED
;
632 target
->state
= TARGET_RUNNING
;
634 /* registers are now invalid */
635 armv4_5_invalidate_core_regs(target
);
637 if (!debug_execution
)
639 target
->state
= TARGET_RUNNING
;
640 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
641 LOG_DEBUG("target resumed at 0x%" PRIx32
, resume_pc
);
645 target
->state
= TARGET_DEBUG_RUNNING
;
646 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
647 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, resume_pc
);
650 dap_ap_select(swjdp
, saved_apsel
);
655 int cortex_a8_debug_entry(target_t
*target
)
658 uint32_t regfile
[16], pc
, cpsr
, dscr
;
659 int retval
= ERROR_OK
;
660 working_area_t
*regfile_working_area
= NULL
;
662 /* get pointers to arch-specific information */
663 armv4_5_common_t
*armv4_5
= target
->arch_info
;
664 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
665 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
666 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
668 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
670 /* Enable the ITR execution once we are in debug mode */
671 mem_ap_read_atomic_u32(swjdp
,
672 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
673 dscr
|= (1 << DSCR_EXT_INT_EN
);
674 retval
= mem_ap_write_atomic_u32(swjdp
,
675 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
);
677 /* Examine debug reason */
678 switch ((cortex_a8
->cpudbg_dscr
>> 2)&0xF)
682 target
->debug_reason
= DBG_REASON_DBGRQ
;
686 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
689 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
692 target
->debug_reason
= DBG_REASON_UNDEFINED
;
696 /* Examine target state and mode */
697 if (cortex_a8
->fast_reg_read
)
698 target_alloc_working_area(target
, 64, ®file_working_area
);
700 /* First load register acessible through core debug port*/
701 if (!regfile_working_area
)
703 for (i
= 0; i
<= 15; i
++)
704 cortex_a8_dap_read_coreregister_u32(target
,
709 dap_ap_select(swjdp
, swjdp_memoryap
);
710 cortex_a8_read_regs_through_mem(target
,
711 regfile_working_area
->address
, regfile
);
712 dap_ap_select(swjdp
, swjdp_memoryap
);
713 target_free_working_area(target
, regfile_working_area
);
716 cortex_a8_dap_read_coreregister_u32(target
, &cpsr
, 16);
718 dap_ap_select(swjdp
, swjdp_debugap
);
719 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
721 armv4_5
->core_mode
= cpsr
& 0x1F;
722 armv7a
->core_state
= (cpsr
& 0x20)?ARMV7A_STATE_THUMB
:ARMV7A_STATE_ARM
;
724 for (i
= 0; i
<= ARM_PC
; i
++)
726 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
727 armv4_5
->core_mode
, i
).value
,
729 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
730 armv4_5
->core_mode
, i
).valid
= 1;
731 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
732 armv4_5
->core_mode
, i
).dirty
= 0;
734 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
735 armv4_5
->core_mode
, 16).value
,
737 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
738 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
740 /* Fixup PC Resume Address */
741 if (armv7a
->core_state
== ARMV7A_STATE_THUMB
)
743 // T bit set for Thumb or ThumbEE state
744 regfile
[ARM_PC
] -= 4;
749 regfile
[ARM_PC
] -= 8;
751 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
752 armv4_5
->core_mode
, ARM_PC
).value
,
753 0, 32, regfile
[ARM_PC
]);
755 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 0)
756 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
757 armv4_5
->core_mode
, 0).valid
;
758 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 15)
759 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
760 armv4_5
->core_mode
, 15).valid
;
763 /* TODO, Move this */
764 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
765 cortex_a8_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
766 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
768 cortex_a8_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
769 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
771 cortex_a8_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
772 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
775 /* Are we in an exception handler */
776 // armv4_5->exception_number = 0;
777 if (armv7a
->post_debug_entry
)
778 armv7a
->post_debug_entry(target
);
786 void cortex_a8_post_debug_entry(target_t
*target
)
788 /* get pointers to arch-specific information */
789 armv4_5_common_t
*armv4_5
= target
->arch_info
;
790 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
791 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
793 // cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
794 /* examine cp15 control reg */
795 armv7a
->read_cp15(target
, 0, 0, 1, 0, &cortex_a8
->cp15_control_reg
);
796 jtag_execute_queue();
797 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
799 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
801 uint32_t cache_type_reg
;
802 /* identify caches */
803 armv7a
->read_cp15(target
, 0, 1, 0, 0, &cache_type_reg
);
804 jtag_execute_queue();
805 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
806 armv4_5_identify_cache(cache_type_reg
,
807 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
810 armv7a
->armv4_5_mmu
.mmu_enabled
=
811 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
812 armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
=
813 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
814 armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
=
815 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
820 int cortex_a8_step(struct target_s
*target
, int current
, uint32_t address
,
821 int handle_breakpoints
)
823 /* get pointers to arch-specific information */
824 armv4_5_common_t
*armv4_5
= target
->arch_info
;
825 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
826 breakpoint_t
*breakpoint
= NULL
;
827 breakpoint_t stepbreakpoint
;
831 if (target
->state
!= TARGET_HALTED
)
833 LOG_WARNING("target not halted");
834 return ERROR_TARGET_NOT_HALTED
;
837 /* current = 1: continue on current pc, otherwise continue at <address> */
840 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
841 armv4_5
->core_mode
, ARM_PC
).value
,
846 address
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
847 armv4_5
->core_mode
, ARM_PC
).value
,
851 /* The front-end may request us not to handle breakpoints.
852 * But since Cortex-A8 uses breakpoint for single step,
853 * we MUST handle breakpoints.
855 handle_breakpoints
= 1;
856 if (handle_breakpoints
) {
857 breakpoint
= breakpoint_find(target
,
858 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
859 armv4_5
->core_mode
, 15).value
,
862 cortex_a8_unset_breakpoint(target
, breakpoint
);
865 /* Setup single step breakpoint */
866 stepbreakpoint
.address
= address
;
867 stepbreakpoint
.length
= (armv7a
->core_state
== ARMV7A_STATE_THUMB
) ? 2 : 4;
868 stepbreakpoint
.type
= BKPT_HARD
;
869 stepbreakpoint
.set
= 0;
871 /* Break on IVA mismatch */
872 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
874 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
876 cortex_a8_resume(target
, 1, address
, 0, 0);
878 while (target
->state
!= TARGET_HALTED
)
880 cortex_a8_poll(target
);
883 LOG_WARNING("timeout waiting for target halt");
888 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
889 if (timeout
> 0) target
->debug_reason
= DBG_REASON_BREAKPOINT
;
892 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
894 if (target
->state
!= TARGET_HALTED
)
895 LOG_DEBUG("target stepped");
900 int cortex_a8_restore_context(target_t
*target
)
905 /* get pointers to arch-specific information */
906 armv4_5_common_t
*armv4_5
= target
->arch_info
;
907 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
911 if (armv7a
->pre_restore_context
)
912 armv7a
->pre_restore_context(target
);
914 for (i
= 15; i
>= 0; i
--)
916 if (ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
917 armv4_5
->core_mode
, i
).dirty
)
919 value
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
920 armv4_5
->core_mode
, i
).value
,
922 /* TODO Check return values */
923 cortex_a8_dap_write_coreregister_u32(target
, value
, i
);
927 if (armv7a
->post_restore_context
)
928 armv7a
->post_restore_context(target
);
935 * Cortex-A8 Core register functions
938 int cortex_a8_load_core_reg_u32(struct target_s
*target
, int num
,
939 armv4_5_mode_t mode
, uint32_t * value
)
942 /* get pointers to arch-specific information */
943 armv4_5_common_t
*armv4_5
= target
->arch_info
;
945 if ((num
<= ARM_CPSR
))
947 /* read a normal core register */
948 retval
= cortex_a8_dap_read_coreregister_u32(target
, value
, num
);
950 if (retval
!= ERROR_OK
)
952 LOG_ERROR("JTAG failure %i", retval
);
953 return ERROR_JTAG_DEVICE_ERROR
;
955 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
, num
, *value
);
959 return ERROR_INVALID_ARGUMENTS
;
962 /* Register other than r0 - r14 uses r0 for access */
964 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
965 armv4_5
->core_mode
, 0).dirty
=
966 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
967 armv4_5
->core_mode
, 0).valid
;
968 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
969 armv4_5
->core_mode
, 15).dirty
=
970 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
971 armv4_5
->core_mode
, 15).valid
;
976 int cortex_a8_store_core_reg_u32(struct target_s
*target
, int num
,
977 armv4_5_mode_t mode
, uint32_t value
)
982 /* get pointers to arch-specific information */
983 armv4_5_common_t
*armv4_5
= target
->arch_info
;
985 #ifdef ARMV7_GDB_HACKS
986 /* If the LR register is being modified, make sure it will put us
987 * in "thumb" mode, or an INVSTATE exception will occur. This is a
988 * hack to deal with the fact that gdb will sometimes "forge"
989 * return addresses, and doesn't set the LSB correctly (i.e., when
990 * printing expressions containing function calls, it sets LR=0.) */
996 if ((num
<= ARM_CPSR
))
998 retval
= cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
999 if (retval
!= ERROR_OK
)
1001 LOG_ERROR("JTAG failure %i", retval
);
1002 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
1003 armv4_5
->core_mode
, num
).dirty
=
1004 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
1005 armv4_5
->core_mode
, num
).valid
;
1006 return ERROR_JTAG_DEVICE_ERROR
;
1008 LOG_DEBUG("write core reg %i value 0x%" PRIx32
, num
, value
);
1012 return ERROR_INVALID_ARGUMENTS
;
1019 int cortex_a8_read_core_reg(struct target_s
*target
, int num
,
1020 enum armv4_5_mode mode
)
1024 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1025 cortex_a8_dap_read_coreregister_u32(target
, &value
, num
);
1027 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
1032 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
1033 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
1034 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
1035 mode
, num
).value
, 0, 32, value
);
1040 int cortex_a8_write_core_reg(struct target_s
*target
, int num
,
1041 enum armv4_5_mode mode
, uint32_t value
)
1044 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1046 cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
1047 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
1052 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
1053 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
1060 * Cortex-A8 Breakpoint and watchpoint fuctions
1063 /* Setup hardware Breakpoint Register Pair */
1064 int cortex_a8_set_breakpoint(struct target_s
*target
,
1065 breakpoint_t
*breakpoint
, uint8_t matchmode
)
1070 uint8_t byte_addr_select
= 0x0F;
1073 /* get pointers to arch-specific information */
1074 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1075 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1076 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1077 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
1079 if (breakpoint
->set
)
1081 LOG_WARNING("breakpoint already set");
1085 if (breakpoint
->type
== BKPT_HARD
)
1087 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
1089 if (brp_i
>= cortex_a8
->brp_num
)
1091 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1094 breakpoint
->set
= brp_i
+ 1;
1095 if (breakpoint
->length
== 2)
1097 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1099 control
= ((matchmode
& 0x7) << 20)
1100 | (byte_addr_select
<< 5)
1102 brp_list
[brp_i
].used
= 1;
1103 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1104 brp_list
[brp_i
].control
= control
;
1105 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1106 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1107 brp_list
[brp_i
].value
);
1108 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1109 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1110 brp_list
[brp_i
].control
);
1111 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1112 brp_list
[brp_i
].control
,
1113 brp_list
[brp_i
].value
);
1115 else if (breakpoint
->type
== BKPT_SOFT
)
1118 if (breakpoint
->length
== 2)
1120 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1124 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1126 retval
= target
->type
->read_memory(target
,
1127 breakpoint
->address
& 0xFFFFFFFE,
1128 breakpoint
->length
, 1,
1129 breakpoint
->orig_instr
);
1130 if (retval
!= ERROR_OK
)
1132 retval
= target
->type
->write_memory(target
,
1133 breakpoint
->address
& 0xFFFFFFFE,
1134 breakpoint
->length
, 1, code
);
1135 if (retval
!= ERROR_OK
)
1137 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1143 int cortex_a8_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1146 /* get pointers to arch-specific information */
1147 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1148 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1149 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1150 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
1152 if (!breakpoint
->set
)
1154 LOG_WARNING("breakpoint not set");
1158 if (breakpoint
->type
== BKPT_HARD
)
1160 int brp_i
= breakpoint
->set
- 1;
1161 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1163 LOG_DEBUG("Invalid BRP number in breakpoint");
1166 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1167 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1168 brp_list
[brp_i
].used
= 0;
1169 brp_list
[brp_i
].value
= 0;
1170 brp_list
[brp_i
].control
= 0;
1171 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1172 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1173 brp_list
[brp_i
].control
);
1174 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1175 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1176 brp_list
[brp_i
].value
);
1180 /* restore original instruction (kept in target endianness) */
1181 if (breakpoint
->length
== 4)
1183 retval
= target
->type
->write_memory(target
,
1184 breakpoint
->address
& 0xFFFFFFFE,
1185 4, 1, breakpoint
->orig_instr
);
1186 if (retval
!= ERROR_OK
)
1191 retval
= target
->type
->write_memory(target
,
1192 breakpoint
->address
& 0xFFFFFFFE,
1193 2, 1, breakpoint
->orig_instr
);
1194 if (retval
!= ERROR_OK
)
1198 breakpoint
->set
= 0;
1203 int cortex_a8_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1205 /* get pointers to arch-specific information */
1206 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1207 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1208 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1210 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1212 LOG_INFO("no hardware breakpoint available");
1213 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1216 if (breakpoint
->type
== BKPT_HARD
)
1217 cortex_a8
->brp_num_available
--;
1218 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1223 int cortex_a8_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1225 /* get pointers to arch-specific information */
1226 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1227 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1228 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1231 /* It is perfectly possible to remove brakpoints while the taget is running */
1232 if (target
->state
!= TARGET_HALTED
)
1234 LOG_WARNING("target not halted");
1235 return ERROR_TARGET_NOT_HALTED
;
1239 if (breakpoint
->set
)
1241 cortex_a8_unset_breakpoint(target
, breakpoint
);
1242 if (breakpoint
->type
== BKPT_HARD
)
1243 cortex_a8
->brp_num_available
++ ;
1253 * Cortex-A8 Reset fuctions
1256 int cortex_a8_assert_reset(target_t
*target
)
1261 /* registers are now invalid */
1262 armv4_5_invalidate_core_regs(target
);
1264 target
->state
= TARGET_RESET
;
1269 int cortex_a8_deassert_reset(target_t
*target
)
1274 if (target
->reset_halt
)
1277 if ((retval
= target_halt(target
)) != ERROR_OK
)
1285 * Cortex-A8 Memory access
1287 * This is same Cortex M3 but we must also use the correct
1288 * ap number for every access.
1291 int cortex_a8_read_memory(struct target_s
*target
, uint32_t address
,
1292 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1294 /* get pointers to arch-specific information */
1295 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1296 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1297 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1299 int retval
= ERROR_OK
;
1301 /* sanitize arguments */
1302 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1303 return ERROR_INVALID_ARGUMENTS
;
1305 /* cortex_a8 handles unaligned memory access */
1307 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1312 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1315 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1318 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1321 LOG_ERROR("BUG: we shouldn't get here");
1328 int cortex_a8_write_memory(struct target_s
*target
, uint32_t address
,
1329 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1331 /* get pointers to arch-specific information */
1332 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1333 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1334 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1338 /* sanitize arguments */
1339 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1340 return ERROR_INVALID_ARGUMENTS
;
1342 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1347 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1350 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1353 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1356 LOG_ERROR("BUG: we shouldn't get here");
1360 if (target
->state
== TARGET_HALTED
)
1362 /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */
1363 /* invalidate I-Cache */
1364 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
1366 /* Invalidate ICache single entry with MVA, repeat this for all cache
1367 lines in the address range, Cortex-A8 has fixed 64 byte line length */
1368 /* Invalidate Cache single entry with MVA to PoU */
1369 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1370 armv7a
->write_cp15(target
, 0, 1, 7, 5, cacheline
); /* I-Cache to PoU */
1372 /* invalidate D-Cache */
1373 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
1375 /* Invalidate Cache single entry with MVA to PoC */
1376 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1377 armv7a
->write_cp15(target
, 0, 1, 7, 6, cacheline
); /* U/D cache to PoC */
1384 int cortex_a8_bulk_write_memory(target_t
*target
, uint32_t address
,
1385 uint32_t count
, uint8_t *buffer
)
1387 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1391 int cortex_a8_dcc_read(swjdp_common_t
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1396 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1397 *ctrl
= (uint8_t)dcrdr
;
1398 *value
= (uint8_t)(dcrdr
>> 8);
1400 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1402 /* write ack back to software dcc register
1403 * signify we have read data */
1404 if (dcrdr
& (1 << 0))
1407 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1414 int cortex_a8_handle_target_request(void *priv
)
1416 target_t
*target
= priv
;
1417 if (!target
->type
->examined
)
1419 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1420 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1421 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1424 if (!target
->dbg_msg_enabled
)
1427 if (target
->state
== TARGET_RUNNING
)
1432 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1434 /* check if we have data */
1435 if (ctrl
& (1 << 0))
1439 /* we assume target is quick enough */
1441 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1442 request
|= (data
<< 8);
1443 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1444 request
|= (data
<< 16);
1445 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1446 request
|= (data
<< 24);
1447 target_request(target
, request
);
1455 * Cortex-A8 target information and configuration
1458 int cortex_a8_examine(struct target_s
*target
)
1460 /* get pointers to arch-specific information */
1461 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1462 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1463 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1464 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1468 int retval
= ERROR_OK
;
1469 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1473 /* Here we shall insert a proper ROM Table scan */
1474 armv7a
->debug_base
= OMAP3530_DEBUG_BASE
;
1476 /* We do one extra read to ensure DAP is configured,
1477 * we call ahbap_debugport_init(swjdp) instead
1479 ahbap_debugport_init(swjdp
);
1480 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
1481 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1482 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1484 LOG_DEBUG("Examine failed");
1488 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1489 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1491 LOG_DEBUG("Examine failed");
1495 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1496 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1498 LOG_DEBUG("Examine failed");
1502 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1503 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1505 LOG_DEBUG("Examine failed");
1509 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1510 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1511 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1512 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1514 /* Setup Breakpoint Register Pairs */
1515 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1516 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1517 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1518 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(cortex_a8_brp_t
));
1519 // cortex_a8->brb_enabled = ????;
1520 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1522 cortex_a8
->brp_list
[i
].used
= 0;
1523 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1524 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1526 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1527 cortex_a8
->brp_list
[i
].value
= 0;
1528 cortex_a8
->brp_list
[i
].control
= 0;
1529 cortex_a8
->brp_list
[i
].BRPn
= i
;
1532 /* Setup Watchpoint Register Pairs */
1533 cortex_a8
->wrp_num
= ((didr
>> 28) & 0x0F) + 1;
1534 cortex_a8
->wrp_num_available
= cortex_a8
->wrp_num
;
1535 cortex_a8
->wrp_list
= calloc(cortex_a8
->wrp_num
, sizeof(cortex_a8_wrp_t
));
1536 for (i
= 0; i
< cortex_a8
->wrp_num
; i
++)
1538 cortex_a8
->wrp_list
[i
].used
= 0;
1539 cortex_a8
->wrp_list
[i
].type
= 0;
1540 cortex_a8
->wrp_list
[i
].value
= 0;
1541 cortex_a8
->wrp_list
[i
].control
= 0;
1542 cortex_a8
->wrp_list
[i
].WRPn
= i
;
1544 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1545 cortex_a8
->brp_num
, cortex_a8
->wrp_num
);
1547 /* Configure core debug access */
1548 cortex_a8_init_debug_access(target
);
1550 target
->type
->examined
= 1;
1556 * Cortex-A8 target creation and initialization
1559 void cortex_a8_build_reg_cache(target_t
*target
)
1561 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1562 /* get pointers to arch-specific information */
1563 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1565 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
1566 armv4_5
->core_cache
= (*cache_p
);
1570 int cortex_a8_init_target(struct command_context_s
*cmd_ctx
,
1571 struct target_s
*target
)
1573 cortex_a8_build_reg_cache(target
);
1577 int cortex_a8_init_arch_info(target_t
*target
,
1578 cortex_a8_common_t
*cortex_a8
, jtag_tap_t
*tap
)
1580 armv4_5_common_t
*armv4_5
;
1581 armv7a_common_t
*armv7a
;
1583 armv7a
= &cortex_a8
->armv7a_common
;
1584 armv4_5
= &armv7a
->armv4_5_common
;
1585 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1587 /* Setup cortex_a8_common_t */
1588 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1589 cortex_a8
->arch_info
= NULL
;
1590 armv7a
->arch_info
= cortex_a8
;
1591 armv4_5
->arch_info
= armv7a
;
1593 armv4_5_init_arch_info(target
, armv4_5
);
1595 /* prepare JTAG information for the new target */
1596 cortex_a8
->jtag_info
.tap
= tap
;
1597 cortex_a8
->jtag_info
.scann_size
= 4;
1599 swjdp
->dp_select_value
= -1;
1600 swjdp
->ap_csw_value
= -1;
1601 swjdp
->ap_tar_value
= -1;
1602 swjdp
->jtag_info
= &cortex_a8
->jtag_info
;
1603 swjdp
->memaccess_tck
= 80;
1605 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1606 swjdp
->tar_autoincr_block
= (1 << 10);
1608 cortex_a8
->fast_reg_read
= 0;
1611 /* register arch-specific functions */
1612 armv7a
->examine_debug_reason
= NULL
;
1614 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1616 armv7a
->pre_restore_context
= NULL
;
1617 armv7a
->post_restore_context
= NULL
;
1618 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1619 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1620 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_memory
;
1621 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_memory
;
1622 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1623 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1624 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1625 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1626 armv7a
->read_cp15
= cortex_a8_read_cp15
;
1627 armv7a
->write_cp15
= cortex_a8_write_cp15
;
1630 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1632 armv4_5
->read_core_reg
= cortex_a8_read_core_reg
;
1633 armv4_5
->write_core_reg
= cortex_a8_write_core_reg
;
1634 // armv4_5->full_context = arm7_9_full_context;
1636 // armv4_5->load_core_reg_u32 = cortex_a8_load_core_reg_u32;
1637 // armv4_5->store_core_reg_u32 = cortex_a8_store_core_reg_u32;
1638 // armv4_5->read_core_reg = armv4_5_read_core_reg; /* this is default */
1639 // armv4_5->write_core_reg = armv4_5_write_core_reg;
1641 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1646 int cortex_a8_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1648 cortex_a8_common_t
*cortex_a8
= calloc(1, sizeof(cortex_a8_common_t
));
1650 cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1655 static int cortex_a8_handle_cache_info_command(struct command_context_s
*cmd_ctx
,
1656 char *cmd
, char **args
, int argc
)
1658 target_t
*target
= get_current_target(cmd_ctx
);
1659 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1660 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1662 return armv4_5_handle_cache_info_command(cmd_ctx
,
1663 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1667 static int cortex_a8_handle_dbginit_command(struct command_context_s
*cmd_ctx
,
1668 char *cmd
, char **args
, int argc
)
1670 target_t
*target
= get_current_target(cmd_ctx
);
1672 cortex_a8_init_debug_access(target
);
1678 int cortex_a8_register_commands(struct command_context_s
*cmd_ctx
)
1680 command_t
*cortex_a8_cmd
;
1681 int retval
= ERROR_OK
;
1683 armv4_5_register_commands(cmd_ctx
);
1684 armv7a_register_commands(cmd_ctx
);
1686 cortex_a8_cmd
= register_command(cmd_ctx
, NULL
, "cortex_a8",
1688 "cortex_a8 specific commands");
1690 register_command(cmd_ctx
, cortex_a8_cmd
, "cache_info",
1691 cortex_a8_handle_cache_info_command
, COMMAND_EXEC
,
1692 "display information about target caches");
1694 register_command(cmd_ctx
, cortex_a8_cmd
, "dbginit",
1695 cortex_a8_handle_dbginit_command
, COMMAND_EXEC
,
1696 "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)