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

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)