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

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)