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

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)