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 "breakpoints.h"
37 #include "cortex_a8.h"
39 #include "target_request.h"
40 #include "target_type.h"
42 static int cortex_a8_poll(struct target
*target
);
43 static int cortex_a8_debug_entry(struct target
*target
);
44 static int cortex_a8_restore_context(struct target
*target
);
45 static int cortex_a8_set_breakpoint(struct target
*target
,
46 struct breakpoint
*breakpoint
, uint8_t matchmode
);
47 static int cortex_a8_unset_breakpoint(struct target
*target
,
48 struct breakpoint
*breakpoint
);
49 static int cortex_a8_dap_read_coreregister_u32(struct target
*target
,
50 uint32_t *value
, int regnum
);
51 static int cortex_a8_dap_write_coreregister_u32(struct target
*target
,
52 uint32_t value
, int regnum
);
54 * FIXME do topology discovery using the ROM; don't
55 * assume this is an OMAP3.
57 #define swjdp_memoryap 0
58 #define swjdp_debugap 1
59 #define OMAP3530_DEBUG_BASE 0x54011000
62 * Cortex-A8 Basic debug access, very low level assumes state is saved
64 static int cortex_a8_init_debug_access(struct target
*target
)
66 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
67 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
74 /* Unlocking the debug registers for modification */
75 /* The debugport might be uninitialised so try twice */
76 retval
= mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
77 if (retval
!= ERROR_OK
)
78 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
79 /* Clear Sticky Power Down status Bit in PRSR to enable access to
80 the registers in the Core Power Domain */
81 retval
= mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_PRSR
, &dummy
);
82 /* Enabling of instruction execution in debug mode is done in debug_entry code */
84 /* Resync breakpoint registers */
86 /* Since this is likley called from init or reset, update targtet state information*/
87 cortex_a8_poll(target
);
92 int cortex_a8_exec_opcode(struct target
*target
, uint32_t opcode
)
96 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
97 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
99 LOG_DEBUG("exec opcode 0x%08" PRIx32
, opcode
);
102 retval
= mem_ap_read_atomic_u32(swjdp
,
103 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
104 if (retval
!= ERROR_OK
)
106 LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32
, opcode
);
110 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
112 mem_ap_write_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_ITR
, opcode
);
116 retval
= mem_ap_read_atomic_u32(swjdp
,
117 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
118 if (retval
!= ERROR_OK
)
120 LOG_ERROR("Could not read DSCR register");
124 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
129 /**************************************************************************
130 Read core register with very few exec_opcode, fast but needs work_area.
131 This can cause problems with MMU active.
132 **************************************************************************/
133 static int cortex_a8_read_regs_through_mem(struct target
*target
, uint32_t address
,
136 int retval
= ERROR_OK
;
137 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
138 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
140 cortex_a8_dap_read_coreregister_u32(target
, regfile
, 0);
141 cortex_a8_dap_write_coreregister_u32(target
, address
, 0);
142 cortex_a8_exec_opcode(target
, ARMV4_5_STMIA(0, 0xFFFE, 0, 0));
143 dap_ap_select(swjdp
, swjdp_memoryap
);
144 mem_ap_read_buf_u32(swjdp
, (uint8_t *)(®file
[1]), 4*15, address
);
145 dap_ap_select(swjdp
, swjdp_debugap
);
150 static int cortex_a8_read_cp(struct target
*target
, uint32_t *value
, uint8_t CP
,
151 uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
154 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
155 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
157 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(CP
, op1
, 0, CRn
, CRm
, op2
));
158 /* Move R0 to DTRTX */
159 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
162 retval
= mem_ap_read_atomic_u32(swjdp
,
163 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
168 static int cortex_a8_write_cp(struct target
*target
, uint32_t value
,
169 uint8_t CP
, uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
173 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
174 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
176 LOG_DEBUG("CP%i, CRn %i, value 0x%08" PRIx32
, CP
, CRn
, value
);
178 /* Check that DCCRX is not full */
179 retval
= mem_ap_read_atomic_u32(swjdp
,
180 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
181 if (dscr
& (1 << DSCR_DTR_RX_FULL
))
183 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
184 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
185 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
188 retval
= mem_ap_write_u32(swjdp
,
189 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
190 /* Move DTRRX to r0 */
191 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
193 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(CP
, op1
, 0, CRn
, CRm
, op2
));
197 static int cortex_a8_read_cp15(struct target
*target
, uint32_t op1
, uint32_t op2
,
198 uint32_t CRn
, uint32_t CRm
, uint32_t *value
)
200 return cortex_a8_read_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
203 static int cortex_a8_write_cp15(struct target
*target
, uint32_t op1
, uint32_t op2
,
204 uint32_t CRn
, uint32_t CRm
, uint32_t value
)
206 return cortex_a8_write_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
209 static int cortex_a8_mrc(struct target
*target
, int cpnum
, uint32_t op1
, uint32_t op2
, uint32_t CRn
, uint32_t CRm
, uint32_t *value
)
213 LOG_ERROR("Only cp15 is supported");
216 return cortex_a8_read_cp15(target
, op1
, op2
, CRn
, CRm
, value
);
219 static int cortex_a8_mcr(struct target
*target
, int cpnum
, uint32_t op1
, uint32_t op2
, uint32_t CRn
, uint32_t CRm
, uint32_t value
)
223 LOG_ERROR("Only cp15 is supported");
226 return cortex_a8_write_cp15(target
, op1
, op2
, CRn
, CRm
, value
);
231 static int cortex_a8_dap_read_coreregister_u32(struct target
*target
,
232 uint32_t *value
, int regnum
)
234 int retval
= ERROR_OK
;
235 uint8_t reg
= regnum
&0xFF;
237 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
238 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
245 /* Rn to DCCTX, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
246 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, reg
, 0, 5, 0));
250 cortex_a8_exec_opcode(target
, 0xE1A0000F);
251 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
255 cortex_a8_exec_opcode(target
, ARMV4_5_MRS(0, 0));
256 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
262 retval
= mem_ap_read_atomic_u32(swjdp
,
263 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
265 while ((dscr
& (1 << DSCR_DTR_TX_FULL
)) == 0); /* Wait for DTRRXfull */
267 retval
= mem_ap_read_atomic_u32(swjdp
,
268 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
273 static int cortex_a8_dap_write_coreregister_u32(struct target
*target
, uint32_t value
, int regnum
)
275 int retval
= ERROR_OK
;
276 uint8_t Rd
= regnum
&0xFF;
278 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
279 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
281 LOG_DEBUG("register %i, value 0x%08" PRIx32
, regnum
, value
);
283 /* Check that DCCRX is not full */
284 retval
= mem_ap_read_atomic_u32(swjdp
,
285 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
286 if (dscr
& (1 << DSCR_DTR_RX_FULL
))
288 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
289 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
290 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
297 retval
= mem_ap_write_u32(swjdp
,
298 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
302 /* DCCRX to Rd, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
303 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, Rd
, 0, 5, 0));
307 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
308 cortex_a8_exec_opcode(target
, 0xE1A0F000);
312 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
313 cortex_a8_exec_opcode(target
, ARMV4_5_MSR_GP(0, 0xF, 0));
314 /* Execute a PrefetchFlush instruction through the ITR. */
315 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(15, 0, 0, 7, 5, 4));
321 /* Write to memory mapped registers directly with no cache or mmu handling */
322 static int cortex_a8_dap_write_memap_register_u32(struct target
*target
, uint32_t address
, uint32_t value
)
325 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
326 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
328 retval
= mem_ap_write_atomic_u32(swjdp
, address
, value
);
334 * Cortex-A8 Run control
337 static int cortex_a8_poll(struct target
*target
)
339 int retval
= ERROR_OK
;
341 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
342 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
343 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
344 enum target_state prev_target_state
= target
->state
;
345 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
347 dap_ap_select(swjdp
, swjdp_debugap
);
348 retval
= mem_ap_read_atomic_u32(swjdp
,
349 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
350 if (retval
!= ERROR_OK
)
352 dap_ap_select(swjdp
, saved_apsel
);
355 cortex_a8
->cpudbg_dscr
= dscr
;
357 if ((dscr
& 0x3) == 0x3)
359 if (prev_target_state
!= TARGET_HALTED
)
361 /* We have a halting debug event */
362 LOG_DEBUG("Target halted");
363 target
->state
= TARGET_HALTED
;
364 if ((prev_target_state
== TARGET_RUNNING
)
365 || (prev_target_state
== TARGET_RESET
))
367 retval
= cortex_a8_debug_entry(target
);
368 if (retval
!= ERROR_OK
)
371 target_call_event_callbacks(target
,
372 TARGET_EVENT_HALTED
);
374 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
378 retval
= cortex_a8_debug_entry(target
);
379 if (retval
!= ERROR_OK
)
382 target_call_event_callbacks(target
,
383 TARGET_EVENT_DEBUG_HALTED
);
387 else if ((dscr
& 0x3) == 0x2)
389 target
->state
= TARGET_RUNNING
;
393 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32
, dscr
);
394 target
->state
= TARGET_UNKNOWN
;
397 dap_ap_select(swjdp
, saved_apsel
);
402 static int cortex_a8_halt(struct target
*target
)
404 int retval
= ERROR_OK
;
406 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
407 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
408 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
409 dap_ap_select(swjdp
, swjdp_debugap
);
412 * Tell the core to be halted by writing DRCR with 0x1
413 * and then wait for the core to be halted.
415 retval
= mem_ap_write_atomic_u32(swjdp
,
416 armv7a
->debug_base
+ CPUDBG_DRCR
, 0x1);
419 * enter halting debug mode
421 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
422 retval
= mem_ap_write_atomic_u32(swjdp
,
423 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
| (1 << DSCR_HALT_DBG_MODE
));
425 if (retval
!= ERROR_OK
)
429 mem_ap_read_atomic_u32(swjdp
,
430 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
431 } while ((dscr
& (1 << DSCR_CORE_HALTED
)) == 0);
433 target
->debug_reason
= DBG_REASON_DBGRQ
;
436 dap_ap_select(swjdp
, saved_apsel
);
440 static int cortex_a8_resume(struct target
*target
, int current
,
441 uint32_t address
, int handle_breakpoints
, int debug_execution
)
443 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
444 struct armv4_5_common_s
*armv4_5
= &armv7a
->armv4_5_common
;
445 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
447 // struct breakpoint *breakpoint = NULL;
448 uint32_t resume_pc
, dscr
;
450 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
451 dap_ap_select(swjdp
, swjdp_debugap
);
453 if (!debug_execution
)
455 target_free_all_working_areas(target
);
456 // cortex_m3_enable_breakpoints(target);
457 // cortex_m3_enable_watchpoints(target);
463 /* Disable interrupts */
464 /* We disable interrupts in the PRIMASK register instead of
465 * masking with C_MASKINTS,
466 * This is probably the same issue as Cortex-M3 Errata 377493:
467 * C_MASKINTS in parallel with disabled interrupts can cause
468 * local faults to not be taken. */
469 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
470 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
471 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
473 /* Make sure we are in Thumb mode */
474 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
475 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
476 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
477 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
481 /* current = 1: continue on current pc, otherwise continue at <address> */
482 resume_pc
= buf_get_u32(
483 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
484 armv4_5
->core_mode
, 15).value
,
489 /* Make sure that the Armv7 gdb thumb fixups does not
490 * kill the return address
492 if (armv7a
->core_state
== ARMV7A_STATE_ARM
)
494 resume_pc
&= 0xFFFFFFFC;
496 /* When the return address is loaded into PC
497 * bit 0 must be 1 to stay in Thumb state
499 if (armv7a
->core_state
== ARMV7A_STATE_THUMB
)
503 LOG_DEBUG("resume pc = 0x%08" PRIx32
, resume_pc
);
504 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
505 armv4_5
->core_mode
, 15).value
,
507 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
508 armv4_5
->core_mode
, 15).dirty
= 1;
509 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
510 armv4_5
->core_mode
, 15).valid
= 1;
512 cortex_a8_restore_context(target
);
513 // arm7_9_restore_context(target); TODO Context is currently NOT Properly restored
515 /* the front-end may request us not to handle breakpoints */
516 if (handle_breakpoints
)
518 /* Single step past breakpoint at current address */
519 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
521 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
522 cortex_m3_unset_breakpoint(target
, breakpoint
);
523 cortex_m3_single_step_core(target
);
524 cortex_m3_set_breakpoint(target
, breakpoint
);
529 /* Restart core and wait for it to be started */
530 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DRCR
, 0x2);
533 mem_ap_read_atomic_u32(swjdp
,
534 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
535 } while ((dscr
& (1 << DSCR_CORE_RESTARTED
)) == 0);
537 target
->debug_reason
= DBG_REASON_NOTHALTED
;
538 target
->state
= TARGET_RUNNING
;
540 /* registers are now invalid */
541 armv4_5_invalidate_core_regs(target
);
543 if (!debug_execution
)
545 target
->state
= TARGET_RUNNING
;
546 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
547 LOG_DEBUG("target resumed at 0x%" PRIx32
, resume_pc
);
551 target
->state
= TARGET_DEBUG_RUNNING
;
552 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
553 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, resume_pc
);
556 dap_ap_select(swjdp
, saved_apsel
);
561 static int cortex_a8_debug_entry(struct target
*target
)
564 uint32_t regfile
[16], pc
, cpsr
, dscr
;
565 int retval
= ERROR_OK
;
566 struct working_area
*regfile_working_area
= NULL
;
567 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
568 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
569 struct armv4_5_common_s
*armv4_5
= &armv7a
->armv4_5_common
;
570 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
572 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
574 /* Enable the ITR execution once we are in debug mode */
575 mem_ap_read_atomic_u32(swjdp
,
576 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
577 dscr
|= (1 << DSCR_EXT_INT_EN
);
578 retval
= mem_ap_write_atomic_u32(swjdp
,
579 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
);
581 /* Examine debug reason */
582 switch ((cortex_a8
->cpudbg_dscr
>> 2)&0xF)
586 target
->debug_reason
= DBG_REASON_DBGRQ
;
590 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
593 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
596 target
->debug_reason
= DBG_REASON_UNDEFINED
;
600 /* Examine target state and mode */
601 if (cortex_a8
->fast_reg_read
)
602 target_alloc_working_area(target
, 64, ®file_working_area
);
604 /* First load register acessible through core debug port*/
605 if (!regfile_working_area
)
607 for (i
= 0; i
<= 15; i
++)
608 cortex_a8_dap_read_coreregister_u32(target
,
613 dap_ap_select(swjdp
, swjdp_memoryap
);
614 cortex_a8_read_regs_through_mem(target
,
615 regfile_working_area
->address
, regfile
);
616 dap_ap_select(swjdp
, swjdp_memoryap
);
617 target_free_working_area(target
, regfile_working_area
);
620 cortex_a8_dap_read_coreregister_u32(target
, &cpsr
, 16);
622 dap_ap_select(swjdp
, swjdp_debugap
);
623 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
625 armv4_5
->core_mode
= cpsr
& 0x1F;
626 armv7a
->core_state
= (cpsr
& 0x20)?ARMV7A_STATE_THUMB
:ARMV7A_STATE_ARM
;
628 for (i
= 0; i
<= ARM_PC
; i
++)
630 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
631 armv4_5
->core_mode
, i
).value
,
633 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
634 armv4_5
->core_mode
, i
).valid
= 1;
635 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
636 armv4_5
->core_mode
, i
).dirty
= 0;
638 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
639 armv4_5
->core_mode
, 16).value
,
641 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
642 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
644 /* Fixup PC Resume Address */
645 if (armv7a
->core_state
== ARMV7A_STATE_THUMB
)
647 // T bit set for Thumb or ThumbEE state
648 regfile
[ARM_PC
] -= 4;
653 regfile
[ARM_PC
] -= 8;
655 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
656 armv4_5
->core_mode
, ARM_PC
).value
,
657 0, 32, regfile
[ARM_PC
]);
659 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 0)
660 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
661 armv4_5
->core_mode
, 0).valid
;
662 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 15)
663 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
664 armv4_5
->core_mode
, 15).valid
;
667 /* TODO, Move this */
668 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
669 cortex_a8_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
670 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
672 cortex_a8_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
673 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
675 cortex_a8_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
676 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
679 /* Are we in an exception handler */
680 // armv4_5->exception_number = 0;
681 if (armv7a
->post_debug_entry
)
682 armv7a
->post_debug_entry(target
);
690 static void cortex_a8_post_debug_entry(struct target
*target
)
692 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
693 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
695 // cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
696 /* examine cp15 control reg */
697 armv7a
->read_cp15(target
, 0, 0, 1, 0, &cortex_a8
->cp15_control_reg
);
698 jtag_execute_queue();
699 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
701 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
703 uint32_t cache_type_reg
;
704 /* identify caches */
705 armv7a
->read_cp15(target
, 0, 1, 0, 0, &cache_type_reg
);
706 jtag_execute_queue();
707 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
708 armv4_5_identify_cache(cache_type_reg
,
709 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
712 armv7a
->armv4_5_mmu
.mmu_enabled
=
713 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
714 armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
=
715 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
716 armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
=
717 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
722 static int cortex_a8_step(struct target
*target
, int current
, uint32_t address
,
723 int handle_breakpoints
)
725 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
726 struct armv4_5_common_s
*armv4_5
= &armv7a
->armv4_5_common
;
727 struct breakpoint
*breakpoint
= NULL
;
728 struct breakpoint stepbreakpoint
;
732 if (target
->state
!= TARGET_HALTED
)
734 LOG_WARNING("target not halted");
735 return ERROR_TARGET_NOT_HALTED
;
738 /* current = 1: continue on current pc, otherwise continue at <address> */
741 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
742 armv4_5
->core_mode
, ARM_PC
).value
,
747 address
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
748 armv4_5
->core_mode
, ARM_PC
).value
,
752 /* The front-end may request us not to handle breakpoints.
753 * But since Cortex-A8 uses breakpoint for single step,
754 * we MUST handle breakpoints.
756 handle_breakpoints
= 1;
757 if (handle_breakpoints
) {
758 breakpoint
= breakpoint_find(target
,
759 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
760 armv4_5
->core_mode
, 15).value
,
763 cortex_a8_unset_breakpoint(target
, breakpoint
);
766 /* Setup single step breakpoint */
767 stepbreakpoint
.address
= address
;
768 stepbreakpoint
.length
= (armv7a
->core_state
== ARMV7A_STATE_THUMB
) ? 2 : 4;
769 stepbreakpoint
.type
= BKPT_HARD
;
770 stepbreakpoint
.set
= 0;
772 /* Break on IVA mismatch */
773 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
775 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
777 cortex_a8_resume(target
, 1, address
, 0, 0);
779 while (target
->state
!= TARGET_HALTED
)
781 cortex_a8_poll(target
);
784 LOG_WARNING("timeout waiting for target halt");
789 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
790 if (timeout
> 0) target
->debug_reason
= DBG_REASON_BREAKPOINT
;
793 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
795 if (target
->state
!= TARGET_HALTED
)
796 LOG_DEBUG("target stepped");
801 static int cortex_a8_restore_context(struct target
*target
)
805 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
806 struct armv4_5_common_s
*armv4_5
= &armv7a
->armv4_5_common
;
810 if (armv7a
->pre_restore_context
)
811 armv7a
->pre_restore_context(target
);
813 for (i
= 15; i
>= 0; i
--)
815 if (ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
816 armv4_5
->core_mode
, i
).dirty
)
818 value
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
819 armv4_5
->core_mode
, i
).value
,
821 /* TODO Check return values */
822 cortex_a8_dap_write_coreregister_u32(target
, value
, i
);
826 if (armv7a
->post_restore_context
)
827 armv7a
->post_restore_context(target
);
835 * Cortex-A8 Core register functions
837 static int cortex_a8_load_core_reg_u32(struct target
*target
, int num
,
838 armv4_5_mode_t mode
, uint32_t * value
)
841 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
843 if ((num
<= ARM_CPSR
))
845 /* read a normal core register */
846 retval
= cortex_a8_dap_read_coreregister_u32(target
, value
, num
);
848 if (retval
!= ERROR_OK
)
850 LOG_ERROR("JTAG failure %i", retval
);
851 return ERROR_JTAG_DEVICE_ERROR
;
853 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
, num
, *value
);
857 return ERROR_INVALID_ARGUMENTS
;
860 /* Register other than r0 - r14 uses r0 for access */
862 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
863 armv4_5
->core_mode
, 0).dirty
=
864 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
865 armv4_5
->core_mode
, 0).valid
;
866 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
867 armv4_5
->core_mode
, 15).dirty
=
868 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
869 armv4_5
->core_mode
, 15).valid
;
874 static int cortex_a8_store_core_reg_u32(struct target
*target
, int num
,
875 armv4_5_mode_t mode
, uint32_t value
)
879 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
881 #ifdef ARMV7_GDB_HACKS
882 /* If the LR register is being modified, make sure it will put us
883 * in "thumb" mode, or an INVSTATE exception will occur. This is a
884 * hack to deal with the fact that gdb will sometimes "forge"
885 * return addresses, and doesn't set the LSB correctly (i.e., when
886 * printing expressions containing function calls, it sets LR=0.) */
892 if ((num
<= ARM_CPSR
))
894 retval
= cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
895 if (retval
!= ERROR_OK
)
897 LOG_ERROR("JTAG failure %i", retval
);
898 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
899 armv4_5
->core_mode
, num
).dirty
=
900 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
901 armv4_5
->core_mode
, num
).valid
;
902 return ERROR_JTAG_DEVICE_ERROR
;
904 LOG_DEBUG("write core reg %i value 0x%" PRIx32
, num
, value
);
908 return ERROR_INVALID_ARGUMENTS
;
916 static int cortex_a8_read_core_reg(struct target
*target
, int num
,
917 enum armv4_5_mode mode
)
921 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
923 cortex_a8_dap_read_coreregister_u32(target
, &value
, num
);
925 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
930 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
931 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
932 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
933 mode
, num
).value
, 0, 32, value
);
938 int cortex_a8_write_core_reg(struct target
*target
, int num
,
939 enum armv4_5_mode mode
, uint32_t value
)
942 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
944 cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
945 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
950 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
951 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
958 * Cortex-A8 Breakpoint and watchpoint fuctions
961 /* Setup hardware Breakpoint Register Pair */
962 static int cortex_a8_set_breakpoint(struct target
*target
,
963 struct breakpoint
*breakpoint
, uint8_t matchmode
)
968 uint8_t byte_addr_select
= 0x0F;
969 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
970 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
971 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
975 LOG_WARNING("breakpoint already set");
979 if (breakpoint
->type
== BKPT_HARD
)
981 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
983 if (brp_i
>= cortex_a8
->brp_num
)
985 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
988 breakpoint
->set
= brp_i
+ 1;
989 if (breakpoint
->length
== 2)
991 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
993 control
= ((matchmode
& 0x7) << 20)
994 | (byte_addr_select
<< 5)
996 brp_list
[brp_i
].used
= 1;
997 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
998 brp_list
[brp_i
].control
= control
;
999 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1000 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1001 brp_list
[brp_i
].value
);
1002 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1003 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1004 brp_list
[brp_i
].control
);
1005 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1006 brp_list
[brp_i
].control
,
1007 brp_list
[brp_i
].value
);
1009 else if (breakpoint
->type
== BKPT_SOFT
)
1012 if (breakpoint
->length
== 2)
1014 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1018 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1020 retval
= target
->type
->read_memory(target
,
1021 breakpoint
->address
& 0xFFFFFFFE,
1022 breakpoint
->length
, 1,
1023 breakpoint
->orig_instr
);
1024 if (retval
!= ERROR_OK
)
1026 retval
= target
->type
->write_memory(target
,
1027 breakpoint
->address
& 0xFFFFFFFE,
1028 breakpoint
->length
, 1, code
);
1029 if (retval
!= ERROR_OK
)
1031 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1037 static int cortex_a8_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1040 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1041 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1042 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1044 if (!breakpoint
->set
)
1046 LOG_WARNING("breakpoint not set");
1050 if (breakpoint
->type
== BKPT_HARD
)
1052 int brp_i
= breakpoint
->set
- 1;
1053 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1055 LOG_DEBUG("Invalid BRP number in breakpoint");
1058 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1059 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1060 brp_list
[brp_i
].used
= 0;
1061 brp_list
[brp_i
].value
= 0;
1062 brp_list
[brp_i
].control
= 0;
1063 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1064 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1065 brp_list
[brp_i
].control
);
1066 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1067 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1068 brp_list
[brp_i
].value
);
1072 /* restore original instruction (kept in target endianness) */
1073 if (breakpoint
->length
== 4)
1075 retval
= target
->type
->write_memory(target
,
1076 breakpoint
->address
& 0xFFFFFFFE,
1077 4, 1, breakpoint
->orig_instr
);
1078 if (retval
!= ERROR_OK
)
1083 retval
= target
->type
->write_memory(target
,
1084 breakpoint
->address
& 0xFFFFFFFE,
1085 2, 1, breakpoint
->orig_instr
);
1086 if (retval
!= ERROR_OK
)
1090 breakpoint
->set
= 0;
1095 int cortex_a8_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1097 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1099 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1101 LOG_INFO("no hardware breakpoint available");
1102 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1105 if (breakpoint
->type
== BKPT_HARD
)
1106 cortex_a8
->brp_num_available
--;
1107 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1112 static int cortex_a8_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1114 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1117 /* It is perfectly possible to remove brakpoints while the taget is running */
1118 if (target
->state
!= TARGET_HALTED
)
1120 LOG_WARNING("target not halted");
1121 return ERROR_TARGET_NOT_HALTED
;
1125 if (breakpoint
->set
)
1127 cortex_a8_unset_breakpoint(target
, breakpoint
);
1128 if (breakpoint
->type
== BKPT_HARD
)
1129 cortex_a8
->brp_num_available
++ ;
1139 * Cortex-A8 Reset fuctions
1142 static int cortex_a8_assert_reset(struct target
*target
)
1147 /* registers are now invalid */
1148 armv4_5_invalidate_core_regs(target
);
1150 target
->state
= TARGET_RESET
;
1155 static int cortex_a8_deassert_reset(struct target
*target
)
1160 if (target
->reset_halt
)
1163 if ((retval
= target_halt(target
)) != ERROR_OK
)
1171 * Cortex-A8 Memory access
1173 * This is same Cortex M3 but we must also use the correct
1174 * ap number for every access.
1177 static int cortex_a8_read_memory(struct target
*target
, uint32_t address
,
1178 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1180 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1181 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1182 int retval
= ERROR_INVALID_ARGUMENTS
;
1184 /* cortex_a8 handles unaligned memory access */
1186 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1188 if (count
&& buffer
) {
1191 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1194 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1197 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1205 int cortex_a8_write_memory(struct target
*target
, uint32_t address
,
1206 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1208 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1209 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1210 int retval
= ERROR_INVALID_ARGUMENTS
;
1212 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1214 if (count
&& buffer
) {
1217 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1220 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1223 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1228 if (retval
== ERROR_OK
&& target
->state
== TARGET_HALTED
)
1230 /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */
1231 /* invalidate I-Cache */
1232 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
1234 /* Invalidate ICache single entry with MVA, repeat this for all cache
1235 lines in the address range, Cortex-A8 has fixed 64 byte line length */
1236 /* Invalidate Cache single entry with MVA to PoU */
1237 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1238 armv7a
->write_cp15(target
, 0, 1, 7, 5, cacheline
); /* I-Cache to PoU */
1240 /* invalidate D-Cache */
1241 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
1243 /* Invalidate Cache single entry with MVA to PoC */
1244 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1245 armv7a
->write_cp15(target
, 0, 1, 7, 6, cacheline
); /* U/D cache to PoC */
1252 static int cortex_a8_bulk_write_memory(struct target
*target
, uint32_t address
,
1253 uint32_t count
, uint8_t *buffer
)
1255 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1259 static int cortex_a8_dcc_read(struct swjdp_common
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1264 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1265 *ctrl
= (uint8_t)dcrdr
;
1266 *value
= (uint8_t)(dcrdr
>> 8);
1268 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1270 /* write ack back to software dcc register
1271 * signify we have read data */
1272 if (dcrdr
& (1 << 0))
1275 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1282 static int cortex_a8_handle_target_request(void *priv
)
1284 struct target
*target
= priv
;
1285 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1286 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1288 if (!target_was_examined(target
))
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 static int cortex_a8_examine(struct target
*target
)
1326 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1327 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1328 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1330 int retval
= ERROR_OK
;
1331 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1335 /* Here we shall insert a proper ROM Table scan */
1336 armv7a
->debug_base
= OMAP3530_DEBUG_BASE
;
1338 /* We do one extra read to ensure DAP is configured,
1339 * we call ahbap_debugport_init(swjdp) instead
1341 ahbap_debugport_init(swjdp
);
1342 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
1343 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1344 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1346 LOG_DEBUG("Examine failed");
1350 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1351 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1353 LOG_DEBUG("Examine failed");
1357 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1358 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1360 LOG_DEBUG("Examine failed");
1364 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1365 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1367 LOG_DEBUG("Examine failed");
1371 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1372 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1373 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1374 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1376 /* Setup Breakpoint Register Pairs */
1377 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1378 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1379 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1380 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(struct cortex_a8_brp
));
1381 // cortex_a8->brb_enabled = ????;
1382 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1384 cortex_a8
->brp_list
[i
].used
= 0;
1385 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1386 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1388 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1389 cortex_a8
->brp_list
[i
].value
= 0;
1390 cortex_a8
->brp_list
[i
].control
= 0;
1391 cortex_a8
->brp_list
[i
].BRPn
= i
;
1394 /* Setup Watchpoint Register Pairs */
1395 cortex_a8
->wrp_num
= ((didr
>> 28) & 0x0F) + 1;
1396 cortex_a8
->wrp_num_available
= cortex_a8
->wrp_num
;
1397 cortex_a8
->wrp_list
= calloc(cortex_a8
->wrp_num
, sizeof(struct cortex_a8_wrp
));
1398 for (i
= 0; i
< cortex_a8
->wrp_num
; i
++)
1400 cortex_a8
->wrp_list
[i
].used
= 0;
1401 cortex_a8
->wrp_list
[i
].type
= 0;
1402 cortex_a8
->wrp_list
[i
].value
= 0;
1403 cortex_a8
->wrp_list
[i
].control
= 0;
1404 cortex_a8
->wrp_list
[i
].WRPn
= i
;
1406 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1407 cortex_a8
->brp_num
, cortex_a8
->wrp_num
);
1409 /* Configure core debug access */
1410 cortex_a8_init_debug_access(target
);
1412 target_set_examined(target
);
1418 * Cortex-A8 target creation and initialization
1421 static void cortex_a8_build_reg_cache(struct target
*target
)
1423 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1424 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
1426 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
1427 armv4_5
->core_cache
= (*cache_p
);
1431 static int cortex_a8_init_target(struct command_context
*cmd_ctx
,
1432 struct target
*target
)
1434 cortex_a8_build_reg_cache(target
);
1438 int cortex_a8_init_arch_info(struct target
*target
,
1439 struct cortex_a8_common
*cortex_a8
, struct jtag_tap
*tap
)
1441 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1442 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
1443 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1445 /* REVISIT v7a setup should be in a v7a-specific routine */
1446 armv4_5_init_arch_info(target
, armv4_5
);
1447 armv7a
->common_magic
= ARMV7_COMMON_MAGIC
;
1449 /* Setup struct cortex_a8_common */
1450 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1451 armv4_5
->arch_info
= armv7a
;
1453 /* prepare JTAG information for the new target */
1454 cortex_a8
->jtag_info
.tap
= tap
;
1455 cortex_a8
->jtag_info
.scann_size
= 4;
1457 swjdp
->dp_select_value
= -1;
1458 swjdp
->ap_csw_value
= -1;
1459 swjdp
->ap_tar_value
= -1;
1460 swjdp
->jtag_info
= &cortex_a8
->jtag_info
;
1461 swjdp
->memaccess_tck
= 80;
1463 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1464 swjdp
->tar_autoincr_block
= (1 << 10);
1466 cortex_a8
->fast_reg_read
= 0;
1469 /* register arch-specific functions */
1470 armv7a
->examine_debug_reason
= NULL
;
1472 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1474 armv7a
->pre_restore_context
= NULL
;
1475 armv7a
->post_restore_context
= NULL
;
1476 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1477 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1478 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_memory
;
1479 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_memory
;
1480 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1481 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1482 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1483 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1484 armv7a
->read_cp15
= cortex_a8_read_cp15
;
1485 armv7a
->write_cp15
= cortex_a8_write_cp15
;
1488 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1490 armv4_5
->read_core_reg
= cortex_a8_read_core_reg
;
1491 armv4_5
->write_core_reg
= cortex_a8_write_core_reg
;
1492 // armv4_5->full_context = arm7_9_full_context;
1494 // armv4_5->load_core_reg_u32 = cortex_a8_load_core_reg_u32;
1495 // armv4_5->store_core_reg_u32 = cortex_a8_store_core_reg_u32;
1496 // armv4_5->read_core_reg = armv4_5_read_core_reg; /* this is default */
1497 // armv4_5->write_core_reg = armv4_5_write_core_reg;
1499 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1504 static int cortex_a8_target_create(struct target
*target
, Jim_Interp
*interp
)
1506 struct cortex_a8_common
*cortex_a8
= calloc(1, sizeof(struct cortex_a8_common
));
1508 cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1513 COMMAND_HANDLER(cortex_a8_handle_cache_info_command
)
1515 struct target
*target
= get_current_target(CMD_CTX
);
1516 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1518 return armv4_5_handle_cache_info_command(CMD_CTX
,
1519 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1523 COMMAND_HANDLER(cortex_a8_handle_dbginit_command
)
1525 struct target
*target
= get_current_target(CMD_CTX
);
1527 cortex_a8_init_debug_access(target
);
1533 static int cortex_a8_register_commands(struct command_context
*cmd_ctx
)
1535 struct command
*cortex_a8_cmd
;
1536 int retval
= ERROR_OK
;
1538 armv4_5_register_commands(cmd_ctx
);
1539 armv7a_register_commands(cmd_ctx
);
1541 cortex_a8_cmd
= register_command(cmd_ctx
, NULL
, "cortex_a8",
1543 "cortex_a8 specific commands");
1545 register_command(cmd_ctx
, cortex_a8_cmd
, "cache_info",
1546 cortex_a8_handle_cache_info_command
, COMMAND_EXEC
,
1547 "display information about target caches");
1549 register_command(cmd_ctx
, cortex_a8_cmd
, "dbginit",
1550 cortex_a8_handle_dbginit_command
, COMMAND_EXEC
,
1551 "Initialize core debug");
1556 struct target_type cortexa8_target
= {
1557 .name
= "cortex_a8",
1559 .poll
= cortex_a8_poll
,
1560 .arch_state
= armv7a_arch_state
,
1562 .target_request_data
= NULL
,
1564 .halt
= cortex_a8_halt
,
1565 .resume
= cortex_a8_resume
,
1566 .step
= cortex_a8_step
,
1568 .assert_reset
= cortex_a8_assert_reset
,
1569 .deassert_reset
= cortex_a8_deassert_reset
,
1570 .soft_reset_halt
= NULL
,
1572 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
1574 .read_memory
= cortex_a8_read_memory
,
1575 .write_memory
= cortex_a8_write_memory
,
1576 .bulk_write_memory
= cortex_a8_bulk_write_memory
,
1578 .checksum_memory
= arm_checksum_memory
,
1579 .blank_check_memory
= arm_blank_check_memory
,
1581 .run_algorithm
= armv4_5_run_algorithm
,
1583 .add_breakpoint
= cortex_a8_add_breakpoint
,
1584 .remove_breakpoint
= cortex_a8_remove_breakpoint
,
1585 .add_watchpoint
= NULL
,
1586 .remove_watchpoint
= NULL
,
1588 .register_commands
= cortex_a8_register_commands
,
1589 .target_create
= cortex_a8_target_create
,
1590 .init_target
= cortex_a8_init_target
,
1591 .examine
= cortex_a8_examine
,
1592 .mrc
= cortex_a8_mrc
,
1593 .mcr
= cortex_a8_mcr
,
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)