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

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)