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
);
164 mem_ap_write_u32(swjdp
, OMAP3530_DEBUG_BASE
+ CPUDBG_ITR
, opcode
);
167 retvalue
= mem_ap_read_atomic_u32(swjdp
,
168 OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, &dscr
);
170 while ((dscr
& (1 << 24)) == 0); /* Wait for InstrCompl bit to be set */
175 /**************************************************************************
176 Read core register with very few exec_opcode, fast but needs work_area.
177 This can cause problems with MMU active.
178 **************************************************************************/
179 int cortex_a8_read_regs_through_mem(target_t
*target
, uint32_t address
,
182 int retval
= ERROR_OK
;
183 /* get pointers to arch-specific information */
184 armv4_5_common_t
*armv4_5
= target
->arch_info
;
185 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
186 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
188 cortex_a8_dap_read_coreregister_u32(target
, regfile
, 0);
189 cortex_a8_dap_write_coreregister_u32(target
, address
, 0);
190 cortex_a8_exec_opcode(target
, ARMV4_5_STMIA(0, 0xFFFE, 0, 0));
191 dap_ap_select(swjdp
, swjdp_memoryap
);
192 mem_ap_read_buf_u32(swjdp
, (uint8_t *)(®file
[1]), 4*15, address
);
193 dap_ap_select(swjdp
, swjdp_debugap
);
198 int cortex_a8_read_cp(target_t
*target
, uint32_t *value
, uint8_t CP
,
199 uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
202 /* get pointers to arch-specific information */
203 armv4_5_common_t
*armv4_5
= target
->arch_info
;
204 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
205 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
207 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(CP
, op1
, 0, CRn
, CRm
, op2
));
208 /* Move R0 to DTRTX */
209 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
212 retval
= mem_ap_read_atomic_u32(swjdp
,
213 OMAP3530_DEBUG_BASE
+ CPUDBG_DTRTX
, value
);
218 int cortex_a8_write_cp(target_t
*target
, uint32_t value
,
219 uint8_t CP
, uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
223 /* get pointers to arch-specific information */
224 armv4_5_common_t
*armv4_5
= target
->arch_info
;
225 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
226 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
228 retval
= mem_ap_write_u32(swjdp
,
229 OMAP3530_DEBUG_BASE
+ CPUDBG_DTRRX
, value
);
230 /* Move DTRRX to r0 */
231 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
233 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(CP
, 0, 0, 0, 5, 0));
237 int cortex_a8_read_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
238 uint32_t CRn
, uint32_t CRm
, uint32_t *value
)
240 return cortex_a8_read_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
243 int cortex_a8_write_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
244 uint32_t CRn
, uint32_t CRm
, uint32_t value
)
246 return cortex_a8_write_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
249 int cortex_a8_dap_read_coreregister_u32(target_t
*target
,
250 uint32_t *value
, int regnum
)
252 int retval
= ERROR_OK
;
253 uint8_t reg
= regnum
&0xFF;
255 /* get pointers to arch-specific information */
256 armv4_5_common_t
*armv4_5
= target
->arch_info
;
257 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
258 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
260 swjdp
->trans_mode
= TRANS_MODE_COMPOSITE
;
267 /* Rn to DCCTX, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
268 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, reg
, 0, 5, 0));
272 cortex_a8_exec_opcode(target
, 0xE1A0000F);
273 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
277 cortex_a8_exec_opcode(target
, ARMV4_5_MRS(0, 0));
278 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
282 retval
= mem_ap_read_atomic_u32(swjdp
,
283 OMAP3530_DEBUG_BASE
+ CPUDBG_DTRTX
, value
);
284 // retval = mem_ap_read_u32(swjdp, OMAP3530_DEBUG_BASE + CPUDBG_DTRTX, value);
289 int cortex_a8_dap_write_coreregister_u32(target_t
*target
, uint32_t value
, int regnum
)
291 int retval
= ERROR_OK
;
292 uint8_t Rd
= regnum
&0xFF;
294 /* get pointers to arch-specific information */
295 armv4_5_common_t
*armv4_5
= target
->arch_info
;
296 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
297 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
303 retval
= mem_ap_write_u32(swjdp
,
304 OMAP3530_DEBUG_BASE
+ CPUDBG_DTRRX
, value
);
308 /* DCCRX to Rd, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
309 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, Rd
, 0, 5, 0));
313 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
314 cortex_a8_exec_opcode(target
, 0xE1A0F000);
318 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
319 cortex_a8_exec_opcode(target
, ARMV4_5_MSR_GP(0, 0xF, 0));
320 /* Execute a PrefetchFlush instruction through the ITR. */
321 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(15, 0, 0, 7, 5, 4));
328 * Cortex-A8 Run control
331 int cortex_a8_poll(target_t
*target
)
333 int retval
= ERROR_OK
;
335 /* get pointers to arch-specific information */
336 armv4_5_common_t
*armv4_5
= target
->arch_info
;
337 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
338 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
339 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
342 enum target_state prev_target_state
= target
->state
;
344 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
345 dap_ap_select(swjdp
, swjdp_debugap
);
346 retval
= mem_ap_read_atomic_u32(swjdp
,
347 OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, &dscr
);
348 if (retval
!= ERROR_OK
)
350 dap_ap_select(swjdp
, saved_apsel
);
353 cortex_a8
->cpudbg_dscr
= dscr
;
355 if ((dscr
& 0x3) == 0x3)
357 if (prev_target_state
!= TARGET_HALTED
)
359 /* We have a halting debug event */
360 LOG_DEBUG("Target halted");
361 target
->state
= TARGET_HALTED
;
362 if ((prev_target_state
== TARGET_RUNNING
)
363 || (prev_target_state
== TARGET_RESET
))
365 retval
= cortex_a8_debug_entry(target
);
366 if (retval
!= ERROR_OK
)
369 target_call_event_callbacks(target
,
370 TARGET_EVENT_HALTED
);
372 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
376 retval
= cortex_a8_debug_entry(target
);
377 if (retval
!= ERROR_OK
)
380 target_call_event_callbacks(target
,
381 TARGET_EVENT_DEBUG_HALTED
);
385 else if ((dscr
& 0x3) == 0x2)
387 target
->state
= TARGET_RUNNING
;
391 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32
, dscr
);
392 target
->state
= TARGET_UNKNOWN
;
395 dap_ap_select(swjdp
, saved_apsel
);
400 int cortex_a8_halt(target_t
*target
)
402 int retval
= ERROR_OK
;
403 /* get pointers to arch-specific information */
404 armv4_5_common_t
*armv4_5
= target
->arch_info
;
405 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
406 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
408 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
409 dap_ap_select(swjdp
, swjdp_debugap
);
411 /* Perhaps we should do a read-modify-write here */
412 retval
= mem_ap_write_atomic_u32(swjdp
,
413 OMAP3530_DEBUG_BASE
+ CPUDBG_DRCR
, 0x1);
415 target
->debug_reason
= DBG_REASON_DBGRQ
;
416 dap_ap_select(swjdp
, saved_apsel
);
421 int cortex_a8_resume(struct target_s
*target
, int current
,
422 uint32_t address
, int handle_breakpoints
, int debug_execution
)
424 /* get pointers to arch-specific information */
425 armv4_5_common_t
*armv4_5
= target
->arch_info
;
426 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
427 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
428 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
430 // breakpoint_t *breakpoint = NULL;
433 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
434 dap_ap_select(swjdp
, swjdp_debugap
);
436 if (!debug_execution
)
438 target_free_all_working_areas(target
);
439 // cortex_m3_enable_breakpoints(target);
440 // cortex_m3_enable_watchpoints(target);
446 /* Disable interrupts */
447 /* We disable interrupts in the PRIMASK register instead of
448 * masking with C_MASKINTS,
449 * This is probably the same issue as Cortex-M3 Errata 377493:
450 * C_MASKINTS in parallel with disabled interrupts can cause
451 * local faults to not be taken. */
452 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
453 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
454 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
456 /* Make sure we are in Thumb mode */
457 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
458 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
459 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
460 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
464 /* current = 1: continue on current pc, otherwise continue at <address> */
465 resume_pc
= buf_get_u32(
466 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
467 armv4_5
->core_mode
, 15).value
,
472 /* Make sure that the Armv7 gdb thumb fixups does not
473 * kill the return address
475 if (!(cortex_a8
->cpudbg_dscr
& (1 << 5)))
477 resume_pc
&= 0xFFFFFFFC;
479 LOG_DEBUG("resume pc = 0x%08" PRIx32
, resume_pc
);
480 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
481 armv4_5
->core_mode
, 15).value
,
483 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
484 armv4_5
->core_mode
, 15).dirty
= 1;
485 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
486 armv4_5
->core_mode
, 15).valid
= 1;
488 cortex_a8_restore_context(target
);
489 // arm7_9_restore_context(target); TODO Context is currently NOT Properly restored
491 /* the front-end may request us not to handle breakpoints */
492 if (handle_breakpoints
)
494 /* Single step past breakpoint at current address */
495 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
497 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
498 cortex_m3_unset_breakpoint(target
, breakpoint
);
499 cortex_m3_single_step_core(target
);
500 cortex_m3_set_breakpoint(target
, breakpoint
);
506 /* Perhaps we should do a read-modify-write here */
507 mem_ap_write_atomic_u32(swjdp
, OMAP3530_DEBUG_BASE
+ CPUDBG_DRCR
, 0x2);
509 target
->debug_reason
= DBG_REASON_NOTHALTED
;
510 target
->state
= TARGET_RUNNING
;
512 /* registers are now invalid */
513 armv4_5_invalidate_core_regs(target
);
515 if (!debug_execution
)
517 target
->state
= TARGET_RUNNING
;
518 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
519 LOG_DEBUG("target resumed at 0x%" PRIx32
, resume_pc
);
523 target
->state
= TARGET_DEBUG_RUNNING
;
524 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
525 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, resume_pc
);
528 dap_ap_select(swjdp
, saved_apsel
);
533 int cortex_a8_debug_entry(target_t
*target
)
536 uint32_t regfile
[16], pc
, cpsr
;
537 int retval
= ERROR_OK
;
538 working_area_t
*regfile_working_area
= NULL
;
540 /* get pointers to arch-specific information */
541 armv4_5_common_t
*armv4_5
= target
->arch_info
;
542 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
543 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
544 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
546 if (armv7a
->pre_debug_entry
)
547 armv7a
->pre_debug_entry(target
);
549 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
551 /* Examine debug reason */
552 switch ((cortex_a8
->cpudbg_dscr
>> 2)&0xF)
556 target
->debug_reason
= DBG_REASON_DBGRQ
;
560 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
563 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
566 target
->debug_reason
= DBG_REASON_UNDEFINED
;
570 /* Examine target state and mode */
571 dap_ap_select(swjdp
, swjdp_memoryap
);
572 if (cortex_a8
->fast_reg_read
)
573 target_alloc_working_area(target
, 64, ®file_working_area
);
575 /* First load register acessible through core debug port*/
576 if (!regfile_working_area
)
578 for (i
= 0; i
<= 15; i
++)
579 cortex_a8_dap_read_coreregister_u32(target
,
584 cortex_a8_read_regs_through_mem(target
,
585 regfile_working_area
->address
, regfile
);
586 dap_ap_select(swjdp
, swjdp_memoryap
);
587 target_free_working_area(target
, regfile_working_area
);
590 cortex_a8_dap_read_coreregister_u32(target
, &cpsr
, 16);
592 dap_ap_select(swjdp
, swjdp_debugap
);
593 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
595 armv4_5
->core_mode
= cpsr
& 0x3F;
597 for (i
= 0; i
<= ARM_PC
; i
++)
599 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
600 armv4_5
->core_mode
, i
).value
,
602 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
603 armv4_5
->core_mode
, i
).valid
= 1;
604 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
605 armv4_5
->core_mode
, i
).dirty
= 0;
607 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
608 armv4_5
->core_mode
, 16).value
,
610 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
611 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
613 /* Fixup PC Resume Address */
614 /* TODO Her we should use arch->core_state */
615 if (cortex_a8
->cpudbg_dscr
& (1 << 5))
617 // T bit set for Thumb or ThumbEE state
618 regfile
[ARM_PC
] -= 4;
623 regfile
[ARM_PC
] -= 8;
625 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
626 armv4_5
->core_mode
, ARM_PC
).value
,
627 0, 32, regfile
[ARM_PC
]);
629 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 0)
630 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
631 armv4_5
->core_mode
, 0).valid
;
632 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 15)
633 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
634 armv4_5
->core_mode
, 15).valid
;
637 /* TODO, Move this */
638 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
639 cortex_a8_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
640 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
642 cortex_a8_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
643 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
645 cortex_a8_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
646 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
649 /* Are we in an exception handler */
650 // armv4_5->exception_number = 0;
651 if (armv7a
->post_debug_entry
)
652 armv7a
->post_debug_entry(target
);
660 void cortex_a8_post_debug_entry(target_t
*target
)
662 /* get pointers to arch-specific information */
663 armv4_5_common_t
*armv4_5
= target
->arch_info
;
664 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
665 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
667 // cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
668 /* examine cp15 control reg */
669 armv7a
->read_cp15(target
, 0, 0, 1, 0, &cortex_a8
->cp15_control_reg
);
670 jtag_execute_queue();
671 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
673 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
675 uint32_t cache_type_reg
;
676 /* identify caches */
677 armv7a
->read_cp15(target
, 0, 1, 0, 0, &cache_type_reg
);
678 jtag_execute_queue();
679 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
680 armv4_5_identify_cache(cache_type_reg
,
681 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
684 armv7a
->armv4_5_mmu
.mmu_enabled
=
685 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
686 armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
=
687 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
688 armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
=
689 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
694 int cortex_a8_step(struct target_s
*target
, int current
, uint32_t address
,
695 int handle_breakpoints
)
697 /* get pointers to arch-specific information */
698 armv4_5_common_t
*armv4_5
= target
->arch_info
;
699 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
700 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
701 breakpoint_t
*breakpoint
= NULL
;
702 breakpoint_t stepbreakpoint
;
706 if (target
->state
!= TARGET_HALTED
)
708 LOG_WARNING("target not halted");
709 return ERROR_TARGET_NOT_HALTED
;
712 /* current = 1: continue on current pc, otherwise continue at <address> */
715 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
716 armv4_5
->core_mode
, ARM_PC
).value
,
721 address
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
722 armv4_5
->core_mode
, ARM_PC
).value
,
726 /* The front-end may request us not to handle breakpoints.
727 * But since Cortex-A8 uses breakpoint for single step,
728 * we MUST handle breakpoints.
730 handle_breakpoints
= 1;
731 if (handle_breakpoints
) {
732 breakpoint
= breakpoint_find(target
,
733 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
734 armv4_5
->core_mode
, 15).value
,
737 cortex_a8_unset_breakpoint(target
, breakpoint
);
740 /* Setup single step breakpoint */
741 stepbreakpoint
.address
= address
;
742 stepbreakpoint
.length
= (cortex_a8
->cpudbg_dscr
& (1 << 5)) ? 2 : 4;
743 stepbreakpoint
.type
= BKPT_HARD
;
744 stepbreakpoint
.set
= 0;
746 /* Break on IVA mismatch */
747 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
749 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
751 cortex_a8_resume(target
, 1, address
, 0, 0);
753 while (target
->state
!= TARGET_HALTED
)
755 cortex_a8_poll(target
);
758 LOG_WARNING("timeout waiting for target halt");
763 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
764 if (timeout
> 0) target
->debug_reason
= DBG_REASON_BREAKPOINT
;
767 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
769 if (target
->state
!= TARGET_HALTED
)
770 LOG_DEBUG("target stepped");
775 int cortex_a8_restore_context(target_t
*target
)
780 /* get pointers to arch-specific information */
781 armv4_5_common_t
*armv4_5
= target
->arch_info
;
782 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
786 if (armv7a
->pre_restore_context
)
787 armv7a
->pre_restore_context(target
);
789 for (i
= 15; i
>= 0; i
--)
791 if (ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
792 armv4_5
->core_mode
, i
).dirty
)
794 value
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
795 armv4_5
->core_mode
, i
).value
,
797 /* TODO Check return values */
798 cortex_a8_dap_write_coreregister_u32(target
, value
, i
);
802 if (armv7a
->post_restore_context
)
803 armv7a
->post_restore_context(target
);
810 * Cortex-A8 Core register functions
813 int cortex_a8_load_core_reg_u32(struct target_s
*target
, int num
,
814 armv4_5_mode_t mode
, uint32_t * value
)
817 /* get pointers to arch-specific information */
818 armv4_5_common_t
*armv4_5
= target
->arch_info
;
820 if ((num
<= ARM_CPSR
))
822 /* read a normal core register */
823 retval
= cortex_a8_dap_read_coreregister_u32(target
, value
, num
);
825 if (retval
!= ERROR_OK
)
827 LOG_ERROR("JTAG failure %i", retval
);
828 return ERROR_JTAG_DEVICE_ERROR
;
830 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
, num
, *value
);
834 return ERROR_INVALID_ARGUMENTS
;
837 /* Register other than r0 - r14 uses r0 for access */
839 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
840 armv4_5
->core_mode
, 0).dirty
=
841 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
842 armv4_5
->core_mode
, 0).valid
;
843 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
844 armv4_5
->core_mode
, 15).dirty
=
845 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
846 armv4_5
->core_mode
, 15).valid
;
851 int cortex_a8_store_core_reg_u32(struct target_s
*target
, int num
,
852 armv4_5_mode_t mode
, uint32_t value
)
857 /* get pointers to arch-specific information */
858 armv4_5_common_t
*armv4_5
= target
->arch_info
;
860 #ifdef ARMV7_GDB_HACKS
861 /* If the LR register is being modified, make sure it will put us
862 * in "thumb" mode, or an INVSTATE exception will occur. This is a
863 * hack to deal with the fact that gdb will sometimes "forge"
864 * return addresses, and doesn't set the LSB correctly (i.e., when
865 * printing expressions containing function calls, it sets LR=0.) */
871 if ((num
<= ARM_CPSR
))
873 retval
= cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
874 if (retval
!= ERROR_OK
)
876 LOG_ERROR("JTAG failure %i", retval
);
877 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
878 armv4_5
->core_mode
, num
).dirty
=
879 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
880 armv4_5
->core_mode
, num
).valid
;
881 return ERROR_JTAG_DEVICE_ERROR
;
883 LOG_DEBUG("write core reg %i value 0x%" PRIx32
, num
, value
);
887 return ERROR_INVALID_ARGUMENTS
;
894 int cortex_a8_read_core_reg(struct target_s
*target
, int num
,
895 enum armv4_5_mode mode
)
899 armv4_5_common_t
*armv4_5
= target
->arch_info
;
900 cortex_a8_dap_read_coreregister_u32(target
, &value
, num
);
902 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
907 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
908 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
909 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
910 mode
, num
).value
, 0, 32, value
);
915 int cortex_a8_write_core_reg(struct target_s
*target
, int num
,
916 enum armv4_5_mode mode
, uint32_t value
)
919 armv4_5_common_t
*armv4_5
= target
->arch_info
;
921 cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
922 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
927 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
928 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
935 * Cortex-A8 Breakpoint and watchpoint fuctions
938 /* Setup hardware Breakpoint Register Pair */
939 int cortex_a8_set_breakpoint(struct target_s
*target
,
940 breakpoint_t
*breakpoint
, uint8_t matchmode
)
945 uint8_t byte_addr_select
= 0x0F;
948 /* get pointers to arch-specific information */
949 armv4_5_common_t
*armv4_5
= target
->arch_info
;
950 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
951 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
952 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
956 LOG_WARNING("breakpoint already set");
960 if (breakpoint
->type
== BKPT_HARD
)
962 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
964 if (brp_i
>= cortex_a8
->brp_num
)
966 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
969 breakpoint
->set
= brp_i
+ 1;
970 if (breakpoint
->length
== 2)
972 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
974 control
= ((matchmode
& 0x7) << 20)
975 | (byte_addr_select
<< 5)
977 brp_list
[brp_i
].used
= 1;
978 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
979 brp_list
[brp_i
].control
= control
;
980 target_write_u32(target
, OMAP3530_DEBUG_BASE
981 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
982 brp_list
[brp_i
].value
);
983 target_write_u32(target
, OMAP3530_DEBUG_BASE
984 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
985 brp_list
[brp_i
].control
);
986 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
987 brp_list
[brp_i
].control
,
988 brp_list
[brp_i
].value
);
990 else if (breakpoint
->type
== BKPT_SOFT
)
993 if (breakpoint
->length
== 2)
995 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
999 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1001 retval
= target
->type
->read_memory(target
,
1002 breakpoint
->address
& 0xFFFFFFFE,
1003 breakpoint
->length
, 1,
1004 breakpoint
->orig_instr
);
1005 if (retval
!= ERROR_OK
)
1007 retval
= target
->type
->write_memory(target
,
1008 breakpoint
->address
& 0xFFFFFFFE,
1009 breakpoint
->length
, 1, code
);
1010 if (retval
!= ERROR_OK
)
1012 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1018 int cortex_a8_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
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 not set");
1033 if (breakpoint
->type
== BKPT_HARD
)
1035 int brp_i
= breakpoint
->set
- 1;
1036 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1038 LOG_DEBUG("Invalid BRP number in breakpoint");
1041 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1042 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1043 brp_list
[brp_i
].used
= 0;
1044 brp_list
[brp_i
].value
= 0;
1045 brp_list
[brp_i
].control
= 0;
1046 target_write_u32(target
, OMAP3530_DEBUG_BASE
1047 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1048 brp_list
[brp_i
].control
);
1049 target_write_u32(target
, OMAP3530_DEBUG_BASE
1050 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1051 brp_list
[brp_i
].value
);
1055 /* restore original instruction (kept in target endianness) */
1056 if (breakpoint
->length
== 4)
1058 retval
= target
->type
->write_memory(target
,
1059 breakpoint
->address
& 0xFFFFFFFE,
1060 4, 1, breakpoint
->orig_instr
);
1061 if (retval
!= ERROR_OK
)
1066 retval
= target
->type
->write_memory(target
,
1067 breakpoint
->address
& 0xFFFFFFFE,
1068 2, 1, breakpoint
->orig_instr
);
1069 if (retval
!= ERROR_OK
)
1073 breakpoint
->set
= 0;
1078 int cortex_a8_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1080 /* get pointers to arch-specific information */
1081 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1082 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1083 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1085 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1087 LOG_INFO("no hardware breakpoint available");
1088 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1091 if (breakpoint
->type
== BKPT_HARD
)
1092 cortex_a8
->brp_num_available
--;
1093 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1098 int cortex_a8_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1100 /* get pointers to arch-specific information */
1101 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1102 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1103 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1106 /* It is perfectly possible to remove brakpoints while the taget is running */
1107 if (target
->state
!= TARGET_HALTED
)
1109 LOG_WARNING("target not halted");
1110 return ERROR_TARGET_NOT_HALTED
;
1114 if (breakpoint
->set
)
1116 cortex_a8_unset_breakpoint(target
, breakpoint
);
1117 if (breakpoint
->type
== BKPT_HARD
)
1118 cortex_a8
->brp_num_available
++ ;
1128 * Cortex-A8 Reset fuctions
1133 * Cortex-A8 Memory access
1135 * This is same Cortex M3 but we must also use the correct
1136 * ap number for every access.
1139 int cortex_a8_read_memory(struct target_s
*target
, uint32_t address
,
1140 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1142 /* get pointers to arch-specific information */
1143 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1144 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1145 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1147 int retval
= ERROR_OK
;
1149 /* sanitize arguments */
1150 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1151 return ERROR_INVALID_ARGUMENTS
;
1153 /* cortex_a8 handles unaligned memory access */
1155 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1160 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1163 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1166 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1169 LOG_ERROR("BUG: we shouldn't get here");
1176 int cortex_a8_write_memory(struct target_s
*target
, uint32_t address
,
1177 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1179 /* get pointers to arch-specific information */
1180 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1181 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1182 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1186 /* sanitize arguments */
1187 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1188 return ERROR_INVALID_ARGUMENTS
;
1190 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1195 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1198 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1201 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1204 LOG_ERROR("BUG: we shouldn't get here");
1211 int cortex_a8_bulk_write_memory(target_t
*target
, uint32_t address
,
1212 uint32_t count
, uint8_t *buffer
)
1214 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1218 int cortex_a8_dcc_read(swjdp_common_t
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1223 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1224 *ctrl
= (uint8_t)dcrdr
;
1225 *value
= (uint8_t)(dcrdr
>> 8);
1227 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1229 /* write ack back to software dcc register
1230 * signify we have read data */
1231 if (dcrdr
& (1 << 0))
1234 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1241 int cortex_a8_handle_target_request(void *priv
)
1243 target_t
*target
= priv
;
1244 if (!target
->type
->examined
)
1246 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1247 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1248 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1251 if (!target
->dbg_msg_enabled
)
1254 if (target
->state
== TARGET_RUNNING
)
1259 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1261 /* check if we have data */
1262 if (ctrl
& (1 << 0))
1266 /* we assume target is quick enough */
1268 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1269 request
|= (data
<< 8);
1270 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1271 request
|= (data
<< 16);
1272 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1273 request
|= (data
<< 24);
1274 target_request(target
, request
);
1282 * Cortex-A8 target information and configuration
1285 int cortex_a8_examine(struct target_s
*target
)
1287 /* get pointers to arch-specific information */
1288 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1289 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1290 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1291 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1295 int retval
= ERROR_OK
;
1296 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1300 /* We do one extra read to ensure DAP is configured,
1301 * we call ahbap_debugport_init(swjdp) instead
1303 ahbap_debugport_init(swjdp
);
1304 mem_ap_read_atomic_u32(swjdp
, OMAP3530_DEBUG_BASE
+ CPUDBG_CPUID
, &cpuid
);
1305 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1306 OMAP3530_DEBUG_BASE
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1308 LOG_DEBUG("Examine failed");
1312 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1313 OMAP3530_DEBUG_BASE
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1315 LOG_DEBUG("Examine failed");
1319 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1320 OMAP3530_DEBUG_BASE
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1322 LOG_DEBUG("Examine failed");
1326 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1327 OMAP3530_DEBUG_BASE
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1329 LOG_DEBUG("Examine failed");
1333 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1334 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1335 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1336 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1338 /* Setup Breakpoint Register Pairs */
1339 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1340 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1341 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1342 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(cortex_a8_brp_t
));
1343 // cortex_a8->brb_enabled = ????;
1344 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1346 cortex_a8
->brp_list
[i
].used
= 0;
1347 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1348 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1350 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1351 cortex_a8
->brp_list
[i
].value
= 0;
1352 cortex_a8
->brp_list
[i
].control
= 0;
1353 cortex_a8
->brp_list
[i
].BRPn
= i
;
1356 /* Setup Watchpoint Register Pairs */
1357 cortex_a8
->wrp_num
= ((didr
>> 28) & 0x0F) + 1;
1358 cortex_a8
->wrp_num_available
= cortex_a8
->wrp_num
;
1359 cortex_a8
->wrp_list
= calloc(cortex_a8
->wrp_num
, sizeof(cortex_a8_wrp_t
));
1360 for (i
= 0; i
< cortex_a8
->wrp_num
; i
++)
1362 cortex_a8
->wrp_list
[i
].used
= 0;
1363 cortex_a8
->wrp_list
[i
].type
= 0;
1364 cortex_a8
->wrp_list
[i
].value
= 0;
1365 cortex_a8
->wrp_list
[i
].control
= 0;
1366 cortex_a8
->wrp_list
[i
].WRPn
= i
;
1368 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1369 cortex_a8
->brp_num
, cortex_a8
->wrp_num
);
1371 target
->type
->examined
= 1;
1377 * Cortex-A8 target creation and initialization
1380 void cortex_a8_build_reg_cache(target_t
*target
)
1382 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1383 /* get pointers to arch-specific information */
1384 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1386 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
1387 armv4_5
->core_cache
= (*cache_p
);
1391 int cortex_a8_init_target(struct command_context_s
*cmd_ctx
,
1392 struct target_s
*target
)
1394 cortex_a8_build_reg_cache(target
);
1398 int cortex_a8_init_arch_info(target_t
*target
,
1399 cortex_a8_common_t
*cortex_a8
, jtag_tap_t
*tap
)
1401 armv4_5_common_t
*armv4_5
;
1402 armv7a_common_t
*armv7a
;
1404 armv7a
= &cortex_a8
->armv7a_common
;
1405 armv4_5
= &armv7a
->armv4_5_common
;
1406 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1408 /* Setup cortex_a8_common_t */
1409 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1410 cortex_a8
->arch_info
= NULL
;
1411 armv7a
->arch_info
= cortex_a8
;
1412 armv4_5
->arch_info
= armv7a
;
1414 armv4_5_init_arch_info(target
, armv4_5
);
1416 /* prepare JTAG information for the new target */
1417 cortex_a8
->jtag_info
.tap
= tap
;
1418 cortex_a8
->jtag_info
.scann_size
= 4;
1420 swjdp
->dp_select_value
= -1;
1421 swjdp
->ap_csw_value
= -1;
1422 swjdp
->ap_tar_value
= -1;
1423 swjdp
->jtag_info
= &cortex_a8
->jtag_info
;
1424 swjdp
->memaccess_tck
= 80;
1426 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1427 swjdp
->tar_autoincr_block
= (1 << 10);
1429 cortex_a8
->fast_reg_read
= 0;
1432 /* register arch-specific functions */
1433 armv7a
->examine_debug_reason
= NULL
;
1435 armv7a
->pre_debug_entry
= NULL
;
1436 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1438 armv7a
->pre_restore_context
= NULL
;
1439 armv7a
->post_restore_context
= NULL
;
1440 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1441 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1442 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_memory
;
1443 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_memory
;
1444 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1445 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1446 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1447 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1448 armv7a
->read_cp15
= cortex_a8_read_cp15
;
1449 armv7a
->write_cp15
= cortex_a8_write_cp15
;
1452 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1454 armv4_5
->read_core_reg
= cortex_a8_read_core_reg
;
1455 armv4_5
->write_core_reg
= cortex_a8_write_core_reg
;
1456 // armv4_5->full_context = arm7_9_full_context;
1458 // armv4_5->load_core_reg_u32 = cortex_a8_load_core_reg_u32;
1459 // armv4_5->store_core_reg_u32 = cortex_a8_store_core_reg_u32;
1460 // armv4_5->read_core_reg = armv4_5_read_core_reg; /* this is default */
1461 // armv4_5->write_core_reg = armv4_5_write_core_reg;
1463 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1468 int cortex_a8_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1470 cortex_a8_common_t
*cortex_a8
= calloc(1, sizeof(cortex_a8_common_t
));
1472 cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1477 static int cortex_a8_handle_cache_info_command(struct command_context_s
*cmd_ctx
,
1478 char *cmd
, char **args
, int argc
)
1480 target_t
*target
= get_current_target(cmd_ctx
);
1481 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1482 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1484 return armv4_5_handle_cache_info_command(cmd_ctx
,
1485 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1489 int cortex_a8_register_commands(struct command_context_s
*cmd_ctx
)
1491 command_t
*cortex_a8_cmd
;
1492 int retval
= ERROR_OK
;
1494 armv4_5_register_commands(cmd_ctx
);
1495 armv7a_register_commands(cmd_ctx
);
1497 cortex_a8_cmd
= register_command(cmd_ctx
, NULL
, "cortex_a8",
1499 "cortex_a8 specific commands");
1501 register_command(cmd_ctx
, cortex_a8_cmd
, "cache_info",
1502 cortex_a8_handle_cache_info_command
, COMMAND_EXEC
,
1503 "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)