xscale: stackframe corruption bugfix
[openocd.git] / src / target / xscale.c
1 /***************************************************************************
2 * Copyright (C) 2006, 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2007,2008 Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
7 * *
8 * Copyright (C) 2009 Michael Schwingen *
9 * michael@schwingen.org *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
20 * *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 ***************************************************************************/
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "xscale.h"
31 #include "target_type.h"
32 #include "arm7_9_common.h"
33 #include "arm_simulator.h"
34 #include "arm_disassembler.h"
35 #include "time_support.h"
36 #include "image.h"
37
38
39 /*
40 * Important XScale documents available as of October 2009 include:
41 *
42 * Intel XScale® Core Developer’s Manual, January 2004
43 * Order Number: 273473-002
44 * This has a chapter detailing debug facilities, and punts some
45 * details to chip-specific microarchitecture documents.
46 *
47 * Hot-Debug for Intel XScale® Core Debug White Paper, May 2005
48 * Document Number: 273539-005
49 * Less detailed than the developer's manual, but summarizes those
50 * missing details (for most XScales) and gives LOTS of notes about
51 * debugger/handler interaction issues. Presents a simpler reset
52 * and load-handler sequence than the arch doc. (Note, OpenOCD
53 * doesn't currently support "Hot-Debug" as defined there.)
54 *
55 * Chip-specific microarchitecture documents may also be useful.
56 */
57
58
59 /* forward declarations */
60 static int xscale_resume(struct target_s *, int current,
61 uint32_t address, int handle_breakpoints, int debug_execution);
62 static int xscale_debug_entry(target_t *);
63 static int xscale_restore_context(target_t *);
64 static int xscale_get_reg(reg_t *reg);
65 static int xscale_set_reg(reg_t *reg, uint8_t *buf);
66 static int xscale_set_breakpoint(struct target_s *, breakpoint_t *);
67 static int xscale_set_watchpoint(struct target_s *, watchpoint_t *);
68 static int xscale_unset_breakpoint(struct target_s *, breakpoint_t *);
69 static int xscale_read_trace(target_t *);
70
71
72 static char *const xscale_reg_list[] =
73 {
74 "XSCALE_MAINID", /* 0 */
75 "XSCALE_CACHETYPE",
76 "XSCALE_CTRL",
77 "XSCALE_AUXCTRL",
78 "XSCALE_TTB",
79 "XSCALE_DAC",
80 "XSCALE_FSR",
81 "XSCALE_FAR",
82 "XSCALE_PID",
83 "XSCALE_CPACCESS",
84 "XSCALE_IBCR0", /* 10 */
85 "XSCALE_IBCR1",
86 "XSCALE_DBR0",
87 "XSCALE_DBR1",
88 "XSCALE_DBCON",
89 "XSCALE_TBREG",
90 "XSCALE_CHKPT0",
91 "XSCALE_CHKPT1",
92 "XSCALE_DCSR",
93 "XSCALE_TX",
94 "XSCALE_RX", /* 20 */
95 "XSCALE_TXRXCTRL",
96 };
97
98 static const xscale_reg_t xscale_reg_arch_info[] =
99 {
100 {XSCALE_MAINID, NULL},
101 {XSCALE_CACHETYPE, NULL},
102 {XSCALE_CTRL, NULL},
103 {XSCALE_AUXCTRL, NULL},
104 {XSCALE_TTB, NULL},
105 {XSCALE_DAC, NULL},
106 {XSCALE_FSR, NULL},
107 {XSCALE_FAR, NULL},
108 {XSCALE_PID, NULL},
109 {XSCALE_CPACCESS, NULL},
110 {XSCALE_IBCR0, NULL},
111 {XSCALE_IBCR1, NULL},
112 {XSCALE_DBR0, NULL},
113 {XSCALE_DBR1, NULL},
114 {XSCALE_DBCON, NULL},
115 {XSCALE_TBREG, NULL},
116 {XSCALE_CHKPT0, NULL},
117 {XSCALE_CHKPT1, NULL},
118 {XSCALE_DCSR, NULL}, /* DCSR accessed via JTAG or SW */
119 {-1, NULL}, /* TX accessed via JTAG */
120 {-1, NULL}, /* RX accessed via JTAG */
121 {-1, NULL}, /* TXRXCTRL implicit access via JTAG */
122 };
123
124 static int xscale_reg_arch_type = -1;
125
126 /* convenience wrapper to access XScale specific registers */
127 static int xscale_set_reg_u32(reg_t *reg, uint32_t value)
128 {
129 uint8_t buf[4];
130
131 buf_set_u32(buf, 0, 32, value);
132
133 return xscale_set_reg(reg, buf);
134 }
135
136
137 static int xscale_get_arch_pointers(target_t *target,
138 armv4_5_common_t **armv4_5_p, xscale_common_t **xscale_p)
139 {
140 armv4_5_common_t *armv4_5 = target->arch_info;
141 xscale_common_t *xscale = armv4_5->arch_info;
142
143 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
144 {
145 LOG_ERROR("target isn't an XScale target");
146 return -1;
147 }
148
149 if (xscale->common_magic != XSCALE_COMMON_MAGIC)
150 {
151 LOG_ERROR("target isn't an XScale target");
152 return -1;
153 }
154
155 *armv4_5_p = armv4_5;
156 *xscale_p = xscale;
157
158 return ERROR_OK;
159 }
160
161 static int xscale_jtag_set_instr(jtag_tap_t *tap, uint32_t new_instr)
162 {
163 if (tap == NULL)
164 return ERROR_FAIL;
165
166 if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr)
167 {
168 scan_field_t field;
169 uint8_t scratch[4];
170
171 memset(&field, 0, sizeof field);
172 field.tap = tap;
173 field.num_bits = tap->ir_length;
174 field.out_value = scratch;
175 buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
176
177 jtag_add_ir_scan(1, &field, jtag_get_end_state());
178 }
179
180 return ERROR_OK;
181 }
182
183 static int xscale_read_dcsr(target_t *target)
184 {
185 armv4_5_common_t *armv4_5 = target->arch_info;
186 xscale_common_t *xscale = armv4_5->arch_info;
187 int retval;
188 scan_field_t fields[3];
189 uint8_t field0 = 0x0;
190 uint8_t field0_check_value = 0x2;
191 uint8_t field0_check_mask = 0x7;
192 uint8_t field2 = 0x0;
193 uint8_t field2_check_value = 0x0;
194 uint8_t field2_check_mask = 0x1;
195
196 jtag_set_end_state(TAP_DRPAUSE);
197 xscale_jtag_set_instr(target->tap, XSCALE_SELDCSR);
198
199 buf_set_u32(&field0, 1, 1, xscale->hold_rst);
200 buf_set_u32(&field0, 2, 1, xscale->external_debug_break);
201
202 memset(&fields, 0, sizeof fields);
203
204 fields[0].tap = target->tap;
205 fields[0].num_bits = 3;
206 fields[0].out_value = &field0;
207 uint8_t tmp;
208 fields[0].in_value = &tmp;
209
210 fields[1].tap = target->tap;
211 fields[1].num_bits = 32;
212 fields[1].in_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value;
213
214 fields[2].tap = target->tap;
215 fields[2].num_bits = 1;
216 fields[2].out_value = &field2;
217 uint8_t tmp2;
218 fields[2].in_value = &tmp2;
219
220 jtag_add_dr_scan(3, fields, jtag_get_end_state());
221
222 jtag_check_value_mask(fields + 0, &field0_check_value, &field0_check_mask);
223 jtag_check_value_mask(fields + 2, &field2_check_value, &field2_check_mask);
224
225 if ((retval = jtag_execute_queue()) != ERROR_OK)
226 {
227 LOG_ERROR("JTAG error while reading DCSR");
228 return retval;
229 }
230
231 xscale->reg_cache->reg_list[XSCALE_DCSR].dirty = 0;
232 xscale->reg_cache->reg_list[XSCALE_DCSR].valid = 1;
233
234 /* write the register with the value we just read
235 * on this second pass, only the first bit of field0 is guaranteed to be 0)
236 */
237 field0_check_mask = 0x1;
238 fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value;
239 fields[1].in_value = NULL;
240
241 jtag_set_end_state(TAP_IDLE);
242
243 jtag_add_dr_scan(3, fields, jtag_get_end_state());
244
245 /* DANGER!!! this must be here. It will make sure that the arguments
246 * to jtag_set_check_value() does not go out of scope! */
247 return jtag_execute_queue();
248 }
249
250
251 static void xscale_getbuf(jtag_callback_data_t arg)
252 {
253 uint8_t *in = (uint8_t *)arg;
254 *((uint32_t *)in) = buf_get_u32(in, 0, 32);
255 }
256
257 static int xscale_receive(target_t *target, uint32_t *buffer, int num_words)
258 {
259 if (num_words == 0)
260 return ERROR_INVALID_ARGUMENTS;
261
262 int retval = ERROR_OK;
263 tap_state_t path[3];
264 scan_field_t fields[3];
265 uint8_t *field0 = malloc(num_words * 1);
266 uint8_t field0_check_value = 0x2;
267 uint8_t field0_check_mask = 0x6;
268 uint32_t *field1 = malloc(num_words * 4);
269 uint8_t field2_check_value = 0x0;
270 uint8_t field2_check_mask = 0x1;
271 int words_done = 0;
272 int words_scheduled = 0;
273 int i;
274
275 path[0] = TAP_DRSELECT;
276 path[1] = TAP_DRCAPTURE;
277 path[2] = TAP_DRSHIFT;
278
279 memset(&fields, 0, sizeof fields);
280
281 fields[0].tap = target->tap;
282 fields[0].num_bits = 3;
283 fields[0].check_value = &field0_check_value;
284 fields[0].check_mask = &field0_check_mask;
285
286 fields[1].tap = target->tap;
287 fields[1].num_bits = 32;
288
289 fields[2].tap = target->tap;
290 fields[2].num_bits = 1;
291 fields[2].check_value = &field2_check_value;
292 fields[2].check_mask = &field2_check_mask;
293
294 jtag_set_end_state(TAP_IDLE);
295 xscale_jtag_set_instr(target->tap, XSCALE_DBGTX);
296 jtag_add_runtest(1, jtag_get_end_state()); /* ensures that we're in the TAP_IDLE state as the above could be a no-op */
297
298 /* repeat until all words have been collected */
299 int attempts = 0;
300 while (words_done < num_words)
301 {
302 /* schedule reads */
303 words_scheduled = 0;
304 for (i = words_done; i < num_words; i++)
305 {
306 fields[0].in_value = &field0[i];
307
308 jtag_add_pathmove(3, path);
309
310 fields[1].in_value = (uint8_t *)(field1 + i);
311
312 jtag_add_dr_scan_check(3, fields, jtag_set_end_state(TAP_IDLE));
313
314 jtag_add_callback(xscale_getbuf, (jtag_callback_data_t)(field1 + i));
315
316 words_scheduled++;
317 }
318
319 if ((retval = jtag_execute_queue()) != ERROR_OK)
320 {
321 LOG_ERROR("JTAG error while receiving data from debug handler");
322 break;
323 }
324
325 /* examine results */
326 for (i = words_done; i < num_words; i++)
327 {
328 if (!(field0[0] & 1))
329 {
330 /* move backwards if necessary */
331 int j;
332 for (j = i; j < num_words - 1; j++)
333 {
334 field0[j] = field0[j + 1];
335 field1[j] = field1[j + 1];
336 }
337 words_scheduled--;
338 }
339 }
340 if (words_scheduled == 0)
341 {
342 if (attempts++==1000)
343 {
344 LOG_ERROR("Failed to receiving data from debug handler after 1000 attempts");
345 retval = ERROR_TARGET_TIMEOUT;
346 break;
347 }
348 }
349
350 words_done += words_scheduled;
351 }
352
353 for (i = 0; i < num_words; i++)
354 *(buffer++) = buf_get_u32((uint8_t*)&field1[i], 0, 32);
355
356 free(field1);
357
358 return retval;
359 }
360
361 static int xscale_read_tx(target_t *target, int consume)
362 {
363 armv4_5_common_t *armv4_5 = target->arch_info;
364 xscale_common_t *xscale = armv4_5->arch_info;
365 tap_state_t path[3];
366 tap_state_t noconsume_path[6];
367 int retval;
368 struct timeval timeout, now;
369 scan_field_t fields[3];
370 uint8_t field0_in = 0x0;
371 uint8_t field0_check_value = 0x2;
372 uint8_t field0_check_mask = 0x6;
373 uint8_t field2_check_value = 0x0;
374 uint8_t field2_check_mask = 0x1;
375
376 jtag_set_end_state(TAP_IDLE);
377
378 xscale_jtag_set_instr(target->tap, XSCALE_DBGTX);
379
380 path[0] = TAP_DRSELECT;
381 path[1] = TAP_DRCAPTURE;
382 path[2] = TAP_DRSHIFT;
383
384 noconsume_path[0] = TAP_DRSELECT;
385 noconsume_path[1] = TAP_DRCAPTURE;
386 noconsume_path[2] = TAP_DREXIT1;
387 noconsume_path[3] = TAP_DRPAUSE;
388 noconsume_path[4] = TAP_DREXIT2;
389 noconsume_path[5] = TAP_DRSHIFT;
390
391 memset(&fields, 0, sizeof fields);
392
393 fields[0].tap = target->tap;
394 fields[0].num_bits = 3;
395 fields[0].in_value = &field0_in;
396
397 fields[1].tap = target->tap;
398 fields[1].num_bits = 32;
399 fields[1].in_value = xscale->reg_cache->reg_list[XSCALE_TX].value;
400
401 fields[2].tap = target->tap;
402 fields[2].num_bits = 1;
403 uint8_t tmp;
404 fields[2].in_value = &tmp;
405
406 gettimeofday(&timeout, NULL);
407 timeval_add_time(&timeout, 1, 0);
408
409 for (;;)
410 {
411 /* if we want to consume the register content (i.e. clear TX_READY),
412 * we have to go straight from Capture-DR to Shift-DR
413 * otherwise, we go from Capture-DR to Exit1-DR to Pause-DR
414 */
415 if (consume)
416 jtag_add_pathmove(3, path);
417 else
418 {
419 jtag_add_pathmove(sizeof(noconsume_path)/sizeof(*noconsume_path), noconsume_path);
420 }
421
422 jtag_add_dr_scan(3, fields, jtag_set_end_state(TAP_IDLE));
423
424 jtag_check_value_mask(fields + 0, &field0_check_value, &field0_check_mask);
425 jtag_check_value_mask(fields + 2, &field2_check_value, &field2_check_mask);
426
427 if ((retval = jtag_execute_queue()) != ERROR_OK)
428 {
429 LOG_ERROR("JTAG error while reading TX");
430 return ERROR_TARGET_TIMEOUT;
431 }
432
433 gettimeofday(&now, NULL);
434 if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec)&& (now.tv_usec > timeout.tv_usec)))
435 {
436 LOG_ERROR("time out reading TX register");
437 return ERROR_TARGET_TIMEOUT;
438 }
439 if (!((!(field0_in & 1)) && consume))
440 {
441 goto done;
442 }
443 if (debug_level >= 3)
444 {
445 LOG_DEBUG("waiting 100ms");
446 alive_sleep(100); /* avoid flooding the logs */
447 } else
448 {
449 keep_alive();
450 }
451 }
452 done:
453
454 if (!(field0_in & 1))
455 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
456
457 return ERROR_OK;
458 }
459
460 static int xscale_write_rx(target_t *target)
461 {
462 armv4_5_common_t *armv4_5 = target->arch_info;
463 xscale_common_t *xscale = armv4_5->arch_info;
464 int retval;
465 struct timeval timeout, now;
466 scan_field_t fields[3];
467 uint8_t field0_out = 0x0;
468 uint8_t field0_in = 0x0;
469 uint8_t field0_check_value = 0x2;
470 uint8_t field0_check_mask = 0x6;
471 uint8_t field2 = 0x0;
472 uint8_t field2_check_value = 0x0;
473 uint8_t field2_check_mask = 0x1;
474
475 jtag_set_end_state(TAP_IDLE);
476
477 xscale_jtag_set_instr(target->tap, XSCALE_DBGRX);
478
479 memset(&fields, 0, sizeof fields);
480
481 fields[0].tap = target->tap;
482 fields[0].num_bits = 3;
483 fields[0].out_value = &field0_out;
484 fields[0].in_value = &field0_in;
485
486 fields[1].tap = target->tap;
487 fields[1].num_bits = 32;
488 fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_RX].value;
489
490 fields[2].tap = target->tap;
491 fields[2].num_bits = 1;
492 fields[2].out_value = &field2;
493 uint8_t tmp;
494 fields[2].in_value = &tmp;
495
496 gettimeofday(&timeout, NULL);
497 timeval_add_time(&timeout, 1, 0);
498
499 /* poll until rx_read is low */
500 LOG_DEBUG("polling RX");
501 for (;;)
502 {
503 jtag_add_dr_scan(3, fields, jtag_set_end_state(TAP_IDLE));
504
505 jtag_check_value_mask(fields + 0, &field0_check_value, &field0_check_mask);
506 jtag_check_value_mask(fields + 2, &field2_check_value, &field2_check_mask);
507
508 if ((retval = jtag_execute_queue()) != ERROR_OK)
509 {
510 LOG_ERROR("JTAG error while writing RX");
511 return retval;
512 }
513
514 gettimeofday(&now, NULL);
515 if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec)&& (now.tv_usec > timeout.tv_usec)))
516 {
517 LOG_ERROR("time out writing RX register");
518 return ERROR_TARGET_TIMEOUT;
519 }
520 if (!(field0_in & 1))
521 goto done;
522 if (debug_level >= 3)
523 {
524 LOG_DEBUG("waiting 100ms");
525 alive_sleep(100); /* avoid flooding the logs */
526 } else
527 {
528 keep_alive();
529 }
530 }
531 done:
532
533 /* set rx_valid */
534 field2 = 0x1;
535 jtag_add_dr_scan(3, fields, jtag_set_end_state(TAP_IDLE));
536
537 if ((retval = jtag_execute_queue()) != ERROR_OK)
538 {
539 LOG_ERROR("JTAG error while writing RX");
540 return retval;
541 }
542
543 return ERROR_OK;
544 }
545
546 /* send count elements of size byte to the debug handler */
547 static int xscale_send(target_t *target, uint8_t *buffer, int count, int size)
548 {
549 uint32_t t[3];
550 int bits[3];
551 int retval;
552 int done_count = 0;
553
554 jtag_set_end_state(TAP_IDLE);
555
556 xscale_jtag_set_instr(target->tap, XSCALE_DBGRX);
557
558 bits[0]=3;
559 t[0]=0;
560 bits[1]=32;
561 t[2]=1;
562 bits[2]=1;
563 int endianness = target->endianness;
564 while (done_count++ < count)
565 {
566 switch (size)
567 {
568 case 4:
569 if (endianness == TARGET_LITTLE_ENDIAN)
570 {
571 t[1]=le_to_h_u32(buffer);
572 } else
573 {
574 t[1]=be_to_h_u32(buffer);
575 }
576 break;
577 case 2:
578 if (endianness == TARGET_LITTLE_ENDIAN)
579 {
580 t[1]=le_to_h_u16(buffer);
581 } else
582 {
583 t[1]=be_to_h_u16(buffer);
584 }
585 break;
586 case 1:
587 t[1]=buffer[0];
588 break;
589 default:
590 LOG_ERROR("BUG: size neither 4, 2 nor 1");
591 exit(-1);
592 }
593 jtag_add_dr_out(target->tap,
594 3,
595 bits,
596 t,
597 jtag_set_end_state(TAP_IDLE));
598 buffer += size;
599 }
600
601 if ((retval = jtag_execute_queue()) != ERROR_OK)
602 {
603 LOG_ERROR("JTAG error while sending data to debug handler");
604 return retval;
605 }
606
607 return ERROR_OK;
608 }
609
610 static int xscale_send_u32(target_t *target, uint32_t value)
611 {
612 armv4_5_common_t *armv4_5 = target->arch_info;
613 xscale_common_t *xscale = armv4_5->arch_info;
614
615 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_RX].value, 0, 32, value);
616 return xscale_write_rx(target);
617 }
618
619 static int xscale_write_dcsr(target_t *target, int hold_rst, int ext_dbg_brk)
620 {
621 armv4_5_common_t *armv4_5 = target->arch_info;
622 xscale_common_t *xscale = armv4_5->arch_info;
623 int retval;
624 scan_field_t fields[3];
625 uint8_t field0 = 0x0;
626 uint8_t field0_check_value = 0x2;
627 uint8_t field0_check_mask = 0x7;
628 uint8_t field2 = 0x0;
629 uint8_t field2_check_value = 0x0;
630 uint8_t field2_check_mask = 0x1;
631
632 if (hold_rst != -1)
633 xscale->hold_rst = hold_rst;
634
635 if (ext_dbg_brk != -1)
636 xscale->external_debug_break = ext_dbg_brk;
637
638 jtag_set_end_state(TAP_IDLE);
639 xscale_jtag_set_instr(target->tap, XSCALE_SELDCSR);
640
641 buf_set_u32(&field0, 1, 1, xscale->hold_rst);
642 buf_set_u32(&field0, 2, 1, xscale->external_debug_break);
643
644 memset(&fields, 0, sizeof fields);
645
646 fields[0].tap = target->tap;
647 fields[0].num_bits = 3;
648 fields[0].out_value = &field0;
649 uint8_t tmp;
650 fields[0].in_value = &tmp;
651
652 fields[1].tap = target->tap;
653 fields[1].num_bits = 32;
654 fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value;
655
656 fields[2].tap = target->tap;
657 fields[2].num_bits = 1;
658 fields[2].out_value = &field2;
659 uint8_t tmp2;
660 fields[2].in_value = &tmp2;
661
662 jtag_add_dr_scan(3, fields, jtag_get_end_state());
663
664 jtag_check_value_mask(fields + 0, &field0_check_value, &field0_check_mask);
665 jtag_check_value_mask(fields + 2, &field2_check_value, &field2_check_mask);
666
667 if ((retval = jtag_execute_queue()) != ERROR_OK)
668 {
669 LOG_ERROR("JTAG error while writing DCSR");
670 return retval;
671 }
672
673 xscale->reg_cache->reg_list[XSCALE_DCSR].dirty = 0;
674 xscale->reg_cache->reg_list[XSCALE_DCSR].valid = 1;
675
676 return ERROR_OK;
677 }
678
679 /* parity of the number of bits 0 if even; 1 if odd. for 32 bit words */
680 static unsigned int parity (unsigned int v)
681 {
682 // unsigned int ov = v;
683 v ^= v >> 16;
684 v ^= v >> 8;
685 v ^= v >> 4;
686 v &= 0xf;
687 // LOG_DEBUG("parity of 0x%x is %i", ov, (0x6996 >> v) & 1);
688 return (0x6996 >> v) & 1;
689 }
690
691 static int xscale_load_ic(target_t *target, uint32_t va, uint32_t buffer[8])
692 {
693 uint8_t packet[4];
694 uint8_t cmd;
695 int word;
696 scan_field_t fields[2];
697
698 LOG_DEBUG("loading miniIC at 0x%8.8" PRIx32 "", va);
699
700 /* LDIC into IR */
701 jtag_set_end_state(TAP_IDLE);
702 xscale_jtag_set_instr(target->tap, XSCALE_LDIC);
703
704 /* CMD is b011 to load a cacheline into the Mini ICache.
705 * Loading into the main ICache is deprecated, and unused.
706 * It's followed by three zero bits, and 27 address bits.
707 */
708 buf_set_u32(&cmd, 0, 6, 0x3);
709
710 /* virtual address of desired cache line */
711 buf_set_u32(packet, 0, 27, va >> 5);
712
713 memset(&fields, 0, sizeof fields);
714
715 fields[0].tap = target->tap;
716 fields[0].num_bits = 6;
717 fields[0].out_value = &cmd;
718
719 fields[1].tap = target->tap;
720 fields[1].num_bits = 27;
721 fields[1].out_value = packet;
722
723 jtag_add_dr_scan(2, fields, jtag_get_end_state());
724
725 /* rest of packet is a cacheline: 8 instructions, with parity */
726 fields[0].num_bits = 32;
727 fields[0].out_value = packet;
728
729 fields[1].num_bits = 1;
730 fields[1].out_value = &cmd;
731
732 for (word = 0; word < 8; word++)
733 {
734 buf_set_u32(packet, 0, 32, buffer[word]);
735
736 uint32_t value;
737 memcpy(&value, packet, sizeof(uint32_t));
738 cmd = parity(value);
739
740 jtag_add_dr_scan(2, fields, jtag_get_end_state());
741 }
742
743 return jtag_execute_queue();
744 }
745
746 static int xscale_invalidate_ic_line(target_t *target, uint32_t va)
747 {
748 uint8_t packet[4];
749 uint8_t cmd;
750 scan_field_t fields[2];
751
752 jtag_set_end_state(TAP_IDLE);
753 xscale_jtag_set_instr(target->tap, XSCALE_LDIC);
754
755 /* CMD for invalidate IC line b000, bits [6:4] b000 */
756 buf_set_u32(&cmd, 0, 6, 0x0);
757
758 /* virtual address of desired cache line */
759 buf_set_u32(packet, 0, 27, va >> 5);
760
761 memset(&fields, 0, sizeof fields);
762
763 fields[0].tap = target->tap;
764 fields[0].num_bits = 6;
765 fields[0].out_value = &cmd;
766
767 fields[1].tap = target->tap;
768 fields[1].num_bits = 27;
769 fields[1].out_value = packet;
770
771 jtag_add_dr_scan(2, fields, jtag_get_end_state());
772
773 return ERROR_OK;
774 }
775
776 static int xscale_update_vectors(target_t *target)
777 {
778 armv4_5_common_t *armv4_5 = target->arch_info;
779 xscale_common_t *xscale = armv4_5->arch_info;
780 int i;
781 int retval;
782
783 uint32_t low_reset_branch, high_reset_branch;
784
785 for (i = 1; i < 8; i++)
786 {
787 /* if there's a static vector specified for this exception, override */
788 if (xscale->static_high_vectors_set & (1 << i))
789 {
790 xscale->high_vectors[i] = xscale->static_high_vectors[i];
791 }
792 else
793 {
794 retval = target_read_u32(target, 0xffff0000 + 4*i, &xscale->high_vectors[i]);
795 if (retval == ERROR_TARGET_TIMEOUT)
796 return retval;
797 if (retval != ERROR_OK)
798 {
799 /* Some of these reads will fail as part of normal execution */
800 xscale->high_vectors[i] = ARMV4_5_B(0xfffffe, 0);
801 }
802 }
803 }
804
805 for (i = 1; i < 8; i++)
806 {
807 if (xscale->static_low_vectors_set & (1 << i))
808 {
809 xscale->low_vectors[i] = xscale->static_low_vectors[i];
810 }
811 else
812 {
813 retval = target_read_u32(target, 0x0 + 4*i, &xscale->low_vectors[i]);
814 if (retval == ERROR_TARGET_TIMEOUT)
815 return retval;
816 if (retval != ERROR_OK)
817 {
818 /* Some of these reads will fail as part of normal execution */
819 xscale->low_vectors[i] = ARMV4_5_B(0xfffffe, 0);
820 }
821 }
822 }
823
824 /* calculate branches to debug handler */
825 low_reset_branch = (xscale->handler_address + 0x20 - 0x0 - 0x8) >> 2;
826 high_reset_branch = (xscale->handler_address + 0x20 - 0xffff0000 - 0x8) >> 2;
827
828 xscale->low_vectors[0] = ARMV4_5_B((low_reset_branch & 0xffffff), 0);
829 xscale->high_vectors[0] = ARMV4_5_B((high_reset_branch & 0xffffff), 0);
830
831 /* invalidate and load exception vectors in mini i-cache */
832 xscale_invalidate_ic_line(target, 0x0);
833 xscale_invalidate_ic_line(target, 0xffff0000);
834
835 xscale_load_ic(target, 0x0, xscale->low_vectors);
836 xscale_load_ic(target, 0xffff0000, xscale->high_vectors);
837
838 return ERROR_OK;
839 }
840
841 static int xscale_arch_state(struct target_s *target)
842 {
843 armv4_5_common_t *armv4_5 = target->arch_info;
844 xscale_common_t *xscale = armv4_5->arch_info;
845
846 static const char *state[] =
847 {
848 "disabled", "enabled"
849 };
850
851 static const char *arch_dbg_reason[] =
852 {
853 "", "\n(processor reset)", "\n(trace buffer full)"
854 };
855
856 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
857 {
858 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
859 exit(-1);
860 }
861
862 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
863 "cpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "\n"
864 "MMU: %s, D-Cache: %s, I-Cache: %s"
865 "%s",
866 armv4_5_state_strings[armv4_5->core_state],
867 Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name ,
868 armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
869 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
870 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
871 state[xscale->armv4_5_mmu.mmu_enabled],
872 state[xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
873 state[xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled],
874 arch_dbg_reason[xscale->arch_debug_reason]);
875
876 return ERROR_OK;
877 }
878
879 static int xscale_poll(target_t *target)
880 {
881 int retval = ERROR_OK;
882 armv4_5_common_t *armv4_5 = target->arch_info;
883 xscale_common_t *xscale = armv4_5->arch_info;
884
885 if ((target->state == TARGET_RUNNING) || (target->state == TARGET_DEBUG_RUNNING))
886 {
887 enum target_state previous_state = target->state;
888 if ((retval = xscale_read_tx(target, 0)) == ERROR_OK)
889 {
890
891 /* there's data to read from the tx register, we entered debug state */
892 xscale->handler_running = 1;
893
894 target->state = TARGET_HALTED;
895
896 /* process debug entry, fetching current mode regs */
897 retval = xscale_debug_entry(target);
898 }
899 else if (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
900 {
901 LOG_USER("error while polling TX register, reset CPU");
902 /* here we "lie" so GDB won't get stuck and a reset can be perfomed */
903 target->state = TARGET_HALTED;
904 }
905
906 /* debug_entry could have overwritten target state (i.e. immediate resume)
907 * don't signal event handlers in that case
908 */
909 if (target->state != TARGET_HALTED)
910 return ERROR_OK;
911
912 /* if target was running, signal that we halted
913 * otherwise we reentered from debug execution */
914 if (previous_state == TARGET_RUNNING)
915 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
916 else
917 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
918 }
919
920 return retval;
921 }
922
923 static int xscale_debug_entry(target_t *target)
924 {
925 armv4_5_common_t *armv4_5 = target->arch_info;
926 xscale_common_t *xscale = armv4_5->arch_info;
927 uint32_t pc;
928 uint32_t buffer[10];
929 int i;
930 int retval;
931
932 uint32_t moe;
933
934 /* clear external dbg break (will be written on next DCSR read) */
935 xscale->external_debug_break = 0;
936 if ((retval = xscale_read_dcsr(target)) != ERROR_OK)
937 return retval;
938
939 /* get r0, pc, r1 to r7 and cpsr */
940 if ((retval = xscale_receive(target, buffer, 10)) != ERROR_OK)
941 return retval;
942
943 /* move r0 from buffer to register cache */
944 buf_set_u32(armv4_5->core_cache->reg_list[0].value, 0, 32, buffer[0]);
945 armv4_5->core_cache->reg_list[0].dirty = 1;
946 armv4_5->core_cache->reg_list[0].valid = 1;
947 LOG_DEBUG("r0: 0x%8.8" PRIx32 "", buffer[0]);
948
949 /* move pc from buffer to register cache */
950 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, buffer[1]);
951 armv4_5->core_cache->reg_list[15].dirty = 1;
952 armv4_5->core_cache->reg_list[15].valid = 1;
953 LOG_DEBUG("pc: 0x%8.8" PRIx32 "", buffer[1]);
954
955 /* move data from buffer to register cache */
956 for (i = 1; i <= 7; i++)
957 {
958 buf_set_u32(armv4_5->core_cache->reg_list[i].value, 0, 32, buffer[1 + i]);
959 armv4_5->core_cache->reg_list[i].dirty = 1;
960 armv4_5->core_cache->reg_list[i].valid = 1;
961 LOG_DEBUG("r%i: 0x%8.8" PRIx32 "", i, buffer[i + 1]);
962 }
963
964 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32, buffer[9]);
965 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
966 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
967 LOG_DEBUG("cpsr: 0x%8.8" PRIx32 "", buffer[9]);
968
969 armv4_5->core_mode = buffer[9] & 0x1f;
970 if (armv4_5_mode_to_number(armv4_5->core_mode) == -1)
971 {
972 target->state = TARGET_UNKNOWN;
973 LOG_ERROR("cpsr contains invalid mode value - communication failure");
974 return ERROR_TARGET_FAILURE;
975 }
976 LOG_DEBUG("target entered debug state in %s mode", armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)]);
977
978 if (buffer[9] & 0x20)
979 armv4_5->core_state = ARMV4_5_STATE_THUMB;
980 else
981 armv4_5->core_state = ARMV4_5_STATE_ARM;
982
983
984 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
985 return ERROR_FAIL;
986
987 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
988 if ((armv4_5->core_mode != ARMV4_5_MODE_USR) && (armv4_5->core_mode != ARMV4_5_MODE_SYS))
989 {
990 xscale_receive(target, buffer, 8);
991 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32, buffer[7]);
992 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).dirty = 0;
993 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).valid = 1;
994 }
995 else
996 {
997 /* r8 to r14, but no spsr */
998 xscale_receive(target, buffer, 7);
999 }
1000
1001 /* move data from buffer to register cache */
1002 for (i = 8; i <= 14; i++)
1003 {
1004 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).value, 0, 32, buffer[i - 8]);
1005 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = 0;
1006 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid = 1;
1007 }
1008
1009 /* examine debug reason */
1010 xscale_read_dcsr(target);
1011 moe = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 2, 3);
1012
1013 /* stored PC (for calculating fixup) */
1014 pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
1015
1016 switch (moe)
1017 {
1018 case 0x0: /* Processor reset */
1019 target->debug_reason = DBG_REASON_DBGRQ;
1020 xscale->arch_debug_reason = XSCALE_DBG_REASON_RESET;
1021 pc -= 4;
1022 break;
1023 case 0x1: /* Instruction breakpoint hit */
1024 target->debug_reason = DBG_REASON_BREAKPOINT;
1025 xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;
1026 pc -= 4;
1027 break;
1028 case 0x2: /* Data breakpoint hit */
1029 target->debug_reason = DBG_REASON_WATCHPOINT;
1030 xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;
1031 pc -= 4;
1032 break;
1033 case 0x3: /* BKPT instruction executed */
1034 target->debug_reason = DBG_REASON_BREAKPOINT;
1035 xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;
1036 pc -= 4;
1037 break;
1038 case 0x4: /* Ext. debug event */
1039 target->debug_reason = DBG_REASON_DBGRQ;
1040 xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;
1041 pc -= 4;
1042 break;
1043 case 0x5: /* Vector trap occured */
1044 target->debug_reason = DBG_REASON_BREAKPOINT;
1045 xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;
1046 pc -= 4;
1047 break;
1048 case 0x6: /* Trace buffer full break */
1049 target->debug_reason = DBG_REASON_DBGRQ;
1050 xscale->arch_debug_reason = XSCALE_DBG_REASON_TB_FULL;
1051 pc -= 4;
1052 break;
1053 case 0x7: /* Reserved (may flag Hot-Debug support) */
1054 default:
1055 LOG_ERROR("Method of Entry is 'Reserved'");
1056 exit(-1);
1057 break;
1058 }
1059
1060 /* apply PC fixup */
1061 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, pc);
1062
1063 /* on the first debug entry, identify cache type */
1064 if (xscale->armv4_5_mmu.armv4_5_cache.ctype == -1)
1065 {
1066 uint32_t cache_type_reg;
1067
1068 /* read cp15 cache type register */
1069 xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CACHETYPE]);
1070 cache_type_reg = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CACHETYPE].value, 0, 32);
1071
1072 armv4_5_identify_cache(cache_type_reg, &xscale->armv4_5_mmu.armv4_5_cache);
1073 }
1074
1075 /* examine MMU and Cache settings */
1076 /* read cp15 control register */
1077 xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);
1078 xscale->cp15_control_reg = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32);
1079 xscale->armv4_5_mmu.mmu_enabled = (xscale->cp15_control_reg & 0x1U) ? 1 : 0;
1080 xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = (xscale->cp15_control_reg & 0x4U) ? 1 : 0;
1081 xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = (xscale->cp15_control_reg & 0x1000U) ? 1 : 0;
1082
1083 /* tracing enabled, read collected trace data */
1084 if (xscale->trace.buffer_enabled)
1085 {
1086 xscale_read_trace(target);
1087 xscale->trace.buffer_fill--;
1088
1089 /* resume if we're still collecting trace data */
1090 if ((xscale->arch_debug_reason == XSCALE_DBG_REASON_TB_FULL)
1091 && (xscale->trace.buffer_fill > 0))
1092 {
1093 xscale_resume(target, 1, 0x0, 1, 0);
1094 }
1095 else
1096 {
1097 xscale->trace.buffer_enabled = 0;
1098 }
1099 }
1100
1101 return ERROR_OK;
1102 }
1103
1104 static int xscale_halt(target_t *target)
1105 {
1106 armv4_5_common_t *armv4_5 = target->arch_info;
1107 xscale_common_t *xscale = armv4_5->arch_info;
1108
1109 LOG_DEBUG("target->state: %s",
1110 target_state_name(target));
1111
1112 if (target->state == TARGET_HALTED)
1113 {
1114 LOG_DEBUG("target was already halted");
1115 return ERROR_OK;
1116 }
1117 else if (target->state == TARGET_UNKNOWN)
1118 {
1119 /* this must not happen for a xscale target */
1120 LOG_ERROR("target was in unknown state when halt was requested");
1121 return ERROR_TARGET_INVALID;
1122 }
1123 else if (target->state == TARGET_RESET)
1124 {
1125 LOG_DEBUG("target->state == TARGET_RESET");
1126 }
1127 else
1128 {
1129 /* assert external dbg break */
1130 xscale->external_debug_break = 1;
1131 xscale_read_dcsr(target);
1132
1133 target->debug_reason = DBG_REASON_DBGRQ;
1134 }
1135
1136 return ERROR_OK;
1137 }
1138
1139 static int xscale_enable_single_step(struct target_s *target, uint32_t next_pc)
1140 {
1141 armv4_5_common_t *armv4_5 = target->arch_info;
1142 xscale_common_t *xscale= armv4_5->arch_info;
1143 reg_t *ibcr0 = &xscale->reg_cache->reg_list[XSCALE_IBCR0];
1144 int retval;
1145
1146 if (xscale->ibcr0_used)
1147 {
1148 breakpoint_t *ibcr0_bp = breakpoint_find(target, buf_get_u32(ibcr0->value, 0, 32) & 0xfffffffe);
1149
1150 if (ibcr0_bp)
1151 {
1152 xscale_unset_breakpoint(target, ibcr0_bp);
1153 }
1154 else
1155 {
1156 LOG_ERROR("BUG: xscale->ibcr0_used is set, but no breakpoint with that address found");
1157 exit(-1);
1158 }
1159 }
1160
1161 if ((retval = xscale_set_reg_u32(ibcr0, next_pc | 0x1)) != ERROR_OK)
1162 return retval;
1163
1164 return ERROR_OK;
1165 }
1166
1167 static int xscale_disable_single_step(struct target_s *target)
1168 {
1169 armv4_5_common_t *armv4_5 = target->arch_info;
1170 xscale_common_t *xscale= armv4_5->arch_info;
1171 reg_t *ibcr0 = &xscale->reg_cache->reg_list[XSCALE_IBCR0];
1172 int retval;
1173
1174 if ((retval = xscale_set_reg_u32(ibcr0, 0x0)) != ERROR_OK)
1175 return retval;
1176
1177 return ERROR_OK;
1178 }
1179
1180 static void xscale_enable_watchpoints(struct target_s *target)
1181 {
1182 watchpoint_t *watchpoint = target->watchpoints;
1183
1184 while (watchpoint)
1185 {
1186 if (watchpoint->set == 0)
1187 xscale_set_watchpoint(target, watchpoint);
1188 watchpoint = watchpoint->next;
1189 }
1190 }
1191
1192 static void xscale_enable_breakpoints(struct target_s *target)
1193 {
1194 breakpoint_t *breakpoint = target->breakpoints;
1195
1196 /* set any pending breakpoints */
1197 while (breakpoint)
1198 {
1199 if (breakpoint->set == 0)
1200 xscale_set_breakpoint(target, breakpoint);
1201 breakpoint = breakpoint->next;
1202 }
1203 }
1204
1205 static int xscale_resume(struct target_s *target, int current,
1206 uint32_t address, int handle_breakpoints, int debug_execution)
1207 {
1208 armv4_5_common_t *armv4_5 = target->arch_info;
1209 xscale_common_t *xscale= armv4_5->arch_info;
1210 breakpoint_t *breakpoint = target->breakpoints;
1211
1212 uint32_t current_pc;
1213
1214 int retval;
1215 int i;
1216
1217 LOG_DEBUG("-");
1218
1219 if (target->state != TARGET_HALTED)
1220 {
1221 LOG_WARNING("target not halted");
1222 return ERROR_TARGET_NOT_HALTED;
1223 }
1224
1225 if (!debug_execution)
1226 {
1227 target_free_all_working_areas(target);
1228 }
1229
1230 /* update vector tables */
1231 if ((retval = xscale_update_vectors(target)) != ERROR_OK)
1232 return retval;
1233
1234 /* current = 1: continue on current pc, otherwise continue at <address> */
1235 if (!current)
1236 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, address);
1237
1238 current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
1239
1240 /* if we're at the reset vector, we have to simulate the branch */
1241 if (current_pc == 0x0)
1242 {
1243 arm_simulate_step(target, NULL);
1244 current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
1245 }
1246
1247 /* the front-end may request us not to handle breakpoints */
1248 if (handle_breakpoints)
1249 {
1250 if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))))
1251 {
1252 uint32_t next_pc;
1253
1254 /* there's a breakpoint at the current PC, we have to step over it */
1255 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
1256 xscale_unset_breakpoint(target, breakpoint);
1257
1258 /* calculate PC of next instruction */
1259 if ((retval = arm_simulate_step(target, &next_pc)) != ERROR_OK)
1260 {
1261 uint32_t current_opcode;
1262 target_read_u32(target, current_pc, &current_opcode);
1263 LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8" PRIx32 "", current_opcode);
1264 }
1265
1266 LOG_DEBUG("enable single-step");
1267 xscale_enable_single_step(target, next_pc);
1268
1269 /* restore banked registers */
1270 xscale_restore_context(target);
1271
1272 /* send resume request (command 0x30 or 0x31)
1273 * clean the trace buffer if it is to be enabled (0x62) */
1274 if (xscale->trace.buffer_enabled)
1275 {
1276 xscale_send_u32(target, 0x62);
1277 xscale_send_u32(target, 0x31);
1278 }
1279 else
1280 xscale_send_u32(target, 0x30);
1281
1282 /* send CPSR */
1283 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1284 LOG_DEBUG("writing cpsr with value 0x%8.8" PRIx32 "", buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1285
1286 for (i = 7; i >= 0; i--)
1287 {
1288 /* send register */
1289 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
1290 LOG_DEBUG("writing r%i with value 0x%8.8" PRIx32 "", i, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
1291 }
1292
1293 /* send PC */
1294 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1295 LOG_DEBUG("writing PC with value 0x%8.8" PRIx32 "", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1296
1297 /* wait for and process debug entry */
1298 xscale_debug_entry(target);
1299
1300 LOG_DEBUG("disable single-step");
1301 xscale_disable_single_step(target);
1302
1303 LOG_DEBUG("set breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
1304 xscale_set_breakpoint(target, breakpoint);
1305 }
1306 }
1307
1308 /* enable any pending breakpoints and watchpoints */
1309 xscale_enable_breakpoints(target);
1310 xscale_enable_watchpoints(target);
1311
1312 /* restore banked registers */
1313 xscale_restore_context(target);
1314
1315 /* send resume request (command 0x30 or 0x31)
1316 * clean the trace buffer if it is to be enabled (0x62) */
1317 if (xscale->trace.buffer_enabled)
1318 {
1319 xscale_send_u32(target, 0x62);
1320 xscale_send_u32(target, 0x31);
1321 }
1322 else
1323 xscale_send_u32(target, 0x30);
1324
1325 /* send CPSR */
1326 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1327 LOG_DEBUG("writing cpsr with value 0x%8.8" PRIx32 "", buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1328
1329 for (i = 7; i >= 0; i--)
1330 {
1331 /* send register */
1332 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
1333 LOG_DEBUG("writing r%i with value 0x%8.8" PRIx32 "", i, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
1334 }
1335
1336 /* send PC */
1337 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1338 LOG_DEBUG("writing PC with value 0x%8.8" PRIx32 "", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1339
1340 target->debug_reason = DBG_REASON_NOTHALTED;
1341
1342 if (!debug_execution)
1343 {
1344 /* registers are now invalid */
1345 armv4_5_invalidate_core_regs(target);
1346 target->state = TARGET_RUNNING;
1347 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1348 }
1349 else
1350 {
1351 target->state = TARGET_DEBUG_RUNNING;
1352 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
1353 }
1354
1355 LOG_DEBUG("target resumed");
1356
1357 xscale->handler_running = 1;
1358
1359 return ERROR_OK;
1360 }
1361
1362 static int xscale_step_inner(struct target_s *target, int current,
1363 uint32_t address, int handle_breakpoints)
1364 {
1365 armv4_5_common_t *armv4_5 = target->arch_info;
1366 xscale_common_t *xscale = armv4_5->arch_info;
1367
1368 uint32_t next_pc;
1369 int retval;
1370 int i;
1371
1372 target->debug_reason = DBG_REASON_SINGLESTEP;
1373
1374 /* calculate PC of next instruction */
1375 if ((retval = arm_simulate_step(target, &next_pc)) != ERROR_OK)
1376 {
1377 uint32_t current_opcode, current_pc;
1378 current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
1379
1380 target_read_u32(target, current_pc, &current_opcode);
1381 LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8" PRIx32 "", current_opcode);
1382 return retval;
1383 }
1384
1385 LOG_DEBUG("enable single-step");
1386 if ((retval = xscale_enable_single_step(target, next_pc)) != ERROR_OK)
1387 return retval;
1388
1389 /* restore banked registers */
1390 if ((retval = xscale_restore_context(target)) != ERROR_OK)
1391 return retval;
1392
1393 /* send resume request (command 0x30 or 0x31)
1394 * clean the trace buffer if it is to be enabled (0x62) */
1395 if (xscale->trace.buffer_enabled)
1396 {
1397 if ((retval = xscale_send_u32(target, 0x62)) != ERROR_OK)
1398 return retval;
1399 if ((retval = xscale_send_u32(target, 0x31)) != ERROR_OK)
1400 return retval;
1401 }
1402 else
1403 if ((retval = xscale_send_u32(target, 0x30)) != ERROR_OK)
1404 return retval;
1405
1406 /* send CPSR */
1407 if ((retval = xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32))) != ERROR_OK)
1408 return retval;
1409 LOG_DEBUG("writing cpsr with value 0x%8.8" PRIx32 "", buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1410
1411 for (i = 7; i >= 0; i--)
1412 {
1413 /* send register */
1414 if ((retval = xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32))) != ERROR_OK)
1415 return retval;
1416 LOG_DEBUG("writing r%i with value 0x%8.8" PRIx32 "", i, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
1417 }
1418
1419 /* send PC */
1420 if ((retval = xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))) != ERROR_OK)
1421 return retval;
1422 LOG_DEBUG("writing PC with value 0x%8.8" PRIx32, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1423
1424 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1425
1426 /* registers are now invalid */
1427 if ((retval = armv4_5_invalidate_core_regs(target)) != ERROR_OK)
1428 return retval;
1429
1430 /* wait for and process debug entry */
1431 if ((retval = xscale_debug_entry(target)) != ERROR_OK)
1432 return retval;
1433
1434 LOG_DEBUG("disable single-step");
1435 if ((retval = xscale_disable_single_step(target)) != ERROR_OK)
1436 return retval;
1437
1438 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1439
1440 return ERROR_OK;
1441 }
1442
1443 static int xscale_step(struct target_s *target, int current,
1444 uint32_t address, int handle_breakpoints)
1445 {
1446 armv4_5_common_t *armv4_5 = target->arch_info;
1447 breakpoint_t *breakpoint = target->breakpoints;
1448
1449 uint32_t current_pc;
1450 int retval;
1451
1452 if (target->state != TARGET_HALTED)
1453 {
1454 LOG_WARNING("target not halted");
1455 return ERROR_TARGET_NOT_HALTED;
1456 }
1457
1458 /* current = 1: continue on current pc, otherwise continue at <address> */
1459 if (!current)
1460 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, address);
1461
1462 current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
1463
1464 /* if we're at the reset vector, we have to simulate the step */
1465 if (current_pc == 0x0)
1466 {
1467 if ((retval = arm_simulate_step(target, NULL)) != ERROR_OK)
1468 return retval;
1469 current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
1470
1471 target->debug_reason = DBG_REASON_SINGLESTEP;
1472 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1473
1474 return ERROR_OK;
1475 }
1476
1477 /* the front-end may request us not to handle breakpoints */
1478 if (handle_breakpoints)
1479 if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))))
1480 {
1481 if ((retval = xscale_unset_breakpoint(target, breakpoint)) != ERROR_OK)
1482 return retval;
1483 }
1484
1485 retval = xscale_step_inner(target, current, address, handle_breakpoints);
1486
1487 if (breakpoint)
1488 {
1489 xscale_set_breakpoint(target, breakpoint);
1490 }
1491
1492 LOG_DEBUG("target stepped");
1493
1494 return ERROR_OK;
1495
1496 }
1497
1498 static int xscale_assert_reset(target_t *target)
1499 {
1500 armv4_5_common_t *armv4_5 = target->arch_info;
1501 xscale_common_t *xscale = armv4_5->arch_info;
1502
1503 LOG_DEBUG("target->state: %s",
1504 target_state_name(target));
1505
1506 /* select DCSR instruction (set endstate to R-T-I to ensure we don't
1507 * end up in T-L-R, which would reset JTAG
1508 */
1509 jtag_set_end_state(TAP_IDLE);
1510 xscale_jtag_set_instr(target->tap, XSCALE_SELDCSR);
1511
1512 /* set Hold reset, Halt mode and Trap Reset */
1513 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
1514 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);
1515 xscale_write_dcsr(target, 1, 0);
1516
1517 /* select BYPASS, because having DCSR selected caused problems on the PXA27x */
1518 xscale_jtag_set_instr(target->tap, 0x7f);
1519 jtag_execute_queue();
1520
1521 /* assert reset */
1522 jtag_add_reset(0, 1);
1523
1524 /* sleep 1ms, to be sure we fulfill any requirements */
1525 jtag_add_sleep(1000);
1526 jtag_execute_queue();
1527
1528 target->state = TARGET_RESET;
1529
1530 if (target->reset_halt)
1531 {
1532 int retval;
1533 if ((retval = target_halt(target)) != ERROR_OK)
1534 return retval;
1535 }
1536
1537 return ERROR_OK;
1538 }
1539
1540 static int xscale_deassert_reset(target_t *target)
1541 {
1542 armv4_5_common_t *armv4_5 = target->arch_info;
1543 xscale_common_t *xscale = armv4_5->arch_info;
1544 breakpoint_t *breakpoint = target->breakpoints;
1545
1546 LOG_DEBUG("-");
1547
1548 xscale->ibcr_available = 2;
1549 xscale->ibcr0_used = 0;
1550 xscale->ibcr1_used = 0;
1551
1552 xscale->dbr_available = 2;
1553 xscale->dbr0_used = 0;
1554 xscale->dbr1_used = 0;
1555
1556 /* mark all hardware breakpoints as unset */
1557 while (breakpoint)
1558 {
1559 if (breakpoint->type == BKPT_HARD)
1560 {
1561 breakpoint->set = 0;
1562 }
1563 breakpoint = breakpoint->next;
1564 }
1565
1566 if (!xscale->handler_installed)
1567 {
1568 uint32_t address;
1569 unsigned buf_cnt;
1570 const uint8_t *buffer = xscale_debug_handler;
1571 int retval;
1572
1573 /* release SRST */
1574 jtag_add_reset(0, 0);
1575
1576 /* wait 300ms; 150 and 100ms were not enough */
1577 jtag_add_sleep(300*1000);
1578
1579 jtag_add_runtest(2030, jtag_set_end_state(TAP_IDLE));
1580 jtag_execute_queue();
1581
1582 /* set Hold reset, Halt mode and Trap Reset */
1583 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
1584 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);
1585 xscale_write_dcsr(target, 1, 0);
1586
1587 /* Load the debug handler into the mini-icache. Since
1588 * it's using halt mode (not monitor mode), it runs in
1589 * "Special Debug State" for access to registers, memory,
1590 * coprocessors, trace data, etc.
1591 *
1592 * REVISIT: *assumes* we've had a SRST+TRST reset so the
1593 * mini-icache contents have been invalidated. Safest to
1594 * force that, so writing new contents is reliable...
1595 */
1596 address = xscale->handler_address;
1597 for (unsigned binary_size = xscale_debug_handler_size;
1598 binary_size > 0;
1599 binary_size -= buf_cnt, buffer += buf_cnt)
1600 {
1601 uint32_t cache_line[8];
1602 unsigned i;
1603
1604 buf_cnt = binary_size;
1605 if (buf_cnt > 32)
1606 buf_cnt = 32;
1607
1608 for (i = 0; i < buf_cnt; i += 4)
1609 {
1610 /* convert LE buffer to host-endian uint32_t */
1611 cache_line[i / 4] = le_to_h_u32(&buffer[i]);
1612 }
1613
1614 for (; i < 32; i += 4)
1615 {
1616 cache_line[i / 4] = 0xe1a08008;
1617 }
1618
1619 /* only load addresses other than the reset vectors */
1620 if ((address % 0x400) != 0x0)
1621 {
1622 retval = xscale_load_ic(target, address,
1623 cache_line);
1624 if (retval != ERROR_OK)
1625 return retval;
1626 }
1627
1628 address += buf_cnt;
1629 };
1630
1631 retval = xscale_load_ic(target, 0x0,
1632 xscale->low_vectors);
1633 if (retval != ERROR_OK)
1634 return retval;
1635 retval = xscale_load_ic(target, 0xffff0000,
1636 xscale->high_vectors);
1637 if (retval != ERROR_OK)
1638 return retval;
1639
1640 jtag_add_runtest(30, jtag_set_end_state(TAP_IDLE));
1641
1642 jtag_add_sleep(100000);
1643
1644 /* set Hold reset, Halt mode and Trap Reset */
1645 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
1646 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);
1647 xscale_write_dcsr(target, 1, 0);
1648
1649 /* clear Hold reset to let the target run (should enter debug handler) */
1650 xscale_write_dcsr(target, 0, 1);
1651 target->state = TARGET_RUNNING;
1652
1653 if (!target->reset_halt)
1654 {
1655 jtag_add_sleep(10000);
1656
1657 /* we should have entered debug now */
1658 xscale_debug_entry(target);
1659 target->state = TARGET_HALTED;
1660
1661 /* resume the target */
1662 xscale_resume(target, 1, 0x0, 1, 0);
1663 }
1664 }
1665 else
1666 {
1667 jtag_add_reset(0, 0);
1668 }
1669
1670 return ERROR_OK;
1671 }
1672
1673 static int xscale_read_core_reg(struct target_s *target, int num,
1674 enum armv4_5_mode mode)
1675 {
1676 LOG_ERROR("not implemented");
1677 return ERROR_OK;
1678 }
1679
1680 static int xscale_write_core_reg(struct target_s *target, int num,
1681 enum armv4_5_mode mode, uint32_t value)
1682 {
1683 LOG_ERROR("not implemented");
1684 return ERROR_OK;
1685 }
1686
1687 static int xscale_full_context(target_t *target)
1688 {
1689 armv4_5_common_t *armv4_5 = target->arch_info;
1690
1691 uint32_t *buffer;
1692
1693 int i, j;
1694
1695 LOG_DEBUG("-");
1696
1697 if (target->state != TARGET_HALTED)
1698 {
1699 LOG_WARNING("target not halted");
1700 return ERROR_TARGET_NOT_HALTED;
1701 }
1702
1703 buffer = malloc(4 * 8);
1704
1705 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1706 * we can't enter User mode on an XScale (unpredictable),
1707 * but User shares registers with SYS
1708 */
1709 for (i = 1; i < 7; i++)
1710 {
1711 int valid = 1;
1712
1713 /* check if there are invalid registers in the current mode
1714 */
1715 for (j = 0; j <= 16; j++)
1716 {
1717 if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).valid == 0)
1718 valid = 0;
1719 }
1720
1721 if (!valid)
1722 {
1723 uint32_t tmp_cpsr;
1724
1725 /* request banked registers */
1726 xscale_send_u32(target, 0x0);
1727
1728 tmp_cpsr = 0x0;
1729 tmp_cpsr |= armv4_5_number_to_mode(i);
1730 tmp_cpsr |= 0xc0; /* I/F bits */
1731
1732 /* send CPSR for desired mode */
1733 xscale_send_u32(target, tmp_cpsr);
1734
1735 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1736 if ((armv4_5_number_to_mode(i) != ARMV4_5_MODE_USR) && (armv4_5_number_to_mode(i) != ARMV4_5_MODE_SYS))
1737 {
1738 xscale_receive(target, buffer, 8);
1739 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32, buffer[7]);
1740 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty = 0;
1741 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).valid = 1;
1742 }
1743 else
1744 {
1745 xscale_receive(target, buffer, 7);
1746 }
1747
1748 /* move data from buffer to register cache */
1749 for (j = 8; j <= 14; j++)
1750 {
1751 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).value, 0, 32, buffer[j - 8]);
1752 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty = 0;
1753 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).valid = 1;
1754 }
1755 }
1756 }
1757
1758 free(buffer);
1759
1760 return ERROR_OK;
1761 }
1762
1763 static int xscale_restore_context(target_t *target)
1764 {
1765 armv4_5_common_t *armv4_5 = target->arch_info;
1766
1767 int i, j;
1768
1769 if (target->state != TARGET_HALTED)
1770 {
1771 LOG_WARNING("target not halted");
1772 return ERROR_TARGET_NOT_HALTED;
1773 }
1774
1775 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1776 * we can't enter User mode on an XScale (unpredictable),
1777 * but User shares registers with SYS
1778 */
1779 for (i = 1; i < 7; i++)
1780 {
1781 int dirty = 0;
1782
1783 /* check if there are invalid registers in the current mode
1784 */
1785 for (j = 8; j <= 14; j++)
1786 {
1787 if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty == 1)
1788 dirty = 1;
1789 }
1790
1791 /* if not USR/SYS, check if the SPSR needs to be written */
1792 if ((armv4_5_number_to_mode(i) != ARMV4_5_MODE_USR) && (armv4_5_number_to_mode(i) != ARMV4_5_MODE_SYS))
1793 {
1794 if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty == 1)
1795 dirty = 1;
1796 }
1797
1798 if (dirty)
1799 {
1800 uint32_t tmp_cpsr;
1801
1802 /* send banked registers */
1803 xscale_send_u32(target, 0x1);
1804
1805 tmp_cpsr = 0x0;
1806 tmp_cpsr |= armv4_5_number_to_mode(i);
1807 tmp_cpsr |= 0xc0; /* I/F bits */
1808
1809 /* send CPSR for desired mode */
1810 xscale_send_u32(target, tmp_cpsr);
1811
1812 /* send banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1813 for (j = 8; j <= 14; j++)
1814 {
1815 xscale_send_u32(target, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, j).value, 0, 32));
1816 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty = 0;
1817 }
1818
1819 if ((armv4_5_number_to_mode(i) != ARMV4_5_MODE_USR) && (armv4_5_number_to_mode(i) != ARMV4_5_MODE_SYS))
1820 {
1821 xscale_send_u32(target, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32));
1822 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty = 0;
1823 }
1824 }
1825 }
1826
1827 return ERROR_OK;
1828 }
1829
1830 static int xscale_read_memory(struct target_s *target, uint32_t address,
1831 uint32_t size, uint32_t count, uint8_t *buffer)
1832 {
1833 armv4_5_common_t *armv4_5 = target->arch_info;
1834 xscale_common_t *xscale = armv4_5->arch_info;
1835 uint32_t *buf32;
1836 uint32_t i;
1837 int retval;
1838
1839 LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32, address, size, count);
1840
1841 if (target->state != TARGET_HALTED)
1842 {
1843 LOG_WARNING("target not halted");
1844 return ERROR_TARGET_NOT_HALTED;
1845 }
1846
1847 /* sanitize arguments */
1848 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1849 return ERROR_INVALID_ARGUMENTS;
1850
1851 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
1852 return ERROR_TARGET_UNALIGNED_ACCESS;
1853
1854 /* send memory read request (command 0x1n, n: access size) */
1855 if ((retval = xscale_send_u32(target, 0x10 | size)) != ERROR_OK)
1856 return retval;
1857
1858 /* send base address for read request */
1859 if ((retval = xscale_send_u32(target, address)) != ERROR_OK)
1860 return retval;
1861
1862 /* send number of requested data words */
1863 if ((retval = xscale_send_u32(target, count)) != ERROR_OK)
1864 return retval;
1865
1866 /* receive data from target (count times 32-bit words in host endianness) */
1867 buf32 = malloc(4 * count);
1868 if ((retval = xscale_receive(target, buf32, count)) != ERROR_OK)
1869 return retval;
1870
1871 /* extract data from host-endian buffer into byte stream */
1872 for (i = 0; i < count; i++)
1873 {
1874 switch (size)
1875 {
1876 case 4:
1877 target_buffer_set_u32(target, buffer, buf32[i]);
1878 buffer += 4;
1879 break;
1880 case 2:
1881 target_buffer_set_u16(target, buffer, buf32[i] & 0xffff);
1882 buffer += 2;
1883 break;
1884 case 1:
1885 *buffer++ = buf32[i] & 0xff;
1886 break;
1887 default:
1888 LOG_ERROR("should never get here");
1889 exit(-1);
1890 }
1891 }
1892
1893 free(buf32);
1894
1895 /* examine DCSR, to see if Sticky Abort (SA) got set */
1896 if ((retval = xscale_read_dcsr(target)) != ERROR_OK)
1897 return retval;
1898 if (buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 5, 1) == 1)
1899 {
1900 /* clear SA bit */
1901 if ((retval = xscale_send_u32(target, 0x60)) != ERROR_OK)
1902 return retval;
1903
1904 return ERROR_TARGET_DATA_ABORT;
1905 }
1906
1907 return ERROR_OK;
1908 }
1909
1910 static int xscale_write_memory(struct target_s *target, uint32_t address,
1911 uint32_t size, uint32_t count, uint8_t *buffer)
1912 {
1913 armv4_5_common_t *armv4_5 = target->arch_info;
1914 xscale_common_t *xscale = armv4_5->arch_info;
1915 int retval;
1916
1917 LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32, address, size, count);
1918
1919 if (target->state != TARGET_HALTED)
1920 {
1921 LOG_WARNING("target not halted");
1922 return ERROR_TARGET_NOT_HALTED;
1923 }
1924
1925 /* sanitize arguments */
1926 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1927 return ERROR_INVALID_ARGUMENTS;
1928
1929 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
1930 return ERROR_TARGET_UNALIGNED_ACCESS;
1931
1932 /* send memory write request (command 0x2n, n: access size) */
1933 if ((retval = xscale_send_u32(target, 0x20 | size)) != ERROR_OK)
1934 return retval;
1935
1936 /* send base address for read request */
1937 if ((retval = xscale_send_u32(target, address)) != ERROR_OK)
1938 return retval;
1939
1940 /* send number of requested data words to be written*/
1941 if ((retval = xscale_send_u32(target, count)) != ERROR_OK)
1942 return retval;
1943
1944 /* extract data from host-endian buffer into byte stream */
1945 #if 0
1946 for (i = 0; i < count; i++)
1947 {
1948 switch (size)
1949 {
1950 case 4:
1951 value = target_buffer_get_u32(target, buffer);
1952 xscale_send_u32(target, value);
1953 buffer += 4;
1954 break;
1955 case 2:
1956 value = target_buffer_get_u16(target, buffer);
1957 xscale_send_u32(target, value);
1958 buffer += 2;
1959 break;
1960 case 1:
1961 value = *buffer;
1962 xscale_send_u32(target, value);
1963 buffer += 1;
1964 break;
1965 default:
1966 LOG_ERROR("should never get here");
1967 exit(-1);
1968 }
1969 }
1970 #endif
1971 if ((retval = xscale_send(target, buffer, count, size)) != ERROR_OK)
1972 return retval;
1973
1974 /* examine DCSR, to see if Sticky Abort (SA) got set */
1975 if ((retval = xscale_read_dcsr(target)) != ERROR_OK)
1976 return retval;
1977 if (buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 5, 1) == 1)
1978 {
1979 /* clear SA bit */
1980 if ((retval = xscale_send_u32(target, 0x60)) != ERROR_OK)
1981 return retval;
1982
1983 return ERROR_TARGET_DATA_ABORT;
1984 }
1985
1986 return ERROR_OK;
1987 }
1988
1989 static int xscale_bulk_write_memory(target_t *target, uint32_t address,
1990 uint32_t count, uint8_t *buffer)
1991 {
1992 return xscale_write_memory(target, address, 4, count, buffer);
1993 }
1994
1995 static uint32_t xscale_get_ttb(target_t *target)
1996 {
1997 armv4_5_common_t *armv4_5 = target->arch_info;
1998 xscale_common_t *xscale = armv4_5->arch_info;
1999 uint32_t ttb;
2000
2001 xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_TTB]);
2002 ttb = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_TTB].value, 0, 32);
2003
2004 return ttb;
2005 }
2006
2007 static void xscale_disable_mmu_caches(target_t *target, int mmu,
2008 int d_u_cache, int i_cache)
2009 {
2010 armv4_5_common_t *armv4_5 = target->arch_info;
2011 xscale_common_t *xscale = armv4_5->arch_info;
2012 uint32_t cp15_control;
2013
2014 /* read cp15 control register */
2015 xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);
2016 cp15_control = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32);
2017
2018 if (mmu)
2019 cp15_control &= ~0x1U;
2020
2021 if (d_u_cache)
2022 {
2023 /* clean DCache */
2024 xscale_send_u32(target, 0x50);
2025 xscale_send_u32(target, xscale->cache_clean_address);
2026
2027 /* invalidate DCache */
2028 xscale_send_u32(target, 0x51);
2029
2030 cp15_control &= ~0x4U;
2031 }
2032
2033 if (i_cache)
2034 {
2035 /* invalidate ICache */
2036 xscale_send_u32(target, 0x52);
2037 cp15_control &= ~0x1000U;
2038 }
2039
2040 /* write new cp15 control register */
2041 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_CTRL], cp15_control);
2042
2043 /* execute cpwait to ensure outstanding operations complete */
2044 xscale_send_u32(target, 0x53);
2045 }
2046
2047 static void xscale_enable_mmu_caches(target_t *target, int mmu,
2048 int d_u_cache, int i_cache)
2049 {
2050 armv4_5_common_t *armv4_5 = target->arch_info;
2051 xscale_common_t *xscale = armv4_5->arch_info;
2052 uint32_t cp15_control;
2053
2054 /* read cp15 control register */
2055 xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);
2056 cp15_control = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32);
2057
2058 if (mmu)
2059 cp15_control |= 0x1U;
2060
2061 if (d_u_cache)
2062 cp15_control |= 0x4U;
2063
2064 if (i_cache)
2065 cp15_control |= 0x1000U;
2066
2067 /* write new cp15 control register */
2068 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_CTRL], cp15_control);
2069
2070 /* execute cpwait to ensure outstanding operations complete */
2071 xscale_send_u32(target, 0x53);
2072 }
2073
2074 static int xscale_set_breakpoint(struct target_s *target,
2075 breakpoint_t *breakpoint)
2076 {
2077 int retval;
2078 armv4_5_common_t *armv4_5 = target->arch_info;
2079 xscale_common_t *xscale = armv4_5->arch_info;
2080
2081 if (target->state != TARGET_HALTED)
2082 {
2083 LOG_WARNING("target not halted");
2084 return ERROR_TARGET_NOT_HALTED;
2085 }
2086
2087 if (breakpoint->set)
2088 {
2089 LOG_WARNING("breakpoint already set");
2090 return ERROR_OK;
2091 }
2092
2093 if (breakpoint->type == BKPT_HARD)
2094 {
2095 uint32_t value = breakpoint->address | 1;
2096 if (!xscale->ibcr0_used)
2097 {
2098 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR0], value);
2099 xscale->ibcr0_used = 1;
2100 breakpoint->set = 1; /* breakpoint set on first breakpoint register */
2101 }
2102 else if (!xscale->ibcr1_used)
2103 {
2104 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR1], value);
2105 xscale->ibcr1_used = 1;
2106 breakpoint->set = 2; /* breakpoint set on second breakpoint register */
2107 }
2108 else
2109 {
2110 LOG_ERROR("BUG: no hardware comparator available");
2111 return ERROR_OK;
2112 }
2113 }
2114 else if (breakpoint->type == BKPT_SOFT)
2115 {
2116 if (breakpoint->length == 4)
2117 {
2118 /* keep the original instruction in target endianness */
2119 if ((retval = target_read_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr)) != ERROR_OK)
2120 {
2121 return retval;
2122 }
2123 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2124 if ((retval = target_write_u32(target, breakpoint->address, xscale->arm_bkpt)) != ERROR_OK)
2125 {
2126 return retval;
2127 }
2128 }
2129 else
2130 {
2131 /* keep the original instruction in target endianness */
2132 if ((retval = target_read_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr)) != ERROR_OK)
2133 {
2134 return retval;
2135 }
2136 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2137 if ((retval = target_write_u32(target, breakpoint->address, xscale->thumb_bkpt)) != ERROR_OK)
2138 {
2139 return retval;
2140 }
2141 }
2142 breakpoint->set = 1;
2143 }
2144
2145 return ERROR_OK;
2146 }
2147
2148 static int xscale_add_breakpoint(struct target_s *target,
2149 breakpoint_t *breakpoint)
2150 {
2151 armv4_5_common_t *armv4_5 = target->arch_info;
2152 xscale_common_t *xscale = armv4_5->arch_info;
2153
2154 if (target->state != TARGET_HALTED)
2155 {
2156 LOG_WARNING("target not halted");
2157 return ERROR_TARGET_NOT_HALTED;
2158 }
2159
2160 if ((breakpoint->type == BKPT_HARD) && (xscale->ibcr_available < 1))
2161 {
2162 LOG_INFO("no breakpoint unit available for hardware breakpoint");
2163 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2164 }
2165
2166 if ((breakpoint->length != 2) && (breakpoint->length != 4))
2167 {
2168 LOG_INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
2169 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2170 }
2171
2172 if (breakpoint->type == BKPT_HARD)
2173 {
2174 xscale->ibcr_available--;
2175 }
2176
2177 return ERROR_OK;
2178 }
2179
2180 static int xscale_unset_breakpoint(struct target_s *target,
2181 breakpoint_t *breakpoint)
2182 {
2183 int retval;
2184 armv4_5_common_t *armv4_5 = target->arch_info;
2185 xscale_common_t *xscale = armv4_5->arch_info;
2186
2187 if (target->state != TARGET_HALTED)
2188 {
2189 LOG_WARNING("target not halted");
2190 return ERROR_TARGET_NOT_HALTED;
2191 }
2192
2193 if (!breakpoint->set)
2194 {
2195 LOG_WARNING("breakpoint not set");
2196 return ERROR_OK;
2197 }
2198
2199 if (breakpoint->type == BKPT_HARD)
2200 {
2201 if (breakpoint->set == 1)
2202 {
2203 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR0], 0x0);
2204 xscale->ibcr0_used = 0;
2205 }
2206 else if (breakpoint->set == 2)
2207 {
2208 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR1], 0x0);
2209 xscale->ibcr1_used = 0;
2210 }
2211 breakpoint->set = 0;
2212 }
2213 else
2214 {
2215 /* restore original instruction (kept in target endianness) */
2216 if (breakpoint->length == 4)
2217 {
2218 if ((retval = target_write_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr)) != ERROR_OK)
2219 {
2220 return retval;
2221 }
2222 }
2223 else
2224 {
2225 if ((retval = target_write_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr)) != ERROR_OK)
2226 {
2227 return retval;
2228 }
2229 }
2230 breakpoint->set = 0;
2231 }
2232
2233 return ERROR_OK;
2234 }
2235
2236 static int xscale_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
2237 {
2238 armv4_5_common_t *armv4_5 = target->arch_info;
2239 xscale_common_t *xscale = armv4_5->arch_info;
2240
2241 if (target->state != TARGET_HALTED)
2242 {
2243 LOG_WARNING("target not halted");
2244 return ERROR_TARGET_NOT_HALTED;
2245 }
2246
2247 if (breakpoint->set)
2248 {
2249 xscale_unset_breakpoint(target, breakpoint);
2250 }
2251
2252 if (breakpoint->type == BKPT_HARD)
2253 xscale->ibcr_available++;
2254
2255 return ERROR_OK;
2256 }
2257
2258 static int xscale_set_watchpoint(struct target_s *target,
2259 watchpoint_t *watchpoint)
2260 {
2261 armv4_5_common_t *armv4_5 = target->arch_info;
2262 xscale_common_t *xscale = armv4_5->arch_info;
2263 uint8_t enable = 0;
2264 reg_t *dbcon = &xscale->reg_cache->reg_list[XSCALE_DBCON];
2265 uint32_t dbcon_value = buf_get_u32(dbcon->value, 0, 32);
2266
2267 if (target->state != TARGET_HALTED)
2268 {
2269 LOG_WARNING("target not halted");
2270 return ERROR_TARGET_NOT_HALTED;
2271 }
2272
2273 xscale_get_reg(dbcon);
2274
2275 switch (watchpoint->rw)
2276 {
2277 case WPT_READ:
2278 enable = 0x3;
2279 break;
2280 case WPT_ACCESS:
2281 enable = 0x2;
2282 break;
2283 case WPT_WRITE:
2284 enable = 0x1;
2285 break;
2286 default:
2287 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
2288 }
2289
2290 if (!xscale->dbr0_used)
2291 {
2292 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR0], watchpoint->address);
2293 dbcon_value |= enable;
2294 xscale_set_reg_u32(dbcon, dbcon_value);
2295 watchpoint->set = 1;
2296 xscale->dbr0_used = 1;
2297 }
2298 else if (!xscale->dbr1_used)
2299 {
2300 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR1], watchpoint->address);
2301 dbcon_value |= enable << 2;
2302 xscale_set_reg_u32(dbcon, dbcon_value);
2303 watchpoint->set = 2;
2304 xscale->dbr1_used = 1;
2305 }
2306 else
2307 {
2308 LOG_ERROR("BUG: no hardware comparator available");
2309 return ERROR_OK;
2310 }
2311
2312 return ERROR_OK;
2313 }
2314
2315 static int xscale_add_watchpoint(struct target_s *target,
2316 watchpoint_t *watchpoint)
2317 {
2318 armv4_5_common_t *armv4_5 = target->arch_info;
2319 xscale_common_t *xscale = armv4_5->arch_info;
2320
2321 if (target->state != TARGET_HALTED)
2322 {
2323 LOG_WARNING("target not halted");
2324 return ERROR_TARGET_NOT_HALTED;
2325 }
2326
2327 if (xscale->dbr_available < 1)
2328 {
2329 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2330 }
2331
2332 if ((watchpoint->length != 1) && (watchpoint->length != 2) && (watchpoint->length != 4))
2333 {
2334 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2335 }
2336
2337 xscale->dbr_available--;
2338
2339 return ERROR_OK;
2340 }
2341
2342 static int xscale_unset_watchpoint(struct target_s *target,
2343 watchpoint_t *watchpoint)
2344 {
2345 armv4_5_common_t *armv4_5 = target->arch_info;
2346 xscale_common_t *xscale = armv4_5->arch_info;
2347 reg_t *dbcon = &xscale->reg_cache->reg_list[XSCALE_DBCON];
2348 uint32_t dbcon_value = buf_get_u32(dbcon->value, 0, 32);
2349
2350 if (target->state != TARGET_HALTED)
2351 {
2352 LOG_WARNING("target not halted");
2353 return ERROR_TARGET_NOT_HALTED;
2354 }
2355
2356 if (!watchpoint->set)
2357 {
2358 LOG_WARNING("breakpoint not set");
2359 return ERROR_OK;
2360 }
2361
2362 if (watchpoint->set == 1)
2363 {
2364 dbcon_value &= ~0x3;
2365 xscale_set_reg_u32(dbcon, dbcon_value);
2366 xscale->dbr0_used = 0;
2367 }
2368 else if (watchpoint->set == 2)
2369 {
2370 dbcon_value &= ~0xc;
2371 xscale_set_reg_u32(dbcon, dbcon_value);
2372 xscale->dbr1_used = 0;
2373 }
2374 watchpoint->set = 0;
2375
2376 return ERROR_OK;
2377 }
2378
2379 static int xscale_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
2380 {
2381 armv4_5_common_t *armv4_5 = target->arch_info;
2382 xscale_common_t *xscale = armv4_5->arch_info;
2383
2384 if (target->state != TARGET_HALTED)
2385 {
2386 LOG_WARNING("target not halted");
2387 return ERROR_TARGET_NOT_HALTED;
2388 }
2389
2390 if (watchpoint->set)
2391 {
2392 xscale_unset_watchpoint(target, watchpoint);
2393 }
2394
2395 xscale->dbr_available++;
2396
2397 return ERROR_OK;
2398 }
2399
2400 static int xscale_get_reg(reg_t *reg)
2401 {
2402 xscale_reg_t *arch_info = reg->arch_info;
2403 target_t *target = arch_info->target;
2404 armv4_5_common_t *armv4_5 = target->arch_info;
2405 xscale_common_t *xscale = armv4_5->arch_info;
2406
2407 /* DCSR, TX and RX are accessible via JTAG */
2408 if (strcmp(reg->name, "XSCALE_DCSR") == 0)
2409 {
2410 return xscale_read_dcsr(arch_info->target);
2411 }
2412 else if (strcmp(reg->name, "XSCALE_TX") == 0)
2413 {
2414 /* 1 = consume register content */
2415 return xscale_read_tx(arch_info->target, 1);
2416 }
2417 else if (strcmp(reg->name, "XSCALE_RX") == 0)
2418 {
2419 /* can't read from RX register (host -> debug handler) */
2420 return ERROR_OK;
2421 }
2422 else if (strcmp(reg->name, "XSCALE_TXRXCTRL") == 0)
2423 {
2424 /* can't (explicitly) read from TXRXCTRL register */
2425 return ERROR_OK;
2426 }
2427 else /* Other DBG registers have to be transfered by the debug handler */
2428 {
2429 /* send CP read request (command 0x40) */
2430 xscale_send_u32(target, 0x40);
2431
2432 /* send CP register number */
2433 xscale_send_u32(target, arch_info->dbg_handler_number);
2434
2435 /* read register value */
2436 xscale_read_tx(target, 1);
2437 buf_cpy(xscale->reg_cache->reg_list[XSCALE_TX].value, reg->value, 32);
2438
2439 reg->dirty = 0;
2440 reg->valid = 1;
2441 }
2442
2443 return ERROR_OK;
2444 }
2445
2446 static int xscale_set_reg(reg_t *reg, uint8_t* buf)
2447 {
2448 xscale_reg_t *arch_info = reg->arch_info;
2449 target_t *target = arch_info->target;
2450 armv4_5_common_t *armv4_5 = target->arch_info;
2451 xscale_common_t *xscale = armv4_5->arch_info;
2452 uint32_t value = buf_get_u32(buf, 0, 32);
2453
2454 /* DCSR, TX and RX are accessible via JTAG */
2455 if (strcmp(reg->name, "XSCALE_DCSR") == 0)
2456 {
2457 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 0, 32, value);
2458 return xscale_write_dcsr(arch_info->target, -1, -1);
2459 }
2460 else if (strcmp(reg->name, "XSCALE_RX") == 0)
2461 {
2462 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_RX].value, 0, 32, value);
2463 return xscale_write_rx(arch_info->target);
2464 }
2465 else if (strcmp(reg->name, "XSCALE_TX") == 0)
2466 {
2467 /* can't write to TX register (debug-handler -> host) */
2468 return ERROR_OK;
2469 }
2470 else if (strcmp(reg->name, "XSCALE_TXRXCTRL") == 0)
2471 {
2472 /* can't (explicitly) write to TXRXCTRL register */
2473 return ERROR_OK;
2474 }
2475 else /* Other DBG registers have to be transfered by the debug handler */
2476 {
2477 /* send CP write request (command 0x41) */
2478 xscale_send_u32(target, 0x41);
2479
2480 /* send CP register number */
2481 xscale_send_u32(target, arch_info->dbg_handler_number);
2482
2483 /* send CP register value */
2484 xscale_send_u32(target, value);
2485 buf_set_u32(reg->value, 0, 32, value);
2486 }
2487
2488 return ERROR_OK;
2489 }
2490
2491 static int xscale_write_dcsr_sw(target_t *target, uint32_t value)
2492 {
2493 /* get pointers to arch-specific information */
2494 armv4_5_common_t *armv4_5 = target->arch_info;
2495 xscale_common_t *xscale = armv4_5->arch_info;
2496 reg_t *dcsr = &xscale->reg_cache->reg_list[XSCALE_DCSR];
2497 xscale_reg_t *dcsr_arch_info = dcsr->arch_info;
2498
2499 /* send CP write request (command 0x41) */
2500 xscale_send_u32(target, 0x41);
2501
2502 /* send CP register number */
2503 xscale_send_u32(target, dcsr_arch_info->dbg_handler_number);
2504
2505 /* send CP register value */
2506 xscale_send_u32(target, value);
2507 buf_set_u32(dcsr->value, 0, 32, value);
2508
2509 return ERROR_OK;
2510 }
2511
2512 static int xscale_read_trace(target_t *target)
2513 {
2514 /* get pointers to arch-specific information */
2515 armv4_5_common_t *armv4_5 = target->arch_info;
2516 xscale_common_t *xscale = armv4_5->arch_info;
2517 xscale_trace_data_t **trace_data_p;
2518
2519 /* 258 words from debug handler
2520 * 256 trace buffer entries
2521 * 2 checkpoint addresses
2522 */
2523 uint32_t trace_buffer[258];
2524 int is_address[256];
2525 int i, j;
2526
2527 if (target->state != TARGET_HALTED)
2528 {
2529 LOG_WARNING("target must be stopped to read trace data");
2530 return ERROR_TARGET_NOT_HALTED;
2531 }
2532
2533 /* send read trace buffer command (command 0x61) */
2534 xscale_send_u32(target, 0x61);
2535
2536 /* receive trace buffer content */
2537 xscale_receive(target, trace_buffer, 258);
2538
2539 /* parse buffer backwards to identify address entries */
2540 for (i = 255; i >= 0; i--)
2541 {
2542 is_address[i] = 0;
2543 if (((trace_buffer[i] & 0xf0) == 0x90) ||
2544 ((trace_buffer[i] & 0xf0) == 0xd0))
2545 {
2546 if (i >= 3)
2547 is_address[--i] = 1;
2548 if (i >= 2)
2549 is_address[--i] = 1;
2550 if (i >= 1)
2551 is_address[--i] = 1;
2552 if (i >= 0)
2553 is_address[--i] = 1;
2554 }
2555 }
2556
2557
2558 /* search first non-zero entry */
2559 for (j = 0; (j < 256) && (trace_buffer[j] == 0) && (!is_address[j]); j++)
2560 ;
2561
2562 if (j == 256)
2563 {
2564 LOG_DEBUG("no trace data collected");
2565 return ERROR_XSCALE_NO_TRACE_DATA;
2566 }
2567
2568 for (trace_data_p = &xscale->trace.data; *trace_data_p; trace_data_p = &(*trace_data_p)->next)
2569 ;
2570
2571 *trace_data_p = malloc(sizeof(xscale_trace_data_t));
2572 (*trace_data_p)->next = NULL;
2573 (*trace_data_p)->chkpt0 = trace_buffer[256];
2574 (*trace_data_p)->chkpt1 = trace_buffer[257];
2575 (*trace_data_p)->last_instruction = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
2576 (*trace_data_p)->entries = malloc(sizeof(xscale_trace_entry_t) * (256 - j));
2577 (*trace_data_p)->depth = 256 - j;
2578
2579 for (i = j; i < 256; i++)
2580 {
2581 (*trace_data_p)->entries[i - j].data = trace_buffer[i];
2582 if (is_address[i])
2583 (*trace_data_p)->entries[i - j].type = XSCALE_TRACE_ADDRESS;
2584 else
2585 (*trace_data_p)->entries[i - j].type = XSCALE_TRACE_MESSAGE;
2586 }
2587
2588 return ERROR_OK;
2589 }
2590
2591 static int xscale_read_instruction(target_t *target,
2592 arm_instruction_t *instruction)
2593 {
2594 /* get pointers to arch-specific information */
2595 armv4_5_common_t *armv4_5 = target->arch_info;
2596 xscale_common_t *xscale = armv4_5->arch_info;
2597 int i;
2598 int section = -1;
2599 uint32_t size_read;
2600 uint32_t opcode;
2601 int retval;
2602
2603 if (!xscale->trace.image)
2604 return ERROR_TRACE_IMAGE_UNAVAILABLE;
2605
2606 /* search for the section the current instruction belongs to */
2607 for (i = 0; i < xscale->trace.image->num_sections; i++)
2608 {
2609 if ((xscale->trace.image->sections[i].base_address <= xscale->trace.current_pc) &&
2610 (xscale->trace.image->sections[i].base_address + xscale->trace.image->sections[i].size > xscale->trace.current_pc))
2611 {
2612 section = i;
2613 break;
2614 }
2615 }
2616
2617 if (section == -1)
2618 {
2619 /* current instruction couldn't be found in the image */
2620 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
2621 }
2622
2623 if (xscale->trace.core_state == ARMV4_5_STATE_ARM)
2624 {
2625 uint8_t buf[4];
2626 if ((retval = image_read_section(xscale->trace.image, section,
2627 xscale->trace.current_pc - xscale->trace.image->sections[section].base_address,
2628 4, buf, &size_read)) != ERROR_OK)
2629 {
2630 LOG_ERROR("error while reading instruction: %i", retval);
2631 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
2632 }
2633 opcode = target_buffer_get_u32(target, buf);
2634 arm_evaluate_opcode(opcode, xscale->trace.current_pc, instruction);
2635 }
2636 else if (xscale->trace.core_state == ARMV4_5_STATE_THUMB)
2637 {
2638 uint8_t buf[2];
2639 if ((retval = image_read_section(xscale->trace.image, section,
2640 xscale->trace.current_pc - xscale->trace.image->sections[section].base_address,
2641 2, buf, &size_read)) != ERROR_OK)
2642 {
2643 LOG_ERROR("error while reading instruction: %i", retval);
2644 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
2645 }
2646 opcode = target_buffer_get_u16(target, buf);
2647 thumb_evaluate_opcode(opcode, xscale->trace.current_pc, instruction);
2648 }
2649 else
2650 {
2651 LOG_ERROR("BUG: unknown core state encountered");
2652 exit(-1);
2653 }
2654
2655 return ERROR_OK;
2656 }
2657
2658 static int xscale_branch_address(xscale_trace_data_t *trace_data,
2659 int i, uint32_t *target)
2660 {
2661 /* if there are less than four entries prior to the indirect branch message
2662 * we can't extract the address */
2663 if (i < 4)
2664 {
2665 return -1;
2666 }
2667
2668 *target = (trace_data->entries[i-1].data) | (trace_data->entries[i-2].data << 8) |
2669 (trace_data->entries[i-3].data << 16) | (trace_data->entries[i-4].data << 24);
2670
2671 return 0;
2672 }
2673
2674 static int xscale_analyze_trace(target_t *target, command_context_t *cmd_ctx)
2675 {
2676 /* get pointers to arch-specific information */
2677 armv4_5_common_t *armv4_5 = target->arch_info;
2678 xscale_common_t *xscale = armv4_5->arch_info;
2679 int next_pc_ok = 0;
2680 uint32_t next_pc = 0x0;
2681 xscale_trace_data_t *trace_data = xscale->trace.data;
2682 int retval;
2683
2684 while (trace_data)
2685 {
2686 int i, chkpt;
2687 int rollover;
2688 int branch;
2689 int exception;
2690 xscale->trace.core_state = ARMV4_5_STATE_ARM;
2691
2692 chkpt = 0;
2693 rollover = 0;
2694
2695 for (i = 0; i < trace_data->depth; i++)
2696 {
2697 next_pc_ok = 0;
2698 branch = 0;
2699 exception = 0;
2700
2701 if (trace_data->entries[i].type == XSCALE_TRACE_ADDRESS)
2702 continue;
2703
2704 switch ((trace_data->entries[i].data & 0xf0) >> 4)
2705 {
2706 case 0: /* Exceptions */
2707 case 1:
2708 case 2:
2709 case 3:
2710 case 4:
2711 case 5:
2712 case 6:
2713 case 7:
2714 exception = (trace_data->entries[i].data & 0x70) >> 4;
2715 next_pc_ok = 1;
2716 next_pc = (trace_data->entries[i].data & 0xf0) >> 2;
2717 command_print(cmd_ctx, "--- exception %i ---", (trace_data->entries[i].data & 0xf0) >> 4);
2718 break;
2719 case 8: /* Direct Branch */
2720 branch = 1;
2721 break;
2722 case 9: /* Indirect Branch */
2723 branch = 1;
2724 if (xscale_branch_address(trace_data, i, &next_pc) == 0)
2725 {
2726 next_pc_ok = 1;
2727 }
2728 break;
2729 case 13: /* Checkpointed Indirect Branch */
2730 if (xscale_branch_address(trace_data, i, &next_pc) == 0)
2731 {
2732 next_pc_ok = 1;
2733 if (((chkpt == 0) && (next_pc != trace_data->chkpt0))
2734 || ((chkpt == 1) && (next_pc != trace_data->chkpt1)))
2735 LOG_WARNING("checkpointed indirect branch target address doesn't match checkpoint");
2736 }
2737 /* explicit fall-through */
2738 case 12: /* Checkpointed Direct Branch */
2739 branch = 1;
2740 if (chkpt == 0)
2741 {
2742 next_pc_ok = 1;
2743 next_pc = trace_data->chkpt0;
2744 chkpt++;
2745 }
2746 else if (chkpt == 1)
2747 {
2748 next_pc_ok = 1;
2749 next_pc = trace_data->chkpt0;
2750 chkpt++;
2751 }
2752 else
2753 {
2754 LOG_WARNING("more than two checkpointed branches encountered");
2755 }
2756 break;
2757 case 15: /* Roll-over */
2758 rollover++;
2759 continue;
2760 default: /* Reserved */
2761 command_print(cmd_ctx, "--- reserved trace message ---");
2762 LOG_ERROR("BUG: trace message %i is reserved", (trace_data->entries[i].data & 0xf0) >> 4);
2763 return ERROR_OK;
2764 }
2765
2766 if (xscale->trace.pc_ok)
2767 {
2768 int executed = (trace_data->entries[i].data & 0xf) + rollover * 16;
2769 arm_instruction_t instruction;
2770
2771 if ((exception == 6) || (exception == 7))
2772 {
2773 /* IRQ or FIQ exception, no instruction executed */
2774 executed -= 1;
2775 }
2776
2777 while (executed-- >= 0)
2778 {
2779 if ((retval = xscale_read_instruction(target, &instruction)) != ERROR_OK)
2780 {
2781 /* can't continue tracing with no image available */
2782 if (retval == ERROR_TRACE_IMAGE_UNAVAILABLE)
2783 {
2784 return retval;
2785 }
2786 else if (retval == ERROR_TRACE_INSTRUCTION_UNAVAILABLE)
2787 {
2788 /* TODO: handle incomplete images */
2789 }
2790 }
2791
2792 /* a precise abort on a load to the PC is included in the incremental
2793 * word count, other instructions causing data aborts are not included
2794 */
2795 if ((executed == 0) && (exception == 4)
2796 && ((instruction.type >= ARM_LDR) && (instruction.type <= ARM_LDM)))
2797 {
2798 if ((instruction.type == ARM_LDM)
2799 && ((instruction.info.load_store_multiple.register_list & 0x8000) == 0))
2800 {
2801 executed--;
2802 }
2803 else if (((instruction.type >= ARM_LDR) && (instruction.type <= ARM_LDRSH))
2804 && (instruction.info.load_store.Rd != 15))
2805 {
2806 executed--;
2807 }
2808 }
2809
2810 /* only the last instruction executed
2811 * (the one that caused the control flow change)
2812 * could be a taken branch
2813 */
2814 if (((executed == -1) && (branch == 1)) &&
2815 (((instruction.type == ARM_B) ||
2816 (instruction.type == ARM_BL) ||
2817 (instruction.type == ARM_BLX)) &&
2818 (instruction.info.b_bl_bx_blx.target_address != 0xffffffff)))
2819 {
2820 xscale->trace.current_pc = instruction.info.b_bl_bx_blx.target_address;
2821 }
2822 else
2823 {
2824 xscale->trace.current_pc += (xscale->trace.core_state == ARMV4_5_STATE_ARM) ? 4 : 2;
2825 }
2826 command_print(cmd_ctx, "%s", instruction.text);
2827 }
2828
2829 rollover = 0;
2830 }
2831
2832 if (next_pc_ok)
2833 {
2834 xscale->trace.current_pc = next_pc;
2835 xscale->trace.pc_ok = 1;
2836 }
2837 }
2838
2839 for (; xscale->trace.current_pc < trace_data->last_instruction; xscale->trace.current_pc += (xscale->trace.core_state == ARMV4_5_STATE_ARM) ? 4 : 2)
2840 {
2841 arm_instruction_t instruction;
2842 if ((retval = xscale_read_instruction(target, &instruction)) != ERROR_OK)
2843 {
2844 /* can't continue tracing with no image available */
2845 if (retval == ERROR_TRACE_IMAGE_UNAVAILABLE)
2846 {
2847 return retval;
2848 }
2849 else if (retval == ERROR_TRACE_INSTRUCTION_UNAVAILABLE)
2850 {
2851 /* TODO: handle incomplete images */
2852 }
2853 }
2854 command_print(cmd_ctx, "%s", instruction.text);
2855 }
2856
2857 trace_data = trace_data->next;
2858 }
2859
2860 return ERROR_OK;
2861 }
2862
2863 static void xscale_build_reg_cache(target_t *target)
2864 {
2865 /* get pointers to arch-specific information */
2866 armv4_5_common_t *armv4_5 = target->arch_info;
2867 xscale_common_t *xscale = armv4_5->arch_info;
2868
2869 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
2870 xscale_reg_t *arch_info = malloc(sizeof(xscale_reg_arch_info));
2871 int i;
2872 int num_regs = sizeof(xscale_reg_arch_info) / sizeof(xscale_reg_t);
2873
2874 (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
2875 armv4_5->core_cache = (*cache_p);
2876
2877 /* register a register arch-type for XScale dbg registers only once */
2878 if (xscale_reg_arch_type == -1)
2879 xscale_reg_arch_type = register_reg_arch_type(xscale_get_reg, xscale_set_reg);
2880
2881 (*cache_p)->next = malloc(sizeof(reg_cache_t));
2882 cache_p = &(*cache_p)->next;
2883
2884 /* fill in values for the xscale reg cache */
2885 (*cache_p)->name = "XScale registers";
2886 (*cache_p)->next = NULL;
2887 (*cache_p)->reg_list = malloc(num_regs * sizeof(reg_t));
2888 (*cache_p)->num_regs = num_regs;
2889
2890 for (i = 0; i < num_regs; i++)
2891 {
2892 (*cache_p)->reg_list[i].name = xscale_reg_list[i];
2893 (*cache_p)->reg_list[i].value = calloc(4, 1);
2894 (*cache_p)->reg_list[i].dirty = 0;
2895 (*cache_p)->reg_list[i].valid = 0;
2896 (*cache_p)->reg_list[i].size = 32;
2897 (*cache_p)->reg_list[i].bitfield_desc = NULL;
2898 (*cache_p)->reg_list[i].num_bitfields = 0;
2899 (*cache_p)->reg_list[i].arch_info = &arch_info[i];
2900 (*cache_p)->reg_list[i].arch_type = xscale_reg_arch_type;
2901 arch_info[i] = xscale_reg_arch_info[i];
2902 arch_info[i].target = target;
2903 }
2904
2905 xscale->reg_cache = (*cache_p);
2906 }
2907
2908 static int xscale_init_target(struct command_context_s *cmd_ctx,
2909 struct target_s *target)
2910 {
2911 xscale_build_reg_cache(target);
2912 return ERROR_OK;
2913 }
2914
2915 static int xscale_quit(void)
2916 {
2917 jtag_add_runtest(100, TAP_RESET);
2918 return ERROR_OK;
2919 }
2920
2921 static int xscale_init_arch_info(target_t *target,
2922 xscale_common_t *xscale, jtag_tap_t *tap, const char *variant)
2923 {
2924 armv4_5_common_t *armv4_5;
2925 uint32_t high_reset_branch, low_reset_branch;
2926 int i;
2927
2928 armv4_5 = &xscale->armv4_5_common;
2929
2930 /* store architecture specfic data (none so far) */
2931 xscale->arch_info = NULL;
2932 xscale->common_magic = XSCALE_COMMON_MAGIC;
2933
2934 /* we don't really *need* variant info ... */
2935 if (variant) {
2936 int ir_length = 0;
2937
2938 if (strcmp(variant, "pxa250") == 0
2939 || strcmp(variant, "pxa255") == 0
2940 || strcmp(variant, "pxa26x") == 0)
2941 ir_length = 5;
2942 else if (strcmp(variant, "pxa27x") == 0
2943 || strcmp(variant, "ixp42x") == 0
2944 || strcmp(variant, "ixp45x") == 0
2945 || strcmp(variant, "ixp46x") == 0)
2946 ir_length = 7;
2947 else
2948 LOG_WARNING("%s: unrecognized variant %s",
2949 tap->dotted_name, variant);
2950
2951 if (ir_length && ir_length != tap->ir_length) {
2952 LOG_WARNING("%s: IR length for %s is %d; fixing",
2953 tap->dotted_name, variant, ir_length);
2954 tap->ir_length = ir_length;
2955 }
2956 }
2957
2958 /* the debug handler isn't installed (and thus not running) at this time */
2959 xscale->handler_installed = 0;
2960 xscale->handler_running = 0;
2961 xscale->handler_address = 0xfe000800;
2962
2963 /* clear the vectors we keep locally for reference */
2964 memset(xscale->low_vectors, 0, sizeof(xscale->low_vectors));
2965 memset(xscale->high_vectors, 0, sizeof(xscale->high_vectors));
2966
2967 /* no user-specified vectors have been configured yet */
2968 xscale->static_low_vectors_set = 0x0;
2969 xscale->static_high_vectors_set = 0x0;
2970
2971 /* calculate branches to debug handler */
2972 low_reset_branch = (xscale->handler_address + 0x20 - 0x0 - 0x8) >> 2;
2973 high_reset_branch = (xscale->handler_address + 0x20 - 0xffff0000 - 0x8) >> 2;
2974
2975 xscale->low_vectors[0] = ARMV4_5_B((low_reset_branch & 0xffffff), 0);
2976 xscale->high_vectors[0] = ARMV4_5_B((high_reset_branch & 0xffffff), 0);
2977
2978 for (i = 1; i <= 7; i++)
2979 {
2980 xscale->low_vectors[i] = ARMV4_5_B(0xfffffe, 0);
2981 xscale->high_vectors[i] = ARMV4_5_B(0xfffffe, 0);
2982 }
2983
2984 /* 64kB aligned region used for DCache cleaning */
2985 xscale->cache_clean_address = 0xfffe0000;
2986
2987 xscale->hold_rst = 0;
2988 xscale->external_debug_break = 0;
2989
2990 xscale->ibcr_available = 2;
2991 xscale->ibcr0_used = 0;
2992 xscale->ibcr1_used = 0;
2993
2994 xscale->dbr_available = 2;
2995 xscale->dbr0_used = 0;
2996 xscale->dbr1_used = 0;
2997
2998 xscale->arm_bkpt = ARMV5_BKPT(0x0);
2999 xscale->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
3000
3001 xscale->vector_catch = 0x1;
3002
3003 xscale->trace.capture_status = TRACE_IDLE;
3004 xscale->trace.data = NULL;
3005 xscale->trace.image = NULL;
3006 xscale->trace.buffer_enabled = 0;
3007 xscale->trace.buffer_fill = 0;
3008
3009 /* prepare ARMv4/5 specific information */
3010 armv4_5->arch_info = xscale;
3011 armv4_5->read_core_reg = xscale_read_core_reg;
3012 armv4_5->write_core_reg = xscale_write_core_reg;
3013 armv4_5->full_context = xscale_full_context;
3014
3015 armv4_5_init_arch_info(target, armv4_5);
3016
3017 xscale->armv4_5_mmu.armv4_5_cache.ctype = -1;
3018 xscale->armv4_5_mmu.get_ttb = xscale_get_ttb;
3019 xscale->armv4_5_mmu.read_memory = xscale_read_memory;
3020 xscale->armv4_5_mmu.write_memory = xscale_write_memory;
3021 xscale->armv4_5_mmu.disable_mmu_caches = xscale_disable_mmu_caches;
3022 xscale->armv4_5_mmu.enable_mmu_caches = xscale_enable_mmu_caches;
3023 xscale->armv4_5_mmu.has_tiny_pages = 1;
3024 xscale->armv4_5_mmu.mmu_enabled = 0;
3025
3026 return ERROR_OK;
3027 }
3028
3029 static int xscale_target_create(struct target_s *target, Jim_Interp *interp)
3030 {
3031 xscale_common_t *xscale;
3032
3033 if (xscale_debug_handler_size > 0x800) {
3034 LOG_ERROR("debug_handler.bin: larger than 2kb");
3035 return ERROR_FAIL;
3036 }
3037
3038 xscale = calloc(1, sizeof(*xscale));
3039 if (!xscale)
3040 return ERROR_FAIL;
3041
3042 return xscale_init_arch_info(target, xscale, target->tap,
3043 target->variant);
3044 }
3045
3046 static int
3047 xscale_handle_debug_handler_command(struct command_context_s *cmd_ctx,
3048 char *cmd, char **args, int argc)
3049 {
3050 target_t *target = NULL;
3051 armv4_5_common_t *armv4_5;
3052 xscale_common_t *xscale;
3053
3054 uint32_t handler_address;
3055
3056 if (argc < 2)
3057 {
3058 LOG_ERROR("'xscale debug_handler <target#> <address>' command takes two required operands");
3059 return ERROR_OK;
3060 }
3061
3062 if ((target = get_target(args[0])) == NULL)
3063 {
3064 LOG_ERROR("target '%s' not defined", args[0]);
3065 return ERROR_FAIL;
3066 }
3067
3068 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3069 {
3070 return ERROR_FAIL;
3071 }
3072
3073 handler_address = strtoul(args[1], NULL, 0);
3074
3075 if (((handler_address >= 0x800) && (handler_address <= 0x1fef800)) ||
3076 ((handler_address >= 0xfe000800) && (handler_address <= 0xfffff800)))
3077 {
3078 xscale->handler_address = handler_address;
3079 }
3080 else
3081 {
3082 LOG_ERROR("xscale debug_handler <address> must be between 0x800 and 0x1fef800 or between 0xfe000800 and 0xfffff800");
3083 return ERROR_FAIL;
3084 }
3085
3086 return ERROR_OK;
3087 }
3088
3089 static int
3090 xscale_handle_cache_clean_address_command(struct command_context_s *cmd_ctx,
3091 char *cmd, char **args, int argc)
3092 {
3093 target_t *target = NULL;
3094 armv4_5_common_t *armv4_5;
3095 xscale_common_t *xscale;
3096
3097 uint32_t cache_clean_address;
3098
3099 if (argc < 2)
3100 {
3101 return ERROR_COMMAND_SYNTAX_ERROR;
3102 }
3103
3104 target = get_target(args[0]);
3105 if (target == NULL)
3106 {
3107 LOG_ERROR("target '%s' not defined", args[0]);
3108 return ERROR_FAIL;
3109 }
3110
3111 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3112 {
3113 return ERROR_FAIL;
3114 }
3115
3116 cache_clean_address = strtoul(args[1], NULL, 0);
3117
3118 if (cache_clean_address & 0xffff)
3119 {
3120 LOG_ERROR("xscale cache_clean_address <address> must be 64kb aligned");
3121 }
3122 else
3123 {
3124 xscale->cache_clean_address = cache_clean_address;
3125 }
3126
3127 return ERROR_OK;
3128 }
3129
3130 static int
3131 xscale_handle_cache_info_command(struct command_context_s *cmd_ctx,
3132 char *cmd, char **args, int argc)
3133 {
3134 target_t *target = get_current_target(cmd_ctx);
3135 armv4_5_common_t *armv4_5;
3136 xscale_common_t *xscale;
3137
3138 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3139 {
3140 return ERROR_OK;
3141 }
3142
3143 return armv4_5_handle_cache_info_command(cmd_ctx, &xscale->armv4_5_mmu.armv4_5_cache);
3144 }
3145
3146 static int xscale_virt2phys(struct target_s *target,
3147 uint32_t virtual, uint32_t *physical)
3148 {
3149 armv4_5_common_t *armv4_5;
3150 xscale_common_t *xscale;
3151 int retval;
3152 int type;
3153 uint32_t cb;
3154 int domain;
3155 uint32_t ap;
3156
3157 if ((retval = xscale_get_arch_pointers(target, &armv4_5, &xscale)) != ERROR_OK)
3158 {
3159 return retval;
3160 }
3161 uint32_t ret = armv4_5_mmu_translate_va(target, &xscale->armv4_5_mmu, virtual, &type, &cb, &domain, &ap);
3162 if (type == -1)
3163 {
3164 return ret;
3165 }
3166 *physical = ret;
3167 return ERROR_OK;
3168 }
3169
3170 static int xscale_mmu(struct target_s *target, int *enabled)
3171 {
3172 armv4_5_common_t *armv4_5 = target->arch_info;
3173 xscale_common_t *xscale = armv4_5->arch_info;
3174
3175 if (target->state != TARGET_HALTED)
3176 {
3177 LOG_ERROR("Target not halted");
3178 return ERROR_TARGET_INVALID;
3179 }
3180 *enabled = xscale->armv4_5_mmu.mmu_enabled;
3181 return ERROR_OK;
3182 }
3183
3184 static int xscale_handle_mmu_command(command_context_t *cmd_ctx,
3185 char *cmd, char **args, int argc)
3186 {
3187 target_t *target = get_current_target(cmd_ctx);
3188 armv4_5_common_t *armv4_5;
3189 xscale_common_t *xscale;
3190
3191 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3192 {
3193 return ERROR_OK;
3194 }
3195
3196 if (target->state != TARGET_HALTED)
3197 {
3198 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3199 return ERROR_OK;
3200 }
3201
3202 if (argc >= 1)
3203 {
3204 if (strcmp("enable", args[0]) == 0)
3205 {
3206 xscale_enable_mmu_caches(target, 1, 0, 0);
3207 xscale->armv4_5_mmu.mmu_enabled = 1;
3208 }
3209 else if (strcmp("disable", args[0]) == 0)
3210 {
3211 xscale_disable_mmu_caches(target, 1, 0, 0);
3212 xscale->armv4_5_mmu.mmu_enabled = 0;
3213 }
3214 }
3215
3216 command_print(cmd_ctx, "mmu %s", (xscale->armv4_5_mmu.mmu_enabled) ? "enabled" : "disabled");
3217
3218 return ERROR_OK;
3219 }
3220
3221 static int xscale_handle_idcache_command(command_context_t *cmd_ctx,
3222 char *cmd, char **args, int argc)
3223 {
3224 target_t *target = get_current_target(cmd_ctx);
3225 armv4_5_common_t *armv4_5;
3226 xscale_common_t *xscale;
3227 int icache = 0, dcache = 0;
3228
3229 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3230 {
3231 return ERROR_OK;
3232 }
3233
3234 if (target->state != TARGET_HALTED)
3235 {
3236 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3237 return ERROR_OK;
3238 }
3239
3240 if (strcmp(cmd, "icache") == 0)
3241 icache = 1;
3242 else if (strcmp(cmd, "dcache") == 0)
3243 dcache = 1;
3244
3245 if (argc >= 1)
3246 {
3247 if (strcmp("enable", args[0]) == 0)
3248 {
3249 xscale_enable_mmu_caches(target, 0, dcache, icache);
3250
3251 if (icache)
3252 xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 1;
3253 else if (dcache)
3254 xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 1;
3255 }
3256 else if (strcmp("disable", args[0]) == 0)
3257 {
3258 xscale_disable_mmu_caches(target, 0, dcache, icache);
3259
3260 if (icache)
3261 xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
3262 else if (dcache)
3263 xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
3264 }
3265 }
3266
3267 if (icache)
3268 command_print(cmd_ctx, "icache %s", (xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled) ? "enabled" : "disabled");
3269
3270 if (dcache)
3271 command_print(cmd_ctx, "dcache %s", (xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) ? "enabled" : "disabled");
3272
3273 return ERROR_OK;
3274 }
3275
3276 static int xscale_handle_vector_catch_command(command_context_t *cmd_ctx,
3277 char *cmd, char **args, int argc)
3278 {
3279 target_t *target = get_current_target(cmd_ctx);
3280 armv4_5_common_t *armv4_5;
3281 xscale_common_t *xscale;
3282
3283 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3284 {
3285 return ERROR_OK;
3286 }
3287
3288 if (argc < 1)
3289 {
3290 command_print(cmd_ctx, "usage: xscale vector_catch [mask]");
3291 }
3292 else
3293 {
3294 xscale->vector_catch = strtoul(args[0], NULL, 0);
3295 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 8, xscale->vector_catch);
3296 xscale_write_dcsr(target, -1, -1);
3297 }
3298
3299 command_print(cmd_ctx, "vector catch mask: 0x%2.2x", xscale->vector_catch);
3300
3301 return ERROR_OK;
3302 }
3303
3304
3305 static int xscale_handle_vector_table_command(command_context_t *cmd_ctx,
3306 char *cmd, char **args, int argc)
3307 {
3308 target_t *target = get_current_target(cmd_ctx);
3309 armv4_5_common_t *armv4_5;
3310 xscale_common_t *xscale;
3311 int err = 0;
3312
3313 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3314 {
3315 return ERROR_OK;
3316 }
3317
3318 if (argc == 0) /* print current settings */
3319 {
3320 int idx;
3321
3322 command_print(cmd_ctx, "active user-set static vectors:");
3323 for (idx = 1; idx < 8; idx++)
3324 if (xscale->static_low_vectors_set & (1 << idx))
3325 command_print(cmd_ctx, "low %d: 0x%" PRIx32, idx, xscale->static_low_vectors[idx]);
3326 for (idx = 1; idx < 8; idx++)
3327 if (xscale->static_high_vectors_set & (1 << idx))
3328 command_print(cmd_ctx, "high %d: 0x%" PRIx32, idx, xscale->static_high_vectors[idx]);
3329 return ERROR_OK;
3330 }
3331
3332 if (argc != 3)
3333 err = 1;
3334 else
3335 {
3336 int idx;
3337 uint32_t vec;
3338 idx = strtoul(args[1], NULL, 0);
3339 vec = strtoul(args[2], NULL, 0);
3340
3341 if (idx < 1 || idx >= 8)
3342 err = 1;
3343
3344 if (!err && strcmp(args[0], "low") == 0)
3345 {
3346 xscale->static_low_vectors_set |= (1<<idx);
3347 xscale->static_low_vectors[idx] = vec;
3348 }
3349 else if (!err && (strcmp(args[0], "high") == 0))
3350 {
3351 xscale->static_high_vectors_set |= (1<<idx);
3352 xscale->static_high_vectors[idx] = vec;
3353 }
3354 else
3355 err = 1;
3356 }
3357
3358 if (err)
3359 command_print(cmd_ctx, "usage: xscale vector_table <high|low> <index> <code>");
3360
3361 return ERROR_OK;
3362 }
3363
3364
3365 static int
3366 xscale_handle_trace_buffer_command(struct command_context_s *cmd_ctx,
3367 char *cmd, char **args, int argc)
3368 {
3369 target_t *target = get_current_target(cmd_ctx);
3370 armv4_5_common_t *armv4_5;
3371 xscale_common_t *xscale;
3372 uint32_t dcsr_value;
3373
3374 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3375 {
3376 return ERROR_OK;
3377 }
3378
3379 if (target->state != TARGET_HALTED)
3380 {
3381 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3382 return ERROR_OK;
3383 }
3384
3385 if ((argc >= 1) && (strcmp("enable", args[0]) == 0))
3386 {
3387 xscale_trace_data_t *td, *next_td;
3388 xscale->trace.buffer_enabled = 1;
3389
3390 /* free old trace data */
3391 td = xscale->trace.data;
3392 while (td)
3393 {
3394 next_td = td->next;
3395
3396 if (td->entries)
3397 free(td->entries);
3398 free(td);
3399 td = next_td;
3400 }
3401 xscale->trace.data = NULL;
3402 }
3403 else if ((argc >= 1) && (strcmp("disable", args[0]) == 0))
3404 {
3405 xscale->trace.buffer_enabled = 0;
3406 }
3407
3408 if ((argc >= 2) && (strcmp("fill", args[1]) == 0))
3409 {
3410 if (argc >= 3)
3411 xscale->trace.buffer_fill = strtoul(args[2], NULL, 0);
3412 else
3413 xscale->trace.buffer_fill = 1;
3414 }
3415 else if ((argc >= 2) && (strcmp("wrap", args[1]) == 0))
3416 {
3417 xscale->trace.buffer_fill = -1;
3418 }
3419
3420 if (xscale->trace.buffer_enabled)
3421 {
3422 /* if we enable the trace buffer in fill-once
3423 * mode we know the address of the first instruction */
3424 xscale->trace.pc_ok = 1;
3425 xscale->trace.current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
3426 }
3427 else
3428 {
3429 /* otherwise the address is unknown, and we have no known good PC */
3430 xscale->trace.pc_ok = 0;
3431 }
3432
3433 command_print(cmd_ctx, "trace buffer %s (%s)",
3434 (xscale->trace.buffer_enabled) ? "enabled" : "disabled",
3435 (xscale->trace.buffer_fill > 0) ? "fill" : "wrap");
3436
3437 dcsr_value = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 0, 32);
3438 if (xscale->trace.buffer_fill >= 0)
3439 xscale_write_dcsr_sw(target, (dcsr_value & 0xfffffffc) | 2);
3440 else
3441 xscale_write_dcsr_sw(target, dcsr_value & 0xfffffffc);
3442
3443 return ERROR_OK;
3444 }
3445
3446 static int
3447 xscale_handle_trace_image_command(struct command_context_s *cmd_ctx,
3448 char *cmd, char **args, int argc)
3449 {
3450 target_t *target;
3451 armv4_5_common_t *armv4_5;
3452 xscale_common_t *xscale;
3453
3454 if (argc < 1)
3455 {
3456 command_print(cmd_ctx, "usage: xscale trace_image <file> [base address] [type]");
3457 return ERROR_OK;
3458 }
3459
3460 target = get_current_target(cmd_ctx);
3461
3462 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3463 {
3464 return ERROR_OK;
3465 }
3466
3467 if (xscale->trace.image)
3468 {
3469 image_close(xscale->trace.image);
3470 free(xscale->trace.image);
3471 command_print(cmd_ctx, "previously loaded image found and closed");
3472 }
3473
3474 xscale->trace.image = malloc(sizeof(image_t));
3475 xscale->trace.image->base_address_set = 0;
3476 xscale->trace.image->start_address_set = 0;
3477
3478 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
3479 if (argc >= 2)
3480 {
3481 xscale->trace.image->base_address_set = 1;
3482 xscale->trace.image->base_address = strtoul(args[1], NULL, 0);
3483 }
3484 else
3485 {
3486 xscale->trace.image->base_address_set = 0;
3487 }
3488
3489 if (image_open(xscale->trace.image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
3490 {
3491 free(xscale->trace.image);
3492 xscale->trace.image = NULL;
3493 return ERROR_OK;
3494 }
3495
3496 return ERROR_OK;
3497 }
3498
3499 static int xscale_handle_dump_trace_command(struct command_context_s *cmd_ctx,
3500 char *cmd, char **args, int argc)
3501 {
3502 target_t *target = get_current_target(cmd_ctx);
3503 armv4_5_common_t *armv4_5;
3504 xscale_common_t *xscale;
3505 xscale_trace_data_t *trace_data;
3506 fileio_t file;
3507
3508 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3509 {
3510 return ERROR_OK;
3511 }
3512
3513 if (target->state != TARGET_HALTED)
3514 {
3515 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3516 return ERROR_OK;
3517 }
3518
3519 if (argc < 1)
3520 {
3521 command_print(cmd_ctx, "usage: xscale dump_trace <file>");
3522 return ERROR_OK;
3523 }
3524
3525 trace_data = xscale->trace.data;
3526
3527 if (!trace_data)
3528 {
3529 command_print(cmd_ctx, "no trace data collected");
3530 return ERROR_OK;
3531 }
3532
3533 if (fileio_open(&file, args[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)
3534 {
3535 return ERROR_OK;
3536 }
3537
3538 while (trace_data)
3539 {
3540 int i;
3541
3542 fileio_write_u32(&file, trace_data->chkpt0);
3543 fileio_write_u32(&file, trace_data->chkpt1);
3544 fileio_write_u32(&file, trace_data->last_instruction);
3545 fileio_write_u32(&file, trace_data->depth);
3546
3547 for (i = 0; i < trace_data->depth; i++)
3548 fileio_write_u32(&file, trace_data->entries[i].data | ((trace_data->entries[i].type & 0xffff) << 16));
3549
3550 trace_data = trace_data->next;
3551 }
3552
3553 fileio_close(&file);
3554
3555 return ERROR_OK;
3556 }
3557
3558 static int
3559 xscale_handle_analyze_trace_buffer_command(struct command_context_s *cmd_ctx,
3560 char *cmd, char **args, int argc)
3561 {
3562 target_t *target = get_current_target(cmd_ctx);
3563 armv4_5_common_t *armv4_5;
3564 xscale_common_t *xscale;
3565
3566 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3567 {
3568 return ERROR_OK;
3569 }
3570
3571 xscale_analyze_trace(target, cmd_ctx);
3572
3573 return ERROR_OK;
3574 }
3575
3576 static int xscale_handle_cp15(command_context_t *cmd_ctx,
3577 char *cmd, char **args, int argc)
3578 {
3579 target_t *target = get_current_target(cmd_ctx);
3580 armv4_5_common_t *armv4_5;
3581 xscale_common_t *xscale;
3582
3583 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3584 {
3585 return ERROR_OK;
3586 }
3587
3588 if (target->state != TARGET_HALTED)
3589 {
3590 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3591 return ERROR_OK;
3592 }
3593 uint32_t reg_no = 0;
3594 reg_t *reg = NULL;
3595 if (argc > 0)
3596 {
3597 reg_no = strtoul(args[0], NULL, 0);
3598 /*translate from xscale cp15 register no to openocd register*/
3599 switch (reg_no)
3600 {
3601 case 0:
3602 reg_no = XSCALE_MAINID;
3603 break;
3604 case 1:
3605 reg_no = XSCALE_CTRL;
3606 break;
3607 case 2:
3608 reg_no = XSCALE_TTB;
3609 break;
3610 case 3:
3611 reg_no = XSCALE_DAC;
3612 break;
3613 case 5:
3614 reg_no = XSCALE_FSR;
3615 break;
3616 case 6:
3617 reg_no = XSCALE_FAR;
3618 break;
3619 case 13:
3620 reg_no = XSCALE_PID;
3621 break;
3622 case 15:
3623 reg_no = XSCALE_CPACCESS;
3624 break;
3625 default:
3626 command_print(cmd_ctx, "invalid register number");
3627 return ERROR_INVALID_ARGUMENTS;
3628 }
3629 reg = &xscale->reg_cache->reg_list[reg_no];
3630
3631 }
3632 if (argc == 1)
3633 {
3634 uint32_t value;
3635
3636 /* read cp15 control register */
3637 xscale_get_reg(reg);
3638 value = buf_get_u32(reg->value, 0, 32);
3639 command_print(cmd_ctx, "%s (/%i): 0x%" PRIx32 "", reg->name, (int)(reg->size), value);
3640 }
3641 else if (argc == 2)
3642 {
3643
3644 uint32_t value = strtoul(args[1], NULL, 0);
3645
3646 /* send CP write request (command 0x41) */
3647 xscale_send_u32(target, 0x41);
3648
3649 /* send CP register number */
3650 xscale_send_u32(target, reg_no);
3651
3652 /* send CP register value */
3653 xscale_send_u32(target, value);
3654
3655 /* execute cpwait to ensure outstanding operations complete */
3656 xscale_send_u32(target, 0x53);
3657 }
3658 else
3659 {
3660 command_print(cmd_ctx, "usage: cp15 [register]<, [value]>");
3661 }
3662
3663 return ERROR_OK;
3664 }
3665
3666 static int xscale_register_commands(struct command_context_s *cmd_ctx)
3667 {
3668 command_t *xscale_cmd;
3669
3670 xscale_cmd = register_command(cmd_ctx, NULL, "xscale", NULL, COMMAND_ANY, "xscale specific commands");
3671
3672 register_command(cmd_ctx, xscale_cmd, "debug_handler", xscale_handle_debug_handler_command, COMMAND_ANY, "'xscale debug_handler <target#> <address>' command takes two required operands");
3673 register_command(cmd_ctx, xscale_cmd, "cache_clean_address", xscale_handle_cache_clean_address_command, COMMAND_ANY, NULL);
3674
3675 register_command(cmd_ctx, xscale_cmd, "cache_info", xscale_handle_cache_info_command, COMMAND_EXEC, NULL);
3676 register_command(cmd_ctx, xscale_cmd, "mmu", xscale_handle_mmu_command, COMMAND_EXEC, "['enable'|'disable'] the MMU");
3677 register_command(cmd_ctx, xscale_cmd, "icache", xscale_handle_idcache_command, COMMAND_EXEC, "['enable'|'disable'] the ICache");
3678 register_command(cmd_ctx, xscale_cmd, "dcache", xscale_handle_idcache_command, COMMAND_EXEC, "['enable'|'disable'] the DCache");
3679
3680 register_command(cmd_ctx, xscale_cmd, "vector_catch", xscale_handle_vector_catch_command, COMMAND_EXEC, "<mask> of vectors that should be catched");
3681 register_command(cmd_ctx, xscale_cmd, "vector_table", xscale_handle_vector_table_command, COMMAND_EXEC, "<high|low> <index> <code> set static code for exception handler entry");
3682
3683 register_command(cmd_ctx, xscale_cmd, "trace_buffer", xscale_handle_trace_buffer_command, COMMAND_EXEC, "<enable | disable> ['fill' [n]|'wrap']");
3684
3685 register_command(cmd_ctx, xscale_cmd, "dump_trace", xscale_handle_dump_trace_command, COMMAND_EXEC, "dump content of trace buffer to <file>");
3686 register_command(cmd_ctx, xscale_cmd, "analyze_trace", xscale_handle_analyze_trace_buffer_command, COMMAND_EXEC, "analyze content of trace buffer");
3687 register_command(cmd_ctx, xscale_cmd, "trace_image", xscale_handle_trace_image_command,
3688 COMMAND_EXEC, "load image from <file> [base address]");
3689
3690 register_command(cmd_ctx, xscale_cmd, "cp15", xscale_handle_cp15, COMMAND_EXEC, "access coproc 15 <register> [value]");
3691
3692 armv4_5_register_commands(cmd_ctx);
3693
3694 return ERROR_OK;
3695 }
3696
3697 target_type_t xscale_target =
3698 {
3699 .name = "xscale",
3700
3701 .poll = xscale_poll,
3702 .arch_state = xscale_arch_state,
3703
3704 .target_request_data = NULL,
3705
3706 .halt = xscale_halt,
3707 .resume = xscale_resume,
3708 .step = xscale_step,
3709
3710 .assert_reset = xscale_assert_reset,
3711 .deassert_reset = xscale_deassert_reset,
3712 .soft_reset_halt = NULL,
3713
3714 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
3715
3716 .read_memory = xscale_read_memory,
3717 .write_memory = xscale_write_memory,
3718 .bulk_write_memory = xscale_bulk_write_memory,
3719 .checksum_memory = arm7_9_checksum_memory,
3720 .blank_check_memory = arm7_9_blank_check_memory,
3721
3722 .run_algorithm = armv4_5_run_algorithm,
3723
3724 .add_breakpoint = xscale_add_breakpoint,
3725 .remove_breakpoint = xscale_remove_breakpoint,
3726 .add_watchpoint = xscale_add_watchpoint,
3727 .remove_watchpoint = xscale_remove_watchpoint,
3728
3729 .register_commands = xscale_register_commands,
3730 .target_create = xscale_target_create,
3731 .init_target = xscale_init_target,
3732 .quit = xscale_quit,
3733
3734 .virt2phys = xscale_virt2phys,
3735 .mmu = xscale_mmu
3736 };

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)