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

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)