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

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)