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

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)