1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2006 by Magnus Lundin *
8 * Copyright (C) 2008 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
11 * Copyright (C) 2009 by Dirk Behme *
12 * dirk.behme@gmail.com - copy from cortex_m3 *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program; if not, write to the *
26 * Free Software Foundation, Inc., *
27 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
29 * Cortex-A8(tm) TRM, ARM DDI 0344H *
31 ***************************************************************************/
36 #include "cortex_a8.h"
40 #include "target_request.h"
41 #include "target_type.h"
44 int cortex_a8_register_commands(struct command_context_s
*cmd_ctx
);
46 /* forward declarations */
47 int cortex_a8_target_create(struct target_s
*target
, Jim_Interp
*interp
);
48 int cortex_a8_init_target(struct command_context_s
*cmd_ctx
,
49 struct target_s
*target
);
50 int cortex_a8_examine(struct target_s
*target
);
51 int cortex_a8_poll(target_t
*target
);
52 int cortex_a8_halt(target_t
*target
);
53 int cortex_a8_resume(struct target_s
*target
, int current
, uint32_t address
,
54 int handle_breakpoints
, int debug_execution
);
55 int cortex_a8_step(struct target_s
*target
, int current
, uint32_t address
,
56 int handle_breakpoints
);
57 int cortex_a8_debug_entry(target_t
*target
);
58 int cortex_a8_restore_context(target_t
*target
);
59 int cortex_a8_bulk_write_memory(target_t
*target
, uint32_t address
,
60 uint32_t count
, uint8_t *buffer
);
61 int cortex_a8_set_breakpoint(struct target_s
*target
,
62 breakpoint_t
*breakpoint
, uint8_t matchmode
);
63 int cortex_a8_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
64 int cortex_a8_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
65 int cortex_a8_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
66 int cortex_a8_dap_read_coreregister_u32(target_t
*target
,
67 uint32_t *value
, int regnum
);
68 int cortex_a8_dap_write_coreregister_u32(target_t
*target
,
69 uint32_t value
, int regnum
);
70 int cortex_a8_assert_reset(target_t
*target
);
71 int cortex_a8_deassert_reset(target_t
*target
);
73 static int cortex_a8_mrc(target_t
*target
, int cpnum
, uint32_t op1
,
74 uint32_t op2
, uint32_t CRn
, uint32_t CRm
, uint32_t *value
);
75 static int cortex_a8_mcr(target_t
*target
, int cpnum
, uint32_t op1
,
76 uint32_t op2
, uint32_t CRn
, uint32_t CRm
, uint32_t value
);
78 target_type_t cortexa8_target
=
82 .poll
= cortex_a8_poll
,
83 .arch_state
= armv7a_arch_state
,
85 .target_request_data
= NULL
,
87 .halt
= cortex_a8_halt
,
88 .resume
= cortex_a8_resume
,
89 .step
= cortex_a8_step
,
91 .assert_reset
= cortex_a8_assert_reset
,
92 .deassert_reset
= cortex_a8_deassert_reset
,
93 .soft_reset_halt
= NULL
,
95 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
97 .read_memory
= cortex_a8_read_memory
,
98 .write_memory
= cortex_a8_write_memory
,
99 .bulk_write_memory
= cortex_a8_bulk_write_memory
,
100 .checksum_memory
= arm7_9_checksum_memory
,
101 .blank_check_memory
= arm7_9_blank_check_memory
,
103 .run_algorithm
= armv4_5_run_algorithm
,
105 .add_breakpoint
= cortex_a8_add_breakpoint
,
106 .remove_breakpoint
= cortex_a8_remove_breakpoint
,
107 .add_watchpoint
= NULL
,
108 .remove_watchpoint
= NULL
,
110 .register_commands
= cortex_a8_register_commands
,
111 .target_create
= cortex_a8_target_create
,
112 .init_target
= cortex_a8_init_target
,
113 .examine
= cortex_a8_examine
,
114 .mrc
= cortex_a8_mrc
,
115 .mcr
= cortex_a8_mcr
,
119 * FIXME do topology discovery using the ROM; don't
120 * assume this is an OMAP3.
122 #define swjdp_memoryap 0
123 #define swjdp_debugap 1
124 #define OMAP3530_DEBUG_BASE 0x54011000
127 * Cortex-A8 Basic debug access, very low level assumes state is saved
129 int cortex_a8_init_debug_access(target_t
*target
)
131 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
132 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
139 /* Unlocking the debug registers for modification */
140 /* The debugport might be uninitialised so try twice */
141 retval
= mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
142 if (retval
!= ERROR_OK
)
143 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_LOCKACCESS
, 0xC5ACCE55);
144 /* Clear Sticky Power Down status Bit in PRSR to enable access to
145 the registers in the Core Power Domain */
146 retval
= mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_PRSR
, &dummy
);
147 /* Enabling of instruction execution in debug mode is done in debug_entry code */
149 /* Resync breakpoint registers */
151 /* Since this is likley called from init or reset, update targtet state information*/
152 cortex_a8_poll(target
);
157 int cortex_a8_exec_opcode(target_t
*target
, uint32_t opcode
)
161 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
162 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
164 LOG_DEBUG("exec opcode 0x%08" PRIx32
, opcode
);
167 retval
= mem_ap_read_atomic_u32(swjdp
,
168 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
169 if (retval
!= ERROR_OK
)
171 LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32
, opcode
);
175 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
177 mem_ap_write_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_ITR
, opcode
);
181 retval
= mem_ap_read_atomic_u32(swjdp
,
182 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
183 if (retval
!= ERROR_OK
)
185 LOG_ERROR("Could not read DSCR register");
189 while ((dscr
& (1 << DSCR_INSTR_COMP
)) == 0); /* Wait for InstrCompl bit to be set */
194 /**************************************************************************
195 Read core register with very few exec_opcode, fast but needs work_area.
196 This can cause problems with MMU active.
197 **************************************************************************/
198 int cortex_a8_read_regs_through_mem(target_t
*target
, uint32_t address
,
201 int retval
= ERROR_OK
;
202 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
203 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
205 cortex_a8_dap_read_coreregister_u32(target
, regfile
, 0);
206 cortex_a8_dap_write_coreregister_u32(target
, address
, 0);
207 cortex_a8_exec_opcode(target
, ARMV4_5_STMIA(0, 0xFFFE, 0, 0));
208 dap_ap_select(swjdp
, swjdp_memoryap
);
209 mem_ap_read_buf_u32(swjdp
, (uint8_t *)(®file
[1]), 4*15, address
);
210 dap_ap_select(swjdp
, swjdp_debugap
);
215 int cortex_a8_read_cp(target_t
*target
, uint32_t *value
, uint8_t CP
,
216 uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
219 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
220 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
222 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(CP
, op1
, 0, CRn
, CRm
, op2
));
223 /* Move R0 to DTRTX */
224 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
227 retval
= mem_ap_read_atomic_u32(swjdp
,
228 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
233 int cortex_a8_write_cp(target_t
*target
, uint32_t value
,
234 uint8_t CP
, uint8_t op1
, uint8_t CRn
, uint8_t CRm
, uint8_t op2
)
238 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
239 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
241 LOG_DEBUG("CP%i, CRn %i, value 0x%08" PRIx32
, CP
, CRn
, value
);
243 /* Check that DCCRX is not full */
244 retval
= mem_ap_read_atomic_u32(swjdp
,
245 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
246 if (dscr
& (1 << DSCR_DTR_RX_FULL
))
248 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
249 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
250 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
253 retval
= mem_ap_write_u32(swjdp
,
254 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
255 /* Move DTRRX to r0 */
256 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
258 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(CP
, op1
, 0, CRn
, CRm
, op2
));
262 int cortex_a8_read_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
263 uint32_t CRn
, uint32_t CRm
, uint32_t *value
)
265 return cortex_a8_read_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
268 int cortex_a8_write_cp15(target_t
*target
, uint32_t op1
, uint32_t op2
,
269 uint32_t CRn
, uint32_t CRm
, uint32_t value
)
271 return cortex_a8_write_cp(target
, value
, 15, op1
, CRn
, CRm
, op2
);
274 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
)
278 LOG_ERROR("Only cp15 is supported");
281 return cortex_a8_read_cp15(target
, op1
, op2
, CRn
, CRm
, value
);
284 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
)
288 LOG_ERROR("Only cp15 is supported");
291 return cortex_a8_write_cp15(target
, op1
, op2
, CRn
, CRm
, value
);
296 int cortex_a8_dap_read_coreregister_u32(target_t
*target
,
297 uint32_t *value
, int regnum
)
299 int retval
= ERROR_OK
;
300 uint8_t reg
= regnum
&0xFF;
302 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
303 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
310 /* Rn to DCCTX, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
311 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, reg
, 0, 5, 0));
315 cortex_a8_exec_opcode(target
, 0xE1A0000F);
316 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
320 cortex_a8_exec_opcode(target
, ARMV4_5_MRS(0, 0));
321 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
327 retval
= mem_ap_read_atomic_u32(swjdp
,
328 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
330 while ((dscr
& (1 << DSCR_DTR_TX_FULL
)) == 0); /* Wait for DTRRXfull */
332 retval
= mem_ap_read_atomic_u32(swjdp
,
333 armv7a
->debug_base
+ CPUDBG_DTRTX
, value
);
338 int cortex_a8_dap_write_coreregister_u32(target_t
*target
, uint32_t value
, int regnum
)
340 int retval
= ERROR_OK
;
341 uint8_t Rd
= regnum
&0xFF;
343 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
344 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
346 LOG_DEBUG("register %i, value 0x%08" PRIx32
, regnum
, value
);
348 /* Check that DCCRX is not full */
349 retval
= mem_ap_read_atomic_u32(swjdp
,
350 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
351 if (dscr
& (1 << DSCR_DTR_RX_FULL
))
353 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32
, dscr
);
354 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
355 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
362 retval
= mem_ap_write_u32(swjdp
,
363 armv7a
->debug_base
+ CPUDBG_DTRRX
, value
);
367 /* DCCRX to Rd, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
368 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, Rd
, 0, 5, 0));
372 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
373 cortex_a8_exec_opcode(target
, 0xE1A0F000);
377 cortex_a8_exec_opcode(target
, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
378 cortex_a8_exec_opcode(target
, ARMV4_5_MSR_GP(0, 0xF, 0));
379 /* Execute a PrefetchFlush instruction through the ITR. */
380 cortex_a8_exec_opcode(target
, ARMV4_5_MCR(15, 0, 0, 7, 5, 4));
386 /* Write to memory mapped registers directly with no cache or mmu handling */
387 int cortex_a8_dap_write_memap_register_u32(target_t
*target
, uint32_t address
, uint32_t value
)
390 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
391 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
393 retval
= mem_ap_write_atomic_u32(swjdp
, address
, value
);
399 * Cortex-A8 Run control
402 int cortex_a8_poll(target_t
*target
)
404 int retval
= ERROR_OK
;
406 struct cortex_a8_common_s
*cortex_a8
= target_to_cortex_a8(target
);
407 struct armv7a_common_s
*armv7a
= &cortex_a8
->armv7a_common
;
408 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
409 enum target_state prev_target_state
= target
->state
;
410 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
412 dap_ap_select(swjdp
, swjdp_debugap
);
413 retval
= mem_ap_read_atomic_u32(swjdp
,
414 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
415 if (retval
!= ERROR_OK
)
417 dap_ap_select(swjdp
, saved_apsel
);
420 cortex_a8
->cpudbg_dscr
= dscr
;
422 if ((dscr
& 0x3) == 0x3)
424 if (prev_target_state
!= TARGET_HALTED
)
426 /* We have a halting debug event */
427 LOG_DEBUG("Target halted");
428 target
->state
= TARGET_HALTED
;
429 if ((prev_target_state
== TARGET_RUNNING
)
430 || (prev_target_state
== TARGET_RESET
))
432 retval
= cortex_a8_debug_entry(target
);
433 if (retval
!= ERROR_OK
)
436 target_call_event_callbacks(target
,
437 TARGET_EVENT_HALTED
);
439 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
443 retval
= cortex_a8_debug_entry(target
);
444 if (retval
!= ERROR_OK
)
447 target_call_event_callbacks(target
,
448 TARGET_EVENT_DEBUG_HALTED
);
452 else if ((dscr
& 0x3) == 0x2)
454 target
->state
= TARGET_RUNNING
;
458 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32
, dscr
);
459 target
->state
= TARGET_UNKNOWN
;
462 dap_ap_select(swjdp
, saved_apsel
);
467 int cortex_a8_halt(target_t
*target
)
469 int retval
= ERROR_OK
;
471 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
472 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
473 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
474 dap_ap_select(swjdp
, swjdp_debugap
);
477 * Tell the core to be halted by writing DRCR with 0x1
478 * and then wait for the core to be halted.
480 retval
= mem_ap_write_atomic_u32(swjdp
,
481 armv7a
->debug_base
+ CPUDBG_DRCR
, 0x1);
484 * enter halting debug mode
486 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
487 retval
= mem_ap_write_atomic_u32(swjdp
,
488 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
| (1 << DSCR_HALT_DBG_MODE
));
490 if (retval
!= ERROR_OK
)
494 mem_ap_read_atomic_u32(swjdp
,
495 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
496 } while ((dscr
& (1 << DSCR_CORE_HALTED
)) == 0);
498 target
->debug_reason
= DBG_REASON_DBGRQ
;
501 dap_ap_select(swjdp
, saved_apsel
);
505 int cortex_a8_resume(struct target_s
*target
, int current
,
506 uint32_t address
, int handle_breakpoints
, int debug_execution
)
508 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
509 struct armv4_5_common_s
*armv4_5
= &armv7a
->armv4_5_common
;
510 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
512 // breakpoint_t *breakpoint = NULL;
513 uint32_t resume_pc
, dscr
;
515 uint8_t saved_apsel
= dap_ap_get_select(swjdp
);
516 dap_ap_select(swjdp
, swjdp_debugap
);
518 if (!debug_execution
)
520 target_free_all_working_areas(target
);
521 // cortex_m3_enable_breakpoints(target);
522 // cortex_m3_enable_watchpoints(target);
528 /* Disable interrupts */
529 /* We disable interrupts in the PRIMASK register instead of
530 * masking with C_MASKINTS,
531 * This is probably the same issue as Cortex-M3 Errata 377493:
532 * C_MASKINTS in parallel with disabled interrupts can cause
533 * local faults to not be taken. */
534 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
535 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
536 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
538 /* Make sure we are in Thumb mode */
539 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
540 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
541 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
542 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
546 /* current = 1: continue on current pc, otherwise continue at <address> */
547 resume_pc
= buf_get_u32(
548 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
549 armv4_5
->core_mode
, 15).value
,
554 /* Make sure that the Armv7 gdb thumb fixups does not
555 * kill the return address
557 if (armv7a
->core_state
== ARMV7A_STATE_ARM
)
559 resume_pc
&= 0xFFFFFFFC;
561 /* When the return address is loaded into PC
562 * bit 0 must be 1 to stay in Thumb state
564 if (armv7a
->core_state
== ARMV7A_STATE_THUMB
)
568 LOG_DEBUG("resume pc = 0x%08" PRIx32
, resume_pc
);
569 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
570 armv4_5
->core_mode
, 15).value
,
572 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
573 armv4_5
->core_mode
, 15).dirty
= 1;
574 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
575 armv4_5
->core_mode
, 15).valid
= 1;
577 cortex_a8_restore_context(target
);
578 // arm7_9_restore_context(target); TODO Context is currently NOT Properly restored
580 /* the front-end may request us not to handle breakpoints */
581 if (handle_breakpoints
)
583 /* Single step past breakpoint at current address */
584 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
586 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
587 cortex_m3_unset_breakpoint(target
, breakpoint
);
588 cortex_m3_single_step_core(target
);
589 cortex_m3_set_breakpoint(target
, breakpoint
);
594 /* Restart core and wait for it to be started */
595 mem_ap_write_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_DRCR
, 0x2);
598 mem_ap_read_atomic_u32(swjdp
,
599 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
600 } while ((dscr
& (1 << DSCR_CORE_RESTARTED
)) == 0);
602 target
->debug_reason
= DBG_REASON_NOTHALTED
;
603 target
->state
= TARGET_RUNNING
;
605 /* registers are now invalid */
606 armv4_5_invalidate_core_regs(target
);
608 if (!debug_execution
)
610 target
->state
= TARGET_RUNNING
;
611 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
612 LOG_DEBUG("target resumed at 0x%" PRIx32
, resume_pc
);
616 target
->state
= TARGET_DEBUG_RUNNING
;
617 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
618 LOG_DEBUG("target debug resumed at 0x%" PRIx32
, resume_pc
);
621 dap_ap_select(swjdp
, saved_apsel
);
626 int cortex_a8_debug_entry(target_t
*target
)
629 uint32_t regfile
[16], pc
, cpsr
, dscr
;
630 int retval
= ERROR_OK
;
631 working_area_t
*regfile_working_area
= NULL
;
632 struct cortex_a8_common_s
*cortex_a8
= target_to_cortex_a8(target
);
633 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
634 struct armv4_5_common_s
*armv4_5
= &armv7a
->armv4_5_common
;
635 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
637 LOG_DEBUG("dscr = 0x%08" PRIx32
, cortex_a8
->cpudbg_dscr
);
639 /* Enable the ITR execution once we are in debug mode */
640 mem_ap_read_atomic_u32(swjdp
,
641 armv7a
->debug_base
+ CPUDBG_DSCR
, &dscr
);
642 dscr
|= (1 << DSCR_EXT_INT_EN
);
643 retval
= mem_ap_write_atomic_u32(swjdp
,
644 armv7a
->debug_base
+ CPUDBG_DSCR
, dscr
);
646 /* Examine debug reason */
647 switch ((cortex_a8
->cpudbg_dscr
>> 2)&0xF)
651 target
->debug_reason
= DBG_REASON_DBGRQ
;
655 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
658 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
661 target
->debug_reason
= DBG_REASON_UNDEFINED
;
665 /* Examine target state and mode */
666 if (cortex_a8
->fast_reg_read
)
667 target_alloc_working_area(target
, 64, ®file_working_area
);
669 /* First load register acessible through core debug port*/
670 if (!regfile_working_area
)
672 for (i
= 0; i
<= 15; i
++)
673 cortex_a8_dap_read_coreregister_u32(target
,
678 dap_ap_select(swjdp
, swjdp_memoryap
);
679 cortex_a8_read_regs_through_mem(target
,
680 regfile_working_area
->address
, regfile
);
681 dap_ap_select(swjdp
, swjdp_memoryap
);
682 target_free_working_area(target
, regfile_working_area
);
685 cortex_a8_dap_read_coreregister_u32(target
, &cpsr
, 16);
687 dap_ap_select(swjdp
, swjdp_debugap
);
688 LOG_DEBUG("cpsr: %8.8" PRIx32
, cpsr
);
690 armv4_5
->core_mode
= cpsr
& 0x1F;
691 armv7a
->core_state
= (cpsr
& 0x20)?ARMV7A_STATE_THUMB
:ARMV7A_STATE_ARM
;
693 for (i
= 0; i
<= ARM_PC
; i
++)
695 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
696 armv4_5
->core_mode
, i
).value
,
698 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
699 armv4_5
->core_mode
, i
).valid
= 1;
700 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
701 armv4_5
->core_mode
, i
).dirty
= 0;
703 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
704 armv4_5
->core_mode
, 16).value
,
706 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
707 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
709 /* Fixup PC Resume Address */
710 if (armv7a
->core_state
== ARMV7A_STATE_THUMB
)
712 // T bit set for Thumb or ThumbEE state
713 regfile
[ARM_PC
] -= 4;
718 regfile
[ARM_PC
] -= 8;
720 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
721 armv4_5
->core_mode
, ARM_PC
).value
,
722 0, 32, regfile
[ARM_PC
]);
724 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 0)
725 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
726 armv4_5
->core_mode
, 0).valid
;
727 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 15)
728 .dirty
= ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
729 armv4_5
->core_mode
, 15).valid
;
732 /* TODO, Move this */
733 uint32_t cp15_control_register
, cp15_cacr
, cp15_nacr
;
734 cortex_a8_read_cp(target
, &cp15_control_register
, 15, 0, 1, 0, 0);
735 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register
);
737 cortex_a8_read_cp(target
, &cp15_cacr
, 15, 0, 1, 0, 2);
738 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr
);
740 cortex_a8_read_cp(target
, &cp15_nacr
, 15, 0, 1, 1, 2);
741 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr
);
744 /* Are we in an exception handler */
745 // armv4_5->exception_number = 0;
746 if (armv7a
->post_debug_entry
)
747 armv7a
->post_debug_entry(target
);
755 void cortex_a8_post_debug_entry(target_t
*target
)
757 struct cortex_a8_common_s
*cortex_a8
= target_to_cortex_a8(target
);
758 struct armv7a_common_s
*armv7a
= &cortex_a8
->armv7a_common
;
760 // cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
761 /* examine cp15 control reg */
762 armv7a
->read_cp15(target
, 0, 0, 1, 0, &cortex_a8
->cp15_control_reg
);
763 jtag_execute_queue();
764 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32
, cortex_a8
->cp15_control_reg
);
766 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
768 uint32_t cache_type_reg
;
769 /* identify caches */
770 armv7a
->read_cp15(target
, 0, 1, 0, 0, &cache_type_reg
);
771 jtag_execute_queue();
772 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
773 armv4_5_identify_cache(cache_type_reg
,
774 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
777 armv7a
->armv4_5_mmu
.mmu_enabled
=
778 (cortex_a8
->cp15_control_reg
& 0x1U
) ? 1 : 0;
779 armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
=
780 (cortex_a8
->cp15_control_reg
& 0x4U
) ? 1 : 0;
781 armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
=
782 (cortex_a8
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
787 int cortex_a8_step(struct target_s
*target
, int current
, uint32_t address
,
788 int handle_breakpoints
)
790 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
791 struct armv4_5_common_s
*armv4_5
= &armv7a
->armv4_5_common
;
792 breakpoint_t
*breakpoint
= NULL
;
793 breakpoint_t stepbreakpoint
;
797 if (target
->state
!= TARGET_HALTED
)
799 LOG_WARNING("target not halted");
800 return ERROR_TARGET_NOT_HALTED
;
803 /* current = 1: continue on current pc, otherwise continue at <address> */
806 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
807 armv4_5
->core_mode
, ARM_PC
).value
,
812 address
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
813 armv4_5
->core_mode
, ARM_PC
).value
,
817 /* The front-end may request us not to handle breakpoints.
818 * But since Cortex-A8 uses breakpoint for single step,
819 * we MUST handle breakpoints.
821 handle_breakpoints
= 1;
822 if (handle_breakpoints
) {
823 breakpoint
= breakpoint_find(target
,
824 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
825 armv4_5
->core_mode
, 15).value
,
828 cortex_a8_unset_breakpoint(target
, breakpoint
);
831 /* Setup single step breakpoint */
832 stepbreakpoint
.address
= address
;
833 stepbreakpoint
.length
= (armv7a
->core_state
== ARMV7A_STATE_THUMB
) ? 2 : 4;
834 stepbreakpoint
.type
= BKPT_HARD
;
835 stepbreakpoint
.set
= 0;
837 /* Break on IVA mismatch */
838 cortex_a8_set_breakpoint(target
, &stepbreakpoint
, 0x04);
840 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
842 cortex_a8_resume(target
, 1, address
, 0, 0);
844 while (target
->state
!= TARGET_HALTED
)
846 cortex_a8_poll(target
);
849 LOG_WARNING("timeout waiting for target halt");
854 cortex_a8_unset_breakpoint(target
, &stepbreakpoint
);
855 if (timeout
> 0) target
->debug_reason
= DBG_REASON_BREAKPOINT
;
858 cortex_a8_set_breakpoint(target
, breakpoint
, 0);
860 if (target
->state
!= TARGET_HALTED
)
861 LOG_DEBUG("target stepped");
866 int cortex_a8_restore_context(target_t
*target
)
870 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
871 struct armv4_5_common_s
*armv4_5
= &armv7a
->armv4_5_common
;
875 if (armv7a
->pre_restore_context
)
876 armv7a
->pre_restore_context(target
);
878 for (i
= 15; i
>= 0; i
--)
880 if (ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
881 armv4_5
->core_mode
, i
).dirty
)
883 value
= buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
884 armv4_5
->core_mode
, i
).value
,
886 /* TODO Check return values */
887 cortex_a8_dap_write_coreregister_u32(target
, value
, i
);
891 if (armv7a
->post_restore_context
)
892 armv7a
->post_restore_context(target
);
899 * Cortex-A8 Core register functions
902 int cortex_a8_load_core_reg_u32(struct target_s
*target
, int num
,
903 armv4_5_mode_t mode
, uint32_t * value
)
906 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
908 if ((num
<= ARM_CPSR
))
910 /* read a normal core register */
911 retval
= cortex_a8_dap_read_coreregister_u32(target
, value
, num
);
913 if (retval
!= ERROR_OK
)
915 LOG_ERROR("JTAG failure %i", retval
);
916 return ERROR_JTAG_DEVICE_ERROR
;
918 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
, num
, *value
);
922 return ERROR_INVALID_ARGUMENTS
;
925 /* Register other than r0 - r14 uses r0 for access */
927 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
928 armv4_5
->core_mode
, 0).dirty
=
929 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
930 armv4_5
->core_mode
, 0).valid
;
931 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
932 armv4_5
->core_mode
, 15).dirty
=
933 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
934 armv4_5
->core_mode
, 15).valid
;
939 int cortex_a8_store_core_reg_u32(struct target_s
*target
, int num
,
940 armv4_5_mode_t mode
, uint32_t value
)
944 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
946 #ifdef ARMV7_GDB_HACKS
947 /* If the LR register is being modified, make sure it will put us
948 * in "thumb" mode, or an INVSTATE exception will occur. This is a
949 * hack to deal with the fact that gdb will sometimes "forge"
950 * return addresses, and doesn't set the LSB correctly (i.e., when
951 * printing expressions containing function calls, it sets LR=0.) */
957 if ((num
<= ARM_CPSR
))
959 retval
= cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
960 if (retval
!= ERROR_OK
)
962 LOG_ERROR("JTAG failure %i", retval
);
963 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
964 armv4_5
->core_mode
, num
).dirty
=
965 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
966 armv4_5
->core_mode
, num
).valid
;
967 return ERROR_JTAG_DEVICE_ERROR
;
969 LOG_DEBUG("write core reg %i value 0x%" PRIx32
, num
, value
);
973 return ERROR_INVALID_ARGUMENTS
;
980 int cortex_a8_read_core_reg(struct target_s
*target
, int num
,
981 enum armv4_5_mode mode
)
985 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
987 cortex_a8_dap_read_coreregister_u32(target
, &value
, num
);
989 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
994 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
995 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
996 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
997 mode
, num
).value
, 0, 32, value
);
1002 int cortex_a8_write_core_reg(struct target_s
*target
, int num
,
1003 enum armv4_5_mode mode
, uint32_t value
)
1006 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
1008 cortex_a8_dap_write_coreregister_u32(target
, value
, num
);
1009 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
1014 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).valid
= 1;
1015 ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
, mode
, num
).dirty
= 0;
1022 * Cortex-A8 Breakpoint and watchpoint fuctions
1025 /* Setup hardware Breakpoint Register Pair */
1026 int cortex_a8_set_breakpoint(struct target_s
*target
,
1027 breakpoint_t
*breakpoint
, uint8_t matchmode
)
1032 uint8_t byte_addr_select
= 0x0F;
1033 struct cortex_a8_common_s
*cortex_a8
= target_to_cortex_a8(target
);
1034 struct armv7a_common_s
*armv7a
= &cortex_a8
->armv7a_common
;
1035 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
1037 if (breakpoint
->set
)
1039 LOG_WARNING("breakpoint already set");
1043 if (breakpoint
->type
== BKPT_HARD
)
1045 while (brp_list
[brp_i
].used
&& (brp_i
< cortex_a8
->brp_num
))
1047 if (brp_i
>= cortex_a8
->brp_num
)
1049 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1052 breakpoint
->set
= brp_i
+ 1;
1053 if (breakpoint
->length
== 2)
1055 byte_addr_select
= (3 << (breakpoint
->address
& 0x02));
1057 control
= ((matchmode
& 0x7) << 20)
1058 | (byte_addr_select
<< 5)
1060 brp_list
[brp_i
].used
= 1;
1061 brp_list
[brp_i
].value
= (breakpoint
->address
& 0xFFFFFFFC);
1062 brp_list
[brp_i
].control
= control
;
1063 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1064 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1065 brp_list
[brp_i
].value
);
1066 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1067 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1068 brp_list
[brp_i
].control
);
1069 LOG_DEBUG("brp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1070 brp_list
[brp_i
].control
,
1071 brp_list
[brp_i
].value
);
1073 else if (breakpoint
->type
== BKPT_SOFT
)
1076 if (breakpoint
->length
== 2)
1078 buf_set_u32(code
, 0, 32, ARMV5_T_BKPT(0x11));
1082 buf_set_u32(code
, 0, 32, ARMV5_BKPT(0x11));
1084 retval
= target
->type
->read_memory(target
,
1085 breakpoint
->address
& 0xFFFFFFFE,
1086 breakpoint
->length
, 1,
1087 breakpoint
->orig_instr
);
1088 if (retval
!= ERROR_OK
)
1090 retval
= target
->type
->write_memory(target
,
1091 breakpoint
->address
& 0xFFFFFFFE,
1092 breakpoint
->length
, 1, code
);
1093 if (retval
!= ERROR_OK
)
1095 breakpoint
->set
= 0x11; /* Any nice value but 0 */
1101 int cortex_a8_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1104 struct cortex_a8_common_s
*cortex_a8
= target_to_cortex_a8(target
);
1105 struct armv7a_common_s
*armv7a
= &cortex_a8
->armv7a_common
;
1106 cortex_a8_brp_t
* brp_list
= cortex_a8
->brp_list
;
1108 if (!breakpoint
->set
)
1110 LOG_WARNING("breakpoint not set");
1114 if (breakpoint
->type
== BKPT_HARD
)
1116 int brp_i
= breakpoint
->set
- 1;
1117 if ((brp_i
< 0) || (brp_i
>= cortex_a8
->brp_num
))
1119 LOG_DEBUG("Invalid BRP number in breakpoint");
1122 LOG_DEBUG("rbp %i control 0x%0" PRIx32
" value 0x%0" PRIx32
, brp_i
,
1123 brp_list
[brp_i
].control
, brp_list
[brp_i
].value
);
1124 brp_list
[brp_i
].used
= 0;
1125 brp_list
[brp_i
].value
= 0;
1126 brp_list
[brp_i
].control
= 0;
1127 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1128 + CPUDBG_BCR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1129 brp_list
[brp_i
].control
);
1130 cortex_a8_dap_write_memap_register_u32(target
, armv7a
->debug_base
1131 + CPUDBG_BVR_BASE
+ 4 * brp_list
[brp_i
].BRPn
,
1132 brp_list
[brp_i
].value
);
1136 /* restore original instruction (kept in target endianness) */
1137 if (breakpoint
->length
== 4)
1139 retval
= target
->type
->write_memory(target
,
1140 breakpoint
->address
& 0xFFFFFFFE,
1141 4, 1, breakpoint
->orig_instr
);
1142 if (retval
!= ERROR_OK
)
1147 retval
= target
->type
->write_memory(target
,
1148 breakpoint
->address
& 0xFFFFFFFE,
1149 2, 1, breakpoint
->orig_instr
);
1150 if (retval
!= ERROR_OK
)
1154 breakpoint
->set
= 0;
1159 int cortex_a8_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1161 struct cortex_a8_common_s
*cortex_a8
= target_to_cortex_a8(target
);
1163 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_a8
->brp_num_available
< 1))
1165 LOG_INFO("no hardware breakpoint available");
1166 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1169 if (breakpoint
->type
== BKPT_HARD
)
1170 cortex_a8
->brp_num_available
--;
1171 cortex_a8_set_breakpoint(target
, breakpoint
, 0x00); /* Exact match */
1176 int cortex_a8_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1178 struct cortex_a8_common_s
*cortex_a8
= target_to_cortex_a8(target
);
1181 /* It is perfectly possible to remove brakpoints while the taget is running */
1182 if (target
->state
!= TARGET_HALTED
)
1184 LOG_WARNING("target not halted");
1185 return ERROR_TARGET_NOT_HALTED
;
1189 if (breakpoint
->set
)
1191 cortex_a8_unset_breakpoint(target
, breakpoint
);
1192 if (breakpoint
->type
== BKPT_HARD
)
1193 cortex_a8
->brp_num_available
++ ;
1203 * Cortex-A8 Reset fuctions
1206 int cortex_a8_assert_reset(target_t
*target
)
1211 /* registers are now invalid */
1212 armv4_5_invalidate_core_regs(target
);
1214 target
->state
= TARGET_RESET
;
1219 int cortex_a8_deassert_reset(target_t
*target
)
1224 if (target
->reset_halt
)
1227 if ((retval
= target_halt(target
)) != ERROR_OK
)
1235 * Cortex-A8 Memory access
1237 * This is same Cortex M3 but we must also use the correct
1238 * ap number for every access.
1241 int cortex_a8_read_memory(struct target_s
*target
, uint32_t address
,
1242 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1244 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
1245 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1247 int retval
= ERROR_OK
;
1249 /* sanitize arguments */
1250 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1251 return ERROR_INVALID_ARGUMENTS
;
1253 /* cortex_a8 handles unaligned memory access */
1255 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1260 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1263 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1266 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1269 LOG_ERROR("BUG: we shouldn't get here");
1276 int cortex_a8_write_memory(struct target_s
*target
, uint32_t address
,
1277 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1279 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
1280 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1284 /* sanitize arguments */
1285 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1286 return ERROR_INVALID_ARGUMENTS
;
1288 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1293 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1296 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1299 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1302 LOG_ERROR("BUG: we shouldn't get here");
1306 if (target
->state
== TARGET_HALTED
)
1308 /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */
1309 /* invalidate I-Cache */
1310 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
)
1312 /* Invalidate ICache single entry with MVA, repeat this for all cache
1313 lines in the address range, Cortex-A8 has fixed 64 byte line length */
1314 /* Invalidate Cache single entry with MVA to PoU */
1315 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1316 armv7a
->write_cp15(target
, 0, 1, 7, 5, cacheline
); /* I-Cache to PoU */
1318 /* invalidate D-Cache */
1319 if (armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
)
1321 /* Invalidate Cache single entry with MVA to PoC */
1322 for (uint32_t cacheline
=address
; cacheline
<address
+size
*count
; cacheline
+=64)
1323 armv7a
->write_cp15(target
, 0, 1, 7, 6, cacheline
); /* U/D cache to PoC */
1330 int cortex_a8_bulk_write_memory(target_t
*target
, uint32_t address
,
1331 uint32_t count
, uint8_t *buffer
)
1333 return cortex_a8_write_memory(target
, address
, 4, count
, buffer
);
1337 int cortex_a8_dcc_read(swjdp_common_t
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1342 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1343 *ctrl
= (uint8_t)dcrdr
;
1344 *value
= (uint8_t)(dcrdr
>> 8);
1346 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1348 /* write ack back to software dcc register
1349 * signify we have read data */
1350 if (dcrdr
& (1 << 0))
1353 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1360 int cortex_a8_handle_target_request(void *priv
)
1362 target_t
*target
= priv
;
1363 if (!target
->type
->examined
)
1365 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
1366 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1368 if (!target
->dbg_msg_enabled
)
1371 if (target
->state
== TARGET_RUNNING
)
1376 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1378 /* check if we have data */
1379 if (ctrl
& (1 << 0))
1383 /* we assume target is quick enough */
1385 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1386 request
|= (data
<< 8);
1387 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1388 request
|= (data
<< 16);
1389 cortex_a8_dcc_read(swjdp
, &data
, &ctrl
);
1390 request
|= (data
<< 24);
1391 target_request(target
, request
);
1399 * Cortex-A8 target information and configuration
1402 int cortex_a8_examine(struct target_s
*target
)
1404 struct cortex_a8_common_s
*cortex_a8
= target_to_cortex_a8(target
);
1405 struct armv7a_common_s
*armv7a
= &cortex_a8
->armv7a_common
;
1406 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1408 int retval
= ERROR_OK
;
1409 uint32_t didr
, ctypr
, ttypr
, cpuid
;
1413 /* Here we shall insert a proper ROM Table scan */
1414 armv7a
->debug_base
= OMAP3530_DEBUG_BASE
;
1416 /* We do one extra read to ensure DAP is configured,
1417 * we call ahbap_debugport_init(swjdp) instead
1419 ahbap_debugport_init(swjdp
);
1420 mem_ap_read_atomic_u32(swjdp
, armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
);
1421 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1422 armv7a
->debug_base
+ CPUDBG_CPUID
, &cpuid
)) != ERROR_OK
)
1424 LOG_DEBUG("Examine failed");
1428 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1429 armv7a
->debug_base
+ CPUDBG_CTYPR
, &ctypr
)) != ERROR_OK
)
1431 LOG_DEBUG("Examine failed");
1435 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1436 armv7a
->debug_base
+ CPUDBG_TTYPR
, &ttypr
)) != ERROR_OK
)
1438 LOG_DEBUG("Examine failed");
1442 if ((retval
= mem_ap_read_atomic_u32(swjdp
,
1443 armv7a
->debug_base
+ CPUDBG_DIDR
, &didr
)) != ERROR_OK
)
1445 LOG_DEBUG("Examine failed");
1449 LOG_DEBUG("cpuid = 0x%08" PRIx32
, cpuid
);
1450 LOG_DEBUG("ctypr = 0x%08" PRIx32
, ctypr
);
1451 LOG_DEBUG("ttypr = 0x%08" PRIx32
, ttypr
);
1452 LOG_DEBUG("didr = 0x%08" PRIx32
, didr
);
1454 /* Setup Breakpoint Register Pairs */
1455 cortex_a8
->brp_num
= ((didr
>> 24) & 0x0F) + 1;
1456 cortex_a8
->brp_num_context
= ((didr
>> 20) & 0x0F) + 1;
1457 cortex_a8
->brp_num_available
= cortex_a8
->brp_num
;
1458 cortex_a8
->brp_list
= calloc(cortex_a8
->brp_num
, sizeof(cortex_a8_brp_t
));
1459 // cortex_a8->brb_enabled = ????;
1460 for (i
= 0; i
< cortex_a8
->brp_num
; i
++)
1462 cortex_a8
->brp_list
[i
].used
= 0;
1463 if (i
< (cortex_a8
->brp_num
-cortex_a8
->brp_num_context
))
1464 cortex_a8
->brp_list
[i
].type
= BRP_NORMAL
;
1466 cortex_a8
->brp_list
[i
].type
= BRP_CONTEXT
;
1467 cortex_a8
->brp_list
[i
].value
= 0;
1468 cortex_a8
->brp_list
[i
].control
= 0;
1469 cortex_a8
->brp_list
[i
].BRPn
= i
;
1472 /* Setup Watchpoint Register Pairs */
1473 cortex_a8
->wrp_num
= ((didr
>> 28) & 0x0F) + 1;
1474 cortex_a8
->wrp_num_available
= cortex_a8
->wrp_num
;
1475 cortex_a8
->wrp_list
= calloc(cortex_a8
->wrp_num
, sizeof(cortex_a8_wrp_t
));
1476 for (i
= 0; i
< cortex_a8
->wrp_num
; i
++)
1478 cortex_a8
->wrp_list
[i
].used
= 0;
1479 cortex_a8
->wrp_list
[i
].type
= 0;
1480 cortex_a8
->wrp_list
[i
].value
= 0;
1481 cortex_a8
->wrp_list
[i
].control
= 0;
1482 cortex_a8
->wrp_list
[i
].WRPn
= i
;
1484 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1485 cortex_a8
->brp_num
, cortex_a8
->wrp_num
);
1487 /* Configure core debug access */
1488 cortex_a8_init_debug_access(target
);
1490 target
->type
->examined
= 1;
1496 * Cortex-A8 target creation and initialization
1499 void cortex_a8_build_reg_cache(target_t
*target
)
1501 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
1502 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
1504 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
1505 armv4_5
->core_cache
= (*cache_p
);
1509 int cortex_a8_init_target(struct command_context_s
*cmd_ctx
,
1510 struct target_s
*target
)
1512 cortex_a8_build_reg_cache(target
);
1516 int cortex_a8_init_arch_info(target_t
*target
,
1517 cortex_a8_common_t
*cortex_a8
, jtag_tap_t
*tap
)
1519 armv4_5_common_t
*armv4_5
;
1520 armv7a_common_t
*armv7a
;
1522 armv7a
= &cortex_a8
->armv7a_common
;
1523 armv4_5
= &armv7a
->armv4_5_common
;
1524 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
1526 /* Setup cortex_a8_common_t */
1527 cortex_a8
->common_magic
= CORTEX_A8_COMMON_MAGIC
;
1528 armv4_5
->arch_info
= armv7a
;
1530 armv4_5_init_arch_info(target
, armv4_5
);
1532 /* prepare JTAG information for the new target */
1533 cortex_a8
->jtag_info
.tap
= tap
;
1534 cortex_a8
->jtag_info
.scann_size
= 4;
1536 swjdp
->dp_select_value
= -1;
1537 swjdp
->ap_csw_value
= -1;
1538 swjdp
->ap_tar_value
= -1;
1539 swjdp
->jtag_info
= &cortex_a8
->jtag_info
;
1540 swjdp
->memaccess_tck
= 80;
1542 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1543 swjdp
->tar_autoincr_block
= (1 << 10);
1545 cortex_a8
->fast_reg_read
= 0;
1548 /* register arch-specific functions */
1549 armv7a
->examine_debug_reason
= NULL
;
1551 armv7a
->post_debug_entry
= cortex_a8_post_debug_entry
;
1553 armv7a
->pre_restore_context
= NULL
;
1554 armv7a
->post_restore_context
= NULL
;
1555 armv7a
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
1556 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1557 armv7a
->armv4_5_mmu
.read_memory
= cortex_a8_read_memory
;
1558 armv7a
->armv4_5_mmu
.write_memory
= cortex_a8_write_memory
;
1559 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1560 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1561 armv7a
->armv4_5_mmu
.has_tiny_pages
= 1;
1562 armv7a
->armv4_5_mmu
.mmu_enabled
= 0;
1563 armv7a
->read_cp15
= cortex_a8_read_cp15
;
1564 armv7a
->write_cp15
= cortex_a8_write_cp15
;
1567 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1569 armv4_5
->read_core_reg
= cortex_a8_read_core_reg
;
1570 armv4_5
->write_core_reg
= cortex_a8_write_core_reg
;
1571 // armv4_5->full_context = arm7_9_full_context;
1573 // armv4_5->load_core_reg_u32 = cortex_a8_load_core_reg_u32;
1574 // armv4_5->store_core_reg_u32 = cortex_a8_store_core_reg_u32;
1575 // armv4_5->read_core_reg = armv4_5_read_core_reg; /* this is default */
1576 // armv4_5->write_core_reg = armv4_5_write_core_reg;
1578 target_register_timer_callback(cortex_a8_handle_target_request
, 1, 1, target
);
1583 int cortex_a8_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1585 cortex_a8_common_t
*cortex_a8
= calloc(1, sizeof(cortex_a8_common_t
));
1587 cortex_a8_init_arch_info(target
, cortex_a8
, target
->tap
);
1592 static int cortex_a8_handle_cache_info_command(struct command_context_s
*cmd_ctx
,
1593 char *cmd
, char **args
, int argc
)
1595 target_t
*target
= get_current_target(cmd_ctx
);
1596 struct armv7a_common_s
*armv7a
= target_to_armv7a(target
);
1598 return armv4_5_handle_cache_info_command(cmd_ctx
,
1599 &armv7a
->armv4_5_mmu
.armv4_5_cache
);
1603 static int cortex_a8_handle_dbginit_command(struct command_context_s
*cmd_ctx
,
1604 char *cmd
, char **args
, int argc
)
1606 target_t
*target
= get_current_target(cmd_ctx
);
1608 cortex_a8_init_debug_access(target
);
1614 int cortex_a8_register_commands(struct command_context_s
*cmd_ctx
)
1616 command_t
*cortex_a8_cmd
;
1617 int retval
= ERROR_OK
;
1619 armv4_5_register_commands(cmd_ctx
);
1620 armv7a_register_commands(cmd_ctx
);
1622 cortex_a8_cmd
= register_command(cmd_ctx
, NULL
, "cortex_a8",
1624 "cortex_a8 specific commands");
1626 register_command(cmd_ctx
, cortex_a8_cmd
, "cache_info",
1627 cortex_a8_handle_cache_info_command
, COMMAND_EXEC
,
1628 "display information about target caches");
1630 register_command(cmd_ctx
, cortex_a8_cmd
, "dbginit",
1631 cortex_a8_handle_dbginit_command
, COMMAND_EXEC
,
1632 "Initialize core debug");
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)