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 retvalue
= mem_ap_read_atomic_u32(swjdp
,
166 OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, &dscr
);
168 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
170 mem_ap_write_u32(swjdp
, OMAP3530_DEBUG_BASE
+ CPUDBG_ITR
, opcode
);
174 retvalue
= mem_ap_read_atomic_u32(swjdp
,
175 OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, &dscr
);
177 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
182 /**************************************************************************
183 Read core register with very few exec_opcode, fast but needs work_area.
184 This can cause problems with MMU active.
185 **************************************************************************/
186 int cortex_a8_read_regs_through_mem(target_t
*target
, uint32_t address
,
189 int retval
= ERROR_OK
;
190 /* get pointers to arch-specific information */
191 armv4_5_common_t
*armv4_5
= target
->arch_info
;
192 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
193 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
195 cortex_a8_dap_read_coreregister_u32(target
, regfile
, 0);
196 cortex_a8_dap_write_coreregister_u32(target
, address
, 0);
197 cortex_a8_exec_opcode(target
, ARMV4_5_STMIA(0, 0xFFFE, 0, 0));
198 dap_ap_select(swjdp
, swjdp_memoryap
);
199 mem_ap_read_buf_u32(swjdp
, (uint8_t *)(®file
[1]), 4*15, address
);
200 dap_ap_select(swjdp
, swjdp_debugap
);
205 int cortex_a8_read_cp(target_t
*target
, uint32_t *value
, uint8_t CP
,
206 uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
209 /* get pointers to arch-specific information */
210 armv4_5_common_t
*armv4_5
= target
->arch_info
;
211 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
212 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
214 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(CP
, op1
, 0, CRn
, CRm
, op2
));
215 /* Move R0 to DTRTX */
216 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
219 retval
= mem_ap_read_atomic_u32(swjdp
,
220 OMAP3530_DEBUG_BASE
+ CPUDBG_DTRTX
, value
);
225 int cortex_a8_write_cp(target_t
*target
, uint32_t value
,
226 uint8_t CP
, uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
229 /* get pointers to arch-specific information */
230 armv4_5_common_t
*armv4_5
= target
->arch_info
;
231 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
232 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
234 retval
= mem_ap_write_u32(swjdp
,
235 OMAP3530_DEBUG_BASE
+ CPUDBG_DTRRX
, value
);
236 /* Move DTRRX to r0 */
237 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
239 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(CP
, op1
, 0, CRn
, CRm
, op2
));
243 int cortex_a8_read_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
244 uint32_t CRn
, uint32_t CRm
, uint32_t *value
)
246 return cortex_a8_read_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
249 int cortex_a8_write_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
250 uint32_t CRn
, uint32_t CRm
, uint32_t value
)
252 return cortex_a8_write_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
255 int cortex_a8_dap_read_coreregister_u32(target_t
*target
,
256 uint32_t *value
, int regnum
)
258 int retval
= ERROR_OK
;
259 uint8_t reg
= regnum
&0xFF;
262 /* get pointers to arch-specific information */
263 armv4_5_common_t
*armv4_5
= target
->arch_info
;
264 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
265 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
272 /* Rn to DCCTX, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
273 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, reg
, 0, 5, 0));
277 cortex_a8_exec_opcode(target
, 0xE1A0000F);
278 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
282 cortex_a8_exec_opcode(target
, ARMV4_5_MRS(0, 0));
283 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
289 retval
= mem_ap_read_atomic_u32(swjdp
,
290 OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, &dscr
);
292 while ((dscr
& (1 << DSCR_DTR_TX_FULL
)) == 0); /* Wait for DTRRXfull */
294 retval
= mem_ap_read_atomic_u32(swjdp
,
295 OMAP3530_DEBUG_BASE
+ CPUDBG_DTRTX
, value
);
300 int cortex_a8_dap_write_coreregister_u32(target_t
*target
, uint32_t value
, int regnum
)
302 int retval
= ERROR_OK
;
303 uint8_t Rd
= regnum
&0xFF;
305 /* get pointers to arch-specific information */
306 armv4_5_common_t
*armv4_5
= target
->arch_info
;
307 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
308 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
314 retval
= mem_ap_write_u32(swjdp
,
315 OMAP3530_DEBUG_BASE
+ CPUDBG_DTRRX
, value
);
319 /* DCCRX to Rd, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
320 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, Rd
, 0, 5, 0));
324 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
325 cortex_a8_exec_opcode(target
, 0xE1A0F000);
329 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
330 cortex_a8_exec_opcode(target
, ARMV4_5_MSR_GP(0, 0xF, 0));
331 /* Execute a PrefetchFlush instruction through the ITR. */
332 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(15, 0, 0, 7, 5, 4));
339 * Cortex-A8 Run control
342 int cortex_a8_poll(target_t
*target
)
344 int retval
= ERROR_OK
;
346 /* get pointers to arch-specific information */
347 armv4_5_common_t
*armv4_5
= target
->arch_info
;
348 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
349 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
350 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
353 enum target_state prev_target_state
= target
->state
;
355 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
356 dap_ap_select(swjdp
, swjdp_debugap
);
357 retval
= mem_ap_read_atomic_u32(swjdp
,
358 OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, &dscr
);
359 if (retval
!= ERROR_OK
)
361 dap_ap_select(swjdp
, saved_apsel
);
364 cortex_a8
->cpudbg_dscr
= dscr
;
366 if ((dscr
& 0x3) == 0x3)
368 if (prev_target_state
!= TARGET_HALTED
)
370 /* We have a halting debug event */
371 LOG_DEBUG("Target halted");
372 target
->state
= TARGET_HALTED
;
373 if ((prev_target_state
== TARGET_RUNNING
)
374 || (prev_target_state
== TARGET_RESET
))
376 retval
= cortex_a8_debug_entry(target
);
377 if (retval
!= ERROR_OK
)
380 target_call_event_callbacks(target
,
381 TARGET_EVENT_HALTED
);
383 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
387 retval
= cortex_a8_debug_entry(target
);
388 if (retval
!= ERROR_OK
)
391 target_call_event_callbacks(target
,
392 TARGET_EVENT_DEBUG_HALTED
);
396 else if ((dscr
& 0x3) == 0x2)
398 target
->state
= TARGET_RUNNING
;
402 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32
, dscr
);
403 target
->state
= TARGET_UNKNOWN
;
406 dap_ap_select(swjdp
, saved_apsel
);
411 int cortex_a8_halt(target_t
*target
)
413 int retval
= ERROR_OK
;
416 /* get pointers to arch-specific information */
417 armv4_5_common_t
*armv4_5
= target
->arch_info
;
418 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
419 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
421 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
422 dap_ap_select(swjdp
, swjdp_debugap
);
425 * Tell the core to be halted by writing DRCR with 0x1
426 * and then wait for the core to be halted.
428 retval
= mem_ap_write_atomic_u32(swjdp
,
429 OMAP3530_DEBUG_BASE
+ CPUDBG_DRCR
, 0x1);
432 * enter halting debug mode
434 mem_ap_read_atomic_u32(swjdp
, OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, &dscr
);
435 retval
= mem_ap_write_atomic_u32(swjdp
,
436 OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, dscr
| (1 << DSCR_HALT_DBG_MODE
));
438 if (retval
!= ERROR_OK
)
442 mem_ap_read_atomic_u32(swjdp
,
443 OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, &dscr
);
444 } while ((dscr
& (1 << DSCR_CORE_HALTED
)) == 0);
446 target
->debug_reason
= DBG_REASON_DBGRQ
;
449 dap_ap_select(swjdp
, saved_apsel
);
453 int cortex_a8_resume(struct target_s
*target
, int current
,
454 uint32_t address
, int handle_breakpoints
, int debug_execution
)
456 /* get pointers to arch-specific information */
457 armv4_5_common_t
*armv4_5
= target
->arch_info
;
458 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
459 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
461 // breakpoint_t *breakpoint = NULL;
462 uint32_t resume_pc
, dscr
;
464 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
465 dap_ap_select(swjdp
, swjdp_debugap
);
467 if (!debug_execution
)
469 target_free_all_working_areas(target
);
470 // cortex_m3_enable_breakpoints(target);
471 // cortex_m3_enable_watchpoints(target);
477 /* Disable interrupts */
478 /* We disable interrupts in the PRIMASK register instead of
479 * masking with C_MASKINTS,
480 * This is probably the same issue as Cortex-M3 Errata 377493:
481 * C_MASKINTS in parallel with disabled interrupts can cause
482 * local faults to not be taken. */
483 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
484 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
485 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
487 /* Make sure we are in Thumb mode */
488 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
489 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
490 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
491 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
495 /* current = 1: continue on current pc, otherwise continue at <address> */
496 resume_pc
= buf_get_u32(
497 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
498 armv4_5
->core_mode
, 15).value
,
503 /* Make sure that the Armv7 gdb thumb fixups does not
504 * kill the return address
506 if (armv7a
->core_state
== ARMV7A_STATE_ARM
)
508 resume_pc
&= 0xFFFFFFFC;
510 /* When the return address is loaded into PC
511 * bit 0 must be 1 to stay in Thumb state
513 if (armv7a
->core_state
== ARMV7A_STATE_THUMB
)
517 LOG_DEBUG("resume pc = 0x%08" PRIx32
, resume_pc
);
518 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
519 armv4_5
->core_mode
, 15).value
,
521 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
522 armv4_5
->core_mode
, 15).dirty
= 1;
523 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
524 armv4_5
->core_mode
, 15).valid
= 1;
526 cortex_a8_restore_context(target
);
527 // arm7_9_restore_context(target); TODO Context is currently NOT Properly restored
529 /* the front-end may request us not to handle breakpoints */
530 if (handle_breakpoints
)
532 /* Single step past breakpoint at current address */
533 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
535 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
536 cortex_m3_unset_breakpoint(target
, breakpoint
);
537 cortex_m3_single_step_core(target
);
538 cortex_m3_set_breakpoint(target
, breakpoint
);
543 /* Restart core and wait for it to be started */
544 mem_ap_write_atomic_u32(swjdp
, OMAP3530_DEBUG_BASE
+ CPUDBG_DRCR
, 0x2);
547 mem_ap_read_atomic_u32(swjdp
,
548 OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, &dscr
);
549 } while ((dscr
& (1 << DSCR_CORE_RESTARTED
)) == 0);
551 target
->debug_reason
= DBG_REASON_NOTHALTED
;
552 target
->state
= TARGET_RUNNING
;
554 /* registers are now invalid */
555 armv4_5_invalidate_core_regs(target
);
557 if (!debug_execution
)
559 target
->state
= TARGET_RUNNING
;
560 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
561 LOG_DEBUG("target resumed at 0x%" PRIx32
, resume_pc
);
565 target
->state
= TARGET_DEBUG_RUNNING
;
566 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
567 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, resume_pc
);
570 dap_ap_select(swjdp
, saved_apsel
);
575 int cortex_a8_debug_entry(target_t
*target
)
578 uint32_t regfile
[16], pc
, cpsr
, dscr
;
579 int retval
= ERROR_OK
;
580 working_area_t
*regfile_working_area
= NULL
;
582 /* get pointers to arch-specific information */
583 armv4_5_common_t
*armv4_5
= target
->arch_info
;
584 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
585 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
586 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
588 if (armv7a
->pre_debug_entry
)
589 armv7a
->pre_debug_entry(target
);
591 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
593 /* Enable the ITR execution once we are in debug mode */
594 mem_ap_read_atomic_u32(swjdp
,
595 OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, &dscr
);
596 dscr
|= (1 << DSCR_EXT_INT_EN
);
597 retval
= mem_ap_write_atomic_u32(swjdp
,
598 OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, dscr
);
600 /* Examine debug reason */
601 switch ((cortex_a8
->cpudbg_dscr
>> 2)&0xF)
605 target
->debug_reason
= DBG_REASON_DBGRQ
;
609 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
612 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
615 target
->debug_reason
= DBG_REASON_UNDEFINED
;
619 /* Examine target state and mode */
620 if (cortex_a8
->fast_reg_read
)
621 target_alloc_working_area(target
, 64, ®file_working_area
);
623 /* First load register acessible through core debug port*/
624 if (!regfile_working_area
)
626 for (i
= 0; i
<= 15; i
++)
627 cortex_a8_dap_read_coreregister_u32(target
,
632 dap_ap_select(swjdp
, swjdp_memoryap
);
633 cortex_a8_read_regs_through_mem(target
,
634 regfile_working_area
->address
, regfile
);
635 dap_ap_select(swjdp
, swjdp_memoryap
);
636 target_free_working_area(target
, regfile_working_area
);
639 cortex_a8_dap_read_coreregister_u32(target
, &cpsr
, 16);
641 dap_ap_select(swjdp
, swjdp_debugap
);
642 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
644 armv4_5
->core_mode
= cpsr
& 0x1F;
645 armv7a
->core_state
= (cpsr
& 0x20)?ARMV7A_STATE_THUMB
:ARMV7A_STATE_ARM
;
647 for (i
= 0; i
<= ARM_PC
; i
++)
649 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
650 armv4_5
->core_mode
, i
).value
,
652 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
653 armv4_5
->core_mode
, i
).valid
= 1;
654 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
655 armv4_5
->core_mode
, i
).dirty
= 0;
657 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
658 armv4_5
->core_mode
, 16).value
,
660 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
661 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
663 /* Fixup PC Resume Address */
664 if (armv7a
->core_state
== ARMV7A_STATE_THUMB
)
666 // T bit set for Thumb or ThumbEE state
667 regfile
[ARM_PC
] -= 4;
672 regfile
[ARM_PC
] -= 8;
674 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
675 armv4_5
->core_mode
, ARM_PC
).value
,
676 0, 32, regfile
[ARM_PC
]);
678 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 0)
679 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
680 armv4_5
->core_mode
, 0).valid
;
681 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 15)
682 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
683 armv4_5
->core_mode
, 15).valid
;
686 /* TODO, Move this */
687 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
688 cortex_a8_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
689 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
691 cortex_a8_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
692 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
694 cortex_a8_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
695 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
698 /* Are we in an exception handler */
699 // armv4_5->exception_number = 0;
700 if (armv7a
->post_debug_entry
)
701 armv7a
->post_debug_entry(target
);
709 void cortex_a8_post_debug_entry(target_t
*target
)
711 /* get pointers to arch-specific information */
712 armv4_5_common_t
*armv4_5
= target
->arch_info
;
713 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
714 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
716 // cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
717 /* examine cp15 control reg */
718 armv7a
->read_cp15(target
, 0, 0, 1, 0, &cortex_a8
->cp15_control_reg
);
719 jtag_execute_queue();
720 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
722 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
724 uint32_t cache_type_reg
;
725 /* identify caches */
726 armv7a
->read_cp15(target
, 0, 1, 0, 0, &cache_type_reg
);
727 jtag_execute_queue();
728 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
729 armv4_5_identify_cache(cache_type_reg
,
730 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
733 armv7a
->armv4_5_mmu
.mmu_enabled
=
734 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
735 armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
=
736 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
737 armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
=
738 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
743 int cortex_a8_step(struct target_s
*target
, int current
, uint32_t address
,
744 int handle_breakpoints
)
746 /* get pointers to arch-specific information */
747 armv4_5_common_t
*armv4_5
= target
->arch_info
;
748 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
749 breakpoint_t
*breakpoint
= NULL
;
750 breakpoint_t stepbreakpoint
;
754 if (target
->state
!= TARGET_HALTED
)
756 LOG_WARNING("target not halted");
757 return ERROR_TARGET_NOT_HALTED
;
760 /* current = 1: continue on current pc, otherwise continue at <address> */
763 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
764 armv4_5
->core_mode
, ARM_PC
).value
,
769 address
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
770 armv4_5
->core_mode
, ARM_PC
).value
,
774 /* The front-end may request us not to handle breakpoints.
775 * But since Cortex-A8 uses breakpoint for single step,
776 * we MUST handle breakpoints.
778 handle_breakpoints
= 1;
779 if (handle_breakpoints
) {
780 breakpoint
= breakpoint_find(target
,
781 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
782 armv4_5
->core_mode
, 15).value
,
785 cortex_a8_unset_breakpoint(target
, breakpoint
);
788 /* Setup single step breakpoint */
789 stepbreakpoint
.address
= address
;
790 stepbreakpoint
.length
= (armv7a
->core_state
== ARMV7A_STATE_THUMB
) ? 2 : 4;
791 stepbreakpoint
.type
= BKPT_HARD
;
792 stepbreakpoint
.set
= 0;
794 /* Break on IVA mismatch */
795 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
797 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
799 cortex_a8_resume(target
, 1, address
, 0, 0);
801 while (target
->state
!= TARGET_HALTED
)
803 cortex_a8_poll(target
);
806 LOG_WARNING("timeout waiting for target halt");
811 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
812 if (timeout
> 0) target
->debug_reason
= DBG_REASON_BREAKPOINT
;
815 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
817 if (target
->state
!= TARGET_HALTED
)
818 LOG_DEBUG("target stepped");
823 int cortex_a8_restore_context(target_t
*target
)
828 /* get pointers to arch-specific information */
829 armv4_5_common_t
*armv4_5
= target
->arch_info
;
830 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
834 if (armv7a
->pre_restore_context
)
835 armv7a
->pre_restore_context(target
);
837 for (i
= 15; i
>= 0; i
--)
839 if (ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
840 armv4_5
->core_mode
, i
).dirty
)
842 value
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
843 armv4_5
->core_mode
, i
).value
,
845 /* TODO Check return values */
846 cortex_a8_dap_write_coreregister_u32(target
, value
, i
);
850 if (armv7a
->post_restore_context
)
851 armv7a
->post_restore_context(target
);
858 * Cortex-A8 Core register functions
861 int cortex_a8_load_core_reg_u32(struct target_s
*target
, int num
,
862 armv4_5_mode_t mode
, uint32_t * value
)
865 /* get pointers to arch-specific information */
866 armv4_5_common_t
*armv4_5
= target
->arch_info
;
868 if ((num
<= ARM_CPSR
))
870 /* read a normal core register */
871 retval
= cortex_a8_dap_read_coreregister_u32(target
, value
, num
);
873 if (retval
!= ERROR_OK
)
875 LOG_ERROR("JTAG failure %i", retval
);
876 return ERROR_JTAG_DEVICE_ERROR
;
878 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
, num
, *value
);
882 return ERROR_INVALID_ARGUMENTS
;
885 /* Register other than r0 - r14 uses r0 for access */
887 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
888 armv4_5
->core_mode
, 0).dirty
=
889 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
890 armv4_5
->core_mode
, 0).valid
;
891 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
892 armv4_5
->core_mode
, 15).dirty
=
893 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
894 armv4_5
->core_mode
, 15).valid
;
899 int cortex_a8_store_core_reg_u32(struct target_s
*target
, int num
,
900 armv4_5_mode_t mode
, uint32_t value
)
905 /* get pointers to arch-specific information */
906 armv4_5_common_t
*armv4_5
= target
->arch_info
;
908 #ifdef ARMV7_GDB_HACKS
909 /* If the LR register is being modified, make sure it will put us
910 * in "thumb" mode, or an INVSTATE exception will occur. This is a
911 * hack to deal with the fact that gdb will sometimes "forge"
912 * return addresses, and doesn't set the LSB correctly (i.e., when
913 * printing expressions containing function calls, it sets LR=0.) */
919 if ((num
<= ARM_CPSR
))
921 retval
= cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
922 if (retval
!= ERROR_OK
)
924 LOG_ERROR("JTAG failure %i", retval
);
925 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
926 armv4_5
->core_mode
, num
).dirty
=
927 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
928 armv4_5
->core_mode
, num
).valid
;
929 return ERROR_JTAG_DEVICE_ERROR
;
931 LOG_DEBUG("write core reg %i value 0x%" PRIx32
, num
, value
);
935 return ERROR_INVALID_ARGUMENTS
;
942 int cortex_a8_read_core_reg(struct target_s
*target
, int num
,
943 enum armv4_5_mode mode
)
947 armv4_5_common_t
*armv4_5
= target
->arch_info
;
948 cortex_a8_dap_read_coreregister_u32(target
, &value
, num
);
950 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
955 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
956 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
957 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
958 mode
, num
).value
, 0, 32, value
);
963 int cortex_a8_write_core_reg(struct target_s
*target
, int num
,
964 enum armv4_5_mode mode
, uint32_t value
)
967 armv4_5_common_t
*armv4_5
= target
->arch_info
;
969 cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
970 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
975 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
976 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
983 * Cortex-A8 Breakpoint and watchpoint fuctions
986 /* Setup hardware Breakpoint Register Pair */
987 int cortex_a8_set_breakpoint(struct target_s
*target
,
988 breakpoint_t
*breakpoint
, uint8_t matchmode
)
993 uint8_t byte_addr_select
= 0x0F;
996 /* get pointers to arch-specific information */
997 armv4_5_common_t
*armv4_5
= target
->arch_info
;
998 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
999 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1000 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
1002 if (breakpoint
->set
)
1004 LOG_WARNING("breakpoint already set");
1008 if (breakpoint
->type
== BKPT_HARD
)
1010 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
1012 if (brp_i
>= cortex_a8
->brp_num
)
1014 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1017 breakpoint
->set
= brp_i
+ 1;
1018 if (breakpoint
->length
== 2)
1020 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1022 control
= ((matchmode
& 0x7) << 20)
1023 | (byte_addr_select
<< 5)
1025 brp_list
[brp_i
].used
= 1;
1026 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1027 brp_list
[brp_i
].control
= control
;
1028 target_write_u32(target
, OMAP3530_DEBUG_BASE
1029 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1030 brp_list
[brp_i
].value
);
1031 target_write_u32(target
, OMAP3530_DEBUG_BASE
1032 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1033 brp_list
[brp_i
].control
);
1034 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1035 brp_list
[brp_i
].control
,
1036 brp_list
[brp_i
].value
);
1038 else if (breakpoint
->type
== BKPT_SOFT
)
1041 if (breakpoint
->length
== 2)
1043 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1047 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1049 retval
= target
->type
->read_memory(target
,
1050 breakpoint
->address
& 0xFFFFFFFE,
1051 breakpoint
->length
, 1,
1052 breakpoint
->orig_instr
);
1053 if (retval
!= ERROR_OK
)
1055 retval
= target
->type
->write_memory(target
,
1056 breakpoint
->address
& 0xFFFFFFFE,
1057 breakpoint
->length
, 1, code
);
1058 if (retval
!= ERROR_OK
)
1060 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1066 int cortex_a8_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1069 /* get pointers to arch-specific information */
1070 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1071 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1072 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1073 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
1075 if (!breakpoint
->set
)
1077 LOG_WARNING("breakpoint not set");
1081 if (breakpoint
->type
== BKPT_HARD
)
1083 int brp_i
= breakpoint
->set
- 1;
1084 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1086 LOG_DEBUG("Invalid BRP number in breakpoint");
1089 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1090 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1091 brp_list
[brp_i
].used
= 0;
1092 brp_list
[brp_i
].value
= 0;
1093 brp_list
[brp_i
].control
= 0;
1094 target_write_u32(target
, OMAP3530_DEBUG_BASE
1095 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1096 brp_list
[brp_i
].control
);
1097 target_write_u32(target
, OMAP3530_DEBUG_BASE
1098 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1099 brp_list
[brp_i
].value
);
1103 /* restore original instruction (kept in target endianness) */
1104 if (breakpoint
->length
== 4)
1106 retval
= target
->type
->write_memory(target
,
1107 breakpoint
->address
& 0xFFFFFFFE,
1108 4, 1, breakpoint
->orig_instr
);
1109 if (retval
!= ERROR_OK
)
1114 retval
= target
->type
->write_memory(target
,
1115 breakpoint
->address
& 0xFFFFFFFE,
1116 2, 1, breakpoint
->orig_instr
);
1117 if (retval
!= ERROR_OK
)
1121 breakpoint
->set
= 0;
1126 int cortex_a8_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1128 /* get pointers to arch-specific information */
1129 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1130 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1131 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1133 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1135 LOG_INFO("no hardware breakpoint available");
1136 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1139 if (breakpoint
->type
== BKPT_HARD
)
1140 cortex_a8
->brp_num_available
--;
1141 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1146 int cortex_a8_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1148 /* get pointers to arch-specific information */
1149 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1150 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1151 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1154 /* It is perfectly possible to remove brakpoints while the taget is running */
1155 if (target
->state
!= TARGET_HALTED
)
1157 LOG_WARNING("target not halted");
1158 return ERROR_TARGET_NOT_HALTED
;
1162 if (breakpoint
->set
)
1164 cortex_a8_unset_breakpoint(target
, breakpoint
);
1165 if (breakpoint
->type
== BKPT_HARD
)
1166 cortex_a8
->brp_num_available
++ ;
1176 * Cortex-A8 Reset fuctions
1181 * Cortex-A8 Memory access
1183 * This is same Cortex M3 but we must also use the correct
1184 * ap number for every access.
1187 int cortex_a8_read_memory(struct target_s
*target
, uint32_t address
,
1188 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1190 /* get pointers to arch-specific information */
1191 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1192 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1193 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1195 int retval
= ERROR_OK
;
1197 /* sanitize arguments */
1198 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1199 return ERROR_INVALID_ARGUMENTS
;
1201 /* cortex_a8 handles unaligned memory access */
1203 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1208 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1211 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1214 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1217 LOG_ERROR("BUG: we shouldn't get here");
1224 int cortex_a8_write_memory(struct target_s
*target
, uint32_t address
,
1225 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1227 /* get pointers to arch-specific information */
1228 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1229 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1230 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1234 /* sanitize arguments */
1235 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1236 return ERROR_INVALID_ARGUMENTS
;
1238 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1243 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1246 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1249 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1252 LOG_ERROR("BUG: we shouldn't get here");
1256 /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */
1257 /* invalidate I-Cache */
1258 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
1260 /* Invalidate ICache single entry with MVA, repeat this for all cache
1261 lines in the address range, Cortex-A8 has fixed 64 byte line length */
1262 /* Invalidate Cache single entry with MVA to PoU */
1263 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1264 armv7a
->write_cp15(target
, 0, 1, 7, 5, cacheline
); /* I-Cache to PoU */
1266 /* invalidate D-Cache */
1267 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
1269 /* Invalidate Cache single entry with MVA to PoC */
1270 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1271 armv7a
->write_cp15(target
, 0, 1, 7, 6, cacheline
); /* U/D cache to PoC */
1277 int cortex_a8_bulk_write_memory(target_t
*target
, uint32_t address
,
1278 uint32_t count
, uint8_t *buffer
)
1280 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1284 int cortex_a8_dcc_read(swjdp_common_t
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1289 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1290 *ctrl
= (uint8_t)dcrdr
;
1291 *value
= (uint8_t)(dcrdr
>> 8);
1293 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1295 /* write ack back to software dcc register
1296 * signify we have read data */
1297 if (dcrdr
& (1 << 0))
1300 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1307 int cortex_a8_handle_target_request(void *priv
)
1309 target_t
*target
= priv
;
1310 if (!target
->type
->examined
)
1312 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1313 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1314 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1317 if (!target
->dbg_msg_enabled
)
1320 if (target
->state
== TARGET_RUNNING
)
1325 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1327 /* check if we have data */
1328 if (ctrl
& (1 << 0))
1332 /* we assume target is quick enough */
1334 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1335 request
|= (data
<< 8);
1336 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1337 request
|= (data
<< 16);
1338 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1339 request
|= (data
<< 24);
1340 target_request(target
, request
);
1348 * Cortex-A8 target information and configuration
1351 int cortex_a8_examine(struct target_s
*target
)
1353 /* get pointers to arch-specific information */
1354 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1355 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1356 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1357 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1361 int retval
= ERROR_OK
;
1362 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1366 /* We do one extra read to ensure DAP is configured,
1367 * we call ahbap_debugport_init(swjdp) instead
1369 ahbap_debugport_init(swjdp
);
1370 mem_ap_read_atomic_u32(swjdp
, OMAP3530_DEBUG_BASE
+ CPUDBG_CPUID
, &cpuid
);
1371 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1372 OMAP3530_DEBUG_BASE
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1374 LOG_DEBUG("Examine failed");
1378 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1379 OMAP3530_DEBUG_BASE
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1381 LOG_DEBUG("Examine failed");
1385 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1386 OMAP3530_DEBUG_BASE
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1388 LOG_DEBUG("Examine failed");
1392 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1393 OMAP3530_DEBUG_BASE
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1395 LOG_DEBUG("Examine failed");
1399 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1400 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1401 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1402 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1404 /* Setup Breakpoint Register Pairs */
1405 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1406 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1407 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1408 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(cortex_a8_brp_t
));
1409 // cortex_a8->brb_enabled = ????;
1410 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1412 cortex_a8
->brp_list
[i
].used
= 0;
1413 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1414 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1416 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1417 cortex_a8
->brp_list
[i
].value
= 0;
1418 cortex_a8
->brp_list
[i
].control
= 0;
1419 cortex_a8
->brp_list
[i
].BRPn
= i
;
1422 /* Setup Watchpoint Register Pairs */
1423 cortex_a8
->wrp_num
= ((didr
>> 28) & 0x0F) + 1;
1424 cortex_a8
->wrp_num_available
= cortex_a8
->wrp_num
;
1425 cortex_a8
->wrp_list
= calloc(cortex_a8
->wrp_num
, sizeof(cortex_a8_wrp_t
));
1426 for (i
= 0; i
< cortex_a8
->wrp_num
; i
++)
1428 cortex_a8
->wrp_list
[i
].used
= 0;
1429 cortex_a8
->wrp_list
[i
].type
= 0;
1430 cortex_a8
->wrp_list
[i
].value
= 0;
1431 cortex_a8
->wrp_list
[i
].control
= 0;
1432 cortex_a8
->wrp_list
[i
].WRPn
= i
;
1434 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1435 cortex_a8
->brp_num
, cortex_a8
->wrp_num
);
1437 target
->type
->examined
= 1;
1443 * Cortex-A8 target creation and initialization
1446 void cortex_a8_build_reg_cache(target_t
*target
)
1448 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1449 /* get pointers to arch-specific information */
1450 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1452 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
1453 armv4_5
->core_cache
= (*cache_p
);
1457 int cortex_a8_init_target(struct command_context_s
*cmd_ctx
,
1458 struct target_s
*target
)
1460 cortex_a8_build_reg_cache(target
);
1464 int cortex_a8_init_arch_info(target_t
*target
,
1465 cortex_a8_common_t
*cortex_a8
, jtag_tap_t
*tap
)
1467 armv4_5_common_t
*armv4_5
;
1468 armv7a_common_t
*armv7a
;
1470 armv7a
= &cortex_a8
->armv7a_common
;
1471 armv4_5
= &armv7a
->armv4_5_common
;
1472 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1474 /* Setup cortex_a8_common_t */
1475 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1476 cortex_a8
->arch_info
= NULL
;
1477 armv7a
->arch_info
= cortex_a8
;
1478 armv4_5
->arch_info
= armv7a
;
1480 armv4_5_init_arch_info(target
, armv4_5
);
1482 /* prepare JTAG information for the new target */
1483 cortex_a8
->jtag_info
.tap
= tap
;
1484 cortex_a8
->jtag_info
.scann_size
= 4;
1486 swjdp
->dp_select_value
= -1;
1487 swjdp
->ap_csw_value
= -1;
1488 swjdp
->ap_tar_value
= -1;
1489 swjdp
->jtag_info
= &cortex_a8
->jtag_info
;
1490 swjdp
->memaccess_tck
= 80;
1492 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1493 swjdp
->tar_autoincr_block
= (1 << 10);
1495 cortex_a8
->fast_reg_read
= 0;
1498 /* register arch-specific functions */
1499 armv7a
->examine_debug_reason
= NULL
;
1501 armv7a
->pre_debug_entry
= NULL
;
1502 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1504 armv7a
->pre_restore_context
= NULL
;
1505 armv7a
->post_restore_context
= NULL
;
1506 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1507 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1508 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_memory
;
1509 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_memory
;
1510 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1511 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1512 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1513 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1514 armv7a
->read_cp15
= cortex_a8_read_cp15
;
1515 armv7a
->write_cp15
= cortex_a8_write_cp15
;
1518 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1520 armv4_5
->read_core_reg
= cortex_a8_read_core_reg
;
1521 armv4_5
->write_core_reg
= cortex_a8_write_core_reg
;
1522 // armv4_5->full_context = arm7_9_full_context;
1524 // armv4_5->load_core_reg_u32 = cortex_a8_load_core_reg_u32;
1525 // armv4_5->store_core_reg_u32 = cortex_a8_store_core_reg_u32;
1526 // armv4_5->read_core_reg = armv4_5_read_core_reg; /* this is default */
1527 // armv4_5->write_core_reg = armv4_5_write_core_reg;
1529 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1534 int cortex_a8_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1536 cortex_a8_common_t
*cortex_a8
= calloc(1, sizeof(cortex_a8_common_t
));
1538 cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1543 static int cortex_a8_handle_cache_info_command(struct command_context_s
*cmd_ctx
,
1544 char *cmd
, char **args
, int argc
)
1546 target_t
*target
= get_current_target(cmd_ctx
);
1547 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1548 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1550 return armv4_5_handle_cache_info_command(cmd_ctx
,
1551 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1555 int cortex_a8_register_commands(struct command_context_s
*cmd_ctx
)
1557 command_t
*cortex_a8_cmd
;
1558 int retval
= ERROR_OK
;
1560 armv4_5_register_commands(cmd_ctx
);
1561 armv7a_register_commands(cmd_ctx
);
1563 cortex_a8_cmd
= register_command(cmd_ctx
, NULL
, "cortex_a8",
1565 "cortex_a8 specific commands");
1567 register_command(cmd_ctx
, cortex_a8_cmd
, "cache_info",
1568 cortex_a8_handle_cache_info_command
, COMMAND_EXEC
,
1569 "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)