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

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)