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, Rn, c0, c5, 0" 0xEE00nE15 */
246 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, reg
, 0, 5, 0));
250 /* "MOV r0, r15"; then move r0 to DCCTX */
251 cortex_a8_exec_opcode(target
, 0xE1A0000F);
252 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
256 /* "MRS r0, CPSR" or "MRS r0, SPSR"
257 * then move r0 to DCCTX
259 cortex_a8_exec_opcode(target
, ARMV4_5_MRS(0, reg
& 1));
260 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
266 retval
= mem_ap_read_atomic_u32(swjdp
,
267 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
269 while ((dscr
& (1 << DSCR_DTR_TX_FULL
)) == 0); /* Wait for DTRRXfull */
271 retval
= mem_ap_read_atomic_u32(swjdp
,
272 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
273 LOG_DEBUG("read DCC 0x%08" PRIx32
, *value
);
278 static int cortex_a8_dap_write_coreregister_u32(struct target
*target
,
279 uint32_t value
, int regnum
)
281 int retval
= ERROR_OK
;
282 uint8_t Rd
= regnum
&0xFF;
284 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
285 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
287 LOG_DEBUG("register %i, value 0x%08" PRIx32
, regnum
, value
);
289 /* Check that DCCRX is not full */
290 retval
= mem_ap_read_atomic_u32(swjdp
,
291 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
292 if (dscr
& (1 << DSCR_DTR_RX_FULL
))
294 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
295 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
296 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
303 LOG_DEBUG("write DCC 0x%08" PRIx32
, value
);
304 retval
= mem_ap_write_u32(swjdp
,
305 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
309 /* DCCRX to Rn, "MCR p14, 0, Rn, c0, c5, 0", 0xEE00nE15 */
310 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, Rd
, 0, 5, 0));
314 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15
317 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
318 cortex_a8_exec_opcode(target
, 0xE1A0F000);
322 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15
323 * then "MSR CPSR_cxsf, r0" or "MSR SPSR_cxsf, r0" (all fields)
325 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
326 cortex_a8_exec_opcode(target
, ARMV4_5_MSR_GP(0, 0xF, Rd
& 1));
328 /* "Prefetch flush" after modifying execution status in CPSR */
330 cortex_a8_exec_opcode(target
,
331 ARMV4_5_MCR(15, 0, 0, 7, 5, 4));
337 /* Write to memory mapped registers directly with no cache or mmu handling */
338 static int cortex_a8_dap_write_memap_register_u32(struct target
*target
, uint32_t address
, uint32_t value
)
341 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
342 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
344 retval
= mem_ap_write_atomic_u32(swjdp
, address
, value
);
350 * Cortex-A8 Run control
353 static int cortex_a8_poll(struct target
*target
)
355 int retval
= ERROR_OK
;
357 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
358 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
359 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
360 enum target_state prev_target_state
= target
->state
;
361 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
363 dap_ap_select(swjdp
, swjdp_debugap
);
364 retval
= mem_ap_read_atomic_u32(swjdp
,
365 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
366 if (retval
!= ERROR_OK
)
368 dap_ap_select(swjdp
, saved_apsel
);
371 cortex_a8
->cpudbg_dscr
= dscr
;
373 if ((dscr
& 0x3) == 0x3)
375 if (prev_target_state
!= TARGET_HALTED
)
377 /* We have a halting debug event */
378 LOG_DEBUG("Target halted");
379 target
->state
= TARGET_HALTED
;
380 if ((prev_target_state
== TARGET_RUNNING
)
381 || (prev_target_state
== TARGET_RESET
))
383 retval
= cortex_a8_debug_entry(target
);
384 if (retval
!= ERROR_OK
)
387 target_call_event_callbacks(target
,
388 TARGET_EVENT_HALTED
);
390 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
394 retval
= cortex_a8_debug_entry(target
);
395 if (retval
!= ERROR_OK
)
398 target_call_event_callbacks(target
,
399 TARGET_EVENT_DEBUG_HALTED
);
403 else if ((dscr
& 0x3) == 0x2)
405 target
->state
= TARGET_RUNNING
;
409 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32
, dscr
);
410 target
->state
= TARGET_UNKNOWN
;
413 dap_ap_select(swjdp
, saved_apsel
);
418 static int cortex_a8_halt(struct target
*target
)
420 int retval
= ERROR_OK
;
422 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
423 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
424 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
425 dap_ap_select(swjdp
, swjdp_debugap
);
428 * Tell the core to be halted by writing DRCR with 0x1
429 * and then wait for the core to be halted.
431 retval
= mem_ap_write_atomic_u32(swjdp
,
432 armv7a
->debug_base
+ CPUDBG_DRCR
, 0x1);
435 * enter halting debug mode
437 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
438 retval
= mem_ap_write_atomic_u32(swjdp
,
439 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
| (1 << DSCR_HALT_DBG_MODE
));
441 if (retval
!= ERROR_OK
)
445 mem_ap_read_atomic_u32(swjdp
,
446 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
447 } while ((dscr
& (1 << DSCR_CORE_HALTED
)) == 0);
449 target
->debug_reason
= DBG_REASON_DBGRQ
;
452 dap_ap_select(swjdp
, saved_apsel
);
456 static int cortex_a8_resume(struct target
*target
, int current
,
457 uint32_t address
, int handle_breakpoints
, int debug_execution
)
459 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
460 struct armv4_5_common_s
*armv4_5
= &armv7a
->armv4_5_common
;
461 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
463 // struct breakpoint *breakpoint = NULL;
464 uint32_t resume_pc
, dscr
;
466 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
467 dap_ap_select(swjdp
, swjdp_debugap
);
469 if (!debug_execution
)
471 target_free_all_working_areas(target
);
472 // cortex_m3_enable_breakpoints(target);
473 // cortex_m3_enable_watchpoints(target);
479 /* Disable interrupts */
480 /* We disable interrupts in the PRIMASK register instead of
481 * masking with C_MASKINTS,
482 * This is probably the same issue as Cortex-M3 Errata 377493:
483 * C_MASKINTS in parallel with disabled interrupts can cause
484 * local faults to not be taken. */
485 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
486 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
487 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
489 /* Make sure we are in Thumb mode */
490 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
491 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
492 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
493 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
497 /* current = 1: continue on current pc, otherwise continue at <address> */
498 resume_pc
= buf_get_u32(
499 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
,
500 armv4_5
->core_mode
, 15).value
,
505 /* Make sure that the Armv7 gdb thumb fixups does not
506 * kill the return address
508 switch (armv4_5
->core_state
)
510 case ARMV4_5_STATE_ARM
:
511 resume_pc
&= 0xFFFFFFFC;
513 case ARMV4_5_STATE_THUMB
:
514 case ARM_STATE_THUMB_EE
:
515 /* When the return address is loaded into PC
516 * bit 0 must be 1 to stay in Thumb state
520 case ARMV4_5_STATE_JAZELLE
:
521 LOG_ERROR("How do I resume into Jazelle state??");
524 LOG_DEBUG("resume pc = 0x%08" PRIx32
, resume_pc
);
525 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
,
526 armv4_5
->core_mode
, 15).value
,
528 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
,
529 armv4_5
->core_mode
, 15).dirty
= 1;
530 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
,
531 armv4_5
->core_mode
, 15).valid
= 1;
533 cortex_a8_restore_context(target
);
536 /* the front-end may request us not to handle breakpoints */
537 if (handle_breakpoints
)
539 /* Single step past breakpoint at current address */
540 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
542 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
543 cortex_m3_unset_breakpoint(target
, breakpoint
);
544 cortex_m3_single_step_core(target
);
545 cortex_m3_set_breakpoint(target
, breakpoint
);
550 /* Restart core and wait for it to be started */
551 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DRCR
, 0x2);
554 mem_ap_read_atomic_u32(swjdp
,
555 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
556 } while ((dscr
& (1 << DSCR_CORE_RESTARTED
)) == 0);
558 target
->debug_reason
= DBG_REASON_NOTHALTED
;
559 target
->state
= TARGET_RUNNING
;
561 /* registers are now invalid */
562 register_cache_invalidate(armv4_5
->core_cache
);
564 if (!debug_execution
)
566 target
->state
= TARGET_RUNNING
;
567 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
568 LOG_DEBUG("target resumed at 0x%" PRIx32
, resume_pc
);
572 target
->state
= TARGET_DEBUG_RUNNING
;
573 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
574 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, resume_pc
);
577 dap_ap_select(swjdp
, saved_apsel
);
582 static int cortex_a8_debug_entry(struct target
*target
)
585 uint32_t regfile
[16], pc
, cpsr
, dscr
;
586 int retval
= ERROR_OK
;
587 struct working_area
*regfile_working_area
= NULL
;
588 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
589 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
590 struct armv4_5_common_s
*armv4_5
= &armv7a
->armv4_5_common
;
591 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
594 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
596 /* Enable the ITR execution once we are in debug mode */
597 mem_ap_read_atomic_u32(swjdp
,
598 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
599 dscr
|= (1 << DSCR_EXT_INT_EN
);
600 retval
= mem_ap_write_atomic_u32(swjdp
,
601 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
);
603 /* Examine debug reason */
604 switch ((cortex_a8
->cpudbg_dscr
>> 2)&0xF)
608 target
->debug_reason
= DBG_REASON_DBGRQ
;
612 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
615 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
618 target
->debug_reason
= DBG_REASON_UNDEFINED
;
622 /* Examine target state and mode */
623 if (cortex_a8
->fast_reg_read
)
624 target_alloc_working_area(target
, 64, ®file_working_area
);
626 /* First load register acessible through core debug port*/
627 if (!regfile_working_area
)
629 /* FIXME we don't actually need all these registers;
630 * reading them slows us down. Just R0, PC, CPSR...
632 for (i
= 0; i
<= 15; i
++)
633 cortex_a8_dap_read_coreregister_u32(target
,
638 dap_ap_select(swjdp
, swjdp_memoryap
);
639 cortex_a8_read_regs_through_mem(target
,
640 regfile_working_area
->address
, regfile
);
641 dap_ap_select(swjdp
, swjdp_memoryap
);
642 target_free_working_area(target
, regfile_working_area
);
645 /* read Current PSR */
646 cortex_a8_dap_read_coreregister_u32(target
, &cpsr
, 16);
648 dap_ap_select(swjdp
, swjdp_debugap
);
649 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
651 armv4_5
->core_mode
= cpsr
& 0x1F;
653 i
= (cpsr
>> 5) & 1; /* T */
654 i
|= (cpsr
>> 23) & 1; /* J << 1 */
656 case 0: /* J = 0, T = 0 */
657 armv4_5
->core_state
= ARMV4_5_STATE_ARM
;
659 case 1: /* J = 0, T = 1 */
660 armv4_5
->core_state
= ARMV4_5_STATE_THUMB
;
662 case 2: /* J = 1, T = 0 */
663 LOG_WARNING("Jazelle state -- not handled");
664 armv4_5
->core_state
= ARMV4_5_STATE_JAZELLE
;
666 case 3: /* J = 1, T = 1 */
667 /* ThumbEE is very much like Thumb, but some of the
668 * instructions are different. Single stepping and
669 * breakpoints need updating...
671 LOG_WARNING("ThumbEE -- incomplete support");
672 armv4_5
->core_state
= ARM_STATE_THUMB_EE
;
678 buf_set_u32(reg
->value
, 0, 32, cpsr
);
682 for (i
= 0; i
<= ARM_PC
; i
++)
684 reg
= &ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
,
685 armv4_5
->core_mode
, i
);
687 buf_set_u32(reg
->value
, 0, 32, regfile
[i
]);
692 /* Fixup PC Resume Address */
695 // T bit set for Thumb or ThumbEE state
696 regfile
[ARM_PC
] -= 4;
701 regfile
[ARM_PC
] -= 8;
703 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
,
704 armv4_5
->core_mode
, ARM_PC
).value
,
705 0, 32, regfile
[ARM_PC
]);
707 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 0)
708 .dirty
= ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
,
709 armv4_5
->core_mode
, 0).valid
;
710 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 15)
711 .dirty
= ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
,
712 armv4_5
->core_mode
, 15).valid
;
715 /* TODO, Move this */
716 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
717 cortex_a8_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
718 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
720 cortex_a8_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
721 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
723 cortex_a8_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
724 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
727 /* Are we in an exception handler */
728 // armv4_5->exception_number = 0;
729 if (armv7a
->post_debug_entry
)
730 armv7a
->post_debug_entry(target
);
738 static void cortex_a8_post_debug_entry(struct target
*target
)
740 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
741 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
743 // cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
744 /* examine cp15 control reg */
745 armv7a
->read_cp15(target
, 0, 0, 1, 0, &cortex_a8
->cp15_control_reg
);
746 jtag_execute_queue();
747 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
749 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
751 uint32_t cache_type_reg
;
752 /* identify caches */
753 armv7a
->read_cp15(target
, 0, 1, 0, 0, &cache_type_reg
);
754 jtag_execute_queue();
755 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
756 armv4_5_identify_cache(cache_type_reg
,
757 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
760 armv7a
->armv4_5_mmu
.mmu_enabled
=
761 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
762 armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
=
763 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
764 armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
=
765 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
770 static int cortex_a8_step(struct target
*target
, int current
, uint32_t address
,
771 int handle_breakpoints
)
773 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
774 struct armv4_5_common_s
*armv4_5
= &armv7a
->armv4_5_common
;
775 struct breakpoint
*breakpoint
= NULL
;
776 struct breakpoint stepbreakpoint
;
780 if (target
->state
!= TARGET_HALTED
)
782 LOG_WARNING("target not halted");
783 return ERROR_TARGET_NOT_HALTED
;
786 /* current = 1: continue on current pc, otherwise continue at <address> */
789 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
,
790 armv4_5
->core_mode
, ARM_PC
).value
,
795 address
= buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
,
796 armv4_5
->core_mode
, ARM_PC
).value
,
800 /* The front-end may request us not to handle breakpoints.
801 * But since Cortex-A8 uses breakpoint for single step,
802 * we MUST handle breakpoints.
804 handle_breakpoints
= 1;
805 if (handle_breakpoints
) {
806 breakpoint
= breakpoint_find(target
,
807 buf_get_u32(ARMV4_5_CORE_REG_MODE(
809 armv4_5
->core_mode
, 15).value
,
812 cortex_a8_unset_breakpoint(target
, breakpoint
);
815 /* Setup single step breakpoint */
816 stepbreakpoint
.address
= address
;
817 stepbreakpoint
.length
= (armv4_5
->core_state
== ARMV4_5_STATE_THUMB
)
819 stepbreakpoint
.type
= BKPT_HARD
;
820 stepbreakpoint
.set
= 0;
822 /* Break on IVA mismatch */
823 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
825 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
827 cortex_a8_resume(target
, 1, address
, 0, 0);
829 while (target
->state
!= TARGET_HALTED
)
831 cortex_a8_poll(target
);
834 LOG_WARNING("timeout waiting for target halt");
839 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
840 if (timeout
> 0) target
->debug_reason
= DBG_REASON_BREAKPOINT
;
843 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
845 if (target
->state
!= TARGET_HALTED
)
846 LOG_DEBUG("target stepped");
851 static int cortex_a8_restore_context(struct target
*target
)
854 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
855 struct reg_cache
*cache
= armv7a
->armv4_5_common
.core_cache
;
856 unsigned max
= cache
->num_regs
;
858 bool flushed
, flush_cpsr
= false;
862 if (armv7a
->pre_restore_context
)
863 armv7a
->pre_restore_context(target
);
865 /* Flush all dirty registers from the cache, one mode at a time so
866 * that we write CPSR as little as possible. Save CPSR and R0 for
867 * last; they're used to change modes and write other registers.
869 * REVISIT be smarter: save eventual mode for last loop, don't
870 * need to write CPSR an extra time.
873 enum armv4_5_mode mode
= ARMV4_5_MODE_ANY
;
878 /* write dirty non-{R0,CPSR} registers sharing the same mode */
879 for (i
= max
- 1, r
= cache
->reg_list
+ 1; i
> 0; i
--, r
++) {
882 if (!r
->dirty
|| r
== armv7a
->armv4_5_common
.cpsr
)
886 /* TODO Check return values */
888 /* Pick a mode and update CPSR; else ignore this
889 * register if it's for a different mode than what
890 * we're handling on this pass.
892 * REVISIT don't distinguish SYS and USR modes.
894 * FIXME if we restore from FIQ mode, R8..R12 will
895 * get wrongly flushed onto FIQ shadows...
897 if (mode
== ARMV4_5_MODE_ANY
) {
899 if (mode
!= ARMV4_5_MODE_ANY
) {
900 cortex_a8_dap_write_coreregister_u32(
904 } else if (mode
!= reg
->mode
)
907 /* Write this register */
908 value
= buf_get_u32(r
->value
, 0, 32);
909 cortex_a8_dap_write_coreregister_u32(target
, value
,
910 (reg
->num
== 16) ? 17 : reg
->num
);
917 /* now flush CPSR if needed ... */
918 r
= armv7a
->armv4_5_common
.cpsr
;
919 if (flush_cpsr
|| r
->dirty
) {
920 value
= buf_get_u32(r
->value
, 0, 32);
921 cortex_a8_dap_write_coreregister_u32(target
, value
, 16);
925 /* ... and R0 always (it was dirtied when we saved context) */
926 r
= cache
->reg_list
+ 0;
927 value
= buf_get_u32(r
->value
, 0, 32);
928 cortex_a8_dap_write_coreregister_u32(target
, value
, 0);
931 if (armv7a
->post_restore_context
)
932 armv7a
->post_restore_context(target
);
940 * Cortex-A8 Core register functions
942 static int cortex_a8_load_core_reg_u32(struct target
*target
, int num
,
943 armv4_5_mode_t mode
, uint32_t * value
)
946 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
948 if ((num
<= ARM_CPSR
))
950 /* read a normal core register */
951 retval
= cortex_a8_dap_read_coreregister_u32(target
, value
, num
);
953 if (retval
!= ERROR_OK
)
955 LOG_ERROR("JTAG failure %i", retval
);
956 return ERROR_JTAG_DEVICE_ERROR
;
958 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
, num
, *value
);
962 return ERROR_INVALID_ARGUMENTS
;
965 /* Register other than r0 - r14 uses r0 for access */
967 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
,
968 armv4_5
->core_mode
, 0).dirty
=
969 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
,
970 armv4_5
->core_mode
, 0).valid
;
971 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
,
972 armv4_5
->core_mode
, 15).dirty
=
973 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
,
974 armv4_5
->core_mode
, 15).valid
;
979 static int cortex_a8_store_core_reg_u32(struct target
*target
, int num
,
980 armv4_5_mode_t mode
, uint32_t value
)
984 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
986 #ifdef ARMV7_GDB_HACKS
987 /* If the LR register is being modified, make sure it will put us
988 * in "thumb" mode, or an INVSTATE exception will occur. This is a
989 * hack to deal with the fact that gdb will sometimes "forge"
990 * return addresses, and doesn't set the LSB correctly (i.e., when
991 * printing expressions containing function calls, it sets LR=0.) */
997 if ((num
<= ARM_CPSR
))
999 retval
= cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
1000 if (retval
!= ERROR_OK
)
1002 LOG_ERROR("JTAG failure %i", retval
);
1003 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
,
1004 armv4_5
->core_mode
, num
).dirty
=
1005 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
,
1006 armv4_5
->core_mode
, num
).valid
;
1007 return ERROR_JTAG_DEVICE_ERROR
;
1009 LOG_DEBUG("write core reg %i value 0x%" PRIx32
, num
, value
);
1013 return ERROR_INVALID_ARGUMENTS
;
1021 static int cortex_a8_write_core_reg(struct target
*target
, struct reg
*r
,
1022 int num
, enum armv4_5_mode mode
, uint32_t value
);
1024 static int cortex_a8_read_core_reg(struct target
*target
, struct reg
*r
,
1025 int num
, enum armv4_5_mode mode
)
1029 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
1030 struct reg
*cpsr_r
= NULL
;
1032 unsigned cookie
= num
;
1034 /* avoid some needless mode changes
1035 * FIXME move some of these to shared ARM code...
1037 if (mode
!= armv4_5
->core_mode
) {
1038 if ((armv4_5
->core_mode
== ARMV4_5_MODE_SYS
)
1039 && (mode
== ARMV4_5_MODE_USR
))
1040 mode
= ARMV4_5_MODE_ANY
;
1041 else if ((mode
!= ARMV4_5_MODE_FIQ
) && (num
<= 12))
1042 mode
= ARMV4_5_MODE_ANY
;
1044 if (mode
!= ARMV4_5_MODE_ANY
) {
1045 cpsr_r
= armv4_5
->cpsr
;
1046 cpsr
= buf_get_u32(cpsr_r
->value
, 0, 32);
1047 cortex_a8_write_core_reg(target
, cpsr_r
,
1048 16, ARMV4_5_MODE_ANY
, mode
);
1054 case ARMV4_5_MODE_USR
:
1055 case ARMV4_5_MODE_SYS
:
1056 case ARMV4_5_MODE_ANY
:
1066 cortex_a8_dap_read_coreregister_u32(target
, &value
, cookie
);
1067 retval
= jtag_execute_queue();
1068 if (retval
== ERROR_OK
) {
1071 buf_set_u32(r
->value
, 0, 32, value
);
1075 cortex_a8_write_core_reg(target
, cpsr_r
,
1076 16, ARMV4_5_MODE_ANY
, cpsr
);
1080 static int cortex_a8_write_core_reg(struct target
*target
, struct reg
*r
,
1081 int num
, enum armv4_5_mode mode
, uint32_t value
)
1084 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
1085 struct reg
*cpsr_r
= NULL
;
1087 unsigned cookie
= num
;
1089 /* avoid some needless mode changes
1090 * FIXME move some of these to shared ARM code...
1092 if (mode
!= armv4_5
->core_mode
) {
1093 if ((armv4_5
->core_mode
== ARMV4_5_MODE_SYS
)
1094 && (mode
== ARMV4_5_MODE_USR
))
1095 mode
= ARMV4_5_MODE_ANY
;
1096 else if ((mode
!= ARMV4_5_MODE_FIQ
) && (num
<= 12))
1097 mode
= ARMV4_5_MODE_ANY
;
1099 if (mode
!= ARMV4_5_MODE_ANY
) {
1100 cpsr_r
= armv4_5
->cpsr
;
1101 cpsr
= buf_get_u32(cpsr_r
->value
, 0, 32);
1102 cortex_a8_write_core_reg(target
, cpsr_r
,
1103 16, ARMV4_5_MODE_ANY
, mode
);
1110 case ARMV4_5_MODE_USR
:
1111 case ARMV4_5_MODE_SYS
:
1112 case ARMV4_5_MODE_ANY
:
1122 cortex_a8_dap_write_coreregister_u32(target
, value
, cookie
);
1123 if ((retval
= jtag_execute_queue()) == ERROR_OK
) {
1124 buf_set_u32(r
->value
, 0, 32, value
);
1130 cortex_a8_write_core_reg(target
, cpsr_r
,
1131 16, ARMV4_5_MODE_ANY
, cpsr
);
1137 * Cortex-A8 Breakpoint and watchpoint fuctions
1140 /* Setup hardware Breakpoint Register Pair */
1141 static int cortex_a8_set_breakpoint(struct target
*target
,
1142 struct breakpoint
*breakpoint
, uint8_t matchmode
)
1147 uint8_t byte_addr_select
= 0x0F;
1148 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1149 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1150 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1152 if (breakpoint
->set
)
1154 LOG_WARNING("breakpoint already set");
1158 if (breakpoint
->type
== BKPT_HARD
)
1160 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
1162 if (brp_i
>= cortex_a8
->brp_num
)
1164 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1167 breakpoint
->set
= brp_i
+ 1;
1168 if (breakpoint
->length
== 2)
1170 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1172 control
= ((matchmode
& 0x7) << 20)
1173 | (byte_addr_select
<< 5)
1175 brp_list
[brp_i
].used
= 1;
1176 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1177 brp_list
[brp_i
].control
= control
;
1178 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1179 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1180 brp_list
[brp_i
].value
);
1181 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1182 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1183 brp_list
[brp_i
].control
);
1184 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1185 brp_list
[brp_i
].control
,
1186 brp_list
[brp_i
].value
);
1188 else if (breakpoint
->type
== BKPT_SOFT
)
1191 if (breakpoint
->length
== 2)
1193 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1197 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1199 retval
= target
->type
->read_memory(target
,
1200 breakpoint
->address
& 0xFFFFFFFE,
1201 breakpoint
->length
, 1,
1202 breakpoint
->orig_instr
);
1203 if (retval
!= ERROR_OK
)
1205 retval
= target
->type
->write_memory(target
,
1206 breakpoint
->address
& 0xFFFFFFFE,
1207 breakpoint
->length
, 1, code
);
1208 if (retval
!= ERROR_OK
)
1210 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1216 static int cortex_a8_unset_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1219 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1220 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1221 struct cortex_a8_brp
* brp_list
= cortex_a8
->brp_list
;
1223 if (!breakpoint
->set
)
1225 LOG_WARNING("breakpoint not set");
1229 if (breakpoint
->type
== BKPT_HARD
)
1231 int brp_i
= breakpoint
->set
- 1;
1232 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1234 LOG_DEBUG("Invalid BRP number in breakpoint");
1237 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1238 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1239 brp_list
[brp_i
].used
= 0;
1240 brp_list
[brp_i
].value
= 0;
1241 brp_list
[brp_i
].control
= 0;
1242 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1243 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1244 brp_list
[brp_i
].control
);
1245 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1246 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1247 brp_list
[brp_i
].value
);
1251 /* restore original instruction (kept in target endianness) */
1252 if (breakpoint
->length
== 4)
1254 retval
= target
->type
->write_memory(target
,
1255 breakpoint
->address
& 0xFFFFFFFE,
1256 4, 1, breakpoint
->orig_instr
);
1257 if (retval
!= ERROR_OK
)
1262 retval
= target
->type
->write_memory(target
,
1263 breakpoint
->address
& 0xFFFFFFFE,
1264 2, 1, breakpoint
->orig_instr
);
1265 if (retval
!= ERROR_OK
)
1269 breakpoint
->set
= 0;
1274 int cortex_a8_add_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1276 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1278 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1280 LOG_INFO("no hardware breakpoint available");
1281 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1284 if (breakpoint
->type
== BKPT_HARD
)
1285 cortex_a8
->brp_num_available
--;
1286 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1291 static int cortex_a8_remove_breakpoint(struct target
*target
, struct breakpoint
*breakpoint
)
1293 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1296 /* It is perfectly possible to remove brakpoints while the taget is running */
1297 if (target
->state
!= TARGET_HALTED
)
1299 LOG_WARNING("target not halted");
1300 return ERROR_TARGET_NOT_HALTED
;
1304 if (breakpoint
->set
)
1306 cortex_a8_unset_breakpoint(target
, breakpoint
);
1307 if (breakpoint
->type
== BKPT_HARD
)
1308 cortex_a8
->brp_num_available
++ ;
1318 * Cortex-A8 Reset fuctions
1321 static int cortex_a8_assert_reset(struct target
*target
)
1323 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1327 /* registers are now invalid */
1328 register_cache_invalidate(armv7a
->armv4_5_common
.core_cache
);
1330 target
->state
= TARGET_RESET
;
1335 static int cortex_a8_deassert_reset(struct target
*target
)
1340 if (target
->reset_halt
)
1343 if ((retval
= target_halt(target
)) != ERROR_OK
)
1351 * Cortex-A8 Memory access
1353 * This is same Cortex M3 but we must also use the correct
1354 * ap number for every access.
1357 static int cortex_a8_read_memory(struct target
*target
, uint32_t address
,
1358 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1360 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1361 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1362 int retval
= ERROR_INVALID_ARGUMENTS
;
1364 /* cortex_a8 handles unaligned memory access */
1366 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1368 if (count
&& buffer
) {
1371 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1374 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1377 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1385 int cortex_a8_write_memory(struct target
*target
, uint32_t address
,
1386 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1388 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1389 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1390 int retval
= ERROR_INVALID_ARGUMENTS
;
1392 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1394 if (count
&& buffer
) {
1397 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1400 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1403 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1408 if (retval
== ERROR_OK
&& target
->state
== TARGET_HALTED
)
1410 /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */
1411 /* invalidate I-Cache */
1412 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
1414 /* Invalidate ICache single entry with MVA, repeat this for all cache
1415 lines in the address range, Cortex-A8 has fixed 64 byte line length */
1416 /* Invalidate Cache single entry with MVA to PoU */
1417 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1418 armv7a
->write_cp15(target
, 0, 1, 7, 5, cacheline
); /* I-Cache to PoU */
1420 /* invalidate D-Cache */
1421 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
1423 /* Invalidate Cache single entry with MVA to PoC */
1424 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1425 armv7a
->write_cp15(target
, 0, 1, 7, 6, cacheline
); /* U/D cache to PoC */
1432 static int cortex_a8_bulk_write_memory(struct target
*target
, uint32_t address
,
1433 uint32_t count
, uint8_t *buffer
)
1435 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1439 static int cortex_a8_dcc_read(struct swjdp_common
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1444 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1445 *ctrl
= (uint8_t)dcrdr
;
1446 *value
= (uint8_t)(dcrdr
>> 8);
1448 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1450 /* write ack back to software dcc register
1451 * signify we have read data */
1452 if (dcrdr
& (1 << 0))
1455 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1462 static int cortex_a8_handle_target_request(void *priv
)
1464 struct target
*target
= priv
;
1465 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1466 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1468 if (!target_was_examined(target
))
1470 if (!target
->dbg_msg_enabled
)
1473 if (target
->state
== TARGET_RUNNING
)
1478 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1480 /* check if we have data */
1481 if (ctrl
& (1 << 0))
1485 /* we assume target is quick enough */
1487 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1488 request
|= (data
<< 8);
1489 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1490 request
|= (data
<< 16);
1491 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1492 request
|= (data
<< 24);
1493 target_request(target
, request
);
1501 * Cortex-A8 target information and configuration
1504 static int cortex_a8_examine_first(struct target
*target
)
1506 struct cortex_a8_common
*cortex_a8
= target_to_cortex_a8(target
);
1507 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1508 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1510 int retval
= ERROR_OK
;
1511 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1515 /* Here we shall insert a proper ROM Table scan */
1516 armv7a
->debug_base
= OMAP3530_DEBUG_BASE
;
1518 /* We do one extra read to ensure DAP is configured,
1519 * we call ahbap_debugport_init(swjdp) instead
1521 ahbap_debugport_init(swjdp
);
1522 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
1523 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1524 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1526 LOG_DEBUG("Examine failed");
1530 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1531 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1533 LOG_DEBUG("Examine failed");
1537 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1538 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1540 LOG_DEBUG("Examine failed");
1544 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1545 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1547 LOG_DEBUG("Examine failed");
1551 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1552 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1553 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1554 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1556 /* Setup Breakpoint Register Pairs */
1557 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1558 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1559 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1560 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(struct cortex_a8_brp
));
1561 // cortex_a8->brb_enabled = ????;
1562 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1564 cortex_a8
->brp_list
[i
].used
= 0;
1565 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1566 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1568 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1569 cortex_a8
->brp_list
[i
].value
= 0;
1570 cortex_a8
->brp_list
[i
].control
= 0;
1571 cortex_a8
->brp_list
[i
].BRPn
= i
;
1574 /* Setup Watchpoint Register Pairs */
1575 cortex_a8
->wrp_num
= ((didr
>> 28) & 0x0F) + 1;
1576 cortex_a8
->wrp_num_available
= cortex_a8
->wrp_num
;
1577 cortex_a8
->wrp_list
= calloc(cortex_a8
->wrp_num
, sizeof(struct cortex_a8_wrp
));
1578 for (i
= 0; i
< cortex_a8
->wrp_num
; i
++)
1580 cortex_a8
->wrp_list
[i
].used
= 0;
1581 cortex_a8
->wrp_list
[i
].type
= 0;
1582 cortex_a8
->wrp_list
[i
].value
= 0;
1583 cortex_a8
->wrp_list
[i
].control
= 0;
1584 cortex_a8
->wrp_list
[i
].WRPn
= i
;
1586 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1587 cortex_a8
->brp_num
, cortex_a8
->wrp_num
);
1589 target_set_examined(target
);
1593 static int cortex_a8_examine(struct target
*target
)
1595 int retval
= ERROR_OK
;
1597 /* don't re-probe hardware after each reset */
1598 if (!target_was_examined(target
))
1599 retval
= cortex_a8_examine_first(target
);
1601 /* Configure core debug access */
1602 if (retval
== ERROR_OK
)
1603 retval
= cortex_a8_init_debug_access(target
);
1609 * Cortex-A8 target creation and initialization
1612 static void cortex_a8_build_reg_cache(struct target
*target
)
1614 struct reg_cache
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1615 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
1617 armv4_5
->core_type
= ARM_MODE_MON
;
1619 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
1623 static int cortex_a8_init_target(struct command_context
*cmd_ctx
,
1624 struct target
*target
)
1626 cortex_a8_build_reg_cache(target
);
1630 int cortex_a8_init_arch_info(struct target
*target
,
1631 struct cortex_a8_common
*cortex_a8
, struct jtag_tap
*tap
)
1633 struct armv7a_common
*armv7a
= &cortex_a8
->armv7a_common
;
1634 struct arm
*armv4_5
= &armv7a
->armv4_5_common
;
1635 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
1637 /* Setup struct cortex_a8_common */
1638 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1639 armv4_5
->arch_info
= armv7a
;
1641 /* prepare JTAG information for the new target */
1642 cortex_a8
->jtag_info
.tap
= tap
;
1643 cortex_a8
->jtag_info
.scann_size
= 4;
1645 swjdp
->dp_select_value
= -1;
1646 swjdp
->ap_csw_value
= -1;
1647 swjdp
->ap_tar_value
= -1;
1648 swjdp
->jtag_info
= &cortex_a8
->jtag_info
;
1649 swjdp
->memaccess_tck
= 80;
1651 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1652 swjdp
->tar_autoincr_block
= (1 << 10);
1654 cortex_a8
->fast_reg_read
= 0;
1657 /* register arch-specific functions */
1658 armv7a
->examine_debug_reason
= NULL
;
1660 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1662 armv7a
->pre_restore_context
= NULL
;
1663 armv7a
->post_restore_context
= NULL
;
1664 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1665 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1666 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_memory
;
1667 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_memory
;
1668 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1669 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1670 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1671 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1672 armv7a
->read_cp15
= cortex_a8_read_cp15
;
1673 armv7a
->write_cp15
= cortex_a8_write_cp15
;
1676 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1678 armv4_5
->read_core_reg
= cortex_a8_read_core_reg
;
1679 armv4_5
->write_core_reg
= cortex_a8_write_core_reg
;
1681 /* REVISIT v7a setup should be in a v7a-specific routine */
1682 armv4_5_init_arch_info(target
, armv4_5
);
1683 armv7a
->common_magic
= ARMV7_COMMON_MAGIC
;
1685 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1690 static int cortex_a8_target_create(struct target
*target
, Jim_Interp
*interp
)
1692 struct cortex_a8_common
*cortex_a8
= calloc(1, sizeof(struct cortex_a8_common
));
1694 cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1699 COMMAND_HANDLER(cortex_a8_handle_cache_info_command
)
1701 struct target
*target
= get_current_target(CMD_CTX
);
1702 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
1704 return armv4_5_handle_cache_info_command(CMD_CTX
,
1705 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1709 COMMAND_HANDLER(cortex_a8_handle_dbginit_command
)
1711 struct target
*target
= get_current_target(CMD_CTX
);
1713 cortex_a8_init_debug_access(target
);
1719 static int cortex_a8_register_commands(struct command_context
*cmd_ctx
)
1721 struct command
*cortex_a8_cmd
;
1722 int retval
= ERROR_OK
;
1724 armv4_5_register_commands(cmd_ctx
);
1725 armv7a_register_commands(cmd_ctx
);
1727 cortex_a8_cmd
= register_command(cmd_ctx
, NULL
, "cortex_a8",
1729 "cortex_a8 specific commands");
1731 register_command(cmd_ctx
, cortex_a8_cmd
, "cache_info",
1732 cortex_a8_handle_cache_info_command
, COMMAND_EXEC
,
1733 "display information about target caches");
1735 register_command(cmd_ctx
, cortex_a8_cmd
, "dbginit",
1736 cortex_a8_handle_dbginit_command
, COMMAND_EXEC
,
1737 "Initialize core debug");
1742 struct target_type cortexa8_target
= {
1743 .name
= "cortex_a8",
1745 .poll
= cortex_a8_poll
,
1746 .arch_state
= armv7a_arch_state
,
1748 .target_request_data
= NULL
,
1750 .halt
= cortex_a8_halt
,
1751 .resume
= cortex_a8_resume
,
1752 .step
= cortex_a8_step
,
1754 .assert_reset
= cortex_a8_assert_reset
,
1755 .deassert_reset
= cortex_a8_deassert_reset
,
1756 .soft_reset_halt
= NULL
,
1758 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
1760 .read_memory
= cortex_a8_read_memory
,
1761 .write_memory
= cortex_a8_write_memory
,
1762 .bulk_write_memory
= cortex_a8_bulk_write_memory
,
1764 .checksum_memory
= arm_checksum_memory
,
1765 .blank_check_memory
= arm_blank_check_memory
,
1767 .run_algorithm
= armv4_5_run_algorithm
,
1769 .add_breakpoint
= cortex_a8_add_breakpoint
,
1770 .remove_breakpoint
= cortex_a8_remove_breakpoint
,
1771 .add_watchpoint
= NULL
,
1772 .remove_watchpoint
= NULL
,
1774 .register_commands
= cortex_a8_register_commands
,
1775 .target_create
= cortex_a8_target_create
,
1776 .init_target
= cortex_a8_init_target
,
1777 .examine
= cortex_a8_examine
,
1778 .mrc
= cortex_a8_mrc
,
1779 .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)