]> git.sur5r.net Git - openocd/blob - src/target/cortex_a8.c
David Brownell The rest of the Cortex-A8 support from Magnus: replace the previous
[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 "cortex_a8.h"
37 #include "armv7a.h"
38 #include "armv4_5.h"
39
40 #include "target_request.h"
41 #include "target_type.h"
42
43 /* cli handling */
44 int cortex_a8_register_commands(struct command_context_s *cmd_ctx);
45
46 /* forward declarations */
47 int cortex_a8_target_create(struct target_s *target, Jim_Interp *interp);
48 int cortex_a8_init_target(struct command_context_s *cmd_ctx,
49                 struct target_s *target);
50 int cortex_a8_examine(struct target_s *target);
51 int cortex_a8_poll(target_t *target);
52 int cortex_a8_halt(target_t *target);
53 int cortex_a8_resume(struct target_s *target, int current, uint32_t address,
54                 int handle_breakpoints, int debug_execution);
55 int cortex_a8_step(struct target_s *target, int current, uint32_t address,
56                 int handle_breakpoints);
57 int cortex_a8_debug_entry(target_t *target);
58 int cortex_a8_restore_context(target_t *target);
59 int cortex_a8_bulk_write_memory(target_t *target, uint32_t address,
60                 uint32_t count, uint8_t *buffer);
61 int cortex_a8_set_breakpoint(struct target_s *target,
62                 breakpoint_t *breakpoint, uint8_t matchmode);
63 int cortex_a8_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
64 int cortex_a8_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
65 int cortex_a8_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
66 int cortex_a8_dap_read_coreregister_u32(target_t *target,
67                 uint32_t *value, int regnum);
68 int cortex_a8_dap_write_coreregister_u32(target_t *target,
69                 uint32_t value, int regnum);
70
71 target_type_t cortexa8_target =
72 {
73         .name = "cortex_a8",
74
75         .poll = cortex_a8_poll,
76         .arch_state = armv7a_arch_state,
77
78         .target_request_data = NULL,
79
80         .halt = cortex_a8_halt,
81         .resume = cortex_a8_resume,
82         .step = cortex_a8_step,
83
84         .assert_reset = NULL,
85         .deassert_reset = NULL,
86         .soft_reset_halt = NULL,
87
88 //      .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
89         .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
90
91         .read_memory = cortex_a8_read_memory,
92         .write_memory = cortex_a8_write_memory,
93         .bulk_write_memory = cortex_a8_bulk_write_memory,
94         .checksum_memory = arm7_9_checksum_memory,
95         .blank_check_memory = arm7_9_blank_check_memory,
96
97         .run_algorithm = armv4_5_run_algorithm,
98
99         .add_breakpoint = cortex_a8_add_breakpoint,
100         .remove_breakpoint = cortex_a8_remove_breakpoint,
101         .add_watchpoint = NULL,
102         .remove_watchpoint = NULL,
103
104         .register_commands = cortex_a8_register_commands,
105         .target_create = cortex_a8_target_create,
106         .init_target = cortex_a8_init_target,
107         .examine = cortex_a8_examine,
108         .quit = NULL
109 };
110
111 /*
112  * FIXME do topology discovery using the ROM; don't
113  * assume this is an OMAP3.
114  */
115 #define swjdp_memoryap 0
116 #define swjdp_debugap 1
117 #define OMAP3530_DEBUG_BASE 0x54011000
118
119 /*
120  * Cortex-A8 Basic debug access, very low level assumes state is saved
121  */
122 int cortex_a8_init_debug_access(target_t *target)
123 {
124 #if 0
125 # Unlocking the debug registers for modification
126 mww 0x54011FB0 0xC5ACCE55 4
127
128 # Clear Sticky Power Down status Bit to enable access to
129 # the registers in the Core Power Domain
130 mdw 0x54011314
131 # Check that it is cleared
132 mdw 0x54011314
133 # Now we can read Core Debug Registers at offset 0x080
134 mdw 0x54011080 4
135 # We can also read RAM.
136 mdw 0x80000000 32
137
138 mdw 0x5401d030
139 mdw 0x54011FB8
140
141 # Set DBGEN line for hardware debug (OMAP35xx)
142 mww 0x5401d030 0x00002000
143
144 #Check AUTHSTATUS
145 mdw 0x54011FB8
146
147 # Instr enable
148 mww 0x54011088 0x2000
149 mdw 0x54011080 4
150 #endif
151         return ERROR_OK;
152 }
153
154 int cortex_a8_exec_opcode(target_t *target, uint32_t opcode)
155 {
156         uint32_t dscr;
157         int retvalue;
158         /* get pointers to arch-specific information */
159         armv4_5_common_t *armv4_5 = target->arch_info;
160         armv7a_common_t *armv7a = armv4_5->arch_info;
161         swjdp_common_t *swjdp = &armv7a->swjdp_info;
162
163         LOG_DEBUG("exec opcode 0x%08x", opcode);
164         mem_ap_write_u32(swjdp, OMAP3530_DEBUG_BASE + CPUDBG_ITR, opcode);
165         do
166         {
167                 retvalue = mem_ap_read_atomic_u32(swjdp,
168                                 OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
169         }
170         while ((dscr & (1 << 24)) == 0); /* Wait for InstrCompl bit to be set */
171
172         return retvalue;
173 }
174
175 /**************************************************************************
176 Read core register with very few exec_opcode, fast but needs work_area.
177 This can cause problems with MMU active.
178 **************************************************************************/
179 int cortex_a8_read_regs_through_mem(target_t *target, uint32_t address,
180                 uint32_t * regfile)
181 {
182         int retval = ERROR_OK;
183         /* get pointers to arch-specific information */
184         armv4_5_common_t *armv4_5 = target->arch_info;
185         armv7a_common_t *armv7a = armv4_5->arch_info;
186         swjdp_common_t *swjdp = &armv7a->swjdp_info;
187
188         cortex_a8_dap_read_coreregister_u32(target, regfile, 0);
189         cortex_a8_dap_write_coreregister_u32(target, address, 0);
190         cortex_a8_exec_opcode(target, ARMV4_5_STMIA(0, 0xFFFE, 0, 0));
191         dap_ap_select(swjdp, swjdp_memoryap);
192         mem_ap_read_buf_u32(swjdp, (uint8_t *)(&regfile[1]), 4*15, address);
193         dap_ap_select(swjdp, swjdp_debugap);
194
195         return retval;
196 }
197
198 int cortex_a8_read_cp(target_t *target, uint32_t *value, uint8_t CP,
199                 uint8_t op1, uint8_t CRn, uint8_t CRm, uint8_t op2)
200 {
201         int retval;
202         /* get pointers to arch-specific information */
203         armv4_5_common_t *armv4_5 = target->arch_info;
204         armv7a_common_t *armv7a = armv4_5->arch_info;
205         swjdp_common_t *swjdp = &armv7a->swjdp_info;
206
207         cortex_a8_exec_opcode(target, ARMV4_5_MRC(CP, op1, 0, CRn, CRm, op2));
208         /* Move R0 to DTRTX */
209         cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
210
211         /* Read DCCTX */
212         retval = mem_ap_read_atomic_u32(swjdp,
213                         OMAP3530_DEBUG_BASE + CPUDBG_DTRTX, value);
214
215         return retval;
216 }
217
218 int cortex_a8_write_cp(target_t *target, uint32_t value,
219         uint8_t CP, uint8_t op1, uint8_t CRn, uint8_t CRm, uint8_t op2)
220 /* TODO Fix this */
221 {
222         int retval;
223         /* get pointers to arch-specific information */
224         armv4_5_common_t *armv4_5 = target->arch_info;
225         armv7a_common_t *armv7a = armv4_5->arch_info;
226         swjdp_common_t *swjdp = &armv7a->swjdp_info;
227
228         retval = mem_ap_write_u32(swjdp,
229                         OMAP3530_DEBUG_BASE + CPUDBG_DTRRX, value);
230         /* Move DTRRX to r0 */
231         cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
232
233         cortex_a8_exec_opcode(target, ARMV4_5_MCR(CP, 0, 0, 0, 5, 0));
234         return retval;
235 }
236
237 int cortex_a8_read_cp15(target_t *target, uint32_t op1, uint32_t op2,
238                 uint32_t CRn, uint32_t CRm, uint32_t *value)
239 {
240         return cortex_a8_read_cp(target, value, 15, op1, CRn, CRm, op2);
241 }
242
243 int cortex_a8_write_cp15(target_t *target, uint32_t op1, uint32_t op2,
244                 uint32_t CRn, uint32_t CRm, uint32_t value)
245 {
246         return cortex_a8_write_cp(target, value, 15, op1, CRn, CRm, op2);
247 }
248
249 int cortex_a8_dap_read_coreregister_u32(target_t *target,
250                 uint32_t *value, int regnum)
251 {
252         int retval = ERROR_OK;
253         uint8_t reg = regnum&0xFF;
254
255         /* get pointers to arch-specific information */
256         armv4_5_common_t *armv4_5 = target->arch_info;
257         armv7a_common_t *armv7a = armv4_5->arch_info;
258         swjdp_common_t *swjdp = &armv7a->swjdp_info;
259
260         swjdp->trans_mode = TRANS_MODE_COMPOSITE;
261
262         if (reg > 16)
263                 return retval;
264
265         if (reg < 15)
266         {
267                 /* Rn to DCCTX, MCR p14, 0, Rd, c0, c5, 0,  0xEE000E15 */
268                 cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, reg, 0, 5, 0));
269         }
270         else if (reg == 15)
271         {
272                 cortex_a8_exec_opcode(target, 0xE1A0000F);
273                 cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
274         }
275         else if (reg == 16)
276         {
277                 cortex_a8_exec_opcode(target, ARMV4_5_MRS(0, 0));
278                 cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
279         }
280
281         /* Read DCCTX */
282         retval = mem_ap_read_atomic_u32(swjdp,
283                         OMAP3530_DEBUG_BASE + CPUDBG_DTRTX, value);
284 //      retval = mem_ap_read_u32(swjdp, OMAP3530_DEBUG_BASE + CPUDBG_DTRTX, value);
285
286         return retval;
287 }
288
289 int cortex_a8_dap_write_coreregister_u32(target_t *target, uint32_t value, int regnum)
290 {
291         int retval = ERROR_OK;
292         uint8_t Rd = regnum&0xFF;
293
294         /* get pointers to arch-specific information */
295         armv4_5_common_t *armv4_5 = target->arch_info;
296         armv7a_common_t *armv7a = armv4_5->arch_info;
297         swjdp_common_t *swjdp = &armv7a->swjdp_info;
298
299         if (Rd > 16)
300                 return retval;
301
302         /* Write to DCCRX */
303         retval = mem_ap_write_u32(swjdp,
304                         OMAP3530_DEBUG_BASE + CPUDBG_DTRRX, value);
305
306         if (Rd < 15)
307         {
308                 /* DCCRX to Rd, MCR p14, 0, Rd, c0, c5, 0,  0xEE000E15 */
309                 cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, Rd, 0, 5, 0));
310         }
311         else if (Rd == 15)
312         {
313                 cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
314                 cortex_a8_exec_opcode(target, 0xE1A0F000);
315         }
316         else if (Rd == 16)
317         {
318                 cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0));
319                 cortex_a8_exec_opcode(target, ARMV4_5_MSR_GP(0, 0xF, 0));
320                 /* Execute a PrefetchFlush instruction through the ITR. */
321                 cortex_a8_exec_opcode(target, ARMV4_5_MCR(15, 0, 0, 7, 5, 4));
322         }
323
324         return retval;
325 }
326
327 /*
328  * Cortex-A8 Run control
329  */
330
331 int cortex_a8_poll(target_t *target)
332 {
333         int retval = ERROR_OK;
334         uint32_t dscr;
335         /* get pointers to arch-specific information */
336         armv4_5_common_t *armv4_5 = target->arch_info;
337         armv7a_common_t *armv7a = armv4_5->arch_info;
338         cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
339         swjdp_common_t *swjdp = &armv7a->swjdp_info;
340
341
342         enum target_state prev_target_state = target->state;
343
344         uint8_t saved_apsel = dap_ap_get_select(swjdp);
345         dap_ap_select(swjdp, swjdp_debugap);
346         retval = mem_ap_read_atomic_u32(swjdp,
347                         OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
348         if (retval != ERROR_OK)
349         {
350                 dap_ap_select(swjdp, saved_apsel);
351                 return retval;
352         }
353         cortex_a8->cpudbg_dscr = dscr;
354
355         if ((dscr & 0x3) == 0x3)
356         {
357                 if (prev_target_state != TARGET_HALTED)
358                 {
359                         /* We have a halting debug event */
360                         LOG_DEBUG("Target halted");
361                         target->state = TARGET_HALTED;
362                         if ((prev_target_state == TARGET_RUNNING)
363                                         || (prev_target_state == TARGET_RESET))
364                         {
365                                 retval = cortex_a8_debug_entry(target);
366                                 if (retval != ERROR_OK)
367                                         return retval;
368
369                                 target_call_event_callbacks(target,
370                                                 TARGET_EVENT_HALTED);
371                         }
372                         if (prev_target_state == TARGET_DEBUG_RUNNING)
373                         {
374                                 LOG_DEBUG(" ");
375
376                                 retval = cortex_a8_debug_entry(target);
377                                 if (retval != ERROR_OK)
378                                         return retval;
379
380                                 target_call_event_callbacks(target,
381                                                 TARGET_EVENT_DEBUG_HALTED);
382                         }
383                 }
384         }
385         else if ((dscr & 0x3) == 0x2)
386         {
387                 target->state = TARGET_RUNNING;
388         }
389         else
390         {
391                 LOG_DEBUG("Unknown target state dscr = 0x%08x", dscr);
392                 target->state = TARGET_UNKNOWN;
393         }
394
395         dap_ap_select(swjdp, saved_apsel);
396
397         return retval;
398 }
399
400 int cortex_a8_halt(target_t *target)
401 {
402         int retval = ERROR_OK;
403         /* get pointers to arch-specific information */
404         armv4_5_common_t *armv4_5 = target->arch_info;
405         armv7a_common_t *armv7a = armv4_5->arch_info;
406         swjdp_common_t *swjdp = &armv7a->swjdp_info;
407
408         uint8_t saved_apsel = dap_ap_get_select(swjdp);
409         dap_ap_select(swjdp, swjdp_debugap);
410
411         /* Perhaps we should do a read-modify-write here */
412         retval = mem_ap_write_atomic_u32(swjdp,
413                         OMAP3530_DEBUG_BASE + CPUDBG_DRCR, 0x1);
414
415         target->debug_reason = DBG_REASON_DBGRQ;
416         dap_ap_select(swjdp, saved_apsel);
417
418         return retval;
419 }
420
421 int cortex_a8_resume(struct target_s *target, int current,
422                 uint32_t address, int handle_breakpoints, int debug_execution)
423 {
424         /* get pointers to arch-specific information */
425         armv4_5_common_t *armv4_5 = target->arch_info;
426         armv7a_common_t *armv7a = armv4_5->arch_info;
427         cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
428         swjdp_common_t *swjdp = &armv7a->swjdp_info;
429
430 //      breakpoint_t *breakpoint = NULL;
431         uint32_t resume_pc;
432
433         uint8_t saved_apsel = dap_ap_get_select(swjdp);
434         dap_ap_select(swjdp, swjdp_debugap);
435
436         if (!debug_execution)
437         {
438                 target_free_all_working_areas(target);
439 //              cortex_m3_enable_breakpoints(target);
440 //              cortex_m3_enable_watchpoints(target);
441         }
442
443 #if 0
444         if (debug_execution)
445         {
446                 /* Disable interrupts */
447                 /* We disable interrupts in the PRIMASK register instead of
448                  * masking with C_MASKINTS,
449                  * This is probably the same issue as Cortex-M3 Errata 377493:
450                  * C_MASKINTS in parallel with disabled interrupts can cause
451                  * local faults to not be taken. */
452                 buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_PRIMASK].value, 0, 32, 1);
453                 armv7m->core_cache->reg_list[ARMV7M_PRIMASK].dirty = 1;
454                 armv7m->core_cache->reg_list[ARMV7M_PRIMASK].valid = 1;
455
456                 /* Make sure we are in Thumb mode */
457                 buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32,
458                         buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32) | (1 << 24));
459                 armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty = 1;
460                 armv7m->core_cache->reg_list[ARMV7M_xPSR].valid = 1;
461         }
462 #endif
463
464         /* current = 1: continue on current pc, otherwise continue at <address> */
465         resume_pc = buf_get_u32(
466                         ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
467                                 armv4_5->core_mode, 15).value,
468                         0, 32);
469         if (!current)
470                 resume_pc = address;
471
472         /* Make sure that the Armv7 gdb thumb fixups does not
473          * kill the return address
474          */
475         if (!(cortex_a8->cpudbg_dscr & (1 << 5)))
476         {
477                 resume_pc &= 0xFFFFFFFC;
478         }
479         LOG_DEBUG("resume pc = 0x%08x", resume_pc);
480         buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
481                                 armv4_5->core_mode, 15).value,
482                         0, 32, resume_pc);
483         ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
484                         armv4_5->core_mode, 15).dirty = 1;
485         ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
486                         armv4_5->core_mode, 15).valid = 1;
487
488         cortex_a8_restore_context(target);
489 //      arm7_9_restore_context(target); TODO Context is currently NOT Properly restored
490 #if 0
491         /* the front-end may request us not to handle breakpoints */
492         if (handle_breakpoints)
493         {
494                 /* Single step past breakpoint at current address */
495                 if ((breakpoint = breakpoint_find(target, resume_pc)))
496                 {
497                         LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint->address);
498                         cortex_m3_unset_breakpoint(target, breakpoint);
499                         cortex_m3_single_step_core(target);
500                         cortex_m3_set_breakpoint(target, breakpoint);
501                 }
502         }
503
504 #endif
505         /* Restart core */
506         /* Perhaps we should do a read-modify-write here */
507         mem_ap_write_atomic_u32(swjdp, OMAP3530_DEBUG_BASE + CPUDBG_DRCR, 0x2);
508
509         target->debug_reason = DBG_REASON_NOTHALTED;
510         target->state = TARGET_RUNNING;
511
512         /* registers are now invalid */
513         armv4_5_invalidate_core_regs(target);
514
515         if (!debug_execution)
516         {
517                 target->state = TARGET_RUNNING;
518                 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
519                 LOG_DEBUG("target resumed at 0x%x", resume_pc);
520         }
521         else
522         {
523                 target->state = TARGET_DEBUG_RUNNING;
524                 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
525                 LOG_DEBUG("target debug resumed at 0x%x", resume_pc);
526         }
527
528         dap_ap_select(swjdp, saved_apsel);
529
530         return ERROR_OK;
531 }
532
533 int cortex_a8_debug_entry(target_t *target)
534 {
535         int i;
536         uint32_t regfile[16], pc, cpsr;
537         int retval = ERROR_OK;
538         working_area_t *regfile_working_area = NULL;
539
540         /* get pointers to arch-specific information */
541         armv4_5_common_t *armv4_5 = target->arch_info;
542         armv7a_common_t *armv7a = armv4_5->arch_info;
543         cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
544         swjdp_common_t *swjdp = &armv7a->swjdp_info;
545
546         if (armv7a->pre_debug_entry)
547                 armv7a->pre_debug_entry(target);
548
549         LOG_DEBUG("dscr = 0x%08x", cortex_a8->cpudbg_dscr);
550
551         /* Examine debug reason */
552         switch ((cortex_a8->cpudbg_dscr >> 2)&0xF)
553         {
554                 case 0:
555                 case 4:
556                         target->debug_reason = DBG_REASON_DBGRQ;
557                         break;
558                 case 1:
559                 case 3:
560                         target->debug_reason = DBG_REASON_BREAKPOINT;
561                         break;
562                 case 10:
563                         target->debug_reason = DBG_REASON_WATCHPOINT;
564                         break;
565                 default:
566                         target->debug_reason = DBG_REASON_UNDEFINED;
567                         break;
568         }
569
570         /* Examine target state and mode */
571         dap_ap_select(swjdp, swjdp_memoryap);
572         if (cortex_a8->fast_reg_read)
573                 target_alloc_working_area(target, 64, &regfile_working_area);
574
575         /* First load register acessible through core debug port*/
576         if (!regfile_working_area)
577         {
578                 for (i = 0; i <= 15; i++)
579                         cortex_a8_dap_read_coreregister_u32(target,
580                                         &regfile[i], i);
581         }
582         else
583         {
584                 cortex_a8_read_regs_through_mem(target,
585                                 regfile_working_area->address, regfile);
586                 dap_ap_select(swjdp, swjdp_memoryap);
587                 target_free_working_area(target, regfile_working_area);
588         }
589
590         cortex_a8_dap_read_coreregister_u32(target, &cpsr, 16);
591         pc = regfile[15];
592         dap_ap_select(swjdp, swjdp_debugap);
593         LOG_DEBUG("cpsr: %8.8x", cpsr);
594
595         armv4_5->core_mode = cpsr & 0x3F;
596
597         for (i = 0; i <= ARM_PC; i++)
598         {
599                 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
600                                         armv4_5->core_mode, i).value,
601                                 0, 32, regfile[i]);
602                 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
603                                 armv4_5->core_mode, i).valid = 1;
604                 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
605                                 armv4_5->core_mode, i).dirty = 0;
606         }
607         buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
608                                 armv4_5->core_mode, 16).value,
609                         0, 32, cpsr);
610         ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).valid = 1;
611         ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).dirty = 0;
612
613         /* Fixup PC Resume Address */
614         /* TODO Her we should use arch->core_state */
615         if (cortex_a8->cpudbg_dscr & (1 << 5))
616         {
617                 // T bit set for Thumb or ThumbEE state
618                 regfile[ARM_PC] -= 4;
619         }
620         else
621         {
622                 // ARM state
623                 regfile[ARM_PC] -= 8;
624         }
625         buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
626                                 armv4_5->core_mode, ARM_PC).value,
627                         0, 32, regfile[ARM_PC]);
628
629         ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0)
630                 .dirty = ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
631                                 armv4_5->core_mode, 0).valid;
632         ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 15)
633                 .dirty = ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
634                                 armv4_5->core_mode, 15).valid;
635
636 #if 0
637 /* TODO, Move this */
638         uint32_t cp15_control_register, cp15_cacr, cp15_nacr;
639         cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
640         LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register);
641
642         cortex_a8_read_cp(target, &cp15_cacr, 15, 0, 1, 0, 2);
643         LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr);
644
645         cortex_a8_read_cp(target, &cp15_nacr, 15, 0, 1, 1, 2);
646         LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr);
647 #endif
648
649         /* Are we in an exception handler */
650 //      armv4_5->exception_number = 0;
651         if (armv7a->post_debug_entry)
652                 armv7a->post_debug_entry(target);
653
654
655
656         return retval;
657
658 }
659
660 void cortex_a8_post_debug_entry(target_t *target)
661 {
662         /* get pointers to arch-specific information */
663         armv4_5_common_t *armv4_5 = target->arch_info;
664         armv7a_common_t *armv7a = armv4_5->arch_info;
665         cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
666
667 //      cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
668         /* examine cp15 control reg */
669         armv7a->read_cp15(target, 0, 0, 1, 0, &cortex_a8->cp15_control_reg);
670         jtag_execute_queue();
671         LOG_DEBUG("cp15_control_reg: %8.8x", cortex_a8->cp15_control_reg);
672
673         if (armv7a->armv4_5_mmu.armv4_5_cache.ctype == -1)
674         {
675                 uint32_t cache_type_reg;
676                 /* identify caches */
677                 armv7a->read_cp15(target, 0, 1, 0, 0, &cache_type_reg);
678                 jtag_execute_queue();
679                 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
680                 armv4_5_identify_cache(cache_type_reg,
681                                 &armv7a->armv4_5_mmu.armv4_5_cache);
682         }
683
684         armv7a->armv4_5_mmu.mmu_enabled =
685                         (cortex_a8->cp15_control_reg & 0x1U) ? 1 : 0;
686         armv7a->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled =
687                         (cortex_a8->cp15_control_reg & 0x4U) ? 1 : 0;
688         armv7a->armv4_5_mmu.armv4_5_cache.i_cache_enabled =
689                         (cortex_a8->cp15_control_reg & 0x1000U) ? 1 : 0;
690
691
692 }
693
694 int cortex_a8_step(struct target_s *target, int current, uint32_t address,
695                 int handle_breakpoints)
696 {
697         /* get pointers to arch-specific information */
698         armv4_5_common_t *armv4_5 = target->arch_info;
699         armv7a_common_t *armv7a = armv4_5->arch_info;
700         cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
701         breakpoint_t *breakpoint = NULL;
702         breakpoint_t stepbreakpoint;
703
704         int timeout = 100;
705
706         if (target->state != TARGET_HALTED)
707         {
708                 LOG_WARNING("target not halted");
709                 return ERROR_TARGET_NOT_HALTED;
710         }
711
712         /* current = 1: continue on current pc, otherwise continue at <address> */
713         if (!current)
714         {
715                 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
716                                         armv4_5->core_mode, ARM_PC).value,
717                                 0, 32, address);
718         }
719         else
720         {
721                 address = buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
722                                         armv4_5->core_mode, ARM_PC).value,
723                                 0, 32);
724         }
725
726         /* The front-end may request us not to handle breakpoints.
727          * But since Cortex-A8 uses breakpoint for single step,
728          * we MUST handle breakpoints.
729          */
730         handle_breakpoints = 1;
731         if (handle_breakpoints) {
732                 breakpoint = breakpoint_find(target,
733                                 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
734                                         armv4_5->core_mode, 15).value,
735                         0, 32));
736                 if (breakpoint)
737                         cortex_a8_unset_breakpoint(target, breakpoint);
738         }
739
740         /* Setup single step breakpoint */
741         stepbreakpoint.address = address;
742         stepbreakpoint.length = (cortex_a8->cpudbg_dscr & (1 << 5)) ? 2 : 4;
743         stepbreakpoint.type = BKPT_HARD;
744         stepbreakpoint.set = 0;
745
746         /* Break on IVA mismatch */
747         cortex_a8_set_breakpoint(target, &stepbreakpoint, 0x04);
748
749         target->debug_reason = DBG_REASON_SINGLESTEP;
750
751         cortex_a8_resume(target, 1, address, 0, 0);
752
753         while (target->state != TARGET_HALTED)
754         {
755                 cortex_a8_poll(target);
756                 if (--timeout == 0)
757                 {
758                         LOG_WARNING("timeout waiting for target halt");
759                         break;
760                 }
761         }
762
763         cortex_a8_unset_breakpoint(target, &stepbreakpoint);
764         if (timeout > 0) target->debug_reason = DBG_REASON_BREAKPOINT;
765
766         if (breakpoint)
767                 cortex_a8_set_breakpoint(target, breakpoint, 0);
768
769         if (target->state != TARGET_HALTED)
770                 LOG_DEBUG("target stepped");
771
772         return ERROR_OK;
773 }
774
775 int cortex_a8_restore_context(target_t *target)
776 {
777         int i;
778         uint32_t value;
779
780         /* get pointers to arch-specific information */
781         armv4_5_common_t *armv4_5 = target->arch_info;
782         armv7a_common_t *armv7a = armv4_5->arch_info;
783
784         LOG_DEBUG(" ");
785
786         if (armv7a->pre_restore_context)
787                 armv7a->pre_restore_context(target);
788
789         for (i = 15; i >= 0; i--)
790         {
791                 if (ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
792                                         armv4_5->core_mode, i).dirty)
793                 {
794                         value = buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
795                                                 armv4_5->core_mode, i).value,
796                                         0, 32);
797                         /* TODO Check return values */
798                         cortex_a8_dap_write_coreregister_u32(target, value, i);
799                 }
800         }
801
802         if (armv7a->post_restore_context)
803                 armv7a->post_restore_context(target);
804
805         return ERROR_OK;
806 }
807
808
809 /*
810  * Cortex-A8 Core register functions
811  */
812
813 int cortex_a8_load_core_reg_u32(struct target_s *target, int num,
814                 armv4_5_mode_t mode, uint32_t * value)
815 {
816         int retval;
817         /* get pointers to arch-specific information */
818         armv4_5_common_t *armv4_5 = target->arch_info;
819
820         if ((num <= ARM_CPSR))
821         {
822                 /* read a normal core register */
823                 retval = cortex_a8_dap_read_coreregister_u32(target, value, num);
824
825                 if (retval != ERROR_OK)
826                 {
827                         LOG_ERROR("JTAG failure %i", retval);
828                         return ERROR_JTAG_DEVICE_ERROR;
829                 }
830                 LOG_DEBUG("load from core reg %i value 0x%x", num, *value);
831         }
832         else
833         {
834                 return ERROR_INVALID_ARGUMENTS;
835         }
836
837         /* Register other than r0 - r14 uses r0 for access */
838         if (num > 14)
839                 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
840                                 armv4_5->core_mode, 0).dirty =
841                         ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
842                                 armv4_5->core_mode, 0).valid;
843         ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
844                                 armv4_5->core_mode, 15).dirty =
845                         ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
846                                 armv4_5->core_mode, 15).valid;
847
848         return ERROR_OK;
849 }
850
851 int cortex_a8_store_core_reg_u32(struct target_s *target, int num,
852                 armv4_5_mode_t mode, uint32_t value)
853 {
854         int retval;
855 //      uint32_t reg;
856
857         /* get pointers to arch-specific information */
858         armv4_5_common_t *armv4_5 = target->arch_info;
859
860 #ifdef ARMV7_GDB_HACKS
861         /* If the LR register is being modified, make sure it will put us
862          * in "thumb" mode, or an INVSTATE exception will occur. This is a
863          * hack to deal with the fact that gdb will sometimes "forge"
864          * return addresses, and doesn't set the LSB correctly (i.e., when
865          * printing expressions containing function calls, it sets LR=0.) */
866
867         if (num == 14)
868                 value |= 0x01;
869 #endif
870
871         if ((num <= ARM_CPSR))
872         {
873                 retval = cortex_a8_dap_write_coreregister_u32(target, value, num);
874                 if (retval != ERROR_OK)
875                 {
876                         LOG_ERROR("JTAG failure %i", retval);
877                         ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
878                                         armv4_5->core_mode, num).dirty =
879                                 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
880                                         armv4_5->core_mode, num).valid;
881                         return ERROR_JTAG_DEVICE_ERROR;
882                 }
883                 LOG_DEBUG("write core reg %i value 0x%x", num, value);
884         }
885         else
886         {
887                 return ERROR_INVALID_ARGUMENTS;
888         }
889
890         return ERROR_OK;
891 }
892
893
894 int cortex_a8_read_core_reg(struct target_s *target, int num,
895                 enum armv4_5_mode mode)
896 {
897         uint32_t value;
898         int retval;
899         armv4_5_common_t *armv4_5 = target->arch_info;
900         cortex_a8_dap_read_coreregister_u32(target, &value, num);
901
902         if ((retval = jtag_execute_queue()) != ERROR_OK)
903         {
904                 return retval;
905         }
906
907         ARMV7A_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
908         ARMV7A_CORE_REG_MODE(armv4_5->core_cache, mode, num).dirty = 0;
909         buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
910                         mode, num).value, 0, 32, value);
911
912         return ERROR_OK;
913 }
914
915 int cortex_a8_write_core_reg(struct target_s *target, int num,
916                 enum armv4_5_mode mode, uint32_t value)
917 {
918         int retval;
919         armv4_5_common_t *armv4_5 = target->arch_info;
920
921         cortex_a8_dap_write_coreregister_u32(target, value, num);
922         if ((retval = jtag_execute_queue()) != ERROR_OK)
923         {
924                 return retval;
925         }
926
927         ARMV7A_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
928         ARMV7A_CORE_REG_MODE(armv4_5->core_cache, mode, num).dirty = 0;
929
930         return ERROR_OK;
931 }
932
933
934 /*
935  * Cortex-A8 Breakpoint and watchpoint fuctions
936  */
937
938 /* Setup hardware Breakpoint Register Pair */
939 int cortex_a8_set_breakpoint(struct target_s *target,
940                 breakpoint_t *breakpoint, uint8_t matchmode)
941 {
942         int retval;
943         int brp_i=0;
944         uint32_t control;
945         uint8_t byte_addr_select = 0x0F;
946
947
948         /* get pointers to arch-specific information */
949         armv4_5_common_t *armv4_5 = target->arch_info;
950         armv7a_common_t *armv7a = armv4_5->arch_info;
951         cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
952         cortex_a8_brp_t * brp_list = cortex_a8->brp_list;
953
954         if (breakpoint->set)
955         {
956                 LOG_WARNING("breakpoint already set");
957                 return ERROR_OK;
958         }
959
960         if (breakpoint->type == BKPT_HARD)
961         {
962                 while (brp_list[brp_i].used && (brp_i < cortex_a8->brp_num))
963                         brp_i++ ;
964                 if (brp_i >= cortex_a8->brp_num)
965                 {
966                         LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
967                         exit(-1);
968                 }
969                 breakpoint->set = brp_i + 1;
970                 if (breakpoint->length == 2)
971                 {
972                         byte_addr_select = (3 << (breakpoint->address & 0x02));
973                 }
974                 control = ((matchmode & 0x7) << 20)
975                                 | (byte_addr_select << 5)
976                                 | (3 << 1) | 1;
977                 brp_list[brp_i].used = 1;
978                 brp_list[brp_i].value = (breakpoint->address & 0xFFFFFFFC);
979                 brp_list[brp_i].control = control;
980                 target_write_u32(target, OMAP3530_DEBUG_BASE
981                                 + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn,
982                                 brp_list[brp_i].value);
983                 target_write_u32(target, OMAP3530_DEBUG_BASE
984                                 + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn,
985                                 brp_list[brp_i].control);
986                 LOG_DEBUG("brp %i control 0x%0x value 0x%0x", brp_i,
987                                 brp_list[brp_i].control,
988                                 brp_list[brp_i].value);
989         }
990         else if (breakpoint->type == BKPT_SOFT)
991         {
992                 uint8_t code[4];
993                 if (breakpoint->length == 2)
994                 {
995                         buf_set_u32(code, 0, 32, ARMV5_T_BKPT(0x11));
996                 }
997                 else
998                 {
999                         buf_set_u32(code, 0, 32, ARMV5_BKPT(0x11));
1000                 }
1001                 retval = target->type->read_memory(target,
1002                                 breakpoint->address & 0xFFFFFFFE,
1003                                 breakpoint->length, 1,
1004                                 breakpoint->orig_instr);
1005                 if (retval != ERROR_OK)
1006                         return retval;
1007                 retval = target->type->write_memory(target,
1008                                 breakpoint->address & 0xFFFFFFFE,
1009                                 breakpoint->length, 1, code);
1010                 if (retval != ERROR_OK)
1011                         return retval;
1012                 breakpoint->set = 0x11; /* Any nice value but 0 */
1013         }
1014
1015         return ERROR_OK;
1016 }
1017
1018 int cortex_a8_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
1019 {
1020         int retval;
1021         /* get pointers to arch-specific information */
1022         armv4_5_common_t *armv4_5 = target->arch_info;
1023         armv7a_common_t *armv7a = armv4_5->arch_info;
1024         cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
1025         cortex_a8_brp_t * brp_list = cortex_a8->brp_list;
1026
1027         if (!breakpoint->set)
1028         {
1029                 LOG_WARNING("breakpoint not set");
1030                 return ERROR_OK;
1031         }
1032
1033         if (breakpoint->type == BKPT_HARD)
1034         {
1035                 int brp_i = breakpoint->set - 1;
1036                 if ((brp_i < 0) || (brp_i >= cortex_a8->brp_num))
1037                 {
1038                         LOG_DEBUG("Invalid BRP number in breakpoint");
1039                         return ERROR_OK;
1040                 }
1041                 LOG_DEBUG("rbp %i control 0x%0x value 0x%0x", brp_i,
1042                                 brp_list[brp_i].control, brp_list[brp_i].value);
1043                 brp_list[brp_i].used = 0;
1044                 brp_list[brp_i].value = 0;
1045                 brp_list[brp_i].control = 0;
1046                 target_write_u32(target, OMAP3530_DEBUG_BASE
1047                                 + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn,
1048                                 brp_list[brp_i].control);
1049                 target_write_u32(target, OMAP3530_DEBUG_BASE
1050                                 + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn,
1051                                 brp_list[brp_i].value);
1052         }
1053         else
1054         {
1055                 /* restore original instruction (kept in target endianness) */
1056                 if (breakpoint->length == 4)
1057                 {
1058                         retval = target->type->write_memory(target,
1059                                         breakpoint->address & 0xFFFFFFFE,
1060                                         4, 1, breakpoint->orig_instr);
1061                         if (retval != ERROR_OK)
1062                                 return retval;
1063                 }
1064                 else
1065                 {
1066                         retval = target->type->write_memory(target,
1067                                         breakpoint->address & 0xFFFFFFFE,
1068                                         2, 1, breakpoint->orig_instr);
1069                         if (retval != ERROR_OK)
1070                                 return retval;
1071                 }
1072         }
1073         breakpoint->set = 0;
1074
1075         return ERROR_OK;
1076 }
1077
1078 int cortex_a8_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
1079 {
1080         /* get pointers to arch-specific information */
1081         armv4_5_common_t *armv4_5 = target->arch_info;
1082         armv7a_common_t *armv7a = armv4_5->arch_info;
1083         cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
1084
1085         if ((breakpoint->type == BKPT_HARD) && (cortex_a8->brp_num_available < 1))
1086         {
1087                 LOG_INFO("no hardware breakpoint available");
1088                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1089         }
1090
1091         if (breakpoint->type == BKPT_HARD)
1092                 cortex_a8->brp_num_available--;
1093         cortex_a8_set_breakpoint(target, breakpoint, 0x00); /* Exact match */
1094
1095         return ERROR_OK;
1096 }
1097
1098 int cortex_a8_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
1099 {
1100         /* get pointers to arch-specific information */
1101         armv4_5_common_t *armv4_5 = target->arch_info;
1102         armv7a_common_t *armv7a = armv4_5->arch_info;
1103         cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
1104
1105 #if 0
1106 /* It is perfectly possible to remove brakpoints while the taget is running */
1107         if (target->state != TARGET_HALTED)
1108         {
1109                 LOG_WARNING("target not halted");
1110                 return ERROR_TARGET_NOT_HALTED;
1111         }
1112 #endif
1113
1114         if (breakpoint->set)
1115         {
1116                 cortex_a8_unset_breakpoint(target, breakpoint);
1117                 if (breakpoint->type == BKPT_HARD)
1118                         cortex_a8->brp_num_available++ ;
1119         }
1120
1121
1122         return ERROR_OK;
1123 }
1124
1125
1126
1127 /*
1128  * Cortex-A8 Reset fuctions
1129  */
1130
1131
1132 /*
1133  * Cortex-A8 Memory access
1134  *
1135  * This is same Cortex M3 but we must also use the correct
1136  * ap number for every access.
1137  */
1138
1139 int cortex_a8_read_memory(struct target_s *target, uint32_t address,
1140                 uint32_t size, uint32_t count, uint8_t *buffer)
1141 {
1142         /* get pointers to arch-specific information */
1143         armv4_5_common_t *armv4_5 = target->arch_info;
1144         armv7a_common_t *armv7a = armv4_5->arch_info;
1145         swjdp_common_t *swjdp = &armv7a->swjdp_info;
1146
1147         int retval = ERROR_OK;
1148
1149         /* sanitize arguments */
1150         if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1151                 return ERROR_INVALID_ARGUMENTS;
1152
1153         /* cortex_a8 handles unaligned memory access */
1154
1155 // ???  dap_ap_select(swjdp, swjdp_memoryap);
1156
1157         switch (size)
1158         {
1159                 case 4:
1160                         retval = mem_ap_read_buf_u32(swjdp, buffer, 4 * count, address);
1161                         break;
1162                 case 2:
1163                         retval = mem_ap_read_buf_u16(swjdp, buffer, 2 * count, address);
1164                         break;
1165                 case 1:
1166                         retval = mem_ap_read_buf_u8(swjdp, buffer, count, address);
1167                         break;
1168                 default:
1169                         LOG_ERROR("BUG: we shouldn't get here");
1170                         exit(-1);
1171         }
1172
1173         return retval;
1174 }
1175
1176 int cortex_a8_write_memory(struct target_s *target, uint32_t address,
1177                 uint32_t size, uint32_t count, uint8_t *buffer)
1178 {
1179         /* get pointers to arch-specific information */
1180         armv4_5_common_t *armv4_5 = target->arch_info;
1181         armv7a_common_t *armv7a = armv4_5->arch_info;
1182         swjdp_common_t *swjdp = &armv7a->swjdp_info;
1183
1184         int retval;
1185
1186         /* sanitize arguments */
1187         if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1188                 return ERROR_INVALID_ARGUMENTS;
1189
1190 // ???  dap_ap_select(swjdp, swjdp_memoryap);
1191
1192         switch (size)
1193         {
1194                 case 4:
1195                         retval = mem_ap_write_buf_u32(swjdp, buffer, 4 * count, address);
1196                         break;
1197                 case 2:
1198                         retval = mem_ap_write_buf_u16(swjdp, buffer, 2 * count, address);
1199                         break;
1200                 case 1:
1201                         retval = mem_ap_write_buf_u8(swjdp, buffer, count, address);
1202                         break;
1203                 default:
1204                         LOG_ERROR("BUG: we shouldn't get here");
1205                         exit(-1);
1206         }
1207
1208         return retval;
1209 }
1210
1211 int cortex_a8_bulk_write_memory(target_t *target, uint32_t address,
1212                 uint32_t count, uint8_t *buffer)
1213 {
1214         return cortex_a8_write_memory(target, address, 4, count, buffer);
1215 }
1216
1217
1218 int cortex_a8_dcc_read(swjdp_common_t *swjdp, uint8_t *value, uint8_t *ctrl)
1219 {
1220 #if 0
1221         u16 dcrdr;
1222
1223         mem_ap_read_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
1224         *ctrl = (uint8_t)dcrdr;
1225         *value = (uint8_t)(dcrdr >> 8);
1226
1227         LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
1228
1229         /* write ack back to software dcc register
1230          * signify we have read data */
1231         if (dcrdr & (1 << 0))
1232         {
1233                 dcrdr = 0;
1234                 mem_ap_write_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
1235         }
1236 #endif
1237         return ERROR_OK;
1238 }
1239
1240
1241 int cortex_a8_handle_target_request(void *priv)
1242 {
1243         target_t *target = priv;
1244         if (!target->type->examined)
1245                 return ERROR_OK;
1246         armv4_5_common_t *armv4_5 = target->arch_info;
1247         armv7a_common_t *armv7a = armv4_5->arch_info;
1248         swjdp_common_t *swjdp = &armv7a->swjdp_info;
1249
1250
1251         if (!target->dbg_msg_enabled)
1252                 return ERROR_OK;
1253
1254         if (target->state == TARGET_RUNNING)
1255         {
1256                 uint8_t data = 0;
1257                 uint8_t ctrl = 0;
1258
1259                 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1260
1261                 /* check if we have data */
1262                 if (ctrl & (1 << 0))
1263                 {
1264                         uint32_t request;
1265
1266                         /* we assume target is quick enough */
1267                         request = data;
1268                         cortex_a8_dcc_read(swjdp, &data, &ctrl);
1269                         request |= (data << 8);
1270                         cortex_a8_dcc_read(swjdp, &data, &ctrl);
1271                         request |= (data << 16);
1272                         cortex_a8_dcc_read(swjdp, &data, &ctrl);
1273                         request |= (data << 24);
1274                         target_request(target, request);
1275                 }
1276         }
1277
1278         return ERROR_OK;
1279 }
1280
1281 /*
1282  * Cortex-A8 target information and configuration
1283  */
1284
1285 int cortex_a8_examine(struct target_s *target)
1286 {
1287         /* get pointers to arch-specific information */
1288         armv4_5_common_t *armv4_5 = target->arch_info;
1289         armv7a_common_t *armv7a = armv4_5->arch_info;
1290         cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
1291         swjdp_common_t *swjdp = &armv7a->swjdp_info;
1292
1293
1294         int i;
1295         int retval = ERROR_OK;
1296         uint32_t didr, ctypr, ttypr, cpuid;
1297
1298         LOG_DEBUG("TODO");
1299
1300         /* We do one extra read to ensure DAP is configured,
1301          * we call ahbap_debugport_init(swjdp) instead
1302          */
1303         ahbap_debugport_init(swjdp);
1304         mem_ap_read_atomic_u32(swjdp, OMAP3530_DEBUG_BASE + CPUDBG_CPUID, &cpuid);
1305         if ((retval = mem_ap_read_atomic_u32(swjdp,
1306                         OMAP3530_DEBUG_BASE + CPUDBG_CPUID, &cpuid)) != ERROR_OK)
1307         {
1308                 LOG_DEBUG("Examine failed");
1309                 return retval;
1310         }
1311
1312         if ((retval = mem_ap_read_atomic_u32(swjdp,
1313                         OMAP3530_DEBUG_BASE + CPUDBG_CTYPR, &ctypr)) != ERROR_OK)
1314         {
1315                 LOG_DEBUG("Examine failed");
1316                 return retval;
1317         }
1318
1319         if ((retval = mem_ap_read_atomic_u32(swjdp,
1320                         OMAP3530_DEBUG_BASE + CPUDBG_TTYPR, &ttypr)) != ERROR_OK)
1321         {
1322                 LOG_DEBUG("Examine failed");
1323                 return retval;
1324         }
1325
1326         if ((retval = mem_ap_read_atomic_u32(swjdp,
1327                         OMAP3530_DEBUG_BASE + CPUDBG_DIDR, &didr)) != ERROR_OK)
1328         {
1329                 LOG_DEBUG("Examine failed");
1330                 return retval;
1331         }
1332
1333         LOG_DEBUG("cpuid = 0x%08x", cpuid);
1334         LOG_DEBUG("ctypr = 0x%08x", ctypr);
1335         LOG_DEBUG("ttypr = 0x%08x", ttypr);
1336         LOG_DEBUG("didr = 0x%08x", didr);
1337
1338         /* Setup Breakpoint Register Pairs */
1339         cortex_a8->brp_num = ((didr >> 24) & 0x0F) + 1;
1340         cortex_a8->brp_num_context = ((didr >> 20) & 0x0F) + 1;
1341         cortex_a8->brp_num_available = cortex_a8->brp_num;
1342         cortex_a8->brp_list = calloc(cortex_a8->brp_num, sizeof(cortex_a8_brp_t));
1343 //      cortex_a8->brb_enabled = ????;
1344         for (i = 0; i < cortex_a8->brp_num; i++)
1345         {
1346                 cortex_a8->brp_list[i].used = 0;
1347                 if (i < (cortex_a8->brp_num-cortex_a8->brp_num_context))
1348                         cortex_a8->brp_list[i].type = BRP_NORMAL;
1349                 else
1350                         cortex_a8->brp_list[i].type = BRP_CONTEXT;
1351                 cortex_a8->brp_list[i].value = 0;
1352                 cortex_a8->brp_list[i].control = 0;
1353                 cortex_a8->brp_list[i].BRPn = i;
1354         }
1355
1356         /* Setup Watchpoint Register Pairs */
1357         cortex_a8->wrp_num = ((didr >> 28) & 0x0F) + 1;
1358         cortex_a8->wrp_num_available = cortex_a8->wrp_num;
1359         cortex_a8->wrp_list = calloc(cortex_a8->wrp_num, sizeof(cortex_a8_wrp_t));
1360         for (i = 0; i < cortex_a8->wrp_num; i++)
1361         {
1362                 cortex_a8->wrp_list[i].used = 0;
1363                 cortex_a8->wrp_list[i].type = 0;
1364                 cortex_a8->wrp_list[i].value = 0;
1365                 cortex_a8->wrp_list[i].control = 0;
1366                 cortex_a8->wrp_list[i].WRPn = i;
1367         }
1368         LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1369                         cortex_a8->brp_num , cortex_a8->wrp_num);
1370
1371         target->type->examined = 1;
1372
1373         return retval;
1374 }
1375
1376 /*
1377  *      Cortex-A8 target creation and initialization
1378  */
1379
1380 void cortex_a8_build_reg_cache(target_t *target)
1381 {
1382         reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
1383         /* get pointers to arch-specific information */
1384         armv4_5_common_t *armv4_5 = target->arch_info;
1385
1386         (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
1387         armv4_5->core_cache = (*cache_p);
1388 }
1389
1390
1391 int cortex_a8_init_target(struct command_context_s *cmd_ctx,
1392                 struct target_s *target)
1393 {
1394         cortex_a8_build_reg_cache(target);
1395         return ERROR_OK;
1396 }
1397
1398 int cortex_a8_init_arch_info(target_t *target,
1399                 cortex_a8_common_t *cortex_a8, jtag_tap_t *tap)
1400 {
1401         armv4_5_common_t *armv4_5;
1402         armv7a_common_t *armv7a;
1403
1404         armv7a = &cortex_a8->armv7a_common;
1405         armv4_5 = &armv7a->armv4_5_common;
1406         swjdp_common_t *swjdp = &armv7a->swjdp_info;
1407
1408         /* Setup cortex_a8_common_t */
1409         cortex_a8->common_magic = CORTEX_A8_COMMON_MAGIC;
1410         cortex_a8->arch_info = NULL;
1411         armv7a->arch_info = cortex_a8;
1412         armv4_5->arch_info = armv7a;
1413
1414         armv4_5_init_arch_info(target, armv4_5);
1415
1416         /* prepare JTAG information for the new target */
1417         cortex_a8->jtag_info.tap = tap;
1418         cortex_a8->jtag_info.scann_size = 4;
1419 LOG_DEBUG(" ");
1420         swjdp->dp_select_value = -1;
1421         swjdp->ap_csw_value = -1;
1422         swjdp->ap_tar_value = -1;
1423         swjdp->jtag_info = &cortex_a8->jtag_info;
1424         swjdp->memaccess_tck = 80;
1425
1426         /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1427         swjdp->tar_autoincr_block = (1 << 10);
1428
1429         cortex_a8->fast_reg_read = 0;
1430
1431
1432         /* register arch-specific functions */
1433         armv7a->examine_debug_reason = NULL;
1434
1435         armv7a->pre_debug_entry = NULL;
1436         armv7a->post_debug_entry = cortex_a8_post_debug_entry;
1437
1438         armv7a->pre_restore_context = NULL;
1439         armv7a->post_restore_context = NULL;
1440         armv7a->armv4_5_mmu.armv4_5_cache.ctype = -1;
1441 //      armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1442         armv7a->armv4_5_mmu.read_memory = cortex_a8_read_memory;
1443         armv7a->armv4_5_mmu.write_memory = cortex_a8_write_memory;
1444 //      armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1445 //      armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1446         armv7a->armv4_5_mmu.has_tiny_pages = 1;
1447         armv7a->armv4_5_mmu.mmu_enabled = 0;
1448         armv7a->read_cp15 = cortex_a8_read_cp15;
1449         armv7a->write_cp15 = cortex_a8_write_cp15;
1450
1451
1452 //      arm7_9->handle_target_request = cortex_a8_handle_target_request;
1453
1454         armv4_5->read_core_reg = cortex_a8_read_core_reg;
1455         armv4_5->write_core_reg = cortex_a8_write_core_reg;
1456 //      armv4_5->full_context = arm7_9_full_context;
1457
1458 //      armv4_5->load_core_reg_u32 = cortex_a8_load_core_reg_u32;
1459 //      armv4_5->store_core_reg_u32 = cortex_a8_store_core_reg_u32;
1460 //      armv4_5->read_core_reg = armv4_5_read_core_reg; /* this is default */
1461 //      armv4_5->write_core_reg = armv4_5_write_core_reg;
1462
1463         target_register_timer_callback(cortex_a8_handle_target_request, 1, 1, target);
1464
1465         return ERROR_OK;
1466 }
1467
1468 int cortex_a8_target_create(struct target_s *target, Jim_Interp *interp)
1469 {
1470         cortex_a8_common_t *cortex_a8 = calloc(1, sizeof(cortex_a8_common_t));
1471
1472         cortex_a8_init_arch_info(target, cortex_a8, target->tap);
1473
1474         return ERROR_OK;
1475 }
1476
1477 static int cortex_a8_handle_cache_info_command(struct command_context_s *cmd_ctx,
1478                 char *cmd, char **args, int argc)
1479 {
1480         target_t *target = get_current_target(cmd_ctx);
1481         armv4_5_common_t *armv4_5 = target->arch_info;
1482         armv7a_common_t *armv7a = armv4_5->arch_info;
1483
1484         return armv4_5_handle_cache_info_command(cmd_ctx,
1485                         &armv7a->armv4_5_mmu.armv4_5_cache);
1486 }
1487
1488
1489 int cortex_a8_register_commands(struct command_context_s *cmd_ctx)
1490 {
1491         command_t *cortex_a8_cmd;
1492         int retval = ERROR_OK;
1493
1494         armv4_5_register_commands(cmd_ctx);
1495         armv7a_register_commands(cmd_ctx);
1496
1497         cortex_a8_cmd = register_command(cmd_ctx, NULL, "cortex_a8",
1498                         NULL, COMMAND_ANY,
1499                         "cortex_a8 specific commands");
1500
1501         register_command(cmd_ctx, cortex_a8_cmd, "cache_info",
1502                         cortex_a8_handle_cache_info_command, COMMAND_EXEC,
1503                         "display information about target caches");
1504
1505         return retval;
1506 }