1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2006 by Magnus Lundin *
8 * Copyright (C) 2008 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
11 * Copyright (C) 2009 by Dirk Behme *
12 * dirk.behme@gmail.com - copy from cortex_m3 *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program; if not, write to the *
26 * Free Software Foundation, Inc., *
27 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
29 * Cortex-A8(tm) TRM, ARM DDI 0344H *
31 ***************************************************************************/
36 #include "cortex_a8.h"
40 #include "target_request.h"
41 #include "target_type.h"
44 int cortex_a8_register_commands(struct command_context_s
*cmd_ctx
);
46 /* forward declarations */
47 int cortex_a8_target_create(struct target_s
*target
, Jim_Interp
*interp
);
48 int cortex_a8_init_target(struct command_context_s
*cmd_ctx
,
49 struct target_s
*target
);
50 int cortex_a8_examine(struct target_s
*target
);
51 int cortex_a8_poll(target_t
*target
);
52 int cortex_a8_halt(target_t
*target
);
53 int cortex_a8_resume(struct target_s
*target
, int current
, uint32_t address
,
54 int handle_breakpoints
, int debug_execution
);
55 int cortex_a8_step(struct target_s
*target
, int current
, uint32_t address
,
56 int handle_breakpoints
);
57 int cortex_a8_debug_entry(target_t
*target
);
58 int cortex_a8_restore_context(target_t
*target
);
59 int cortex_a8_bulk_write_memory(target_t
*target
, uint32_t address
,
60 uint32_t count
, uint8_t *buffer
);
61 int cortex_a8_set_breakpoint(struct target_s
*target
,
62 breakpoint_t
*breakpoint
, uint8_t matchmode
);
63 int cortex_a8_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
64 int cortex_a8_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
65 int cortex_a8_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
66 int cortex_a8_dap_read_coreregister_u32(target_t
*target
,
67 uint32_t *value
, int regnum
);
68 int cortex_a8_dap_write_coreregister_u32(target_t
*target
,
69 uint32_t value
, int regnum
);
70 int cortex_a8_assert_reset(target_t
*target
);
71 int cortex_a8_deassert_reset(target_t
*target
);
73 target_type_t cortexa8_target
=
77 .poll
= cortex_a8_poll
,
78 .arch_state
= armv7a_arch_state
,
80 .target_request_data
= NULL
,
82 .halt
= cortex_a8_halt
,
83 .resume
= cortex_a8_resume
,
84 .step
= cortex_a8_step
,
86 .assert_reset
= cortex_a8_assert_reset
,
87 .deassert_reset
= cortex_a8_deassert_reset
,
88 .soft_reset_halt
= NULL
,
90 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
92 .read_memory
= cortex_a8_read_memory
,
93 .write_memory
= cortex_a8_write_memory
,
94 .bulk_write_memory
= cortex_a8_bulk_write_memory
,
95 .checksum_memory
= arm7_9_checksum_memory
,
96 .blank_check_memory
= arm7_9_blank_check_memory
,
98 .run_algorithm
= armv4_5_run_algorithm
,
100 .add_breakpoint
= cortex_a8_add_breakpoint
,
101 .remove_breakpoint
= cortex_a8_remove_breakpoint
,
102 .add_watchpoint
= NULL
,
103 .remove_watchpoint
= NULL
,
105 .register_commands
= cortex_a8_register_commands
,
106 .target_create
= cortex_a8_target_create
,
107 .init_target
= cortex_a8_init_target
,
108 .examine
= cortex_a8_examine
,
113 * FIXME do topology discovery using the ROM; don't
114 * assume this is an OMAP3.
116 #define swjdp_memoryap 0
117 #define swjdp_debugap 1
118 #define OMAP3530_DEBUG_BASE 0x54011000
121 * Cortex-A8 Basic debug access, very low level assumes state is saved
123 int cortex_a8_init_debug_access(target_t
*target
)
125 /* get pointers to arch-specific information */
126 armv4_5_common_t
*armv4_5
= target
->arch_info
;
127 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
128 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
135 /* Unlocking the debug registers for modification */
136 /* The debugport might be uninitialised so try twice */
137 retval
= mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
138 if (retval
!= ERROR_OK
)
139 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
140 /* Clear Sticky Power Down status Bit in PRSR to enable access to
141 the registers in the Core Power Domain */
142 retval
= mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_PRSR
, &dummy
);
143 /* Enabling of instruction execution in debug mode is done in debug_entry code */
145 /* Resync breakpoint registers */
147 /* Since this is likley called from init or reset, update targtet state information*/
148 cortex_a8_poll(target
);
153 int cortex_a8_exec_opcode(target_t
*target
, uint32_t opcode
)
157 /* get pointers to arch-specific information */
158 armv4_5_common_t
*armv4_5
= target
->arch_info
;
159 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
160 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
162 LOG_DEBUG("exec opcode 0x%08" PRIx32
, opcode
);
165 retval
= mem_ap_read_atomic_u32(swjdp
,
166 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
167 if (retval
!= ERROR_OK
)
169 LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32
, opcode
);
173 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
175 mem_ap_write_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_ITR
, opcode
);
179 retval
= mem_ap_read_atomic_u32(swjdp
,
180 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
181 if (retval
!= ERROR_OK
)
183 LOG_ERROR("Could not read DSCR register");
187 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
192 /**************************************************************************
193 Read core register with very few exec_opcode, fast but needs work_area.
194 This can cause problems with MMU active.
195 **************************************************************************/
196 int cortex_a8_read_regs_through_mem(target_t
*target
, uint32_t address
,
199 int retval
= ERROR_OK
;
200 /* get pointers to arch-specific information */
201 armv4_5_common_t
*armv4_5
= target
->arch_info
;
202 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
203 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
205 cortex_a8_dap_read_coreregister_u32(target
, regfile
, 0);
206 cortex_a8_dap_write_coreregister_u32(target
, address
, 0);
207 cortex_a8_exec_opcode(target
, ARMV4_5_STMIA(0, 0xFFFE, 0, 0));
208 dap_ap_select(swjdp
, swjdp_memoryap
);
209 mem_ap_read_buf_u32(swjdp
, (uint8_t *)(®file
[1]), 4*15, address
);
210 dap_ap_select(swjdp
, swjdp_debugap
);
215 int cortex_a8_read_cp(target_t
*target
, uint32_t *value
, uint8_t CP
,
216 uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
219 /* get pointers to arch-specific information */
220 armv4_5_common_t
*armv4_5
= target
->arch_info
;
221 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
222 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
224 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(CP
, op1
, 0, CRn
, CRm
, op2
));
225 /* Move R0 to DTRTX */
226 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
229 retval
= mem_ap_read_atomic_u32(swjdp
,
230 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
235 int cortex_a8_write_cp(target_t
*target
, uint32_t value
,
236 uint8_t CP
, uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
239 /* get pointers to arch-specific information */
240 armv4_5_common_t
*armv4_5
= target
->arch_info
;
241 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
242 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
244 retval
= mem_ap_write_u32(swjdp
,
245 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
246 /* Move DTRRX to r0 */
247 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
249 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(CP
, op1
, 0, CRn
, CRm
, op2
));
253 int cortex_a8_read_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
254 uint32_t CRn
, uint32_t CRm
, uint32_t *value
)
256 return cortex_a8_read_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
259 int cortex_a8_write_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
260 uint32_t CRn
, uint32_t CRm
, uint32_t value
)
262 return cortex_a8_write_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
265 int cortex_a8_dap_read_coreregister_u32(target_t
*target
,
266 uint32_t *value
, int regnum
)
268 int retval
= ERROR_OK
;
269 uint8_t reg
= regnum
&0xFF;
272 /* get pointers to arch-specific information */
273 armv4_5_common_t
*armv4_5
= target
->arch_info
;
274 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
275 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
282 /* Rn to DCCTX, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
283 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, reg
, 0, 5, 0));
287 cortex_a8_exec_opcode(target
, 0xE1A0000F);
288 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
292 cortex_a8_exec_opcode(target
, ARMV4_5_MRS(0, 0));
293 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
299 retval
= mem_ap_read_atomic_u32(swjdp
,
300 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
302 while ((dscr
& (1 << DSCR_DTR_TX_FULL
)) == 0); /* Wait for DTRRXfull */
304 retval
= mem_ap_read_atomic_u32(swjdp
,
305 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
310 int cortex_a8_dap_write_coreregister_u32(target_t
*target
, uint32_t value
, int regnum
)
312 int retval
= ERROR_OK
;
313 uint8_t Rd
= regnum
&0xFF;
315 /* get pointers to arch-specific information */
316 armv4_5_common_t
*armv4_5
= target
->arch_info
;
317 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
318 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
324 retval
= mem_ap_write_u32(swjdp
,
325 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
329 /* DCCRX to Rd, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
330 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, Rd
, 0, 5, 0));
334 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
335 cortex_a8_exec_opcode(target
, 0xE1A0F000);
339 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
340 cortex_a8_exec_opcode(target
, ARMV4_5_MSR_GP(0, 0xF, 0));
341 /* Execute a PrefetchFlush instruction through the ITR. */
342 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(15, 0, 0, 7, 5, 4));
348 /* Write to memory mapped registers directly with no cache or mmu handling */
349 int cortex_a8_dap_write_memap_register_u32(target_t
*target
, uint32_t address
, uint32_t value
)
353 /* get pointers to arch-specific information */
354 armv4_5_common_t
*armv4_5
= target
->arch_info
;
355 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
356 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
358 retval
= mem_ap_write_atomic_u32(swjdp
, address
, value
);
364 * Cortex-A8 Run control
367 int cortex_a8_poll(target_t
*target
)
369 int retval
= ERROR_OK
;
371 /* get pointers to arch-specific information */
372 armv4_5_common_t
*armv4_5
= target
->arch_info
;
373 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
374 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
375 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
378 enum target_state prev_target_state
= target
->state
;
380 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
381 dap_ap_select(swjdp
, swjdp_debugap
);
382 retval
= mem_ap_read_atomic_u32(swjdp
,
383 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
384 if (retval
!= ERROR_OK
)
386 dap_ap_select(swjdp
, saved_apsel
);
389 cortex_a8
->cpudbg_dscr
= dscr
;
391 if ((dscr
& 0x3) == 0x3)
393 if (prev_target_state
!= TARGET_HALTED
)
395 /* We have a halting debug event */
396 LOG_DEBUG("Target halted");
397 target
->state
= TARGET_HALTED
;
398 if ((prev_target_state
== TARGET_RUNNING
)
399 || (prev_target_state
== TARGET_RESET
))
401 retval
= cortex_a8_debug_entry(target
);
402 if (retval
!= ERROR_OK
)
405 target_call_event_callbacks(target
,
406 TARGET_EVENT_HALTED
);
408 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
412 retval
= cortex_a8_debug_entry(target
);
413 if (retval
!= ERROR_OK
)
416 target_call_event_callbacks(target
,
417 TARGET_EVENT_DEBUG_HALTED
);
421 else if ((dscr
& 0x3) == 0x2)
423 target
->state
= TARGET_RUNNING
;
427 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32
, dscr
);
428 target
->state
= TARGET_UNKNOWN
;
431 dap_ap_select(swjdp
, saved_apsel
);
436 int cortex_a8_halt(target_t
*target
)
438 int retval
= ERROR_OK
;
441 /* get pointers to arch-specific information */
442 armv4_5_common_t
*armv4_5
= target
->arch_info
;
443 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
444 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
446 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
447 dap_ap_select(swjdp
, swjdp_debugap
);
450 * Tell the core to be halted by writing DRCR with 0x1
451 * and then wait for the core to be halted.
453 retval
= mem_ap_write_atomic_u32(swjdp
,
454 armv7a
->debug_base
+ CPUDBG_DRCR
, 0x1);
457 * enter halting debug mode
459 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
460 retval
= mem_ap_write_atomic_u32(swjdp
,
461 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
| (1 << DSCR_HALT_DBG_MODE
));
463 if (retval
!= ERROR_OK
)
467 mem_ap_read_atomic_u32(swjdp
,
468 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
469 } while ((dscr
& (1 << DSCR_CORE_HALTED
)) == 0);
471 target
->debug_reason
= DBG_REASON_DBGRQ
;
474 dap_ap_select(swjdp
, saved_apsel
);
478 int cortex_a8_resume(struct target_s
*target
, int current
,
479 uint32_t address
, int handle_breakpoints
, int debug_execution
)
481 /* get pointers to arch-specific information */
482 armv4_5_common_t
*armv4_5
= target
->arch_info
;
483 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
484 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
486 // breakpoint_t *breakpoint = NULL;
487 uint32_t resume_pc
, dscr
;
489 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
490 dap_ap_select(swjdp
, swjdp_debugap
);
492 if (!debug_execution
)
494 target_free_all_working_areas(target
);
495 // cortex_m3_enable_breakpoints(target);
496 // cortex_m3_enable_watchpoints(target);
502 /* Disable interrupts */
503 /* We disable interrupts in the PRIMASK register instead of
504 * masking with C_MASKINTS,
505 * This is probably the same issue as Cortex-M3 Errata 377493:
506 * C_MASKINTS in parallel with disabled interrupts can cause
507 * local faults to not be taken. */
508 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
509 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
510 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
512 /* Make sure we are in Thumb mode */
513 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
514 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
515 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
516 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
520 /* current = 1: continue on current pc, otherwise continue at <address> */
521 resume_pc
= buf_get_u32(
522 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
523 armv4_5
->core_mode
, 15).value
,
528 /* Make sure that the Armv7 gdb thumb fixups does not
529 * kill the return address
531 if (armv7a
->core_state
== ARMV7A_STATE_ARM
)
533 resume_pc
&= 0xFFFFFFFC;
535 /* When the return address is loaded into PC
536 * bit 0 must be 1 to stay in Thumb state
538 if (armv7a
->core_state
== ARMV7A_STATE_THUMB
)
542 LOG_DEBUG("resume pc = 0x%08" PRIx32
, resume_pc
);
543 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
544 armv4_5
->core_mode
, 15).value
,
546 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
547 armv4_5
->core_mode
, 15).dirty
= 1;
548 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
549 armv4_5
->core_mode
, 15).valid
= 1;
551 cortex_a8_restore_context(target
);
552 // arm7_9_restore_context(target); TODO Context is currently NOT Properly restored
554 /* the front-end may request us not to handle breakpoints */
555 if (handle_breakpoints
)
557 /* Single step past breakpoint at current address */
558 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
560 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
561 cortex_m3_unset_breakpoint(target
, breakpoint
);
562 cortex_m3_single_step_core(target
);
563 cortex_m3_set_breakpoint(target
, breakpoint
);
568 /* Restart core and wait for it to be started */
569 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DRCR
, 0x2);
572 mem_ap_read_atomic_u32(swjdp
,
573 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
574 } while ((dscr
& (1 << DSCR_CORE_RESTARTED
)) == 0);
576 target
->debug_reason
= DBG_REASON_NOTHALTED
;
577 target
->state
= TARGET_RUNNING
;
579 /* registers are now invalid */
580 armv4_5_invalidate_core_regs(target
);
582 if (!debug_execution
)
584 target
->state
= TARGET_RUNNING
;
585 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
586 LOG_DEBUG("target resumed at 0x%" PRIx32
, resume_pc
);
590 target
->state
= TARGET_DEBUG_RUNNING
;
591 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
592 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, resume_pc
);
595 dap_ap_select(swjdp
, saved_apsel
);
600 int cortex_a8_debug_entry(target_t
*target
)
603 uint32_t regfile
[16], pc
, cpsr
, dscr
;
604 int retval
= ERROR_OK
;
605 working_area_t
*regfile_working_area
= NULL
;
607 /* get pointers to arch-specific information */
608 armv4_5_common_t
*armv4_5
= target
->arch_info
;
609 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
610 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
611 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
613 if (armv7a
->pre_debug_entry
)
614 armv7a
->pre_debug_entry(target
);
616 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
618 /* Enable the ITR execution once we are in debug mode */
619 mem_ap_read_atomic_u32(swjdp
,
620 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
621 dscr
|= (1 << DSCR_EXT_INT_EN
);
622 retval
= mem_ap_write_atomic_u32(swjdp
,
623 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
);
625 /* Examine debug reason */
626 switch ((cortex_a8
->cpudbg_dscr
>> 2)&0xF)
630 target
->debug_reason
= DBG_REASON_DBGRQ
;
634 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
637 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
640 target
->debug_reason
= DBG_REASON_UNDEFINED
;
644 /* Examine target state and mode */
645 if (cortex_a8
->fast_reg_read
)
646 target_alloc_working_area(target
, 64, ®file_working_area
);
648 /* First load register acessible through core debug port*/
649 if (!regfile_working_area
)
651 for (i
= 0; i
<= 15; i
++)
652 cortex_a8_dap_read_coreregister_u32(target
,
657 dap_ap_select(swjdp
, swjdp_memoryap
);
658 cortex_a8_read_regs_through_mem(target
,
659 regfile_working_area
->address
, regfile
);
660 dap_ap_select(swjdp
, swjdp_memoryap
);
661 target_free_working_area(target
, regfile_working_area
);
664 cortex_a8_dap_read_coreregister_u32(target
, &cpsr
, 16);
666 dap_ap_select(swjdp
, swjdp_debugap
);
667 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
669 armv4_5
->core_mode
= cpsr
& 0x1F;
670 armv7a
->core_state
= (cpsr
& 0x20)?ARMV7A_STATE_THUMB
:ARMV7A_STATE_ARM
;
672 for (i
= 0; i
<= ARM_PC
; i
++)
674 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
675 armv4_5
->core_mode
, i
).value
,
677 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
678 armv4_5
->core_mode
, i
).valid
= 1;
679 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
680 armv4_5
->core_mode
, i
).dirty
= 0;
682 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
683 armv4_5
->core_mode
, 16).value
,
685 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
686 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
688 /* Fixup PC Resume Address */
689 if (armv7a
->core_state
== ARMV7A_STATE_THUMB
)
691 // T bit set for Thumb or ThumbEE state
692 regfile
[ARM_PC
] -= 4;
697 regfile
[ARM_PC
] -= 8;
699 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
700 armv4_5
->core_mode
, ARM_PC
).value
,
701 0, 32, regfile
[ARM_PC
]);
703 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 0)
704 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
705 armv4_5
->core_mode
, 0).valid
;
706 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 15)
707 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
708 armv4_5
->core_mode
, 15).valid
;
711 /* TODO, Move this */
712 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
713 cortex_a8_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
714 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
716 cortex_a8_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
717 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
719 cortex_a8_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
720 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
723 /* Are we in an exception handler */
724 // armv4_5->exception_number = 0;
725 if (armv7a
->post_debug_entry
)
726 armv7a
->post_debug_entry(target
);
734 void cortex_a8_post_debug_entry(target_t
*target
)
736 /* get pointers to arch-specific information */
737 armv4_5_common_t
*armv4_5
= target
->arch_info
;
738 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
739 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
741 // cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
742 /* examine cp15 control reg */
743 armv7a
->read_cp15(target
, 0, 0, 1, 0, &cortex_a8
->cp15_control_reg
);
744 jtag_execute_queue();
745 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
747 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
749 uint32_t cache_type_reg
;
750 /* identify caches */
751 armv7a
->read_cp15(target
, 0, 1, 0, 0, &cache_type_reg
);
752 jtag_execute_queue();
753 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
754 armv4_5_identify_cache(cache_type_reg
,
755 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
758 armv7a
->armv4_5_mmu
.mmu_enabled
=
759 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
760 armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
=
761 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
762 armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
=
763 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
768 int cortex_a8_step(struct target_s
*target
, int current
, uint32_t address
,
769 int handle_breakpoints
)
771 /* get pointers to arch-specific information */
772 armv4_5_common_t
*armv4_5
= target
->arch_info
;
773 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
774 breakpoint_t
*breakpoint
= NULL
;
775 breakpoint_t stepbreakpoint
;
779 if (target
->state
!= TARGET_HALTED
)
781 LOG_WARNING("target not halted");
782 return ERROR_TARGET_NOT_HALTED
;
785 /* current = 1: continue on current pc, otherwise continue at <address> */
788 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
789 armv4_5
->core_mode
, ARM_PC
).value
,
794 address
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
795 armv4_5
->core_mode
, ARM_PC
).value
,
799 /* The front-end may request us not to handle breakpoints.
800 * But since Cortex-A8 uses breakpoint for single step,
801 * we MUST handle breakpoints.
803 handle_breakpoints
= 1;
804 if (handle_breakpoints
) {
805 breakpoint
= breakpoint_find(target
,
806 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
807 armv4_5
->core_mode
, 15).value
,
810 cortex_a8_unset_breakpoint(target
, breakpoint
);
813 /* Setup single step breakpoint */
814 stepbreakpoint
.address
= address
;
815 stepbreakpoint
.length
= (armv7a
->core_state
== ARMV7A_STATE_THUMB
) ? 2 : 4;
816 stepbreakpoint
.type
= BKPT_HARD
;
817 stepbreakpoint
.set
= 0;
819 /* Break on IVA mismatch */
820 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
822 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
824 cortex_a8_resume(target
, 1, address
, 0, 0);
826 while (target
->state
!= TARGET_HALTED
)
828 cortex_a8_poll(target
);
831 LOG_WARNING("timeout waiting for target halt");
836 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
837 if (timeout
> 0) target
->debug_reason
= DBG_REASON_BREAKPOINT
;
840 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
842 if (target
->state
!= TARGET_HALTED
)
843 LOG_DEBUG("target stepped");
848 int cortex_a8_restore_context(target_t
*target
)
853 /* get pointers to arch-specific information */
854 armv4_5_common_t
*armv4_5
= target
->arch_info
;
855 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
859 if (armv7a
->pre_restore_context
)
860 armv7a
->pre_restore_context(target
);
862 for (i
= 15; i
>= 0; i
--)
864 if (ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
865 armv4_5
->core_mode
, i
).dirty
)
867 value
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
868 armv4_5
->core_mode
, i
).value
,
870 /* TODO Check return values */
871 cortex_a8_dap_write_coreregister_u32(target
, value
, i
);
875 if (armv7a
->post_restore_context
)
876 armv7a
->post_restore_context(target
);
883 * Cortex-A8 Core register functions
886 int cortex_a8_load_core_reg_u32(struct target_s
*target
, int num
,
887 armv4_5_mode_t mode
, uint32_t * value
)
890 /* get pointers to arch-specific information */
891 armv4_5_common_t
*armv4_5
= target
->arch_info
;
893 if ((num
<= ARM_CPSR
))
895 /* read a normal core register */
896 retval
= cortex_a8_dap_read_coreregister_u32(target
, value
, num
);
898 if (retval
!= ERROR_OK
)
900 LOG_ERROR("JTAG failure %i", retval
);
901 return ERROR_JTAG_DEVICE_ERROR
;
903 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
, num
, *value
);
907 return ERROR_INVALID_ARGUMENTS
;
910 /* Register other than r0 - r14 uses r0 for access */
912 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
913 armv4_5
->core_mode
, 0).dirty
=
914 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
915 armv4_5
->core_mode
, 0).valid
;
916 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
917 armv4_5
->core_mode
, 15).dirty
=
918 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
919 armv4_5
->core_mode
, 15).valid
;
924 int cortex_a8_store_core_reg_u32(struct target_s
*target
, int num
,
925 armv4_5_mode_t mode
, uint32_t value
)
930 /* get pointers to arch-specific information */
931 armv4_5_common_t
*armv4_5
= target
->arch_info
;
933 #ifdef ARMV7_GDB_HACKS
934 /* If the LR register is being modified, make sure it will put us
935 * in "thumb" mode, or an INVSTATE exception will occur. This is a
936 * hack to deal with the fact that gdb will sometimes "forge"
937 * return addresses, and doesn't set the LSB correctly (i.e., when
938 * printing expressions containing function calls, it sets LR=0.) */
944 if ((num
<= ARM_CPSR
))
946 retval
= cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
947 if (retval
!= ERROR_OK
)
949 LOG_ERROR("JTAG failure %i", retval
);
950 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
951 armv4_5
->core_mode
, num
).dirty
=
952 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
953 armv4_5
->core_mode
, num
).valid
;
954 return ERROR_JTAG_DEVICE_ERROR
;
956 LOG_DEBUG("write core reg %i value 0x%" PRIx32
, num
, value
);
960 return ERROR_INVALID_ARGUMENTS
;
967 int cortex_a8_read_core_reg(struct target_s
*target
, int num
,
968 enum armv4_5_mode mode
)
972 armv4_5_common_t
*armv4_5
= target
->arch_info
;
973 cortex_a8_dap_read_coreregister_u32(target
, &value
, num
);
975 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
980 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
981 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
982 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
983 mode
, num
).value
, 0, 32, value
);
988 int cortex_a8_write_core_reg(struct target_s
*target
, int num
,
989 enum armv4_5_mode mode
, uint32_t value
)
992 armv4_5_common_t
*armv4_5
= target
->arch_info
;
994 cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
995 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
1000 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
1001 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
1008 * Cortex-A8 Breakpoint and watchpoint fuctions
1011 /* Setup hardware Breakpoint Register Pair */
1012 int cortex_a8_set_breakpoint(struct target_s
*target
,
1013 breakpoint_t
*breakpoint
, uint8_t matchmode
)
1018 uint8_t byte_addr_select
= 0x0F;
1021 /* get pointers to arch-specific information */
1022 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1023 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1024 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1025 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
1027 if (breakpoint
->set
)
1029 LOG_WARNING("breakpoint already set");
1033 if (breakpoint
->type
== BKPT_HARD
)
1035 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
1037 if (brp_i
>= cortex_a8
->brp_num
)
1039 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1042 breakpoint
->set
= brp_i
+ 1;
1043 if (breakpoint
->length
== 2)
1045 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1047 control
= ((matchmode
& 0x7) << 20)
1048 | (byte_addr_select
<< 5)
1050 brp_list
[brp_i
].used
= 1;
1051 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1052 brp_list
[brp_i
].control
= control
;
1053 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1054 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1055 brp_list
[brp_i
].value
);
1056 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1057 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1058 brp_list
[brp_i
].control
);
1059 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1060 brp_list
[brp_i
].control
,
1061 brp_list
[brp_i
].value
);
1063 else if (breakpoint
->type
== BKPT_SOFT
)
1066 if (breakpoint
->length
== 2)
1068 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1072 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1074 retval
= target
->type
->read_memory(target
,
1075 breakpoint
->address
& 0xFFFFFFFE,
1076 breakpoint
->length
, 1,
1077 breakpoint
->orig_instr
);
1078 if (retval
!= ERROR_OK
)
1080 retval
= target
->type
->write_memory(target
,
1081 breakpoint
->address
& 0xFFFFFFFE,
1082 breakpoint
->length
, 1, code
);
1083 if (retval
!= ERROR_OK
)
1085 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1091 int cortex_a8_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1094 /* get pointers to arch-specific information */
1095 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1096 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1097 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1098 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
1100 if (!breakpoint
->set
)
1102 LOG_WARNING("breakpoint not set");
1106 if (breakpoint
->type
== BKPT_HARD
)
1108 int brp_i
= breakpoint
->set
- 1;
1109 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1111 LOG_DEBUG("Invalid BRP number in breakpoint");
1114 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1115 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1116 brp_list
[brp_i
].used
= 0;
1117 brp_list
[brp_i
].value
= 0;
1118 brp_list
[brp_i
].control
= 0;
1119 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1120 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1121 brp_list
[brp_i
].control
);
1122 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1123 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1124 brp_list
[brp_i
].value
);
1128 /* restore original instruction (kept in target endianness) */
1129 if (breakpoint
->length
== 4)
1131 retval
= target
->type
->write_memory(target
,
1132 breakpoint
->address
& 0xFFFFFFFE,
1133 4, 1, breakpoint
->orig_instr
);
1134 if (retval
!= ERROR_OK
)
1139 retval
= target
->type
->write_memory(target
,
1140 breakpoint
->address
& 0xFFFFFFFE,
1141 2, 1, breakpoint
->orig_instr
);
1142 if (retval
!= ERROR_OK
)
1146 breakpoint
->set
= 0;
1151 int cortex_a8_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1153 /* get pointers to arch-specific information */
1154 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1155 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1156 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1158 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1160 LOG_INFO("no hardware breakpoint available");
1161 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1164 if (breakpoint
->type
== BKPT_HARD
)
1165 cortex_a8
->brp_num_available
--;
1166 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1171 int cortex_a8_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1173 /* get pointers to arch-specific information */
1174 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1175 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1176 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1179 /* It is perfectly possible to remove brakpoints while the taget is running */
1180 if (target
->state
!= TARGET_HALTED
)
1182 LOG_WARNING("target not halted");
1183 return ERROR_TARGET_NOT_HALTED
;
1187 if (breakpoint
->set
)
1189 cortex_a8_unset_breakpoint(target
, breakpoint
);
1190 if (breakpoint
->type
== BKPT_HARD
)
1191 cortex_a8
->brp_num_available
++ ;
1201 * Cortex-A8 Reset fuctions
1204 int cortex_a8_assert_reset(target_t
*target
)
1209 /* registers are now invalid */
1210 armv4_5_invalidate_core_regs(target
);
1212 target
->state
= TARGET_RESET
;
1217 int cortex_a8_deassert_reset(target_t
*target
)
1222 if (target
->reset_halt
)
1225 if ((retval
= target_halt(target
)) != ERROR_OK
)
1233 * Cortex-A8 Memory access
1235 * This is same Cortex M3 but we must also use the correct
1236 * ap number for every access.
1239 int cortex_a8_read_memory(struct target_s
*target
, uint32_t address
,
1240 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1242 /* get pointers to arch-specific information */
1243 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1244 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1245 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1247 int retval
= ERROR_OK
;
1249 /* sanitize arguments */
1250 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1251 return ERROR_INVALID_ARGUMENTS
;
1253 /* cortex_a8 handles unaligned memory access */
1255 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1260 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1263 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1266 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1269 LOG_ERROR("BUG: we shouldn't get here");
1276 int cortex_a8_write_memory(struct target_s
*target
, uint32_t address
,
1277 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1279 /* get pointers to arch-specific information */
1280 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1281 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1282 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1286 /* sanitize arguments */
1287 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1288 return ERROR_INVALID_ARGUMENTS
;
1290 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1295 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1298 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1301 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1304 LOG_ERROR("BUG: we shouldn't get here");
1308 /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */
1309 /* invalidate I-Cache */
1310 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
1312 /* Invalidate ICache single entry with MVA, repeat this for all cache
1313 lines in the address range, Cortex-A8 has fixed 64 byte line length */
1314 /* Invalidate Cache single entry with MVA to PoU */
1315 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1316 armv7a
->write_cp15(target
, 0, 1, 7, 5, cacheline
); /* I-Cache to PoU */
1318 /* invalidate D-Cache */
1319 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
1321 /* Invalidate Cache single entry with MVA to PoC */
1322 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1323 armv7a
->write_cp15(target
, 0, 1, 7, 6, cacheline
); /* U/D cache to PoC */
1329 int cortex_a8_bulk_write_memory(target_t
*target
, uint32_t address
,
1330 uint32_t count
, uint8_t *buffer
)
1332 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1336 int cortex_a8_dcc_read(swjdp_common_t
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1341 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1342 *ctrl
= (uint8_t)dcrdr
;
1343 *value
= (uint8_t)(dcrdr
>> 8);
1345 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1347 /* write ack back to software dcc register
1348 * signify we have read data */
1349 if (dcrdr
& (1 << 0))
1352 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1359 int cortex_a8_handle_target_request(void *priv
)
1361 target_t
*target
= priv
;
1362 if (!target
->type
->examined
)
1364 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1365 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1366 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1369 if (!target
->dbg_msg_enabled
)
1372 if (target
->state
== TARGET_RUNNING
)
1377 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1379 /* check if we have data */
1380 if (ctrl
& (1 << 0))
1384 /* we assume target is quick enough */
1386 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1387 request
|= (data
<< 8);
1388 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1389 request
|= (data
<< 16);
1390 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1391 request
|= (data
<< 24);
1392 target_request(target
, request
);
1400 * Cortex-A8 target information and configuration
1403 int cortex_a8_examine(struct target_s
*target
)
1405 /* get pointers to arch-specific information */
1406 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1407 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1408 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1409 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1413 int retval
= ERROR_OK
;
1414 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1418 /* Here we shall insert a proper ROM Table scan */
1419 armv7a
->debug_base
= OMAP3530_DEBUG_BASE
;
1421 /* We do one extra read to ensure DAP is configured,
1422 * we call ahbap_debugport_init(swjdp) instead
1424 ahbap_debugport_init(swjdp
);
1425 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
1426 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1427 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1429 LOG_DEBUG("Examine failed");
1433 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1434 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1436 LOG_DEBUG("Examine failed");
1440 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1441 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1443 LOG_DEBUG("Examine failed");
1447 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1448 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1450 LOG_DEBUG("Examine failed");
1454 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1455 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1456 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1457 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1459 /* Setup Breakpoint Register Pairs */
1460 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1461 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1462 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1463 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(cortex_a8_brp_t
));
1464 // cortex_a8->brb_enabled = ????;
1465 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1467 cortex_a8
->brp_list
[i
].used
= 0;
1468 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1469 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1471 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1472 cortex_a8
->brp_list
[i
].value
= 0;
1473 cortex_a8
->brp_list
[i
].control
= 0;
1474 cortex_a8
->brp_list
[i
].BRPn
= i
;
1477 /* Setup Watchpoint Register Pairs */
1478 cortex_a8
->wrp_num
= ((didr
>> 28) & 0x0F) + 1;
1479 cortex_a8
->wrp_num_available
= cortex_a8
->wrp_num
;
1480 cortex_a8
->wrp_list
= calloc(cortex_a8
->wrp_num
, sizeof(cortex_a8_wrp_t
));
1481 for (i
= 0; i
< cortex_a8
->wrp_num
; i
++)
1483 cortex_a8
->wrp_list
[i
].used
= 0;
1484 cortex_a8
->wrp_list
[i
].type
= 0;
1485 cortex_a8
->wrp_list
[i
].value
= 0;
1486 cortex_a8
->wrp_list
[i
].control
= 0;
1487 cortex_a8
->wrp_list
[i
].WRPn
= i
;
1489 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1490 cortex_a8
->brp_num
, cortex_a8
->wrp_num
);
1492 /* Configure core debug access */
1493 cortex_a8_init_debug_access(target
);
1495 target
->type
->examined
= 1;
1501 * Cortex-A8 target creation and initialization
1504 void cortex_a8_build_reg_cache(target_t
*target
)
1506 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1507 /* get pointers to arch-specific information */
1508 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1510 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
1511 armv4_5
->core_cache
= (*cache_p
);
1515 int cortex_a8_init_target(struct command_context_s
*cmd_ctx
,
1516 struct target_s
*target
)
1518 cortex_a8_build_reg_cache(target
);
1522 int cortex_a8_init_arch_info(target_t
*target
,
1523 cortex_a8_common_t
*cortex_a8
, jtag_tap_t
*tap
)
1525 armv4_5_common_t
*armv4_5
;
1526 armv7a_common_t
*armv7a
;
1528 armv7a
= &cortex_a8
->armv7a_common
;
1529 armv4_5
= &armv7a
->armv4_5_common
;
1530 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1532 /* Setup cortex_a8_common_t */
1533 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1534 cortex_a8
->arch_info
= NULL
;
1535 armv7a
->arch_info
= cortex_a8
;
1536 armv4_5
->arch_info
= armv7a
;
1538 armv4_5_init_arch_info(target
, armv4_5
);
1540 /* prepare JTAG information for the new target */
1541 cortex_a8
->jtag_info
.tap
= tap
;
1542 cortex_a8
->jtag_info
.scann_size
= 4;
1544 swjdp
->dp_select_value
= -1;
1545 swjdp
->ap_csw_value
= -1;
1546 swjdp
->ap_tar_value
= -1;
1547 swjdp
->jtag_info
= &cortex_a8
->jtag_info
;
1548 swjdp
->memaccess_tck
= 80;
1550 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1551 swjdp
->tar_autoincr_block
= (1 << 10);
1553 cortex_a8
->fast_reg_read
= 0;
1556 /* register arch-specific functions */
1557 armv7a
->examine_debug_reason
= NULL
;
1559 armv7a
->pre_debug_entry
= NULL
;
1560 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1562 armv7a
->pre_restore_context
= NULL
;
1563 armv7a
->post_restore_context
= NULL
;
1564 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1565 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1566 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_memory
;
1567 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_memory
;
1568 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1569 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1570 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1571 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1572 armv7a
->read_cp15
= cortex_a8_read_cp15
;
1573 armv7a
->write_cp15
= cortex_a8_write_cp15
;
1576 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1578 armv4_5
->read_core_reg
= cortex_a8_read_core_reg
;
1579 armv4_5
->write_core_reg
= cortex_a8_write_core_reg
;
1580 // armv4_5->full_context = arm7_9_full_context;
1582 // armv4_5->load_core_reg_u32 = cortex_a8_load_core_reg_u32;
1583 // armv4_5->store_core_reg_u32 = cortex_a8_store_core_reg_u32;
1584 // armv4_5->read_core_reg = armv4_5_read_core_reg; /* this is default */
1585 // armv4_5->write_core_reg = armv4_5_write_core_reg;
1587 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1592 int cortex_a8_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1594 cortex_a8_common_t
*cortex_a8
= calloc(1, sizeof(cortex_a8_common_t
));
1596 cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1601 static int cortex_a8_handle_cache_info_command(struct command_context_s
*cmd_ctx
,
1602 char *cmd
, char **args
, int argc
)
1604 target_t
*target
= get_current_target(cmd_ctx
);
1605 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1606 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1608 return armv4_5_handle_cache_info_command(cmd_ctx
,
1609 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1613 static int cortex_a8_handle_dbginit_command(struct command_context_s
*cmd_ctx
,
1614 char *cmd
, char **args
, int argc
)
1616 target_t
*target
= get_current_target(cmd_ctx
);
1618 cortex_a8_init_debug_access(target
);
1624 int cortex_a8_register_commands(struct command_context_s
*cmd_ctx
)
1626 command_t
*cortex_a8_cmd
;
1627 int retval
= ERROR_OK
;
1629 armv4_5_register_commands(cmd_ctx
);
1630 armv7a_register_commands(cmd_ctx
);
1632 cortex_a8_cmd
= register_command(cmd_ctx
, NULL
, "cortex_a8",
1634 "cortex_a8 specific commands");
1636 register_command(cmd_ctx
, cortex_a8_cmd
, "cache_info",
1637 cortex_a8_handle_cache_info_command
, COMMAND_EXEC
,
1638 "display information about target caches");
1640 register_command(cmd_ctx
, cortex_a8_cmd
, "dbginit",
1641 cortex_a8_handle_dbginit_command
, COMMAND_EXEC
,
1642 "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)