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