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

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)