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

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)