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

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)