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

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)