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

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)