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,
89 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
91 .read_memory
= cortex_a8_read_memory
,
92 .write_memory
= cortex_a8_write_memory
,
93 .bulk_write_memory
= cortex_a8_bulk_write_memory
,
94 .checksum_memory
= arm7_9_checksum_memory
,
95 .blank_check_memory
= arm7_9_blank_check_memory
,
97 .run_algorithm
= armv4_5_run_algorithm
,
99 .add_breakpoint
= cortex_a8_add_breakpoint
,
100 .remove_breakpoint
= cortex_a8_remove_breakpoint
,
101 .add_watchpoint
= NULL
,
102 .remove_watchpoint
= NULL
,
104 .register_commands
= cortex_a8_register_commands
,
105 .target_create
= cortex_a8_target_create
,
106 .init_target
= cortex_a8_init_target
,
107 .examine
= cortex_a8_examine
,
112 * FIXME do topology discovery using the ROM; don't
113 * assume this is an OMAP3.
115 #define swjdp_memoryap 0
116 #define swjdp_debugap 1
117 #define OMAP3530_DEBUG_BASE 0x54011000
120 * Cortex-A8 Basic debug access, very low level assumes state is saved
122 int cortex_a8_init_debug_access(target_t
*target
)
125 # Unlocking the debug registers for modification
126 mww
0x54011FB0 0xC5ACCE55 4
128 # Clear Sticky Power Down status Bit to enable access to
129 # the registers in the Core Power Domain
131 # Check that it is cleared
133 # Now we can read Core Debug Registers at offset 0x080
135 # We can also read RAM.
141 # Set DBGEN line for hardware debug (OMAP35xx)
142 mww
0x5401d030 0x00002000
148 mww
0x54011088 0x2000
154 int cortex_a8_exec_opcode(target_t
*target
, uint32_t opcode
)
158 /* get pointers to arch-specific information */
159 armv4_5_common_t
*armv4_5
= target
->arch_info
;
160 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
161 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
163 LOG_DEBUG("exec opcode 0x%08" PRIx32
, opcode
);
166 retvalue
= mem_ap_read_atomic_u32(swjdp
,
167 OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, &dscr
);
169 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
171 mem_ap_write_u32(swjdp
, OMAP3530_DEBUG_BASE
+ CPUDBG_ITR
, opcode
);
175 retvalue
= mem_ap_read_atomic_u32(swjdp
,
176 OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, &dscr
);
178 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
183 /**************************************************************************
184 Read core register with very few exec_opcode, fast but needs work_area.
185 This can cause problems with MMU active.
186 **************************************************************************/
187 int cortex_a8_read_regs_through_mem(target_t
*target
, uint32_t address
,
190 int retval
= ERROR_OK
;
191 /* get pointers to arch-specific information */
192 armv4_5_common_t
*armv4_5
= target
->arch_info
;
193 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
194 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
196 cortex_a8_dap_read_coreregister_u32(target
, regfile
, 0);
197 cortex_a8_dap_write_coreregister_u32(target
, address
, 0);
198 cortex_a8_exec_opcode(target
, ARMV4_5_STMIA(0, 0xFFFE, 0, 0));
199 dap_ap_select(swjdp
, swjdp_memoryap
);
200 mem_ap_read_buf_u32(swjdp
, (uint8_t *)(®file
[1]), 4*15, address
);
201 dap_ap_select(swjdp
, swjdp_debugap
);
206 int cortex_a8_read_cp(target_t
*target
, uint32_t *value
, uint8_t CP
,
207 uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
210 /* get pointers to arch-specific information */
211 armv4_5_common_t
*armv4_5
= target
->arch_info
;
212 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
213 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
215 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(CP
, op1
, 0, CRn
, CRm
, op2
));
216 /* Move R0 to DTRTX */
217 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
220 retval
= mem_ap_read_atomic_u32(swjdp
,
221 OMAP3530_DEBUG_BASE
+ CPUDBG_DTRTX
, value
);
226 int cortex_a8_write_cp(target_t
*target
, uint32_t value
,
227 uint8_t CP
, uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
231 /* get pointers to arch-specific information */
232 armv4_5_common_t
*armv4_5
= target
->arch_info
;
233 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
234 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
236 retval
= mem_ap_write_u32(swjdp
,
237 OMAP3530_DEBUG_BASE
+ CPUDBG_DTRRX
, value
);
238 /* Move DTRRX to r0 */
239 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
241 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(CP
, 0, 0, 0, 5, 0));
245 int cortex_a8_read_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
246 uint32_t CRn
, uint32_t CRm
, uint32_t *value
)
248 return cortex_a8_read_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
251 int cortex_a8_write_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
252 uint32_t CRn
, uint32_t CRm
, uint32_t value
)
254 return cortex_a8_write_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
257 int cortex_a8_dap_read_coreregister_u32(target_t
*target
,
258 uint32_t *value
, int regnum
)
260 int retval
= ERROR_OK
;
261 uint8_t reg
= regnum
&0xFF;
264 /* get pointers to arch-specific information */
265 armv4_5_common_t
*armv4_5
= target
->arch_info
;
266 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
267 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
274 /* Rn to DCCTX, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
275 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, reg
, 0, 5, 0));
279 cortex_a8_exec_opcode(target
, 0xE1A0000F);
280 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
284 cortex_a8_exec_opcode(target
, ARMV4_5_MRS(0, 0));
285 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
291 retval
= mem_ap_read_atomic_u32(swjdp
,
292 OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, &dscr
);
294 while ((dscr
& (1 << DSCR_DTR_TX_FULL
)) == 0); /* Wait for DTRRXfull */
296 retval
= mem_ap_read_atomic_u32(swjdp
,
297 OMAP3530_DEBUG_BASE
+ CPUDBG_DTRTX
, value
);
302 int cortex_a8_dap_write_coreregister_u32(target_t
*target
, uint32_t value
, int regnum
)
304 int retval
= ERROR_OK
;
305 uint8_t Rd
= regnum
&0xFF;
307 /* get pointers to arch-specific information */
308 armv4_5_common_t
*armv4_5
= target
->arch_info
;
309 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
310 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
316 retval
= mem_ap_write_u32(swjdp
,
317 OMAP3530_DEBUG_BASE
+ CPUDBG_DTRRX
, value
);
321 /* DCCRX to Rd, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
322 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, Rd
, 0, 5, 0));
326 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
327 cortex_a8_exec_opcode(target
, 0xE1A0F000);
331 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
332 cortex_a8_exec_opcode(target
, ARMV4_5_MSR_GP(0, 0xF, 0));
333 /* Execute a PrefetchFlush instruction through the ITR. */
334 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(15, 0, 0, 7, 5, 4));
341 * Cortex-A8 Run control
344 int cortex_a8_poll(target_t
*target
)
346 int retval
= ERROR_OK
;
348 /* get pointers to arch-specific information */
349 armv4_5_common_t
*armv4_5
= target
->arch_info
;
350 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
351 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
352 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
355 enum target_state prev_target_state
= target
->state
;
357 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
358 dap_ap_select(swjdp
, swjdp_debugap
);
359 retval
= mem_ap_read_atomic_u32(swjdp
,
360 OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, &dscr
);
361 if (retval
!= ERROR_OK
)
363 dap_ap_select(swjdp
, saved_apsel
);
366 cortex_a8
->cpudbg_dscr
= dscr
;
368 if ((dscr
& 0x3) == 0x3)
370 if (prev_target_state
!= TARGET_HALTED
)
372 /* We have a halting debug event */
373 LOG_DEBUG("Target halted");
374 target
->state
= TARGET_HALTED
;
375 if ((prev_target_state
== TARGET_RUNNING
)
376 || (prev_target_state
== TARGET_RESET
))
378 retval
= cortex_a8_debug_entry(target
);
379 if (retval
!= ERROR_OK
)
382 target_call_event_callbacks(target
,
383 TARGET_EVENT_HALTED
);
385 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
389 retval
= cortex_a8_debug_entry(target
);
390 if (retval
!= ERROR_OK
)
393 target_call_event_callbacks(target
,
394 TARGET_EVENT_DEBUG_HALTED
);
398 else if ((dscr
& 0x3) == 0x2)
400 target
->state
= TARGET_RUNNING
;
404 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32
, dscr
);
405 target
->state
= TARGET_UNKNOWN
;
408 dap_ap_select(swjdp
, saved_apsel
);
413 int cortex_a8_halt(target_t
*target
)
415 int retval
= ERROR_OK
;
418 /* get pointers to arch-specific information */
419 armv4_5_common_t
*armv4_5
= target
->arch_info
;
420 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
421 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
423 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
424 dap_ap_select(swjdp
, swjdp_debugap
);
427 * Tell the core to be halted by writing DRCR with 0x1
428 * and then wait for the core to be halted.
430 retval
= mem_ap_write_atomic_u32(swjdp
,
431 OMAP3530_DEBUG_BASE
+ CPUDBG_DRCR
, 0x1);
434 * enter halting debug mode
436 mem_ap_read_atomic_u32(swjdp
, OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, &dscr
);
437 retval
= mem_ap_write_atomic_u32(swjdp
,
438 OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, dscr
| (1 << DSCR_HALT_DBG_MODE
));
440 if (retval
!= ERROR_OK
)
444 mem_ap_read_atomic_u32(swjdp
,
445 OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, &dscr
);
446 } while ((dscr
& (1 << DSCR_CORE_HALTED
)) == 0);
448 target
->debug_reason
= DBG_REASON_DBGRQ
;
451 dap_ap_select(swjdp
, saved_apsel
);
455 int cortex_a8_resume(struct target_s
*target
, int current
,
456 uint32_t address
, int handle_breakpoints
, int debug_execution
)
458 /* get pointers to arch-specific information */
459 armv4_5_common_t
*armv4_5
= target
->arch_info
;
460 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
461 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
462 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
464 // breakpoint_t *breakpoint = NULL;
465 uint32_t resume_pc
, dscr
;
467 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
468 dap_ap_select(swjdp
, swjdp_debugap
);
470 if (!debug_execution
)
472 target_free_all_working_areas(target
);
473 // cortex_m3_enable_breakpoints(target);
474 // cortex_m3_enable_watchpoints(target);
480 /* Disable interrupts */
481 /* We disable interrupts in the PRIMASK register instead of
482 * masking with C_MASKINTS,
483 * This is probably the same issue as Cortex-M3 Errata 377493:
484 * C_MASKINTS in parallel with disabled interrupts can cause
485 * local faults to not be taken. */
486 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
487 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
488 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
490 /* Make sure we are in Thumb mode */
491 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
492 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
493 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
494 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
498 /* current = 1: continue on current pc, otherwise continue at <address> */
499 resume_pc
= buf_get_u32(
500 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
501 armv4_5
->core_mode
, 15).value
,
506 /* Make sure that the Armv7 gdb thumb fixups does not
507 * kill the return address
509 if (!(cortex_a8
->cpudbg_dscr
& (1 << 5)))
511 resume_pc
&= 0xFFFFFFFC;
513 LOG_DEBUG("resume pc = 0x%08" PRIx32
, resume_pc
);
514 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
515 armv4_5
->core_mode
, 15).value
,
517 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
518 armv4_5
->core_mode
, 15).dirty
= 1;
519 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
520 armv4_5
->core_mode
, 15).valid
= 1;
522 cortex_a8_restore_context(target
);
523 // arm7_9_restore_context(target); TODO Context is currently NOT Properly restored
525 /* the front-end may request us not to handle breakpoints */
526 if (handle_breakpoints
)
528 /* Single step past breakpoint at current address */
529 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
531 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
532 cortex_m3_unset_breakpoint(target
, breakpoint
);
533 cortex_m3_single_step_core(target
);
534 cortex_m3_set_breakpoint(target
, breakpoint
);
539 /* Restart core and wait for it to be started */
540 mem_ap_write_atomic_u32(swjdp
, OMAP3530_DEBUG_BASE
+ CPUDBG_DRCR
, 0x2);
543 mem_ap_read_atomic_u32(swjdp
,
544 OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, &dscr
);
545 } while ((dscr
& (1 << DSCR_CORE_RESTARTED
)) == 0);
547 target
->debug_reason
= DBG_REASON_NOTHALTED
;
548 target
->state
= TARGET_RUNNING
;
550 /* registers are now invalid */
551 armv4_5_invalidate_core_regs(target
);
553 if (!debug_execution
)
555 target
->state
= TARGET_RUNNING
;
556 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
557 LOG_DEBUG("target resumed at 0x%" PRIx32
, resume_pc
);
561 target
->state
= TARGET_DEBUG_RUNNING
;
562 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
563 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, resume_pc
);
566 dap_ap_select(swjdp
, saved_apsel
);
571 int cortex_a8_debug_entry(target_t
*target
)
574 uint32_t regfile
[16], pc
, cpsr
, dscr
;
575 int retval
= ERROR_OK
;
576 working_area_t
*regfile_working_area
= NULL
;
578 /* get pointers to arch-specific information */
579 armv4_5_common_t
*armv4_5
= target
->arch_info
;
580 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
581 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
582 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
584 if (armv7a
->pre_debug_entry
)
585 armv7a
->pre_debug_entry(target
);
587 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
589 /* Enable the ITR execution once we are in debug mode */
590 mem_ap_read_atomic_u32(swjdp
,
591 OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, &dscr
);
592 dscr
|= (1 << DSCR_EXT_INT_EN
);
593 retval
= mem_ap_write_atomic_u32(swjdp
,
594 OMAP3530_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
& 0x3F;
643 for (i
= 0; i
<= ARM_PC
; i
++)
645 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
646 armv4_5
->core_mode
, i
).value
,
648 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
649 armv4_5
->core_mode
, i
).valid
= 1;
650 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
651 armv4_5
->core_mode
, i
).dirty
= 0;
653 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
654 armv4_5
->core_mode
, 16).value
,
656 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
657 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
659 /* Fixup PC Resume Address */
660 /* TODO Her we should use arch->core_state */
661 if (cortex_a8
->cpudbg_dscr
& (1 << 5))
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 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
747 breakpoint_t
*breakpoint
= NULL
;
748 breakpoint_t stepbreakpoint
;
752 if (target
->state
!= TARGET_HALTED
)
754 LOG_WARNING("target not halted");
755 return ERROR_TARGET_NOT_HALTED
;
758 /* current = 1: continue on current pc, otherwise continue at <address> */
761 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
762 armv4_5
->core_mode
, ARM_PC
).value
,
767 address
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
768 armv4_5
->core_mode
, ARM_PC
).value
,
772 /* The front-end may request us not to handle breakpoints.
773 * But since Cortex-A8 uses breakpoint for single step,
774 * we MUST handle breakpoints.
776 handle_breakpoints
= 1;
777 if (handle_breakpoints
) {
778 breakpoint
= breakpoint_find(target
,
779 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
780 armv4_5
->core_mode
, 15).value
,
783 cortex_a8_unset_breakpoint(target
, breakpoint
);
786 /* Setup single step breakpoint */
787 stepbreakpoint
.address
= address
;
788 stepbreakpoint
.length
= (cortex_a8
->cpudbg_dscr
& (1 << 5)) ? 2 : 4;
789 stepbreakpoint
.type
= BKPT_HARD
;
790 stepbreakpoint
.set
= 0;
792 /* Break on IVA mismatch */
793 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
795 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
797 cortex_a8_resume(target
, 1, address
, 0, 0);
799 while (target
->state
!= TARGET_HALTED
)
801 cortex_a8_poll(target
);
804 LOG_WARNING("timeout waiting for target halt");
809 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
810 if (timeout
> 0) target
->debug_reason
= DBG_REASON_BREAKPOINT
;
813 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
815 if (target
->state
!= TARGET_HALTED
)
816 LOG_DEBUG("target stepped");
821 int cortex_a8_restore_context(target_t
*target
)
826 /* get pointers to arch-specific information */
827 armv4_5_common_t
*armv4_5
= target
->arch_info
;
828 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
832 if (armv7a
->pre_restore_context
)
833 armv7a
->pre_restore_context(target
);
835 for (i
= 15; i
>= 0; i
--)
837 if (ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
838 armv4_5
->core_mode
, i
).dirty
)
840 value
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
841 armv4_5
->core_mode
, i
).value
,
843 /* TODO Check return values */
844 cortex_a8_dap_write_coreregister_u32(target
, value
, i
);
848 if (armv7a
->post_restore_context
)
849 armv7a
->post_restore_context(target
);
856 * Cortex-A8 Core register functions
859 int cortex_a8_load_core_reg_u32(struct target_s
*target
, int num
,
860 armv4_5_mode_t mode
, uint32_t * value
)
863 /* get pointers to arch-specific information */
864 armv4_5_common_t
*armv4_5
= target
->arch_info
;
866 if ((num
<= ARM_CPSR
))
868 /* read a normal core register */
869 retval
= cortex_a8_dap_read_coreregister_u32(target
, value
, num
);
871 if (retval
!= ERROR_OK
)
873 LOG_ERROR("JTAG failure %i", retval
);
874 return ERROR_JTAG_DEVICE_ERROR
;
876 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
, num
, *value
);
880 return ERROR_INVALID_ARGUMENTS
;
883 /* Register other than r0 - r14 uses r0 for access */
885 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
886 armv4_5
->core_mode
, 0).dirty
=
887 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
888 armv4_5
->core_mode
, 0).valid
;
889 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
890 armv4_5
->core_mode
, 15).dirty
=
891 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
892 armv4_5
->core_mode
, 15).valid
;
897 int cortex_a8_store_core_reg_u32(struct target_s
*target
, int num
,
898 armv4_5_mode_t mode
, uint32_t value
)
903 /* get pointers to arch-specific information */
904 armv4_5_common_t
*armv4_5
= target
->arch_info
;
906 #ifdef ARMV7_GDB_HACKS
907 /* If the LR register is being modified, make sure it will put us
908 * in "thumb" mode, or an INVSTATE exception will occur. This is a
909 * hack to deal with the fact that gdb will sometimes "forge"
910 * return addresses, and doesn't set the LSB correctly (i.e., when
911 * printing expressions containing function calls, it sets LR=0.) */
917 if ((num
<= ARM_CPSR
))
919 retval
= cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
920 if (retval
!= ERROR_OK
)
922 LOG_ERROR("JTAG failure %i", retval
);
923 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
924 armv4_5
->core_mode
, num
).dirty
=
925 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
926 armv4_5
->core_mode
, num
).valid
;
927 return ERROR_JTAG_DEVICE_ERROR
;
929 LOG_DEBUG("write core reg %i value 0x%" PRIx32
, num
, value
);
933 return ERROR_INVALID_ARGUMENTS
;
940 int cortex_a8_read_core_reg(struct target_s
*target
, int num
,
941 enum armv4_5_mode mode
)
945 armv4_5_common_t
*armv4_5
= target
->arch_info
;
946 cortex_a8_dap_read_coreregister_u32(target
, &value
, num
);
948 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
953 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
954 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
955 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
956 mode
, num
).value
, 0, 32, value
);
961 int cortex_a8_write_core_reg(struct target_s
*target
, int num
,
962 enum armv4_5_mode mode
, uint32_t value
)
965 armv4_5_common_t
*armv4_5
= target
->arch_info
;
967 cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
968 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
973 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
974 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
981 * Cortex-A8 Breakpoint and watchpoint fuctions
984 /* Setup hardware Breakpoint Register Pair */
985 int cortex_a8_set_breakpoint(struct target_s
*target
,
986 breakpoint_t
*breakpoint
, uint8_t matchmode
)
991 uint8_t byte_addr_select
= 0x0F;
994 /* get pointers to arch-specific information */
995 armv4_5_common_t
*armv4_5
= target
->arch_info
;
996 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
997 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
998 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
1000 if (breakpoint
->set
)
1002 LOG_WARNING("breakpoint already set");
1006 if (breakpoint
->type
== BKPT_HARD
)
1008 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
1010 if (brp_i
>= cortex_a8
->brp_num
)
1012 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1015 breakpoint
->set
= brp_i
+ 1;
1016 if (breakpoint
->length
== 2)
1018 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1020 control
= ((matchmode
& 0x7) << 20)
1021 | (byte_addr_select
<< 5)
1023 brp_list
[brp_i
].used
= 1;
1024 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1025 brp_list
[brp_i
].control
= control
;
1026 target_write_u32(target
, OMAP3530_DEBUG_BASE
1027 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1028 brp_list
[brp_i
].value
);
1029 target_write_u32(target
, OMAP3530_DEBUG_BASE
1030 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1031 brp_list
[brp_i
].control
);
1032 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1033 brp_list
[brp_i
].control
,
1034 brp_list
[brp_i
].value
);
1036 else if (breakpoint
->type
== BKPT_SOFT
)
1039 if (breakpoint
->length
== 2)
1041 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1045 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1047 retval
= target
->type
->read_memory(target
,
1048 breakpoint
->address
& 0xFFFFFFFE,
1049 breakpoint
->length
, 1,
1050 breakpoint
->orig_instr
);
1051 if (retval
!= ERROR_OK
)
1053 retval
= target
->type
->write_memory(target
,
1054 breakpoint
->address
& 0xFFFFFFFE,
1055 breakpoint
->length
, 1, code
);
1056 if (retval
!= ERROR_OK
)
1058 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1064 int cortex_a8_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1067 /* get pointers to arch-specific information */
1068 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1069 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1070 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1071 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
1073 if (!breakpoint
->set
)
1075 LOG_WARNING("breakpoint not set");
1079 if (breakpoint
->type
== BKPT_HARD
)
1081 int brp_i
= breakpoint
->set
- 1;
1082 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1084 LOG_DEBUG("Invalid BRP number in breakpoint");
1087 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1088 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1089 brp_list
[brp_i
].used
= 0;
1090 brp_list
[brp_i
].value
= 0;
1091 brp_list
[brp_i
].control
= 0;
1092 target_write_u32(target
, OMAP3530_DEBUG_BASE
1093 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1094 brp_list
[brp_i
].control
);
1095 target_write_u32(target
, OMAP3530_DEBUG_BASE
1096 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1097 brp_list
[brp_i
].value
);
1101 /* restore original instruction (kept in target endianness) */
1102 if (breakpoint
->length
== 4)
1104 retval
= target
->type
->write_memory(target
,
1105 breakpoint
->address
& 0xFFFFFFFE,
1106 4, 1, breakpoint
->orig_instr
);
1107 if (retval
!= ERROR_OK
)
1112 retval
= target
->type
->write_memory(target
,
1113 breakpoint
->address
& 0xFFFFFFFE,
1114 2, 1, breakpoint
->orig_instr
);
1115 if (retval
!= ERROR_OK
)
1119 breakpoint
->set
= 0;
1124 int cortex_a8_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1126 /* get pointers to arch-specific information */
1127 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1128 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1129 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1131 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1133 LOG_INFO("no hardware breakpoint available");
1134 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1137 if (breakpoint
->type
== BKPT_HARD
)
1138 cortex_a8
->brp_num_available
--;
1139 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1144 int cortex_a8_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1146 /* get pointers to arch-specific information */
1147 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1148 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1149 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1152 /* It is perfectly possible to remove brakpoints while the taget is running */
1153 if (target
->state
!= TARGET_HALTED
)
1155 LOG_WARNING("target not halted");
1156 return ERROR_TARGET_NOT_HALTED
;
1160 if (breakpoint
->set
)
1162 cortex_a8_unset_breakpoint(target
, breakpoint
);
1163 if (breakpoint
->type
== BKPT_HARD
)
1164 cortex_a8
->brp_num_available
++ ;
1174 * Cortex-A8 Reset fuctions
1179 * Cortex-A8 Memory access
1181 * This is same Cortex M3 but we must also use the correct
1182 * ap number for every access.
1185 int cortex_a8_read_memory(struct target_s
*target
, uint32_t address
,
1186 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1188 /* get pointers to arch-specific information */
1189 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1190 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1191 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1193 int retval
= ERROR_OK
;
1195 /* sanitize arguments */
1196 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1197 return ERROR_INVALID_ARGUMENTS
;
1199 /* cortex_a8 handles unaligned memory access */
1201 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1206 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1209 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1212 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1215 LOG_ERROR("BUG: we shouldn't get here");
1222 int cortex_a8_write_memory(struct target_s
*target
, uint32_t address
,
1223 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1225 /* get pointers to arch-specific information */
1226 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1227 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1228 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1232 /* sanitize arguments */
1233 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1234 return ERROR_INVALID_ARGUMENTS
;
1236 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1241 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1244 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1247 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1250 LOG_ERROR("BUG: we shouldn't get here");
1257 int cortex_a8_bulk_write_memory(target_t
*target
, uint32_t address
,
1258 uint32_t count
, uint8_t *buffer
)
1260 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1264 int cortex_a8_dcc_read(swjdp_common_t
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1269 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1270 *ctrl
= (uint8_t)dcrdr
;
1271 *value
= (uint8_t)(dcrdr
>> 8);
1273 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1275 /* write ack back to software dcc register
1276 * signify we have read data */
1277 if (dcrdr
& (1 << 0))
1280 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1287 int cortex_a8_handle_target_request(void *priv
)
1289 target_t
*target
= priv
;
1290 if (!target
->type
->examined
)
1292 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1293 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1294 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1297 if (!target
->dbg_msg_enabled
)
1300 if (target
->state
== TARGET_RUNNING
)
1305 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1307 /* check if we have data */
1308 if (ctrl
& (1 << 0))
1312 /* we assume target is quick enough */
1314 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1315 request
|= (data
<< 8);
1316 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1317 request
|= (data
<< 16);
1318 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1319 request
|= (data
<< 24);
1320 target_request(target
, request
);
1328 * Cortex-A8 target information and configuration
1331 int cortex_a8_examine(struct target_s
*target
)
1333 /* get pointers to arch-specific information */
1334 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1335 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1336 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1337 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1341 int retval
= ERROR_OK
;
1342 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1346 /* We do one extra read to ensure DAP is configured,
1347 * we call ahbap_debugport_init(swjdp) instead
1349 ahbap_debugport_init(swjdp
);
1350 mem_ap_read_atomic_u32(swjdp
, OMAP3530_DEBUG_BASE
+ CPUDBG_CPUID
, &cpuid
);
1351 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1352 OMAP3530_DEBUG_BASE
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1354 LOG_DEBUG("Examine failed");
1358 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1359 OMAP3530_DEBUG_BASE
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1361 LOG_DEBUG("Examine failed");
1365 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1366 OMAP3530_DEBUG_BASE
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1368 LOG_DEBUG("Examine failed");
1372 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1373 OMAP3530_DEBUG_BASE
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1375 LOG_DEBUG("Examine failed");
1379 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1380 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1381 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1382 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1384 /* Setup Breakpoint Register Pairs */
1385 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1386 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1387 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1388 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(cortex_a8_brp_t
));
1389 // cortex_a8->brb_enabled = ????;
1390 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1392 cortex_a8
->brp_list
[i
].used
= 0;
1393 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1394 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1396 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1397 cortex_a8
->brp_list
[i
].value
= 0;
1398 cortex_a8
->brp_list
[i
].control
= 0;
1399 cortex_a8
->brp_list
[i
].BRPn
= i
;
1402 /* Setup Watchpoint Register Pairs */
1403 cortex_a8
->wrp_num
= ((didr
>> 28) & 0x0F) + 1;
1404 cortex_a8
->wrp_num_available
= cortex_a8
->wrp_num
;
1405 cortex_a8
->wrp_list
= calloc(cortex_a8
->wrp_num
, sizeof(cortex_a8_wrp_t
));
1406 for (i
= 0; i
< cortex_a8
->wrp_num
; i
++)
1408 cortex_a8
->wrp_list
[i
].used
= 0;
1409 cortex_a8
->wrp_list
[i
].type
= 0;
1410 cortex_a8
->wrp_list
[i
].value
= 0;
1411 cortex_a8
->wrp_list
[i
].control
= 0;
1412 cortex_a8
->wrp_list
[i
].WRPn
= i
;
1414 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1415 cortex_a8
->brp_num
, cortex_a8
->wrp_num
);
1417 target
->type
->examined
= 1;
1423 * Cortex-A8 target creation and initialization
1426 void cortex_a8_build_reg_cache(target_t
*target
)
1428 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1429 /* get pointers to arch-specific information */
1430 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1432 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
1433 armv4_5
->core_cache
= (*cache_p
);
1437 int cortex_a8_init_target(struct command_context_s
*cmd_ctx
,
1438 struct target_s
*target
)
1440 cortex_a8_build_reg_cache(target
);
1444 int cortex_a8_init_arch_info(target_t
*target
,
1445 cortex_a8_common_t
*cortex_a8
, jtag_tap_t
*tap
)
1447 armv4_5_common_t
*armv4_5
;
1448 armv7a_common_t
*armv7a
;
1450 armv7a
= &cortex_a8
->armv7a_common
;
1451 armv4_5
= &armv7a
->armv4_5_common
;
1452 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1454 /* Setup cortex_a8_common_t */
1455 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1456 cortex_a8
->arch_info
= NULL
;
1457 armv7a
->arch_info
= cortex_a8
;
1458 armv4_5
->arch_info
= armv7a
;
1460 armv4_5_init_arch_info(target
, armv4_5
);
1462 /* prepare JTAG information for the new target */
1463 cortex_a8
->jtag_info
.tap
= tap
;
1464 cortex_a8
->jtag_info
.scann_size
= 4;
1466 swjdp
->dp_select_value
= -1;
1467 swjdp
->ap_csw_value
= -1;
1468 swjdp
->ap_tar_value
= -1;
1469 swjdp
->jtag_info
= &cortex_a8
->jtag_info
;
1470 swjdp
->memaccess_tck
= 80;
1472 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1473 swjdp
->tar_autoincr_block
= (1 << 10);
1475 cortex_a8
->fast_reg_read
= 0;
1478 /* register arch-specific functions */
1479 armv7a
->examine_debug_reason
= NULL
;
1481 armv7a
->pre_debug_entry
= NULL
;
1482 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1484 armv7a
->pre_restore_context
= NULL
;
1485 armv7a
->post_restore_context
= NULL
;
1486 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1487 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1488 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_memory
;
1489 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_memory
;
1490 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1491 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1492 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1493 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1494 armv7a
->read_cp15
= cortex_a8_read_cp15
;
1495 armv7a
->write_cp15
= cortex_a8_write_cp15
;
1498 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1500 armv4_5
->read_core_reg
= cortex_a8_read_core_reg
;
1501 armv4_5
->write_core_reg
= cortex_a8_write_core_reg
;
1502 // armv4_5->full_context = arm7_9_full_context;
1504 // armv4_5->load_core_reg_u32 = cortex_a8_load_core_reg_u32;
1505 // armv4_5->store_core_reg_u32 = cortex_a8_store_core_reg_u32;
1506 // armv4_5->read_core_reg = armv4_5_read_core_reg; /* this is default */
1507 // armv4_5->write_core_reg = armv4_5_write_core_reg;
1509 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1514 int cortex_a8_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1516 cortex_a8_common_t
*cortex_a8
= calloc(1, sizeof(cortex_a8_common_t
));
1518 cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1523 static int cortex_a8_handle_cache_info_command(struct command_context_s
*cmd_ctx
,
1524 char *cmd
, char **args
, int argc
)
1526 target_t
*target
= get_current_target(cmd_ctx
);
1527 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1528 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1530 return armv4_5_handle_cache_info_command(cmd_ctx
,
1531 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1535 int cortex_a8_register_commands(struct command_context_s
*cmd_ctx
)
1537 command_t
*cortex_a8_cmd
;
1538 int retval
= ERROR_OK
;
1540 armv4_5_register_commands(cmd_ctx
);
1541 armv7a_register_commands(cmd_ctx
);
1543 cortex_a8_cmd
= register_command(cmd_ctx
, NULL
, "cortex_a8",
1545 "cortex_a8 specific commands");
1547 register_command(cmd_ctx
, cortex_a8_cmd
, "cache_info",
1548 cortex_a8_handle_cache_info_command
, COMMAND_EXEC
,
1549 "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)