ARM: define two register utilities
[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 arm_set_cpsr(armv4_5, cpsr);
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 for (i = 0; i <= ARM_PC; i++)
678 {
679 reg = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
680 armv4_5->core_mode, i);
681
682 buf_set_u32(reg->value, 0, 32, regfile[i]);
683 reg->valid = 1;
684 reg->dirty = 0;
685 }
686
687 /* Fixup PC Resume Address */
688 if (cpsr & (1 << 5))
689 {
690 // T bit set for Thumb or ThumbEE state
691 regfile[ARM_PC] -= 4;
692 }
693 else
694 {
695 // ARM state
696 regfile[ARM_PC] -= 8;
697 }
698 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
699 armv4_5->core_mode, ARM_PC).value,
700 0, 32, regfile[ARM_PC]);
701
702 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0)
703 .dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
704 armv4_5->core_mode, 0).valid;
705 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 15)
706 .dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
707 armv4_5->core_mode, 15).valid;
708
709 #if 0
710 /* TODO, Move this */
711 uint32_t cp15_control_register, cp15_cacr, cp15_nacr;
712 cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
713 LOG_DEBUG("cp15_control_register = 0x%08x", cp15_control_register);
714
715 cortex_a8_read_cp(target, &cp15_cacr, 15, 0, 1, 0, 2);
716 LOG_DEBUG("cp15 Coprocessor Access Control Register = 0x%08x", cp15_cacr);
717
718 cortex_a8_read_cp(target, &cp15_nacr, 15, 0, 1, 1, 2);
719 LOG_DEBUG("cp15 Nonsecure Access Control Register = 0x%08x", cp15_nacr);
720 #endif
721
722 /* Are we in an exception handler */
723 // armv4_5->exception_number = 0;
724 if (armv7a->post_debug_entry)
725 armv7a->post_debug_entry(target);
726
727
728
729 return retval;
730
731 }
732
733 static void cortex_a8_post_debug_entry(struct target *target)
734 {
735 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
736 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
737
738 // cortex_a8_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);
739 /* examine cp15 control reg */
740 armv7a->read_cp15(target, 0, 0, 1, 0, &cortex_a8->cp15_control_reg);
741 jtag_execute_queue();
742 LOG_DEBUG("cp15_control_reg: %8.8" PRIx32, cortex_a8->cp15_control_reg);
743
744 if (armv7a->armv4_5_mmu.armv4_5_cache.ctype == -1)
745 {
746 uint32_t cache_type_reg;
747 /* identify caches */
748 armv7a->read_cp15(target, 0, 1, 0, 0, &cache_type_reg);
749 jtag_execute_queue();
750 /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */
751 armv4_5_identify_cache(cache_type_reg,
752 &armv7a->armv4_5_mmu.armv4_5_cache);
753 }
754
755 armv7a->armv4_5_mmu.mmu_enabled =
756 (cortex_a8->cp15_control_reg & 0x1U) ? 1 : 0;
757 armv7a->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled =
758 (cortex_a8->cp15_control_reg & 0x4U) ? 1 : 0;
759 armv7a->armv4_5_mmu.armv4_5_cache.i_cache_enabled =
760 (cortex_a8->cp15_control_reg & 0x1000U) ? 1 : 0;
761
762
763 }
764
765 static int cortex_a8_step(struct target *target, int current, uint32_t address,
766 int handle_breakpoints)
767 {
768 struct armv7a_common *armv7a = target_to_armv7a(target);
769 struct armv4_5_common_s *armv4_5 = &armv7a->armv4_5_common;
770 struct breakpoint *breakpoint = NULL;
771 struct breakpoint stepbreakpoint;
772
773 int timeout = 100;
774
775 if (target->state != TARGET_HALTED)
776 {
777 LOG_WARNING("target not halted");
778 return ERROR_TARGET_NOT_HALTED;
779 }
780
781 /* current = 1: continue on current pc, otherwise continue at <address> */
782 if (!current)
783 {
784 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
785 armv4_5->core_mode, ARM_PC).value,
786 0, 32, address);
787 }
788 else
789 {
790 address = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
791 armv4_5->core_mode, ARM_PC).value,
792 0, 32);
793 }
794
795 /* The front-end may request us not to handle breakpoints.
796 * But since Cortex-A8 uses breakpoint for single step,
797 * we MUST handle breakpoints.
798 */
799 handle_breakpoints = 1;
800 if (handle_breakpoints) {
801 breakpoint = breakpoint_find(target,
802 buf_get_u32(ARMV4_5_CORE_REG_MODE(
803 armv4_5->core_cache,
804 armv4_5->core_mode, 15).value,
805 0, 32));
806 if (breakpoint)
807 cortex_a8_unset_breakpoint(target, breakpoint);
808 }
809
810 /* Setup single step breakpoint */
811 stepbreakpoint.address = address;
812 stepbreakpoint.length = (armv4_5->core_state == ARMV4_5_STATE_THUMB)
813 ? 2 : 4;
814 stepbreakpoint.type = BKPT_HARD;
815 stepbreakpoint.set = 0;
816
817 /* Break on IVA mismatch */
818 cortex_a8_set_breakpoint(target, &stepbreakpoint, 0x04);
819
820 target->debug_reason = DBG_REASON_SINGLESTEP;
821
822 cortex_a8_resume(target, 1, address, 0, 0);
823
824 while (target->state != TARGET_HALTED)
825 {
826 cortex_a8_poll(target);
827 if (--timeout == 0)
828 {
829 LOG_WARNING("timeout waiting for target halt");
830 break;
831 }
832 }
833
834 cortex_a8_unset_breakpoint(target, &stepbreakpoint);
835 if (timeout > 0) target->debug_reason = DBG_REASON_BREAKPOINT;
836
837 if (breakpoint)
838 cortex_a8_set_breakpoint(target, breakpoint, 0);
839
840 if (target->state != TARGET_HALTED)
841 LOG_DEBUG("target stepped");
842
843 return ERROR_OK;
844 }
845
846 static int cortex_a8_restore_context(struct target *target)
847 {
848 uint32_t value;
849 struct armv7a_common *armv7a = target_to_armv7a(target);
850 struct reg_cache *cache = armv7a->armv4_5_common.core_cache;
851 unsigned max = cache->num_regs;
852 struct reg *r;
853 bool flushed, flush_cpsr = false;
854
855 LOG_DEBUG(" ");
856
857 if (armv7a->pre_restore_context)
858 armv7a->pre_restore_context(target);
859
860 /* Flush all dirty registers from the cache, one mode at a time so
861 * that we write CPSR as little as possible. Save CPSR and R0 for
862 * last; they're used to change modes and write other registers.
863 *
864 * REVISIT be smarter: save eventual mode for last loop, don't
865 * need to write CPSR an extra time.
866 */
867 do {
868 enum armv4_5_mode mode = ARMV4_5_MODE_ANY;
869 unsigned i;
870
871 flushed = false;
872
873 /* write dirty non-{R0,CPSR} registers sharing the same mode */
874 for (i = max - 1, r = cache->reg_list + 1; i > 0; i--, r++) {
875 struct arm_reg *reg;
876
877 if (!r->dirty || r == armv7a->armv4_5_common.cpsr)
878 continue;
879 reg = r->arch_info;
880
881 /* TODO Check return values */
882
883 /* Pick a mode and update CPSR; else ignore this
884 * register if it's for a different mode than what
885 * we're handling on this pass.
886 *
887 * REVISIT don't distinguish SYS and USR modes.
888 *
889 * FIXME if we restore from FIQ mode, R8..R12 will
890 * get wrongly flushed onto FIQ shadows...
891 */
892 if (mode == ARMV4_5_MODE_ANY) {
893 mode = reg->mode;
894 if (mode != ARMV4_5_MODE_ANY) {
895 cortex_a8_dap_write_coreregister_u32(
896 target, mode, 16);
897 flush_cpsr = true;
898 }
899 } else if (mode != reg->mode)
900 continue;
901
902 /* Write this register */
903 value = buf_get_u32(r->value, 0, 32);
904 cortex_a8_dap_write_coreregister_u32(target, value,
905 (reg->num == 16) ? 17 : reg->num);
906 r->dirty = false;
907 flushed = true;
908 }
909
910 } while (flushed);
911
912 /* now flush CPSR if needed ... */
913 r = armv7a->armv4_5_common.cpsr;
914 if (flush_cpsr || r->dirty) {
915 value = buf_get_u32(r->value, 0, 32);
916 cortex_a8_dap_write_coreregister_u32(target, value, 16);
917 r->dirty = false;
918 }
919
920 /* ... and R0 always (it was dirtied when we saved context) */
921 r = cache->reg_list + 0;
922 value = buf_get_u32(r->value, 0, 32);
923 cortex_a8_dap_write_coreregister_u32(target, value, 0);
924 r->dirty = false;
925
926 if (armv7a->post_restore_context)
927 armv7a->post_restore_context(target);
928
929 return ERROR_OK;
930 }
931
932
933 #if 0
934 /*
935 * Cortex-A8 Core register functions
936 */
937 static int cortex_a8_load_core_reg_u32(struct target *target, int num,
938 armv4_5_mode_t mode, uint32_t * value)
939 {
940 int retval;
941 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
942
943 if ((num <= ARM_CPSR))
944 {
945 /* read a normal core register */
946 retval = cortex_a8_dap_read_coreregister_u32(target, value, num);
947
948 if (retval != ERROR_OK)
949 {
950 LOG_ERROR("JTAG failure %i", retval);
951 return ERROR_JTAG_DEVICE_ERROR;
952 }
953 LOG_DEBUG("load from core reg %i value 0x%" PRIx32, num, *value);
954 }
955 else
956 {
957 return ERROR_INVALID_ARGUMENTS;
958 }
959
960 /* Register other than r0 - r14 uses r0 for access */
961 if (num > 14)
962 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
963 armv4_5->core_mode, 0).dirty =
964 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
965 armv4_5->core_mode, 0).valid;
966 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
967 armv4_5->core_mode, 15).dirty =
968 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
969 armv4_5->core_mode, 15).valid;
970
971 return ERROR_OK;
972 }
973
974 static int cortex_a8_store_core_reg_u32(struct target *target, int num,
975 armv4_5_mode_t mode, uint32_t value)
976 {
977 int retval;
978 // uint32_t reg;
979 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
980
981 #ifdef ARMV7_GDB_HACKS
982 /* If the LR register is being modified, make sure it will put us
983 * in "thumb" mode, or an INVSTATE exception will occur. This is a
984 * hack to deal with the fact that gdb will sometimes "forge"
985 * return addresses, and doesn't set the LSB correctly (i.e., when
986 * printing expressions containing function calls, it sets LR=0.) */
987
988 if (num == 14)
989 value |= 0x01;
990 #endif
991
992 if ((num <= ARM_CPSR))
993 {
994 retval = cortex_a8_dap_write_coreregister_u32(target, value, num);
995 if (retval != ERROR_OK)
996 {
997 LOG_ERROR("JTAG failure %i", retval);
998 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
999 armv4_5->core_mode, num).dirty =
1000 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
1001 armv4_5->core_mode, num).valid;
1002 return ERROR_JTAG_DEVICE_ERROR;
1003 }
1004 LOG_DEBUG("write core reg %i value 0x%" PRIx32, num, value);
1005 }
1006 else
1007 {
1008 return ERROR_INVALID_ARGUMENTS;
1009 }
1010
1011 return ERROR_OK;
1012 }
1013 #endif
1014
1015
1016 static int cortex_a8_write_core_reg(struct target *target, struct reg *r,
1017 int num, enum armv4_5_mode mode, uint32_t value);
1018
1019 static int cortex_a8_read_core_reg(struct target *target, struct reg *r,
1020 int num, enum armv4_5_mode mode)
1021 {
1022 uint32_t value;
1023 int retval;
1024 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
1025 struct reg *cpsr_r = NULL;
1026 uint32_t cpsr = 0;
1027 unsigned cookie = num;
1028
1029 /* avoid some needless mode changes
1030 * FIXME move some of these to shared ARM code...
1031 */
1032 if (mode != armv4_5->core_mode) {
1033 if ((armv4_5->core_mode == ARMV4_5_MODE_SYS)
1034 && (mode == ARMV4_5_MODE_USR))
1035 mode = ARMV4_5_MODE_ANY;
1036 else if ((mode != ARMV4_5_MODE_FIQ) && (num <= 12))
1037 mode = ARMV4_5_MODE_ANY;
1038
1039 if (mode != ARMV4_5_MODE_ANY) {
1040 cpsr_r = armv4_5->cpsr;
1041 cpsr = buf_get_u32(cpsr_r->value, 0, 32);
1042 cortex_a8_write_core_reg(target, cpsr_r,
1043 16, ARMV4_5_MODE_ANY, mode);
1044 }
1045 }
1046
1047 if (num == 16) {
1048 switch (mode) {
1049 case ARMV4_5_MODE_USR:
1050 case ARMV4_5_MODE_SYS:
1051 case ARMV4_5_MODE_ANY:
1052 /* CPSR */
1053 break;
1054 default:
1055 /* SPSR */
1056 cookie++;
1057 break;
1058 }
1059 }
1060
1061 cortex_a8_dap_read_coreregister_u32(target, &value, cookie);
1062 retval = jtag_execute_queue();
1063 if (retval == ERROR_OK) {
1064 r->valid = 1;
1065 r->dirty = 0;
1066 buf_set_u32(r->value, 0, 32, value);
1067 }
1068
1069 if (cpsr_r)
1070 cortex_a8_write_core_reg(target, cpsr_r,
1071 16, ARMV4_5_MODE_ANY, cpsr);
1072 return retval;
1073 }
1074
1075 static int cortex_a8_write_core_reg(struct target *target, struct reg *r,
1076 int num, enum armv4_5_mode mode, uint32_t value)
1077 {
1078 int retval;
1079 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
1080 struct reg *cpsr_r = NULL;
1081 uint32_t cpsr = 0;
1082 unsigned cookie = num;
1083
1084 /* avoid some needless mode changes
1085 * FIXME move some of these to shared ARM code...
1086 */
1087 if (mode != armv4_5->core_mode) {
1088 if ((armv4_5->core_mode == ARMV4_5_MODE_SYS)
1089 && (mode == ARMV4_5_MODE_USR))
1090 mode = ARMV4_5_MODE_ANY;
1091 else if ((mode != ARMV4_5_MODE_FIQ) && (num <= 12))
1092 mode = ARMV4_5_MODE_ANY;
1093
1094 if (mode != ARMV4_5_MODE_ANY) {
1095 cpsr_r = armv4_5->cpsr;
1096 cpsr = buf_get_u32(cpsr_r->value, 0, 32);
1097 cortex_a8_write_core_reg(target, cpsr_r,
1098 16, ARMV4_5_MODE_ANY, mode);
1099 }
1100 }
1101
1102
1103 if (num == 16) {
1104 switch (mode) {
1105 case ARMV4_5_MODE_USR:
1106 case ARMV4_5_MODE_SYS:
1107 case ARMV4_5_MODE_ANY:
1108 /* CPSR */
1109 break;
1110 default:
1111 /* SPSR */
1112 cookie++;
1113 break;
1114 }
1115 }
1116
1117 cortex_a8_dap_write_coreregister_u32(target, value, cookie);
1118 if ((retval = jtag_execute_queue()) == ERROR_OK) {
1119 buf_set_u32(r->value, 0, 32, value);
1120 r->valid = 1;
1121 r->dirty = 0;
1122 }
1123
1124 if (cpsr_r)
1125 cortex_a8_write_core_reg(target, cpsr_r,
1126 16, ARMV4_5_MODE_ANY, cpsr);
1127 return retval;
1128 }
1129
1130
1131 /*
1132 * Cortex-A8 Breakpoint and watchpoint fuctions
1133 */
1134
1135 /* Setup hardware Breakpoint Register Pair */
1136 static int cortex_a8_set_breakpoint(struct target *target,
1137 struct breakpoint *breakpoint, uint8_t matchmode)
1138 {
1139 int retval;
1140 int brp_i=0;
1141 uint32_t control;
1142 uint8_t byte_addr_select = 0x0F;
1143 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
1144 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
1145 struct cortex_a8_brp * brp_list = cortex_a8->brp_list;
1146
1147 if (breakpoint->set)
1148 {
1149 LOG_WARNING("breakpoint already set");
1150 return ERROR_OK;
1151 }
1152
1153 if (breakpoint->type == BKPT_HARD)
1154 {
1155 while (brp_list[brp_i].used && (brp_i < cortex_a8->brp_num))
1156 brp_i++ ;
1157 if (brp_i >= cortex_a8->brp_num)
1158 {
1159 LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
1160 return ERROR_FAIL;
1161 }
1162 breakpoint->set = brp_i + 1;
1163 if (breakpoint->length == 2)
1164 {
1165 byte_addr_select = (3 << (breakpoint->address & 0x02));
1166 }
1167 control = ((matchmode & 0x7) << 20)
1168 | (byte_addr_select << 5)
1169 | (3 << 1) | 1;
1170 brp_list[brp_i].used = 1;
1171 brp_list[brp_i].value = (breakpoint->address & 0xFFFFFFFC);
1172 brp_list[brp_i].control = control;
1173 cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
1174 + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn,
1175 brp_list[brp_i].value);
1176 cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
1177 + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn,
1178 brp_list[brp_i].control);
1179 LOG_DEBUG("brp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_i,
1180 brp_list[brp_i].control,
1181 brp_list[brp_i].value);
1182 }
1183 else if (breakpoint->type == BKPT_SOFT)
1184 {
1185 uint8_t code[4];
1186 if (breakpoint->length == 2)
1187 {
1188 buf_set_u32(code, 0, 32, ARMV5_T_BKPT(0x11));
1189 }
1190 else
1191 {
1192 buf_set_u32(code, 0, 32, ARMV5_BKPT(0x11));
1193 }
1194 retval = target->type->read_memory(target,
1195 breakpoint->address & 0xFFFFFFFE,
1196 breakpoint->length, 1,
1197 breakpoint->orig_instr);
1198 if (retval != ERROR_OK)
1199 return retval;
1200 retval = target->type->write_memory(target,
1201 breakpoint->address & 0xFFFFFFFE,
1202 breakpoint->length, 1, code);
1203 if (retval != ERROR_OK)
1204 return retval;
1205 breakpoint->set = 0x11; /* Any nice value but 0 */
1206 }
1207
1208 return ERROR_OK;
1209 }
1210
1211 static int cortex_a8_unset_breakpoint(struct target *target, struct breakpoint *breakpoint)
1212 {
1213 int retval;
1214 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
1215 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
1216 struct cortex_a8_brp * brp_list = cortex_a8->brp_list;
1217
1218 if (!breakpoint->set)
1219 {
1220 LOG_WARNING("breakpoint not set");
1221 return ERROR_OK;
1222 }
1223
1224 if (breakpoint->type == BKPT_HARD)
1225 {
1226 int brp_i = breakpoint->set - 1;
1227 if ((brp_i < 0) || (brp_i >= cortex_a8->brp_num))
1228 {
1229 LOG_DEBUG("Invalid BRP number in breakpoint");
1230 return ERROR_OK;
1231 }
1232 LOG_DEBUG("rbp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_i,
1233 brp_list[brp_i].control, brp_list[brp_i].value);
1234 brp_list[brp_i].used = 0;
1235 brp_list[brp_i].value = 0;
1236 brp_list[brp_i].control = 0;
1237 cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
1238 + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].BRPn,
1239 brp_list[brp_i].control);
1240 cortex_a8_dap_write_memap_register_u32(target, armv7a->debug_base
1241 + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].BRPn,
1242 brp_list[brp_i].value);
1243 }
1244 else
1245 {
1246 /* restore original instruction (kept in target endianness) */
1247 if (breakpoint->length == 4)
1248 {
1249 retval = target->type->write_memory(target,
1250 breakpoint->address & 0xFFFFFFFE,
1251 4, 1, breakpoint->orig_instr);
1252 if (retval != ERROR_OK)
1253 return retval;
1254 }
1255 else
1256 {
1257 retval = target->type->write_memory(target,
1258 breakpoint->address & 0xFFFFFFFE,
1259 2, 1, breakpoint->orig_instr);
1260 if (retval != ERROR_OK)
1261 return retval;
1262 }
1263 }
1264 breakpoint->set = 0;
1265
1266 return ERROR_OK;
1267 }
1268
1269 int cortex_a8_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
1270 {
1271 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
1272
1273 if ((breakpoint->type == BKPT_HARD) && (cortex_a8->brp_num_available < 1))
1274 {
1275 LOG_INFO("no hardware breakpoint available");
1276 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1277 }
1278
1279 if (breakpoint->type == BKPT_HARD)
1280 cortex_a8->brp_num_available--;
1281 cortex_a8_set_breakpoint(target, breakpoint, 0x00); /* Exact match */
1282
1283 return ERROR_OK;
1284 }
1285
1286 static int cortex_a8_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)
1287 {
1288 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
1289
1290 #if 0
1291 /* It is perfectly possible to remove brakpoints while the taget is running */
1292 if (target->state != TARGET_HALTED)
1293 {
1294 LOG_WARNING("target not halted");
1295 return ERROR_TARGET_NOT_HALTED;
1296 }
1297 #endif
1298
1299 if (breakpoint->set)
1300 {
1301 cortex_a8_unset_breakpoint(target, breakpoint);
1302 if (breakpoint->type == BKPT_HARD)
1303 cortex_a8->brp_num_available++ ;
1304 }
1305
1306
1307 return ERROR_OK;
1308 }
1309
1310
1311
1312 /*
1313 * Cortex-A8 Reset fuctions
1314 */
1315
1316 static int cortex_a8_assert_reset(struct target *target)
1317 {
1318 struct armv7a_common *armv7a = target_to_armv7a(target);
1319
1320 LOG_DEBUG(" ");
1321
1322 /* registers are now invalid */
1323 register_cache_invalidate(armv7a->armv4_5_common.core_cache);
1324
1325 target->state = TARGET_RESET;
1326
1327 return ERROR_OK;
1328 }
1329
1330 static int cortex_a8_deassert_reset(struct target *target)
1331 {
1332
1333 LOG_DEBUG(" ");
1334
1335 if (target->reset_halt)
1336 {
1337 int retval;
1338 if ((retval = target_halt(target)) != ERROR_OK)
1339 return retval;
1340 }
1341
1342 return ERROR_OK;
1343 }
1344
1345 /*
1346 * Cortex-A8 Memory access
1347 *
1348 * This is same Cortex M3 but we must also use the correct
1349 * ap number for every access.
1350 */
1351
1352 static int cortex_a8_read_memory(struct target *target, uint32_t address,
1353 uint32_t size, uint32_t count, uint8_t *buffer)
1354 {
1355 struct armv7a_common *armv7a = target_to_armv7a(target);
1356 struct swjdp_common *swjdp = &armv7a->swjdp_info;
1357 int retval = ERROR_INVALID_ARGUMENTS;
1358
1359 /* cortex_a8 handles unaligned memory access */
1360
1361 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1362
1363 if (count && buffer) {
1364 switch (size) {
1365 case 4:
1366 retval = mem_ap_read_buf_u32(swjdp, buffer, 4 * count, address);
1367 break;
1368 case 2:
1369 retval = mem_ap_read_buf_u16(swjdp, buffer, 2 * count, address);
1370 break;
1371 case 1:
1372 retval = mem_ap_read_buf_u8(swjdp, buffer, count, address);
1373 break;
1374 }
1375 }
1376
1377 return retval;
1378 }
1379
1380 int cortex_a8_write_memory(struct target *target, uint32_t address,
1381 uint32_t size, uint32_t count, uint8_t *buffer)
1382 {
1383 struct armv7a_common *armv7a = target_to_armv7a(target);
1384 struct swjdp_common *swjdp = &armv7a->swjdp_info;
1385 int retval = ERROR_INVALID_ARGUMENTS;
1386
1387 // ??? dap_ap_select(swjdp, swjdp_memoryap);
1388
1389 if (count && buffer) {
1390 switch (size) {
1391 case 4:
1392 retval = mem_ap_write_buf_u32(swjdp, buffer, 4 * count, address);
1393 break;
1394 case 2:
1395 retval = mem_ap_write_buf_u16(swjdp, buffer, 2 * count, address);
1396 break;
1397 case 1:
1398 retval = mem_ap_write_buf_u8(swjdp, buffer, count, address);
1399 break;
1400 }
1401 }
1402
1403 if (retval == ERROR_OK && target->state == TARGET_HALTED)
1404 {
1405 /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */
1406 /* invalidate I-Cache */
1407 if (armv7a->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
1408 {
1409 /* Invalidate ICache single entry with MVA, repeat this for all cache
1410 lines in the address range, Cortex-A8 has fixed 64 byte line length */
1411 /* Invalidate Cache single entry with MVA to PoU */
1412 for (uint32_t cacheline=address; cacheline<address+size*count; cacheline+=64)
1413 armv7a->write_cp15(target, 0, 1, 7, 5, cacheline); /* I-Cache to PoU */
1414 }
1415 /* invalidate D-Cache */
1416 if (armv7a->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled)
1417 {
1418 /* Invalidate Cache single entry with MVA to PoC */
1419 for (uint32_t cacheline=address; cacheline<address+size*count; cacheline+=64)
1420 armv7a->write_cp15(target, 0, 1, 7, 6, cacheline); /* U/D cache to PoC */
1421 }
1422 }
1423
1424 return retval;
1425 }
1426
1427 static int cortex_a8_bulk_write_memory(struct target *target, uint32_t address,
1428 uint32_t count, uint8_t *buffer)
1429 {
1430 return cortex_a8_write_memory(target, address, 4, count, buffer);
1431 }
1432
1433
1434 static int cortex_a8_dcc_read(struct swjdp_common *swjdp, uint8_t *value, uint8_t *ctrl)
1435 {
1436 #if 0
1437 u16 dcrdr;
1438
1439 mem_ap_read_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
1440 *ctrl = (uint8_t)dcrdr;
1441 *value = (uint8_t)(dcrdr >> 8);
1442
1443 LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
1444
1445 /* write ack back to software dcc register
1446 * signify we have read data */
1447 if (dcrdr & (1 << 0))
1448 {
1449 dcrdr = 0;
1450 mem_ap_write_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
1451 }
1452 #endif
1453 return ERROR_OK;
1454 }
1455
1456
1457 static int cortex_a8_handle_target_request(void *priv)
1458 {
1459 struct target *target = priv;
1460 struct armv7a_common *armv7a = target_to_armv7a(target);
1461 struct swjdp_common *swjdp = &armv7a->swjdp_info;
1462
1463 if (!target_was_examined(target))
1464 return ERROR_OK;
1465 if (!target->dbg_msg_enabled)
1466 return ERROR_OK;
1467
1468 if (target->state == TARGET_RUNNING)
1469 {
1470 uint8_t data = 0;
1471 uint8_t ctrl = 0;
1472
1473 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1474
1475 /* check if we have data */
1476 if (ctrl & (1 << 0))
1477 {
1478 uint32_t request;
1479
1480 /* we assume target is quick enough */
1481 request = data;
1482 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1483 request |= (data << 8);
1484 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1485 request |= (data << 16);
1486 cortex_a8_dcc_read(swjdp, &data, &ctrl);
1487 request |= (data << 24);
1488 target_request(target, request);
1489 }
1490 }
1491
1492 return ERROR_OK;
1493 }
1494
1495 /*
1496 * Cortex-A8 target information and configuration
1497 */
1498
1499 static int cortex_a8_examine_first(struct target *target)
1500 {
1501 struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target);
1502 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
1503 struct swjdp_common *swjdp = &armv7a->swjdp_info;
1504 int i;
1505 int retval = ERROR_OK;
1506 uint32_t didr, ctypr, ttypr, cpuid;
1507
1508 LOG_DEBUG("TODO");
1509
1510 /* Here we shall insert a proper ROM Table scan */
1511 armv7a->debug_base = OMAP3530_DEBUG_BASE;
1512
1513 /* We do one extra read to ensure DAP is configured,
1514 * we call ahbap_debugport_init(swjdp) instead
1515 */
1516 ahbap_debugport_init(swjdp);
1517 mem_ap_read_atomic_u32(swjdp, armv7a->debug_base + CPUDBG_CPUID, &cpuid);
1518 if ((retval = mem_ap_read_atomic_u32(swjdp,
1519 armv7a->debug_base + CPUDBG_CPUID, &cpuid)) != ERROR_OK)
1520 {
1521 LOG_DEBUG("Examine failed");
1522 return retval;
1523 }
1524
1525 if ((retval = mem_ap_read_atomic_u32(swjdp,
1526 armv7a->debug_base + CPUDBG_CTYPR, &ctypr)) != 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_TTYPR, &ttypr)) != 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_DIDR, &didr)) != ERROR_OK)
1541 {
1542 LOG_DEBUG("Examine failed");
1543 return retval;
1544 }
1545
1546 LOG_DEBUG("cpuid = 0x%08" PRIx32, cpuid);
1547 LOG_DEBUG("ctypr = 0x%08" PRIx32, ctypr);
1548 LOG_DEBUG("ttypr = 0x%08" PRIx32, ttypr);
1549 LOG_DEBUG("didr = 0x%08" PRIx32, didr);
1550
1551 /* Setup Breakpoint Register Pairs */
1552 cortex_a8->brp_num = ((didr >> 24) & 0x0F) + 1;
1553 cortex_a8->brp_num_context = ((didr >> 20) & 0x0F) + 1;
1554 cortex_a8->brp_num_available = cortex_a8->brp_num;
1555 cortex_a8->brp_list = calloc(cortex_a8->brp_num, sizeof(struct cortex_a8_brp));
1556 // cortex_a8->brb_enabled = ????;
1557 for (i = 0; i < cortex_a8->brp_num; i++)
1558 {
1559 cortex_a8->brp_list[i].used = 0;
1560 if (i < (cortex_a8->brp_num-cortex_a8->brp_num_context))
1561 cortex_a8->brp_list[i].type = BRP_NORMAL;
1562 else
1563 cortex_a8->brp_list[i].type = BRP_CONTEXT;
1564 cortex_a8->brp_list[i].value = 0;
1565 cortex_a8->brp_list[i].control = 0;
1566 cortex_a8->brp_list[i].BRPn = i;
1567 }
1568
1569 /* Setup Watchpoint Register Pairs */
1570 cortex_a8->wrp_num = ((didr >> 28) & 0x0F) + 1;
1571 cortex_a8->wrp_num_available = cortex_a8->wrp_num;
1572 cortex_a8->wrp_list = calloc(cortex_a8->wrp_num, sizeof(struct cortex_a8_wrp));
1573 for (i = 0; i < cortex_a8->wrp_num; i++)
1574 {
1575 cortex_a8->wrp_list[i].used = 0;
1576 cortex_a8->wrp_list[i].type = 0;
1577 cortex_a8->wrp_list[i].value = 0;
1578 cortex_a8->wrp_list[i].control = 0;
1579 cortex_a8->wrp_list[i].WRPn = i;
1580 }
1581 LOG_DEBUG("Configured %i hw breakpoint pairs and %i hw watchpoint pairs",
1582 cortex_a8->brp_num , cortex_a8->wrp_num);
1583
1584 target_set_examined(target);
1585 return ERROR_OK;
1586 }
1587
1588 static int cortex_a8_examine(struct target *target)
1589 {
1590 int retval = ERROR_OK;
1591
1592 /* don't re-probe hardware after each reset */
1593 if (!target_was_examined(target))
1594 retval = cortex_a8_examine_first(target);
1595
1596 /* Configure core debug access */
1597 if (retval == ERROR_OK)
1598 retval = cortex_a8_init_debug_access(target);
1599
1600 return retval;
1601 }
1602
1603 /*
1604 * Cortex-A8 target creation and initialization
1605 */
1606
1607 static void cortex_a8_build_reg_cache(struct target *target)
1608 {
1609 struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
1610 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
1611
1612 armv4_5->core_type = ARM_MODE_MON;
1613
1614 (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
1615 }
1616
1617
1618 static int cortex_a8_init_target(struct command_context *cmd_ctx,
1619 struct target *target)
1620 {
1621 cortex_a8_build_reg_cache(target);
1622 return ERROR_OK;
1623 }
1624
1625 int cortex_a8_init_arch_info(struct target *target,
1626 struct cortex_a8_common *cortex_a8, struct jtag_tap *tap)
1627 {
1628 struct armv7a_common *armv7a = &cortex_a8->armv7a_common;
1629 struct arm *armv4_5 = &armv7a->armv4_5_common;
1630 struct swjdp_common *swjdp = &armv7a->swjdp_info;
1631
1632 /* Setup struct cortex_a8_common */
1633 cortex_a8->common_magic = CORTEX_A8_COMMON_MAGIC;
1634 armv4_5->arch_info = armv7a;
1635
1636 /* prepare JTAG information for the new target */
1637 cortex_a8->jtag_info.tap = tap;
1638 cortex_a8->jtag_info.scann_size = 4;
1639 LOG_DEBUG(" ");
1640 swjdp->dp_select_value = -1;
1641 swjdp->ap_csw_value = -1;
1642 swjdp->ap_tar_value = -1;
1643 swjdp->jtag_info = &cortex_a8->jtag_info;
1644 swjdp->memaccess_tck = 80;
1645
1646 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
1647 swjdp->tar_autoincr_block = (1 << 10);
1648
1649 cortex_a8->fast_reg_read = 0;
1650
1651
1652 /* register arch-specific functions */
1653 armv7a->examine_debug_reason = NULL;
1654
1655 armv7a->post_debug_entry = cortex_a8_post_debug_entry;
1656
1657 armv7a->pre_restore_context = NULL;
1658 armv7a->post_restore_context = NULL;
1659 armv7a->armv4_5_mmu.armv4_5_cache.ctype = -1;
1660 // armv7a->armv4_5_mmu.get_ttb = armv7a_get_ttb;
1661 armv7a->armv4_5_mmu.read_memory = cortex_a8_read_memory;
1662 armv7a->armv4_5_mmu.write_memory = cortex_a8_write_memory;
1663 // armv7a->armv4_5_mmu.disable_mmu_caches = armv7a_disable_mmu_caches;
1664 // armv7a->armv4_5_mmu.enable_mmu_caches = armv7a_enable_mmu_caches;
1665 armv7a->armv4_5_mmu.has_tiny_pages = 1;
1666 armv7a->armv4_5_mmu.mmu_enabled = 0;
1667 armv7a->read_cp15 = cortex_a8_read_cp15;
1668 armv7a->write_cp15 = cortex_a8_write_cp15;
1669
1670
1671 // arm7_9->handle_target_request = cortex_a8_handle_target_request;
1672
1673 armv4_5->read_core_reg = cortex_a8_read_core_reg;
1674 armv4_5->write_core_reg = cortex_a8_write_core_reg;
1675
1676 /* REVISIT v7a setup should be in a v7a-specific routine */
1677 armv4_5_init_arch_info(target, armv4_5);
1678 armv7a->common_magic = ARMV7_COMMON_MAGIC;
1679
1680 target_register_timer_callback(cortex_a8_handle_target_request, 1, 1, target);
1681
1682 return ERROR_OK;
1683 }
1684
1685 static int cortex_a8_target_create(struct target *target, Jim_Interp *interp)
1686 {
1687 struct cortex_a8_common *cortex_a8 = calloc(1, sizeof(struct cortex_a8_common));
1688
1689 cortex_a8_init_arch_info(target, cortex_a8, target->tap);
1690
1691 return ERROR_OK;
1692 }
1693
1694 COMMAND_HANDLER(cortex_a8_handle_cache_info_command)
1695 {
1696 struct target *target = get_current_target(CMD_CTX);
1697 struct armv7a_common *armv7a = target_to_armv7a(target);
1698
1699 return armv4_5_handle_cache_info_command(CMD_CTX,
1700 &armv7a->armv4_5_mmu.armv4_5_cache);
1701 }
1702
1703
1704 COMMAND_HANDLER(cortex_a8_handle_dbginit_command)
1705 {
1706 struct target *target = get_current_target(CMD_CTX);
1707
1708 cortex_a8_init_debug_access(target);
1709
1710 return ERROR_OK;
1711 }
1712
1713
1714 static int cortex_a8_register_commands(struct command_context *cmd_ctx)
1715 {
1716 struct command *cortex_a8_cmd;
1717 int retval = ERROR_OK;
1718
1719 armv4_5_register_commands(cmd_ctx);
1720 armv7a_register_commands(cmd_ctx);
1721
1722 cortex_a8_cmd = register_command(cmd_ctx, NULL, "cortex_a8",
1723 NULL, COMMAND_ANY,
1724 "cortex_a8 specific commands");
1725
1726 register_command(cmd_ctx, cortex_a8_cmd, "cache_info",
1727 cortex_a8_handle_cache_info_command, COMMAND_EXEC,
1728 "display information about target caches");
1729
1730 register_command(cmd_ctx, cortex_a8_cmd, "dbginit",
1731 cortex_a8_handle_dbginit_command, COMMAND_EXEC,
1732 "Initialize core debug");
1733
1734 return retval;
1735 }
1736
1737 struct target_type cortexa8_target = {
1738 .name = "cortex_a8",
1739
1740 .poll = cortex_a8_poll,
1741 .arch_state = armv7a_arch_state,
1742
1743 .target_request_data = NULL,
1744
1745 .halt = cortex_a8_halt,
1746 .resume = cortex_a8_resume,
1747 .step = cortex_a8_step,
1748
1749 .assert_reset = cortex_a8_assert_reset,
1750 .deassert_reset = cortex_a8_deassert_reset,
1751 .soft_reset_halt = NULL,
1752
1753 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
1754
1755 .read_memory = cortex_a8_read_memory,
1756 .write_memory = cortex_a8_write_memory,
1757 .bulk_write_memory = cortex_a8_bulk_write_memory,
1758
1759 .checksum_memory = arm_checksum_memory,
1760 .blank_check_memory = arm_blank_check_memory,
1761
1762 .run_algorithm = armv4_5_run_algorithm,
1763
1764 .add_breakpoint = cortex_a8_add_breakpoint,
1765 .remove_breakpoint = cortex_a8_remove_breakpoint,
1766 .add_watchpoint = NULL,
1767 .remove_watchpoint = NULL,
1768
1769 .register_commands = cortex_a8_register_commands,
1770 .target_create = cortex_a8_target_create,
1771 .init_target = cortex_a8_init_target,
1772 .examine = cortex_a8_examine,
1773 .mrc = cortex_a8_mrc,
1774 .mcr = cortex_a8_mcr,
1775 };

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)