332a55a5fc9cff538e71c5e2e4f6e353f2f3bf25
[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 #include "arm_opcodes.h"
42
43 static int cortex_a8_poll(struct target *target);
44 static int cortex_a8_debug_entry(struct target *target);
45 static int cortex_a8_restore_context(struct target *target, bool bpwp);
46 static int cortex_a8_set_breakpoint(struct target *target,
47 struct breakpoint *breakpoint, uint8_t matchmode);
48 static int cortex_a8_unset_breakpoint(struct target *target,
49 struct breakpoint *breakpoint);
50 static int cortex_a8_dap_read_coreregister_u32(struct target *target,
51 uint32_t *value, int regnum);
52 static int cortex_a8_dap_write_coreregister_u32(struct target *target,
53 uint32_t value, int regnum);
54 /*
55 * FIXME do topology discovery using the ROM; don't
56 * assume this is an OMAP3. Also, allow for multiple ARMv7-A
57 * cores, with different AP numbering ... don't use a #define
58 * for these numbers, use per-core armv7a state.
59 */
60 #define swjdp_memoryap 0
61 #define swjdp_debugap 1
62 #define OMAP3530_DEBUG_BASE 0x54011000
63
64 /*
65 * Cortex-A8 Basic debug access, very low level assumes state is saved
66 */
67 static int cortex_a8_init_debug_access(struct target *target)
68 {
69 struct armv7a_common *armv7a = target_to_armv7a(target);
70 struct adiv5_dap *swjdp = &armv7a->dap;
71
72 int retval;
73 uint32_t dummy;
74
75 LOG_DEBUG(" ");
76
77 /* Unlocking the debug registers for modification */
78 /* The debugport might be uninitialised so try twice */
79 retval = mem_ap_write_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_LOCKACCESS, 0xC5ACCE55);
80 if (retval != ERROR_OK)
81 mem_ap_write_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_LOCKACCESS, 0xC5ACCE55);
82 /* Clear Sticky Power Down status Bit in PRSR to enable access to
83 the registers in the Core Power Domain */
84 retval = mem_ap_read_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_PRSR, &dummy);
85 /* Enabling of instruction execution in debug mode is done in debug_entry code */
86
87 /* Resync breakpoint registers */
88
89 /* Since this is likley called from init or reset, update targtet state information*/
90 cortex_a8_poll(target);
91
92 return retval;
93 }
94
95 /* To reduce needless round-trips, pass in a pointer to the current
96 * DSCR value. Initialize it to zero if you just need to know the
97 * value on return from this function; or DSCR_INSTR_COMP if you
98 * happen to know that no instruction is pending.
99 */
100 static int cortex_a8_exec_opcode(struct target *target,
101 uint32_t opcode, uint32_t *dscr_p)
102 {
103 uint32_t dscr;
104 int retval;
105 struct armv7a_common *armv7a = target_to_armv7a(target);
106 struct adiv5_dap *swjdp = &armv7a->dap;
107
108 dscr = dscr_p ? *dscr_p : 0;
109
110 LOG_DEBUG("exec opcode 0x%08" PRIx32, opcode);
111
112 /* Wait for InstrCompl bit to be set */
113 while ((dscr & DSCR_INSTR_COMP) == 0)
114 {
115 retval = mem_ap_read_atomic_u32(swjdp,
116 armv7a->debug_base + CPUDBG_DSCR, &dscr);
117 if (retval != ERROR_OK)
118 {
119 LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32, opcode);
120 return retval;
121 }
122 }
123
124 mem_ap_write_u32(swjdp, armv7a->debug_base + CPUDBG_ITR, opcode);
125
126 do
127 {
128 retval = mem_ap_read_atomic_u32(swjdp,
129 armv7a->debug_base + CPUDBG_DSCR, &dscr);
130 if (retval != ERROR_OK)
131 {
132 LOG_ERROR("Could not read DSCR register");
133 return retval;
134 }
135 }
136 while ((dscr & DSCR_INSTR_COMP) == 0); /* Wait for InstrCompl bit to be set */
137
138 if (dscr_p)
139 *dscr_p = dscr;
140
141 return retval;
142 }
143
144 /**************************************************************************
145 Read core register with very few exec_opcode, fast but needs work_area.
146 This can cause problems with MMU active.
147 **************************************************************************/
148 static int cortex_a8_read_regs_through_mem(struct target *target, uint32_t address,
149 uint32_t * regfile)
150 {
151 int retval = ERROR_OK;
152 struct armv7a_common *armv7a = target_to_armv7a(target);
153 struct adiv5_dap *swjdp = &armv7a->dap;
154
155 cortex_a8_dap_read_coreregister_u32(target, regfile, 0);
156 cortex_a8_dap_write_coreregister_u32(target, address, 0);
157 cortex_a8_exec_opcode(target, ARMV4_5_STMIA(0, 0xFFFE, 0, 0), NULL);
158 dap_ap_select(swjdp, swjdp_memoryap);
159 mem_ap_read_buf_u32(swjdp, (uint8_t *)(&regfile[1]), 4*15, address);
160 dap_ap_select(swjdp, swjdp_debugap);
161
162 return retval;
163 }
164
165 static int cortex_a8_dap_read_coreregister_u32(struct target *target,
166 uint32_t *value, int regnum)
167 {
168 int retval = ERROR_OK;
169 uint8_t reg = regnum&0xFF;
170 uint32_t dscr = 0;
171 struct armv7a_common *armv7a = target_to_armv7a(target);
172 struct adiv5_dap *swjdp = &armv7a->dap;
173
174 if (reg > 17)
175 return retval;
176
177 if (reg < 15)
178 {
179 /* Rn to DCCTX, "MCR p14, 0, Rn, c0, c5, 0" 0xEE00nE15 */
180 cortex_a8_exec_opcode(target,
181 ARMV4_5_MCR(14, 0, reg, 0, 5, 0),
182 &dscr);
183 }
184 else if (reg == 15)
185 {
186 /* "MOV r0, r15"; then move r0 to DCCTX */
187 cortex_a8_exec_opcode(target, 0xE1A0000F, &dscr);
188 cortex_a8_exec_opcode(target,
189 ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
190 &dscr);
191 }
192 else
193 {
194 /* "MRS r0, CPSR" or "MRS r0, SPSR"
195 * then move r0 to DCCTX
196 */
197 cortex_a8_exec_opcode(target, ARMV4_5_MRS(0, reg & 1), &dscr);
198 cortex_a8_exec_opcode(target,
199 ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
200 &dscr);
201 }
202
203 /* Wait for DTRRXfull then read DTRRTX */
204 while ((dscr & DSCR_DTR_TX_FULL) == 0)
205 {
206 retval = mem_ap_read_atomic_u32(swjdp,
207 armv7a->debug_base + CPUDBG_DSCR, &dscr);
208 }
209
210 retval = mem_ap_read_atomic_u32(swjdp,
211 armv7a->debug_base + CPUDBG_DTRTX, value);
212 LOG_DEBUG("read DCC 0x%08" PRIx32, *value);
213
214 return retval;
215 }
216
217 static int cortex_a8_dap_write_coreregister_u32(struct target *target,
218 uint32_t value, int regnum)
219 {
220 int retval = ERROR_OK;
221 uint8_t Rd = regnum&0xFF;
222 uint32_t dscr;
223 struct armv7a_common *armv7a = target_to_armv7a(target);
224 struct adiv5_dap *swjdp = &armv7a->dap;
225
226 LOG_DEBUG("register %i, value 0x%08" PRIx32, regnum, value);
227
228 /* Check that DCCRX is not full */
229 retval = mem_ap_read_atomic_u32(swjdp,
230 armv7a->debug_base + CPUDBG_DSCR, &dscr);
231 if (dscr & DSCR_DTR_RX_FULL)
232 {
233 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32, dscr);
234 /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */
235 cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
236 &dscr);
237 }
238
239 if (Rd > 17)
240 return retval;
241
242 /* Write DTRRX ... sets DSCR.DTRRXfull but exec_opcode() won't care */
243 LOG_DEBUG("write DCC 0x%08" PRIx32, value);
244 retval = mem_ap_write_u32(swjdp,
245 armv7a->debug_base + CPUDBG_DTRRX, value);
246
247 if (Rd < 15)
248 {
249 /* DCCRX to Rn, "MCR p14, 0, Rn, c0, c5, 0", 0xEE00nE15 */
250 cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, Rd, 0, 5, 0),
251 &dscr);
252 }
253 else if (Rd == 15)
254 {
255 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15
256 * then "mov r15, r0"
257 */
258 cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
259 &dscr);
260 cortex_a8_exec_opcode(target, 0xE1A0F000, &dscr);
261 }
262 else
263 {
264 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15
265 * then "MSR CPSR_cxsf, r0" or "MSR SPSR_cxsf, r0" (all fields)
266 */
267 cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
268 &dscr);
269 cortex_a8_exec_opcode(target, ARMV4_5_MSR_GP(0, 0xF, Rd & 1),
270 &dscr);
271
272 /* "Prefetch flush" after modifying execution status in CPSR */
273 if (Rd == 16)
274 cortex_a8_exec_opcode(target,
275 ARMV4_5_MCR(15, 0, 0, 7, 5, 4),
276 &dscr);
277 }
278
279 return retval;
280 }
281
282 /* Write to memory mapped registers directly with no cache or mmu handling */
283 static int cortex_a8_dap_write_memap_register_u32(struct target *target, uint32_t address, uint32_t value)
284 {
285 int retval;
286 struct armv7a_common *armv7a = target_to_armv7a(target);
287 struct adiv5_dap *swjdp = &armv7a->dap;
288
289 retval = mem_ap_write_atomic_u32(swjdp, address, value);
290
291 return retval;
292 }
293
294 /*
295 * Cortex-A8 implementation of Debug Programmer's Model
296 *
297 * NOTE the invariant: these routines return with DSCR_INSTR_COMP set,
298 * so there's no need to poll for it before executing an instruction.
299 *
300 * NOTE that in several of these cases the "stall" mode might be useful.
301 * It'd let us queue a few operations together... prepare/finish might
302 * be the places to enable/disable that mode.
303 */
304
305 static inline struct cortex_a8_common *dpm_to_a8(struct arm_dpm *dpm)
306 {
307 return container_of(dpm, struct cortex_a8_common, armv7a_common.dpm);
308 }
309
310 static int cortex_a8_write_dcc(struct cortex_a8_common *a8, uint32_t data)
311 {
312 LOG_DEBUG("write DCC 0x%08" PRIx32, data);
313 return mem_ap_write_u32(&a8->armv7a_common.dap,
314 a8->armv7a_common.debug_base + CPUDBG_DTRRX, data);
315 }
316
317 static int cortex_a8_read_dcc(struct cortex_a8_common *a8, uint32_t *data,
318 uint32_t *dscr_p)
319 {
320 struct adiv5_dap *swjdp = &a8->armv7a_common.dap;
321 uint32_t dscr = DSCR_INSTR_COMP;
322 int retval;
323
324 if (dscr_p)
325 dscr = *dscr_p;
326
327 /* Wait for DTRRXfull */
328 while ((dscr & DSCR_DTR_TX_FULL) == 0) {
329 retval = mem_ap_read_atomic_u32(swjdp,
330 a8->armv7a_common.debug_base + CPUDBG_DSCR,
331 &dscr);
332 }
333
334 retval = mem_ap_read_atomic_u32(swjdp,
335 a8->armv7a_common.debug_base + CPUDBG_DTRTX, data);
336 //LOG_DEBUG("read DCC 0x%08" PRIx32, *data);
337
338 if (dscr_p)
339 *dscr_p = dscr;
340
341 return retval;
342 }
343
344 static int cortex_a8_dpm_prepare(struct arm_dpm *dpm)
345 {
346 struct cortex_a8_common *a8 = dpm_to_a8(dpm);
347 struct adiv5_dap *swjdp = &a8->armv7a_common.dap;
348 uint32_t dscr;
349 int retval;
350
351 /* set up invariant: INSTR_COMP is set after ever DPM operation */
352 do {
353 retval = mem_ap_read_atomic_u32(swjdp,
354 a8->armv7a_common.debug_base + CPUDBG_DSCR,
355 &dscr);
356 } while ((dscr & DSCR_INSTR_COMP) == 0);
357
358 /* this "should never happen" ... */
359 if (dscr & DSCR_DTR_RX_FULL) {
360 LOG_ERROR("DSCR_DTR_RX_FULL, dscr 0x%08" PRIx32, dscr);
361 /* Clear DCCRX */
362 retval = cortex_a8_exec_opcode(
363 a8->armv7a_common.armv4_5_common.target,
364 ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
365 &dscr);
366 }
367
368 return retval;
369 }
370
371 static int cortex_a8_dpm_finish(struct arm_dpm *dpm)
372 {
373 /* REVISIT what could be done here? */
374 return ERROR_OK;
375 }
376
377 static int cortex_a8_instr_write_data_dcc(struct arm_dpm *dpm,
378 uint32_t opcode, uint32_t data)
379 {
380 struct cortex_a8_common *a8 = dpm_to_a8(dpm);
381 int retval;
382 uint32_t dscr = DSCR_INSTR_COMP;
383
384 retval = cortex_a8_write_dcc(a8, data);
385
386 return cortex_a8_exec_opcode(
387 a8->armv7a_common.armv4_5_common.target,
388 opcode,
389 &dscr);
390 }
391
392 static int cortex_a8_instr_write_data_r0(struct arm_dpm *dpm,
393 uint32_t opcode, uint32_t data)
394 {
395 struct cortex_a8_common *a8 = dpm_to_a8(dpm);
396 uint32_t dscr = DSCR_INSTR_COMP;
397 int retval;
398
399 retval = cortex_a8_write_dcc(a8, data);
400
401 /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15 */
402 retval = cortex_a8_exec_opcode(
403 a8->armv7a_common.armv4_5_common.target,
404 ARMV4_5_MRC(14, 0, 0, 0, 5, 0),
405 &dscr);
406
407 /* then the opcode, taking data from R0 */
408 retval = cortex_a8_exec_opcode(
409 a8->armv7a_common.armv4_5_common.target,
410 opcode,
411 &dscr);
412
413 return retval;
414 }
415
416 static int cortex_a8_instr_cpsr_sync(struct arm_dpm *dpm)
417 {
418 struct target *target = dpm->arm->target;
419 uint32_t dscr = DSCR_INSTR_COMP;
420
421 /* "Prefetch flush" after modifying execution status in CPSR */
422 return cortex_a8_exec_opcode(target,
423 ARMV4_5_MCR(15, 0, 0, 7, 5, 4),
424 &dscr);
425 }
426
427 static int cortex_a8_instr_read_data_dcc(struct arm_dpm *dpm,
428 uint32_t opcode, uint32_t *data)
429 {
430 struct cortex_a8_common *a8 = dpm_to_a8(dpm);
431 int retval;
432 uint32_t dscr = DSCR_INSTR_COMP;
433
434 /* the opcode, writing data to DCC */
435 retval = cortex_a8_exec_opcode(
436 a8->armv7a_common.armv4_5_common.target,
437 opcode,
438 &dscr);
439
440 return cortex_a8_read_dcc(a8, data, &dscr);
441 }
442
443
444 static int cortex_a8_instr_read_data_r0(struct arm_dpm *dpm,
445 uint32_t opcode, uint32_t *data)
446 {
447 struct cortex_a8_common *a8 = dpm_to_a8(dpm);
448 uint32_t dscr = DSCR_INSTR_COMP;
449 int retval;
450
451 /* the opcode, writing data to R0 */
452 retval = cortex_a8_exec_opcode(
453 a8->armv7a_common.armv4_5_common.target,
454 opcode,
455 &dscr);
456
457 /* write R0 to DCC */
458 retval = cortex_a8_exec_opcode(
459 a8->armv7a_common.armv4_5_common.target,
460 ARMV4_5_MCR(14, 0, 0, 0, 5, 0),
461 &dscr);
462
463 return cortex_a8_read_dcc(a8, data, &dscr);
464 }
465
466 static int cortex_a8_bpwp_enable(struct arm_dpm *dpm, unsigned index,
467 uint32_t addr, uint32_t control)
468 {
469 struct cortex_a8_common *a8 = dpm_to_a8(dpm);
470 uint32_t vr = a8->armv7a_common.debug_base;
471 uint32_t cr = a8->armv7a_common.debug_base;
472 int retval;
473
474 switch (index) {
475 case 0 ... 15: /* breakpoints */
476 vr += CPUDBG_BVR_BASE;
477 cr += CPUDBG_BCR_BASE;
478 break;
479 case 16 ... 31: /* watchpoints */
480 vr += CPUDBG_WVR_BASE;
481 cr += CPUDBG_WCR_BASE;
482 index -= 16;
483 break;
484 default:
485 return ERROR_FAIL;
486 }
487 vr += 4 * index;
488 cr += 4 * index;
489
490 LOG_DEBUG("A8: bpwp enable, vr %08x cr %08x",
491 (unsigned) vr, (unsigned) cr);
492
493 retval = cortex_a8_dap_write_memap_register_u32(dpm->arm->target,
494 vr, addr);
495 if (retval != ERROR_OK)
496 return retval;
497 retval = cortex_a8_dap_write_memap_register_u32(dpm->arm->target,
498 cr, control);
499 return retval;
500 }
501
502 static int cortex_a8_bpwp_disable(struct arm_dpm *dpm, unsigned index)
503 {
504 struct cortex_a8_common *a8 = dpm_to_a8(dpm);
505 uint32_t cr;
506
507 switch (index) {
508 case 0 ... 15:
509 cr = a8->armv7a_common.debug_base + CPUDBG_BCR_BASE;
510 break;
511 case 16 ... 31:
512 cr = a8->armv7a_common.debug_base + CPUDBG_WCR_BASE;
513 index -= 16;
514 break;
515 default:
516 return ERROR_FAIL;
517 }
518 cr += 4 * index;
519
520 LOG_DEBUG("A8: bpwp disable, cr %08x", (unsigned) cr);
521
522 /* clear control register */
523 return cortex_a8_dap_write_memap_register_u32(dpm->arm->target, cr, 0);
524 }
525
526 static int cortex_a8_dpm_setup(struct cortex_a8_common *a8, uint32_t didr)
527 {
528 struct arm_dpm *dpm = &a8->armv7a_common.dpm;
529 int retval;
530
531 dpm->arm = &a8->armv7a_common.armv4_5_common;
532 dpm->didr = didr;
533
534 dpm->prepare = cortex_a8_dpm_prepare;
535 dpm->finish = cortex_a8_dpm_finish;
536
537 dpm->instr_write_data_dcc = cortex_a8_instr_write_data_dcc;
538 dpm->instr_write_data_r0 = cortex_a8_instr_write_data_r0;
539 dpm->instr_cpsr_sync = cortex_a8_instr_cpsr_sync;
540
541 dpm->instr_read_data_dcc = cortex_a8_instr_read_data_dcc;
542 dpm->instr_read_data_r0 = cortex_a8_instr_read_data_r0;
543
544 dpm->bpwp_enable = cortex_a8_bpwp_enable;
545 dpm->bpwp_disable = cortex_a8_bpwp_disable;
546
547 retval = arm_dpm_setup(dpm);
548 if (retval == ERROR_OK)
549 retval = arm_dpm_initialize(dpm);
550
551 return retval;
552 }
553
554
555 /*
556 * Cortex-A8 Run control
557 */
558
559 static int cortex_a8_poll(struct target *target)
560 {
561 int retval = ERROR_OK;
562 uint32_t dscr;
563 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
564 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
565 struct adiv5_dap *swjdp = &armv7a->dap;
566 enum target_state prev_target_state = target->state;
567 uint8_t saved_apsel = dap_ap_get_select(swjdp);
568
569 dap_ap_select(swjdp, swjdp_debugap);
570 retval = mem_ap_read_atomic_u32(swjdp,
571 armv7a->debug_base + CPUDBG_DSCR, &dscr);
572 if (retval != ERROR_OK)
573 {
574 dap_ap_select(swjdp, saved_apsel);
575 return retval;
576 }
577 cortex_a8->cpudbg_dscr = dscr;
578
579 if ((dscr & 0x3) == 0x3)
580 {
581 if (prev_target_state != TARGET_HALTED)
582 {
583 /* We have a halting debug event */
584 LOG_DEBUG("Target halted");
585 target->state = TARGET_HALTED;
586 if ((prev_target_state == TARGET_RUNNING)
587 || (prev_target_state == TARGET_RESET))
588 {
589 retval = cortex_a8_debug_entry(target);
590 if (retval != ERROR_OK)
591 return retval;
592
593 target_call_event_callbacks(target,
594 TARGET_EVENT_HALTED);
595 }
596 if (prev_target_state == TARGET_DEBUG_RUNNING)
597 {
598 LOG_DEBUG(" ");
599
600 retval = cortex_a8_debug_entry(target);
601 if (retval != ERROR_OK)
602 return retval;
603
604 target_call_event_callbacks(target,
605 TARGET_EVENT_DEBUG_HALTED);
606 }
607 }
608 }
609 else if ((dscr & 0x3) == 0x2)
610 {
611 target->state = TARGET_RUNNING;
612 }
613 else
614 {
615 LOG_DEBUG("Unknown target state dscr = 0x%08" PRIx32, dscr);
616 target->state = TARGET_UNKNOWN;
617 }
618
619 dap_ap_select(swjdp, saved_apsel);
620
621 return retval;
622 }
623
624 static int cortex_a8_halt(struct target *target)
625 {
626 int retval = ERROR_OK;
627 uint32_t dscr;
628 struct armv7a_common *armv7a = target_to_armv7a(target);
629 struct adiv5_dap *swjdp = &armv7a->dap;
630 uint8_t saved_apsel = dap_ap_get_select(swjdp);
631 dap_ap_select(swjdp, swjdp_debugap);
632
633 /*
634 * Tell the core to be halted by writing DRCR with 0x1
635 * and then wait for the core to be halted.
636 */
637 retval = mem_ap_write_atomic_u32(swjdp,
638 armv7a->debug_base + CPUDBG_DRCR, 0x1);
639
640 /*
641 * enter halting debug mode
642 */
643 mem_ap_read_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_DSCR, &dscr);
644 retval = mem_ap_write_atomic_u32(swjdp,
645 armv7a->debug_base + CPUDBG_DSCR, dscr | DSCR_HALT_DBG_MODE);
646
647 if (retval != ERROR_OK)
648 goto out;
649
650 do {
651 mem_ap_read_atomic_u32(swjdp,
652 armv7a->debug_base + CPUDBG_DSCR, &dscr);
653 } while ((dscr & DSCR_CORE_HALTED) == 0);
654
655 target->debug_reason = DBG_REASON_DBGRQ;
656
657 out:
658 dap_ap_select(swjdp, saved_apsel);
659 return retval;
660 }
661
662 static int cortex_a8_resume(struct target *target, int current,
663 uint32_t address, int handle_breakpoints, int debug_execution)
664 {
665 struct armv7a_common *armv7a = target_to_armv7a(target);
666 struct arm *armv4_5 = &armv7a->armv4_5_common;
667 struct adiv5_dap *swjdp = &armv7a->dap;
668
669 // struct breakpoint *breakpoint = NULL;
670 uint32_t resume_pc, dscr;
671
672 uint8_t saved_apsel = dap_ap_get_select(swjdp);
673 dap_ap_select(swjdp, swjdp_debugap);
674
675 if (!debug_execution)
676 target_free_all_working_areas(target);
677
678 #if 0
679 if (debug_execution)
680 {
681 /* Disable interrupts */
682 /* We disable interrupts in the PRIMASK register instead of
683 * masking with C_MASKINTS,
684 * This is probably the same issue as Cortex-M3 Errata 377493:
685 * C_MASKINTS in parallel with disabled interrupts can cause
686 * local faults to not be taken. */
687 buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_PRIMASK].value, 0, 32, 1);
688 armv7m->core_cache->reg_list[ARMV7M_PRIMASK].dirty = 1;
689 armv7m->core_cache->reg_list[ARMV7M_PRIMASK].valid = 1;
690
691 /* Make sure we are in Thumb mode */
692 buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32,
693 buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32) | (1 << 24));
694 armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty = 1;
695 armv7m->core_cache->reg_list[ARMV7M_xPSR].valid = 1;
696 }
697 #endif
698
699 /* current = 1: continue on current pc, otherwise continue at <address> */
700 resume_pc = buf_get_u32(armv4_5->pc->value, 0, 32);
701 if (!current)
702 resume_pc = address;
703
704 /* Make sure that the Armv7 gdb thumb fixups does not
705 * kill the return address
706 */
707 switch (armv4_5->core_state)
708 {
709 case ARM_STATE_ARM:
710 resume_pc &= 0xFFFFFFFC;
711 break;
712 case ARM_STATE_THUMB:
713 case ARM_STATE_THUMB_EE:
714 /* When the return address is loaded into PC
715 * bit 0 must be 1 to stay in Thumb state
716 */
717 resume_pc |= 0x1;
718 break;
719 case ARM_STATE_JAZELLE:
720 LOG_ERROR("How do I resume into Jazelle state??");
721 return ERROR_FAIL;
722 }
723 LOG_DEBUG("resume pc = 0x%08" PRIx32, resume_pc);
724 buf_set_u32(armv4_5->pc->value, 0, 32, resume_pc);
725 armv4_5->pc->dirty = 1;
726 armv4_5->pc->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 adiv5_dap *swjdp = &armv7a->dap;
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->pc;
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->pc;
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 adiv5_dap *swjdp = &armv7a->dap;
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 adiv5_dap *swjdp = &armv7a->dap;
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 adiv5_dap *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 adiv5_dap *swjdp = &armv7a->dap;
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 adiv5_dap *swjdp = &armv7a->dap;
1459 int i;
1460 int retval = ERROR_OK;
1461 uint32_t didr, ctypr, ttypr, cpuid;
1462
1463 /* stop assuming this is an OMAP! */
1464 LOG_DEBUG("TODO - autoconfigure");
1465
1466 /* Here we shall insert a proper ROM Table scan */
1467 armv7a->debug_base = OMAP3530_DEBUG_BASE;
1468
1469 /* We do one extra read to ensure DAP is configured,
1470 * we call ahbap_debugport_init(swjdp) instead
1471 */
1472 ahbap_debugport_init(swjdp);
1473 mem_ap_read_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_CPUID, &cpuid);
1474 if ((retval = mem_ap_read_atomic_u32(swjdp,
1475 armv7a->debug_base + CPUDBG_CPUID, &cpuid)) != ERROR_OK)
1476 {
1477 LOG_DEBUG("Examine %s failed", "CPUID");
1478 return retval;
1479 }
1480
1481 if ((retval = mem_ap_read_atomic_u32(swjdp,
1482 armv7a->debug_base + CPUDBG_CTYPR, &ctypr)) != ERROR_OK)
1483 {
1484 LOG_DEBUG("Examine %s failed", "CTYPR");
1485 return retval;
1486 }
1487
1488 if ((retval = mem_ap_read_atomic_u32(swjdp,
1489 armv7a->debug_base + CPUDBG_TTYPR, &ttypr)) != ERROR_OK)
1490 {
1491 LOG_DEBUG("Examine %s failed", "TTYPR");
1492 return retval;
1493 }
1494
1495 if ((retval = mem_ap_read_atomic_u32(swjdp,
1496 armv7a->debug_base + CPUDBG_DIDR, &didr)) != ERROR_OK)
1497 {
1498 LOG_DEBUG("Examine %s failed", "DIDR");
1499 return retval;
1500 }
1501
1502 LOG_DEBUG("cpuid = 0x%08" PRIx32, cpuid);
1503 LOG_DEBUG("ctypr = 0x%08" PRIx32, ctypr);
1504 LOG_DEBUG("ttypr = 0x%08" PRIx32, ttypr);
1505 LOG_DEBUG("didr = 0x%08" PRIx32, didr);
1506
1507 armv7a->armv4_5_common.core_type = ARM_MODE_MON;
1508 cortex_a8_dpm_setup(cortex_a8, didr);
1509
1510 /* Setup Breakpoint Register Pairs */
1511 cortex_a8->brp_num = ((didr >> 24) & 0x0F) + 1;
1512 cortex_a8->brp_num_context = ((didr >> 20) & 0x0F) + 1;
1513 cortex_a8->brp_num_available = cortex_a8->brp_num;
1514 cortex_a8->brp_list = calloc(cortex_a8->brp_num, sizeof(struct cortex_a8_brp));
1515 // cortex_a8->brb_enabled = ????;
1516 for (i = 0; i < cortex_a8->brp_num; i++)
1517 {
1518 cortex_a8->brp_list[i].used = 0;
1519 if (i < (cortex_a8->brp_num-cortex_a8->brp_num_context))
1520 cortex_a8->brp_list[i].type = BRP_NORMAL;
1521 else
1522 cortex_a8->brp_list[i].type = BRP_CONTEXT;
1523 cortex_a8->brp_list[i].value = 0;
1524 cortex_a8->brp_list[i].control = 0;
1525 cortex_a8->brp_list[i].BRPn = i;
1526 }
1527
1528 LOG_DEBUG("Configured %i hw breakpoints", cortex_a8->brp_num);
1529
1530 target_set_examined(target);
1531 return ERROR_OK;
1532 }
1533
1534 static int cortex_a8_examine(struct target *target)
1535 {
1536 int retval = ERROR_OK;
1537
1538 /* don't re-probe hardware after each reset */
1539 if (!target_was_examined(target))
1540 retval = cortex_a8_examine_first(target);
1541
1542 /* Configure core debug access */
1543 if (retval == ERROR_OK)
1544 retval = cortex_a8_init_debug_access(target);
1545
1546 return retval;
1547 }
1548
1549 /*
1550 * Cortex-A8 target creation and initialization
1551 */
1552
1553 static int cortex_a8_init_target(struct command_context *cmd_ctx,
1554 struct target *target)
1555 {
1556 /* examine_first() does a bunch of this */
1557 return ERROR_OK;
1558 }
1559
1560 static int cortex_a8_init_arch_info(struct target *target,
1561 struct cortex_a8_common *cortex_a8, struct jtag_tap *tap)
1562 {
1563 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
1564 struct arm *armv4_5 = &armv7a->armv4_5_common;
1565 struct adiv5_dap *dap = &armv7a->dap;
1566
1567 armv7a->armv4_5_common.dap = dap;
1568
1569 /* Setup struct cortex_a8_common */
1570 cortex_a8->common_magic = CORTEX_A8_COMMON_MAGIC;
1571 armv4_5->arch_info = armv7a;
1572
1573 /* prepare JTAG information for the new target */
1574 cortex_a8->jtag_info.tap = tap;
1575 cortex_a8->jtag_info.scann_size = 4;
1576
1577 /* Leave (only) generic DAP stuff for debugport_init() */
1578 dap->jtag_info = &cortex_a8->jtag_info;
1579 dap->memaccess_tck = 80;
1580
1581 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1582 dap->tar_autoincr_block = (1 << 10);
1583
1584 cortex_a8->fast_reg_read = 0;
1585
1586 /* register arch-specific functions */
1587 armv7a->examine_debug_reason = NULL;
1588
1589 armv7a->post_debug_entry = cortex_a8_post_debug_entry;
1590
1591 armv7a->pre_restore_context = NULL;
1592 armv7a->post_restore_context = NULL;
1593 armv7a->armv4_5_mmu.armv4_5_cache.ctype = -1;
1594 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1595 armv7a->armv4_5_mmu.read_memory = cortex_a8_read_memory;
1596 armv7a->armv4_5_mmu.write_memory = cortex_a8_write_memory;
1597 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1598 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1599 armv7a->armv4_5_mmu.has_tiny_pages = 1;
1600 armv7a->armv4_5_mmu.mmu_enabled = 0;
1601
1602
1603 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1604
1605 /* REVISIT v7a setup should be in a v7a-specific routine */
1606 arm_init_arch_info(target, armv4_5);
1607 armv7a->common_magic = ARMV7_COMMON_MAGIC;
1608
1609 target_register_timer_callback(cortex_a8_handle_target_request, 1, 1, target);
1610
1611 return ERROR_OK;
1612 }
1613
1614 static int cortex_a8_target_create(struct target *target, Jim_Interp *interp)
1615 {
1616 struct cortex_a8_common *cortex_a8 = calloc(1, sizeof(struct cortex_a8_common));
1617
1618 cortex_a8_init_arch_info(target, cortex_a8, target->tap);
1619
1620 return ERROR_OK;
1621 }
1622
1623 COMMAND_HANDLER(cortex_a8_handle_cache_info_command)
1624 {
1625 struct target *target = get_current_target(CMD_CTX);
1626 struct armv7a_common *armv7a = target_to_armv7a(target);
1627
1628 return armv4_5_handle_cache_info_command(CMD_CTX,
1629 &armv7a->armv4_5_mmu.armv4_5_cache);
1630 }
1631
1632
1633 COMMAND_HANDLER(cortex_a8_handle_dbginit_command)
1634 {
1635 struct target *target = get_current_target(CMD_CTX);
1636
1637 cortex_a8_init_debug_access(target);
1638
1639 return ERROR_OK;
1640 }
1641
1642 static const struct command_registration cortex_a8_exec_command_handlers[] = {
1643 {
1644 .name = "cache_info",
1645 .handler = cortex_a8_handle_cache_info_command,
1646 .mode = COMMAND_EXEC,
1647 .help = "display information about target caches",
1648 },
1649 {
1650 .name = "dbginit",
1651 .handler = cortex_a8_handle_dbginit_command,
1652 .mode = COMMAND_EXEC,
1653 .help = "Initialize core debug",
1654 },
1655 COMMAND_REGISTRATION_DONE
1656 };
1657 static const struct command_registration cortex_a8_command_handlers[] = {
1658 {
1659 .chain = arm_command_handlers,
1660 },
1661 {
1662 .chain = armv7a_command_handlers,
1663 },
1664 {
1665 .name = "cortex_a8",
1666 .mode = COMMAND_ANY,
1667 .help = "Cortex-A8 command group",
1668 .chain = cortex_a8_exec_command_handlers,
1669 },
1670 COMMAND_REGISTRATION_DONE
1671 };
1672
1673 struct target_type cortexa8_target = {
1674 .name = "cortex_a8",
1675
1676 .poll = cortex_a8_poll,
1677 .arch_state = armv7a_arch_state,
1678
1679 .target_request_data = NULL,
1680
1681 .halt = cortex_a8_halt,
1682 .resume = cortex_a8_resume,
1683 .step = cortex_a8_step,
1684
1685 .assert_reset = cortex_a8_assert_reset,
1686 .deassert_reset = cortex_a8_deassert_reset,
1687 .soft_reset_halt = NULL,
1688
1689 /* REVISIT allow exporting VFP3 registers ... */
1690 .get_gdb_reg_list = arm_get_gdb_reg_list,
1691
1692 .read_memory = cortex_a8_read_memory,
1693 .write_memory = cortex_a8_write_memory,
1694 .bulk_write_memory = cortex_a8_bulk_write_memory,
1695
1696 .checksum_memory = arm_checksum_memory,
1697 .blank_check_memory = arm_blank_check_memory,
1698
1699 .run_algorithm = armv4_5_run_algorithm,
1700
1701 .add_breakpoint = cortex_a8_add_breakpoint,
1702 .remove_breakpoint = cortex_a8_remove_breakpoint,
1703 .add_watchpoint = NULL,
1704 .remove_watchpoint = NULL,
1705
1706 .commands = cortex_a8_command_handlers,
1707 .target_create = cortex_a8_target_create,
1708 .init_target = cortex_a8_init_target,
1709 .examine = cortex_a8_examine,
1710 };

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)