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

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)