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

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)