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

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)