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

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)