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

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)