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

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)