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

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)