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"
43 static int cortex_a8_poll(target_t
*target
);
44 static int cortex_a8_debug_entry(target_t
*target
);
45 static int cortex_a8_restore_context(target_t
*target
);
46 static int cortex_a8_set_breakpoint(struct target_s
*target
,
47 breakpoint_t
*breakpoint
, uint8_t matchmode
);
48 static int cortex_a8_unset_breakpoint(struct target_s
*target
,
49 breakpoint_t
*breakpoint
);
50 static int cortex_a8_dap_read_coreregister_u32(target_t
*target
,
51 uint32_t *value
, int regnum
);
52 static int cortex_a8_dap_write_coreregister_u32(target_t
*target
,
53 uint32_t value
, int regnum
);
55 * FIXME do topology discovery using the ROM; don't
56 * assume this is an OMAP3.
58 #define swjdp_memoryap 0
59 #define swjdp_debugap 1
60 #define OMAP3530_DEBUG_BASE 0x54011000
63 * Cortex-A8 Basic debug access, very low level assumes state is saved
65 static int cortex_a8_init_debug_access(target_t
*target
)
67 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
68 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
75 /* Unlocking the debug registers for modification */
76 /* The debugport might be uninitialised so try twice */
77 retval
= mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
78 if (retval
!= ERROR_OK
)
79 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
80 /* Clear Sticky Power Down status Bit in PRSR to enable access to
81 the registers in the Core Power Domain */
82 retval
= mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_PRSR
, &dummy
);
83 /* Enabling of instruction execution in debug mode is done in debug_entry code */
85 /* Resync breakpoint registers */
87 /* Since this is likley called from init or reset, update targtet state information*/
88 cortex_a8_poll(target
);
93 int cortex_a8_exec_opcode(target_t
*target
, uint32_t opcode
)
97 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
98 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
100 LOG_DEBUG("exec opcode 0x%08" PRIx32
, opcode
);
103 retval
= mem_ap_read_atomic_u32(swjdp
,
104 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
105 if (retval
!= ERROR_OK
)
107 LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32
, opcode
);
111 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
113 mem_ap_write_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_ITR
, opcode
);
117 retval
= mem_ap_read_atomic_u32(swjdp
,
118 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
119 if (retval
!= ERROR_OK
)
121 LOG_ERROR("Could not read DSCR register");
125 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
130 /**************************************************************************
131 Read core register with very few exec_opcode, fast but needs work_area.
132 This can cause problems with MMU active.
133 **************************************************************************/
134 static int cortex_a8_read_regs_through_mem(target_t
*target
, uint32_t address
,
137 int retval
= ERROR_OK
;
138 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
139 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
141 cortex_a8_dap_read_coreregister_u32(target
, regfile
, 0);
142 cortex_a8_dap_write_coreregister_u32(target
, address
, 0);
143 cortex_a8_exec_opcode(target
, ARMV4_5_STMIA(0, 0xFFFE, 0, 0));
144 dap_ap_select(swjdp
, swjdp_memoryap
);
145 mem_ap_read_buf_u32(swjdp
, (uint8_t *)(®file
[1]), 4*15, address
);
146 dap_ap_select(swjdp
, swjdp_debugap
);
151 static int cortex_a8_read_cp(target_t
*target
, uint32_t *value
, uint8_t CP
,
152 uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
155 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
156 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
158 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(CP
, op1
, 0, CRn
, CRm
, op2
));
159 /* Move R0 to DTRTX */
160 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
163 retval
= mem_ap_read_atomic_u32(swjdp
,
164 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
169 static int cortex_a8_write_cp(target_t
*target
, uint32_t value
,
170 uint8_t CP
, uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
174 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
175 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
177 LOG_DEBUG("CP%i, CRn %i, value 0x%08" PRIx32
, CP
, CRn
, value
);
179 /* Check that DCCRX is not full */
180 retval
= mem_ap_read_atomic_u32(swjdp
,
181 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
182 if (dscr
& (1 << DSCR_DTR_RX_FULL
))
184 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
185 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
186 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
189 retval
= mem_ap_write_u32(swjdp
,
190 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
191 /* Move DTRRX to r0 */
192 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
194 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(CP
, op1
, 0, CRn
, CRm
, op2
));
198 static int cortex_a8_read_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
199 uint32_t CRn
, uint32_t CRm
, uint32_t *value
)
201 return cortex_a8_read_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
204 static int cortex_a8_write_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
205 uint32_t CRn
, uint32_t CRm
, uint32_t value
)
207 return cortex_a8_write_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
210 static int cortex_a8_mrc(target_t
*target
, int cpnum
, uint32_t op1
, uint32_t op2
, uint32_t CRn
, uint32_t CRm
, uint32_t *value
)
214 LOG_ERROR("Only cp15 is supported");
217 return cortex_a8_read_cp15(target
, op1
, op2
, CRn
, CRm
, value
);
220 static int cortex_a8_mcr(target_t
*target
, int cpnum
, uint32_t op1
, uint32_t op2
, uint32_t CRn
, uint32_t CRm
, uint32_t value
)
224 LOG_ERROR("Only cp15 is supported");
227 return cortex_a8_write_cp15(target
, op1
, op2
, CRn
, CRm
, value
);
232 static int cortex_a8_dap_read_coreregister_u32(target_t
*target
,
233 uint32_t *value
, int regnum
)
235 int retval
= ERROR_OK
;
236 uint8_t reg
= regnum
&0xFF;
238 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
239 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
246 /* Rn to DCCTX, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
247 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, reg
, 0, 5, 0));
251 cortex_a8_exec_opcode(target
, 0xE1A0000F);
252 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
256 cortex_a8_exec_opcode(target
, ARMV4_5_MRS(0, 0));
257 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
263 retval
= mem_ap_read_atomic_u32(swjdp
,
264 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
266 while ((dscr
& (1 << DSCR_DTR_TX_FULL
)) == 0); /* Wait for DTRRXfull */
268 retval
= mem_ap_read_atomic_u32(swjdp
,
269 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
274 static int cortex_a8_dap_write_coreregister_u32(target_t
*target
, uint32_t value
, int regnum
)
276 int retval
= ERROR_OK
;
277 uint8_t Rd
= regnum
&0xFF;
279 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
280 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
282 LOG_DEBUG("register %i, value 0x%08" PRIx32
, regnum
, value
);
284 /* Check that DCCRX is not full */
285 retval
= mem_ap_read_atomic_u32(swjdp
,
286 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
287 if (dscr
& (1 << DSCR_DTR_RX_FULL
))
289 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
290 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
291 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
298 retval
= mem_ap_write_u32(swjdp
,
299 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
303 /* DCCRX to Rd, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
304 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, Rd
, 0, 5, 0));
308 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
309 cortex_a8_exec_opcode(target
, 0xE1A0F000);
313 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
314 cortex_a8_exec_opcode(target
, ARMV4_5_MSR_GP(0, 0xF, 0));
315 /* Execute a PrefetchFlush instruction through the ITR. */
316 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(15, 0, 0, 7, 5, 4));
322 /* Write to memory mapped registers directly with no cache or mmu handling */
323 static int cortex_a8_dap_write_memap_register_u32(target_t
*target
, uint32_t address
, uint32_t value
)
326 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
327 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
329 retval
= mem_ap_write_atomic_u32(swjdp
, address
, value
);
335 * Cortex-A8 Run control
338 static int cortex_a8_poll(target_t
*target
)
340 int retval
= ERROR_OK
;
342 struct cortex_a8_common_s
*cortex_a8
= target_to_cortex_a8(target
);
343 struct armv7a_common_s
*armv7a
= &cortex_a8
->armv7a_common
;
344 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
345 enum target_state prev_target_state
= target
->state
;
346 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
348 dap_ap_select(swjdp
, swjdp_debugap
);
349 retval
= mem_ap_read_atomic_u32(swjdp
,
350 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
351 if (retval
!= ERROR_OK
)
353 dap_ap_select(swjdp
, saved_apsel
);
356 cortex_a8
->cpudbg_dscr
= dscr
;
358 if ((dscr
& 0x3) == 0x3)
360 if (prev_target_state
!= TARGET_HALTED
)
362 /* We have a halting debug event */
363 LOG_DEBUG("Target halted");
364 target
->state
= TARGET_HALTED
;
365 if ((prev_target_state
== TARGET_RUNNING
)
366 || (prev_target_state
== TARGET_RESET
))
368 retval
= cortex_a8_debug_entry(target
);
369 if (retval
!= ERROR_OK
)
372 target_call_event_callbacks(target
,
373 TARGET_EVENT_HALTED
);
375 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
379 retval
= cortex_a8_debug_entry(target
);
380 if (retval
!= ERROR_OK
)
383 target_call_event_callbacks(target
,
384 TARGET_EVENT_DEBUG_HALTED
);
388 else if ((dscr
& 0x3) == 0x2)
390 target
->state
= TARGET_RUNNING
;
394 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32
, dscr
);
395 target
->state
= TARGET_UNKNOWN
;
398 dap_ap_select(swjdp
, saved_apsel
);
403 static int cortex_a8_halt(target_t
*target
)
405 int retval
= ERROR_OK
;
407 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
408 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
409 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
410 dap_ap_select(swjdp
, swjdp_debugap
);
413 * Tell the core to be halted by writing DRCR with 0x1
414 * and then wait for the core to be halted.
416 retval
= mem_ap_write_atomic_u32(swjdp
,
417 armv7a
->debug_base
+ CPUDBG_DRCR
, 0x1);
420 * enter halting debug mode
422 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
423 retval
= mem_ap_write_atomic_u32(swjdp
,
424 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
| (1 << DSCR_HALT_DBG_MODE
));
426 if (retval
!= ERROR_OK
)
430 mem_ap_read_atomic_u32(swjdp
,
431 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
432 } while ((dscr
& (1 << DSCR_CORE_HALTED
)) == 0);
434 target
->debug_reason
= DBG_REASON_DBGRQ
;
437 dap_ap_select(swjdp
, saved_apsel
);
441 static int cortex_a8_resume(struct target_s
*target
, int current
,
442 uint32_t address
, int handle_breakpoints
, int debug_execution
)
444 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
445 struct armv4_5_common_s
*armv4_5
= &armv7a
->armv4_5_common
;
446 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
448 // breakpoint_t *breakpoint = NULL;
449 uint32_t resume_pc
, dscr
;
451 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
452 dap_ap_select(swjdp
, swjdp_debugap
);
454 if (!debug_execution
)
456 target_free_all_working_areas(target
);
457 // cortex_m3_enable_breakpoints(target);
458 // cortex_m3_enable_watchpoints(target);
464 /* Disable interrupts */
465 /* We disable interrupts in the PRIMASK register instead of
466 * masking with C_MASKINTS,
467 * This is probably the same issue as Cortex-M3 Errata 377493:
468 * C_MASKINTS in parallel with disabled interrupts can cause
469 * local faults to not be taken. */
470 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
471 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
472 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
474 /* Make sure we are in Thumb mode */
475 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
476 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
477 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
478 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
482 /* current = 1: continue on current pc, otherwise continue at <address> */
483 resume_pc
= buf_get_u32(
484 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
485 armv4_5
->core_mode
, 15).value
,
490 /* Make sure that the Armv7 gdb thumb fixups does not
491 * kill the return address
493 if (armv7a
->core_state
== ARMV7A_STATE_ARM
)
495 resume_pc
&= 0xFFFFFFFC;
497 /* When the return address is loaded into PC
498 * bit 0 must be 1 to stay in Thumb state
500 if (armv7a
->core_state
== ARMV7A_STATE_THUMB
)
504 LOG_DEBUG("resume pc = 0x%08" PRIx32
, resume_pc
);
505 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
506 armv4_5
->core_mode
, 15).value
,
508 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
509 armv4_5
->core_mode
, 15).dirty
= 1;
510 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
511 armv4_5
->core_mode
, 15).valid
= 1;
513 cortex_a8_restore_context(target
);
514 // arm7_9_restore_context(target); TODO Context is currently NOT Properly restored
516 /* the front-end may request us not to handle breakpoints */
517 if (handle_breakpoints
)
519 /* Single step past breakpoint at current address */
520 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
522 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
523 cortex_m3_unset_breakpoint(target
, breakpoint
);
524 cortex_m3_single_step_core(target
);
525 cortex_m3_set_breakpoint(target
, breakpoint
);
530 /* Restart core and wait for it to be started */
531 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DRCR
, 0x2);
534 mem_ap_read_atomic_u32(swjdp
,
535 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
536 } while ((dscr
& (1 << DSCR_CORE_RESTARTED
)) == 0);
538 target
->debug_reason
= DBG_REASON_NOTHALTED
;
539 target
->state
= TARGET_RUNNING
;
541 /* registers are now invalid */
542 armv4_5_invalidate_core_regs(target
);
544 if (!debug_execution
)
546 target
->state
= TARGET_RUNNING
;
547 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
548 LOG_DEBUG("target resumed at 0x%" PRIx32
, resume_pc
);
552 target
->state
= TARGET_DEBUG_RUNNING
;
553 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
554 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, resume_pc
);
557 dap_ap_select(swjdp
, saved_apsel
);
562 static int cortex_a8_debug_entry(target_t
*target
)
565 uint32_t regfile
[16], pc
, cpsr
, dscr
;
566 int retval
= ERROR_OK
;
567 working_area_t
*regfile_working_area
= NULL
;
568 struct cortex_a8_common_s
*cortex_a8
= target_to_cortex_a8(target
);
569 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
570 struct armv4_5_common_s
*armv4_5
= &armv7a
->armv4_5_common
;
571 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
573 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
575 /* Enable the ITR execution once we are in debug mode */
576 mem_ap_read_atomic_u32(swjdp
,
577 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
578 dscr
|= (1 << DSCR_EXT_INT_EN
);
579 retval
= mem_ap_write_atomic_u32(swjdp
,
580 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
);
582 /* Examine debug reason */
583 switch ((cortex_a8
->cpudbg_dscr
>> 2)&0xF)
587 target
->debug_reason
= DBG_REASON_DBGRQ
;
591 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
594 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
597 target
->debug_reason
= DBG_REASON_UNDEFINED
;
601 /* Examine target state and mode */
602 if (cortex_a8
->fast_reg_read
)
603 target_alloc_working_area(target
, 64, ®file_working_area
);
605 /* First load register acessible through core debug port*/
606 if (!regfile_working_area
)
608 for (i
= 0; i
<= 15; i
++)
609 cortex_a8_dap_read_coreregister_u32(target
,
614 dap_ap_select(swjdp
, swjdp_memoryap
);
615 cortex_a8_read_regs_through_mem(target
,
616 regfile_working_area
->address
, regfile
);
617 dap_ap_select(swjdp
, swjdp_memoryap
);
618 target_free_working_area(target
, regfile_working_area
);
621 cortex_a8_dap_read_coreregister_u32(target
, &cpsr
, 16);
623 dap_ap_select(swjdp
, swjdp_debugap
);
624 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
626 armv4_5
->core_mode
= cpsr
& 0x1F;
627 armv7a
->core_state
= (cpsr
& 0x20)?ARMV7A_STATE_THUMB
:ARMV7A_STATE_ARM
;
629 for (i
= 0; i
<= ARM_PC
; i
++)
631 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
632 armv4_5
->core_mode
, i
).value
,
634 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
635 armv4_5
->core_mode
, i
).valid
= 1;
636 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
637 armv4_5
->core_mode
, i
).dirty
= 0;
639 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
640 armv4_5
->core_mode
, 16).value
,
642 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
643 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
645 /* Fixup PC Resume Address */
646 if (armv7a
->core_state
== ARMV7A_STATE_THUMB
)
648 // T bit set for Thumb or ThumbEE state
649 regfile
[ARM_PC
] -= 4;
654 regfile
[ARM_PC
] -= 8;
656 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
657 armv4_5
->core_mode
, ARM_PC
).value
,
658 0, 32, regfile
[ARM_PC
]);
660 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 0)
661 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
662 armv4_5
->core_mode
, 0).valid
;
663 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 15)
664 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
665 armv4_5
->core_mode
, 15).valid
;
668 /* TODO, Move this */
669 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
670 cortex_a8_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
671 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
673 cortex_a8_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
674 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
676 cortex_a8_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
677 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
680 /* Are we in an exception handler */
681 // armv4_5->exception_number = 0;
682 if (armv7a
->post_debug_entry
)
683 armv7a
->post_debug_entry(target
);
691 static void cortex_a8_post_debug_entry(target_t
*target
)
693 struct cortex_a8_common_s
*cortex_a8
= target_to_cortex_a8(target
);
694 struct armv7a_common_s
*armv7a
= &cortex_a8
->armv7a_common
;
696 // cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
697 /* examine cp15 control reg */
698 armv7a
->read_cp15(target
, 0, 0, 1, 0, &cortex_a8
->cp15_control_reg
);
699 jtag_execute_queue();
700 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
702 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
704 uint32_t cache_type_reg
;
705 /* identify caches */
706 armv7a
->read_cp15(target
, 0, 1, 0, 0, &cache_type_reg
);
707 jtag_execute_queue();
708 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
709 armv4_5_identify_cache(cache_type_reg
,
710 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
713 armv7a
->armv4_5_mmu
.mmu_enabled
=
714 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
715 armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
=
716 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
717 armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
=
718 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
723 static int cortex_a8_step(struct target_s
*target
, int current
, uint32_t address
,
724 int handle_breakpoints
)
726 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
727 struct armv4_5_common_s
*armv4_5
= &armv7a
->armv4_5_common
;
728 breakpoint_t
*breakpoint
= NULL
;
729 breakpoint_t stepbreakpoint
;
733 if (target
->state
!= TARGET_HALTED
)
735 LOG_WARNING("target not halted");
736 return ERROR_TARGET_NOT_HALTED
;
739 /* current = 1: continue on current pc, otherwise continue at <address> */
742 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
743 armv4_5
->core_mode
, ARM_PC
).value
,
748 address
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
749 armv4_5
->core_mode
, ARM_PC
).value
,
753 /* The front-end may request us not to handle breakpoints.
754 * But since Cortex-A8 uses breakpoint for single step,
755 * we MUST handle breakpoints.
757 handle_breakpoints
= 1;
758 if (handle_breakpoints
) {
759 breakpoint
= breakpoint_find(target
,
760 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
761 armv4_5
->core_mode
, 15).value
,
764 cortex_a8_unset_breakpoint(target
, breakpoint
);
767 /* Setup single step breakpoint */
768 stepbreakpoint
.address
= address
;
769 stepbreakpoint
.length
= (armv7a
->core_state
== ARMV7A_STATE_THUMB
) ? 2 : 4;
770 stepbreakpoint
.type
= BKPT_HARD
;
771 stepbreakpoint
.set
= 0;
773 /* Break on IVA mismatch */
774 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
776 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
778 cortex_a8_resume(target
, 1, address
, 0, 0);
780 while (target
->state
!= TARGET_HALTED
)
782 cortex_a8_poll(target
);
785 LOG_WARNING("timeout waiting for target halt");
790 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
791 if (timeout
> 0) target
->debug_reason
= DBG_REASON_BREAKPOINT
;
794 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
796 if (target
->state
!= TARGET_HALTED
)
797 LOG_DEBUG("target stepped");
802 static int cortex_a8_restore_context(target_t
*target
)
806 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
807 struct armv4_5_common_s
*armv4_5
= &armv7a
->armv4_5_common
;
811 if (armv7a
->pre_restore_context
)
812 armv7a
->pre_restore_context(target
);
814 for (i
= 15; i
>= 0; i
--)
816 if (ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
817 armv4_5
->core_mode
, i
).dirty
)
819 value
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
820 armv4_5
->core_mode
, i
).value
,
822 /* TODO Check return values */
823 cortex_a8_dap_write_coreregister_u32(target
, value
, i
);
827 if (armv7a
->post_restore_context
)
828 armv7a
->post_restore_context(target
);
836 * Cortex-A8 Core register functions
838 static int cortex_a8_load_core_reg_u32(struct target_s
*target
, int num
,
839 armv4_5_mode_t mode
, uint32_t * value
)
842 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
844 if ((num
<= ARM_CPSR
))
846 /* read a normal core register */
847 retval
= cortex_a8_dap_read_coreregister_u32(target
, value
, num
);
849 if (retval
!= ERROR_OK
)
851 LOG_ERROR("JTAG failure %i", retval
);
852 return ERROR_JTAG_DEVICE_ERROR
;
854 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
, num
, *value
);
858 return ERROR_INVALID_ARGUMENTS
;
861 /* Register other than r0 - r14 uses r0 for access */
863 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
864 armv4_5
->core_mode
, 0).dirty
=
865 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
866 armv4_5
->core_mode
, 0).valid
;
867 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
868 armv4_5
->core_mode
, 15).dirty
=
869 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
870 armv4_5
->core_mode
, 15).valid
;
875 static int cortex_a8_store_core_reg_u32(struct target_s
*target
, int num
,
876 armv4_5_mode_t mode
, uint32_t value
)
880 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
882 #ifdef ARMV7_GDB_HACKS
883 /* If the LR register is being modified, make sure it will put us
884 * in "thumb" mode, or an INVSTATE exception will occur. This is a
885 * hack to deal with the fact that gdb will sometimes "forge"
886 * return addresses, and doesn't set the LSB correctly (i.e., when
887 * printing expressions containing function calls, it sets LR=0.) */
893 if ((num
<= ARM_CPSR
))
895 retval
= cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
896 if (retval
!= ERROR_OK
)
898 LOG_ERROR("JTAG failure %i", retval
);
899 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
900 armv4_5
->core_mode
, num
).dirty
=
901 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
902 armv4_5
->core_mode
, num
).valid
;
903 return ERROR_JTAG_DEVICE_ERROR
;
905 LOG_DEBUG("write core reg %i value 0x%" PRIx32
, num
, value
);
909 return ERROR_INVALID_ARGUMENTS
;
917 static int cortex_a8_read_core_reg(struct target_s
*target
, int num
,
918 enum armv4_5_mode mode
)
922 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
924 cortex_a8_dap_read_coreregister_u32(target
, &value
, num
);
926 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
931 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
932 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
933 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
934 mode
, num
).value
, 0, 32, value
);
939 int cortex_a8_write_core_reg(struct target_s
*target
, int num
,
940 enum armv4_5_mode mode
, uint32_t value
)
943 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
945 cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
946 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
951 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
952 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
959 * Cortex-A8 Breakpoint and watchpoint fuctions
962 /* Setup hardware Breakpoint Register Pair */
963 static int cortex_a8_set_breakpoint(struct target_s
*target
,
964 breakpoint_t
*breakpoint
, uint8_t matchmode
)
969 uint8_t byte_addr_select
= 0x0F;
970 struct cortex_a8_common_s
*cortex_a8
= target_to_cortex_a8(target
);
971 struct armv7a_common_s
*armv7a
= &cortex_a8
->armv7a_common
;
972 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
976 LOG_WARNING("breakpoint already set");
980 if (breakpoint
->type
== BKPT_HARD
)
982 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
984 if (brp_i
>= cortex_a8
->brp_num
)
986 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
989 breakpoint
->set
= brp_i
+ 1;
990 if (breakpoint
->length
== 2)
992 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
994 control
= ((matchmode
& 0x7) << 20)
995 | (byte_addr_select
<< 5)
997 brp_list
[brp_i
].used
= 1;
998 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
999 brp_list
[brp_i
].control
= control
;
1000 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1001 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1002 brp_list
[brp_i
].value
);
1003 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1004 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1005 brp_list
[brp_i
].control
);
1006 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1007 brp_list
[brp_i
].control
,
1008 brp_list
[brp_i
].value
);
1010 else if (breakpoint
->type
== BKPT_SOFT
)
1013 if (breakpoint
->length
== 2)
1015 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1019 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1021 retval
= target
->type
->read_memory(target
,
1022 breakpoint
->address
& 0xFFFFFFFE,
1023 breakpoint
->length
, 1,
1024 breakpoint
->orig_instr
);
1025 if (retval
!= ERROR_OK
)
1027 retval
= target
->type
->write_memory(target
,
1028 breakpoint
->address
& 0xFFFFFFFE,
1029 breakpoint
->length
, 1, code
);
1030 if (retval
!= ERROR_OK
)
1032 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1038 static int cortex_a8_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1041 struct cortex_a8_common_s
*cortex_a8
= target_to_cortex_a8(target
);
1042 struct armv7a_common_s
*armv7a
= &cortex_a8
->armv7a_common
;
1043 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
1045 if (!breakpoint
->set
)
1047 LOG_WARNING("breakpoint not set");
1051 if (breakpoint
->type
== BKPT_HARD
)
1053 int brp_i
= breakpoint
->set
- 1;
1054 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1056 LOG_DEBUG("Invalid BRP number in breakpoint");
1059 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1060 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1061 brp_list
[brp_i
].used
= 0;
1062 brp_list
[brp_i
].value
= 0;
1063 brp_list
[brp_i
].control
= 0;
1064 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1065 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1066 brp_list
[brp_i
].control
);
1067 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1068 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1069 brp_list
[brp_i
].value
);
1073 /* restore original instruction (kept in target endianness) */
1074 if (breakpoint
->length
== 4)
1076 retval
= target
->type
->write_memory(target
,
1077 breakpoint
->address
& 0xFFFFFFFE,
1078 4, 1, breakpoint
->orig_instr
);
1079 if (retval
!= ERROR_OK
)
1084 retval
= target
->type
->write_memory(target
,
1085 breakpoint
->address
& 0xFFFFFFFE,
1086 2, 1, breakpoint
->orig_instr
);
1087 if (retval
!= ERROR_OK
)
1091 breakpoint
->set
= 0;
1096 int cortex_a8_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1098 struct cortex_a8_common_s
*cortex_a8
= target_to_cortex_a8(target
);
1100 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1102 LOG_INFO("no hardware breakpoint available");
1103 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1106 if (breakpoint
->type
== BKPT_HARD
)
1107 cortex_a8
->brp_num_available
--;
1108 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1113 static int cortex_a8_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1115 struct cortex_a8_common_s
*cortex_a8
= target_to_cortex_a8(target
);
1118 /* It is perfectly possible to remove brakpoints while the taget is running */
1119 if (target
->state
!= TARGET_HALTED
)
1121 LOG_WARNING("target not halted");
1122 return ERROR_TARGET_NOT_HALTED
;
1126 if (breakpoint
->set
)
1128 cortex_a8_unset_breakpoint(target
, breakpoint
);
1129 if (breakpoint
->type
== BKPT_HARD
)
1130 cortex_a8
->brp_num_available
++ ;
1140 * Cortex-A8 Reset fuctions
1143 static int cortex_a8_assert_reset(target_t
*target
)
1148 /* registers are now invalid */
1149 armv4_5_invalidate_core_regs(target
);
1151 target
->state
= TARGET_RESET
;
1156 static int cortex_a8_deassert_reset(target_t
*target
)
1161 if (target
->reset_halt
)
1164 if ((retval
= target_halt(target
)) != ERROR_OK
)
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 static int cortex_a8_read_memory(struct target_s
*target
, uint32_t address
,
1179 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1181 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
1182 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1184 int retval
= ERROR_OK
;
1186 /* sanitize arguments */
1187 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1188 return ERROR_INVALID_ARGUMENTS
;
1190 /* cortex_a8 handles unaligned memory access */
1192 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1197 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1200 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1203 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1206 LOG_ERROR("BUG: we shouldn't get here");
1213 int cortex_a8_write_memory(struct target_s
*target
, uint32_t address
,
1214 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1216 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
1217 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1221 /* sanitize arguments */
1222 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1223 return ERROR_INVALID_ARGUMENTS
;
1225 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1230 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1233 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1236 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1239 LOG_ERROR("BUG: we shouldn't get here");
1243 if (target
->state
== TARGET_HALTED
)
1245 /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */
1246 /* invalidate I-Cache */
1247 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
1249 /* Invalidate ICache single entry with MVA, repeat this for all cache
1250 lines in the address range, Cortex-A8 has fixed 64 byte line length */
1251 /* Invalidate Cache single entry with MVA to PoU */
1252 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1253 armv7a
->write_cp15(target
, 0, 1, 7, 5, cacheline
); /* I-Cache to PoU */
1255 /* invalidate D-Cache */
1256 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
1258 /* Invalidate Cache single entry with MVA to PoC */
1259 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1260 armv7a
->write_cp15(target
, 0, 1, 7, 6, cacheline
); /* U/D cache to PoC */
1267 static int cortex_a8_bulk_write_memory(target_t
*target
, uint32_t address
,
1268 uint32_t count
, uint8_t *buffer
)
1270 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1274 static int cortex_a8_dcc_read(swjdp_common_t
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1279 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1280 *ctrl
= (uint8_t)dcrdr
;
1281 *value
= (uint8_t)(dcrdr
>> 8);
1283 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1285 /* write ack back to software dcc register
1286 * signify we have read data */
1287 if (dcrdr
& (1 << 0))
1290 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1297 static int cortex_a8_handle_target_request(void *priv
)
1299 target_t
*target
= priv
;
1300 if (!target
->type
->examined
)
1302 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
1303 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1305 if (!target
->dbg_msg_enabled
)
1308 if (target
->state
== TARGET_RUNNING
)
1313 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1315 /* check if we have data */
1316 if (ctrl
& (1 << 0))
1320 /* we assume target is quick enough */
1322 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1323 request
|= (data
<< 8);
1324 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1325 request
|= (data
<< 16);
1326 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1327 request
|= (data
<< 24);
1328 target_request(target
, request
);
1336 * Cortex-A8 target information and configuration
1339 static int cortex_a8_examine(struct target_s
*target
)
1341 struct cortex_a8_common_s
*cortex_a8
= target_to_cortex_a8(target
);
1342 struct armv7a_common_s
*armv7a
= &cortex_a8
->armv7a_common
;
1343 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1345 int retval
= ERROR_OK
;
1346 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1350 /* Here we shall insert a proper ROM Table scan */
1351 armv7a
->debug_base
= OMAP3530_DEBUG_BASE
;
1353 /* We do one extra read to ensure DAP is configured,
1354 * we call ahbap_debugport_init(swjdp) instead
1356 ahbap_debugport_init(swjdp
);
1357 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
1358 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1359 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1361 LOG_DEBUG("Examine failed");
1365 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1366 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1368 LOG_DEBUG("Examine failed");
1372 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1373 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1375 LOG_DEBUG("Examine failed");
1379 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1380 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1382 LOG_DEBUG("Examine failed");
1386 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1387 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1388 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1389 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1391 /* Setup Breakpoint Register Pairs */
1392 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1393 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1394 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1395 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(cortex_a8_brp_t
));
1396 // cortex_a8->brb_enabled = ????;
1397 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1399 cortex_a8
->brp_list
[i
].used
= 0;
1400 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1401 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1403 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1404 cortex_a8
->brp_list
[i
].value
= 0;
1405 cortex_a8
->brp_list
[i
].control
= 0;
1406 cortex_a8
->brp_list
[i
].BRPn
= i
;
1409 /* Setup Watchpoint Register Pairs */
1410 cortex_a8
->wrp_num
= ((didr
>> 28) & 0x0F) + 1;
1411 cortex_a8
->wrp_num_available
= cortex_a8
->wrp_num
;
1412 cortex_a8
->wrp_list
= calloc(cortex_a8
->wrp_num
, sizeof(cortex_a8_wrp_t
));
1413 for (i
= 0; i
< cortex_a8
->wrp_num
; i
++)
1415 cortex_a8
->wrp_list
[i
].used
= 0;
1416 cortex_a8
->wrp_list
[i
].type
= 0;
1417 cortex_a8
->wrp_list
[i
].value
= 0;
1418 cortex_a8
->wrp_list
[i
].control
= 0;
1419 cortex_a8
->wrp_list
[i
].WRPn
= i
;
1421 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1422 cortex_a8
->brp_num
, cortex_a8
->wrp_num
);
1424 /* Configure core debug access */
1425 cortex_a8_init_debug_access(target
);
1427 target
->type
->examined
= 1;
1433 * Cortex-A8 target creation and initialization
1436 static void cortex_a8_build_reg_cache(target_t
*target
)
1438 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1439 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
1441 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
1442 armv4_5
->core_cache
= (*cache_p
);
1446 static int cortex_a8_init_target(struct command_context_s
*cmd_ctx
,
1447 struct target_s
*target
)
1449 cortex_a8_build_reg_cache(target
);
1453 int cortex_a8_init_arch_info(target_t
*target
,
1454 cortex_a8_common_t
*cortex_a8
, struct jtag_tap
*tap
)
1456 armv4_5_common_t
*armv4_5
;
1457 armv7a_common_t
*armv7a
;
1459 armv7a
= &cortex_a8
->armv7a_common
;
1460 armv4_5
= &armv7a
->armv4_5_common
;
1461 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1463 /* Setup cortex_a8_common_t */
1464 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1465 armv4_5
->arch_info
= armv7a
;
1467 armv4_5_init_arch_info(target
, armv4_5
);
1469 /* prepare JTAG information for the new target */
1470 cortex_a8
->jtag_info
.tap
= tap
;
1471 cortex_a8
->jtag_info
.scann_size
= 4;
1473 swjdp
->dp_select_value
= -1;
1474 swjdp
->ap_csw_value
= -1;
1475 swjdp
->ap_tar_value
= -1;
1476 swjdp
->jtag_info
= &cortex_a8
->jtag_info
;
1477 swjdp
->memaccess_tck
= 80;
1479 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1480 swjdp
->tar_autoincr_block
= (1 << 10);
1482 cortex_a8
->fast_reg_read
= 0;
1485 /* register arch-specific functions */
1486 armv7a
->examine_debug_reason
= NULL
;
1488 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1490 armv7a
->pre_restore_context
= NULL
;
1491 armv7a
->post_restore_context
= NULL
;
1492 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1493 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1494 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_memory
;
1495 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_memory
;
1496 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1497 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1498 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1499 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1500 armv7a
->read_cp15
= cortex_a8_read_cp15
;
1501 armv7a
->write_cp15
= cortex_a8_write_cp15
;
1504 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1506 armv4_5
->read_core_reg
= cortex_a8_read_core_reg
;
1507 armv4_5
->write_core_reg
= cortex_a8_write_core_reg
;
1508 // armv4_5->full_context = arm7_9_full_context;
1510 // armv4_5->load_core_reg_u32 = cortex_a8_load_core_reg_u32;
1511 // armv4_5->store_core_reg_u32 = cortex_a8_store_core_reg_u32;
1512 // armv4_5->read_core_reg = armv4_5_read_core_reg; /* this is default */
1513 // armv4_5->write_core_reg = armv4_5_write_core_reg;
1515 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1520 static int cortex_a8_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1522 cortex_a8_common_t
*cortex_a8
= calloc(1, sizeof(cortex_a8_common_t
));
1524 cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1529 COMMAND_HANDLER(cortex_a8_handle_cache_info_command
)
1531 target_t
*target
= get_current_target(cmd_ctx
);
1532 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
1534 return armv4_5_handle_cache_info_command(cmd_ctx
,
1535 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1539 COMMAND_HANDLER(cortex_a8_handle_dbginit_command
)
1541 target_t
*target
= get_current_target(cmd_ctx
);
1543 cortex_a8_init_debug_access(target
);
1549 static int cortex_a8_register_commands(struct command_context_s
*cmd_ctx
)
1551 command_t
*cortex_a8_cmd
;
1552 int retval
= ERROR_OK
;
1554 armv4_5_register_commands(cmd_ctx
);
1555 armv7a_register_commands(cmd_ctx
);
1557 cortex_a8_cmd
= register_command(cmd_ctx
, NULL
, "cortex_a8",
1559 "cortex_a8 specific commands");
1561 register_command(cmd_ctx
, cortex_a8_cmd
, "cache_info",
1562 cortex_a8_handle_cache_info_command
, COMMAND_EXEC
,
1563 "display information about target caches");
1565 register_command(cmd_ctx
, cortex_a8_cmd
, "dbginit",
1566 cortex_a8_handle_dbginit_command
, COMMAND_EXEC
,
1567 "Initialize core debug");
1572 target_type_t cortexa8_target
= {
1573 .name
= "cortex_a8",
1575 .poll
= cortex_a8_poll
,
1576 .arch_state
= armv7a_arch_state
,
1578 .target_request_data
= NULL
,
1580 .halt
= cortex_a8_halt
,
1581 .resume
= cortex_a8_resume
,
1582 .step
= cortex_a8_step
,
1584 .assert_reset
= cortex_a8_assert_reset
,
1585 .deassert_reset
= cortex_a8_deassert_reset
,
1586 .soft_reset_halt
= NULL
,
1588 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
1590 .read_memory
= cortex_a8_read_memory
,
1591 .write_memory
= cortex_a8_write_memory
,
1592 .bulk_write_memory
= cortex_a8_bulk_write_memory
,
1593 .checksum_memory
= arm7_9_checksum_memory
,
1594 .blank_check_memory
= arm7_9_blank_check_memory
,
1596 .run_algorithm
= armv4_5_run_algorithm
,
1598 .add_breakpoint
= cortex_a8_add_breakpoint
,
1599 .remove_breakpoint
= cortex_a8_remove_breakpoint
,
1600 .add_watchpoint
= NULL
,
1601 .remove_watchpoint
= NULL
,
1603 .register_commands
= cortex_a8_register_commands
,
1604 .target_create
= cortex_a8_target_create
,
1605 .init_target
= cortex_a8_init_target
,
1606 .examine
= cortex_a8_examine
,
1607 .mrc
= cortex_a8_mrc
,
1608 .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)