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

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)