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