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

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)