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

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)