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

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)