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

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)