1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2006 by Magnus Lundin *
8 * Copyright (C) 2008 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
11 * Copyright (C) 2009 by Dirk Behme *
12 * dirk.behme@gmail.com - copy from cortex_m3 *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program; if not, write to the *
26 * Free Software Foundation, Inc., *
27 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
29 * Cortex-A8(tm) TRM, ARM DDI 0344H *
31 ***************************************************************************/
36 #include "cortex_a8.h"
40 #include "target_request.h"
41 #include "target_type.h"
44 int cortex_a8_register_commands(struct command_context_s
*cmd_ctx
);
46 /* forward declarations */
47 int cortex_a8_target_create(struct target_s
*target
, Jim_Interp
*interp
);
48 int cortex_a8_init_target(struct command_context_s
*cmd_ctx
,
49 struct target_s
*target
);
50 int cortex_a8_examine(struct target_s
*target
);
51 int cortex_a8_poll(target_t
*target
);
52 int cortex_a8_halt(target_t
*target
);
53 int cortex_a8_resume(struct target_s
*target
, int current
, uint32_t address
,
54 int handle_breakpoints
, int debug_execution
);
55 int cortex_a8_step(struct target_s
*target
, int current
, uint32_t address
,
56 int handle_breakpoints
);
57 int cortex_a8_debug_entry(target_t
*target
);
58 int cortex_a8_restore_context(target_t
*target
);
59 int cortex_a8_bulk_write_memory(target_t
*target
, uint32_t address
,
60 uint32_t count
, uint8_t *buffer
);
61 int cortex_a8_set_breakpoint(struct target_s
*target
,
62 breakpoint_t
*breakpoint
, uint8_t matchmode
);
63 int cortex_a8_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
64 int cortex_a8_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
65 int cortex_a8_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
66 int cortex_a8_dap_read_coreregister_u32(target_t
*target
,
67 uint32_t *value
, int regnum
);
68 int cortex_a8_dap_write_coreregister_u32(target_t
*target
,
69 uint32_t value
, int regnum
);
71 target_type_t cortexa8_target
=
75 .poll
= cortex_a8_poll
,
76 .arch_state
= armv7a_arch_state
,
78 .target_request_data
= NULL
,
80 .halt
= cortex_a8_halt
,
81 .resume
= cortex_a8_resume
,
82 .step
= cortex_a8_step
,
85 .deassert_reset
= NULL
,
86 .soft_reset_halt
= NULL
,
88 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
90 .read_memory
= cortex_a8_read_memory
,
91 .write_memory
= cortex_a8_write_memory
,
92 .bulk_write_memory
= cortex_a8_bulk_write_memory
,
93 .checksum_memory
= arm7_9_checksum_memory
,
94 .blank_check_memory
= arm7_9_blank_check_memory
,
96 .run_algorithm
= armv4_5_run_algorithm
,
98 .add_breakpoint
= cortex_a8_add_breakpoint
,
99 .remove_breakpoint
= cortex_a8_remove_breakpoint
,
100 .add_watchpoint
= NULL
,
101 .remove_watchpoint
= NULL
,
103 .register_commands
= cortex_a8_register_commands
,
104 .target_create
= cortex_a8_target_create
,
105 .init_target
= cortex_a8_init_target
,
106 .examine
= cortex_a8_examine
,
111 * FIXME do topology discovery using the ROM; don't
112 * assume this is an OMAP3.
114 #define swjdp_memoryap 0
115 #define swjdp_debugap 1
116 #define OMAP3530_DEBUG_BASE 0x54011000
119 * Cortex-A8 Basic debug access, very low level assumes state is saved
121 int cortex_a8_init_debug_access(target_t
*target
)
123 /* get pointers to arch-specific information */
124 armv4_5_common_t
*armv4_5
= target
->arch_info
;
125 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
126 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
133 /* Unlocking the debug registers for modification */
134 /* The debugport might be uninitialised so try twice */
135 retval
= mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
136 if (retval
!= ERROR_OK
)
137 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
138 /* Clear Sticky Power Down status Bit in PRSR to enable access to
139 the registers in the Core Power Domain */
140 retval
= mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_PRSR
, &dummy
);
141 /* Enabling of instruction execution in debug mode is done in debug_entry code */
146 int cortex_a8_exec_opcode(target_t
*target
, uint32_t opcode
)
150 /* get pointers to arch-specific information */
151 armv4_5_common_t
*armv4_5
= target
->arch_info
;
152 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
153 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
155 LOG_DEBUG("exec opcode 0x%08" PRIx32
, opcode
);
158 retval
= mem_ap_read_atomic_u32(swjdp
,
159 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
160 if (retval
!= ERROR_OK
)
163 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
165 mem_ap_write_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_ITR
, opcode
);
169 retval
= mem_ap_read_atomic_u32(swjdp
,
170 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
171 if (retval
!= ERROR_OK
)
174 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
179 /**************************************************************************
180 Read core register with very few exec_opcode, fast but needs work_area.
181 This can cause problems with MMU active.
182 **************************************************************************/
183 int cortex_a8_read_regs_through_mem(target_t
*target
, uint32_t address
,
186 int retval
= ERROR_OK
;
187 /* get pointers to arch-specific information */
188 armv4_5_common_t
*armv4_5
= target
->arch_info
;
189 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
190 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
192 cortex_a8_dap_read_coreregister_u32(target
, regfile
, 0);
193 cortex_a8_dap_write_coreregister_u32(target
, address
, 0);
194 cortex_a8_exec_opcode(target
, ARMV4_5_STMIA(0, 0xFFFE, 0, 0));
195 dap_ap_select(swjdp
, swjdp_memoryap
);
196 mem_ap_read_buf_u32(swjdp
, (uint8_t *)(®file
[1]), 4*15, address
);
197 dap_ap_select(swjdp
, swjdp_debugap
);
202 int cortex_a8_read_cp(target_t
*target
, uint32_t *value
, uint8_t CP
,
203 uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
206 /* get pointers to arch-specific information */
207 armv4_5_common_t
*armv4_5
= target
->arch_info
;
208 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
209 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
211 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(CP
, op1
, 0, CRn
, CRm
, op2
));
212 /* Move R0 to DTRTX */
213 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
216 retval
= mem_ap_read_atomic_u32(swjdp
,
217 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
222 int cortex_a8_write_cp(target_t
*target
, uint32_t value
,
223 uint8_t CP
, uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
226 /* get pointers to arch-specific information */
227 armv4_5_common_t
*armv4_5
= target
->arch_info
;
228 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
229 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
231 retval
= mem_ap_write_u32(swjdp
,
232 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
233 /* Move DTRRX to r0 */
234 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
236 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(CP
, op1
, 0, CRn
, CRm
, op2
));
240 int cortex_a8_read_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
241 uint32_t CRn
, uint32_t CRm
, uint32_t *value
)
243 return cortex_a8_read_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
246 int cortex_a8_write_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
247 uint32_t CRn
, uint32_t CRm
, uint32_t value
)
249 return cortex_a8_write_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
252 int cortex_a8_dap_read_coreregister_u32(target_t
*target
,
253 uint32_t *value
, int regnum
)
255 int retval
= ERROR_OK
;
256 uint8_t reg
= regnum
&0xFF;
259 /* get pointers to arch-specific information */
260 armv4_5_common_t
*armv4_5
= target
->arch_info
;
261 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
262 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
269 /* Rn to DCCTX, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
270 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, reg
, 0, 5, 0));
274 cortex_a8_exec_opcode(target
, 0xE1A0000F);
275 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
279 cortex_a8_exec_opcode(target
, ARMV4_5_MRS(0, 0));
280 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
286 retval
= mem_ap_read_atomic_u32(swjdp
,
287 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
289 while ((dscr
& (1 << DSCR_DTR_TX_FULL
)) == 0); /* Wait for DTRRXfull */
291 retval
= mem_ap_read_atomic_u32(swjdp
,
292 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
297 int cortex_a8_dap_write_coreregister_u32(target_t
*target
, uint32_t value
, int regnum
)
299 int retval
= ERROR_OK
;
300 uint8_t Rd
= regnum
&0xFF;
302 /* get pointers to arch-specific information */
303 armv4_5_common_t
*armv4_5
= target
->arch_info
;
304 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
305 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
311 retval
= mem_ap_write_u32(swjdp
,
312 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
316 /* DCCRX to Rd, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
317 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, Rd
, 0, 5, 0));
321 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
322 cortex_a8_exec_opcode(target
, 0xE1A0F000);
326 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
327 cortex_a8_exec_opcode(target
, ARMV4_5_MSR_GP(0, 0xF, 0));
328 /* Execute a PrefetchFlush instruction through the ITR. */
329 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(15, 0, 0, 7, 5, 4));
336 * Cortex-A8 Run control
339 int cortex_a8_poll(target_t
*target
)
341 int retval
= ERROR_OK
;
343 /* get pointers to arch-specific information */
344 armv4_5_common_t
*armv4_5
= target
->arch_info
;
345 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
346 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
347 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
350 enum target_state prev_target_state
= target
->state
;
352 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
353 dap_ap_select(swjdp
, swjdp_debugap
);
354 retval
= mem_ap_read_atomic_u32(swjdp
,
355 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
356 if (retval
!= ERROR_OK
)
358 dap_ap_select(swjdp
, saved_apsel
);
361 cortex_a8
->cpudbg_dscr
= dscr
;
363 if ((dscr
& 0x3) == 0x3)
365 if (prev_target_state
!= TARGET_HALTED
)
367 /* We have a halting debug event */
368 LOG_DEBUG("Target halted");
369 target
->state
= TARGET_HALTED
;
370 if ((prev_target_state
== TARGET_RUNNING
)
371 || (prev_target_state
== TARGET_RESET
))
373 retval
= cortex_a8_debug_entry(target
);
374 if (retval
!= ERROR_OK
)
377 target_call_event_callbacks(target
,
378 TARGET_EVENT_HALTED
);
380 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
384 retval
= cortex_a8_debug_entry(target
);
385 if (retval
!= ERROR_OK
)
388 target_call_event_callbacks(target
,
389 TARGET_EVENT_DEBUG_HALTED
);
393 else if ((dscr
& 0x3) == 0x2)
395 target
->state
= TARGET_RUNNING
;
399 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32
, dscr
);
400 target
->state
= TARGET_UNKNOWN
;
403 dap_ap_select(swjdp
, saved_apsel
);
408 int cortex_a8_halt(target_t
*target
)
410 int retval
= ERROR_OK
;
413 /* get pointers to arch-specific information */
414 armv4_5_common_t
*armv4_5
= target
->arch_info
;
415 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
416 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
418 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
419 dap_ap_select(swjdp
, swjdp_debugap
);
422 * Tell the core to be halted by writing DRCR with 0x1
423 * and then wait for the core to be halted.
425 retval
= mem_ap_write_atomic_u32(swjdp
,
426 armv7a
->debug_base
+ CPUDBG_DRCR
, 0x1);
429 * enter halting debug mode
431 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
432 retval
= mem_ap_write_atomic_u32(swjdp
,
433 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
| (1 << DSCR_HALT_DBG_MODE
));
435 if (retval
!= ERROR_OK
)
439 mem_ap_read_atomic_u32(swjdp
,
440 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
441 } while ((dscr
& (1 << DSCR_CORE_HALTED
)) == 0);
443 target
->debug_reason
= DBG_REASON_DBGRQ
;
446 dap_ap_select(swjdp
, saved_apsel
);
450 int cortex_a8_resume(struct target_s
*target
, int current
,
451 uint32_t address
, int handle_breakpoints
, int debug_execution
)
453 /* get pointers to arch-specific information */
454 armv4_5_common_t
*armv4_5
= target
->arch_info
;
455 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
456 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
458 // breakpoint_t *breakpoint = NULL;
459 uint32_t resume_pc
, dscr
;
461 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
462 dap_ap_select(swjdp
, swjdp_debugap
);
464 if (!debug_execution
)
466 target_free_all_working_areas(target
);
467 // cortex_m3_enable_breakpoints(target);
468 // cortex_m3_enable_watchpoints(target);
474 /* Disable interrupts */
475 /* We disable interrupts in the PRIMASK register instead of
476 * masking with C_MASKINTS,
477 * This is probably the same issue as Cortex-M3 Errata 377493:
478 * C_MASKINTS in parallel with disabled interrupts can cause
479 * local faults to not be taken. */
480 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
481 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
482 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
484 /* Make sure we are in Thumb mode */
485 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
486 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
487 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
488 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
492 /* current = 1: continue on current pc, otherwise continue at <address> */
493 resume_pc
= buf_get_u32(
494 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
495 armv4_5
->core_mode
, 15).value
,
500 /* Make sure that the Armv7 gdb thumb fixups does not
501 * kill the return address
503 if (armv7a
->core_state
== ARMV7A_STATE_ARM
)
505 resume_pc
&= 0xFFFFFFFC;
507 /* When the return address is loaded into PC
508 * bit 0 must be 1 to stay in Thumb state
510 if (armv7a
->core_state
== ARMV7A_STATE_THUMB
)
514 LOG_DEBUG("resume pc = 0x%08" PRIx32
, resume_pc
);
515 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
516 armv4_5
->core_mode
, 15).value
,
518 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
519 armv4_5
->core_mode
, 15).dirty
= 1;
520 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
521 armv4_5
->core_mode
, 15).valid
= 1;
523 cortex_a8_restore_context(target
);
524 // arm7_9_restore_context(target); TODO Context is currently NOT Properly restored
526 /* the front-end may request us not to handle breakpoints */
527 if (handle_breakpoints
)
529 /* Single step past breakpoint at current address */
530 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
532 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
533 cortex_m3_unset_breakpoint(target
, breakpoint
);
534 cortex_m3_single_step_core(target
);
535 cortex_m3_set_breakpoint(target
, breakpoint
);
540 /* Restart core and wait for it to be started */
541 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DRCR
, 0x2);
544 mem_ap_read_atomic_u32(swjdp
,
545 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
546 } while ((dscr
& (1 << DSCR_CORE_RESTARTED
)) == 0);
548 target
->debug_reason
= DBG_REASON_NOTHALTED
;
549 target
->state
= TARGET_RUNNING
;
551 /* registers are now invalid */
552 armv4_5_invalidate_core_regs(target
);
554 if (!debug_execution
)
556 target
->state
= TARGET_RUNNING
;
557 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
558 LOG_DEBUG("target resumed at 0x%" PRIx32
, resume_pc
);
562 target
->state
= TARGET_DEBUG_RUNNING
;
563 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
564 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, resume_pc
);
567 dap_ap_select(swjdp
, saved_apsel
);
572 int cortex_a8_debug_entry(target_t
*target
)
575 uint32_t regfile
[16], pc
, cpsr
, dscr
;
576 int retval
= ERROR_OK
;
577 working_area_t
*regfile_working_area
= NULL
;
579 /* get pointers to arch-specific information */
580 armv4_5_common_t
*armv4_5
= target
->arch_info
;
581 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
582 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
583 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
585 if (armv7a
->pre_debug_entry
)
586 armv7a
->pre_debug_entry(target
);
588 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
590 /* Enable the ITR execution once we are in debug mode */
591 mem_ap_read_atomic_u32(swjdp
,
592 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
593 dscr
|= (1 << DSCR_EXT_INT_EN
);
594 retval
= mem_ap_write_atomic_u32(swjdp
,
595 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
);
597 /* Examine debug reason */
598 switch ((cortex_a8
->cpudbg_dscr
>> 2)&0xF)
602 target
->debug_reason
= DBG_REASON_DBGRQ
;
606 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
609 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
612 target
->debug_reason
= DBG_REASON_UNDEFINED
;
616 /* Examine target state and mode */
617 if (cortex_a8
->fast_reg_read
)
618 target_alloc_working_area(target
, 64, ®file_working_area
);
620 /* First load register acessible through core debug port*/
621 if (!regfile_working_area
)
623 for (i
= 0; i
<= 15; i
++)
624 cortex_a8_dap_read_coreregister_u32(target
,
629 dap_ap_select(swjdp
, swjdp_memoryap
);
630 cortex_a8_read_regs_through_mem(target
,
631 regfile_working_area
->address
, regfile
);
632 dap_ap_select(swjdp
, swjdp_memoryap
);
633 target_free_working_area(target
, regfile_working_area
);
636 cortex_a8_dap_read_coreregister_u32(target
, &cpsr
, 16);
638 dap_ap_select(swjdp
, swjdp_debugap
);
639 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
641 armv4_5
->core_mode
= cpsr
& 0x1F;
642 armv7a
->core_state
= (cpsr
& 0x20)?ARMV7A_STATE_THUMB
:ARMV7A_STATE_ARM
;
644 for (i
= 0; i
<= ARM_PC
; i
++)
646 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
647 armv4_5
->core_mode
, i
).value
,
649 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
650 armv4_5
->core_mode
, i
).valid
= 1;
651 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
652 armv4_5
->core_mode
, i
).dirty
= 0;
654 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
655 armv4_5
->core_mode
, 16).value
,
657 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
658 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
660 /* Fixup PC Resume Address */
661 if (armv7a
->core_state
== ARMV7A_STATE_THUMB
)
663 // T bit set for Thumb or ThumbEE state
664 regfile
[ARM_PC
] -= 4;
669 regfile
[ARM_PC
] -= 8;
671 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
672 armv4_5
->core_mode
, ARM_PC
).value
,
673 0, 32, regfile
[ARM_PC
]);
675 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 0)
676 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
677 armv4_5
->core_mode
, 0).valid
;
678 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 15)
679 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
680 armv4_5
->core_mode
, 15).valid
;
683 /* TODO, Move this */
684 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
685 cortex_a8_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
686 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
688 cortex_a8_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
689 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
691 cortex_a8_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
692 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
695 /* Are we in an exception handler */
696 // armv4_5->exception_number = 0;
697 if (armv7a
->post_debug_entry
)
698 armv7a
->post_debug_entry(target
);
706 void cortex_a8_post_debug_entry(target_t
*target
)
708 /* get pointers to arch-specific information */
709 armv4_5_common_t
*armv4_5
= target
->arch_info
;
710 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
711 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
713 // cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
714 /* examine cp15 control reg */
715 armv7a
->read_cp15(target
, 0, 0, 1, 0, &cortex_a8
->cp15_control_reg
);
716 jtag_execute_queue();
717 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
719 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
721 uint32_t cache_type_reg
;
722 /* identify caches */
723 armv7a
->read_cp15(target
, 0, 1, 0, 0, &cache_type_reg
);
724 jtag_execute_queue();
725 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
726 armv4_5_identify_cache(cache_type_reg
,
727 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
730 armv7a
->armv4_5_mmu
.mmu_enabled
=
731 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
732 armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
=
733 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
734 armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
=
735 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
740 int cortex_a8_step(struct target_s
*target
, int current
, uint32_t address
,
741 int handle_breakpoints
)
743 /* get pointers to arch-specific information */
744 armv4_5_common_t
*armv4_5
= target
->arch_info
;
745 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
746 breakpoint_t
*breakpoint
= NULL
;
747 breakpoint_t stepbreakpoint
;
751 if (target
->state
!= TARGET_HALTED
)
753 LOG_WARNING("target not halted");
754 return ERROR_TARGET_NOT_HALTED
;
757 /* current = 1: continue on current pc, otherwise continue at <address> */
760 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
761 armv4_5
->core_mode
, ARM_PC
).value
,
766 address
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
767 armv4_5
->core_mode
, ARM_PC
).value
,
771 /* The front-end may request us not to handle breakpoints.
772 * But since Cortex-A8 uses breakpoint for single step,
773 * we MUST handle breakpoints.
775 handle_breakpoints
= 1;
776 if (handle_breakpoints
) {
777 breakpoint
= breakpoint_find(target
,
778 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
779 armv4_5
->core_mode
, 15).value
,
782 cortex_a8_unset_breakpoint(target
, breakpoint
);
785 /* Setup single step breakpoint */
786 stepbreakpoint
.address
= address
;
787 stepbreakpoint
.length
= (armv7a
->core_state
== ARMV7A_STATE_THUMB
) ? 2 : 4;
788 stepbreakpoint
.type
= BKPT_HARD
;
789 stepbreakpoint
.set
= 0;
791 /* Break on IVA mismatch */
792 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
794 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
796 cortex_a8_resume(target
, 1, address
, 0, 0);
798 while (target
->state
!= TARGET_HALTED
)
800 cortex_a8_poll(target
);
803 LOG_WARNING("timeout waiting for target halt");
808 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
809 if (timeout
> 0) target
->debug_reason
= DBG_REASON_BREAKPOINT
;
812 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
814 if (target
->state
!= TARGET_HALTED
)
815 LOG_DEBUG("target stepped");
820 int cortex_a8_restore_context(target_t
*target
)
825 /* get pointers to arch-specific information */
826 armv4_5_common_t
*armv4_5
= target
->arch_info
;
827 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
831 if (armv7a
->pre_restore_context
)
832 armv7a
->pre_restore_context(target
);
834 for (i
= 15; i
>= 0; i
--)
836 if (ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
837 armv4_5
->core_mode
, i
).dirty
)
839 value
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
840 armv4_5
->core_mode
, i
).value
,
842 /* TODO Check return values */
843 cortex_a8_dap_write_coreregister_u32(target
, value
, i
);
847 if (armv7a
->post_restore_context
)
848 armv7a
->post_restore_context(target
);
855 * Cortex-A8 Core register functions
858 int cortex_a8_load_core_reg_u32(struct target_s
*target
, int num
,
859 armv4_5_mode_t mode
, uint32_t * value
)
862 /* get pointers to arch-specific information */
863 armv4_5_common_t
*armv4_5
= target
->arch_info
;
865 if ((num
<= ARM_CPSR
))
867 /* read a normal core register */
868 retval
= cortex_a8_dap_read_coreregister_u32(target
, value
, num
);
870 if (retval
!= ERROR_OK
)
872 LOG_ERROR("JTAG failure %i", retval
);
873 return ERROR_JTAG_DEVICE_ERROR
;
875 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
, num
, *value
);
879 return ERROR_INVALID_ARGUMENTS
;
882 /* Register other than r0 - r14 uses r0 for access */
884 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
885 armv4_5
->core_mode
, 0).dirty
=
886 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
887 armv4_5
->core_mode
, 0).valid
;
888 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
889 armv4_5
->core_mode
, 15).dirty
=
890 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
891 armv4_5
->core_mode
, 15).valid
;
896 int cortex_a8_store_core_reg_u32(struct target_s
*target
, int num
,
897 armv4_5_mode_t mode
, uint32_t value
)
902 /* get pointers to arch-specific information */
903 armv4_5_common_t
*armv4_5
= target
->arch_info
;
905 #ifdef ARMV7_GDB_HACKS
906 /* If the LR register is being modified, make sure it will put us
907 * in "thumb" mode, or an INVSTATE exception will occur. This is a
908 * hack to deal with the fact that gdb will sometimes "forge"
909 * return addresses, and doesn't set the LSB correctly (i.e., when
910 * printing expressions containing function calls, it sets LR=0.) */
916 if ((num
<= ARM_CPSR
))
918 retval
= cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
919 if (retval
!= ERROR_OK
)
921 LOG_ERROR("JTAG failure %i", retval
);
922 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
923 armv4_5
->core_mode
, num
).dirty
=
924 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
925 armv4_5
->core_mode
, num
).valid
;
926 return ERROR_JTAG_DEVICE_ERROR
;
928 LOG_DEBUG("write core reg %i value 0x%" PRIx32
, num
, value
);
932 return ERROR_INVALID_ARGUMENTS
;
939 int cortex_a8_read_core_reg(struct target_s
*target
, int num
,
940 enum armv4_5_mode mode
)
944 armv4_5_common_t
*armv4_5
= target
->arch_info
;
945 cortex_a8_dap_read_coreregister_u32(target
, &value
, num
);
947 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
952 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
953 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
954 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
955 mode
, num
).value
, 0, 32, value
);
960 int cortex_a8_write_core_reg(struct target_s
*target
, int num
,
961 enum armv4_5_mode mode
, uint32_t value
)
964 armv4_5_common_t
*armv4_5
= target
->arch_info
;
966 cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
967 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
972 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
973 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
980 * Cortex-A8 Breakpoint and watchpoint fuctions
983 /* Setup hardware Breakpoint Register Pair */
984 int cortex_a8_set_breakpoint(struct target_s
*target
,
985 breakpoint_t
*breakpoint
, uint8_t matchmode
)
990 uint8_t byte_addr_select
= 0x0F;
993 /* get pointers to arch-specific information */
994 armv4_5_common_t
*armv4_5
= target
->arch_info
;
995 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
996 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
997 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
1001 LOG_WARNING("breakpoint already set");
1005 if (breakpoint
->type
== BKPT_HARD
)
1007 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
1009 if (brp_i
>= cortex_a8
->brp_num
)
1011 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1014 breakpoint
->set
= brp_i
+ 1;
1015 if (breakpoint
->length
== 2)
1017 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1019 control
= ((matchmode
& 0x7) << 20)
1020 | (byte_addr_select
<< 5)
1022 brp_list
[brp_i
].used
= 1;
1023 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1024 brp_list
[brp_i
].control
= control
;
1025 target_write_u32(target
, armv7a
->debug_base
1026 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1027 brp_list
[brp_i
].value
);
1028 target_write_u32(target
, armv7a
->debug_base
1029 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1030 brp_list
[brp_i
].control
);
1031 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1032 brp_list
[brp_i
].control
,
1033 brp_list
[brp_i
].value
);
1035 else if (breakpoint
->type
== BKPT_SOFT
)
1038 if (breakpoint
->length
== 2)
1040 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1044 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1046 retval
= target
->type
->read_memory(target
,
1047 breakpoint
->address
& 0xFFFFFFFE,
1048 breakpoint
->length
, 1,
1049 breakpoint
->orig_instr
);
1050 if (retval
!= ERROR_OK
)
1052 retval
= target
->type
->write_memory(target
,
1053 breakpoint
->address
& 0xFFFFFFFE,
1054 breakpoint
->length
, 1, code
);
1055 if (retval
!= ERROR_OK
)
1057 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1063 int cortex_a8_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1066 /* get pointers to arch-specific information */
1067 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1068 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1069 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1070 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
1072 if (!breakpoint
->set
)
1074 LOG_WARNING("breakpoint not set");
1078 if (breakpoint
->type
== BKPT_HARD
)
1080 int brp_i
= breakpoint
->set
- 1;
1081 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1083 LOG_DEBUG("Invalid BRP number in breakpoint");
1086 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1087 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1088 brp_list
[brp_i
].used
= 0;
1089 brp_list
[brp_i
].value
= 0;
1090 brp_list
[brp_i
].control
= 0;
1091 target_write_u32(target
, armv7a
->debug_base
1092 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1093 brp_list
[brp_i
].control
);
1094 target_write_u32(target
, armv7a
->debug_base
1095 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1096 brp_list
[brp_i
].value
);
1100 /* restore original instruction (kept in target endianness) */
1101 if (breakpoint
->length
== 4)
1103 retval
= target
->type
->write_memory(target
,
1104 breakpoint
->address
& 0xFFFFFFFE,
1105 4, 1, breakpoint
->orig_instr
);
1106 if (retval
!= ERROR_OK
)
1111 retval
= target
->type
->write_memory(target
,
1112 breakpoint
->address
& 0xFFFFFFFE,
1113 2, 1, breakpoint
->orig_instr
);
1114 if (retval
!= ERROR_OK
)
1118 breakpoint
->set
= 0;
1123 int cortex_a8_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1125 /* get pointers to arch-specific information */
1126 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1127 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1128 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1130 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1132 LOG_INFO("no hardware breakpoint available");
1133 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1136 if (breakpoint
->type
== BKPT_HARD
)
1137 cortex_a8
->brp_num_available
--;
1138 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1143 int cortex_a8_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1145 /* get pointers to arch-specific information */
1146 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1147 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1148 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1151 /* It is perfectly possible to remove brakpoints while the taget is running */
1152 if (target
->state
!= TARGET_HALTED
)
1154 LOG_WARNING("target not halted");
1155 return ERROR_TARGET_NOT_HALTED
;
1159 if (breakpoint
->set
)
1161 cortex_a8_unset_breakpoint(target
, breakpoint
);
1162 if (breakpoint
->type
== BKPT_HARD
)
1163 cortex_a8
->brp_num_available
++ ;
1173 * Cortex-A8 Reset fuctions
1178 * Cortex-A8 Memory access
1180 * This is same Cortex M3 but we must also use the correct
1181 * ap number for every access.
1184 int cortex_a8_read_memory(struct target_s
*target
, uint32_t address
,
1185 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1187 /* get pointers to arch-specific information */
1188 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1189 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1190 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1192 int retval
= ERROR_OK
;
1194 /* sanitize arguments */
1195 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1196 return ERROR_INVALID_ARGUMENTS
;
1198 /* cortex_a8 handles unaligned memory access */
1200 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1205 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1208 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1211 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1214 LOG_ERROR("BUG: we shouldn't get here");
1221 int cortex_a8_write_memory(struct target_s
*target
, uint32_t address
,
1222 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1224 /* get pointers to arch-specific information */
1225 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1226 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1227 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1231 /* sanitize arguments */
1232 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1233 return ERROR_INVALID_ARGUMENTS
;
1235 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1240 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1243 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1246 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1249 LOG_ERROR("BUG: we shouldn't get here");
1253 /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */
1254 /* invalidate I-Cache */
1255 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
1257 /* Invalidate ICache single entry with MVA, repeat this for all cache
1258 lines in the address range, Cortex-A8 has fixed 64 byte line length */
1259 /* Invalidate Cache single entry with MVA to PoU */
1260 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1261 armv7a
->write_cp15(target
, 0, 1, 7, 5, cacheline
); /* I-Cache to PoU */
1263 /* invalidate D-Cache */
1264 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
1266 /* Invalidate Cache single entry with MVA to PoC */
1267 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1268 armv7a
->write_cp15(target
, 0, 1, 7, 6, cacheline
); /* U/D cache to PoC */
1274 int cortex_a8_bulk_write_memory(target_t
*target
, uint32_t address
,
1275 uint32_t count
, uint8_t *buffer
)
1277 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1281 int cortex_a8_dcc_read(swjdp_common_t
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1286 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1287 *ctrl
= (uint8_t)dcrdr
;
1288 *value
= (uint8_t)(dcrdr
>> 8);
1290 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1292 /* write ack back to software dcc register
1293 * signify we have read data */
1294 if (dcrdr
& (1 << 0))
1297 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1304 int cortex_a8_handle_target_request(void *priv
)
1306 target_t
*target
= priv
;
1307 if (!target
->type
->examined
)
1309 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1310 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1311 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1314 if (!target
->dbg_msg_enabled
)
1317 if (target
->state
== TARGET_RUNNING
)
1322 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1324 /* check if we have data */
1325 if (ctrl
& (1 << 0))
1329 /* we assume target is quick enough */
1331 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1332 request
|= (data
<< 8);
1333 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1334 request
|= (data
<< 16);
1335 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1336 request
|= (data
<< 24);
1337 target_request(target
, request
);
1345 * Cortex-A8 target information and configuration
1348 int cortex_a8_examine(struct target_s
*target
)
1350 /* get pointers to arch-specific information */
1351 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1352 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1353 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1354 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1358 int retval
= ERROR_OK
;
1359 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1363 /* Here we shall insert a proper ROM Table scan */
1364 armv7a
->debug_base
= OMAP3530_DEBUG_BASE
;
1366 /* We do one extra read to ensure DAP is configured,
1367 * we call ahbap_debugport_init(swjdp) instead
1369 ahbap_debugport_init(swjdp
);
1370 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
1371 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1372 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1374 LOG_DEBUG("Examine failed");
1378 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1379 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1381 LOG_DEBUG("Examine failed");
1385 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1386 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1388 LOG_DEBUG("Examine failed");
1392 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1393 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1395 LOG_DEBUG("Examine failed");
1399 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1400 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1401 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1402 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1404 /* Setup Breakpoint Register Pairs */
1405 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1406 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1407 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1408 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(cortex_a8_brp_t
));
1409 // cortex_a8->brb_enabled = ????;
1410 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1412 cortex_a8
->brp_list
[i
].used
= 0;
1413 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1414 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1416 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1417 cortex_a8
->brp_list
[i
].value
= 0;
1418 cortex_a8
->brp_list
[i
].control
= 0;
1419 cortex_a8
->brp_list
[i
].BRPn
= i
;
1422 /* Setup Watchpoint Register Pairs */
1423 cortex_a8
->wrp_num
= ((didr
>> 28) & 0x0F) + 1;
1424 cortex_a8
->wrp_num_available
= cortex_a8
->wrp_num
;
1425 cortex_a8
->wrp_list
= calloc(cortex_a8
->wrp_num
, sizeof(cortex_a8_wrp_t
));
1426 for (i
= 0; i
< cortex_a8
->wrp_num
; i
++)
1428 cortex_a8
->wrp_list
[i
].used
= 0;
1429 cortex_a8
->wrp_list
[i
].type
= 0;
1430 cortex_a8
->wrp_list
[i
].value
= 0;
1431 cortex_a8
->wrp_list
[i
].control
= 0;
1432 cortex_a8
->wrp_list
[i
].WRPn
= i
;
1434 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1435 cortex_a8
->brp_num
, cortex_a8
->wrp_num
);
1437 /* Configure core debug access */
1438 cortex_a8_init_debug_access(target
);
1440 target
->type
->examined
= 1;
1446 * Cortex-A8 target creation and initialization
1449 void cortex_a8_build_reg_cache(target_t
*target
)
1451 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1452 /* get pointers to arch-specific information */
1453 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1455 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
1456 armv4_5
->core_cache
= (*cache_p
);
1460 int cortex_a8_init_target(struct command_context_s
*cmd_ctx
,
1461 struct target_s
*target
)
1463 cortex_a8_build_reg_cache(target
);
1467 int cortex_a8_init_arch_info(target_t
*target
,
1468 cortex_a8_common_t
*cortex_a8
, jtag_tap_t
*tap
)
1470 armv4_5_common_t
*armv4_5
;
1471 armv7a_common_t
*armv7a
;
1473 armv7a
= &cortex_a8
->armv7a_common
;
1474 armv4_5
= &armv7a
->armv4_5_common
;
1475 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1477 /* Setup cortex_a8_common_t */
1478 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1479 cortex_a8
->arch_info
= NULL
;
1480 armv7a
->arch_info
= cortex_a8
;
1481 armv4_5
->arch_info
= armv7a
;
1483 armv4_5_init_arch_info(target
, armv4_5
);
1485 /* prepare JTAG information for the new target */
1486 cortex_a8
->jtag_info
.tap
= tap
;
1487 cortex_a8
->jtag_info
.scann_size
= 4;
1489 swjdp
->dp_select_value
= -1;
1490 swjdp
->ap_csw_value
= -1;
1491 swjdp
->ap_tar_value
= -1;
1492 swjdp
->jtag_info
= &cortex_a8
->jtag_info
;
1493 swjdp
->memaccess_tck
= 80;
1495 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1496 swjdp
->tar_autoincr_block
= (1 << 10);
1498 cortex_a8
->fast_reg_read
= 0;
1501 /* register arch-specific functions */
1502 armv7a
->examine_debug_reason
= NULL
;
1504 armv7a
->pre_debug_entry
= NULL
;
1505 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1507 armv7a
->pre_restore_context
= NULL
;
1508 armv7a
->post_restore_context
= NULL
;
1509 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1510 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1511 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_memory
;
1512 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_memory
;
1513 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1514 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1515 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1516 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1517 armv7a
->read_cp15
= cortex_a8_read_cp15
;
1518 armv7a
->write_cp15
= cortex_a8_write_cp15
;
1521 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1523 armv4_5
->read_core_reg
= cortex_a8_read_core_reg
;
1524 armv4_5
->write_core_reg
= cortex_a8_write_core_reg
;
1525 // armv4_5->full_context = arm7_9_full_context;
1527 // armv4_5->load_core_reg_u32 = cortex_a8_load_core_reg_u32;
1528 // armv4_5->store_core_reg_u32 = cortex_a8_store_core_reg_u32;
1529 // armv4_5->read_core_reg = armv4_5_read_core_reg; /* this is default */
1530 // armv4_5->write_core_reg = armv4_5_write_core_reg;
1532 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1537 int cortex_a8_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1539 cortex_a8_common_t
*cortex_a8
= calloc(1, sizeof(cortex_a8_common_t
));
1541 cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1546 static int cortex_a8_handle_cache_info_command(struct command_context_s
*cmd_ctx
,
1547 char *cmd
, char **args
, int argc
)
1549 target_t
*target
= get_current_target(cmd_ctx
);
1550 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1551 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1553 return armv4_5_handle_cache_info_command(cmd_ctx
,
1554 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1558 static int cortex_a8_handle_dbginit_command(struct command_context_s
*cmd_ctx
,
1559 char *cmd
, char **args
, int argc
)
1561 target_t
*target
= get_current_target(cmd_ctx
);
1563 cortex_a8_init_debug_access(target
);
1569 int cortex_a8_register_commands(struct command_context_s
*cmd_ctx
)
1571 command_t
*cortex_a8_cmd
;
1572 int retval
= ERROR_OK
;
1574 armv4_5_register_commands(cmd_ctx
);
1575 armv7a_register_commands(cmd_ctx
);
1577 cortex_a8_cmd
= register_command(cmd_ctx
, NULL
, "cortex_a8",
1579 "cortex_a8 specific commands");
1581 register_command(cmd_ctx
, cortex_a8_cmd
, "cache_info",
1582 cortex_a8_handle_cache_info_command
, COMMAND_EXEC
,
1583 "display information about target caches");
1585 register_command(cmd_ctx
, cortex_a8_cmd
, "dbginit",
1586 cortex_a8_handle_dbginit_command
, COMMAND_EXEC
,
1587 "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)