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

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)