cortex a8: lots of error propagation fixes
[fw/openocd] / 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 };