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 << 24)) == 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 << 24)) == 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 << 29)) == 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);
433 if (retval
!= ERROR_OK
)
437 mem_ap_read_atomic_u32(swjdp
,
438 OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, &dscr
);
439 } while ((dscr
& (1 << 0)) == 0);
441 target
->debug_reason
= DBG_REASON_DBGRQ
;
444 dap_ap_select(swjdp
, saved_apsel
);
448 int cortex_a8_resume(struct target_s
*target
, int current
,
449 uint32_t address
, int handle_breakpoints
, int debug_execution
)
451 /* get pointers to arch-specific information */
452 armv4_5_common_t
*armv4_5
= target
->arch_info
;
453 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
454 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
455 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
457 // breakpoint_t *breakpoint = NULL;
458 uint32_t resume_pc
, dscr
;
460 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
461 dap_ap_select(swjdp
, swjdp_debugap
);
463 if (!debug_execution
)
465 target_free_all_working_areas(target
);
466 // cortex_m3_enable_breakpoints(target);
467 // cortex_m3_enable_watchpoints(target);
473 /* Disable interrupts */
474 /* We disable interrupts in the PRIMASK register instead of
475 * masking with C_MASKINTS,
476 * This is probably the same issue as Cortex-M3 Errata 377493:
477 * C_MASKINTS in parallel with disabled interrupts can cause
478 * local faults to not be taken. */
479 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
480 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
481 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
483 /* Make sure we are in Thumb mode */
484 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
485 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
486 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
487 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
491 /* current = 1: continue on current pc, otherwise continue at <address> */
492 resume_pc
= buf_get_u32(
493 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
494 armv4_5
->core_mode
, 15).value
,
499 /* Make sure that the Armv7 gdb thumb fixups does not
500 * kill the return address
502 if (!(cortex_a8
->cpudbg_dscr
& (1 << 5)))
504 resume_pc
&= 0xFFFFFFFC;
506 LOG_DEBUG("resume pc = 0x%08" PRIx32
, resume_pc
);
507 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
508 armv4_5
->core_mode
, 15).value
,
510 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
511 armv4_5
->core_mode
, 15).dirty
= 1;
512 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
513 armv4_5
->core_mode
, 15).valid
= 1;
515 cortex_a8_restore_context(target
);
516 // arm7_9_restore_context(target); TODO Context is currently NOT Properly restored
518 /* the front-end may request us not to handle breakpoints */
519 if (handle_breakpoints
)
521 /* Single step past breakpoint at current address */
522 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
524 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
525 cortex_m3_unset_breakpoint(target
, breakpoint
);
526 cortex_m3_single_step_core(target
);
527 cortex_m3_set_breakpoint(target
, breakpoint
);
532 /* Restart core and wait for it to be started */
533 mem_ap_write_atomic_u32(swjdp
, OMAP3530_DEBUG_BASE
+ CPUDBG_DRCR
, 0x2);
536 mem_ap_read_atomic_u32(swjdp
,
537 OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, &dscr
);
538 } while ((dscr
& (1 << 1)) == 0);
540 target
->debug_reason
= DBG_REASON_NOTHALTED
;
541 target
->state
= TARGET_RUNNING
;
543 /* registers are now invalid */
544 armv4_5_invalidate_core_regs(target
);
546 if (!debug_execution
)
548 target
->state
= TARGET_RUNNING
;
549 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
550 LOG_DEBUG("target resumed at 0x%" PRIx32
, resume_pc
);
554 target
->state
= TARGET_DEBUG_RUNNING
;
555 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
556 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, resume_pc
);
559 dap_ap_select(swjdp
, saved_apsel
);
564 int cortex_a8_debug_entry(target_t
*target
)
567 uint32_t regfile
[16], pc
, cpsr
, dscr
;
568 int retval
= ERROR_OK
;
569 working_area_t
*regfile_working_area
= NULL
;
571 /* get pointers to arch-specific information */
572 armv4_5_common_t
*armv4_5
= target
->arch_info
;
573 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
574 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
575 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
577 if (armv7a
->pre_debug_entry
)
578 armv7a
->pre_debug_entry(target
);
580 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
582 /* Enable the ITR execution once we are in debug mode */
583 mem_ap_read_atomic_u32(swjdp
,
584 OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, &dscr
);
586 retval
= mem_ap_write_atomic_u32(swjdp
,
587 OMAP3530_DEBUG_BASE
+ CPUDBG_DSCR
, dscr
);
590 /* Examine debug reason */
591 switch ((cortex_a8
->cpudbg_dscr
>> 2)&0xF)
595 target
->debug_reason
= DBG_REASON_DBGRQ
;
599 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
602 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
605 target
->debug_reason
= DBG_REASON_UNDEFINED
;
609 /* Examine target state and mode */
610 if (cortex_a8
->fast_reg_read
)
611 target_alloc_working_area(target
, 64, ®file_working_area
);
613 /* First load register acessible through core debug port*/
614 if (!regfile_working_area
)
616 for (i
= 0; i
<= 15; i
++)
617 cortex_a8_dap_read_coreregister_u32(target
,
622 dap_ap_select(swjdp
, swjdp_memoryap
);
623 cortex_a8_read_regs_through_mem(target
,
624 regfile_working_area
->address
, regfile
);
625 dap_ap_select(swjdp
, swjdp_memoryap
);
626 target_free_working_area(target
, regfile_working_area
);
629 cortex_a8_dap_read_coreregister_u32(target
, &cpsr
, 16);
631 dap_ap_select(swjdp
, swjdp_debugap
);
632 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
634 armv4_5
->core_mode
= cpsr
& 0x3F;
636 for (i
= 0; i
<= ARM_PC
; i
++)
638 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
639 armv4_5
->core_mode
, i
).value
,
641 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
642 armv4_5
->core_mode
, i
).valid
= 1;
643 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
644 armv4_5
->core_mode
, i
).dirty
= 0;
646 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
647 armv4_5
->core_mode
, 16).value
,
649 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
650 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
652 /* Fixup PC Resume Address */
653 /* TODO Her we should use arch->core_state */
654 if (cortex_a8
->cpudbg_dscr
& (1 << 5))
656 // T bit set for Thumb or ThumbEE state
657 regfile
[ARM_PC
] -= 4;
662 regfile
[ARM_PC
] -= 8;
664 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
665 armv4_5
->core_mode
, ARM_PC
).value
,
666 0, 32, regfile
[ARM_PC
]);
668 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 0)
669 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
670 armv4_5
->core_mode
, 0).valid
;
671 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 15)
672 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
673 armv4_5
->core_mode
, 15).valid
;
676 /* TODO, Move this */
677 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
678 cortex_a8_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
679 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
681 cortex_a8_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
682 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
684 cortex_a8_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
685 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
688 /* Are we in an exception handler */
689 // armv4_5->exception_number = 0;
690 if (armv7a
->post_debug_entry
)
691 armv7a
->post_debug_entry(target
);
699 void cortex_a8_post_debug_entry(target_t
*target
)
701 /* get pointers to arch-specific information */
702 armv4_5_common_t
*armv4_5
= target
->arch_info
;
703 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
704 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
706 // cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
707 /* examine cp15 control reg */
708 armv7a
->read_cp15(target
, 0, 0, 1, 0, &cortex_a8
->cp15_control_reg
);
709 jtag_execute_queue();
710 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
712 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
714 uint32_t cache_type_reg
;
715 /* identify caches */
716 armv7a
->read_cp15(target
, 0, 1, 0, 0, &cache_type_reg
);
717 jtag_execute_queue();
718 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
719 armv4_5_identify_cache(cache_type_reg
,
720 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
723 armv7a
->armv4_5_mmu
.mmu_enabled
=
724 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
725 armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
=
726 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
727 armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
=
728 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
733 int cortex_a8_step(struct target_s
*target
, int current
, uint32_t address
,
734 int handle_breakpoints
)
736 /* get pointers to arch-specific information */
737 armv4_5_common_t
*armv4_5
= target
->arch_info
;
738 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
739 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
740 breakpoint_t
*breakpoint
= NULL
;
741 breakpoint_t stepbreakpoint
;
745 if (target
->state
!= TARGET_HALTED
)
747 LOG_WARNING("target not halted");
748 return ERROR_TARGET_NOT_HALTED
;
751 /* current = 1: continue on current pc, otherwise continue at <address> */
754 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
755 armv4_5
->core_mode
, ARM_PC
).value
,
760 address
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
761 armv4_5
->core_mode
, ARM_PC
).value
,
765 /* The front-end may request us not to handle breakpoints.
766 * But since Cortex-A8 uses breakpoint for single step,
767 * we MUST handle breakpoints.
769 handle_breakpoints
= 1;
770 if (handle_breakpoints
) {
771 breakpoint
= breakpoint_find(target
,
772 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
773 armv4_5
->core_mode
, 15).value
,
776 cortex_a8_unset_breakpoint(target
, breakpoint
);
779 /* Setup single step breakpoint */
780 stepbreakpoint
.address
= address
;
781 stepbreakpoint
.length
= (cortex_a8
->cpudbg_dscr
& (1 << 5)) ? 2 : 4;
782 stepbreakpoint
.type
= BKPT_HARD
;
783 stepbreakpoint
.set
= 0;
785 /* Break on IVA mismatch */
786 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
788 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
790 cortex_a8_resume(target
, 1, address
, 0, 0);
792 while (target
->state
!= TARGET_HALTED
)
794 cortex_a8_poll(target
);
797 LOG_WARNING("timeout waiting for target halt");
802 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
803 if (timeout
> 0) target
->debug_reason
= DBG_REASON_BREAKPOINT
;
806 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
808 if (target
->state
!= TARGET_HALTED
)
809 LOG_DEBUG("target stepped");
814 int cortex_a8_restore_context(target_t
*target
)
819 /* get pointers to arch-specific information */
820 armv4_5_common_t
*armv4_5
= target
->arch_info
;
821 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
825 if (armv7a
->pre_restore_context
)
826 armv7a
->pre_restore_context(target
);
828 for (i
= 15; i
>= 0; i
--)
830 if (ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
831 armv4_5
->core_mode
, i
).dirty
)
833 value
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
834 armv4_5
->core_mode
, i
).value
,
836 /* TODO Check return values */
837 cortex_a8_dap_write_coreregister_u32(target
, value
, i
);
841 if (armv7a
->post_restore_context
)
842 armv7a
->post_restore_context(target
);
849 * Cortex-A8 Core register functions
852 int cortex_a8_load_core_reg_u32(struct target_s
*target
, int num
,
853 armv4_5_mode_t mode
, uint32_t * value
)
856 /* get pointers to arch-specific information */
857 armv4_5_common_t
*armv4_5
= target
->arch_info
;
859 if ((num
<= ARM_CPSR
))
861 /* read a normal core register */
862 retval
= cortex_a8_dap_read_coreregister_u32(target
, value
, num
);
864 if (retval
!= ERROR_OK
)
866 LOG_ERROR("JTAG failure %i", retval
);
867 return ERROR_JTAG_DEVICE_ERROR
;
869 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
, num
, *value
);
873 return ERROR_INVALID_ARGUMENTS
;
876 /* Register other than r0 - r14 uses r0 for access */
878 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
879 armv4_5
->core_mode
, 0).dirty
=
880 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
881 armv4_5
->core_mode
, 0).valid
;
882 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
883 armv4_5
->core_mode
, 15).dirty
=
884 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
885 armv4_5
->core_mode
, 15).valid
;
890 int cortex_a8_store_core_reg_u32(struct target_s
*target
, int num
,
891 armv4_5_mode_t mode
, uint32_t value
)
896 /* get pointers to arch-specific information */
897 armv4_5_common_t
*armv4_5
= target
->arch_info
;
899 #ifdef ARMV7_GDB_HACKS
900 /* If the LR register is being modified, make sure it will put us
901 * in "thumb" mode, or an INVSTATE exception will occur. This is a
902 * hack to deal with the fact that gdb will sometimes "forge"
903 * return addresses, and doesn't set the LSB correctly (i.e., when
904 * printing expressions containing function calls, it sets LR=0.) */
910 if ((num
<= ARM_CPSR
))
912 retval
= cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
913 if (retval
!= ERROR_OK
)
915 LOG_ERROR("JTAG failure %i", retval
);
916 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
917 armv4_5
->core_mode
, num
).dirty
=
918 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
919 armv4_5
->core_mode
, num
).valid
;
920 return ERROR_JTAG_DEVICE_ERROR
;
922 LOG_DEBUG("write core reg %i value 0x%" PRIx32
, num
, value
);
926 return ERROR_INVALID_ARGUMENTS
;
933 int cortex_a8_read_core_reg(struct target_s
*target
, int num
,
934 enum armv4_5_mode mode
)
938 armv4_5_common_t
*armv4_5
= target
->arch_info
;
939 cortex_a8_dap_read_coreregister_u32(target
, &value
, num
);
941 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
946 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
947 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
948 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
949 mode
, num
).value
, 0, 32, value
);
954 int cortex_a8_write_core_reg(struct target_s
*target
, int num
,
955 enum armv4_5_mode mode
, uint32_t value
)
958 armv4_5_common_t
*armv4_5
= target
->arch_info
;
960 cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
961 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
966 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
967 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
974 * Cortex-A8 Breakpoint and watchpoint fuctions
977 /* Setup hardware Breakpoint Register Pair */
978 int cortex_a8_set_breakpoint(struct target_s
*target
,
979 breakpoint_t
*breakpoint
, uint8_t matchmode
)
984 uint8_t byte_addr_select
= 0x0F;
987 /* get pointers to arch-specific information */
988 armv4_5_common_t
*armv4_5
= target
->arch_info
;
989 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
990 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
991 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
995 LOG_WARNING("breakpoint already set");
999 if (breakpoint
->type
== BKPT_HARD
)
1001 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
1003 if (brp_i
>= cortex_a8
->brp_num
)
1005 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1008 breakpoint
->set
= brp_i
+ 1;
1009 if (breakpoint
->length
== 2)
1011 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1013 control
= ((matchmode
& 0x7) << 20)
1014 | (byte_addr_select
<< 5)
1016 brp_list
[brp_i
].used
= 1;
1017 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1018 brp_list
[brp_i
].control
= control
;
1019 target_write_u32(target
, OMAP3530_DEBUG_BASE
1020 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1021 brp_list
[brp_i
].value
);
1022 target_write_u32(target
, OMAP3530_DEBUG_BASE
1023 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1024 brp_list
[brp_i
].control
);
1025 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1026 brp_list
[brp_i
].control
,
1027 brp_list
[brp_i
].value
);
1029 else if (breakpoint
->type
== BKPT_SOFT
)
1032 if (breakpoint
->length
== 2)
1034 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1038 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1040 retval
= target
->type
->read_memory(target
,
1041 breakpoint
->address
& 0xFFFFFFFE,
1042 breakpoint
->length
, 1,
1043 breakpoint
->orig_instr
);
1044 if (retval
!= ERROR_OK
)
1046 retval
= target
->type
->write_memory(target
,
1047 breakpoint
->address
& 0xFFFFFFFE,
1048 breakpoint
->length
, 1, code
);
1049 if (retval
!= ERROR_OK
)
1051 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1057 int cortex_a8_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1060 /* get pointers to arch-specific information */
1061 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1062 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1063 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1064 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
1066 if (!breakpoint
->set
)
1068 LOG_WARNING("breakpoint not set");
1072 if (breakpoint
->type
== BKPT_HARD
)
1074 int brp_i
= breakpoint
->set
- 1;
1075 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1077 LOG_DEBUG("Invalid BRP number in breakpoint");
1080 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1081 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1082 brp_list
[brp_i
].used
= 0;
1083 brp_list
[brp_i
].value
= 0;
1084 brp_list
[brp_i
].control
= 0;
1085 target_write_u32(target
, OMAP3530_DEBUG_BASE
1086 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1087 brp_list
[brp_i
].control
);
1088 target_write_u32(target
, OMAP3530_DEBUG_BASE
1089 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1090 brp_list
[brp_i
].value
);
1094 /* restore original instruction (kept in target endianness) */
1095 if (breakpoint
->length
== 4)
1097 retval
= target
->type
->write_memory(target
,
1098 breakpoint
->address
& 0xFFFFFFFE,
1099 4, 1, breakpoint
->orig_instr
);
1100 if (retval
!= ERROR_OK
)
1105 retval
= target
->type
->write_memory(target
,
1106 breakpoint
->address
& 0xFFFFFFFE,
1107 2, 1, breakpoint
->orig_instr
);
1108 if (retval
!= ERROR_OK
)
1112 breakpoint
->set
= 0;
1117 int cortex_a8_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1119 /* get pointers to arch-specific information */
1120 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1121 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1122 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1124 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1126 LOG_INFO("no hardware breakpoint available");
1127 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1130 if (breakpoint
->type
== BKPT_HARD
)
1131 cortex_a8
->brp_num_available
--;
1132 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1137 int cortex_a8_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1139 /* get pointers to arch-specific information */
1140 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1141 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1142 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1145 /* It is perfectly possible to remove brakpoints while the taget is running */
1146 if (target
->state
!= TARGET_HALTED
)
1148 LOG_WARNING("target not halted");
1149 return ERROR_TARGET_NOT_HALTED
;
1153 if (breakpoint
->set
)
1155 cortex_a8_unset_breakpoint(target
, breakpoint
);
1156 if (breakpoint
->type
== BKPT_HARD
)
1157 cortex_a8
->brp_num_available
++ ;
1167 * Cortex-A8 Reset fuctions
1172 * Cortex-A8 Memory access
1174 * This is same Cortex M3 but we must also use the correct
1175 * ap number for every access.
1178 int cortex_a8_read_memory(struct target_s
*target
, uint32_t address
,
1179 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1181 /* get pointers to arch-specific information */
1182 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1183 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1184 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1186 int retval
= ERROR_OK
;
1188 /* sanitize arguments */
1189 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1190 return ERROR_INVALID_ARGUMENTS
;
1192 /* cortex_a8 handles unaligned memory access */
1194 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1199 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1202 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1205 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1208 LOG_ERROR("BUG: we shouldn't get here");
1215 int cortex_a8_write_memory(struct target_s
*target
, uint32_t address
,
1216 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1218 /* get pointers to arch-specific information */
1219 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1220 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1221 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1225 /* sanitize arguments */
1226 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1227 return ERROR_INVALID_ARGUMENTS
;
1229 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1234 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1237 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1240 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1243 LOG_ERROR("BUG: we shouldn't get here");
1250 int cortex_a8_bulk_write_memory(target_t
*target
, uint32_t address
,
1251 uint32_t count
, uint8_t *buffer
)
1253 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1257 int cortex_a8_dcc_read(swjdp_common_t
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1262 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1263 *ctrl
= (uint8_t)dcrdr
;
1264 *value
= (uint8_t)(dcrdr
>> 8);
1266 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1268 /* write ack back to software dcc register
1269 * signify we have read data */
1270 if (dcrdr
& (1 << 0))
1273 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1280 int cortex_a8_handle_target_request(void *priv
)
1282 target_t
*target
= priv
;
1283 if (!target
->type
->examined
)
1285 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1286 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1287 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1290 if (!target
->dbg_msg_enabled
)
1293 if (target
->state
== TARGET_RUNNING
)
1298 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1300 /* check if we have data */
1301 if (ctrl
& (1 << 0))
1305 /* we assume target is quick enough */
1307 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1308 request
|= (data
<< 8);
1309 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1310 request
|= (data
<< 16);
1311 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1312 request
|= (data
<< 24);
1313 target_request(target
, request
);
1321 * Cortex-A8 target information and configuration
1324 int cortex_a8_examine(struct target_s
*target
)
1326 /* get pointers to arch-specific information */
1327 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1328 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1329 cortex_a8_common_t
*cortex_a8
= armv7a
->arch_info
;
1330 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1334 int retval
= ERROR_OK
;
1335 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1339 /* We do one extra read to ensure DAP is configured,
1340 * we call ahbap_debugport_init(swjdp) instead
1342 ahbap_debugport_init(swjdp
);
1343 mem_ap_read_atomic_u32(swjdp
, OMAP3530_DEBUG_BASE
+ CPUDBG_CPUID
, &cpuid
);
1344 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1345 OMAP3530_DEBUG_BASE
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1347 LOG_DEBUG("Examine failed");
1351 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1352 OMAP3530_DEBUG_BASE
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1354 LOG_DEBUG("Examine failed");
1358 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1359 OMAP3530_DEBUG_BASE
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1361 LOG_DEBUG("Examine failed");
1365 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1366 OMAP3530_DEBUG_BASE
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1368 LOG_DEBUG("Examine failed");
1372 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1373 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1374 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1375 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1377 /* Setup Breakpoint Register Pairs */
1378 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1379 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1380 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1381 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(cortex_a8_brp_t
));
1382 // cortex_a8->brb_enabled = ????;
1383 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1385 cortex_a8
->brp_list
[i
].used
= 0;
1386 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1387 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1389 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1390 cortex_a8
->brp_list
[i
].value
= 0;
1391 cortex_a8
->brp_list
[i
].control
= 0;
1392 cortex_a8
->brp_list
[i
].BRPn
= i
;
1395 /* Setup Watchpoint Register Pairs */
1396 cortex_a8
->wrp_num
= ((didr
>> 28) & 0x0F) + 1;
1397 cortex_a8
->wrp_num_available
= cortex_a8
->wrp_num
;
1398 cortex_a8
->wrp_list
= calloc(cortex_a8
->wrp_num
, sizeof(cortex_a8_wrp_t
));
1399 for (i
= 0; i
< cortex_a8
->wrp_num
; i
++)
1401 cortex_a8
->wrp_list
[i
].used
= 0;
1402 cortex_a8
->wrp_list
[i
].type
= 0;
1403 cortex_a8
->wrp_list
[i
].value
= 0;
1404 cortex_a8
->wrp_list
[i
].control
= 0;
1405 cortex_a8
->wrp_list
[i
].WRPn
= i
;
1407 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1408 cortex_a8
->brp_num
, cortex_a8
->wrp_num
);
1410 target
->type
->examined
= 1;
1416 * Cortex-A8 target creation and initialization
1419 void cortex_a8_build_reg_cache(target_t
*target
)
1421 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1422 /* get pointers to arch-specific information */
1423 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1425 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
1426 armv4_5
->core_cache
= (*cache_p
);
1430 int cortex_a8_init_target(struct command_context_s
*cmd_ctx
,
1431 struct target_s
*target
)
1433 cortex_a8_build_reg_cache(target
);
1437 int cortex_a8_init_arch_info(target_t
*target
,
1438 cortex_a8_common_t
*cortex_a8
, jtag_tap_t
*tap
)
1440 armv4_5_common_t
*armv4_5
;
1441 armv7a_common_t
*armv7a
;
1443 armv7a
= &cortex_a8
->armv7a_common
;
1444 armv4_5
= &armv7a
->armv4_5_common
;
1445 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1447 /* Setup cortex_a8_common_t */
1448 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1449 cortex_a8
->arch_info
= NULL
;
1450 armv7a
->arch_info
= cortex_a8
;
1451 armv4_5
->arch_info
= armv7a
;
1453 armv4_5_init_arch_info(target
, armv4_5
);
1455 /* prepare JTAG information for the new target */
1456 cortex_a8
->jtag_info
.tap
= tap
;
1457 cortex_a8
->jtag_info
.scann_size
= 4;
1459 swjdp
->dp_select_value
= -1;
1460 swjdp
->ap_csw_value
= -1;
1461 swjdp
->ap_tar_value
= -1;
1462 swjdp
->jtag_info
= &cortex_a8
->jtag_info
;
1463 swjdp
->memaccess_tck
= 80;
1465 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1466 swjdp
->tar_autoincr_block
= (1 << 10);
1468 cortex_a8
->fast_reg_read
= 0;
1471 /* register arch-specific functions */
1472 armv7a
->examine_debug_reason
= NULL
;
1474 armv7a
->pre_debug_entry
= NULL
;
1475 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1477 armv7a
->pre_restore_context
= NULL
;
1478 armv7a
->post_restore_context
= NULL
;
1479 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1480 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1481 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_memory
;
1482 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_memory
;
1483 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1484 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1485 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1486 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1487 armv7a
->read_cp15
= cortex_a8_read_cp15
;
1488 armv7a
->write_cp15
= cortex_a8_write_cp15
;
1491 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1493 armv4_5
->read_core_reg
= cortex_a8_read_core_reg
;
1494 armv4_5
->write_core_reg
= cortex_a8_write_core_reg
;
1495 // armv4_5->full_context = arm7_9_full_context;
1497 // armv4_5->load_core_reg_u32 = cortex_a8_load_core_reg_u32;
1498 // armv4_5->store_core_reg_u32 = cortex_a8_store_core_reg_u32;
1499 // armv4_5->read_core_reg = armv4_5_read_core_reg; /* this is default */
1500 // armv4_5->write_core_reg = armv4_5_write_core_reg;
1502 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1507 int cortex_a8_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1509 cortex_a8_common_t
*cortex_a8
= calloc(1, sizeof(cortex_a8_common_t
));
1511 cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1516 static int cortex_a8_handle_cache_info_command(struct command_context_s
*cmd_ctx
,
1517 char *cmd
, char **args
, int argc
)
1519 target_t
*target
= get_current_target(cmd_ctx
);
1520 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1521 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
1523 return armv4_5_handle_cache_info_command(cmd_ctx
,
1524 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1528 int cortex_a8_register_commands(struct command_context_s
*cmd_ctx
)
1530 command_t
*cortex_a8_cmd
;
1531 int retval
= ERROR_OK
;
1533 armv4_5_register_commands(cmd_ctx
);
1534 armv7a_register_commands(cmd_ctx
);
1536 cortex_a8_cmd
= register_command(cmd_ctx
, NULL
, "cortex_a8",
1538 "cortex_a8 specific commands");
1540 register_command(cmd_ctx
, cortex_a8_cmd
, "cache_info",
1541 cortex_a8_handle_cache_info_command
, COMMAND_EXEC
,
1542 "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)