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

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)