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

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)