Fix argument passing in cortex_a8_write_cp.
[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 return retval;
1257 }
1258
1259 int cortex_a8_bulk_write_memory(target_t *target, uint32_t address,
1260 uint32_t count, uint8_t *buffer)
1261 {
1262 return cortex_a8_write_memory(target, address, 4, count, buffer);
1263 }
1264
1265
1266 int cortex_a8_dcc_read(swjdp_common_t *swjdp, uint8_t *value, uint8_t *ctrl)
1267 {
1268 #if 0
1269 u16 dcrdr;
1270
1271 mem_ap_read_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
1272 *ctrl = (uint8_t)dcrdr;
1273 *value = (uint8_t)(dcrdr >> 8);
1274
1275 LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
1276
1277 /* write ack back to software dcc register
1278 * signify we have read data */
1279 if (dcrdr & (1 << 0))
1280 {
1281 dcrdr = 0;
1282 mem_ap_write_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
1283 }
1284 #endif
1285 return ERROR_OK;
1286 }
1287
1288
1289 int cortex_a8_handle_target_request(void *priv)
1290 {
1291 target_t *target = priv;
1292 if (!target->type->examined)
1293 return ERROR_OK;
1294 armv4_5_common_t *armv4_5 = target->arch_info;
1295 armv7a_common_t *armv7a = armv4_5->arch_info;
1296 swjdp_common_t *swjdp = &armv7a->swjdp_info;
1297
1298
1299 if (!target->dbg_msg_enabled)
1300 return ERROR_OK;
1301
1302 if (target->state == TARGET_RUNNING)
1303 {
1304 uint8_t data = 0;
1305 uint8_t ctrl = 0;
1306
1307 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1308
1309 /* check if we have data */
1310 if (ctrl & (1 << 0))
1311 {
1312 uint32_t request;
1313
1314 /* we assume target is quick enough */
1315 request = data;
1316 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1317 request |= (data << 8);
1318 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1319 request |= (data << 16);
1320 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1321 request |= (data << 24);
1322 target_request(target, request);
1323 }
1324 }
1325
1326 return ERROR_OK;
1327 }
1328
1329 /*
1330 * Cortex-A8 target information and configuration
1331 */
1332
1333 int cortex_a8_examine(struct target_s *target)
1334 {
1335 /* get pointers to arch-specific information */
1336 armv4_5_common_t *armv4_5 = target->arch_info;
1337 armv7a_common_t *armv7a = armv4_5->arch_info;
1338 cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
1339 swjdp_common_t *swjdp = &armv7a->swjdp_info;
1340
1341
1342 int i;
1343 int retval = ERROR_OK;
1344 uint32_t didr, ctypr, ttypr, cpuid;
1345
1346 LOG_DEBUG("TODO");
1347
1348 /* We do one extra read to ensure DAP is configured,
1349 * we call ahbap_debugport_init(swjdp) instead
1350 */
1351 ahbap_debugport_init(swjdp);
1352 mem_ap_read_atomic_u32(swjdp, OMAP3530_DEBUG_BASE + CPUDBG_CPUID, &cpuid);
1353 if ((retval = mem_ap_read_atomic_u32(swjdp,
1354 OMAP3530_DEBUG_BASE + CPUDBG_CPUID, &cpuid)) != ERROR_OK)
1355 {
1356 LOG_DEBUG("Examine failed");
1357 return retval;
1358 }
1359
1360 if ((retval = mem_ap_read_atomic_u32(swjdp,
1361 OMAP3530_DEBUG_BASE + CPUDBG_CTYPR, &ctypr)) != ERROR_OK)
1362 {
1363 LOG_DEBUG("Examine failed");
1364 return retval;
1365 }
1366
1367 if ((retval = mem_ap_read_atomic_u32(swjdp,
1368 OMAP3530_DEBUG_BASE + CPUDBG_TTYPR, &ttypr)) != ERROR_OK)
1369 {
1370 LOG_DEBUG("Examine failed");
1371 return retval;
1372 }
1373
1374 if ((retval = mem_ap_read_atomic_u32(swjdp,
1375 OMAP3530_DEBUG_BASE + CPUDBG_DIDR, &didr)) != ERROR_OK)
1376 {
1377 LOG_DEBUG("Examine failed");
1378 return retval;
1379 }
1380
1381 LOG_DEBUG("cpuid = 0x%08" PRIx32, cpuid);
1382 LOG_DEBUG("ctypr = 0x%08" PRIx32, ctypr);
1383 LOG_DEBUG("ttypr = 0x%08" PRIx32, ttypr);
1384 LOG_DEBUG("didr = 0x%08" PRIx32, didr);
1385
1386 /* Setup Breakpoint Register Pairs */
1387 cortex_a8->brp_num = ((didr >> 24) & 0x0F) + 1;
1388 cortex_a8->brp_num_context = ((didr >> 20) & 0x0F) + 1;
1389 cortex_a8->brp_num_available = cortex_a8->brp_num;
1390 cortex_a8->brp_list = calloc(cortex_a8->brp_num, sizeof(cortex_a8_brp_t));
1391 // cortex_a8->brb_enabled = ????;
1392 for (i = 0; i < cortex_a8->brp_num; i++)
1393 {
1394 cortex_a8->brp_list[i].used = 0;
1395 if (i < (cortex_a8->brp_num-cortex_a8->brp_num_context))
1396 cortex_a8->brp_list[i].type = BRP_NORMAL;
1397 else
1398 cortex_a8->brp_list[i].type = BRP_CONTEXT;
1399 cortex_a8->brp_list[i].value = 0;
1400 cortex_a8->brp_list[i].control = 0;
1401 cortex_a8->brp_list[i].BRPn = i;
1402 }
1403
1404 /* Setup Watchpoint Register Pairs */
1405 cortex_a8->wrp_num = ((didr >> 28) & 0x0F) + 1;
1406 cortex_a8->wrp_num_available = cortex_a8->wrp_num;
1407 cortex_a8->wrp_list = calloc(cortex_a8->wrp_num, sizeof(cortex_a8_wrp_t));
1408 for (i = 0; i < cortex_a8->wrp_num; i++)
1409 {
1410 cortex_a8->wrp_list[i].used = 0;
1411 cortex_a8->wrp_list[i].type = 0;
1412 cortex_a8->wrp_list[i].value = 0;
1413 cortex_a8->wrp_list[i].control = 0;
1414 cortex_a8->wrp_list[i].WRPn = i;
1415 }
1416 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1417 cortex_a8->brp_num , cortex_a8->wrp_num);
1418
1419 target->type->examined = 1;
1420
1421 return retval;
1422 }
1423
1424 /*
1425 * Cortex-A8 target creation and initialization
1426 */
1427
1428 void cortex_a8_build_reg_cache(target_t *target)
1429 {
1430 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
1431 /* get pointers to arch-specific information */
1432 armv4_5_common_t *armv4_5 = target->arch_info;
1433
1434 (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
1435 armv4_5->core_cache = (*cache_p);
1436 }
1437
1438
1439 int cortex_a8_init_target(struct command_context_s *cmd_ctx,
1440 struct target_s *target)
1441 {
1442 cortex_a8_build_reg_cache(target);
1443 return ERROR_OK;
1444 }
1445
1446 int cortex_a8_init_arch_info(target_t *target,
1447 cortex_a8_common_t *cortex_a8, jtag_tap_t *tap)
1448 {
1449 armv4_5_common_t *armv4_5;
1450 armv7a_common_t *armv7a;
1451
1452 armv7a = &cortex_a8->armv7a_common;
1453 armv4_5 = &armv7a->armv4_5_common;
1454 swjdp_common_t *swjdp = &armv7a->swjdp_info;
1455
1456 /* Setup cortex_a8_common_t */
1457 cortex_a8->common_magic = CORTEX_A8_COMMON_MAGIC;
1458 cortex_a8->arch_info = NULL;
1459 armv7a->arch_info = cortex_a8;
1460 armv4_5->arch_info = armv7a;
1461
1462 armv4_5_init_arch_info(target, armv4_5);
1463
1464 /* prepare JTAG information for the new target */
1465 cortex_a8->jtag_info.tap = tap;
1466 cortex_a8->jtag_info.scann_size = 4;
1467 LOG_DEBUG(" ");
1468 swjdp->dp_select_value = -1;
1469 swjdp->ap_csw_value = -1;
1470 swjdp->ap_tar_value = -1;
1471 swjdp->jtag_info = &cortex_a8->jtag_info;
1472 swjdp->memaccess_tck = 80;
1473
1474 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1475 swjdp->tar_autoincr_block = (1 << 10);
1476
1477 cortex_a8->fast_reg_read = 0;
1478
1479
1480 /* register arch-specific functions */
1481 armv7a->examine_debug_reason = NULL;
1482
1483 armv7a->pre_debug_entry = NULL;
1484 armv7a->post_debug_entry = cortex_a8_post_debug_entry;
1485
1486 armv7a->pre_restore_context = NULL;
1487 armv7a->post_restore_context = NULL;
1488 armv7a->armv4_5_mmu.armv4_5_cache.ctype = -1;
1489 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1490 armv7a->armv4_5_mmu.read_memory = cortex_a8_read_memory;
1491 armv7a->armv4_5_mmu.write_memory = cortex_a8_write_memory;
1492 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1493 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1494 armv7a->armv4_5_mmu.has_tiny_pages = 1;
1495 armv7a->armv4_5_mmu.mmu_enabled = 0;
1496 armv7a->read_cp15 = cortex_a8_read_cp15;
1497 armv7a->write_cp15 = cortex_a8_write_cp15;
1498
1499
1500 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1501
1502 armv4_5->read_core_reg = cortex_a8_read_core_reg;
1503 armv4_5->write_core_reg = cortex_a8_write_core_reg;
1504 // armv4_5->full_context = arm7_9_full_context;
1505
1506 // armv4_5->load_core_reg_u32 = cortex_a8_load_core_reg_u32;
1507 // armv4_5->store_core_reg_u32 = cortex_a8_store_core_reg_u32;
1508 // armv4_5->read_core_reg = armv4_5_read_core_reg; /* this is default */
1509 // armv4_5->write_core_reg = armv4_5_write_core_reg;
1510
1511 target_register_timer_callback(cortex_a8_handle_target_request, 1, 1, target);
1512
1513 return ERROR_OK;
1514 }
1515
1516 int cortex_a8_target_create(struct target_s *target, Jim_Interp *interp)
1517 {
1518 cortex_a8_common_t *cortex_a8 = calloc(1, sizeof(cortex_a8_common_t));
1519
1520 cortex_a8_init_arch_info(target, cortex_a8, target->tap);
1521
1522 return ERROR_OK;
1523 }
1524
1525 static int cortex_a8_handle_cache_info_command(struct command_context_s *cmd_ctx,
1526 char *cmd, char **args, int argc)
1527 {
1528 target_t *target = get_current_target(cmd_ctx);
1529 armv4_5_common_t *armv4_5 = target->arch_info;
1530 armv7a_common_t *armv7a = armv4_5->arch_info;
1531
1532 return armv4_5_handle_cache_info_command(cmd_ctx,
1533 &armv7a->armv4_5_mmu.armv4_5_cache);
1534 }
1535
1536
1537 int cortex_a8_register_commands(struct command_context_s *cmd_ctx)
1538 {
1539 command_t *cortex_a8_cmd;
1540 int retval = ERROR_OK;
1541
1542 armv4_5_register_commands(cmd_ctx);
1543 armv7a_register_commands(cmd_ctx);
1544
1545 cortex_a8_cmd = register_command(cmd_ctx, NULL, "cortex_a8",
1546 NULL, COMMAND_ANY,
1547 "cortex_a8 specific commands");
1548
1549 register_command(cmd_ctx, cortex_a8_cmd, "cache_info",
1550 cortex_a8_handle_cache_info_command, COMMAND_EXEC,
1551 "display information about target caches");
1552
1553 return retval;
1554 }

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)