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

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)