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

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)