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

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)