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

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)