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