9585b35c2a658cb0de9980ce5b99b6ac854234c2
[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, dscr;
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 /* Enable the ITR execution once we are in debug mode */
565 mem_ap_read_atomic_u32(swjdp,
566 OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
567 dscr |= (1 << 13);
568 retval = mem_ap_write_atomic_u32(swjdp,
569 OMAP3530_DEBUG_BASE + CPUDBG_DSCR, dscr);
570
571
572 /* Examine debug reason */
573 switch ((cortex_a8->cpudbg_dscr >> 2)&0xF)
574 {
575 case 0:
576 case 4:
577 target->debug_reason = DBG_REASON_DBGRQ;
578 break;
579 case 1:
580 case 3:
581 target->debug_reason = DBG_REASON_BREAKPOINT;
582 break;
583 case 10:
584 target->debug_reason = DBG_REASON_WATCHPOINT;
585 break;
586 default:
587 target->debug_reason = DBG_REASON_UNDEFINED;
588 break;
589 }
590
591 /* Examine target state and mode */
592 dap_ap_select(swjdp, swjdp_memoryap);
593 if (cortex_a8->fast_reg_read)
594 target_alloc_working_area(target, 64, &regfile_working_area);
595
596 /* First load register acessible through core debug port*/
597 if (!regfile_working_area)
598 {
599 for (i = 0; i <= 15; i++)
600 cortex_a8_dap_read_coreregister_u32(target,
601 &regfile[i], i);
602 }
603 else
604 {
605 cortex_a8_read_regs_through_mem(target,
606 regfile_working_area->address, regfile);
607 dap_ap_select(swjdp, swjdp_memoryap);
608 target_free_working_area(target, regfile_working_area);
609 }
610
611 cortex_a8_dap_read_coreregister_u32(target, &cpsr, 16);
612 pc = regfile[15];
613 dap_ap_select(swjdp, swjdp_debugap);
614 LOG_DEBUG("cpsr: %8.8" PRIx32, cpsr);
615
616 armv4_5->core_mode = cpsr & 0x3F;
617
618 for (i = 0; i <= ARM_PC; i++)
619 {
620 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
621 armv4_5->core_mode, i).value,
622 0, 32, regfile[i]);
623 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
624 armv4_5->core_mode, i).valid = 1;
625 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
626 armv4_5->core_mode, i).dirty = 0;
627 }
628 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
629 armv4_5->core_mode, 16).value,
630 0, 32, cpsr);
631 ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).valid = 1;
632 ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).dirty = 0;
633
634 /* Fixup PC Resume Address */
635 /* TODO Her we should use arch->core_state */
636 if (cortex_a8->cpudbg_dscr & (1 << 5))
637 {
638 // T bit set for Thumb or ThumbEE state
639 regfile[ARM_PC] -= 4;
640 }
641 else
642 {
643 // ARM state
644 regfile[ARM_PC] -= 8;
645 }
646 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
647 armv4_5->core_mode, ARM_PC).value,
648 0, 32, regfile[ARM_PC]);
649
650 ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0)
651 .dirty = ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
652 armv4_5->core_mode, 0).valid;
653 ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 15)
654 .dirty = ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
655 armv4_5->core_mode, 15).valid;
656
657 #if 0
658 /* TODO, Move this */
659 uint32_t cp15_control_register, cp15_cacr, cp15_nacr;
660 cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
661 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register);
662
663 cortex_a8_read_cp(target, &cp15_cacr, 15, 0, 1, 0, 2);
664 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr);
665
666 cortex_a8_read_cp(target, &cp15_nacr, 15, 0, 1, 1, 2);
667 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr);
668 #endif
669
670 /* Are we in an exception handler */
671 // armv4_5->exception_number = 0;
672 if (armv7a->post_debug_entry)
673 armv7a->post_debug_entry(target);
674
675
676
677 return retval;
678
679 }
680
681 void cortex_a8_post_debug_entry(target_t *target)
682 {
683 /* get pointers to arch-specific information */
684 armv4_5_common_t *armv4_5 = target->arch_info;
685 armv7a_common_t *armv7a = armv4_5->arch_info;
686 cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
687
688 // cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
689 /* examine cp15 control reg */
690 armv7a->read_cp15(target, 0, 0, 1, 0, &cortex_a8->cp15_control_reg);
691 jtag_execute_queue();
692 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32, cortex_a8->cp15_control_reg);
693
694 if (armv7a->armv4_5_mmu.armv4_5_cache.ctype == -1)
695 {
696 uint32_t cache_type_reg;
697 /* identify caches */
698 armv7a->read_cp15(target, 0, 1, 0, 0, &cache_type_reg);
699 jtag_execute_queue();
700 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
701 armv4_5_identify_cache(cache_type_reg,
702 &armv7a->armv4_5_mmu.armv4_5_cache);
703 }
704
705 armv7a->armv4_5_mmu.mmu_enabled =
706 (cortex_a8->cp15_control_reg & 0x1U) ? 1 : 0;
707 armv7a->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled =
708 (cortex_a8->cp15_control_reg & 0x4U) ? 1 : 0;
709 armv7a->armv4_5_mmu.armv4_5_cache.i_cache_enabled =
710 (cortex_a8->cp15_control_reg & 0x1000U) ? 1 : 0;
711
712
713 }
714
715 int cortex_a8_step(struct target_s *target, int current, uint32_t address,
716 int handle_breakpoints)
717 {
718 /* get pointers to arch-specific information */
719 armv4_5_common_t *armv4_5 = target->arch_info;
720 armv7a_common_t *armv7a = armv4_5->arch_info;
721 cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
722 breakpoint_t *breakpoint = NULL;
723 breakpoint_t stepbreakpoint;
724
725 int timeout = 100;
726
727 if (target->state != TARGET_HALTED)
728 {
729 LOG_WARNING("target not halted");
730 return ERROR_TARGET_NOT_HALTED;
731 }
732
733 /* current = 1: continue on current pc, otherwise continue at <address> */
734 if (!current)
735 {
736 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
737 armv4_5->core_mode, ARM_PC).value,
738 0, 32, address);
739 }
740 else
741 {
742 address = buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
743 armv4_5->core_mode, ARM_PC).value,
744 0, 32);
745 }
746
747 /* The front-end may request us not to handle breakpoints.
748 * But since Cortex-A8 uses breakpoint for single step,
749 * we MUST handle breakpoints.
750 */
751 handle_breakpoints = 1;
752 if (handle_breakpoints) {
753 breakpoint = breakpoint_find(target,
754 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
755 armv4_5->core_mode, 15).value,
756 0, 32));
757 if (breakpoint)
758 cortex_a8_unset_breakpoint(target, breakpoint);
759 }
760
761 /* Setup single step breakpoint */
762 stepbreakpoint.address = address;
763 stepbreakpoint.length = (cortex_a8->cpudbg_dscr & (1 << 5)) ? 2 : 4;
764 stepbreakpoint.type = BKPT_HARD;
765 stepbreakpoint.set = 0;
766
767 /* Break on IVA mismatch */
768 cortex_a8_set_breakpoint(target, &stepbreakpoint, 0x04);
769
770 target->debug_reason = DBG_REASON_SINGLESTEP;
771
772 cortex_a8_resume(target, 1, address, 0, 0);
773
774 while (target->state != TARGET_HALTED)
775 {
776 cortex_a8_poll(target);
777 if (--timeout == 0)
778 {
779 LOG_WARNING("timeout waiting for target halt");
780 break;
781 }
782 }
783
784 cortex_a8_unset_breakpoint(target, &stepbreakpoint);
785 if (timeout > 0) target->debug_reason = DBG_REASON_BREAKPOINT;
786
787 if (breakpoint)
788 cortex_a8_set_breakpoint(target, breakpoint, 0);
789
790 if (target->state != TARGET_HALTED)
791 LOG_DEBUG("target stepped");
792
793 return ERROR_OK;
794 }
795
796 int cortex_a8_restore_context(target_t *target)
797 {
798 int i;
799 uint32_t value;
800
801 /* get pointers to arch-specific information */
802 armv4_5_common_t *armv4_5 = target->arch_info;
803 armv7a_common_t *armv7a = armv4_5->arch_info;
804
805 LOG_DEBUG(" ");
806
807 if (armv7a->pre_restore_context)
808 armv7a->pre_restore_context(target);
809
810 for (i = 15; i >= 0; i--)
811 {
812 if (ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
813 armv4_5->core_mode, i).dirty)
814 {
815 value = buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
816 armv4_5->core_mode, i).value,
817 0, 32);
818 /* TODO Check return values */
819 cortex_a8_dap_write_coreregister_u32(target, value, i);
820 }
821 }
822
823 if (armv7a->post_restore_context)
824 armv7a->post_restore_context(target);
825
826 return ERROR_OK;
827 }
828
829
830 /*
831 * Cortex-A8 Core register functions
832 */
833
834 int cortex_a8_load_core_reg_u32(struct target_s *target, int num,
835 armv4_5_mode_t mode, uint32_t * value)
836 {
837 int retval;
838 /* get pointers to arch-specific information */
839 armv4_5_common_t *armv4_5 = target->arch_info;
840
841 if ((num <= ARM_CPSR))
842 {
843 /* read a normal core register */
844 retval = cortex_a8_dap_read_coreregister_u32(target, value, num);
845
846 if (retval != ERROR_OK)
847 {
848 LOG_ERROR("JTAG failure %i", retval);
849 return ERROR_JTAG_DEVICE_ERROR;
850 }
851 LOG_DEBUG("load from core reg %i value 0x%" PRIx32, num, *value);
852 }
853 else
854 {
855 return ERROR_INVALID_ARGUMENTS;
856 }
857
858 /* Register other than r0 - r14 uses r0 for access */
859 if (num > 14)
860 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
861 armv4_5->core_mode, 0).dirty =
862 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
863 armv4_5->core_mode, 0).valid;
864 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
865 armv4_5->core_mode, 15).dirty =
866 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
867 armv4_5->core_mode, 15).valid;
868
869 return ERROR_OK;
870 }
871
872 int cortex_a8_store_core_reg_u32(struct target_s *target, int num,
873 armv4_5_mode_t mode, uint32_t value)
874 {
875 int retval;
876 // uint32_t reg;
877
878 /* get pointers to arch-specific information */
879 armv4_5_common_t *armv4_5 = target->arch_info;
880
881 #ifdef ARMV7_GDB_HACKS
882 /* If the LR register is being modified, make sure it will put us
883 * in "thumb" mode, or an INVSTATE exception will occur. This is a
884 * hack to deal with the fact that gdb will sometimes "forge"
885 * return addresses, and doesn't set the LSB correctly (i.e., when
886 * printing expressions containing function calls, it sets LR=0.) */
887
888 if (num == 14)
889 value |= 0x01;
890 #endif
891
892 if ((num <= ARM_CPSR))
893 {
894 retval = cortex_a8_dap_write_coreregister_u32(target, value, num);
895 if (retval != ERROR_OK)
896 {
897 LOG_ERROR("JTAG failure %i", retval);
898 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
899 armv4_5->core_mode, num).dirty =
900 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
901 armv4_5->core_mode, num).valid;
902 return ERROR_JTAG_DEVICE_ERROR;
903 }
904 LOG_DEBUG("write core reg %i value 0x%" PRIx32, num, value);
905 }
906 else
907 {
908 return ERROR_INVALID_ARGUMENTS;
909 }
910
911 return ERROR_OK;
912 }
913
914
915 int cortex_a8_read_core_reg(struct target_s *target, int num,
916 enum armv4_5_mode mode)
917 {
918 uint32_t value;
919 int retval;
920 armv4_5_common_t *armv4_5 = target->arch_info;
921 cortex_a8_dap_read_coreregister_u32(target, &value, num);
922
923 if ((retval = jtag_execute_queue()) != ERROR_OK)
924 {
925 return retval;
926 }
927
928 ARMV7A_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
929 ARMV7A_CORE_REG_MODE(armv4_5->core_cache, mode, num).dirty = 0;
930 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
931 mode, num).value, 0, 32, value);
932
933 return ERROR_OK;
934 }
935
936 int cortex_a8_write_core_reg(struct target_s *target, int num,
937 enum armv4_5_mode mode, uint32_t value)
938 {
939 int retval;
940 armv4_5_common_t *armv4_5 = target->arch_info;
941
942 cortex_a8_dap_write_coreregister_u32(target, value, num);
943 if ((retval = jtag_execute_queue()) != ERROR_OK)
944 {
945 return retval;
946 }
947
948 ARMV7A_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
949 ARMV7A_CORE_REG_MODE(armv4_5->core_cache, mode, num).dirty = 0;
950
951 return ERROR_OK;
952 }
953
954
955 /*
956 * Cortex-A8 Breakpoint and watchpoint fuctions
957 */
958
959 /* Setup hardware Breakpoint Register Pair */
960 int cortex_a8_set_breakpoint(struct target_s *target,
961 breakpoint_t *breakpoint, uint8_t matchmode)
962 {
963 int retval;
964 int brp_i=0;
965 uint32_t control;
966 uint8_t byte_addr_select = 0x0F;
967
968
969 /* get pointers to arch-specific information */
970 armv4_5_common_t *armv4_5 = target->arch_info;
971 armv7a_common_t *armv7a = armv4_5->arch_info;
972 cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
973 cortex_a8_brp_t * brp_list = cortex_a8->brp_list;
974
975 if (breakpoint->set)
976 {
977 LOG_WARNING("breakpoint already set");
978 return ERROR_OK;
979 }
980
981 if (breakpoint->type == BKPT_HARD)
982 {
983 while (brp_list[brp_i].used && (brp_i < cortex_a8->brp_num))
984 brp_i++ ;
985 if (brp_i >= cortex_a8->brp_num)
986 {
987 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
988 exit(-1);
989 }
990 breakpoint->set = brp_i + 1;
991 if (breakpoint->length == 2)
992 {
993 byte_addr_select = (3 << (breakpoint->address & 0x02));
994 }
995 control = ((matchmode & 0x7) << 20)
996 | (byte_addr_select << 5)
997 | (3 << 1) | 1;
998 brp_list[brp_i].used = 1;
999 brp_list[brp_i].value = (breakpoint->address & 0xFFFFFFFC);
1000 brp_list[brp_i].control = control;
1001 target_write_u32(target, OMAP3530_DEBUG_BASE
1002 + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn,
1003 brp_list[brp_i].value);
1004 target_write_u32(target, OMAP3530_DEBUG_BASE
1005 + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn,
1006 brp_list[brp_i].control);
1007 LOG_DEBUG("brp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_i,
1008 brp_list[brp_i].control,
1009 brp_list[brp_i].value);
1010 }
1011 else if (breakpoint->type == BKPT_SOFT)
1012 {
1013 uint8_t code[4];
1014 if (breakpoint->length == 2)
1015 {
1016 buf_set_u32(code, 0, 32, ARMV5_T_BKPT(0x11));
1017 }
1018 else
1019 {
1020 buf_set_u32(code, 0, 32, ARMV5_BKPT(0x11));
1021 }
1022 retval = target->type->read_memory(target,
1023 breakpoint->address & 0xFFFFFFFE,
1024 breakpoint->length, 1,
1025 breakpoint->orig_instr);
1026 if (retval != ERROR_OK)
1027 return retval;
1028 retval = target->type->write_memory(target,
1029 breakpoint->address & 0xFFFFFFFE,
1030 breakpoint->length, 1, code);
1031 if (retval != ERROR_OK)
1032 return retval;
1033 breakpoint->set = 0x11; /* Any nice value but 0 */
1034 }
1035
1036 return ERROR_OK;
1037 }
1038
1039 int cortex_a8_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
1040 {
1041 int retval;
1042 /* get pointers to arch-specific information */
1043 armv4_5_common_t *armv4_5 = target->arch_info;
1044 armv7a_common_t *armv7a = armv4_5->arch_info;
1045 cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
1046 cortex_a8_brp_t * brp_list = cortex_a8->brp_list;
1047
1048 if (!breakpoint->set)
1049 {
1050 LOG_WARNING("breakpoint not set");
1051 return ERROR_OK;
1052 }
1053
1054 if (breakpoint->type == BKPT_HARD)
1055 {
1056 int brp_i = breakpoint->set - 1;
1057 if ((brp_i < 0) || (brp_i >= cortex_a8->brp_num))
1058 {
1059 LOG_DEBUG("Invalid BRP number in breakpoint");
1060 return ERROR_OK;
1061 }
1062 LOG_DEBUG("rbp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_i,
1063 brp_list[brp_i].control, brp_list[brp_i].value);
1064 brp_list[brp_i].used = 0;
1065 brp_list[brp_i].value = 0;
1066 brp_list[brp_i].control = 0;
1067 target_write_u32(target, OMAP3530_DEBUG_BASE
1068 + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn,
1069 brp_list[brp_i].control);
1070 target_write_u32(target, OMAP3530_DEBUG_BASE
1071 + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn,
1072 brp_list[brp_i].value);
1073 }
1074 else
1075 {
1076 /* restore original instruction (kept in target endianness) */
1077 if (breakpoint->length == 4)
1078 {
1079 retval = target->type->write_memory(target,
1080 breakpoint->address & 0xFFFFFFFE,
1081 4, 1, breakpoint->orig_instr);
1082 if (retval != ERROR_OK)
1083 return retval;
1084 }
1085 else
1086 {
1087 retval = target->type->write_memory(target,
1088 breakpoint->address & 0xFFFFFFFE,
1089 2, 1, breakpoint->orig_instr);
1090 if (retval != ERROR_OK)
1091 return retval;
1092 }
1093 }
1094 breakpoint->set = 0;
1095
1096 return ERROR_OK;
1097 }
1098
1099 int cortex_a8_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
1100 {
1101 /* get pointers to arch-specific information */
1102 armv4_5_common_t *armv4_5 = target->arch_info;
1103 armv7a_common_t *armv7a = armv4_5->arch_info;
1104 cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
1105
1106 if ((breakpoint->type == BKPT_HARD) && (cortex_a8->brp_num_available < 1))
1107 {
1108 LOG_INFO("no hardware breakpoint available");
1109 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1110 }
1111
1112 if (breakpoint->type == BKPT_HARD)
1113 cortex_a8->brp_num_available--;
1114 cortex_a8_set_breakpoint(target, breakpoint, 0x00); /* Exact match */
1115
1116 return ERROR_OK;
1117 }
1118
1119 int cortex_a8_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
1120 {
1121 /* get pointers to arch-specific information */
1122 armv4_5_common_t *armv4_5 = target->arch_info;
1123 armv7a_common_t *armv7a = armv4_5->arch_info;
1124 cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
1125
1126 #if 0
1127 /* It is perfectly possible to remove brakpoints while the taget is running */
1128 if (target->state != TARGET_HALTED)
1129 {
1130 LOG_WARNING("target not halted");
1131 return ERROR_TARGET_NOT_HALTED;
1132 }
1133 #endif
1134
1135 if (breakpoint->set)
1136 {
1137 cortex_a8_unset_breakpoint(target, breakpoint);
1138 if (breakpoint->type == BKPT_HARD)
1139 cortex_a8->brp_num_available++ ;
1140 }
1141
1142
1143 return ERROR_OK;
1144 }
1145
1146
1147
1148 /*
1149 * Cortex-A8 Reset fuctions
1150 */
1151
1152
1153 /*
1154 * Cortex-A8 Memory access
1155 *
1156 * This is same Cortex M3 but we must also use the correct
1157 * ap number for every access.
1158 */
1159
1160 int cortex_a8_read_memory(struct target_s *target, uint32_t address,
1161 uint32_t size, uint32_t count, uint8_t *buffer)
1162 {
1163 /* get pointers to arch-specific information */
1164 armv4_5_common_t *armv4_5 = target->arch_info;
1165 armv7a_common_t *armv7a = armv4_5->arch_info;
1166 swjdp_common_t *swjdp = &armv7a->swjdp_info;
1167
1168 int retval = ERROR_OK;
1169
1170 /* sanitize arguments */
1171 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1172 return ERROR_INVALID_ARGUMENTS;
1173
1174 /* cortex_a8 handles unaligned memory access */
1175
1176 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1177
1178 switch (size)
1179 {
1180 case 4:
1181 retval = mem_ap_read_buf_u32(swjdp, buffer, 4 * count, address);
1182 break;
1183 case 2:
1184 retval = mem_ap_read_buf_u16(swjdp, buffer, 2 * count, address);
1185 break;
1186 case 1:
1187 retval = mem_ap_read_buf_u8(swjdp, buffer, count, address);
1188 break;
1189 default:
1190 LOG_ERROR("BUG: we shouldn't get here");
1191 exit(-1);
1192 }
1193
1194 return retval;
1195 }
1196
1197 int cortex_a8_write_memory(struct target_s *target, uint32_t address,
1198 uint32_t size, uint32_t count, uint8_t *buffer)
1199 {
1200 /* get pointers to arch-specific information */
1201 armv4_5_common_t *armv4_5 = target->arch_info;
1202 armv7a_common_t *armv7a = armv4_5->arch_info;
1203 swjdp_common_t *swjdp = &armv7a->swjdp_info;
1204
1205 int retval;
1206
1207 /* sanitize arguments */
1208 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1209 return ERROR_INVALID_ARGUMENTS;
1210
1211 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1212
1213 switch (size)
1214 {
1215 case 4:
1216 retval = mem_ap_write_buf_u32(swjdp, buffer, 4 * count, address);
1217 break;
1218 case 2:
1219 retval = mem_ap_write_buf_u16(swjdp, buffer, 2 * count, address);
1220 break;
1221 case 1:
1222 retval = mem_ap_write_buf_u8(swjdp, buffer, count, address);
1223 break;
1224 default:
1225 LOG_ERROR("BUG: we shouldn't get here");
1226 exit(-1);
1227 }
1228
1229 return retval;
1230 }
1231
1232 int cortex_a8_bulk_write_memory(target_t *target, uint32_t address,
1233 uint32_t count, uint8_t *buffer)
1234 {
1235 return cortex_a8_write_memory(target, address, 4, count, buffer);
1236 }
1237
1238
1239 int cortex_a8_dcc_read(swjdp_common_t *swjdp, uint8_t *value, uint8_t *ctrl)
1240 {
1241 #if 0
1242 u16 dcrdr;
1243
1244 mem_ap_read_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
1245 *ctrl = (uint8_t)dcrdr;
1246 *value = (uint8_t)(dcrdr >> 8);
1247
1248 LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
1249
1250 /* write ack back to software dcc register
1251 * signify we have read data */
1252 if (dcrdr & (1 << 0))
1253 {
1254 dcrdr = 0;
1255 mem_ap_write_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
1256 }
1257 #endif
1258 return ERROR_OK;
1259 }
1260
1261
1262 int cortex_a8_handle_target_request(void *priv)
1263 {
1264 target_t *target = priv;
1265 if (!target->type->examined)
1266 return ERROR_OK;
1267 armv4_5_common_t *armv4_5 = target->arch_info;
1268 armv7a_common_t *armv7a = armv4_5->arch_info;
1269 swjdp_common_t *swjdp = &armv7a->swjdp_info;
1270
1271
1272 if (!target->dbg_msg_enabled)
1273 return ERROR_OK;
1274
1275 if (target->state == TARGET_RUNNING)
1276 {
1277 uint8_t data = 0;
1278 uint8_t ctrl = 0;
1279
1280 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1281
1282 /* check if we have data */
1283 if (ctrl & (1 << 0))
1284 {
1285 uint32_t request;
1286
1287 /* we assume target is quick enough */
1288 request = data;
1289 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1290 request |= (data << 8);
1291 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1292 request |= (data << 16);
1293 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1294 request |= (data << 24);
1295 target_request(target, request);
1296 }
1297 }
1298
1299 return ERROR_OK;
1300 }
1301
1302 /*
1303 * Cortex-A8 target information and configuration
1304 */
1305
1306 int cortex_a8_examine(struct target_s *target)
1307 {
1308 /* get pointers to arch-specific information */
1309 armv4_5_common_t *armv4_5 = target->arch_info;
1310 armv7a_common_t *armv7a = armv4_5->arch_info;
1311 cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
1312 swjdp_common_t *swjdp = &armv7a->swjdp_info;
1313
1314
1315 int i;
1316 int retval = ERROR_OK;
1317 uint32_t didr, ctypr, ttypr, cpuid;
1318
1319 LOG_DEBUG("TODO");
1320
1321 /* We do one extra read to ensure DAP is configured,
1322 * we call ahbap_debugport_init(swjdp) instead
1323 */
1324 ahbap_debugport_init(swjdp);
1325 mem_ap_read_atomic_u32(swjdp, OMAP3530_DEBUG_BASE + CPUDBG_CPUID, &cpuid);
1326 if ((retval = mem_ap_read_atomic_u32(swjdp,
1327 OMAP3530_DEBUG_BASE + CPUDBG_CPUID, &cpuid)) != ERROR_OK)
1328 {
1329 LOG_DEBUG("Examine failed");
1330 return retval;
1331 }
1332
1333 if ((retval = mem_ap_read_atomic_u32(swjdp,
1334 OMAP3530_DEBUG_BASE + CPUDBG_CTYPR, &ctypr)) != ERROR_OK)
1335 {
1336 LOG_DEBUG("Examine failed");
1337 return retval;
1338 }
1339
1340 if ((retval = mem_ap_read_atomic_u32(swjdp,
1341 OMAP3530_DEBUG_BASE + CPUDBG_TTYPR, &ttypr)) != ERROR_OK)
1342 {
1343 LOG_DEBUG("Examine failed");
1344 return retval;
1345 }
1346
1347 if ((retval = mem_ap_read_atomic_u32(swjdp,
1348 OMAP3530_DEBUG_BASE + CPUDBG_DIDR, &didr)) != ERROR_OK)
1349 {
1350 LOG_DEBUG("Examine failed");
1351 return retval;
1352 }
1353
1354 LOG_DEBUG("cpuid = 0x%08" PRIx32, cpuid);
1355 LOG_DEBUG("ctypr = 0x%08" PRIx32, ctypr);
1356 LOG_DEBUG("ttypr = 0x%08" PRIx32, ttypr);
1357 LOG_DEBUG("didr = 0x%08" PRIx32, didr);
1358
1359 /* Setup Breakpoint Register Pairs */
1360 cortex_a8->brp_num = ((didr >> 24) & 0x0F) + 1;
1361 cortex_a8->brp_num_context = ((didr >> 20) & 0x0F) + 1;
1362 cortex_a8->brp_num_available = cortex_a8->brp_num;
1363 cortex_a8->brp_list = calloc(cortex_a8->brp_num, sizeof(cortex_a8_brp_t));
1364 // cortex_a8->brb_enabled = ????;
1365 for (i = 0; i < cortex_a8->brp_num; i++)
1366 {
1367 cortex_a8->brp_list[i].used = 0;
1368 if (i < (cortex_a8->brp_num-cortex_a8->brp_num_context))
1369 cortex_a8->brp_list[i].type = BRP_NORMAL;
1370 else
1371 cortex_a8->brp_list[i].type = BRP_CONTEXT;
1372 cortex_a8->brp_list[i].value = 0;
1373 cortex_a8->brp_list[i].control = 0;
1374 cortex_a8->brp_list[i].BRPn = i;
1375 }
1376
1377 /* Setup Watchpoint Register Pairs */
1378 cortex_a8->wrp_num = ((didr >> 28) & 0x0F) + 1;
1379 cortex_a8->wrp_num_available = cortex_a8->wrp_num;
1380 cortex_a8->wrp_list = calloc(cortex_a8->wrp_num, sizeof(cortex_a8_wrp_t));
1381 for (i = 0; i < cortex_a8->wrp_num; i++)
1382 {
1383 cortex_a8->wrp_list[i].used = 0;
1384 cortex_a8->wrp_list[i].type = 0;
1385 cortex_a8->wrp_list[i].value = 0;
1386 cortex_a8->wrp_list[i].control = 0;
1387 cortex_a8->wrp_list[i].WRPn = i;
1388 }
1389 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1390 cortex_a8->brp_num , cortex_a8->wrp_num);
1391
1392 target->type->examined = 1;
1393
1394 return retval;
1395 }
1396
1397 /*
1398 * Cortex-A8 target creation and initialization
1399 */
1400
1401 void cortex_a8_build_reg_cache(target_t *target)
1402 {
1403 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
1404 /* get pointers to arch-specific information */
1405 armv4_5_common_t *armv4_5 = target->arch_info;
1406
1407 (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
1408 armv4_5->core_cache = (*cache_p);
1409 }
1410
1411
1412 int cortex_a8_init_target(struct command_context_s *cmd_ctx,
1413 struct target_s *target)
1414 {
1415 cortex_a8_build_reg_cache(target);
1416 return ERROR_OK;
1417 }
1418
1419 int cortex_a8_init_arch_info(target_t *target,
1420 cortex_a8_common_t *cortex_a8, jtag_tap_t *tap)
1421 {
1422 armv4_5_common_t *armv4_5;
1423 armv7a_common_t *armv7a;
1424
1425 armv7a = &cortex_a8->armv7a_common;
1426 armv4_5 = &armv7a->armv4_5_common;
1427 swjdp_common_t *swjdp = &armv7a->swjdp_info;
1428
1429 /* Setup cortex_a8_common_t */
1430 cortex_a8->common_magic = CORTEX_A8_COMMON_MAGIC;
1431 cortex_a8->arch_info = NULL;
1432 armv7a->arch_info = cortex_a8;
1433 armv4_5->arch_info = armv7a;
1434
1435 armv4_5_init_arch_info(target, armv4_5);
1436
1437 /* prepare JTAG information for the new target */
1438 cortex_a8->jtag_info.tap = tap;
1439 cortex_a8->jtag_info.scann_size = 4;
1440 LOG_DEBUG(" ");
1441 swjdp->dp_select_value = -1;
1442 swjdp->ap_csw_value = -1;
1443 swjdp->ap_tar_value = -1;
1444 swjdp->jtag_info = &cortex_a8->jtag_info;
1445 swjdp->memaccess_tck = 80;
1446
1447 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1448 swjdp->tar_autoincr_block = (1 << 10);
1449
1450 cortex_a8->fast_reg_read = 0;
1451
1452
1453 /* register arch-specific functions */
1454 armv7a->examine_debug_reason = NULL;
1455
1456 armv7a->pre_debug_entry = NULL;
1457 armv7a->post_debug_entry = cortex_a8_post_debug_entry;
1458
1459 armv7a->pre_restore_context = NULL;
1460 armv7a->post_restore_context = NULL;
1461 armv7a->armv4_5_mmu.armv4_5_cache.ctype = -1;
1462 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1463 armv7a->armv4_5_mmu.read_memory = cortex_a8_read_memory;
1464 armv7a->armv4_5_mmu.write_memory = cortex_a8_write_memory;
1465 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1466 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1467 armv7a->armv4_5_mmu.has_tiny_pages = 1;
1468 armv7a->armv4_5_mmu.mmu_enabled = 0;
1469 armv7a->read_cp15 = cortex_a8_read_cp15;
1470 armv7a->write_cp15 = cortex_a8_write_cp15;
1471
1472
1473 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1474
1475 armv4_5->read_core_reg = cortex_a8_read_core_reg;
1476 armv4_5->write_core_reg = cortex_a8_write_core_reg;
1477 // armv4_5->full_context = arm7_9_full_context;
1478
1479 // armv4_5->load_core_reg_u32 = cortex_a8_load_core_reg_u32;
1480 // armv4_5->store_core_reg_u32 = cortex_a8_store_core_reg_u32;
1481 // armv4_5->read_core_reg = armv4_5_read_core_reg; /* this is default */
1482 // armv4_5->write_core_reg = armv4_5_write_core_reg;
1483
1484 target_register_timer_callback(cortex_a8_handle_target_request, 1, 1, target);
1485
1486 return ERROR_OK;
1487 }
1488
1489 int cortex_a8_target_create(struct target_s *target, Jim_Interp *interp)
1490 {
1491 cortex_a8_common_t *cortex_a8 = calloc(1, sizeof(cortex_a8_common_t));
1492
1493 cortex_a8_init_arch_info(target, cortex_a8, target->tap);
1494
1495 return ERROR_OK;
1496 }
1497
1498 static int cortex_a8_handle_cache_info_command(struct command_context_s *cmd_ctx,
1499 char *cmd, char **args, int argc)
1500 {
1501 target_t *target = get_current_target(cmd_ctx);
1502 armv4_5_common_t *armv4_5 = target->arch_info;
1503 armv7a_common_t *armv7a = armv4_5->arch_info;
1504
1505 return armv4_5_handle_cache_info_command(cmd_ctx,
1506 &armv7a->armv4_5_mmu.armv4_5_cache);
1507 }
1508
1509
1510 int cortex_a8_register_commands(struct command_context_s *cmd_ctx)
1511 {
1512 command_t *cortex_a8_cmd;
1513 int retval = ERROR_OK;
1514
1515 armv4_5_register_commands(cmd_ctx);
1516 armv7a_register_commands(cmd_ctx);
1517
1518 cortex_a8_cmd = register_command(cmd_ctx, NULL, "cortex_a8",
1519 NULL, COMMAND_ANY,
1520 "cortex_a8 specific commands");
1521
1522 register_command(cmd_ctx, cortex_a8_cmd, "cache_info",
1523 cortex_a8_handle_cache_info_command, COMMAND_EXEC,
1524 "display information about target caches");
1525
1526 return retval;
1527 }

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)