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

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)