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

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)