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

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)