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

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)