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