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

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)