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

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)