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

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)