Cortex-A8: minor cleanup
[openocd.git] / src / target / cortex_a8.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2006 by Magnus Lundin *
6 * lundin@mlu.mine.nu *
7 * *
8 * Copyright (C) 2008 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
10 * *
11 * Copyright (C) 2009 by Dirk Behme *
12 * dirk.behme@gmail.com - copy from cortex_m3 *
13 * *
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. *
18 * *
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. *
23 * *
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. *
28 * *
29 * Cortex-A8(tm) TRM, ARM DDI 0344H *
30 * *
31 ***************************************************************************/
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #include "breakpoints.h"
37 #include "cortex_a8.h"
38 #include "register.h"
39 #include "target_request.h"
40 #include "target_type.h"
41
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);
53 /*
54 * FIXME do topology discovery using the ROM; don't
55 * assume this is an OMAP3.
56 */
57 #define swjdp_memoryap 0
58 #define swjdp_debugap 1
59 #define OMAP3530_DEBUG_BASE 0x54011000
60
61 /*
62 * Cortex-A8 Basic debug access, very low level assumes state is saved
63 */
64 static int cortex_a8_init_debug_access(struct target *target)
65 {
66 struct armv7a_common *armv7a = target_to_armv7a(target);
67 struct swjdp_common *swjdp = &armv7a->swjdp_info;
68
69 int retval;
70 uint32_t dummy;
71
72 LOG_DEBUG(" ");
73
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 */
83
84 /* Resync breakpoint registers */
85
86 /* Since this is likley called from init or reset, update targtet state information*/
87 cortex_a8_poll(target);
88
89 return retval;
90 }
91
92 /* FIXME we waste a *LOT* of round-trips with needless DSCR reads, which
93 * slows down operations considerably. One good way to start reducing
94 * them would pass current values into and out of this routine. That
95 * should also help synch DCC read/write.
96 */
97 static int cortex_a8_exec_opcode(struct target *target, uint32_t opcode)
98 {
99 uint32_t dscr;
100 int retval;
101 struct armv7a_common *armv7a = target_to_armv7a(target);
102 struct swjdp_common *swjdp = &armv7a->swjdp_info;
103
104 LOG_DEBUG("exec opcode 0x%08" PRIx32, opcode);
105 do
106 {
107 retval = mem_ap_read_atomic_u32(swjdp,
108 armv7a->debug_base + CPUDBG_DSCR, &dscr);
109 if (retval != ERROR_OK)
110 {
111 LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32, opcode);
112 return retval;
113 }
114 }
115 while ((dscr & (1 << DSCR_INSTR_COMP)) == 0); /* Wait for InstrCompl bit to be set */
116
117 mem_ap_write_u32(swjdp, armv7a->debug_base + CPUDBG_ITR, opcode);
118
119 do
120 {
121 retval = mem_ap_read_atomic_u32(swjdp,
122 armv7a->debug_base + CPUDBG_DSCR, &dscr);
123 if (retval != ERROR_OK)
124 {
125 LOG_ERROR("Could not read DSCR register");
126 return retval;
127 }
128 }
129 while ((dscr & (1 << DSCR_INSTR_COMP)) == 0); /* Wait for InstrCompl bit to be set */
130
131 return retval;
132 }
133
134 /**************************************************************************
135 Read core register with very few exec_opcode, fast but needs work_area.
136 This can cause problems with MMU active.
137 **************************************************************************/
138 static int cortex_a8_read_regs_through_mem(struct target *target, uint32_t address,
139 uint32_t * regfile)
140 {
141 int retval = ERROR_OK;
142 struct armv7a_common *armv7a = target_to_armv7a(target);
143 struct swjdp_common *swjdp = &armv7a->swjdp_info;
144
145 cortex_a8_dap_read_coreregister_u32(target, regfile, 0);
146 cortex_a8_dap_write_coreregister_u32(target, address, 0);
147 cortex_a8_exec_opcode(target, ARMV4_5_STMIA(0, 0xFFFE, 0, 0));
148 dap_ap_select(swjdp, swjdp_memoryap);
149 mem_ap_read_buf_u32(swjdp, (uint8_t *)(&regfile[1]), 4*15, address);
150 dap_ap_select(swjdp, swjdp_debugap);
151
152 return retval;
153 }
154
155 static int cortex_a8_read_cp(struct target *target, uint32_t *value, uint8_t CP,
156 uint8_t op1, uint8_t CRn, uint8_t CRm, uint8_t op2)
157 {
158 int retval;
159 struct armv7a_common *armv7a = target_to_armv7a(target);
160 struct swjdp_common *swjdp = &armv7a->swjdp_info;
161
162 cortex_a8_exec_opcode(target, ARMV4_5_MRC(CP, op1, 0, CRn, CRm, op2));
163 /* Move R0 to DTRTX */
164 cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
165
166 /* Read DCCTX */
167 retval = mem_ap_read_atomic_u32(swjdp,
168 armv7a->debug_base + CPUDBG_DTRTX, value);
169
170 return retval;
171 }
172
173 static int cortex_a8_write_cp(struct target *target, uint32_t value,
174 uint8_t CP, uint8_t op1, uint8_t CRn, uint8_t CRm, uint8_t op2)
175 {
176 int retval;
177 uint32_t dscr;
178 struct armv7a_common *armv7a = target_to_armv7a(target);
179 struct swjdp_common *swjdp = &armv7a->swjdp_info;
180
181 LOG_DEBUG("CP%i, CRn %i, value 0x%08" PRIx32, CP, CRn, value);
182
183 /* Check that DCCRX is not full */
184 retval = mem_ap_read_atomic_u32(swjdp,
185 armv7a->debug_base + CPUDBG_DSCR, &dscr);
186 if (dscr & (1 << DSCR_DTR_RX_FULL))
187 {
188 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32, dscr);
189 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
190 cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
191 }
192
193 retval = mem_ap_write_u32(swjdp,
194 armv7a->debug_base + CPUDBG_DTRRX, value);
195 /* Move DTRRX to r0 */
196 cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
197
198 cortex_a8_exec_opcode(target, ARMV4_5_MCR(CP, op1, 0, CRn, CRm, op2));
199 return retval;
200 }
201
202 static int cortex_a8_read_cp15(struct target *target, uint32_t op1, uint32_t op2,
203 uint32_t CRn, uint32_t CRm, uint32_t *value)
204 {
205 return cortex_a8_read_cp(target, value, 15, op1, CRn, CRm, op2);
206 }
207
208 static int cortex_a8_write_cp15(struct target *target, uint32_t op1, uint32_t op2,
209 uint32_t CRn, uint32_t CRm, uint32_t value)
210 {
211 return cortex_a8_write_cp(target, value, 15, op1, CRn, CRm, op2);
212 }
213
214 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)
215 {
216 if (cpnum!=15)
217 {
218 LOG_ERROR("Only cp15 is supported");
219 return ERROR_FAIL;
220 }
221 return cortex_a8_read_cp15(target, op1, op2, CRn, CRm, value);
222 }
223
224 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)
225 {
226 if (cpnum!=15)
227 {
228 LOG_ERROR("Only cp15 is supported");
229 return ERROR_FAIL;
230 }
231 return cortex_a8_write_cp15(target, op1, op2, CRn, CRm, value);
232 }
233
234
235
236 static int cortex_a8_dap_read_coreregister_u32(struct target *target,
237 uint32_t *value, int regnum)
238 {
239 int retval = ERROR_OK;
240 uint8_t reg = regnum&0xFF;
241 uint32_t dscr;
242 struct armv7a_common *armv7a = target_to_armv7a(target);
243 struct swjdp_common *swjdp = &armv7a->swjdp_info;
244
245 if (reg > 17)
246 return retval;
247
248 if (reg < 15)
249 {
250 /* Rn to DCCTX, "MCR p14, 0, Rn, c0, c5, 0" 0xEE00nE15 */
251 cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, reg, 0, 5, 0));
252 }
253 else if (reg == 15)
254 {
255 /* "MOV r0, r15"; then move r0 to DCCTX */
256 cortex_a8_exec_opcode(target, 0xE1A0000F);
257 cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
258 }
259 else
260 {
261 /* "MRS r0, CPSR" or "MRS r0, SPSR"
262 * then move r0 to DCCTX
263 */
264 cortex_a8_exec_opcode(target, ARMV4_5_MRS(0, reg & 1));
265 cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
266 }
267
268 /* Read DTRRTX */
269 do
270 {
271 retval = mem_ap_read_atomic_u32(swjdp,
272 armv7a->debug_base + CPUDBG_DSCR, &dscr);
273 }
274 while ((dscr & (1 << DSCR_DTR_TX_FULL)) == 0); /* Wait for DTRRXfull */
275
276 retval = mem_ap_read_atomic_u32(swjdp,
277 armv7a->debug_base + CPUDBG_DTRTX, value);
278 LOG_DEBUG("read DCC 0x%08" PRIx32, *value);
279
280 return retval;
281 }
282
283 static int cortex_a8_dap_write_coreregister_u32(struct target *target,
284 uint32_t value, int regnum)
285 {
286 int retval = ERROR_OK;
287 uint8_t Rd = regnum&0xFF;
288 uint32_t dscr;
289 struct armv7a_common *armv7a = target_to_armv7a(target);
290 struct swjdp_common *swjdp = &armv7a->swjdp_info;
291
292 LOG_DEBUG("register %i, value 0x%08" PRIx32, regnum, value);
293
294 /* Check that DCCRX is not full */
295 retval = mem_ap_read_atomic_u32(swjdp,
296 armv7a->debug_base + CPUDBG_DSCR, &dscr);
297 if (dscr & (1 << DSCR_DTR_RX_FULL))
298 {
299 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32, dscr);
300 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
301 cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
302 }
303
304 if (Rd > 17)
305 return retval;
306
307 /* Write to DCCRX */
308 LOG_DEBUG("write DCC 0x%08" PRIx32, value);
309 retval = mem_ap_write_u32(swjdp,
310 armv7a->debug_base + CPUDBG_DTRRX, value);
311
312 if (Rd < 15)
313 {
314 /* DCCRX to Rn, "MCR p14, 0, Rn, c0, c5, 0", 0xEE00nE15 */
315 cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, Rd, 0, 5, 0));
316 }
317 else if (Rd == 15)
318 {
319 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15
320 * then "mov r15, r0"
321 */
322 cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
323 cortex_a8_exec_opcode(target, 0xE1A0F000);
324 }
325 else
326 {
327 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15
328 * then "MSR CPSR_cxsf, r0" or "MSR SPSR_cxsf, r0" (all fields)
329 */
330 cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
331 cortex_a8_exec_opcode(target, ARMV4_5_MSR_GP(0, 0xF, Rd & 1));
332
333 /* "Prefetch flush" after modifying execution status in CPSR */
334 if (Rd == 16)
335 cortex_a8_exec_opcode(target,
336 ARMV4_5_MCR(15, 0, 0, 7, 5, 4));
337 }
338
339 return retval;
340 }
341
342 /* Write to memory mapped registers directly with no cache or mmu handling */
343 static int cortex_a8_dap_write_memap_register_u32(struct target *target, uint32_t address, uint32_t value)
344 {
345 int retval;
346 struct armv7a_common *armv7a = target_to_armv7a(target);
347 struct swjdp_common *swjdp = &armv7a->swjdp_info;
348
349 retval = mem_ap_write_atomic_u32(swjdp, address, value);
350
351 return retval;
352 }
353
354 /*
355 * Cortex-A8 Run control
356 */
357
358 static int cortex_a8_poll(struct target *target)
359 {
360 int retval = ERROR_OK;
361 uint32_t dscr;
362 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
363 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
364 struct swjdp_common *swjdp = &armv7a->swjdp_info;
365 enum target_state prev_target_state = target->state;
366 uint8_t saved_apsel = dap_ap_get_select(swjdp);
367
368 dap_ap_select(swjdp, swjdp_debugap);
369 retval = mem_ap_read_atomic_u32(swjdp,
370 armv7a->debug_base + CPUDBG_DSCR, &dscr);
371 if (retval != ERROR_OK)
372 {
373 dap_ap_select(swjdp, saved_apsel);
374 return retval;
375 }
376 cortex_a8->cpudbg_dscr = dscr;
377
378 if ((dscr & 0x3) == 0x3)
379 {
380 if (prev_target_state != TARGET_HALTED)
381 {
382 /* We have a halting debug event */
383 LOG_DEBUG("Target halted");
384 target->state = TARGET_HALTED;
385 if ((prev_target_state == TARGET_RUNNING)
386 || (prev_target_state == TARGET_RESET))
387 {
388 retval = cortex_a8_debug_entry(target);
389 if (retval != ERROR_OK)
390 return retval;
391
392 target_call_event_callbacks(target,
393 TARGET_EVENT_HALTED);
394 }
395 if (prev_target_state == TARGET_DEBUG_RUNNING)
396 {
397 LOG_DEBUG(" ");
398
399 retval = cortex_a8_debug_entry(target);
400 if (retval != ERROR_OK)
401 return retval;
402
403 target_call_event_callbacks(target,
404 TARGET_EVENT_DEBUG_HALTED);
405 }
406 }
407 }
408 else if ((dscr & 0x3) == 0x2)
409 {
410 target->state = TARGET_RUNNING;
411 }
412 else
413 {
414 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32, dscr);
415 target->state = TARGET_UNKNOWN;
416 }
417
418 dap_ap_select(swjdp, saved_apsel);
419
420 return retval;
421 }
422
423 static int cortex_a8_halt(struct target *target)
424 {
425 int retval = ERROR_OK;
426 uint32_t dscr;
427 struct armv7a_common *armv7a = target_to_armv7a(target);
428 struct swjdp_common *swjdp = &armv7a->swjdp_info;
429 uint8_t saved_apsel = dap_ap_get_select(swjdp);
430 dap_ap_select(swjdp, swjdp_debugap);
431
432 /*
433 * Tell the core to be halted by writing DRCR with 0x1
434 * and then wait for the core to be halted.
435 */
436 retval = mem_ap_write_atomic_u32(swjdp,
437 armv7a->debug_base + CPUDBG_DRCR, 0x1);
438
439 /*
440 * enter halting debug mode
441 */
442 mem_ap_read_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_DSCR, &dscr);
443 retval = mem_ap_write_atomic_u32(swjdp,
444 armv7a->debug_base + CPUDBG_DSCR, dscr | (1 << DSCR_HALT_DBG_MODE));
445
446 if (retval != ERROR_OK)
447 goto out;
448
449 do {
450 mem_ap_read_atomic_u32(swjdp,
451 armv7a->debug_base + CPUDBG_DSCR, &dscr);
452 } while ((dscr & (1 << DSCR_CORE_HALTED)) == 0);
453
454 target->debug_reason = DBG_REASON_DBGRQ;
455
456 out:
457 dap_ap_select(swjdp, saved_apsel);
458 return retval;
459 }
460
461 static int cortex_a8_resume(struct target *target, int current,
462 uint32_t address, int handle_breakpoints, int debug_execution)
463 {
464 struct armv7a_common *armv7a = target_to_armv7a(target);
465 struct arm *armv4_5 = &armv7a->armv4_5_common;
466 struct swjdp_common *swjdp = &armv7a->swjdp_info;
467
468 // struct breakpoint *breakpoint = NULL;
469 uint32_t resume_pc, dscr;
470
471 uint8_t saved_apsel = dap_ap_get_select(swjdp);
472 dap_ap_select(swjdp, swjdp_debugap);
473
474 if (!debug_execution)
475 {
476 target_free_all_working_areas(target);
477 // cortex_m3_enable_breakpoints(target);
478 // cortex_m3_enable_watchpoints(target);
479 }
480
481 #if 0
482 if (debug_execution)
483 {
484 /* Disable interrupts */
485 /* We disable interrupts in the PRIMASK register instead of
486 * masking with C_MASKINTS,
487 * This is probably the same issue as Cortex-M3 Errata 377493:
488 * C_MASKINTS in parallel with disabled interrupts can cause
489 * local faults to not be taken. */
490 buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_PRIMASK].value, 0, 32, 1);
491 armv7m->core_cache->reg_list[ARMV7M_PRIMASK].dirty = 1;
492 armv7m->core_cache->reg_list[ARMV7M_PRIMASK].valid = 1;
493
494 /* Make sure we are in Thumb mode */
495 buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32,
496 buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32) | (1 << 24));
497 armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty = 1;
498 armv7m->core_cache->reg_list[ARMV7M_xPSR].valid = 1;
499 }
500 #endif
501
502 /* current = 1: continue on current pc, otherwise continue at <address> */
503 resume_pc = buf_get_u32(
504 armv4_5->core_cache->reg_list[15].value,
505 0, 32);
506 if (!current)
507 resume_pc = address;
508
509 /* Make sure that the Armv7 gdb thumb fixups does not
510 * kill the return address
511 */
512 switch (armv4_5->core_state)
513 {
514 case ARMV4_5_STATE_ARM:
515 resume_pc &= 0xFFFFFFFC;
516 break;
517 case ARMV4_5_STATE_THUMB:
518 case ARM_STATE_THUMB_EE:
519 /* When the return address is loaded into PC
520 * bit 0 must be 1 to stay in Thumb state
521 */
522 resume_pc |= 0x1;
523 break;
524 case ARMV4_5_STATE_JAZELLE:
525 LOG_ERROR("How do I resume into Jazelle state??");
526 return ERROR_FAIL;
527 }
528 LOG_DEBUG("resume pc = 0x%08" PRIx32, resume_pc);
529 buf_set_u32(armv4_5->core_cache->reg_list[15].value,
530 0, 32, resume_pc);
531 armv4_5->core_cache->reg_list[15].dirty = 1;
532 armv4_5->core_cache->reg_list[15].valid = 1;
533
534 cortex_a8_restore_context(target);
535
536 #if 0
537 /* the front-end may request us not to handle breakpoints */
538 if (handle_breakpoints)
539 {
540 /* Single step past breakpoint at current address */
541 if ((breakpoint = breakpoint_find(target, resume_pc)))
542 {
543 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint->address);
544 cortex_m3_unset_breakpoint(target, breakpoint);
545 cortex_m3_single_step_core(target);
546 cortex_m3_set_breakpoint(target, breakpoint);
547 }
548 }
549
550 #endif
551 /* Restart core and wait for it to be started */
552 mem_ap_write_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_DRCR, 0x2);
553
554 do {
555 mem_ap_read_atomic_u32(swjdp,
556 armv7a->debug_base + CPUDBG_DSCR, &dscr);
557 } while ((dscr & (1 << DSCR_CORE_RESTARTED)) == 0);
558
559 target->debug_reason = DBG_REASON_NOTHALTED;
560 target->state = TARGET_RUNNING;
561
562 /* registers are now invalid */
563 register_cache_invalidate(armv4_5->core_cache);
564
565 if (!debug_execution)
566 {
567 target->state = TARGET_RUNNING;
568 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
569 LOG_DEBUG("target resumed at 0x%" PRIx32, resume_pc);
570 }
571 else
572 {
573 target->state = TARGET_DEBUG_RUNNING;
574 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
575 LOG_DEBUG("target debug resumed at 0x%" PRIx32, resume_pc);
576 }
577
578 dap_ap_select(swjdp, saved_apsel);
579
580 return ERROR_OK;
581 }
582
583 static int cortex_a8_debug_entry(struct target *target)
584 {
585 int i;
586 uint32_t regfile[16], pc, cpsr, dscr;
587 int retval = ERROR_OK;
588 struct working_area *regfile_working_area = NULL;
589 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
590 struct armv7a_common *armv7a = target_to_armv7a(target);
591 struct arm *armv4_5 = &armv7a->armv4_5_common;
592 struct swjdp_common *swjdp = &armv7a->swjdp_info;
593 struct reg *reg;
594
595 LOG_DEBUG("dscr = 0x%08" PRIx32, cortex_a8->cpudbg_dscr);
596
597 /* Enable the ITR execution once we are in debug mode */
598 mem_ap_read_atomic_u32(swjdp,
599 armv7a->debug_base + CPUDBG_DSCR, &dscr);
600
601 /* REVISIT see A8 TRM 12.11.4 steps 2..3 -- make sure that any
602 * imprecise data aborts get discarded by issuing a Data
603 * Synchronization Barrier: ARMV4_5_MCR(15, 0, 0, 7, 10, 4).
604 */
605
606 dscr |= (1 << DSCR_EXT_INT_EN);
607 retval = mem_ap_write_atomic_u32(swjdp,
608 armv7a->debug_base + CPUDBG_DSCR, dscr);
609
610 /* Examine debug reason */
611 switch ((cortex_a8->cpudbg_dscr >> 2)&0xF)
612 {
613 case 0: /* DRCR[0] write */
614 case 4: /* EDBGRQ */
615 target->debug_reason = DBG_REASON_DBGRQ;
616 break;
617 case 1: /* HW breakpoint */
618 case 3: /* SW BKPT */
619 case 5: /* vector catch */
620 target->debug_reason = DBG_REASON_BREAKPOINT;
621 break;
622 case 10: /* precise watchpoint */
623 target->debug_reason = DBG_REASON_WATCHPOINT;
624 /* REVISIT could collect WFAR later, to see just
625 * which instruction triggered the watchpoint.
626 */
627 break;
628 default:
629 target->debug_reason = DBG_REASON_UNDEFINED;
630 break;
631 }
632
633 /* REVISIT fast_reg_read is never set ... */
634
635 /* Examine target state and mode */
636 if (cortex_a8->fast_reg_read)
637 target_alloc_working_area(target, 64, &regfile_working_area);
638
639 /* First load register acessible through core debug port*/
640 if (!regfile_working_area)
641 {
642 /* FIXME we don't actually need all these registers;
643 * reading them slows us down. Just R0, PC, CPSR...
644 */
645 for (i = 0; i <= 15; i++)
646 cortex_a8_dap_read_coreregister_u32(target,
647 &regfile[i], i);
648 }
649 else
650 {
651 dap_ap_select(swjdp, swjdp_memoryap);
652 cortex_a8_read_regs_through_mem(target,
653 regfile_working_area->address, regfile);
654 dap_ap_select(swjdp, swjdp_memoryap);
655 target_free_working_area(target, regfile_working_area);
656 }
657
658 /* read Current PSR */
659 cortex_a8_dap_read_coreregister_u32(target, &cpsr, 16);
660 pc = regfile[15];
661 dap_ap_select(swjdp, swjdp_debugap);
662 LOG_DEBUG("cpsr: %8.8" PRIx32, cpsr);
663
664 arm_set_cpsr(armv4_5, cpsr);
665
666 /* update cache */
667 for (i = 0; i <= ARM_PC; i++)
668 {
669 reg = arm_reg_current(armv4_5, i);
670
671 buf_set_u32(reg->value, 0, 32, regfile[i]);
672 reg->valid = 1;
673 reg->dirty = 0;
674 }
675
676 /* Fixup PC Resume Address */
677 if (cpsr & (1 << 5))
678 {
679 // T bit set for Thumb or ThumbEE state
680 regfile[ARM_PC] -= 4;
681 }
682 else
683 {
684 // ARM state
685 regfile[ARM_PC] -= 8;
686 }
687
688 reg = armv4_5->core_cache->reg_list + 15;
689 buf_set_u32(reg->value, 0, 32, regfile[ARM_PC]);
690 reg->dirty = reg->valid;
691 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 15)
692 .dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
693 armv4_5->core_mode, 15).valid;
694
695 #if 0
696 /* TODO, Move this */
697 uint32_t cp15_control_register, cp15_cacr, cp15_nacr;
698 cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
699 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register);
700
701 cortex_a8_read_cp(target, &cp15_cacr, 15, 0, 1, 0, 2);
702 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr);
703
704 cortex_a8_read_cp(target, &cp15_nacr, 15, 0, 1, 1, 2);
705 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr);
706 #endif
707
708 /* Are we in an exception handler */
709 // armv4_5->exception_number = 0;
710 if (armv7a->post_debug_entry)
711 armv7a->post_debug_entry(target);
712
713
714
715 return retval;
716
717 }
718
719 static void cortex_a8_post_debug_entry(struct target *target)
720 {
721 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
722 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
723
724 // cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
725 /* examine cp15 control reg */
726 armv7a->read_cp15(target, 0, 0, 1, 0, &cortex_a8->cp15_control_reg);
727 jtag_execute_queue();
728 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32, cortex_a8->cp15_control_reg);
729
730 if (armv7a->armv4_5_mmu.armv4_5_cache.ctype == -1)
731 {
732 uint32_t cache_type_reg;
733 /* identify caches */
734 armv7a->read_cp15(target, 0, 1, 0, 0, &cache_type_reg);
735 jtag_execute_queue();
736 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
737 armv4_5_identify_cache(cache_type_reg,
738 &armv7a->armv4_5_mmu.armv4_5_cache);
739 }
740
741 armv7a->armv4_5_mmu.mmu_enabled =
742 (cortex_a8->cp15_control_reg & 0x1U) ? 1 : 0;
743 armv7a->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled =
744 (cortex_a8->cp15_control_reg & 0x4U) ? 1 : 0;
745 armv7a->armv4_5_mmu.armv4_5_cache.i_cache_enabled =
746 (cortex_a8->cp15_control_reg & 0x1000U) ? 1 : 0;
747
748
749 }
750
751 static int cortex_a8_step(struct target *target, int current, uint32_t address,
752 int handle_breakpoints)
753 {
754 struct armv7a_common *armv7a = target_to_armv7a(target);
755 struct arm *armv4_5 = &armv7a->armv4_5_common;
756 struct breakpoint *breakpoint = NULL;
757 struct breakpoint stepbreakpoint;
758 struct reg *r;
759
760 int timeout = 100;
761
762 if (target->state != TARGET_HALTED)
763 {
764 LOG_WARNING("target not halted");
765 return ERROR_TARGET_NOT_HALTED;
766 }
767
768 /* current = 1: continue on current pc, otherwise continue at <address> */
769 r = armv4_5->core_cache->reg_list + 15;
770 if (!current)
771 {
772 buf_set_u32(r->value, 0, 32, address);
773 }
774 else
775 {
776 address = buf_get_u32(r->value, 0, 32);
777 }
778
779 /* The front-end may request us not to handle breakpoints.
780 * But since Cortex-A8 uses breakpoint for single step,
781 * we MUST handle breakpoints.
782 */
783 handle_breakpoints = 1;
784 if (handle_breakpoints) {
785 breakpoint = breakpoint_find(target, address);
786 if (breakpoint)
787 cortex_a8_unset_breakpoint(target, breakpoint);
788 }
789
790 /* Setup single step breakpoint */
791 stepbreakpoint.address = address;
792 stepbreakpoint.length = (armv4_5->core_state == ARMV4_5_STATE_THUMB)
793 ? 2 : 4;
794 stepbreakpoint.type = BKPT_HARD;
795 stepbreakpoint.set = 0;
796
797 /* Break on IVA mismatch */
798 cortex_a8_set_breakpoint(target, &stepbreakpoint, 0x04);
799
800 target->debug_reason = DBG_REASON_SINGLESTEP;
801
802 cortex_a8_resume(target, 1, address, 0, 0);
803
804 while (target->state != TARGET_HALTED)
805 {
806 cortex_a8_poll(target);
807 if (--timeout == 0)
808 {
809 LOG_WARNING("timeout waiting for target halt");
810 break;
811 }
812 }
813
814 cortex_a8_unset_breakpoint(target, &stepbreakpoint);
815 if (timeout > 0) target->debug_reason = DBG_REASON_BREAKPOINT;
816
817 if (breakpoint)
818 cortex_a8_set_breakpoint(target, breakpoint, 0);
819
820 if (target->state != TARGET_HALTED)
821 LOG_DEBUG("target stepped");
822
823 return ERROR_OK;
824 }
825
826 static int cortex_a8_restore_context(struct target *target)
827 {
828 uint32_t value;
829 struct armv7a_common *armv7a = target_to_armv7a(target);
830 struct reg_cache *cache = armv7a->armv4_5_common.core_cache;
831 unsigned max = cache->num_regs;
832 struct reg *r;
833 bool flushed, flush_cpsr = false;
834
835 LOG_DEBUG(" ");
836
837 if (armv7a->pre_restore_context)
838 armv7a->pre_restore_context(target);
839
840 /* Flush all dirty registers from the cache, one mode at a time so
841 * that we write CPSR as little as possible. Save CPSR and R0 for
842 * last; they're used to change modes and write other registers.
843 *
844 * REVISIT be smarter: save eventual mode for last loop, don't
845 * need to write CPSR an extra time.
846 */
847 do {
848 enum armv4_5_mode mode = ARMV4_5_MODE_ANY;
849 unsigned i;
850
851 flushed = false;
852
853 /* write dirty non-{R0,CPSR} registers sharing the same mode */
854 for (i = max - 1, r = cache->reg_list + 1; i > 0; i--, r++) {
855 struct arm_reg *reg;
856
857 if (!r->dirty || r == armv7a->armv4_5_common.cpsr)
858 continue;
859 reg = r->arch_info;
860
861 /* TODO Check return values */
862
863 /* Pick a mode and update CPSR; else ignore this
864 * register if it's for a different mode than what
865 * we're handling on this pass.
866 *
867 * REVISIT don't distinguish SYS and USR modes.
868 *
869 * FIXME if we restore from FIQ mode, R8..R12 will
870 * get wrongly flushed onto FIQ shadows...
871 */
872 if (mode == ARMV4_5_MODE_ANY) {
873 mode = reg->mode;
874 if (mode != ARMV4_5_MODE_ANY) {
875 cortex_a8_dap_write_coreregister_u32(
876 target, mode, 16);
877 flush_cpsr = true;
878 }
879 } else if (mode != reg->mode)
880 continue;
881
882 /* Write this register */
883 value = buf_get_u32(r->value, 0, 32);
884 cortex_a8_dap_write_coreregister_u32(target, value,
885 (reg->num == 16) ? 17 : reg->num);
886 r->dirty = false;
887 flushed = true;
888 }
889
890 } while (flushed);
891
892 /* now flush CPSR if needed ... */
893 r = armv7a->armv4_5_common.cpsr;
894 if (flush_cpsr || r->dirty) {
895 value = buf_get_u32(r->value, 0, 32);
896 cortex_a8_dap_write_coreregister_u32(target, value, 16);
897 r->dirty = false;
898 }
899
900 /* ... and R0 always (it was dirtied when we saved context) */
901 r = cache->reg_list + 0;
902 value = buf_get_u32(r->value, 0, 32);
903 cortex_a8_dap_write_coreregister_u32(target, value, 0);
904 r->dirty = false;
905
906 if (armv7a->post_restore_context)
907 armv7a->post_restore_context(target);
908
909 return ERROR_OK;
910 }
911
912
913 #if 0
914 /*
915 * Cortex-A8 Core register functions
916 */
917 static int cortex_a8_load_core_reg_u32(struct target *target, int num,
918 armv4_5_mode_t mode, uint32_t * value)
919 {
920 int retval;
921 struct arm *armv4_5 = target_to_armv4_5(target);
922
923 if ((num <= ARM_CPSR))
924 {
925 /* read a normal core register */
926 retval = cortex_a8_dap_read_coreregister_u32(target, value, num);
927
928 if (retval != ERROR_OK)
929 {
930 LOG_ERROR("JTAG failure %i", retval);
931 return ERROR_JTAG_DEVICE_ERROR;
932 }
933 LOG_DEBUG("load from core reg %i value 0x%" PRIx32, num, *value);
934 }
935 else
936 {
937 return ERROR_INVALID_ARGUMENTS;
938 }
939
940 /* Register other than r0 - r14 uses r0 for access */
941 if (num > 14)
942 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
943 armv4_5->core_mode, 0).dirty =
944 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
945 armv4_5->core_mode, 0).valid;
946 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
947 armv4_5->core_mode, 15).dirty =
948 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
949 armv4_5->core_mode, 15).valid;
950
951 return ERROR_OK;
952 }
953
954 static int cortex_a8_store_core_reg_u32(struct target *target, int num,
955 armv4_5_mode_t mode, uint32_t value)
956 {
957 int retval;
958 // uint32_t reg;
959 struct arm *armv4_5 = target_to_armv4_5(target);
960
961 #ifdef ARMV7_GDB_HACKS
962 /* If the LR register is being modified, make sure it will put us
963 * in "thumb" mode, or an INVSTATE exception will occur. This is a
964 * hack to deal with the fact that gdb will sometimes "forge"
965 * return addresses, and doesn't set the LSB correctly (i.e., when
966 * printing expressions containing function calls, it sets LR=0.) */
967
968 if (num == 14)
969 value |= 0x01;
970 #endif
971
972 if ((num <= ARM_CPSR))
973 {
974 retval = cortex_a8_dap_write_coreregister_u32(target, value, num);
975 if (retval != ERROR_OK)
976 {
977 LOG_ERROR("JTAG failure %i", retval);
978 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
979 armv4_5->core_mode, num).dirty =
980 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
981 armv4_5->core_mode, num).valid;
982 return ERROR_JTAG_DEVICE_ERROR;
983 }
984 LOG_DEBUG("write core reg %i value 0x%" PRIx32, num, value);
985 }
986 else
987 {
988 return ERROR_INVALID_ARGUMENTS;
989 }
990
991 return ERROR_OK;
992 }
993 #endif
994
995
996 static int cortex_a8_write_core_reg(struct target *target, struct reg *r,
997 int num, enum armv4_5_mode mode, uint32_t value);
998
999 static int cortex_a8_read_core_reg(struct target *target, struct reg *r,
1000 int num, enum armv4_5_mode mode)
1001 {
1002 uint32_t value;
1003 int retval;
1004 struct arm *armv4_5 = target_to_armv4_5(target);
1005 struct reg *cpsr_r = NULL;
1006 uint32_t cpsr = 0;
1007 unsigned cookie = num;
1008
1009 /* avoid some needless mode changes
1010 * FIXME move some of these to shared ARM code...
1011 */
1012 if (mode != armv4_5->core_mode) {
1013 if ((armv4_5->core_mode == ARMV4_5_MODE_SYS)
1014 && (mode == ARMV4_5_MODE_USR))
1015 mode = ARMV4_5_MODE_ANY;
1016 else if ((mode != ARMV4_5_MODE_FIQ) && (num <= 12))
1017 mode = ARMV4_5_MODE_ANY;
1018
1019 if (mode != ARMV4_5_MODE_ANY) {
1020 cpsr_r = armv4_5->cpsr;
1021 cpsr = buf_get_u32(cpsr_r->value, 0, 32);
1022 cortex_a8_write_core_reg(target, cpsr_r,
1023 16, ARMV4_5_MODE_ANY, mode);
1024 }
1025 }
1026
1027 if (num == 16) {
1028 switch (mode) {
1029 case ARMV4_5_MODE_USR:
1030 case ARMV4_5_MODE_SYS:
1031 case ARMV4_5_MODE_ANY:
1032 /* CPSR */
1033 break;
1034 default:
1035 /* SPSR */
1036 cookie++;
1037 break;
1038 }
1039 }
1040
1041 cortex_a8_dap_read_coreregister_u32(target, &value, cookie);
1042 retval = jtag_execute_queue();
1043 if (retval == ERROR_OK) {
1044 r->valid = 1;
1045 r->dirty = 0;
1046 buf_set_u32(r->value, 0, 32, value);
1047 }
1048
1049 if (cpsr_r)
1050 cortex_a8_write_core_reg(target, cpsr_r,
1051 16, ARMV4_5_MODE_ANY, cpsr);
1052 return retval;
1053 }
1054
1055 static int cortex_a8_write_core_reg(struct target *target, struct reg *r,
1056 int num, enum armv4_5_mode mode, uint32_t value)
1057 {
1058 int retval;
1059 struct arm *armv4_5 = target_to_armv4_5(target);
1060 struct reg *cpsr_r = NULL;
1061 uint32_t cpsr = 0;
1062 unsigned cookie = num;
1063
1064 /* avoid some needless mode changes
1065 * FIXME move some of these to shared ARM code...
1066 */
1067 if (mode != armv4_5->core_mode) {
1068 if ((armv4_5->core_mode == ARMV4_5_MODE_SYS)
1069 && (mode == ARMV4_5_MODE_USR))
1070 mode = ARMV4_5_MODE_ANY;
1071 else if ((mode != ARMV4_5_MODE_FIQ) && (num <= 12))
1072 mode = ARMV4_5_MODE_ANY;
1073
1074 if (mode != ARMV4_5_MODE_ANY) {
1075 cpsr_r = armv4_5->cpsr;
1076 cpsr = buf_get_u32(cpsr_r->value, 0, 32);
1077 cortex_a8_write_core_reg(target, cpsr_r,
1078 16, ARMV4_5_MODE_ANY, mode);
1079 }
1080 }
1081
1082
1083 if (num == 16) {
1084 switch (mode) {
1085 case ARMV4_5_MODE_USR:
1086 case ARMV4_5_MODE_SYS:
1087 case ARMV4_5_MODE_ANY:
1088 /* CPSR */
1089 break;
1090 default:
1091 /* SPSR */
1092 cookie++;
1093 break;
1094 }
1095 }
1096
1097 cortex_a8_dap_write_coreregister_u32(target, value, cookie);
1098 if ((retval = jtag_execute_queue()) == ERROR_OK) {
1099 buf_set_u32(r->value, 0, 32, value);
1100 r->valid = 1;
1101 r->dirty = 0;
1102 }
1103
1104 if (cpsr_r)
1105 cortex_a8_write_core_reg(target, cpsr_r,
1106 16, ARMV4_5_MODE_ANY, cpsr);
1107 return retval;
1108 }
1109
1110
1111 /*
1112 * Cortex-A8 Breakpoint and watchpoint fuctions
1113 */
1114
1115 /* Setup hardware Breakpoint Register Pair */
1116 static int cortex_a8_set_breakpoint(struct target *target,
1117 struct breakpoint *breakpoint, uint8_t matchmode)
1118 {
1119 int retval;
1120 int brp_i=0;
1121 uint32_t control;
1122 uint8_t byte_addr_select = 0x0F;
1123 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
1124 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
1125 struct cortex_a8_brp * brp_list = cortex_a8->brp_list;
1126
1127 if (breakpoint->set)
1128 {
1129 LOG_WARNING("breakpoint already set");
1130 return ERROR_OK;
1131 }
1132
1133 if (breakpoint->type == BKPT_HARD)
1134 {
1135 while (brp_list[brp_i].used && (brp_i < cortex_a8->brp_num))
1136 brp_i++ ;
1137 if (brp_i >= cortex_a8->brp_num)
1138 {
1139 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1140 return ERROR_FAIL;
1141 }
1142 breakpoint->set = brp_i + 1;
1143 if (breakpoint->length == 2)
1144 {
1145 byte_addr_select = (3 << (breakpoint->address & 0x02));
1146 }
1147 control = ((matchmode & 0x7) << 20)
1148 | (byte_addr_select << 5)
1149 | (3 << 1) | 1;
1150 brp_list[brp_i].used = 1;
1151 brp_list[brp_i].value = (breakpoint->address & 0xFFFFFFFC);
1152 brp_list[brp_i].control = control;
1153 cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
1154 + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn,
1155 brp_list[brp_i].value);
1156 cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
1157 + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn,
1158 brp_list[brp_i].control);
1159 LOG_DEBUG("brp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_i,
1160 brp_list[brp_i].control,
1161 brp_list[brp_i].value);
1162 }
1163 else if (breakpoint->type == BKPT_SOFT)
1164 {
1165 uint8_t code[4];
1166 if (breakpoint->length == 2)
1167 {
1168 buf_set_u32(code, 0, 32, ARMV5_T_BKPT(0x11));
1169 }
1170 else
1171 {
1172 buf_set_u32(code, 0, 32, ARMV5_BKPT(0x11));
1173 }
1174 retval = target->type->read_memory(target,
1175 breakpoint->address & 0xFFFFFFFE,
1176 breakpoint->length, 1,
1177 breakpoint->orig_instr);
1178 if (retval != ERROR_OK)
1179 return retval;
1180 retval = target->type->write_memory(target,
1181 breakpoint->address & 0xFFFFFFFE,
1182 breakpoint->length, 1, code);
1183 if (retval != ERROR_OK)
1184 return retval;
1185 breakpoint->set = 0x11; /* Any nice value but 0 */
1186 }
1187
1188 return ERROR_OK;
1189 }
1190
1191 static int cortex_a8_unset_breakpoint(struct target *target, struct breakpoint *breakpoint)
1192 {
1193 int retval;
1194 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
1195 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
1196 struct cortex_a8_brp * brp_list = cortex_a8->brp_list;
1197
1198 if (!breakpoint->set)
1199 {
1200 LOG_WARNING("breakpoint not set");
1201 return ERROR_OK;
1202 }
1203
1204 if (breakpoint->type == BKPT_HARD)
1205 {
1206 int brp_i = breakpoint->set - 1;
1207 if ((brp_i < 0) || (brp_i >= cortex_a8->brp_num))
1208 {
1209 LOG_DEBUG("Invalid BRP number in breakpoint");
1210 return ERROR_OK;
1211 }
1212 LOG_DEBUG("rbp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_i,
1213 brp_list[brp_i].control, brp_list[brp_i].value);
1214 brp_list[brp_i].used = 0;
1215 brp_list[brp_i].value = 0;
1216 brp_list[brp_i].control = 0;
1217 cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
1218 + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn,
1219 brp_list[brp_i].control);
1220 cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
1221 + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn,
1222 brp_list[brp_i].value);
1223 }
1224 else
1225 {
1226 /* restore original instruction (kept in target endianness) */
1227 if (breakpoint->length == 4)
1228 {
1229 retval = target->type->write_memory(target,
1230 breakpoint->address & 0xFFFFFFFE,
1231 4, 1, breakpoint->orig_instr);
1232 if (retval != ERROR_OK)
1233 return retval;
1234 }
1235 else
1236 {
1237 retval = target->type->write_memory(target,
1238 breakpoint->address & 0xFFFFFFFE,
1239 2, 1, breakpoint->orig_instr);
1240 if (retval != ERROR_OK)
1241 return retval;
1242 }
1243 }
1244 breakpoint->set = 0;
1245
1246 return ERROR_OK;
1247 }
1248
1249 static int cortex_a8_add_breakpoint(struct target *target,
1250 struct breakpoint *breakpoint)
1251 {
1252 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
1253
1254 if ((breakpoint->type == BKPT_HARD) && (cortex_a8->brp_num_available < 1))
1255 {
1256 LOG_INFO("no hardware breakpoint available");
1257 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1258 }
1259
1260 if (breakpoint->type == BKPT_HARD)
1261 cortex_a8->brp_num_available--;
1262 cortex_a8_set_breakpoint(target, breakpoint, 0x00); /* Exact match */
1263
1264 return ERROR_OK;
1265 }
1266
1267 static int cortex_a8_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)
1268 {
1269 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
1270
1271 #if 0
1272 /* It is perfectly possible to remove brakpoints while the taget is running */
1273 if (target->state != TARGET_HALTED)
1274 {
1275 LOG_WARNING("target not halted");
1276 return ERROR_TARGET_NOT_HALTED;
1277 }
1278 #endif
1279
1280 if (breakpoint->set)
1281 {
1282 cortex_a8_unset_breakpoint(target, breakpoint);
1283 if (breakpoint->type == BKPT_HARD)
1284 cortex_a8->brp_num_available++ ;
1285 }
1286
1287
1288 return ERROR_OK;
1289 }
1290
1291
1292
1293 /*
1294 * Cortex-A8 Reset fuctions
1295 */
1296
1297 static int cortex_a8_assert_reset(struct target *target)
1298 {
1299 struct armv7a_common *armv7a = target_to_armv7a(target);
1300
1301 LOG_DEBUG(" ");
1302
1303 /* registers are now invalid */
1304 register_cache_invalidate(armv7a->armv4_5_common.core_cache);
1305
1306 target->state = TARGET_RESET;
1307
1308 return ERROR_OK;
1309 }
1310
1311 static int cortex_a8_deassert_reset(struct target *target)
1312 {
1313
1314 LOG_DEBUG(" ");
1315
1316 if (target->reset_halt)
1317 {
1318 int retval;
1319 if ((retval = target_halt(target)) != ERROR_OK)
1320 return retval;
1321 }
1322
1323 return ERROR_OK;
1324 }
1325
1326 /*
1327 * Cortex-A8 Memory access
1328 *
1329 * This is same Cortex M3 but we must also use the correct
1330 * ap number for every access.
1331 */
1332
1333 static int cortex_a8_read_memory(struct target *target, uint32_t address,
1334 uint32_t size, uint32_t count, uint8_t *buffer)
1335 {
1336 struct armv7a_common *armv7a = target_to_armv7a(target);
1337 struct swjdp_common *swjdp = &armv7a->swjdp_info;
1338 int retval = ERROR_INVALID_ARGUMENTS;
1339
1340 /* cortex_a8 handles unaligned memory access */
1341
1342 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1343
1344 if (count && buffer) {
1345 switch (size) {
1346 case 4:
1347 retval = mem_ap_read_buf_u32(swjdp, buffer, 4 * count, address);
1348 break;
1349 case 2:
1350 retval = mem_ap_read_buf_u16(swjdp, buffer, 2 * count, address);
1351 break;
1352 case 1:
1353 retval = mem_ap_read_buf_u8(swjdp, buffer, count, address);
1354 break;
1355 }
1356 }
1357
1358 return retval;
1359 }
1360
1361 static int cortex_a8_write_memory(struct target *target, uint32_t address,
1362 uint32_t size, uint32_t count, uint8_t *buffer)
1363 {
1364 struct armv7a_common *armv7a = target_to_armv7a(target);
1365 struct swjdp_common *swjdp = &armv7a->swjdp_info;
1366 int retval = ERROR_INVALID_ARGUMENTS;
1367
1368 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1369
1370 if (count && buffer) {
1371 switch (size) {
1372 case 4:
1373 retval = mem_ap_write_buf_u32(swjdp, buffer, 4 * count, address);
1374 break;
1375 case 2:
1376 retval = mem_ap_write_buf_u16(swjdp, buffer, 2 * count, address);
1377 break;
1378 case 1:
1379 retval = mem_ap_write_buf_u8(swjdp, buffer, count, address);
1380 break;
1381 }
1382 }
1383
1384 if (retval == ERROR_OK && target->state == TARGET_HALTED)
1385 {
1386 /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */
1387 /* invalidate I-Cache */
1388 if (armv7a->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
1389 {
1390 /* Invalidate ICache single entry with MVA, repeat this for all cache
1391 lines in the address range, Cortex-A8 has fixed 64 byte line length */
1392 /* Invalidate Cache single entry with MVA to PoU */
1393 for (uint32_t cacheline=address; cacheline<address+size*count; cacheline+=64)
1394 armv7a->write_cp15(target, 0, 1, 7, 5, cacheline); /* I-Cache to PoU */
1395 }
1396 /* invalidate D-Cache */
1397 if (armv7a->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled)
1398 {
1399 /* Invalidate Cache single entry with MVA to PoC */
1400 for (uint32_t cacheline=address; cacheline<address+size*count; cacheline+=64)
1401 armv7a->write_cp15(target, 0, 1, 7, 6, cacheline); /* U/D cache to PoC */
1402 }
1403 }
1404
1405 return retval;
1406 }
1407
1408 static int cortex_a8_bulk_write_memory(struct target *target, uint32_t address,
1409 uint32_t count, uint8_t *buffer)
1410 {
1411 return cortex_a8_write_memory(target, address, 4, count, buffer);
1412 }
1413
1414
1415 static int cortex_a8_dcc_read(struct swjdp_common *swjdp, uint8_t *value, uint8_t *ctrl)
1416 {
1417 #if 0
1418 u16 dcrdr;
1419
1420 mem_ap_read_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
1421 *ctrl = (uint8_t)dcrdr;
1422 *value = (uint8_t)(dcrdr >> 8);
1423
1424 LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
1425
1426 /* write ack back to software dcc register
1427 * signify we have read data */
1428 if (dcrdr & (1 << 0))
1429 {
1430 dcrdr = 0;
1431 mem_ap_write_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
1432 }
1433 #endif
1434 return ERROR_OK;
1435 }
1436
1437
1438 static int cortex_a8_handle_target_request(void *priv)
1439 {
1440 struct target *target = priv;
1441 struct armv7a_common *armv7a = target_to_armv7a(target);
1442 struct swjdp_common *swjdp = &armv7a->swjdp_info;
1443
1444 if (!target_was_examined(target))
1445 return ERROR_OK;
1446 if (!target->dbg_msg_enabled)
1447 return ERROR_OK;
1448
1449 if (target->state == TARGET_RUNNING)
1450 {
1451 uint8_t data = 0;
1452 uint8_t ctrl = 0;
1453
1454 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1455
1456 /* check if we have data */
1457 if (ctrl & (1 << 0))
1458 {
1459 uint32_t request;
1460
1461 /* we assume target is quick enough */
1462 request = data;
1463 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1464 request |= (data << 8);
1465 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1466 request |= (data << 16);
1467 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1468 request |= (data << 24);
1469 target_request(target, request);
1470 }
1471 }
1472
1473 return ERROR_OK;
1474 }
1475
1476 /*
1477 * Cortex-A8 target information and configuration
1478 */
1479
1480 static int cortex_a8_examine_first(struct target *target)
1481 {
1482 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
1483 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
1484 struct swjdp_common *swjdp = &armv7a->swjdp_info;
1485 int i;
1486 int retval = ERROR_OK;
1487 uint32_t didr, ctypr, ttypr, cpuid;
1488
1489 LOG_DEBUG("TODO");
1490
1491 /* Here we shall insert a proper ROM Table scan */
1492 armv7a->debug_base = OMAP3530_DEBUG_BASE;
1493
1494 /* We do one extra read to ensure DAP is configured,
1495 * we call ahbap_debugport_init(swjdp) instead
1496 */
1497 ahbap_debugport_init(swjdp);
1498 mem_ap_read_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_CPUID, &cpuid);
1499 if ((retval = mem_ap_read_atomic_u32(swjdp,
1500 armv7a->debug_base + CPUDBG_CPUID, &cpuid)) != ERROR_OK)
1501 {
1502 LOG_DEBUG("Examine failed");
1503 return retval;
1504 }
1505
1506 if ((retval = mem_ap_read_atomic_u32(swjdp,
1507 armv7a->debug_base + CPUDBG_CTYPR, &ctypr)) != ERROR_OK)
1508 {
1509 LOG_DEBUG("Examine failed");
1510 return retval;
1511 }
1512
1513 if ((retval = mem_ap_read_atomic_u32(swjdp,
1514 armv7a->debug_base + CPUDBG_TTYPR, &ttypr)) != ERROR_OK)
1515 {
1516 LOG_DEBUG("Examine failed");
1517 return retval;
1518 }
1519
1520 if ((retval = mem_ap_read_atomic_u32(swjdp,
1521 armv7a->debug_base + CPUDBG_DIDR, &didr)) != ERROR_OK)
1522 {
1523 LOG_DEBUG("Examine failed");
1524 return retval;
1525 }
1526
1527 LOG_DEBUG("cpuid = 0x%08" PRIx32, cpuid);
1528 LOG_DEBUG("ctypr = 0x%08" PRIx32, ctypr);
1529 LOG_DEBUG("ttypr = 0x%08" PRIx32, ttypr);
1530 LOG_DEBUG("didr = 0x%08" PRIx32, didr);
1531
1532 /* Setup Breakpoint Register Pairs */
1533 cortex_a8->brp_num = ((didr >> 24) & 0x0F) + 1;
1534 cortex_a8->brp_num_context = ((didr >> 20) & 0x0F) + 1;
1535 cortex_a8->brp_num_available = cortex_a8->brp_num;
1536 cortex_a8->brp_list = calloc(cortex_a8->brp_num, sizeof(struct cortex_a8_brp));
1537 // cortex_a8->brb_enabled = ????;
1538 for (i = 0; i < cortex_a8->brp_num; i++)
1539 {
1540 cortex_a8->brp_list[i].used = 0;
1541 if (i < (cortex_a8->brp_num-cortex_a8->brp_num_context))
1542 cortex_a8->brp_list[i].type = BRP_NORMAL;
1543 else
1544 cortex_a8->brp_list[i].type = BRP_CONTEXT;
1545 cortex_a8->brp_list[i].value = 0;
1546 cortex_a8->brp_list[i].control = 0;
1547 cortex_a8->brp_list[i].BRPn = i;
1548 }
1549
1550 /* Setup Watchpoint Register Pairs */
1551 cortex_a8->wrp_num = ((didr >> 28) & 0x0F) + 1;
1552 cortex_a8->wrp_num_available = cortex_a8->wrp_num;
1553 cortex_a8->wrp_list = calloc(cortex_a8->wrp_num, sizeof(struct cortex_a8_wrp));
1554 for (i = 0; i < cortex_a8->wrp_num; i++)
1555 {
1556 cortex_a8->wrp_list[i].used = 0;
1557 cortex_a8->wrp_list[i].type = 0;
1558 cortex_a8->wrp_list[i].value = 0;
1559 cortex_a8->wrp_list[i].control = 0;
1560 cortex_a8->wrp_list[i].WRPn = i;
1561 }
1562 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1563 cortex_a8->brp_num , cortex_a8->wrp_num);
1564
1565 target_set_examined(target);
1566 return ERROR_OK;
1567 }
1568
1569 static int cortex_a8_examine(struct target *target)
1570 {
1571 int retval = ERROR_OK;
1572
1573 /* don't re-probe hardware after each reset */
1574 if (!target_was_examined(target))
1575 retval = cortex_a8_examine_first(target);
1576
1577 /* Configure core debug access */
1578 if (retval == ERROR_OK)
1579 retval = cortex_a8_init_debug_access(target);
1580
1581 return retval;
1582 }
1583
1584 /*
1585 * Cortex-A8 target creation and initialization
1586 */
1587
1588 static void cortex_a8_build_reg_cache(struct target *target)
1589 {
1590 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
1591 struct arm *armv4_5 = target_to_armv4_5(target);
1592
1593 armv4_5->core_type = ARM_MODE_MON;
1594
1595 (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
1596 }
1597
1598
1599 static int cortex_a8_init_target(struct command_context *cmd_ctx,
1600 struct target *target)
1601 {
1602 cortex_a8_build_reg_cache(target);
1603 return ERROR_OK;
1604 }
1605
1606 static int cortex_a8_init_arch_info(struct target *target,
1607 struct cortex_a8_common *cortex_a8, struct jtag_tap *tap)
1608 {
1609 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
1610 struct arm *armv4_5 = &armv7a->armv4_5_common;
1611 struct swjdp_common *swjdp = &armv7a->swjdp_info;
1612
1613 /* Setup struct cortex_a8_common */
1614 cortex_a8->common_magic = CORTEX_A8_COMMON_MAGIC;
1615 armv4_5->arch_info = armv7a;
1616
1617 /* prepare JTAG information for the new target */
1618 cortex_a8->jtag_info.tap = tap;
1619 cortex_a8->jtag_info.scann_size = 4;
1620
1621 swjdp->dp_select_value = -1;
1622 swjdp->ap_csw_value = -1;
1623 swjdp->ap_tar_value = -1;
1624 swjdp->jtag_info = &cortex_a8->jtag_info;
1625 swjdp->memaccess_tck = 80;
1626
1627 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1628 swjdp->tar_autoincr_block = (1 << 10);
1629
1630 cortex_a8->fast_reg_read = 0;
1631
1632
1633 /* register arch-specific functions */
1634 armv7a->examine_debug_reason = NULL;
1635
1636 armv7a->post_debug_entry = cortex_a8_post_debug_entry;
1637
1638 armv7a->pre_restore_context = NULL;
1639 armv7a->post_restore_context = NULL;
1640 armv7a->armv4_5_mmu.armv4_5_cache.ctype = -1;
1641 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1642 armv7a->armv4_5_mmu.read_memory = cortex_a8_read_memory;
1643 armv7a->armv4_5_mmu.write_memory = cortex_a8_write_memory;
1644 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1645 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1646 armv7a->armv4_5_mmu.has_tiny_pages = 1;
1647 armv7a->armv4_5_mmu.mmu_enabled = 0;
1648 armv7a->read_cp15 = cortex_a8_read_cp15;
1649 armv7a->write_cp15 = cortex_a8_write_cp15;
1650
1651
1652 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1653
1654 armv4_5->read_core_reg = cortex_a8_read_core_reg;
1655 armv4_5->write_core_reg = cortex_a8_write_core_reg;
1656
1657 /* REVISIT v7a setup should be in a v7a-specific routine */
1658 armv4_5_init_arch_info(target, armv4_5);
1659 armv7a->common_magic = ARMV7_COMMON_MAGIC;
1660
1661 target_register_timer_callback(cortex_a8_handle_target_request, 1, 1, target);
1662
1663 return ERROR_OK;
1664 }
1665
1666 static int cortex_a8_target_create(struct target *target, Jim_Interp *interp)
1667 {
1668 struct cortex_a8_common *cortex_a8 = calloc(1, sizeof(struct cortex_a8_common));
1669
1670 cortex_a8_init_arch_info(target, cortex_a8, target->tap);
1671
1672 return ERROR_OK;
1673 }
1674
1675 COMMAND_HANDLER(cortex_a8_handle_cache_info_command)
1676 {
1677 struct target *target = get_current_target(CMD_CTX);
1678 struct armv7a_common *armv7a = target_to_armv7a(target);
1679
1680 return armv4_5_handle_cache_info_command(CMD_CTX,
1681 &armv7a->armv4_5_mmu.armv4_5_cache);
1682 }
1683
1684
1685 COMMAND_HANDLER(cortex_a8_handle_dbginit_command)
1686 {
1687 struct target *target = get_current_target(CMD_CTX);
1688
1689 cortex_a8_init_debug_access(target);
1690
1691 return ERROR_OK;
1692 }
1693
1694
1695 static int cortex_a8_register_commands(struct command_context *cmd_ctx)
1696 {
1697 struct command *cortex_a8_cmd;
1698 int retval = ERROR_OK;
1699
1700 armv4_5_register_commands(cmd_ctx);
1701 armv7a_register_commands(cmd_ctx);
1702
1703 cortex_a8_cmd = register_command(cmd_ctx, NULL, "cortex_a8",
1704 NULL, COMMAND_ANY,
1705 "cortex_a8 specific commands");
1706
1707 register_command(cmd_ctx, cortex_a8_cmd, "cache_info",
1708 cortex_a8_handle_cache_info_command, COMMAND_EXEC,
1709 "display information about target caches");
1710
1711 register_command(cmd_ctx, cortex_a8_cmd, "dbginit",
1712 cortex_a8_handle_dbginit_command, COMMAND_EXEC,
1713 "Initialize core debug");
1714
1715 return retval;
1716 }
1717
1718 struct target_type cortexa8_target = {
1719 .name = "cortex_a8",
1720
1721 .poll = cortex_a8_poll,
1722 .arch_state = armv7a_arch_state,
1723
1724 .target_request_data = NULL,
1725
1726 .halt = cortex_a8_halt,
1727 .resume = cortex_a8_resume,
1728 .step = cortex_a8_step,
1729
1730 .assert_reset = cortex_a8_assert_reset,
1731 .deassert_reset = cortex_a8_deassert_reset,
1732 .soft_reset_halt = NULL,
1733
1734 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
1735
1736 .read_memory = cortex_a8_read_memory,
1737 .write_memory = cortex_a8_write_memory,
1738 .bulk_write_memory = cortex_a8_bulk_write_memory,
1739
1740 .checksum_memory = arm_checksum_memory,
1741 .blank_check_memory = arm_blank_check_memory,
1742
1743 .run_algorithm = armv4_5_run_algorithm,
1744
1745 .add_breakpoint = cortex_a8_add_breakpoint,
1746 .remove_breakpoint = cortex_a8_remove_breakpoint,
1747 .add_watchpoint = NULL,
1748 .remove_watchpoint = NULL,
1749
1750 .register_commands = cortex_a8_register_commands,
1751 .target_create = cortex_a8_target_create,
1752 .init_target = cortex_a8_init_target,
1753 .examine = cortex_a8_examine,
1754 .mrc = cortex_a8_mrc,
1755 .mcr = cortex_a8_mcr,
1756 };

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)