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

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)