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

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)