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

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)