832efe92fa095b322c3cb2a06a91261a56c9fad6
[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 "armv7a.h"
39 #include "armv4_5.h"
40
41 #include "target_request.h"
42 #include "target_type.h"
43
44 static int cortex_a8_poll(struct target *target);
45 static int cortex_a8_debug_entry(struct target *target);
46 static int cortex_a8_restore_context(struct target *target);
47 static int cortex_a8_set_breakpoint(struct target *target,
48 struct breakpoint *breakpoint, uint8_t matchmode);
49 static int cortex_a8_unset_breakpoint(struct target *target,
50 struct breakpoint *breakpoint);
51 static int cortex_a8_dap_read_coreregister_u32(struct target *target,
52 uint32_t *value, int regnum);
53 static int cortex_a8_dap_write_coreregister_u32(struct target *target,
54 uint32_t value, int regnum);
55 /*
56 * FIXME do topology discovery using the ROM; don't
57 * assume this is an OMAP3.
58 */
59 #define swjdp_memoryap 0
60 #define swjdp_debugap 1
61 #define OMAP3530_DEBUG_BASE 0x54011000
62
63 /*
64 * Cortex-A8 Basic debug access, very low level assumes state is saved
65 */
66 static int cortex_a8_init_debug_access(struct target *target)
67 {
68 struct armv7a_common *armv7a = target_to_armv7a(target);
69 struct swjdp_common *swjdp = &armv7a->swjdp_info;
70
71 int retval;
72 uint32_t dummy;
73
74 LOG_DEBUG(" ");
75
76 /* Unlocking the debug registers for modification */
77 /* The debugport might be uninitialised so try twice */
78 retval = mem_ap_write_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_LOCKACCESS, 0xC5ACCE55);
79 if (retval != ERROR_OK)
80 mem_ap_write_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_LOCKACCESS, 0xC5ACCE55);
81 /* Clear Sticky Power Down status Bit in PRSR to enable access to
82 the registers in the Core Power Domain */
83 retval = mem_ap_read_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_PRSR, &dummy);
84 /* Enabling of instruction execution in debug mode is done in debug_entry code */
85
86 /* Resync breakpoint registers */
87
88 /* Since this is likley called from init or reset, update targtet state information*/
89 cortex_a8_poll(target);
90
91 return retval;
92 }
93
94 int cortex_a8_exec_opcode(struct target *target, uint32_t opcode)
95 {
96 uint32_t dscr;
97 int retval;
98 struct armv7a_common *armv7a = target_to_armv7a(target);
99 struct swjdp_common *swjdp = &armv7a->swjdp_info;
100
101 LOG_DEBUG("exec opcode 0x%08" PRIx32, opcode);
102 do
103 {
104 retval = mem_ap_read_atomic_u32(swjdp,
105 armv7a->debug_base + CPUDBG_DSCR, &dscr);
106 if (retval != ERROR_OK)
107 {
108 LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32, opcode);
109 return retval;
110 }
111 }
112 while ((dscr & (1 << DSCR_INSTR_COMP)) == 0); /* Wait for InstrCompl bit to be set */
113
114 mem_ap_write_u32(swjdp, armv7a->debug_base + CPUDBG_ITR, opcode);
115
116 do
117 {
118 retval = mem_ap_read_atomic_u32(swjdp,
119 armv7a->debug_base + CPUDBG_DSCR, &dscr);
120 if (retval != ERROR_OK)
121 {
122 LOG_ERROR("Could not read DSCR register");
123 return retval;
124 }
125 }
126 while ((dscr & (1 << DSCR_INSTR_COMP)) == 0); /* Wait for InstrCompl bit to be set */
127
128 return retval;
129 }
130
131 /**************************************************************************
132 Read core register with very few exec_opcode, fast but needs work_area.
133 This can cause problems with MMU active.
134 **************************************************************************/
135 static int cortex_a8_read_regs_through_mem(struct target *target, uint32_t address,
136 uint32_t * regfile)
137 {
138 int retval = ERROR_OK;
139 struct armv7a_common *armv7a = target_to_armv7a(target);
140 struct swjdp_common *swjdp = &armv7a->swjdp_info;
141
142 cortex_a8_dap_read_coreregister_u32(target, regfile, 0);
143 cortex_a8_dap_write_coreregister_u32(target, address, 0);
144 cortex_a8_exec_opcode(target, ARMV4_5_STMIA(0, 0xFFFE, 0, 0));
145 dap_ap_select(swjdp, swjdp_memoryap);
146 mem_ap_read_buf_u32(swjdp, (uint8_t *)(&regfile[1]), 4*15, address);
147 dap_ap_select(swjdp, swjdp_debugap);
148
149 return retval;
150 }
151
152 static int cortex_a8_read_cp(struct target *target, uint32_t *value, uint8_t CP,
153 uint8_t op1, uint8_t CRn, uint8_t CRm, uint8_t op2)
154 {
155 int retval;
156 struct armv7a_common *armv7a = target_to_armv7a(target);
157 struct swjdp_common *swjdp = &armv7a->swjdp_info;
158
159 cortex_a8_exec_opcode(target, ARMV4_5_MRC(CP, op1, 0, CRn, CRm, op2));
160 /* Move R0 to DTRTX */
161 cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
162
163 /* Read DCCTX */
164 retval = mem_ap_read_atomic_u32(swjdp,
165 armv7a->debug_base + CPUDBG_DTRTX, value);
166
167 return retval;
168 }
169
170 static int cortex_a8_write_cp(struct target *target, uint32_t value,
171 uint8_t CP, uint8_t op1, uint8_t CRn, uint8_t CRm, uint8_t op2)
172 {
173 int retval;
174 uint32_t dscr;
175 struct armv7a_common *armv7a = target_to_armv7a(target);
176 struct swjdp_common *swjdp = &armv7a->swjdp_info;
177
178 LOG_DEBUG("CP%i, CRn %i, value 0x%08" PRIx32, CP, CRn, value);
179
180 /* Check that DCCRX is not full */
181 retval = mem_ap_read_atomic_u32(swjdp,
182 armv7a->debug_base + CPUDBG_DSCR, &dscr);
183 if (dscr & (1 << DSCR_DTR_RX_FULL))
184 {
185 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32, dscr);
186 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
187 cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
188 }
189
190 retval = mem_ap_write_u32(swjdp,
191 armv7a->debug_base + CPUDBG_DTRRX, value);
192 /* Move DTRRX to r0 */
193 cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
194
195 cortex_a8_exec_opcode(target, ARMV4_5_MCR(CP, op1, 0, CRn, CRm, op2));
196 return retval;
197 }
198
199 static int cortex_a8_read_cp15(struct target *target, uint32_t op1, uint32_t op2,
200 uint32_t CRn, uint32_t CRm, uint32_t *value)
201 {
202 return cortex_a8_read_cp(target, value, 15, op1, CRn, CRm, op2);
203 }
204
205 static int cortex_a8_write_cp15(struct target *target, uint32_t op1, uint32_t op2,
206 uint32_t CRn, uint32_t CRm, uint32_t value)
207 {
208 return cortex_a8_write_cp(target, value, 15, op1, CRn, CRm, op2);
209 }
210
211 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)
212 {
213 if (cpnum!=15)
214 {
215 LOG_ERROR("Only cp15 is supported");
216 return ERROR_FAIL;
217 }
218 return cortex_a8_read_cp15(target, op1, op2, CRn, CRm, value);
219 }
220
221 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)
222 {
223 if (cpnum!=15)
224 {
225 LOG_ERROR("Only cp15 is supported");
226 return ERROR_FAIL;
227 }
228 return cortex_a8_write_cp15(target, op1, op2, CRn, CRm, value);
229 }
230
231
232
233 static int cortex_a8_dap_read_coreregister_u32(struct target *target,
234 uint32_t *value, int regnum)
235 {
236 int retval = ERROR_OK;
237 uint8_t reg = regnum&0xFF;
238 uint32_t dscr;
239 struct armv7a_common *armv7a = target_to_armv7a(target);
240 struct swjdp_common *swjdp = &armv7a->swjdp_info;
241
242 if (reg > 16)
243 return retval;
244
245 if (reg < 15)
246 {
247 /* Rn to DCCTX, MCR p14, 0, Rd, c0, c5, 0, 0xEE000E15 */
248 cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, reg, 0, 5, 0));
249 }
250 else if (reg == 15)
251 {
252 cortex_a8_exec_opcode(target, 0xE1A0000F);
253 cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
254 }
255 else if (reg == 16)
256 {
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 ARMV7A_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(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
507 armv4_5->core_mode, 15).value,
508 0, 32, resume_pc);
509 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
510 armv4_5->core_mode, 15).dirty = 1;
511 ARMV7A_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
574 LOG_DEBUG("dscr = 0x%08" PRIx32, cortex_a8->cpudbg_dscr);
575
576 /* Enable the ITR execution once we are in debug mode */
577 mem_ap_read_atomic_u32(swjdp,
578 armv7a->debug_base + CPUDBG_DSCR, &dscr);
579 dscr |= (1 << DSCR_EXT_INT_EN);
580 retval = mem_ap_write_atomic_u32(swjdp,
581 armv7a->debug_base + CPUDBG_DSCR, dscr);
582
583 /* Examine debug reason */
584 switch ((cortex_a8->cpudbg_dscr >> 2)&0xF)
585 {
586 case 0:
587 case 4:
588 target->debug_reason = DBG_REASON_DBGRQ;
589 break;
590 case 1:
591 case 3:
592 target->debug_reason = DBG_REASON_BREAKPOINT;
593 break;
594 case 10:
595 target->debug_reason = DBG_REASON_WATCHPOINT;
596 break;
597 default:
598 target->debug_reason = DBG_REASON_UNDEFINED;
599 break;
600 }
601
602 /* Examine target state and mode */
603 if (cortex_a8->fast_reg_read)
604 target_alloc_working_area(target, 64, &regfile_working_area);
605
606 /* First load register acessible through core debug port*/
607 if (!regfile_working_area)
608 {
609 for (i = 0; i <= 15; i++)
610 cortex_a8_dap_read_coreregister_u32(target,
611 &regfile[i], i);
612 }
613 else
614 {
615 dap_ap_select(swjdp, swjdp_memoryap);
616 cortex_a8_read_regs_through_mem(target,
617 regfile_working_area->address, regfile);
618 dap_ap_select(swjdp, swjdp_memoryap);
619 target_free_working_area(target, regfile_working_area);
620 }
621
622 cortex_a8_dap_read_coreregister_u32(target, &cpsr, 16);
623 pc = regfile[15];
624 dap_ap_select(swjdp, swjdp_debugap);
625 LOG_DEBUG("cpsr: %8.8" PRIx32, cpsr);
626
627 armv4_5->core_mode = cpsr & 0x1F;
628 armv7a->core_state = (cpsr & 0x20)?ARMV7A_STATE_THUMB:ARMV7A_STATE_ARM;
629
630 for (i = 0; i <= ARM_PC; i++)
631 {
632 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
633 armv4_5->core_mode, i).value,
634 0, 32, regfile[i]);
635 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
636 armv4_5->core_mode, i).valid = 1;
637 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
638 armv4_5->core_mode, i).dirty = 0;
639 }
640 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
641 armv4_5->core_mode, 16).value,
642 0, 32, cpsr);
643 ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).valid = 1;
644 ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).dirty = 0;
645
646 /* Fixup PC Resume Address */
647 if (armv7a->core_state == ARMV7A_STATE_THUMB)
648 {
649 // T bit set for Thumb or ThumbEE state
650 regfile[ARM_PC] -= 4;
651 }
652 else
653 {
654 // ARM state
655 regfile[ARM_PC] -= 8;
656 }
657 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
658 armv4_5->core_mode, ARM_PC).value,
659 0, 32, regfile[ARM_PC]);
660
661 ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0)
662 .dirty = ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
663 armv4_5->core_mode, 0).valid;
664 ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 15)
665 .dirty = ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
666 armv4_5->core_mode, 15).valid;
667
668 #if 0
669 /* TODO, Move this */
670 uint32_t cp15_control_register, cp15_cacr, cp15_nacr;
671 cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
672 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register);
673
674 cortex_a8_read_cp(target, &cp15_cacr, 15, 0, 1, 0, 2);
675 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr);
676
677 cortex_a8_read_cp(target, &cp15_nacr, 15, 0, 1, 1, 2);
678 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr);
679 #endif
680
681 /* Are we in an exception handler */
682 // armv4_5->exception_number = 0;
683 if (armv7a->post_debug_entry)
684 armv7a->post_debug_entry(target);
685
686
687
688 return retval;
689
690 }
691
692 static void cortex_a8_post_debug_entry(struct target *target)
693 {
694 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
695 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
696
697 // cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
698 /* examine cp15 control reg */
699 armv7a->read_cp15(target, 0, 0, 1, 0, &cortex_a8->cp15_control_reg);
700 jtag_execute_queue();
701 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32, cortex_a8->cp15_control_reg);
702
703 if (armv7a->armv4_5_mmu.armv4_5_cache.ctype == -1)
704 {
705 uint32_t cache_type_reg;
706 /* identify caches */
707 armv7a->read_cp15(target, 0, 1, 0, 0, &cache_type_reg);
708 jtag_execute_queue();
709 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
710 armv4_5_identify_cache(cache_type_reg,
711 &armv7a->armv4_5_mmu.armv4_5_cache);
712 }
713
714 armv7a->armv4_5_mmu.mmu_enabled =
715 (cortex_a8->cp15_control_reg & 0x1U) ? 1 : 0;
716 armv7a->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled =
717 (cortex_a8->cp15_control_reg & 0x4U) ? 1 : 0;
718 armv7a->armv4_5_mmu.armv4_5_cache.i_cache_enabled =
719 (cortex_a8->cp15_control_reg & 0x1000U) ? 1 : 0;
720
721
722 }
723
724 static int cortex_a8_step(struct target *target, int current, uint32_t address,
725 int handle_breakpoints)
726 {
727 struct armv7a_common *armv7a = target_to_armv7a(target);
728 struct armv4_5_common_s *armv4_5 = &armv7a->armv4_5_common;
729 struct breakpoint *breakpoint = NULL;
730 struct breakpoint stepbreakpoint;
731
732 int timeout = 100;
733
734 if (target->state != TARGET_HALTED)
735 {
736 LOG_WARNING("target not halted");
737 return ERROR_TARGET_NOT_HALTED;
738 }
739
740 /* current = 1: continue on current pc, otherwise continue at <address> */
741 if (!current)
742 {
743 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
744 armv4_5->core_mode, ARM_PC).value,
745 0, 32, address);
746 }
747 else
748 {
749 address = buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
750 armv4_5->core_mode, ARM_PC).value,
751 0, 32);
752 }
753
754 /* The front-end may request us not to handle breakpoints.
755 * But since Cortex-A8 uses breakpoint for single step,
756 * we MUST handle breakpoints.
757 */
758 handle_breakpoints = 1;
759 if (handle_breakpoints) {
760 breakpoint = breakpoint_find(target,
761 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
762 armv4_5->core_mode, 15).value,
763 0, 32));
764 if (breakpoint)
765 cortex_a8_unset_breakpoint(target, breakpoint);
766 }
767
768 /* Setup single step breakpoint */
769 stepbreakpoint.address = address;
770 stepbreakpoint.length = (armv7a->core_state == ARMV7A_STATE_THUMB) ? 2 : 4;
771 stepbreakpoint.type = BKPT_HARD;
772 stepbreakpoint.set = 0;
773
774 /* Break on IVA mismatch */
775 cortex_a8_set_breakpoint(target, &stepbreakpoint, 0x04);
776
777 target->debug_reason = DBG_REASON_SINGLESTEP;
778
779 cortex_a8_resume(target, 1, address, 0, 0);
780
781 while (target->state != TARGET_HALTED)
782 {
783 cortex_a8_poll(target);
784 if (--timeout == 0)
785 {
786 LOG_WARNING("timeout waiting for target halt");
787 break;
788 }
789 }
790
791 cortex_a8_unset_breakpoint(target, &stepbreakpoint);
792 if (timeout > 0) target->debug_reason = DBG_REASON_BREAKPOINT;
793
794 if (breakpoint)
795 cortex_a8_set_breakpoint(target, breakpoint, 0);
796
797 if (target->state != TARGET_HALTED)
798 LOG_DEBUG("target stepped");
799
800 return ERROR_OK;
801 }
802
803 static int cortex_a8_restore_context(struct target *target)
804 {
805 int i;
806 uint32_t value;
807 struct armv7a_common *armv7a = target_to_armv7a(target);
808 struct armv4_5_common_s *armv4_5 = &armv7a->armv4_5_common;
809
810 LOG_DEBUG(" ");
811
812 if (armv7a->pre_restore_context)
813 armv7a->pre_restore_context(target);
814
815 for (i = 15; i >= 0; i--)
816 {
817 if (ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
818 armv4_5->core_mode, i).dirty)
819 {
820 value = buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
821 armv4_5->core_mode, i).value,
822 0, 32);
823 /* TODO Check return values */
824 cortex_a8_dap_write_coreregister_u32(target, value, i);
825 }
826 }
827
828 if (armv7a->post_restore_context)
829 armv7a->post_restore_context(target);
830
831 return ERROR_OK;
832 }
833
834
835 #if 0
836 /*
837 * Cortex-A8 Core register functions
838 */
839 static int cortex_a8_load_core_reg_u32(struct target *target, int num,
840 armv4_5_mode_t mode, uint32_t * value)
841 {
842 int retval;
843 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
844
845 if ((num <= ARM_CPSR))
846 {
847 /* read a normal core register */
848 retval = cortex_a8_dap_read_coreregister_u32(target, value, num);
849
850 if (retval != ERROR_OK)
851 {
852 LOG_ERROR("JTAG failure %i", retval);
853 return ERROR_JTAG_DEVICE_ERROR;
854 }
855 LOG_DEBUG("load from core reg %i value 0x%" PRIx32, num, *value);
856 }
857 else
858 {
859 return ERROR_INVALID_ARGUMENTS;
860 }
861
862 /* Register other than r0 - r14 uses r0 for access */
863 if (num > 14)
864 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
865 armv4_5->core_mode, 0).dirty =
866 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
867 armv4_5->core_mode, 0).valid;
868 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
869 armv4_5->core_mode, 15).dirty =
870 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
871 armv4_5->core_mode, 15).valid;
872
873 return ERROR_OK;
874 }
875
876 static int cortex_a8_store_core_reg_u32(struct target *target, int num,
877 armv4_5_mode_t mode, uint32_t value)
878 {
879 int retval;
880 // uint32_t reg;
881 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
882
883 #ifdef ARMV7_GDB_HACKS
884 /* If the LR register is being modified, make sure it will put us
885 * in "thumb" mode, or an INVSTATE exception will occur. This is a
886 * hack to deal with the fact that gdb will sometimes "forge"
887 * return addresses, and doesn't set the LSB correctly (i.e., when
888 * printing expressions containing function calls, it sets LR=0.) */
889
890 if (num == 14)
891 value |= 0x01;
892 #endif
893
894 if ((num <= ARM_CPSR))
895 {
896 retval = cortex_a8_dap_write_coreregister_u32(target, value, num);
897 if (retval != ERROR_OK)
898 {
899 LOG_ERROR("JTAG failure %i", retval);
900 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
901 armv4_5->core_mode, num).dirty =
902 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
903 armv4_5->core_mode, num).valid;
904 return ERROR_JTAG_DEVICE_ERROR;
905 }
906 LOG_DEBUG("write core reg %i value 0x%" PRIx32, num, value);
907 }
908 else
909 {
910 return ERROR_INVALID_ARGUMENTS;
911 }
912
913 return ERROR_OK;
914 }
915 #endif
916
917
918 static int cortex_a8_read_core_reg(struct target *target, int num,
919 enum armv4_5_mode mode)
920 {
921 uint32_t value;
922 int retval;
923 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
924
925 cortex_a8_dap_read_coreregister_u32(target, &value, num);
926
927 if ((retval = jtag_execute_queue()) != ERROR_OK)
928 {
929 return retval;
930 }
931
932 ARMV7A_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
933 ARMV7A_CORE_REG_MODE(armv4_5->core_cache, mode, num).dirty = 0;
934 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
935 mode, num).value, 0, 32, value);
936
937 return ERROR_OK;
938 }
939
940 int cortex_a8_write_core_reg(struct target *target, int num,
941 enum armv4_5_mode mode, uint32_t value)
942 {
943 int retval;
944 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
945
946 cortex_a8_dap_write_coreregister_u32(target, value, num);
947 if ((retval = jtag_execute_queue()) != ERROR_OK)
948 {
949 return retval;
950 }
951
952 ARMV7A_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
953 ARMV7A_CORE_REG_MODE(armv4_5->core_cache, mode, num).dirty = 0;
954
955 return ERROR_OK;
956 }
957
958
959 /*
960 * Cortex-A8 Breakpoint and watchpoint fuctions
961 */
962
963 /* Setup hardware Breakpoint Register Pair */
964 static int cortex_a8_set_breakpoint(struct target *target,
965 struct breakpoint *breakpoint, uint8_t matchmode)
966 {
967 int retval;
968 int brp_i=0;
969 uint32_t control;
970 uint8_t byte_addr_select = 0x0F;
971 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
972 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
973 struct cortex_a8_brp * brp_list = cortex_a8->brp_list;
974
975 if (breakpoint->set)
976 {
977 LOG_WARNING("breakpoint already set");
978 return ERROR_OK;
979 }
980
981 if (breakpoint->type == BKPT_HARD)
982 {
983 while (brp_list[brp_i].used && (brp_i < cortex_a8->brp_num))
984 brp_i++ ;
985 if (brp_i >= cortex_a8->brp_num)
986 {
987 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
988 exit(-1);
989 }
990 breakpoint->set = brp_i + 1;
991 if (breakpoint->length == 2)
992 {
993 byte_addr_select = (3 << (breakpoint->address & 0x02));
994 }
995 control = ((matchmode & 0x7) << 20)
996 | (byte_addr_select << 5)
997 | (3 << 1) | 1;
998 brp_list[brp_i].used = 1;
999 brp_list[brp_i].value = (breakpoint->address & 0xFFFFFFFC);
1000 brp_list[brp_i].control = control;
1001 cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
1002 + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn,
1003 brp_list[brp_i].value);
1004 cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
1005 + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn,
1006 brp_list[brp_i].control);
1007 LOG_DEBUG("brp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_i,
1008 brp_list[brp_i].control,
1009 brp_list[brp_i].value);
1010 }
1011 else if (breakpoint->type == BKPT_SOFT)
1012 {
1013 uint8_t code[4];
1014 if (breakpoint->length == 2)
1015 {
1016 buf_set_u32(code, 0, 32, ARMV5_T_BKPT(0x11));
1017 }
1018 else
1019 {
1020 buf_set_u32(code, 0, 32, ARMV5_BKPT(0x11));
1021 }
1022 retval = target->type->read_memory(target,
1023 breakpoint->address & 0xFFFFFFFE,
1024 breakpoint->length, 1,
1025 breakpoint->orig_instr);
1026 if (retval != ERROR_OK)
1027 return retval;
1028 retval = target->type->write_memory(target,
1029 breakpoint->address & 0xFFFFFFFE,
1030 breakpoint->length, 1, code);
1031 if (retval != ERROR_OK)
1032 return retval;
1033 breakpoint->set = 0x11; /* Any nice value but 0 */
1034 }
1035
1036 return ERROR_OK;
1037 }
1038
1039 static int cortex_a8_unset_breakpoint(struct target *target, struct breakpoint *breakpoint)
1040 {
1041 int retval;
1042 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
1043 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
1044 struct cortex_a8_brp * brp_list = cortex_a8->brp_list;
1045
1046 if (!breakpoint->set)
1047 {
1048 LOG_WARNING("breakpoint not set");
1049 return ERROR_OK;
1050 }
1051
1052 if (breakpoint->type == BKPT_HARD)
1053 {
1054 int brp_i = breakpoint->set - 1;
1055 if ((brp_i < 0) || (brp_i >= cortex_a8->brp_num))
1056 {
1057 LOG_DEBUG("Invalid BRP number in breakpoint");
1058 return ERROR_OK;
1059 }
1060 LOG_DEBUG("rbp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_i,
1061 brp_list[brp_i].control, brp_list[brp_i].value);
1062 brp_list[brp_i].used = 0;
1063 brp_list[brp_i].value = 0;
1064 brp_list[brp_i].control = 0;
1065 cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
1066 + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn,
1067 brp_list[brp_i].control);
1068 cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
1069 + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn,
1070 brp_list[brp_i].value);
1071 }
1072 else
1073 {
1074 /* restore original instruction (kept in target endianness) */
1075 if (breakpoint->length == 4)
1076 {
1077 retval = target->type->write_memory(target,
1078 breakpoint->address & 0xFFFFFFFE,
1079 4, 1, breakpoint->orig_instr);
1080 if (retval != ERROR_OK)
1081 return retval;
1082 }
1083 else
1084 {
1085 retval = target->type->write_memory(target,
1086 breakpoint->address & 0xFFFFFFFE,
1087 2, 1, breakpoint->orig_instr);
1088 if (retval != ERROR_OK)
1089 return retval;
1090 }
1091 }
1092 breakpoint->set = 0;
1093
1094 return ERROR_OK;
1095 }
1096
1097 int cortex_a8_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
1098 {
1099 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
1100
1101 if ((breakpoint->type == BKPT_HARD) && (cortex_a8->brp_num_available < 1))
1102 {
1103 LOG_INFO("no hardware breakpoint available");
1104 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1105 }
1106
1107 if (breakpoint->type == BKPT_HARD)
1108 cortex_a8->brp_num_available--;
1109 cortex_a8_set_breakpoint(target, breakpoint, 0x00); /* Exact match */
1110
1111 return ERROR_OK;
1112 }
1113
1114 static int cortex_a8_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)
1115 {
1116 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
1117
1118 #if 0
1119 /* It is perfectly possible to remove brakpoints while the taget is running */
1120 if (target->state != TARGET_HALTED)
1121 {
1122 LOG_WARNING("target not halted");
1123 return ERROR_TARGET_NOT_HALTED;
1124 }
1125 #endif
1126
1127 if (breakpoint->set)
1128 {
1129 cortex_a8_unset_breakpoint(target, breakpoint);
1130 if (breakpoint->type == BKPT_HARD)
1131 cortex_a8->brp_num_available++ ;
1132 }
1133
1134
1135 return ERROR_OK;
1136 }
1137
1138
1139
1140 /*
1141 * Cortex-A8 Reset fuctions
1142 */
1143
1144 static int cortex_a8_assert_reset(struct target *target)
1145 {
1146
1147 LOG_DEBUG(" ");
1148
1149 /* registers are now invalid */
1150 armv4_5_invalidate_core_regs(target);
1151
1152 target->state = TARGET_RESET;
1153
1154 return ERROR_OK;
1155 }
1156
1157 static int cortex_a8_deassert_reset(struct target *target)
1158 {
1159
1160 LOG_DEBUG(" ");
1161
1162 if (target->reset_halt)
1163 {
1164 int retval;
1165 if ((retval = target_halt(target)) != ERROR_OK)
1166 return retval;
1167 }
1168
1169 return ERROR_OK;
1170 }
1171
1172 /*
1173 * Cortex-A8 Memory access
1174 *
1175 * This is same Cortex M3 but we must also use the correct
1176 * ap number for every access.
1177 */
1178
1179 static int cortex_a8_read_memory(struct target *target, uint32_t address,
1180 uint32_t size, uint32_t count, uint8_t *buffer)
1181 {
1182 struct armv7a_common *armv7a = target_to_armv7a(target);
1183 struct swjdp_common *swjdp = &armv7a->swjdp_info;
1184
1185 int retval = ERROR_OK;
1186
1187 /* sanitize arguments */
1188 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1189 return ERROR_INVALID_ARGUMENTS;
1190
1191 /* cortex_a8 handles unaligned memory access */
1192
1193 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1194
1195 switch (size)
1196 {
1197 case 4:
1198 retval = mem_ap_read_buf_u32(swjdp, buffer, 4 * count, address);
1199 break;
1200 case 2:
1201 retval = mem_ap_read_buf_u16(swjdp, buffer, 2 * count, address);
1202 break;
1203 case 1:
1204 retval = mem_ap_read_buf_u8(swjdp, buffer, count, address);
1205 break;
1206 default:
1207 LOG_ERROR("BUG: we shouldn't get here");
1208 exit(-1);
1209 }
1210
1211 return retval;
1212 }
1213
1214 int cortex_a8_write_memory(struct target *target, uint32_t address,
1215 uint32_t size, uint32_t count, uint8_t *buffer)
1216 {
1217 struct armv7a_common *armv7a = target_to_armv7a(target);
1218 struct swjdp_common *swjdp = &armv7a->swjdp_info;
1219
1220 int retval;
1221
1222 /* sanitize arguments */
1223 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1224 return ERROR_INVALID_ARGUMENTS;
1225
1226 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1227
1228 switch (size)
1229 {
1230 case 4:
1231 retval = mem_ap_write_buf_u32(swjdp, buffer, 4 * count, address);
1232 break;
1233 case 2:
1234 retval = mem_ap_write_buf_u16(swjdp, buffer, 2 * count, address);
1235 break;
1236 case 1:
1237 retval = mem_ap_write_buf_u8(swjdp, buffer, count, address);
1238 break;
1239 default:
1240 LOG_ERROR("BUG: we shouldn't get here");
1241 exit(-1);
1242 }
1243
1244 if (target->state == TARGET_HALTED)
1245 {
1246 /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */
1247 /* invalidate I-Cache */
1248 if (armv7a->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
1249 {
1250 /* Invalidate ICache single entry with MVA, repeat this for all cache
1251 lines in the address range, Cortex-A8 has fixed 64 byte line length */
1252 /* Invalidate Cache single entry with MVA to PoU */
1253 for (uint32_t cacheline=address; cacheline<address+size*count; cacheline+=64)
1254 armv7a->write_cp15(target, 0, 1, 7, 5, cacheline); /* I-Cache to PoU */
1255 }
1256 /* invalidate D-Cache */
1257 if (armv7a->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled)
1258 {
1259 /* Invalidate Cache single entry with MVA to PoC */
1260 for (uint32_t cacheline=address; cacheline<address+size*count; cacheline+=64)
1261 armv7a->write_cp15(target, 0, 1, 7, 6, cacheline); /* U/D cache to PoC */
1262 }
1263 }
1264
1265 return retval;
1266 }
1267
1268 static int cortex_a8_bulk_write_memory(struct target *target, uint32_t address,
1269 uint32_t count, uint8_t *buffer)
1270 {
1271 return cortex_a8_write_memory(target, address, 4, count, buffer);
1272 }
1273
1274
1275 static int cortex_a8_dcc_read(struct swjdp_common *swjdp, uint8_t *value, uint8_t *ctrl)
1276 {
1277 #if 0
1278 u16 dcrdr;
1279
1280 mem_ap_read_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
1281 *ctrl = (uint8_t)dcrdr;
1282 *value = (uint8_t)(dcrdr >> 8);
1283
1284 LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
1285
1286 /* write ack back to software dcc register
1287 * signify we have read data */
1288 if (dcrdr & (1 << 0))
1289 {
1290 dcrdr = 0;
1291 mem_ap_write_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
1292 }
1293 #endif
1294 return ERROR_OK;
1295 }
1296
1297
1298 static int cortex_a8_handle_target_request(void *priv)
1299 {
1300 struct target *target = priv;
1301 struct armv7a_common *armv7a = target_to_armv7a(target);
1302 struct swjdp_common *swjdp = &armv7a->swjdp_info;
1303
1304 if (!target_was_examined(target))
1305 return ERROR_OK;
1306 if (!target->dbg_msg_enabled)
1307 return ERROR_OK;
1308
1309 if (target->state == TARGET_RUNNING)
1310 {
1311 uint8_t data = 0;
1312 uint8_t ctrl = 0;
1313
1314 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1315
1316 /* check if we have data */
1317 if (ctrl & (1 << 0))
1318 {
1319 uint32_t request;
1320
1321 /* we assume target is quick enough */
1322 request = data;
1323 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1324 request |= (data << 8);
1325 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1326 request |= (data << 16);
1327 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1328 request |= (data << 24);
1329 target_request(target, request);
1330 }
1331 }
1332
1333 return ERROR_OK;
1334 }
1335
1336 /*
1337 * Cortex-A8 target information and configuration
1338 */
1339
1340 static int cortex_a8_examine(struct target *target)
1341 {
1342 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
1343 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
1344 struct swjdp_common *swjdp = &armv7a->swjdp_info;
1345 int i;
1346 int retval = ERROR_OK;
1347 uint32_t didr, ctypr, ttypr, cpuid;
1348
1349 LOG_DEBUG("TODO");
1350
1351 /* Here we shall insert a proper ROM Table scan */
1352 armv7a->debug_base = OMAP3530_DEBUG_BASE;
1353
1354 /* We do one extra read to ensure DAP is configured,
1355 * we call ahbap_debugport_init(swjdp) instead
1356 */
1357 ahbap_debugport_init(swjdp);
1358 mem_ap_read_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_CPUID, &cpuid);
1359 if ((retval = mem_ap_read_atomic_u32(swjdp,
1360 armv7a->debug_base + CPUDBG_CPUID, &cpuid)) != ERROR_OK)
1361 {
1362 LOG_DEBUG("Examine failed");
1363 return retval;
1364 }
1365
1366 if ((retval = mem_ap_read_atomic_u32(swjdp,
1367 armv7a->debug_base + CPUDBG_CTYPR, &ctypr)) != ERROR_OK)
1368 {
1369 LOG_DEBUG("Examine failed");
1370 return retval;
1371 }
1372
1373 if ((retval = mem_ap_read_atomic_u32(swjdp,
1374 armv7a->debug_base + CPUDBG_TTYPR, &ttypr)) != ERROR_OK)
1375 {
1376 LOG_DEBUG("Examine failed");
1377 return retval;
1378 }
1379
1380 if ((retval = mem_ap_read_atomic_u32(swjdp,
1381 armv7a->debug_base + CPUDBG_DIDR, &didr)) != ERROR_OK)
1382 {
1383 LOG_DEBUG("Examine failed");
1384 return retval;
1385 }
1386
1387 LOG_DEBUG("cpuid = 0x%08" PRIx32, cpuid);
1388 LOG_DEBUG("ctypr = 0x%08" PRIx32, ctypr);
1389 LOG_DEBUG("ttypr = 0x%08" PRIx32, ttypr);
1390 LOG_DEBUG("didr = 0x%08" PRIx32, didr);
1391
1392 /* Setup Breakpoint Register Pairs */
1393 cortex_a8->brp_num = ((didr >> 24) & 0x0F) + 1;
1394 cortex_a8->brp_num_context = ((didr >> 20) & 0x0F) + 1;
1395 cortex_a8->brp_num_available = cortex_a8->brp_num;
1396 cortex_a8->brp_list = calloc(cortex_a8->brp_num, sizeof(struct cortex_a8_brp));
1397 // cortex_a8->brb_enabled = ????;
1398 for (i = 0; i < cortex_a8->brp_num; i++)
1399 {
1400 cortex_a8->brp_list[i].used = 0;
1401 if (i < (cortex_a8->brp_num-cortex_a8->brp_num_context))
1402 cortex_a8->brp_list[i].type = BRP_NORMAL;
1403 else
1404 cortex_a8->brp_list[i].type = BRP_CONTEXT;
1405 cortex_a8->brp_list[i].value = 0;
1406 cortex_a8->brp_list[i].control = 0;
1407 cortex_a8->brp_list[i].BRPn = i;
1408 }
1409
1410 /* Setup Watchpoint Register Pairs */
1411 cortex_a8->wrp_num = ((didr >> 28) & 0x0F) + 1;
1412 cortex_a8->wrp_num_available = cortex_a8->wrp_num;
1413 cortex_a8->wrp_list = calloc(cortex_a8->wrp_num, sizeof(struct cortex_a8_wrp));
1414 for (i = 0; i < cortex_a8->wrp_num; i++)
1415 {
1416 cortex_a8->wrp_list[i].used = 0;
1417 cortex_a8->wrp_list[i].type = 0;
1418 cortex_a8->wrp_list[i].value = 0;
1419 cortex_a8->wrp_list[i].control = 0;
1420 cortex_a8->wrp_list[i].WRPn = i;
1421 }
1422 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1423 cortex_a8->brp_num , cortex_a8->wrp_num);
1424
1425 /* Configure core debug access */
1426 cortex_a8_init_debug_access(target);
1427
1428 target_set_examined(target);
1429
1430 return retval;
1431 }
1432
1433 /*
1434 * Cortex-A8 target creation and initialization
1435 */
1436
1437 static void cortex_a8_build_reg_cache(struct target *target)
1438 {
1439 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
1440 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
1441
1442 (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
1443 armv4_5->core_cache = (*cache_p);
1444 }
1445
1446
1447 static int cortex_a8_init_target(struct command_context *cmd_ctx,
1448 struct target *target)
1449 {
1450 cortex_a8_build_reg_cache(target);
1451 return ERROR_OK;
1452 }
1453
1454 int cortex_a8_init_arch_info(struct target *target,
1455 struct cortex_a8_common *cortex_a8, struct jtag_tap *tap)
1456 {
1457 struct arm *armv4_5;
1458 struct armv7a_common *armv7a;
1459
1460 armv7a = &cortex_a8->armv7a_common;
1461 armv4_5 = &armv7a->armv4_5_common;
1462 struct swjdp_common *swjdp = &armv7a->swjdp_info;
1463
1464 /* Setup struct cortex_a8_common */
1465 cortex_a8->common_magic = CORTEX_A8_COMMON_MAGIC;
1466 armv4_5->arch_info = armv7a;
1467
1468 armv4_5_init_arch_info(target, armv4_5);
1469
1470 /* prepare JTAG information for the new target */
1471 cortex_a8->jtag_info.tap = tap;
1472 cortex_a8->jtag_info.scann_size = 4;
1473 LOG_DEBUG(" ");
1474 swjdp->dp_select_value = -1;
1475 swjdp->ap_csw_value = -1;
1476 swjdp->ap_tar_value = -1;
1477 swjdp->jtag_info = &cortex_a8->jtag_info;
1478 swjdp->memaccess_tck = 80;
1479
1480 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1481 swjdp->tar_autoincr_block = (1 << 10);
1482
1483 cortex_a8->fast_reg_read = 0;
1484
1485
1486 /* register arch-specific functions */
1487 armv7a->examine_debug_reason = NULL;
1488
1489 armv7a->post_debug_entry = cortex_a8_post_debug_entry;
1490
1491 armv7a->pre_restore_context = NULL;
1492 armv7a->post_restore_context = NULL;
1493 armv7a->armv4_5_mmu.armv4_5_cache.ctype = -1;
1494 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1495 armv7a->armv4_5_mmu.read_memory = cortex_a8_read_memory;
1496 armv7a->armv4_5_mmu.write_memory = cortex_a8_write_memory;
1497 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1498 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1499 armv7a->armv4_5_mmu.has_tiny_pages = 1;
1500 armv7a->armv4_5_mmu.mmu_enabled = 0;
1501 armv7a->read_cp15 = cortex_a8_read_cp15;
1502 armv7a->write_cp15 = cortex_a8_write_cp15;
1503
1504
1505 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1506
1507 armv4_5->read_core_reg = cortex_a8_read_core_reg;
1508 armv4_5->write_core_reg = cortex_a8_write_core_reg;
1509 // armv4_5->full_context = arm7_9_full_context;
1510
1511 // armv4_5->load_core_reg_u32 = cortex_a8_load_core_reg_u32;
1512 // armv4_5->store_core_reg_u32 = cortex_a8_store_core_reg_u32;
1513 // armv4_5->read_core_reg = armv4_5_read_core_reg; /* this is default */
1514 // armv4_5->write_core_reg = armv4_5_write_core_reg;
1515
1516 target_register_timer_callback(cortex_a8_handle_target_request, 1, 1, target);
1517
1518 return ERROR_OK;
1519 }
1520
1521 static int cortex_a8_target_create(struct target *target, Jim_Interp *interp)
1522 {
1523 struct cortex_a8_common *cortex_a8 = calloc(1, sizeof(struct cortex_a8_common));
1524
1525 cortex_a8_init_arch_info(target, cortex_a8, target->tap);
1526
1527 return ERROR_OK;
1528 }
1529
1530 COMMAND_HANDLER(cortex_a8_handle_cache_info_command)
1531 {
1532 struct target *target = get_current_target(cmd_ctx);
1533 struct armv7a_common *armv7a = target_to_armv7a(target);
1534
1535 return armv4_5_handle_cache_info_command(cmd_ctx,
1536 &armv7a->armv4_5_mmu.armv4_5_cache);
1537 }
1538
1539
1540 COMMAND_HANDLER(cortex_a8_handle_dbginit_command)
1541 {
1542 struct target *target = get_current_target(cmd_ctx);
1543
1544 cortex_a8_init_debug_access(target);
1545
1546 return ERROR_OK;
1547 }
1548
1549
1550 static int cortex_a8_register_commands(struct command_context *cmd_ctx)
1551 {
1552 struct command *cortex_a8_cmd;
1553 int retval = ERROR_OK;
1554
1555 armv4_5_register_commands(cmd_ctx);
1556 armv7a_register_commands(cmd_ctx);
1557
1558 cortex_a8_cmd = register_command(cmd_ctx, NULL, "cortex_a8",
1559 NULL, COMMAND_ANY,
1560 "cortex_a8 specific commands");
1561
1562 register_command(cmd_ctx, cortex_a8_cmd, "cache_info",
1563 cortex_a8_handle_cache_info_command, COMMAND_EXEC,
1564 "display information about target caches");
1565
1566 register_command(cmd_ctx, cortex_a8_cmd, "dbginit",
1567 cortex_a8_handle_dbginit_command, COMMAND_EXEC,
1568 "Initialize core debug");
1569
1570 return retval;
1571 }
1572
1573 struct target_type cortexa8_target = {
1574 .name = "cortex_a8",
1575
1576 .poll = cortex_a8_poll,
1577 .arch_state = armv7a_arch_state,
1578
1579 .target_request_data = NULL,
1580
1581 .halt = cortex_a8_halt,
1582 .resume = cortex_a8_resume,
1583 .step = cortex_a8_step,
1584
1585 .assert_reset = cortex_a8_assert_reset,
1586 .deassert_reset = cortex_a8_deassert_reset,
1587 .soft_reset_halt = NULL,
1588
1589 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
1590
1591 .read_memory = cortex_a8_read_memory,
1592 .write_memory = cortex_a8_write_memory,
1593 .bulk_write_memory = cortex_a8_bulk_write_memory,
1594
1595 .checksum_memory = arm_checksum_memory,
1596 .blank_check_memory = arm_blank_check_memory,
1597
1598 .run_algorithm = armv4_5_run_algorithm,
1599
1600 .add_breakpoint = cortex_a8_add_breakpoint,
1601 .remove_breakpoint = cortex_a8_remove_breakpoint,
1602 .add_watchpoint = NULL,
1603 .remove_watchpoint = NULL,
1604
1605 .register_commands = cortex_a8_register_commands,
1606 .target_create = cortex_a8_target_create,
1607 .init_target = cortex_a8_init_target,
1608 .examine = cortex_a8_examine,
1609 .mrc = cortex_a8_mrc,
1610 .mcr = cortex_a8_mcr,
1611 };

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)