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

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)