jtag: retire one instance of jtag_get_end_state() usage
[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 return ERROR_OK;
1024 }
1025
1026
1027 /*
1028 * Cortex-A8 Breakpoint and watchpoint fuctions
1029 */
1030
1031 /* Setup hardware Breakpoint Register Pair */
1032 static int cortex_a8_set_breakpoint(struct target *target,
1033 struct breakpoint *breakpoint, uint8_t matchmode)
1034 {
1035 int retval;
1036 int brp_i=0;
1037 uint32_t control;
1038 uint8_t byte_addr_select = 0x0F;
1039 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
1040 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
1041 struct cortex_a8_brp * brp_list = cortex_a8->brp_list;
1042
1043 if (breakpoint->set)
1044 {
1045 LOG_WARNING("breakpoint already set");
1046 return ERROR_OK;
1047 }
1048
1049 if (breakpoint->type == BKPT_HARD)
1050 {
1051 while (brp_list[brp_i].used && (brp_i < cortex_a8->brp_num))
1052 brp_i++ ;
1053 if (brp_i >= cortex_a8->brp_num)
1054 {
1055 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1056 return ERROR_FAIL;
1057 }
1058 breakpoint->set = brp_i + 1;
1059 if (breakpoint->length == 2)
1060 {
1061 byte_addr_select = (3 << (breakpoint->address & 0x02));
1062 }
1063 control = ((matchmode & 0x7) << 20)
1064 | (byte_addr_select << 5)
1065 | (3 << 1) | 1;
1066 brp_list[brp_i].used = 1;
1067 brp_list[brp_i].value = (breakpoint->address & 0xFFFFFFFC);
1068 brp_list[brp_i].control = control;
1069 cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
1070 + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn,
1071 brp_list[brp_i].value);
1072 cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
1073 + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn,
1074 brp_list[brp_i].control);
1075 LOG_DEBUG("brp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_i,
1076 brp_list[brp_i].control,
1077 brp_list[brp_i].value);
1078 }
1079 else if (breakpoint->type == BKPT_SOFT)
1080 {
1081 uint8_t code[4];
1082 if (breakpoint->length == 2)
1083 {
1084 buf_set_u32(code, 0, 32, ARMV5_T_BKPT(0x11));
1085 }
1086 else
1087 {
1088 buf_set_u32(code, 0, 32, ARMV5_BKPT(0x11));
1089 }
1090 retval = target->type->read_memory(target,
1091 breakpoint->address & 0xFFFFFFFE,
1092 breakpoint->length, 1,
1093 breakpoint->orig_instr);
1094 if (retval != ERROR_OK)
1095 return retval;
1096 retval = target->type->write_memory(target,
1097 breakpoint->address & 0xFFFFFFFE,
1098 breakpoint->length, 1, code);
1099 if (retval != ERROR_OK)
1100 return retval;
1101 breakpoint->set = 0x11; /* Any nice value but 0 */
1102 }
1103
1104 return ERROR_OK;
1105 }
1106
1107 static int cortex_a8_unset_breakpoint(struct target *target, struct breakpoint *breakpoint)
1108 {
1109 int retval;
1110 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
1111 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
1112 struct cortex_a8_brp * brp_list = cortex_a8->brp_list;
1113
1114 if (!breakpoint->set)
1115 {
1116 LOG_WARNING("breakpoint not set");
1117 return ERROR_OK;
1118 }
1119
1120 if (breakpoint->type == BKPT_HARD)
1121 {
1122 int brp_i = breakpoint->set - 1;
1123 if ((brp_i < 0) || (brp_i >= cortex_a8->brp_num))
1124 {
1125 LOG_DEBUG("Invalid BRP number in breakpoint");
1126 return ERROR_OK;
1127 }
1128 LOG_DEBUG("rbp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_i,
1129 brp_list[brp_i].control, brp_list[brp_i].value);
1130 brp_list[brp_i].used = 0;
1131 brp_list[brp_i].value = 0;
1132 brp_list[brp_i].control = 0;
1133 cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
1134 + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn,
1135 brp_list[brp_i].control);
1136 cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
1137 + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn,
1138 brp_list[brp_i].value);
1139 }
1140 else
1141 {
1142 /* restore original instruction (kept in target endianness) */
1143 if (breakpoint->length == 4)
1144 {
1145 retval = target->type->write_memory(target,
1146 breakpoint->address & 0xFFFFFFFE,
1147 4, 1, breakpoint->orig_instr);
1148 if (retval != ERROR_OK)
1149 return retval;
1150 }
1151 else
1152 {
1153 retval = target->type->write_memory(target,
1154 breakpoint->address & 0xFFFFFFFE,
1155 2, 1, breakpoint->orig_instr);
1156 if (retval != ERROR_OK)
1157 return retval;
1158 }
1159 }
1160 breakpoint->set = 0;
1161
1162 return ERROR_OK;
1163 }
1164
1165 static int cortex_a8_add_breakpoint(struct target *target,
1166 struct breakpoint *breakpoint)
1167 {
1168 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
1169
1170 if ((breakpoint->type == BKPT_HARD) && (cortex_a8->brp_num_available < 1))
1171 {
1172 LOG_INFO("no hardware breakpoint available");
1173 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1174 }
1175
1176 if (breakpoint->type == BKPT_HARD)
1177 cortex_a8->brp_num_available--;
1178 cortex_a8_set_breakpoint(target, breakpoint, 0x00); /* Exact match */
1179
1180 return ERROR_OK;
1181 }
1182
1183 static int cortex_a8_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)
1184 {
1185 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
1186
1187 #if 0
1188 /* It is perfectly possible to remove brakpoints while the taget is running */
1189 if (target->state != TARGET_HALTED)
1190 {
1191 LOG_WARNING("target not halted");
1192 return ERROR_TARGET_NOT_HALTED;
1193 }
1194 #endif
1195
1196 if (breakpoint->set)
1197 {
1198 cortex_a8_unset_breakpoint(target, breakpoint);
1199 if (breakpoint->type == BKPT_HARD)
1200 cortex_a8->brp_num_available++ ;
1201 }
1202
1203
1204 return ERROR_OK;
1205 }
1206
1207
1208
1209 /*
1210 * Cortex-A8 Reset fuctions
1211 */
1212
1213 static int cortex_a8_assert_reset(struct target *target)
1214 {
1215 struct armv7a_common *armv7a = target_to_armv7a(target);
1216
1217 LOG_DEBUG(" ");
1218
1219 /* FIXME when halt is requested, make it work somehow... */
1220
1221 /* Issue some kind of warm reset. */
1222 if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT)) {
1223 target_handle_event(target, TARGET_EVENT_RESET_ASSERT);
1224 } else if (jtag_get_reset_config() & RESET_HAS_SRST) {
1225 /* REVISIT handle "pulls" cases, if there's
1226 * hardware that needs them to work.
1227 */
1228 jtag_add_reset(0, 1);
1229 } else {
1230 LOG_ERROR("%s: how to reset?", target_name(target));
1231 return ERROR_FAIL;
1232 }
1233
1234 /* registers are now invalid */
1235 register_cache_invalidate(armv7a->armv4_5_common.core_cache);
1236
1237 target->state = TARGET_RESET;
1238
1239 return ERROR_OK;
1240 }
1241
1242 static int cortex_a8_deassert_reset(struct target *target)
1243 {
1244 int retval;
1245
1246 LOG_DEBUG(" ");
1247
1248 /* be certain SRST is off */
1249 jtag_add_reset(0, 0);
1250
1251 retval = cortex_a8_poll(target);
1252
1253 if (target->reset_halt) {
1254 if (target->state != TARGET_HALTED) {
1255 LOG_WARNING("%s: ran after reset and before halt ...",
1256 target_name(target));
1257 if ((retval = target_halt(target)) != ERROR_OK)
1258 return retval;
1259 }
1260 }
1261
1262 return ERROR_OK;
1263 }
1264
1265 /*
1266 * Cortex-A8 Memory access
1267 *
1268 * This is same Cortex M3 but we must also use the correct
1269 * ap number for every access.
1270 */
1271
1272 static int cortex_a8_read_memory(struct target *target, uint32_t address,
1273 uint32_t size, uint32_t count, uint8_t *buffer)
1274 {
1275 struct armv7a_common *armv7a = target_to_armv7a(target);
1276 struct adiv5_dap *swjdp = &armv7a->dap;
1277 int retval = ERROR_INVALID_ARGUMENTS;
1278
1279 /* cortex_a8 handles unaligned memory access */
1280
1281 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1282
1283 if (count && buffer) {
1284 switch (size) {
1285 case 4:
1286 retval = mem_ap_read_buf_u32(swjdp, buffer, 4 * count, address);
1287 break;
1288 case 2:
1289 retval = mem_ap_read_buf_u16(swjdp, buffer, 2 * count, address);
1290 break;
1291 case 1:
1292 retval = mem_ap_read_buf_u8(swjdp, buffer, count, address);
1293 break;
1294 }
1295 }
1296
1297 return retval;
1298 }
1299
1300 static int cortex_a8_write_memory(struct target *target, uint32_t address,
1301 uint32_t size, uint32_t count, uint8_t *buffer)
1302 {
1303 struct armv7a_common *armv7a = target_to_armv7a(target);
1304 struct adiv5_dap *swjdp = &armv7a->dap;
1305 int retval = ERROR_INVALID_ARGUMENTS;
1306
1307 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1308
1309 if (count && buffer) {
1310 switch (size) {
1311 case 4:
1312 retval = mem_ap_write_buf_u32(swjdp, buffer, 4 * count, address);
1313 break;
1314 case 2:
1315 retval = mem_ap_write_buf_u16(swjdp, buffer, 2 * count, address);
1316 break;
1317 case 1:
1318 retval = mem_ap_write_buf_u8(swjdp, buffer, count, address);
1319 break;
1320 }
1321 }
1322
1323 /* REVISIT this op is generic ARMv7-A/R stuff */
1324 if (retval == ERROR_OK && target->state == TARGET_HALTED)
1325 {
1326 struct arm_dpm *dpm = armv7a->armv4_5_common.dpm;
1327
1328 retval = dpm->prepare(dpm);
1329 if (retval != ERROR_OK)
1330 return retval;
1331
1332 /* The Cache handling will NOT work with MMU active, the
1333 * wrong addresses will be invalidated!
1334 *
1335 * For both ICache and DCache, walk all cache lines in the
1336 * address range. Cortex-A8 has fixed 64 byte line length.
1337 *
1338 * REVISIT per ARMv7, these may trigger watchpoints ...
1339 */
1340
1341 /* invalidate I-Cache */
1342 if (armv7a->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
1343 {
1344 /* ICIMVAU - Invalidate Cache single entry
1345 * with MVA to PoU
1346 * MCR p15, 0, r0, c7, c5, 1
1347 */
1348 for (uint32_t cacheline = address;
1349 cacheline < address + size * count;
1350 cacheline += 64) {
1351 retval = dpm->instr_write_data_r0(dpm,
1352 ARMV4_5_MCR(15, 0, 0, 7, 5, 1),
1353 cacheline);
1354 }
1355 }
1356
1357 /* invalidate D-Cache */
1358 if (armv7a->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled)
1359 {
1360 /* DCIMVAC - Invalidate data Cache line
1361 * with MVA to PoC
1362 * MCR p15, 0, r0, c7, c6, 1
1363 */
1364 for (uint32_t cacheline = address;
1365 cacheline < address + size * count;
1366 cacheline += 64) {
1367 retval = dpm->instr_write_data_r0(dpm,
1368 ARMV4_5_MCR(15, 0, 0, 7, 6, 1),
1369 cacheline);
1370 }
1371 }
1372
1373 /* (void) */ dpm->finish(dpm);
1374 }
1375
1376 return retval;
1377 }
1378
1379 static int cortex_a8_bulk_write_memory(struct target *target, uint32_t address,
1380 uint32_t count, uint8_t *buffer)
1381 {
1382 return cortex_a8_write_memory(target, address, 4, count, buffer);
1383 }
1384
1385
1386 static int cortex_a8_dcc_read(struct adiv5_dap *swjdp, uint8_t *value, uint8_t *ctrl)
1387 {
1388 #if 0
1389 u16 dcrdr;
1390
1391 mem_ap_read_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
1392 *ctrl = (uint8_t)dcrdr;
1393 *value = (uint8_t)(dcrdr >> 8);
1394
1395 LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
1396
1397 /* write ack back to software dcc register
1398 * signify we have read data */
1399 if (dcrdr & (1 << 0))
1400 {
1401 dcrdr = 0;
1402 mem_ap_write_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
1403 }
1404 #endif
1405 return ERROR_OK;
1406 }
1407
1408
1409 static int cortex_a8_handle_target_request(void *priv)
1410 {
1411 struct target *target = priv;
1412 struct armv7a_common *armv7a = target_to_armv7a(target);
1413 struct adiv5_dap *swjdp = &armv7a->dap;
1414
1415 if (!target_was_examined(target))
1416 return ERROR_OK;
1417 if (!target->dbg_msg_enabled)
1418 return ERROR_OK;
1419
1420 if (target->state == TARGET_RUNNING)
1421 {
1422 uint8_t data = 0;
1423 uint8_t ctrl = 0;
1424
1425 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1426
1427 /* check if we have data */
1428 if (ctrl & (1 << 0))
1429 {
1430 uint32_t request;
1431
1432 /* we assume target is quick enough */
1433 request = data;
1434 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1435 request |= (data << 8);
1436 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1437 request |= (data << 16);
1438 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1439 request |= (data << 24);
1440 target_request(target, request);
1441 }
1442 }
1443
1444 return ERROR_OK;
1445 }
1446
1447 /*
1448 * Cortex-A8 target information and configuration
1449 */
1450
1451 static int cortex_a8_examine_first(struct target *target)
1452 {
1453 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
1454 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
1455 struct adiv5_dap *swjdp = &armv7a->dap;
1456 int i;
1457 int retval = ERROR_OK;
1458 uint32_t didr, ctypr, ttypr, cpuid;
1459
1460 /* stop assuming this is an OMAP! */
1461 LOG_DEBUG("TODO - autoconfigure");
1462
1463 /* Here we shall insert a proper ROM Table scan */
1464 armv7a->debug_base = OMAP3530_DEBUG_BASE;
1465
1466 /* We do one extra read to ensure DAP is configured,
1467 * we call ahbap_debugport_init(swjdp) instead
1468 */
1469 ahbap_debugport_init(swjdp);
1470 mem_ap_read_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_CPUID, &cpuid);
1471 if ((retval = mem_ap_read_atomic_u32(swjdp,
1472 armv7a->debug_base + CPUDBG_CPUID, &cpuid)) != ERROR_OK)
1473 {
1474 LOG_DEBUG("Examine %s failed", "CPUID");
1475 return retval;
1476 }
1477
1478 if ((retval = mem_ap_read_atomic_u32(swjdp,
1479 armv7a->debug_base + CPUDBG_CTYPR, &ctypr)) != ERROR_OK)
1480 {
1481 LOG_DEBUG("Examine %s failed", "CTYPR");
1482 return retval;
1483 }
1484
1485 if ((retval = mem_ap_read_atomic_u32(swjdp,
1486 armv7a->debug_base + CPUDBG_TTYPR, &ttypr)) != ERROR_OK)
1487 {
1488 LOG_DEBUG("Examine %s failed", "TTYPR");
1489 return retval;
1490 }
1491
1492 if ((retval = mem_ap_read_atomic_u32(swjdp,
1493 armv7a->debug_base + CPUDBG_DIDR, &didr)) != ERROR_OK)
1494 {
1495 LOG_DEBUG("Examine %s failed", "DIDR");
1496 return retval;
1497 }
1498
1499 LOG_DEBUG("cpuid = 0x%08" PRIx32, cpuid);
1500 LOG_DEBUG("ctypr = 0x%08" PRIx32, ctypr);
1501 LOG_DEBUG("ttypr = 0x%08" PRIx32, ttypr);
1502 LOG_DEBUG("didr = 0x%08" PRIx32, didr);
1503
1504 armv7a->armv4_5_common.core_type = ARM_MODE_MON;
1505 cortex_a8_dpm_setup(cortex_a8, didr);
1506
1507 /* Setup Breakpoint Register Pairs */
1508 cortex_a8->brp_num = ((didr >> 24) & 0x0F) + 1;
1509 cortex_a8->brp_num_context = ((didr >> 20) & 0x0F) + 1;
1510 cortex_a8->brp_num_available = cortex_a8->brp_num;
1511 cortex_a8->brp_list = calloc(cortex_a8->brp_num, sizeof(struct cortex_a8_brp));
1512 // cortex_a8->brb_enabled = ????;
1513 for (i = 0; i < cortex_a8->brp_num; i++)
1514 {
1515 cortex_a8->brp_list[i].used = 0;
1516 if (i < (cortex_a8->brp_num-cortex_a8->brp_num_context))
1517 cortex_a8->brp_list[i].type = BRP_NORMAL;
1518 else
1519 cortex_a8->brp_list[i].type = BRP_CONTEXT;
1520 cortex_a8->brp_list[i].value = 0;
1521 cortex_a8->brp_list[i].control = 0;
1522 cortex_a8->brp_list[i].BRPn = i;
1523 }
1524
1525 LOG_DEBUG("Configured %i hw breakpoints", cortex_a8->brp_num);
1526
1527 target_set_examined(target);
1528 return ERROR_OK;
1529 }
1530
1531 static int cortex_a8_examine(struct target *target)
1532 {
1533 int retval = ERROR_OK;
1534
1535 /* don't re-probe hardware after each reset */
1536 if (!target_was_examined(target))
1537 retval = cortex_a8_examine_first(target);
1538
1539 /* Configure core debug access */
1540 if (retval == ERROR_OK)
1541 retval = cortex_a8_init_debug_access(target);
1542
1543 return retval;
1544 }
1545
1546 /*
1547 * Cortex-A8 target creation and initialization
1548 */
1549
1550 static int cortex_a8_init_target(struct command_context *cmd_ctx,
1551 struct target *target)
1552 {
1553 /* examine_first() does a bunch of this */
1554 return ERROR_OK;
1555 }
1556
1557 static int cortex_a8_init_arch_info(struct target *target,
1558 struct cortex_a8_common *cortex_a8, struct jtag_tap *tap)
1559 {
1560 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
1561 struct arm *armv4_5 = &armv7a->armv4_5_common;
1562 struct adiv5_dap *dap = &armv7a->dap;
1563
1564 armv7a->armv4_5_common.dap = dap;
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 /* Leave (only) generic DAP stuff for debugport_init() */
1575 dap->jtag_info = &cortex_a8->jtag_info;
1576 dap->memaccess_tck = 80;
1577
1578 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1579 dap->tar_autoincr_block = (1 << 10);
1580
1581 cortex_a8->fast_reg_read = 0;
1582
1583 /* register arch-specific functions */
1584 armv7a->examine_debug_reason = NULL;
1585
1586 armv7a->post_debug_entry = cortex_a8_post_debug_entry;
1587
1588 armv7a->pre_restore_context = NULL;
1589 armv7a->armv4_5_mmu.armv4_5_cache.ctype = -1;
1590 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1591 armv7a->armv4_5_mmu.read_memory = cortex_a8_read_memory;
1592 armv7a->armv4_5_mmu.write_memory = cortex_a8_write_memory;
1593 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1594 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1595 armv7a->armv4_5_mmu.has_tiny_pages = 1;
1596 armv7a->armv4_5_mmu.mmu_enabled = 0;
1597
1598
1599 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1600
1601 /* REVISIT v7a setup should be in a v7a-specific routine */
1602 arm_init_arch_info(target, armv4_5);
1603 armv7a->common_magic = ARMV7_COMMON_MAGIC;
1604
1605 target_register_timer_callback(cortex_a8_handle_target_request, 1, 1, target);
1606
1607 return ERROR_OK;
1608 }
1609
1610 static int cortex_a8_target_create(struct target *target, Jim_Interp *interp)
1611 {
1612 struct cortex_a8_common *cortex_a8 = calloc(1, sizeof(struct cortex_a8_common));
1613
1614 cortex_a8_init_arch_info(target, cortex_a8, target->tap);
1615
1616 return ERROR_OK;
1617 }
1618
1619 COMMAND_HANDLER(cortex_a8_handle_cache_info_command)
1620 {
1621 struct target *target = get_current_target(CMD_CTX);
1622 struct armv7a_common *armv7a = target_to_armv7a(target);
1623
1624 return armv4_5_handle_cache_info_command(CMD_CTX,
1625 &armv7a->armv4_5_mmu.armv4_5_cache);
1626 }
1627
1628
1629 COMMAND_HANDLER(cortex_a8_handle_dbginit_command)
1630 {
1631 struct target *target = get_current_target(CMD_CTX);
1632
1633 cortex_a8_init_debug_access(target);
1634
1635 return ERROR_OK;
1636 }
1637
1638 static const struct command_registration cortex_a8_exec_command_handlers[] = {
1639 {
1640 .name = "cache_info",
1641 .handler = cortex_a8_handle_cache_info_command,
1642 .mode = COMMAND_EXEC,
1643 .help = "display information about target caches",
1644 },
1645 {
1646 .name = "dbginit",
1647 .handler = cortex_a8_handle_dbginit_command,
1648 .mode = COMMAND_EXEC,
1649 .help = "Initialize core debug",
1650 },
1651 COMMAND_REGISTRATION_DONE
1652 };
1653 static const struct command_registration cortex_a8_command_handlers[] = {
1654 {
1655 .chain = arm_command_handlers,
1656 },
1657 {
1658 .chain = armv7a_command_handlers,
1659 },
1660 {
1661 .name = "cortex_a8",
1662 .mode = COMMAND_ANY,
1663 .help = "Cortex-A8 command group",
1664 .chain = cortex_a8_exec_command_handlers,
1665 },
1666 COMMAND_REGISTRATION_DONE
1667 };
1668
1669 struct target_type cortexa8_target = {
1670 .name = "cortex_a8",
1671
1672 .poll = cortex_a8_poll,
1673 .arch_state = armv7a_arch_state,
1674
1675 .target_request_data = NULL,
1676
1677 .halt = cortex_a8_halt,
1678 .resume = cortex_a8_resume,
1679 .step = cortex_a8_step,
1680
1681 .assert_reset = cortex_a8_assert_reset,
1682 .deassert_reset = cortex_a8_deassert_reset,
1683 .soft_reset_halt = NULL,
1684
1685 /* REVISIT allow exporting VFP3 registers ... */
1686 .get_gdb_reg_list = arm_get_gdb_reg_list,
1687
1688 .read_memory = cortex_a8_read_memory,
1689 .write_memory = cortex_a8_write_memory,
1690 .bulk_write_memory = cortex_a8_bulk_write_memory,
1691
1692 .checksum_memory = arm_checksum_memory,
1693 .blank_check_memory = arm_blank_check_memory,
1694
1695 .run_algorithm = armv4_5_run_algorithm,
1696
1697 .add_breakpoint = cortex_a8_add_breakpoint,
1698 .remove_breakpoint = cortex_a8_remove_breakpoint,
1699 .add_watchpoint = NULL,
1700 .remove_watchpoint = NULL,
1701
1702 .commands = cortex_a8_command_handlers,
1703 .target_create = cortex_a8_target_create,
1704 .init_target = cortex_a8_init_target,
1705 .examine = cortex_a8_examine,
1706 };

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)