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

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)