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

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)