use COMMAND_REGISTER macro
[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
937 // cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
938 /* examine cp15 control reg */
939 armv7a->read_cp15(target, 0, 0, 1, 0, &cortex_a8->cp15_control_reg);
940 jtag_execute_queue();
941 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32, cortex_a8->cp15_control_reg);
942
943 if (armv7a->armv4_5_mmu.armv4_5_cache.ctype == -1)
944 {
945 uint32_t cache_type_reg;
946 /* identify caches */
947 armv7a->read_cp15(target, 0, 1, 0, 0, &cache_type_reg);
948 jtag_execute_queue();
949 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
950 armv4_5_identify_cache(cache_type_reg,
951 &armv7a->armv4_5_mmu.armv4_5_cache);
952 }
953
954 armv7a->armv4_5_mmu.mmu_enabled =
955 (cortex_a8->cp15_control_reg & 0x1U) ? 1 : 0;
956 armv7a->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled =
957 (cortex_a8->cp15_control_reg & 0x4U) ? 1 : 0;
958 armv7a->armv4_5_mmu.armv4_5_cache.i_cache_enabled =
959 (cortex_a8->cp15_control_reg & 0x1000U) ? 1 : 0;
960
961
962 }
963
964 static int cortex_a8_step(struct target *target, int current, uint32_t address,
965 int handle_breakpoints)
966 {
967 struct armv7a_common *armv7a = target_to_armv7a(target);
968 struct arm *armv4_5 = &armv7a->armv4_5_common;
969 struct breakpoint *breakpoint = NULL;
970 struct breakpoint stepbreakpoint;
971 struct reg *r;
972
973 int timeout = 100;
974
975 if (target->state != TARGET_HALTED)
976 {
977 LOG_WARNING("target not halted");
978 return ERROR_TARGET_NOT_HALTED;
979 }
980
981 /* current = 1: continue on current pc, otherwise continue at <address> */
982 r = armv4_5->core_cache->reg_list + 15;
983 if (!current)
984 {
985 buf_set_u32(r->value, 0, 32, address);
986 }
987 else
988 {
989 address = buf_get_u32(r->value, 0, 32);
990 }
991
992 /* The front-end may request us not to handle breakpoints.
993 * But since Cortex-A8 uses breakpoint for single step,
994 * we MUST handle breakpoints.
995 */
996 handle_breakpoints = 1;
997 if (handle_breakpoints) {
998 breakpoint = breakpoint_find(target, address);
999 if (breakpoint)
1000 cortex_a8_unset_breakpoint(target, breakpoint);
1001 }
1002
1003 /* Setup single step breakpoint */
1004 stepbreakpoint.address = address;
1005 stepbreakpoint.length = (armv4_5->core_state == ARMV4_5_STATE_THUMB)
1006 ? 2 : 4;
1007 stepbreakpoint.type = BKPT_HARD;
1008 stepbreakpoint.set = 0;
1009
1010 /* Break on IVA mismatch */
1011 cortex_a8_set_breakpoint(target, &stepbreakpoint, 0x04);
1012
1013 target->debug_reason = DBG_REASON_SINGLESTEP;
1014
1015 cortex_a8_resume(target, 1, address, 0, 0);
1016
1017 while (target->state != TARGET_HALTED)
1018 {
1019 cortex_a8_poll(target);
1020 if (--timeout == 0)
1021 {
1022 LOG_WARNING("timeout waiting for target halt");
1023 break;
1024 }
1025 }
1026
1027 cortex_a8_unset_breakpoint(target, &stepbreakpoint);
1028 if (timeout > 0) target->debug_reason = DBG_REASON_BREAKPOINT;
1029
1030 if (breakpoint)
1031 cortex_a8_set_breakpoint(target, breakpoint, 0);
1032
1033 if (target->state != TARGET_HALTED)
1034 LOG_DEBUG("target stepped");
1035
1036 return ERROR_OK;
1037 }
1038
1039 static int cortex_a8_restore_context(struct target *target)
1040 {
1041 struct armv7a_common *armv7a = target_to_armv7a(target);
1042
1043 LOG_DEBUG(" ");
1044
1045 if (armv7a->pre_restore_context)
1046 armv7a->pre_restore_context(target);
1047
1048 arm_dpm_write_dirty_registers(&armv7a->dpm);
1049
1050 if (armv7a->post_restore_context)
1051 armv7a->post_restore_context(target);
1052
1053 return ERROR_OK;
1054 }
1055
1056
1057 /*
1058 * Cortex-A8 Breakpoint and watchpoint fuctions
1059 */
1060
1061 /* Setup hardware Breakpoint Register Pair */
1062 static int cortex_a8_set_breakpoint(struct target *target,
1063 struct breakpoint *breakpoint, uint8_t matchmode)
1064 {
1065 int retval;
1066 int brp_i=0;
1067 uint32_t control;
1068 uint8_t byte_addr_select = 0x0F;
1069 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
1070 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
1071 struct cortex_a8_brp * brp_list = cortex_a8->brp_list;
1072
1073 if (breakpoint->set)
1074 {
1075 LOG_WARNING("breakpoint already set");
1076 return ERROR_OK;
1077 }
1078
1079 if (breakpoint->type == BKPT_HARD)
1080 {
1081 while (brp_list[brp_i].used && (brp_i < cortex_a8->brp_num))
1082 brp_i++ ;
1083 if (brp_i >= cortex_a8->brp_num)
1084 {
1085 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1086 return ERROR_FAIL;
1087 }
1088 breakpoint->set = brp_i + 1;
1089 if (breakpoint->length == 2)
1090 {
1091 byte_addr_select = (3 << (breakpoint->address & 0x02));
1092 }
1093 control = ((matchmode & 0x7) << 20)
1094 | (byte_addr_select << 5)
1095 | (3 << 1) | 1;
1096 brp_list[brp_i].used = 1;
1097 brp_list[brp_i].value = (breakpoint->address & 0xFFFFFFFC);
1098 brp_list[brp_i].control = control;
1099 cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
1100 + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn,
1101 brp_list[brp_i].value);
1102 cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
1103 + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn,
1104 brp_list[brp_i].control);
1105 LOG_DEBUG("brp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_i,
1106 brp_list[brp_i].control,
1107 brp_list[brp_i].value);
1108 }
1109 else if (breakpoint->type == BKPT_SOFT)
1110 {
1111 uint8_t code[4];
1112 if (breakpoint->length == 2)
1113 {
1114 buf_set_u32(code, 0, 32, ARMV5_T_BKPT(0x11));
1115 }
1116 else
1117 {
1118 buf_set_u32(code, 0, 32, ARMV5_BKPT(0x11));
1119 }
1120 retval = target->type->read_memory(target,
1121 breakpoint->address & 0xFFFFFFFE,
1122 breakpoint->length, 1,
1123 breakpoint->orig_instr);
1124 if (retval != ERROR_OK)
1125 return retval;
1126 retval = target->type->write_memory(target,
1127 breakpoint->address & 0xFFFFFFFE,
1128 breakpoint->length, 1, code);
1129 if (retval != ERROR_OK)
1130 return retval;
1131 breakpoint->set = 0x11; /* Any nice value but 0 */
1132 }
1133
1134 return ERROR_OK;
1135 }
1136
1137 static int cortex_a8_unset_breakpoint(struct target *target, struct breakpoint *breakpoint)
1138 {
1139 int retval;
1140 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
1141 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
1142 struct cortex_a8_brp * brp_list = cortex_a8->brp_list;
1143
1144 if (!breakpoint->set)
1145 {
1146 LOG_WARNING("breakpoint not set");
1147 return ERROR_OK;
1148 }
1149
1150 if (breakpoint->type == BKPT_HARD)
1151 {
1152 int brp_i = breakpoint->set - 1;
1153 if ((brp_i < 0) || (brp_i >= cortex_a8->brp_num))
1154 {
1155 LOG_DEBUG("Invalid BRP number in breakpoint");
1156 return ERROR_OK;
1157 }
1158 LOG_DEBUG("rbp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_i,
1159 brp_list[brp_i].control, brp_list[brp_i].value);
1160 brp_list[brp_i].used = 0;
1161 brp_list[brp_i].value = 0;
1162 brp_list[brp_i].control = 0;
1163 cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
1164 + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn,
1165 brp_list[brp_i].control);
1166 cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
1167 + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn,
1168 brp_list[brp_i].value);
1169 }
1170 else
1171 {
1172 /* restore original instruction (kept in target endianness) */
1173 if (breakpoint->length == 4)
1174 {
1175 retval = target->type->write_memory(target,
1176 breakpoint->address & 0xFFFFFFFE,
1177 4, 1, breakpoint->orig_instr);
1178 if (retval != ERROR_OK)
1179 return retval;
1180 }
1181 else
1182 {
1183 retval = target->type->write_memory(target,
1184 breakpoint->address & 0xFFFFFFFE,
1185 2, 1, breakpoint->orig_instr);
1186 if (retval != ERROR_OK)
1187 return retval;
1188 }
1189 }
1190 breakpoint->set = 0;
1191
1192 return ERROR_OK;
1193 }
1194
1195 static int cortex_a8_add_breakpoint(struct target *target,
1196 struct breakpoint *breakpoint)
1197 {
1198 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
1199
1200 if ((breakpoint->type == BKPT_HARD) && (cortex_a8->brp_num_available < 1))
1201 {
1202 LOG_INFO("no hardware breakpoint available");
1203 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1204 }
1205
1206 if (breakpoint->type == BKPT_HARD)
1207 cortex_a8->brp_num_available--;
1208 cortex_a8_set_breakpoint(target, breakpoint, 0x00); /* Exact match */
1209
1210 return ERROR_OK;
1211 }
1212
1213 static int cortex_a8_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)
1214 {
1215 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
1216
1217 #if 0
1218 /* It is perfectly possible to remove brakpoints while the taget is running */
1219 if (target->state != TARGET_HALTED)
1220 {
1221 LOG_WARNING("target not halted");
1222 return ERROR_TARGET_NOT_HALTED;
1223 }
1224 #endif
1225
1226 if (breakpoint->set)
1227 {
1228 cortex_a8_unset_breakpoint(target, breakpoint);
1229 if (breakpoint->type == BKPT_HARD)
1230 cortex_a8->brp_num_available++ ;
1231 }
1232
1233
1234 return ERROR_OK;
1235 }
1236
1237
1238
1239 /*
1240 * Cortex-A8 Reset fuctions
1241 */
1242
1243 static int cortex_a8_assert_reset(struct target *target)
1244 {
1245 struct armv7a_common *armv7a = target_to_armv7a(target);
1246
1247 LOG_DEBUG(" ");
1248
1249 /* registers are now invalid */
1250 register_cache_invalidate(armv7a->armv4_5_common.core_cache);
1251
1252 target->state = TARGET_RESET;
1253
1254 return ERROR_OK;
1255 }
1256
1257 static int cortex_a8_deassert_reset(struct target *target)
1258 {
1259
1260 LOG_DEBUG(" ");
1261
1262 if (target->reset_halt)
1263 {
1264 int retval;
1265 if ((retval = target_halt(target)) != ERROR_OK)
1266 return retval;
1267 }
1268
1269 return ERROR_OK;
1270 }
1271
1272 /*
1273 * Cortex-A8 Memory access
1274 *
1275 * This is same Cortex M3 but we must also use the correct
1276 * ap number for every access.
1277 */
1278
1279 static int cortex_a8_read_memory(struct target *target, uint32_t address,
1280 uint32_t size, uint32_t count, uint8_t *buffer)
1281 {
1282 struct armv7a_common *armv7a = target_to_armv7a(target);
1283 struct swjdp_common *swjdp = &armv7a->swjdp_info;
1284 int retval = ERROR_INVALID_ARGUMENTS;
1285
1286 /* cortex_a8 handles unaligned memory access */
1287
1288 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1289
1290 if (count && buffer) {
1291 switch (size) {
1292 case 4:
1293 retval = mem_ap_read_buf_u32(swjdp, buffer, 4 * count, address);
1294 break;
1295 case 2:
1296 retval = mem_ap_read_buf_u16(swjdp, buffer, 2 * count, address);
1297 break;
1298 case 1:
1299 retval = mem_ap_read_buf_u8(swjdp, buffer, count, address);
1300 break;
1301 }
1302 }
1303
1304 return retval;
1305 }
1306
1307 static int cortex_a8_write_memory(struct target *target, uint32_t address,
1308 uint32_t size, uint32_t count, uint8_t *buffer)
1309 {
1310 struct armv7a_common *armv7a = target_to_armv7a(target);
1311 struct swjdp_common *swjdp = &armv7a->swjdp_info;
1312 int retval = ERROR_INVALID_ARGUMENTS;
1313
1314 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1315
1316 if (count && buffer) {
1317 switch (size) {
1318 case 4:
1319 retval = mem_ap_write_buf_u32(swjdp, buffer, 4 * count, address);
1320 break;
1321 case 2:
1322 retval = mem_ap_write_buf_u16(swjdp, buffer, 2 * count, address);
1323 break;
1324 case 1:
1325 retval = mem_ap_write_buf_u8(swjdp, buffer, count, address);
1326 break;
1327 }
1328 }
1329
1330 if (retval == ERROR_OK && target->state == TARGET_HALTED)
1331 {
1332 /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */
1333 /* invalidate I-Cache */
1334 if (armv7a->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
1335 {
1336 /* Invalidate ICache single entry with MVA, repeat this for all cache
1337 lines in the address range, Cortex-A8 has fixed 64 byte line length */
1338 /* Invalidate Cache single entry with MVA to PoU */
1339 for (uint32_t cacheline=address; cacheline<address+size*count; cacheline+=64)
1340 armv7a->write_cp15(target, 0, 1, 7, 5, cacheline); /* I-Cache to PoU */
1341 }
1342 /* invalidate D-Cache */
1343 if (armv7a->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled)
1344 {
1345 /* Invalidate Cache single entry with MVA to PoC */
1346 for (uint32_t cacheline=address; cacheline<address+size*count; cacheline+=64)
1347 armv7a->write_cp15(target, 0, 1, 7, 6, cacheline); /* U/D cache to PoC */
1348 }
1349 }
1350
1351 return retval;
1352 }
1353
1354 static int cortex_a8_bulk_write_memory(struct target *target, uint32_t address,
1355 uint32_t count, uint8_t *buffer)
1356 {
1357 return cortex_a8_write_memory(target, address, 4, count, buffer);
1358 }
1359
1360
1361 static int cortex_a8_dcc_read(struct swjdp_common *swjdp, uint8_t *value, uint8_t *ctrl)
1362 {
1363 #if 0
1364 u16 dcrdr;
1365
1366 mem_ap_read_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
1367 *ctrl = (uint8_t)dcrdr;
1368 *value = (uint8_t)(dcrdr >> 8);
1369
1370 LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
1371
1372 /* write ack back to software dcc register
1373 * signify we have read data */
1374 if (dcrdr & (1 << 0))
1375 {
1376 dcrdr = 0;
1377 mem_ap_write_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
1378 }
1379 #endif
1380 return ERROR_OK;
1381 }
1382
1383
1384 static int cortex_a8_handle_target_request(void *priv)
1385 {
1386 struct target *target = priv;
1387 struct armv7a_common *armv7a = target_to_armv7a(target);
1388 struct swjdp_common *swjdp = &armv7a->swjdp_info;
1389
1390 if (!target_was_examined(target))
1391 return ERROR_OK;
1392 if (!target->dbg_msg_enabled)
1393 return ERROR_OK;
1394
1395 if (target->state == TARGET_RUNNING)
1396 {
1397 uint8_t data = 0;
1398 uint8_t ctrl = 0;
1399
1400 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1401
1402 /* check if we have data */
1403 if (ctrl & (1 << 0))
1404 {
1405 uint32_t request;
1406
1407 /* we assume target is quick enough */
1408 request = data;
1409 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1410 request |= (data << 8);
1411 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1412 request |= (data << 16);
1413 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1414 request |= (data << 24);
1415 target_request(target, request);
1416 }
1417 }
1418
1419 return ERROR_OK;
1420 }
1421
1422 /*
1423 * Cortex-A8 target information and configuration
1424 */
1425
1426 static int cortex_a8_examine_first(struct target *target)
1427 {
1428 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
1429 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
1430 struct swjdp_common *swjdp = &armv7a->swjdp_info;
1431 int i;
1432 int retval = ERROR_OK;
1433 uint32_t didr, ctypr, ttypr, cpuid;
1434
1435 LOG_DEBUG("TODO");
1436
1437 /* Here we shall insert a proper ROM Table scan */
1438 armv7a->debug_base = OMAP3530_DEBUG_BASE;
1439
1440 /* We do one extra read to ensure DAP is configured,
1441 * we call ahbap_debugport_init(swjdp) instead
1442 */
1443 ahbap_debugport_init(swjdp);
1444 mem_ap_read_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_CPUID, &cpuid);
1445 if ((retval = mem_ap_read_atomic_u32(swjdp,
1446 armv7a->debug_base + CPUDBG_CPUID, &cpuid)) != ERROR_OK)
1447 {
1448 LOG_DEBUG("Examine failed");
1449 return retval;
1450 }
1451
1452 if ((retval = mem_ap_read_atomic_u32(swjdp,
1453 armv7a->debug_base + CPUDBG_CTYPR, &ctypr)) != ERROR_OK)
1454 {
1455 LOG_DEBUG("Examine failed");
1456 return retval;
1457 }
1458
1459 if ((retval = mem_ap_read_atomic_u32(swjdp,
1460 armv7a->debug_base + CPUDBG_TTYPR, &ttypr)) != ERROR_OK)
1461 {
1462 LOG_DEBUG("Examine failed");
1463 return retval;
1464 }
1465
1466 if ((retval = mem_ap_read_atomic_u32(swjdp,
1467 armv7a->debug_base + CPUDBG_DIDR, &didr)) != ERROR_OK)
1468 {
1469 LOG_DEBUG("Examine failed");
1470 return retval;
1471 }
1472
1473 LOG_DEBUG("cpuid = 0x%08" PRIx32, cpuid);
1474 LOG_DEBUG("ctypr = 0x%08" PRIx32, ctypr);
1475 LOG_DEBUG("ttypr = 0x%08" PRIx32, ttypr);
1476 LOG_DEBUG("didr = 0x%08" PRIx32, didr);
1477
1478 cortex_a8_dpm_setup(cortex_a8, didr);
1479
1480 /* Setup Breakpoint Register Pairs */
1481 cortex_a8->brp_num = ((didr >> 24) & 0x0F) + 1;
1482 cortex_a8->brp_num_context = ((didr >> 20) & 0x0F) + 1;
1483 cortex_a8->brp_num_available = cortex_a8->brp_num;
1484 cortex_a8->brp_list = calloc(cortex_a8->brp_num, sizeof(struct cortex_a8_brp));
1485 // cortex_a8->brb_enabled = ????;
1486 for (i = 0; i < cortex_a8->brp_num; i++)
1487 {
1488 cortex_a8->brp_list[i].used = 0;
1489 if (i < (cortex_a8->brp_num-cortex_a8->brp_num_context))
1490 cortex_a8->brp_list[i].type = BRP_NORMAL;
1491 else
1492 cortex_a8->brp_list[i].type = BRP_CONTEXT;
1493 cortex_a8->brp_list[i].value = 0;
1494 cortex_a8->brp_list[i].control = 0;
1495 cortex_a8->brp_list[i].BRPn = i;
1496 }
1497
1498 /* Setup Watchpoint Register Pairs */
1499 cortex_a8->wrp_num = ((didr >> 28) & 0x0F) + 1;
1500 cortex_a8->wrp_num_available = cortex_a8->wrp_num;
1501 cortex_a8->wrp_list = calloc(cortex_a8->wrp_num, sizeof(struct cortex_a8_wrp));
1502 for (i = 0; i < cortex_a8->wrp_num; i++)
1503 {
1504 cortex_a8->wrp_list[i].used = 0;
1505 cortex_a8->wrp_list[i].type = 0;
1506 cortex_a8->wrp_list[i].value = 0;
1507 cortex_a8->wrp_list[i].control = 0;
1508 cortex_a8->wrp_list[i].WRPn = i;
1509 }
1510 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1511 cortex_a8->brp_num , cortex_a8->wrp_num);
1512
1513 target_set_examined(target);
1514 return ERROR_OK;
1515 }
1516
1517 static int cortex_a8_examine(struct target *target)
1518 {
1519 int retval = ERROR_OK;
1520
1521 /* don't re-probe hardware after each reset */
1522 if (!target_was_examined(target))
1523 retval = cortex_a8_examine_first(target);
1524
1525 /* Configure core debug access */
1526 if (retval == ERROR_OK)
1527 retval = cortex_a8_init_debug_access(target);
1528
1529 return retval;
1530 }
1531
1532 /*
1533 * Cortex-A8 target creation and initialization
1534 */
1535
1536 static int cortex_a8_init_target(struct command_context *cmd_ctx,
1537 struct target *target)
1538 {
1539 /* examine_first() does a bunch of this */
1540 return ERROR_OK;
1541 }
1542
1543 static int cortex_a8_init_arch_info(struct target *target,
1544 struct cortex_a8_common *cortex_a8, struct jtag_tap *tap)
1545 {
1546 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
1547 struct arm *armv4_5 = &armv7a->armv4_5_common;
1548 struct swjdp_common *swjdp = &armv7a->swjdp_info;
1549
1550 /* Setup struct cortex_a8_common */
1551 cortex_a8->common_magic = CORTEX_A8_COMMON_MAGIC;
1552 armv4_5->arch_info = armv7a;
1553
1554 /* prepare JTAG information for the new target */
1555 cortex_a8->jtag_info.tap = tap;
1556 cortex_a8->jtag_info.scann_size = 4;
1557
1558 swjdp->dp_select_value = -1;
1559 swjdp->ap_csw_value = -1;
1560 swjdp->ap_tar_value = -1;
1561 swjdp->jtag_info = &cortex_a8->jtag_info;
1562 swjdp->memaccess_tck = 80;
1563
1564 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1565 swjdp->tar_autoincr_block = (1 << 10);
1566
1567 cortex_a8->fast_reg_read = 0;
1568
1569
1570 /* register arch-specific functions */
1571 armv7a->examine_debug_reason = NULL;
1572
1573 armv7a->post_debug_entry = cortex_a8_post_debug_entry;
1574
1575 armv7a->pre_restore_context = NULL;
1576 armv7a->post_restore_context = NULL;
1577 armv7a->armv4_5_mmu.armv4_5_cache.ctype = -1;
1578 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1579 armv7a->armv4_5_mmu.read_memory = cortex_a8_read_memory;
1580 armv7a->armv4_5_mmu.write_memory = cortex_a8_write_memory;
1581 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1582 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1583 armv7a->armv4_5_mmu.has_tiny_pages = 1;
1584 armv7a->armv4_5_mmu.mmu_enabled = 0;
1585 armv7a->read_cp15 = cortex_a8_read_cp15;
1586 armv7a->write_cp15 = cortex_a8_write_cp15;
1587
1588
1589 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1590
1591 /* REVISIT v7a setup should be in a v7a-specific routine */
1592 armv4_5_init_arch_info(target, armv4_5);
1593 armv7a->common_magic = ARMV7_COMMON_MAGIC;
1594
1595 target_register_timer_callback(cortex_a8_handle_target_request, 1, 1, target);
1596
1597 return ERROR_OK;
1598 }
1599
1600 static int cortex_a8_target_create(struct target *target, Jim_Interp *interp)
1601 {
1602 struct cortex_a8_common *cortex_a8 = calloc(1, sizeof(struct cortex_a8_common));
1603
1604 cortex_a8_init_arch_info(target, cortex_a8, target->tap);
1605
1606 return ERROR_OK;
1607 }
1608
1609 COMMAND_HANDLER(cortex_a8_handle_cache_info_command)
1610 {
1611 struct target *target = get_current_target(CMD_CTX);
1612 struct armv7a_common *armv7a = target_to_armv7a(target);
1613
1614 return armv4_5_handle_cache_info_command(CMD_CTX,
1615 &armv7a->armv4_5_mmu.armv4_5_cache);
1616 }
1617
1618
1619 COMMAND_HANDLER(cortex_a8_handle_dbginit_command)
1620 {
1621 struct target *target = get_current_target(CMD_CTX);
1622
1623 cortex_a8_init_debug_access(target);
1624
1625 return ERROR_OK;
1626 }
1627
1628
1629 static int cortex_a8_register_commands(struct command_context *cmd_ctx)
1630 {
1631 struct command *cortex_a8_cmd;
1632 int retval = ERROR_OK;
1633
1634 armv4_5_register_commands(cmd_ctx);
1635 armv7a_register_commands(cmd_ctx);
1636
1637 cortex_a8_cmd = COMMAND_REGISTER(cmd_ctx, NULL, "cortex_a8",
1638 NULL, COMMAND_ANY,
1639 "cortex_a8 specific commands");
1640
1641 COMMAND_REGISTER(cmd_ctx, cortex_a8_cmd, "cache_info",
1642 cortex_a8_handle_cache_info_command, COMMAND_EXEC,
1643 "display information about target caches");
1644
1645 COMMAND_REGISTER(cmd_ctx, cortex_a8_cmd, "dbginit",
1646 cortex_a8_handle_dbginit_command, COMMAND_EXEC,
1647 "Initialize core debug");
1648
1649 return retval;
1650 }
1651
1652 struct target_type cortexa8_target = {
1653 .name = "cortex_a8",
1654
1655 .poll = cortex_a8_poll,
1656 .arch_state = armv7a_arch_state,
1657
1658 .target_request_data = NULL,
1659
1660 .halt = cortex_a8_halt,
1661 .resume = cortex_a8_resume,
1662 .step = cortex_a8_step,
1663
1664 .assert_reset = cortex_a8_assert_reset,
1665 .deassert_reset = cortex_a8_deassert_reset,
1666 .soft_reset_halt = NULL,
1667
1668 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
1669
1670 .read_memory = cortex_a8_read_memory,
1671 .write_memory = cortex_a8_write_memory,
1672 .bulk_write_memory = cortex_a8_bulk_write_memory,
1673
1674 .checksum_memory = arm_checksum_memory,
1675 .blank_check_memory = arm_blank_check_memory,
1676
1677 .run_algorithm = armv4_5_run_algorithm,
1678
1679 .add_breakpoint = cortex_a8_add_breakpoint,
1680 .remove_breakpoint = cortex_a8_remove_breakpoint,
1681 .add_watchpoint = NULL,
1682 .remove_watchpoint = NULL,
1683
1684 .register_commands = cortex_a8_register_commands,
1685 .target_create = cortex_a8_target_create,
1686 .init_target = cortex_a8_init_target,
1687 .examine = cortex_a8_examine,
1688 .mrc = cortex_a8_mrc,
1689 .mcr = cortex_a8_mcr,
1690 };

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)