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

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)