e716999063748cee01c69bb728287d36f4c5180a
[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 LOG_DEBUG("dscr = 0x%08" PRIx32, cortex_a8->cpudbg_dscr);
641
642 /* Enable the ITR execution once we are in debug mode */
643 mem_ap_read_atomic_u32(swjdp,
644 armv7a->debug_base + CPUDBG_DSCR, &dscr);
645 dscr |= (1 << DSCR_EXT_INT_EN);
646 retval = mem_ap_write_atomic_u32(swjdp,
647 armv7a->debug_base + CPUDBG_DSCR, dscr);
648
649 /* Examine debug reason */
650 switch ((cortex_a8->cpudbg_dscr >> 2)&0xF)
651 {
652 case 0:
653 case 4:
654 target->debug_reason = DBG_REASON_DBGRQ;
655 break;
656 case 1:
657 case 3:
658 target->debug_reason = DBG_REASON_BREAKPOINT;
659 break;
660 case 10:
661 target->debug_reason = DBG_REASON_WATCHPOINT;
662 break;
663 default:
664 target->debug_reason = DBG_REASON_UNDEFINED;
665 break;
666 }
667
668 /* Examine target state and mode */
669 if (cortex_a8->fast_reg_read)
670 target_alloc_working_area(target, 64, &regfile_working_area);
671
672 /* First load register acessible through core debug port*/
673 if (!regfile_working_area)
674 {
675 for (i = 0; i <= 15; i++)
676 cortex_a8_dap_read_coreregister_u32(target,
677 &regfile[i], i);
678 }
679 else
680 {
681 dap_ap_select(swjdp, swjdp_memoryap);
682 cortex_a8_read_regs_through_mem(target,
683 regfile_working_area->address, regfile);
684 dap_ap_select(swjdp, swjdp_memoryap);
685 target_free_working_area(target, regfile_working_area);
686 }
687
688 cortex_a8_dap_read_coreregister_u32(target, &cpsr, 16);
689 pc = regfile[15];
690 dap_ap_select(swjdp, swjdp_debugap);
691 LOG_DEBUG("cpsr: %8.8" PRIx32, cpsr);
692
693 armv4_5->core_mode = cpsr & 0x1F;
694 armv7a->core_state = (cpsr & 0x20)?ARMV7A_STATE_THUMB:ARMV7A_STATE_ARM;
695
696 for (i = 0; i <= ARM_PC; i++)
697 {
698 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
699 armv4_5->core_mode, i).value,
700 0, 32, regfile[i]);
701 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
702 armv4_5->core_mode, i).valid = 1;
703 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
704 armv4_5->core_mode, i).dirty = 0;
705 }
706 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
707 armv4_5->core_mode, 16).value,
708 0, 32, cpsr);
709 ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).valid = 1;
710 ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).dirty = 0;
711
712 /* Fixup PC Resume Address */
713 if (armv7a->core_state == ARMV7A_STATE_THUMB)
714 {
715 // T bit set for Thumb or ThumbEE state
716 regfile[ARM_PC] -= 4;
717 }
718 else
719 {
720 // ARM state
721 regfile[ARM_PC] -= 8;
722 }
723 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
724 armv4_5->core_mode, ARM_PC).value,
725 0, 32, regfile[ARM_PC]);
726
727 ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0)
728 .dirty = ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
729 armv4_5->core_mode, 0).valid;
730 ARMV7A_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 15)
731 .dirty = ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
732 armv4_5->core_mode, 15).valid;
733
734 #if 0
735 /* TODO, Move this */
736 uint32_t cp15_control_register, cp15_cacr, cp15_nacr;
737 cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
738 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register);
739
740 cortex_a8_read_cp(target, &cp15_cacr, 15, 0, 1, 0, 2);
741 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr);
742
743 cortex_a8_read_cp(target, &cp15_nacr, 15, 0, 1, 1, 2);
744 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr);
745 #endif
746
747 /* Are we in an exception handler */
748 // armv4_5->exception_number = 0;
749 if (armv7a->post_debug_entry)
750 armv7a->post_debug_entry(target);
751
752
753
754 return retval;
755
756 }
757
758 void cortex_a8_post_debug_entry(target_t *target)
759 {
760 /* get pointers to arch-specific information */
761 armv4_5_common_t *armv4_5 = target->arch_info;
762 armv7a_common_t *armv7a = armv4_5->arch_info;
763 cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
764
765 // cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
766 /* examine cp15 control reg */
767 armv7a->read_cp15(target, 0, 0, 1, 0, &cortex_a8->cp15_control_reg);
768 jtag_execute_queue();
769 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32, cortex_a8->cp15_control_reg);
770
771 if (armv7a->armv4_5_mmu.armv4_5_cache.ctype == -1)
772 {
773 uint32_t cache_type_reg;
774 /* identify caches */
775 armv7a->read_cp15(target, 0, 1, 0, 0, &cache_type_reg);
776 jtag_execute_queue();
777 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
778 armv4_5_identify_cache(cache_type_reg,
779 &armv7a->armv4_5_mmu.armv4_5_cache);
780 }
781
782 armv7a->armv4_5_mmu.mmu_enabled =
783 (cortex_a8->cp15_control_reg & 0x1U) ? 1 : 0;
784 armv7a->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled =
785 (cortex_a8->cp15_control_reg & 0x4U) ? 1 : 0;
786 armv7a->armv4_5_mmu.armv4_5_cache.i_cache_enabled =
787 (cortex_a8->cp15_control_reg & 0x1000U) ? 1 : 0;
788
789
790 }
791
792 int cortex_a8_step(struct target_s *target, int current, uint32_t address,
793 int handle_breakpoints)
794 {
795 /* get pointers to arch-specific information */
796 armv4_5_common_t *armv4_5 = target->arch_info;
797 armv7a_common_t *armv7a = armv4_5->arch_info;
798 breakpoint_t *breakpoint = NULL;
799 breakpoint_t stepbreakpoint;
800
801 int timeout = 100;
802
803 if (target->state != TARGET_HALTED)
804 {
805 LOG_WARNING("target not halted");
806 return ERROR_TARGET_NOT_HALTED;
807 }
808
809 /* current = 1: continue on current pc, otherwise continue at <address> */
810 if (!current)
811 {
812 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
813 armv4_5->core_mode, ARM_PC).value,
814 0, 32, address);
815 }
816 else
817 {
818 address = buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
819 armv4_5->core_mode, ARM_PC).value,
820 0, 32);
821 }
822
823 /* The front-end may request us not to handle breakpoints.
824 * But since Cortex-A8 uses breakpoint for single step,
825 * we MUST handle breakpoints.
826 */
827 handle_breakpoints = 1;
828 if (handle_breakpoints) {
829 breakpoint = breakpoint_find(target,
830 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
831 armv4_5->core_mode, 15).value,
832 0, 32));
833 if (breakpoint)
834 cortex_a8_unset_breakpoint(target, breakpoint);
835 }
836
837 /* Setup single step breakpoint */
838 stepbreakpoint.address = address;
839 stepbreakpoint.length = (armv7a->core_state == ARMV7A_STATE_THUMB) ? 2 : 4;
840 stepbreakpoint.type = BKPT_HARD;
841 stepbreakpoint.set = 0;
842
843 /* Break on IVA mismatch */
844 cortex_a8_set_breakpoint(target, &stepbreakpoint, 0x04);
845
846 target->debug_reason = DBG_REASON_SINGLESTEP;
847
848 cortex_a8_resume(target, 1, address, 0, 0);
849
850 while (target->state != TARGET_HALTED)
851 {
852 cortex_a8_poll(target);
853 if (--timeout == 0)
854 {
855 LOG_WARNING("timeout waiting for target halt");
856 break;
857 }
858 }
859
860 cortex_a8_unset_breakpoint(target, &stepbreakpoint);
861 if (timeout > 0) target->debug_reason = DBG_REASON_BREAKPOINT;
862
863 if (breakpoint)
864 cortex_a8_set_breakpoint(target, breakpoint, 0);
865
866 if (target->state != TARGET_HALTED)
867 LOG_DEBUG("target stepped");
868
869 return ERROR_OK;
870 }
871
872 int cortex_a8_restore_context(target_t *target)
873 {
874 int i;
875 uint32_t value;
876
877 /* get pointers to arch-specific information */
878 armv4_5_common_t *armv4_5 = target->arch_info;
879 armv7a_common_t *armv7a = armv4_5->arch_info;
880
881 LOG_DEBUG(" ");
882
883 if (armv7a->pre_restore_context)
884 armv7a->pre_restore_context(target);
885
886 for (i = 15; i >= 0; i--)
887 {
888 if (ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
889 armv4_5->core_mode, i).dirty)
890 {
891 value = buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
892 armv4_5->core_mode, i).value,
893 0, 32);
894 /* TODO Check return values */
895 cortex_a8_dap_write_coreregister_u32(target, value, i);
896 }
897 }
898
899 if (armv7a->post_restore_context)
900 armv7a->post_restore_context(target);
901
902 return ERROR_OK;
903 }
904
905
906 /*
907 * Cortex-A8 Core register functions
908 */
909
910 int cortex_a8_load_core_reg_u32(struct target_s *target, int num,
911 armv4_5_mode_t mode, uint32_t * value)
912 {
913 int retval;
914 /* get pointers to arch-specific information */
915 armv4_5_common_t *armv4_5 = target->arch_info;
916
917 if ((num <= ARM_CPSR))
918 {
919 /* read a normal core register */
920 retval = cortex_a8_dap_read_coreregister_u32(target, value, num);
921
922 if (retval != ERROR_OK)
923 {
924 LOG_ERROR("JTAG failure %i", retval);
925 return ERROR_JTAG_DEVICE_ERROR;
926 }
927 LOG_DEBUG("load from core reg %i value 0x%" PRIx32, num, *value);
928 }
929 else
930 {
931 return ERROR_INVALID_ARGUMENTS;
932 }
933
934 /* Register other than r0 - r14 uses r0 for access */
935 if (num > 14)
936 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
937 armv4_5->core_mode, 0).dirty =
938 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
939 armv4_5->core_mode, 0).valid;
940 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
941 armv4_5->core_mode, 15).dirty =
942 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
943 armv4_5->core_mode, 15).valid;
944
945 return ERROR_OK;
946 }
947
948 int cortex_a8_store_core_reg_u32(struct target_s *target, int num,
949 armv4_5_mode_t mode, uint32_t value)
950 {
951 int retval;
952 // uint32_t reg;
953
954 /* get pointers to arch-specific information */
955 armv4_5_common_t *armv4_5 = target->arch_info;
956
957 #ifdef ARMV7_GDB_HACKS
958 /* If the LR register is being modified, make sure it will put us
959 * in "thumb" mode, or an INVSTATE exception will occur. This is a
960 * hack to deal with the fact that gdb will sometimes "forge"
961 * return addresses, and doesn't set the LSB correctly (i.e., when
962 * printing expressions containing function calls, it sets LR=0.) */
963
964 if (num == 14)
965 value |= 0x01;
966 #endif
967
968 if ((num <= ARM_CPSR))
969 {
970 retval = cortex_a8_dap_write_coreregister_u32(target, value, num);
971 if (retval != ERROR_OK)
972 {
973 LOG_ERROR("JTAG failure %i", retval);
974 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
975 armv4_5->core_mode, num).dirty =
976 ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
977 armv4_5->core_mode, num).valid;
978 return ERROR_JTAG_DEVICE_ERROR;
979 }
980 LOG_DEBUG("write core reg %i value 0x%" PRIx32, num, value);
981 }
982 else
983 {
984 return ERROR_INVALID_ARGUMENTS;
985 }
986
987 return ERROR_OK;
988 }
989
990
991 int cortex_a8_read_core_reg(struct target_s *target, int num,
992 enum armv4_5_mode mode)
993 {
994 uint32_t value;
995 int retval;
996 armv4_5_common_t *armv4_5 = target->arch_info;
997 cortex_a8_dap_read_coreregister_u32(target, &value, num);
998
999 if ((retval = jtag_execute_queue()) != ERROR_OK)
1000 {
1001 return retval;
1002 }
1003
1004 ARMV7A_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
1005 ARMV7A_CORE_REG_MODE(armv4_5->core_cache, mode, num).dirty = 0;
1006 buf_set_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
1007 mode, num).value, 0, 32, value);
1008
1009 return ERROR_OK;
1010 }
1011
1012 int cortex_a8_write_core_reg(struct target_s *target, int num,
1013 enum armv4_5_mode mode, uint32_t value)
1014 {
1015 int retval;
1016 armv4_5_common_t *armv4_5 = target->arch_info;
1017
1018 cortex_a8_dap_write_coreregister_u32(target, value, num);
1019 if ((retval = jtag_execute_queue()) != ERROR_OK)
1020 {
1021 return retval;
1022 }
1023
1024 ARMV7A_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
1025 ARMV7A_CORE_REG_MODE(armv4_5->core_cache, mode, num).dirty = 0;
1026
1027 return ERROR_OK;
1028 }
1029
1030
1031 /*
1032 * Cortex-A8 Breakpoint and watchpoint fuctions
1033 */
1034
1035 /* Setup hardware Breakpoint Register Pair */
1036 int cortex_a8_set_breakpoint(struct target_s *target,
1037 breakpoint_t *breakpoint, uint8_t matchmode)
1038 {
1039 int retval;
1040 int brp_i=0;
1041 uint32_t control;
1042 uint8_t byte_addr_select = 0x0F;
1043
1044
1045 /* get pointers to arch-specific information */
1046 armv4_5_common_t *armv4_5 = target->arch_info;
1047 armv7a_common_t *armv7a = armv4_5->arch_info;
1048 cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
1049 cortex_a8_brp_t * brp_list = cortex_a8->brp_list;
1050
1051 if (breakpoint->set)
1052 {
1053 LOG_WARNING("breakpoint already set");
1054 return ERROR_OK;
1055 }
1056
1057 if (breakpoint->type == BKPT_HARD)
1058 {
1059 while (brp_list[brp_i].used && (brp_i < cortex_a8->brp_num))
1060 brp_i++ ;
1061 if (brp_i >= cortex_a8->brp_num)
1062 {
1063 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1064 exit(-1);
1065 }
1066 breakpoint->set = brp_i + 1;
1067 if (breakpoint->length == 2)
1068 {
1069 byte_addr_select = (3 << (breakpoint->address & 0x02));
1070 }
1071 control = ((matchmode & 0x7) << 20)
1072 | (byte_addr_select << 5)
1073 | (3 << 1) | 1;
1074 brp_list[brp_i].used = 1;
1075 brp_list[brp_i].value = (breakpoint->address & 0xFFFFFFFC);
1076 brp_list[brp_i].control = control;
1077 cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
1078 + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn,
1079 brp_list[brp_i].value);
1080 cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
1081 + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn,
1082 brp_list[brp_i].control);
1083 LOG_DEBUG("brp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_i,
1084 brp_list[brp_i].control,
1085 brp_list[brp_i].value);
1086 }
1087 else if (breakpoint->type == BKPT_SOFT)
1088 {
1089 uint8_t code[4];
1090 if (breakpoint->length == 2)
1091 {
1092 buf_set_u32(code, 0, 32, ARMV5_T_BKPT(0x11));
1093 }
1094 else
1095 {
1096 buf_set_u32(code, 0, 32, ARMV5_BKPT(0x11));
1097 }
1098 retval = target->type->read_memory(target,
1099 breakpoint->address & 0xFFFFFFFE,
1100 breakpoint->length, 1,
1101 breakpoint->orig_instr);
1102 if (retval != ERROR_OK)
1103 return retval;
1104 retval = target->type->write_memory(target,
1105 breakpoint->address & 0xFFFFFFFE,
1106 breakpoint->length, 1, code);
1107 if (retval != ERROR_OK)
1108 return retval;
1109 breakpoint->set = 0x11; /* Any nice value but 0 */
1110 }
1111
1112 return ERROR_OK;
1113 }
1114
1115 int cortex_a8_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
1116 {
1117 int retval;
1118 /* get pointers to arch-specific information */
1119 armv4_5_common_t *armv4_5 = target->arch_info;
1120 armv7a_common_t *armv7a = armv4_5->arch_info;
1121 cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
1122 cortex_a8_brp_t * brp_list = cortex_a8->brp_list;
1123
1124 if (!breakpoint->set)
1125 {
1126 LOG_WARNING("breakpoint not set");
1127 return ERROR_OK;
1128 }
1129
1130 if (breakpoint->type == BKPT_HARD)
1131 {
1132 int brp_i = breakpoint->set - 1;
1133 if ((brp_i < 0) || (brp_i >= cortex_a8->brp_num))
1134 {
1135 LOG_DEBUG("Invalid BRP number in breakpoint");
1136 return ERROR_OK;
1137 }
1138 LOG_DEBUG("rbp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_i,
1139 brp_list[brp_i].control, brp_list[brp_i].value);
1140 brp_list[brp_i].used = 0;
1141 brp_list[brp_i].value = 0;
1142 brp_list[brp_i].control = 0;
1143 cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
1144 + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn,
1145 brp_list[brp_i].control);
1146 cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
1147 + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn,
1148 brp_list[brp_i].value);
1149 }
1150 else
1151 {
1152 /* restore original instruction (kept in target endianness) */
1153 if (breakpoint->length == 4)
1154 {
1155 retval = target->type->write_memory(target,
1156 breakpoint->address & 0xFFFFFFFE,
1157 4, 1, breakpoint->orig_instr);
1158 if (retval != ERROR_OK)
1159 return retval;
1160 }
1161 else
1162 {
1163 retval = target->type->write_memory(target,
1164 breakpoint->address & 0xFFFFFFFE,
1165 2, 1, breakpoint->orig_instr);
1166 if (retval != ERROR_OK)
1167 return retval;
1168 }
1169 }
1170 breakpoint->set = 0;
1171
1172 return ERROR_OK;
1173 }
1174
1175 int cortex_a8_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
1176 {
1177 /* get pointers to arch-specific information */
1178 armv4_5_common_t *armv4_5 = target->arch_info;
1179 armv7a_common_t *armv7a = armv4_5->arch_info;
1180 cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
1181
1182 if ((breakpoint->type == BKPT_HARD) && (cortex_a8->brp_num_available < 1))
1183 {
1184 LOG_INFO("no hardware breakpoint available");
1185 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1186 }
1187
1188 if (breakpoint->type == BKPT_HARD)
1189 cortex_a8->brp_num_available--;
1190 cortex_a8_set_breakpoint(target, breakpoint, 0x00); /* Exact match */
1191
1192 return ERROR_OK;
1193 }
1194
1195 int cortex_a8_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
1196 {
1197 /* get pointers to arch-specific information */
1198 armv4_5_common_t *armv4_5 = target->arch_info;
1199 armv7a_common_t *armv7a = armv4_5->arch_info;
1200 cortex_a8_common_t *cortex_a8 = armv7a->arch_info;
1201
1202 #if 0
1203 /* It is perfectly possible to remove brakpoints while the taget is running */
1204 if (target->state != TARGET_HALTED)
1205 {
1206 LOG_WARNING("target not halted");
1207 return ERROR_TARGET_NOT_HALTED;
1208 }
1209 #endif
1210
1211 if (breakpoint->set)
1212 {
1213 cortex_a8_unset_breakpoint(target, breakpoint);
1214 if (breakpoint->type == BKPT_HARD)
1215 cortex_a8->brp_num_available++ ;
1216 }
1217
1218
1219 return ERROR_OK;
1220 }
1221
1222
1223
1224 /*
1225 * Cortex-A8 Reset fuctions
1226 */
1227
1228 int cortex_a8_assert_reset(target_t *target)
1229 {
1230
1231 LOG_DEBUG(" ");
1232
1233 /* registers are now invalid */
1234 armv4_5_invalidate_core_regs(target);
1235
1236 target->state = TARGET_RESET;
1237
1238 return ERROR_OK;
1239 }
1240
1241 int cortex_a8_deassert_reset(target_t *target)
1242 {
1243
1244 LOG_DEBUG(" ");
1245
1246 if (target->reset_halt)
1247 {
1248 int retval;
1249 if ((retval = target_halt(target)) != ERROR_OK)
1250 return retval;
1251 }
1252
1253 return ERROR_OK;
1254 }
1255
1256 /*
1257 * Cortex-A8 Memory access
1258 *
1259 * This is same Cortex M3 but we must also use the correct
1260 * ap number for every access.
1261 */
1262
1263 int cortex_a8_read_memory(struct target_s *target, uint32_t address,
1264 uint32_t size, uint32_t count, uint8_t *buffer)
1265 {
1266 /* get pointers to arch-specific information */
1267 armv4_5_common_t *armv4_5 = target->arch_info;
1268 armv7a_common_t *armv7a = armv4_5->arch_info;
1269 swjdp_common_t *swjdp = &armv7a->swjdp_info;
1270
1271 int retval = ERROR_OK;
1272
1273 /* sanitize arguments */
1274 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1275 return ERROR_INVALID_ARGUMENTS;
1276
1277 /* cortex_a8 handles unaligned memory access */
1278
1279 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1280
1281 switch (size)
1282 {
1283 case 4:
1284 retval = mem_ap_read_buf_u32(swjdp, buffer, 4 * count, address);
1285 break;
1286 case 2:
1287 retval = mem_ap_read_buf_u16(swjdp, buffer, 2 * count, address);
1288 break;
1289 case 1:
1290 retval = mem_ap_read_buf_u8(swjdp, buffer, count, address);
1291 break;
1292 default:
1293 LOG_ERROR("BUG: we shouldn't get here");
1294 exit(-1);
1295 }
1296
1297 return retval;
1298 }
1299
1300 int cortex_a8_write_memory(struct target_s *target, uint32_t address,
1301 uint32_t size, uint32_t count, uint8_t *buffer)
1302 {
1303 /* get pointers to arch-specific information */
1304 armv4_5_common_t *armv4_5 = target->arch_info;
1305 armv7a_common_t *armv7a = armv4_5->arch_info;
1306 swjdp_common_t *swjdp = &armv7a->swjdp_info;
1307
1308 int retval;
1309
1310 /* sanitize arguments */
1311 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1312 return ERROR_INVALID_ARGUMENTS;
1313
1314 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1315
1316 switch (size)
1317 {
1318 case 4:
1319 retval = mem_ap_write_buf_u32(swjdp, buffer, 4 * count, address);
1320 break;
1321 case 2:
1322 retval = mem_ap_write_buf_u16(swjdp, buffer, 2 * count, address);
1323 break;
1324 case 1:
1325 retval = mem_ap_write_buf_u8(swjdp, buffer, count, address);
1326 break;
1327 default:
1328 LOG_ERROR("BUG: we shouldn't get here");
1329 exit(-1);
1330 }
1331
1332 if (target->state == TARGET_HALTED)
1333 {
1334 /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */
1335 /* invalidate I-Cache */
1336 if (armv7a->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
1337 {
1338 /* Invalidate ICache single entry with MVA, repeat this for all cache
1339 lines in the address range, Cortex-A8 has fixed 64 byte line length */
1340 /* Invalidate Cache single entry with MVA to PoU */
1341 for (uint32_t cacheline=address; cacheline<address+size*count; cacheline+=64)
1342 armv7a->write_cp15(target, 0, 1, 7, 5, cacheline); /* I-Cache to PoU */
1343 }
1344 /* invalidate D-Cache */
1345 if (armv7a->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled)
1346 {
1347 /* Invalidate Cache single entry with MVA to PoC */
1348 for (uint32_t cacheline=address; cacheline<address+size*count; cacheline+=64)
1349 armv7a->write_cp15(target, 0, 1, 7, 6, cacheline); /* U/D cache to PoC */
1350 }
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->post_debug_entry = cortex_a8_post_debug_entry;
1587
1588 armv7a->pre_restore_context = NULL;
1589 armv7a->post_restore_context = NULL;
1590 armv7a->armv4_5_mmu.armv4_5_cache.ctype = -1;
1591 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1592 armv7a->armv4_5_mmu.read_memory = cortex_a8_read_memory;
1593 armv7a->armv4_5_mmu.write_memory = cortex_a8_write_memory;
1594 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1595 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1596 armv7a->armv4_5_mmu.has_tiny_pages = 1;
1597 armv7a->armv4_5_mmu.mmu_enabled = 0;
1598 armv7a->read_cp15 = cortex_a8_read_cp15;
1599 armv7a->write_cp15 = cortex_a8_write_cp15;
1600
1601
1602 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1603
1604 armv4_5->read_core_reg = cortex_a8_read_core_reg;
1605 armv4_5->write_core_reg = cortex_a8_write_core_reg;
1606 // armv4_5->full_context = arm7_9_full_context;
1607
1608 // armv4_5->load_core_reg_u32 = cortex_a8_load_core_reg_u32;
1609 // armv4_5->store_core_reg_u32 = cortex_a8_store_core_reg_u32;
1610 // armv4_5->read_core_reg = armv4_5_read_core_reg; /* this is default */
1611 // armv4_5->write_core_reg = armv4_5_write_core_reg;
1612
1613 target_register_timer_callback(cortex_a8_handle_target_request, 1, 1, target);
1614
1615 return ERROR_OK;
1616 }
1617
1618 int cortex_a8_target_create(struct target_s *target, Jim_Interp *interp)
1619 {
1620 cortex_a8_common_t *cortex_a8 = calloc(1, sizeof(cortex_a8_common_t));
1621
1622 cortex_a8_init_arch_info(target, cortex_a8, target->tap);
1623
1624 return ERROR_OK;
1625 }
1626
1627 static int cortex_a8_handle_cache_info_command(struct command_context_s *cmd_ctx,
1628 char *cmd, char **args, int argc)
1629 {
1630 target_t *target = get_current_target(cmd_ctx);
1631 armv4_5_common_t *armv4_5 = target->arch_info;
1632 armv7a_common_t *armv7a = armv4_5->arch_info;
1633
1634 return armv4_5_handle_cache_info_command(cmd_ctx,
1635 &armv7a->armv4_5_mmu.armv4_5_cache);
1636 }
1637
1638
1639 static int cortex_a8_handle_dbginit_command(struct command_context_s *cmd_ctx,
1640 char *cmd, char **args, int argc)
1641 {
1642 target_t *target = get_current_target(cmd_ctx);
1643
1644 cortex_a8_init_debug_access(target);
1645
1646 return ERROR_OK;
1647 }
1648
1649
1650 int cortex_a8_register_commands(struct command_context_s *cmd_ctx)
1651 {
1652 command_t *cortex_a8_cmd;
1653 int retval = ERROR_OK;
1654
1655 armv4_5_register_commands(cmd_ctx);
1656 armv7a_register_commands(cmd_ctx);
1657
1658 cortex_a8_cmd = register_command(cmd_ctx, NULL, "cortex_a8",
1659 NULL, COMMAND_ANY,
1660 "cortex_a8 specific commands");
1661
1662 register_command(cmd_ctx, cortex_a8_cmd, "cache_info",
1663 cortex_a8_handle_cache_info_command, COMMAND_EXEC,
1664 "display information about target caches");
1665
1666 register_command(cmd_ctx, cortex_a8_cmd, "dbginit",
1667 cortex_a8_handle_dbginit_command, COMMAND_EXEC,
1668 "Initialize core debug");
1669
1670 return retval;
1671 }

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)