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
)
124 # Unlocking the debug registers for modification
125 mww
0x54011FB0 0xC5ACCE55 4
127 # Clear Sticky Power Down status Bit to enable access to
128 # the registers in the Core Power Domain
130 # Check that it is cleared
132 # Now we can read Core Debug Registers at offset 0x080
134 # We can also read RAM.
140 # Set DBGEN line for hardware debug (OMAP35xx)
141 mww
0x5401d030 0x00002000
147 mww
0x54011088 0x2000
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
)
170 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
172 mem_ap_write_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_ITR
, opcode
);
176 retval
= mem_ap_read_atomic_u32(swjdp
,
177 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
178 if (retval
!= ERROR_OK
)
181 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
186 /**************************************************************************
187 Read core register with very few exec_opcode, fast but needs work_area.
188 This can cause problems with MMU active.
189 **************************************************************************/
190 int cortex_a8_read_regs_through_mem(target_t
*target
, uint32_t address
,
193 int retval
= ERROR_OK
;
194 /* get pointers to arch-specific information */
195 armv4_5_common_t
*armv4_5
= target
->arch_info
;
196 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
197 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
199 cortex_a8_dap_read_coreregister_u32(target
, regfile
, 0);
200 cortex_a8_dap_write_coreregister_u32(target
, address
, 0);
201 cortex_a8_exec_opcode(target
, ARMV4_5_STMIA(0, 0xFFFE, 0, 0));
202 dap_ap_select(swjdp
, swjdp_memoryap
);
203 mem_ap_read_buf_u32(swjdp
, (uint8_t *)(®file
[1]), 4*15, address
);
204 dap_ap_select(swjdp
, swjdp_debugap
);
209 int cortex_a8_read_cp(target_t
*target
, uint32_t *value
, uint8_t CP
,
210 uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
213 /* get pointers to arch-specific information */
214 armv4_5_common_t
*armv4_5
= target
->arch_info
;
215 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
216 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
218 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(CP
, op1
, 0, CRn
, CRm
, op2
));
219 /* Move R0 to DTRTX */
220 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
223 retval
= mem_ap_read_atomic_u32(swjdp
,
224 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
229 int cortex_a8_write_cp(target_t
*target
, uint32_t value
,
230 uint8_t CP
, uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
233 /* get pointers to arch-specific information */
234 armv4_5_common_t
*armv4_5
= target
->arch_info
;
235 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
236 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
238 retval
= mem_ap_write_u32(swjdp
,
239 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
240 /* Move DTRRX to r0 */
241 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
243 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(CP
, op1
, 0, CRn
, CRm
, op2
));
247 int cortex_a8_read_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
248 uint32_t CRn
, uint32_t CRm
, uint32_t *value
)
250 return cortex_a8_read_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
253 int cortex_a8_write_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
254 uint32_t CRn
, uint32_t CRm
, uint32_t value
)
256 return cortex_a8_write_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
259 int cortex_a8_dap_read_coreregister_u32(target_t
*target
,
260 uint32_t *value
, int regnum
)
262 int retval
= ERROR_OK
;
263 uint8_t reg
= regnum
&0xFF;
266 /* get pointers to arch-specific information */
267 armv4_5_common_t
*armv4_5
= target
->arch_info
;
268 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
269 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
276 /* Rn to DCCTX, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
277 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, reg
, 0, 5, 0));
281 cortex_a8_exec_opcode(target
, 0xE1A0000F);
282 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
286 cortex_a8_exec_opcode(target
, ARMV4_5_MRS(0, 0));
287 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
293 retval
= mem_ap_read_atomic_u32(swjdp
,
294 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
296 while ((dscr
& (1 << DSCR_DTR_TX_FULL
)) == 0); /* Wait for DTRRXfull */
298 retval
= mem_ap_read_atomic_u32(swjdp
,
299 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
304 int cortex_a8_dap_write_coreregister_u32(target_t
*target
, uint32_t value
, int regnum
)
306 int retval
= ERROR_OK
;
307 uint8_t Rd
= regnum
&0xFF;
309 /* get pointers to arch-specific information */
310 armv4_5_common_t
*armv4_5
= target
->arch_info
;
311 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
312 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
318 retval
= mem_ap_write_u32(swjdp
,
319 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
323 /* DCCRX to Rd, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
324 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, Rd
, 0, 5, 0));
328 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
329 cortex_a8_exec_opcode(target
, 0xE1A0F000);
333 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
334 cortex_a8_exec_opcode(target
, ARMV4_5_MSR_GP(0, 0xF, 0));
335 /* Execute a PrefetchFlush instruction through the ITR. */
336 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(15, 0, 0, 7, 5, 4));
343 * Cortex-A8 Run control
346 int cortex_a8_poll(target_t
*target
)
348 int retval
= ERROR_OK
;
350 /* get pointers to arch-specific information */
351 armv4_5_common_t
*armv4_5
= target
->arch_info
;
352 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
353 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
354 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
357 enum target_state prev_target_state
= target
->state
;
359 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
360 dap_ap_select(swjdp
, swjdp_debugap
);
361 retval
= mem_ap_read_atomic_u32(swjdp
,
362 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
363 if (retval
!= ERROR_OK
)
365 dap_ap_select(swjdp
, saved_apsel
);
368 cortex_a8
->cpudbg_dscr
= dscr
;
370 if ((dscr
& 0x3) == 0x3)
372 if (prev_target_state
!= TARGET_HALTED
)
374 /* We have a halting debug event */
375 LOG_DEBUG("Target halted");
376 target
->state
= TARGET_HALTED
;
377 if ((prev_target_state
== TARGET_RUNNING
)
378 || (prev_target_state
== TARGET_RESET
))
380 retval
= cortex_a8_debug_entry(target
);
381 if (retval
!= ERROR_OK
)
384 target_call_event_callbacks(target
,
385 TARGET_EVENT_HALTED
);
387 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
391 retval
= cortex_a8_debug_entry(target
);
392 if (retval
!= ERROR_OK
)
395 target_call_event_callbacks(target
,
396 TARGET_EVENT_DEBUG_HALTED
);
400 else if ((dscr
& 0x3) == 0x2)
402 target
->state
= TARGET_RUNNING
;
406 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32
, dscr
);
407 target
->state
= TARGET_UNKNOWN
;
410 dap_ap_select(swjdp
, saved_apsel
);
415 int cortex_a8_halt(target_t
*target
)
417 int retval
= ERROR_OK
;
420 /* get pointers to arch-specific information */
421 armv4_5_common_t
*armv4_5
= target
->arch_info
;
422 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
423 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
425 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
426 dap_ap_select(swjdp
, swjdp_debugap
);
429 * Tell the core to be halted by writing DRCR with 0x1
430 * and then wait for the core to be halted.
432 retval
= mem_ap_write_atomic_u32(swjdp
,
433 armv7a
->debug_base
+ CPUDBG_DRCR
, 0x1);
436 * enter halting debug mode
438 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
439 retval
= mem_ap_write_atomic_u32(swjdp
,
440 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
| (1 << DSCR_HALT_DBG_MODE
));
442 if (retval
!= ERROR_OK
)
446 mem_ap_read_atomic_u32(swjdp
,
447 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
448 } while ((dscr
& (1 << DSCR_CORE_HALTED
)) == 0);
450 target
->debug_reason
= DBG_REASON_DBGRQ
;
453 dap_ap_select(swjdp
, saved_apsel
);
457 int cortex_a8_resume(struct target_s
*target
, int current
,
458 uint32_t address
, int handle_breakpoints
, int debug_execution
)
460 /* get pointers to arch-specific information */
461 armv4_5_common_t
*armv4_5
= target
->arch_info
;
462 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
463 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
465 // breakpoint_t *breakpoint = NULL;
466 uint32_t resume_pc
, dscr
;
468 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
469 dap_ap_select(swjdp
, swjdp_debugap
);
471 if (!debug_execution
)
473 target_free_all_working_areas(target
);
474 // cortex_m3_enable_breakpoints(target);
475 // cortex_m3_enable_watchpoints(target);
481 /* Disable interrupts */
482 /* We disable interrupts in the PRIMASK register instead of
483 * masking with C_MASKINTS,
484 * This is probably the same issue as Cortex-M3 Errata 377493:
485 * C_MASKINTS in parallel with disabled interrupts can cause
486 * local faults to not be taken. */
487 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
488 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
489 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
491 /* Make sure we are in Thumb mode */
492 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
493 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
494 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
495 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
499 /* current = 1: continue on current pc, otherwise continue at <address> */
500 resume_pc
= buf_get_u32(
501 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
502 armv4_5
->core_mode
, 15).value
,
507 /* Make sure that the Armv7 gdb thumb fixups does not
508 * kill the return address
510 if (armv7a
->core_state
== ARMV7A_STATE_ARM
)
512 resume_pc
&= 0xFFFFFFFC;
514 /* When the return address is loaded into PC
515 * bit 0 must be 1 to stay in Thumb state
517 if (armv7a
->core_state
== ARMV7A_STATE_THUMB
)
521 LOG_DEBUG("resume pc = 0x%08" PRIx32
, resume_pc
);
522 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
523 armv4_5
->core_mode
, 15).value
,
525 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
526 armv4_5
->core_mode
, 15).dirty
= 1;
527 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
528 armv4_5
->core_mode
, 15).valid
= 1;
530 cortex_a8_restore_context(target
);
531 // arm7_9_restore_context(target); TODO Context is currently NOT Properly restored
533 /* the front-end may request us not to handle breakpoints */
534 if (handle_breakpoints
)
536 /* Single step past breakpoint at current address */
537 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
539 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
540 cortex_m3_unset_breakpoint(target
, breakpoint
);
541 cortex_m3_single_step_core(target
);
542 cortex_m3_set_breakpoint(target
, breakpoint
);
547 /* Restart core and wait for it to be started */
548 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DRCR
, 0x2);
551 mem_ap_read_atomic_u32(swjdp
,
552 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
553 } while ((dscr
& (1 << DSCR_CORE_RESTARTED
)) == 0);
555 target
->debug_reason
= DBG_REASON_NOTHALTED
;
556 target
->state
= TARGET_RUNNING
;
558 /* registers are now invalid */
559 armv4_5_invalidate_core_regs(target
);
561 if (!debug_execution
)
563 target
->state
= TARGET_RUNNING
;
564 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
565 LOG_DEBUG("target resumed at 0x%" PRIx32
, resume_pc
);
569 target
->state
= TARGET_DEBUG_RUNNING
;
570 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
571 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, resume_pc
);
574 dap_ap_select(swjdp
, saved_apsel
);
579 int cortex_a8_debug_entry(target_t
*target
)
582 uint32_t regfile
[16], pc
, cpsr
, dscr
;
583 int retval
= ERROR_OK
;
584 working_area_t
*regfile_working_area
= NULL
;
586 /* get pointers to arch-specific information */
587 armv4_5_common_t
*armv4_5
= target
->arch_info
;
588 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
589 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
590 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
592 if (armv7a
->pre_debug_entry
)
593 armv7a
->pre_debug_entry(target
);
595 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
597 /* Enable the ITR execution once we are in debug mode */
598 mem_ap_read_atomic_u32(swjdp
,
599 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
600 dscr
|= (1 << DSCR_EXT_INT_EN
);
601 retval
= mem_ap_write_atomic_u32(swjdp
,
602 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
);
604 /* Examine debug reason */
605 switch ((cortex_a8
->cpudbg_dscr
>> 2)&0xF)
609 target
->debug_reason
= DBG_REASON_DBGRQ
;
613 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
616 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
619 target
->debug_reason
= DBG_REASON_UNDEFINED
;
623 /* Examine target state and mode */
624 if (cortex_a8
->fast_reg_read
)
625 target_alloc_working_area(target
, 64, ®file_working_area
);
627 /* First load register acessible through core debug port*/
628 if (!regfile_working_area
)
630 for (i
= 0; i
<= 15; i
++)
631 cortex_a8_dap_read_coreregister_u32(target
,
636 dap_ap_select(swjdp
, swjdp_memoryap
);
637 cortex_a8_read_regs_through_mem(target
,
638 regfile_working_area
->address
, regfile
);
639 dap_ap_select(swjdp
, swjdp_memoryap
);
640 target_free_working_area(target
, regfile_working_area
);
643 cortex_a8_dap_read_coreregister_u32(target
, &cpsr
, 16);
645 dap_ap_select(swjdp
, swjdp_debugap
);
646 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
648 armv4_5
->core_mode
= cpsr
& 0x1F;
649 armv7a
->core_state
= (cpsr
& 0x20)?ARMV7A_STATE_THUMB
:ARMV7A_STATE_ARM
;
651 for (i
= 0; i
<= ARM_PC
; i
++)
653 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
654 armv4_5
->core_mode
, i
).value
,
656 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
657 armv4_5
->core_mode
, i
).valid
= 1;
658 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
659 armv4_5
->core_mode
, i
).dirty
= 0;
661 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
662 armv4_5
->core_mode
, 16).value
,
664 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
665 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
667 /* Fixup PC Resume Address */
668 if (armv7a
->core_state
== ARMV7A_STATE_THUMB
)
670 // T bit set for Thumb or ThumbEE state
671 regfile
[ARM_PC
] -= 4;
676 regfile
[ARM_PC
] -= 8;
678 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
679 armv4_5
->core_mode
, ARM_PC
).value
,
680 0, 32, regfile
[ARM_PC
]);
682 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 0)
683 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
684 armv4_5
->core_mode
, 0).valid
;
685 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 15)
686 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
687 armv4_5
->core_mode
, 15).valid
;
690 /* TODO, Move this */
691 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
692 cortex_a8_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
693 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
695 cortex_a8_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
696 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
698 cortex_a8_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
699 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
702 /* Are we in an exception handler */
703 // armv4_5->exception_number = 0;
704 if (armv7a
->post_debug_entry
)
705 armv7a
->post_debug_entry(target
);
713 void cortex_a8_post_debug_entry(target_t
*target
)
715 /* get pointers to arch-specific information */
716 armv4_5_common_t
*armv4_5
= target
->arch_info
;
717 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
718 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
720 // cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
721 /* examine cp15 control reg */
722 armv7a
->read_cp15(target
, 0, 0, 1, 0, &cortex_a8
->cp15_control_reg
);
723 jtag_execute_queue();
724 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
726 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
728 uint32_t cache_type_reg
;
729 /* identify caches */
730 armv7a
->read_cp15(target
, 0, 1, 0, 0, &cache_type_reg
);
731 jtag_execute_queue();
732 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
733 armv4_5_identify_cache(cache_type_reg
,
734 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
737 armv7a
->armv4_5_mmu
.mmu_enabled
=
738 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
739 armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
=
740 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
741 armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
=
742 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
747 int cortex_a8_step(struct target_s
*target
, int current
, uint32_t address
,
748 int handle_breakpoints
)
750 /* get pointers to arch-specific information */
751 armv4_5_common_t
*armv4_5
= target
->arch_info
;
752 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
753 breakpoint_t
*breakpoint
= NULL
;
754 breakpoint_t stepbreakpoint
;
758 if (target
->state
!= TARGET_HALTED
)
760 LOG_WARNING("target not halted");
761 return ERROR_TARGET_NOT_HALTED
;
764 /* current = 1: continue on current pc, otherwise continue at <address> */
767 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
768 armv4_5
->core_mode
, ARM_PC
).value
,
773 address
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
774 armv4_5
->core_mode
, ARM_PC
).value
,
778 /* The front-end may request us not to handle breakpoints.
779 * But since Cortex-A8 uses breakpoint for single step,
780 * we MUST handle breakpoints.
782 handle_breakpoints
= 1;
783 if (handle_breakpoints
) {
784 breakpoint
= breakpoint_find(target
,
785 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
786 armv4_5
->core_mode
, 15).value
,
789 cortex_a8_unset_breakpoint(target
, breakpoint
);
792 /* Setup single step breakpoint */
793 stepbreakpoint
.address
= address
;
794 stepbreakpoint
.length
= (armv7a
->core_state
== ARMV7A_STATE_THUMB
) ? 2 : 4;
795 stepbreakpoint
.type
= BKPT_HARD
;
796 stepbreakpoint
.set
= 0;
798 /* Break on IVA mismatch */
799 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
801 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
803 cortex_a8_resume(target
, 1, address
, 0, 0);
805 while (target
->state
!= TARGET_HALTED
)
807 cortex_a8_poll(target
);
810 LOG_WARNING("timeout waiting for target halt");
815 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
816 if (timeout
> 0) target
->debug_reason
= DBG_REASON_BREAKPOINT
;
819 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
821 if (target
->state
!= TARGET_HALTED
)
822 LOG_DEBUG("target stepped");
827 int cortex_a8_restore_context(target_t
*target
)
832 /* get pointers to arch-specific information */
833 armv4_5_common_t
*armv4_5
= target
->arch_info
;
834 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
838 if (armv7a
->pre_restore_context
)
839 armv7a
->pre_restore_context(target
);
841 for (i
= 15; i
>= 0; i
--)
843 if (ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
844 armv4_5
->core_mode
, i
).dirty
)
846 value
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
847 armv4_5
->core_mode
, i
).value
,
849 /* TODO Check return values */
850 cortex_a8_dap_write_coreregister_u32(target
, value
, i
);
854 if (armv7a
->post_restore_context
)
855 armv7a
->post_restore_context(target
);
862 * Cortex-A8 Core register functions
865 int cortex_a8_load_core_reg_u32(struct target_s
*target
, int num
,
866 armv4_5_mode_t mode
, uint32_t * value
)
869 /* get pointers to arch-specific information */
870 armv4_5_common_t
*armv4_5
= target
->arch_info
;
872 if ((num
<= ARM_CPSR
))
874 /* read a normal core register */
875 retval
= cortex_a8_dap_read_coreregister_u32(target
, value
, num
);
877 if (retval
!= ERROR_OK
)
879 LOG_ERROR("JTAG failure %i", retval
);
880 return ERROR_JTAG_DEVICE_ERROR
;
882 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
, num
, *value
);
886 return ERROR_INVALID_ARGUMENTS
;
889 /* Register other than r0 - r14 uses r0 for access */
891 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
892 armv4_5
->core_mode
, 0).dirty
=
893 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
894 armv4_5
->core_mode
, 0).valid
;
895 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
896 armv4_5
->core_mode
, 15).dirty
=
897 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
898 armv4_5
->core_mode
, 15).valid
;
903 int cortex_a8_store_core_reg_u32(struct target_s
*target
, int num
,
904 armv4_5_mode_t mode
, uint32_t value
)
909 /* get pointers to arch-specific information */
910 armv4_5_common_t
*armv4_5
= target
->arch_info
;
912 #ifdef ARMV7_GDB_HACKS
913 /* If the LR register is being modified, make sure it will put us
914 * in "thumb" mode, or an INVSTATE exception will occur. This is a
915 * hack to deal with the fact that gdb will sometimes "forge"
916 * return addresses, and doesn't set the LSB correctly (i.e., when
917 * printing expressions containing function calls, it sets LR=0.) */
923 if ((num
<= ARM_CPSR
))
925 retval
= cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
926 if (retval
!= ERROR_OK
)
928 LOG_ERROR("JTAG failure %i", retval
);
929 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
930 armv4_5
->core_mode
, num
).dirty
=
931 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
932 armv4_5
->core_mode
, num
).valid
;
933 return ERROR_JTAG_DEVICE_ERROR
;
935 LOG_DEBUG("write core reg %i value 0x%" PRIx32
, num
, value
);
939 return ERROR_INVALID_ARGUMENTS
;
946 int cortex_a8_read_core_reg(struct target_s
*target
, int num
,
947 enum armv4_5_mode mode
)
951 armv4_5_common_t
*armv4_5
= target
->arch_info
;
952 cortex_a8_dap_read_coreregister_u32(target
, &value
, num
);
954 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
959 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
960 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
961 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
962 mode
, num
).value
, 0, 32, value
);
967 int cortex_a8_write_core_reg(struct target_s
*target
, int num
,
968 enum armv4_5_mode mode
, uint32_t value
)
971 armv4_5_common_t
*armv4_5
= target
->arch_info
;
973 cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
974 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
979 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
980 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
987 * Cortex-A8 Breakpoint and watchpoint fuctions
990 /* Setup hardware Breakpoint Register Pair */
991 int cortex_a8_set_breakpoint(struct target_s
*target
,
992 breakpoint_t
*breakpoint
, uint8_t matchmode
)
997 uint8_t byte_addr_select
= 0x0F;
1000 /* get pointers to arch-specific information */
1001 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1002 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1003 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1004 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
1006 if (breakpoint
->set
)
1008 LOG_WARNING("breakpoint already set");
1012 if (breakpoint
->type
== BKPT_HARD
)
1014 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
1016 if (brp_i
>= cortex_a8
->brp_num
)
1018 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1021 breakpoint
->set
= brp_i
+ 1;
1022 if (breakpoint
->length
== 2)
1024 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1026 control
= ((matchmode
& 0x7) << 20)
1027 | (byte_addr_select
<< 5)
1029 brp_list
[brp_i
].used
= 1;
1030 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1031 brp_list
[brp_i
].control
= control
;
1032 target_write_u32(target
, armv7a
->debug_base
1033 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1034 brp_list
[brp_i
].value
);
1035 target_write_u32(target
, armv7a
->debug_base
1036 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1037 brp_list
[brp_i
].control
);
1038 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1039 brp_list
[brp_i
].control
,
1040 brp_list
[brp_i
].value
);
1042 else if (breakpoint
->type
== BKPT_SOFT
)
1045 if (breakpoint
->length
== 2)
1047 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1051 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1053 retval
= target
->type
->read_memory(target
,
1054 breakpoint
->address
& 0xFFFFFFFE,
1055 breakpoint
->length
, 1,
1056 breakpoint
->orig_instr
);
1057 if (retval
!= ERROR_OK
)
1059 retval
= target
->type
->write_memory(target
,
1060 breakpoint
->address
& 0xFFFFFFFE,
1061 breakpoint
->length
, 1, code
);
1062 if (retval
!= ERROR_OK
)
1064 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1070 int cortex_a8_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
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 not set");
1085 if (breakpoint
->type
== BKPT_HARD
)
1087 int brp_i
= breakpoint
->set
- 1;
1088 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1090 LOG_DEBUG("Invalid BRP number in breakpoint");
1093 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1094 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1095 brp_list
[brp_i
].used
= 0;
1096 brp_list
[brp_i
].value
= 0;
1097 brp_list
[brp_i
].control
= 0;
1098 target_write_u32(target
, armv7a
->debug_base
1099 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1100 brp_list
[brp_i
].control
);
1101 target_write_u32(target
, armv7a
->debug_base
1102 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1103 brp_list
[brp_i
].value
);
1107 /* restore original instruction (kept in target endianness) */
1108 if (breakpoint
->length
== 4)
1110 retval
= target
->type
->write_memory(target
,
1111 breakpoint
->address
& 0xFFFFFFFE,
1112 4, 1, breakpoint
->orig_instr
);
1113 if (retval
!= ERROR_OK
)
1118 retval
= target
->type
->write_memory(target
,
1119 breakpoint
->address
& 0xFFFFFFFE,
1120 2, 1, breakpoint
->orig_instr
);
1121 if (retval
!= ERROR_OK
)
1125 breakpoint
->set
= 0;
1130 int cortex_a8_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1132 /* get pointers to arch-specific information */
1133 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1134 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1135 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1137 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1139 LOG_INFO("no hardware breakpoint available");
1140 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1143 if (breakpoint
->type
== BKPT_HARD
)
1144 cortex_a8
->brp_num_available
--;
1145 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1150 int cortex_a8_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1152 /* get pointers to arch-specific information */
1153 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1154 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1155 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1158 /* It is perfectly possible to remove brakpoints while the taget is running */
1159 if (target
->state
!= TARGET_HALTED
)
1161 LOG_WARNING("target not halted");
1162 return ERROR_TARGET_NOT_HALTED
;
1166 if (breakpoint
->set
)
1168 cortex_a8_unset_breakpoint(target
, breakpoint
);
1169 if (breakpoint
->type
== BKPT_HARD
)
1170 cortex_a8
->brp_num_available
++ ;
1180 * Cortex-A8 Reset fuctions
1185 * Cortex-A8 Memory access
1187 * This is same Cortex M3 but we must also use the correct
1188 * ap number for every access.
1191 int cortex_a8_read_memory(struct target_s
*target
, uint32_t address
,
1192 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1194 /* get pointers to arch-specific information */
1195 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1196 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1197 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1199 int retval
= ERROR_OK
;
1201 /* sanitize arguments */
1202 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1203 return ERROR_INVALID_ARGUMENTS
;
1205 /* cortex_a8 handles unaligned memory access */
1207 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1212 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1215 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1218 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1221 LOG_ERROR("BUG: we shouldn't get here");
1228 int cortex_a8_write_memory(struct target_s
*target
, uint32_t address
,
1229 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1231 /* get pointers to arch-specific information */
1232 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1233 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1234 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1238 /* sanitize arguments */
1239 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1240 return ERROR_INVALID_ARGUMENTS
;
1242 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1247 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1250 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1253 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1256 LOG_ERROR("BUG: we shouldn't get here");
1260 /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */
1261 /* invalidate I-Cache */
1262 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
1264 /* Invalidate ICache single entry with MVA, repeat this for all cache
1265 lines in the address range, Cortex-A8 has fixed 64 byte line length */
1266 /* Invalidate Cache single entry with MVA to PoU */
1267 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1268 armv7a
->write_cp15(target
, 0, 1, 7, 5, cacheline
); /* I-Cache to PoU */
1270 /* invalidate D-Cache */
1271 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
1273 /* Invalidate Cache single entry with MVA to PoC */
1274 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1275 armv7a
->write_cp15(target
, 0, 1, 7, 6, cacheline
); /* U/D cache to PoC */
1281 int cortex_a8_bulk_write_memory(target_t
*target
, uint32_t address
,
1282 uint32_t count
, uint8_t *buffer
)
1284 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1288 int cortex_a8_dcc_read(swjdp_common_t
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1293 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1294 *ctrl
= (uint8_t)dcrdr
;
1295 *value
= (uint8_t)(dcrdr
>> 8);
1297 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1299 /* write ack back to software dcc register
1300 * signify we have read data */
1301 if (dcrdr
& (1 << 0))
1304 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1311 int cortex_a8_handle_target_request(void *priv
)
1313 target_t
*target
= priv
;
1314 if (!target
->type
->examined
)
1316 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1317 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1318 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1321 if (!target
->dbg_msg_enabled
)
1324 if (target
->state
== TARGET_RUNNING
)
1329 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1331 /* check if we have data */
1332 if (ctrl
& (1 << 0))
1336 /* we assume target is quick enough */
1338 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1339 request
|= (data
<< 8);
1340 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1341 request
|= (data
<< 16);
1342 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1343 request
|= (data
<< 24);
1344 target_request(target
, request
);
1352 * Cortex-A8 target information and configuration
1355 int cortex_a8_examine(struct target_s
*target
)
1357 /* get pointers to arch-specific information */
1358 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1359 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1360 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1361 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1365 int retval
= ERROR_OK
;
1366 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1370 /* Here we shall insert a proper ROM Table scan */
1371 armv7a
->debug_base
= OMAP3530_DEBUG_BASE
;
1373 /* We do one extra read to ensure DAP is configured,
1374 * we call ahbap_debugport_init(swjdp) instead
1376 ahbap_debugport_init(swjdp
);
1377 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
1378 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1379 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1381 LOG_DEBUG("Examine failed");
1385 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1386 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1388 LOG_DEBUG("Examine failed");
1392 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1393 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1395 LOG_DEBUG("Examine failed");
1399 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1400 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1402 LOG_DEBUG("Examine failed");
1406 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1407 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1408 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1409 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1411 /* Setup Breakpoint Register Pairs */
1412 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1413 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1414 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1415 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(cortex_a8_brp_t
));
1416 // cortex_a8->brb_enabled = ????;
1417 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1419 cortex_a8
->brp_list
[i
].used
= 0;
1420 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1421 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1423 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1424 cortex_a8
->brp_list
[i
].value
= 0;
1425 cortex_a8
->brp_list
[i
].control
= 0;
1426 cortex_a8
->brp_list
[i
].BRPn
= i
;
1429 /* Setup Watchpoint Register Pairs */
1430 cortex_a8
->wrp_num
= ((didr
>> 28) & 0x0F) + 1;
1431 cortex_a8
->wrp_num_available
= cortex_a8
->wrp_num
;
1432 cortex_a8
->wrp_list
= calloc(cortex_a8
->wrp_num
, sizeof(cortex_a8_wrp_t
));
1433 for (i
= 0; i
< cortex_a8
->wrp_num
; i
++)
1435 cortex_a8
->wrp_list
[i
].used
= 0;
1436 cortex_a8
->wrp_list
[i
].type
= 0;
1437 cortex_a8
->wrp_list
[i
].value
= 0;
1438 cortex_a8
->wrp_list
[i
].control
= 0;
1439 cortex_a8
->wrp_list
[i
].WRPn
= i
;
1441 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1442 cortex_a8
->brp_num
, cortex_a8
->wrp_num
);
1444 target
->type
->examined
= 1;
1450 * Cortex-A8 target creation and initialization
1453 void cortex_a8_build_reg_cache(target_t
*target
)
1455 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1456 /* get pointers to arch-specific information */
1457 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1459 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
1460 armv4_5
->core_cache
= (*cache_p
);
1464 int cortex_a8_init_target(struct command_context_s
*cmd_ctx
,
1465 struct target_s
*target
)
1467 cortex_a8_build_reg_cache(target
);
1471 int cortex_a8_init_arch_info(target_t
*target
,
1472 cortex_a8_common_t
*cortex_a8
, jtag_tap_t
*tap
)
1474 armv4_5_common_t
*armv4_5
;
1475 armv7a_common_t
*armv7a
;
1477 armv7a
= &cortex_a8
->armv7a_common
;
1478 armv4_5
= &armv7a
->armv4_5_common
;
1479 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1481 /* Setup cortex_a8_common_t */
1482 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1483 cortex_a8
->arch_info
= NULL
;
1484 armv7a
->arch_info
= cortex_a8
;
1485 armv4_5
->arch_info
= armv7a
;
1487 armv4_5_init_arch_info(target
, armv4_5
);
1489 /* prepare JTAG information for the new target */
1490 cortex_a8
->jtag_info
.tap
= tap
;
1491 cortex_a8
->jtag_info
.scann_size
= 4;
1493 swjdp
->dp_select_value
= -1;
1494 swjdp
->ap_csw_value
= -1;
1495 swjdp
->ap_tar_value
= -1;
1496 swjdp
->jtag_info
= &cortex_a8
->jtag_info
;
1497 swjdp
->memaccess_tck
= 80;
1499 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1500 swjdp
->tar_autoincr_block
= (1 << 10);
1502 cortex_a8
->fast_reg_read
= 0;
1505 /* register arch-specific functions */
1506 armv7a
->examine_debug_reason
= NULL
;
1508 armv7a
->pre_debug_entry
= NULL
;
1509 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1511 armv7a
->pre_restore_context
= NULL
;
1512 armv7a
->post_restore_context
= NULL
;
1513 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1514 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1515 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_memory
;
1516 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_memory
;
1517 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1518 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1519 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1520 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1521 armv7a
->read_cp15
= cortex_a8_read_cp15
;
1522 armv7a
->write_cp15
= cortex_a8_write_cp15
;
1525 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1527 armv4_5
->read_core_reg
= cortex_a8_read_core_reg
;
1528 armv4_5
->write_core_reg
= cortex_a8_write_core_reg
;
1529 // armv4_5->full_context = arm7_9_full_context;
1531 // armv4_5->load_core_reg_u32 = cortex_a8_load_core_reg_u32;
1532 // armv4_5->store_core_reg_u32 = cortex_a8_store_core_reg_u32;
1533 // armv4_5->read_core_reg = armv4_5_read_core_reg; /* this is default */
1534 // armv4_5->write_core_reg = armv4_5_write_core_reg;
1536 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1541 int cortex_a8_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1543 cortex_a8_common_t
*cortex_a8
= calloc(1, sizeof(cortex_a8_common_t
));
1545 cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1550 static int cortex_a8_handle_cache_info_command(struct command_context_s
*cmd_ctx
,
1551 char *cmd
, char **args
, int argc
)
1553 target_t
*target
= get_current_target(cmd_ctx
);
1554 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1555 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1557 return armv4_5_handle_cache_info_command(cmd_ctx
,
1558 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1562 int cortex_a8_register_commands(struct command_context_s
*cmd_ctx
)
1564 command_t
*cortex_a8_cmd
;
1565 int retval
= ERROR_OK
;
1567 armv4_5_register_commands(cmd_ctx
);
1568 armv7a_register_commands(cmd_ctx
);
1570 cortex_a8_cmd
= register_command(cmd_ctx
, NULL
, "cortex_a8",
1572 "cortex_a8 specific commands");
1574 register_command(cmd_ctx
, cortex_a8_cmd
, "cache_info",
1575 cortex_a8_handle_cache_info_command
, COMMAND_EXEC
,
1576 "display information about target caches");
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)