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

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)