switch to jtag_add_callback() - USB performance fix
[openocd.git] / src / target / xscale.c
1 /***************************************************************************
2 * Copyright (C) 2006, 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2007,2008 Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "xscale.h"
28 #include "arm7_9_common.h"
29 #include "arm_simulator.h"
30 #include "arm_disassembler.h"
31 #include "time_support.h"
32 #include "image.h"
33
34 /* cli handling */
35 int xscale_register_commands(struct command_context_s *cmd_ctx);
36
37 /* forward declarations */
38 int xscale_target_create(struct target_s *target, Jim_Interp *interp);
39 int xscale_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
40 int xscale_quit(void);
41
42 int xscale_arch_state(struct target_s *target);
43 int xscale_poll(target_t *target);
44 int xscale_halt(target_t *target);
45 int xscale_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution);
46 int xscale_step(struct target_s *target, int current, u32 address, int handle_breakpoints);
47 int xscale_debug_entry(target_t *target);
48 int xscale_restore_context(target_t *target);
49
50 int xscale_assert_reset(target_t *target);
51 int xscale_deassert_reset(target_t *target);
52 int xscale_soft_reset_halt(struct target_s *target);
53
54 int xscale_set_reg_u32(reg_t *reg, u32 value);
55
56 int xscale_read_core_reg(struct target_s *target, int num, enum armv4_5_mode mode);
57 int xscale_write_core_reg(struct target_s *target, int num, enum armv4_5_mode mode, u32 value);
58
59 int xscale_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
60 int xscale_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
61 int xscale_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer);
62
63 int xscale_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
64 int xscale_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
65 int xscale_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
66 int xscale_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
67 int xscale_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint);
68 int xscale_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint);
69 void xscale_enable_watchpoints(struct target_s *target);
70 void xscale_enable_breakpoints(struct target_s *target);
71 static int xscale_virt2phys(struct target_s *target, u32 virtual, u32 *physical);
72 static int xscale_mmu(struct target_s *target, int *enabled);
73
74 int xscale_read_trace(target_t *target);
75
76 target_type_t xscale_target =
77 {
78 .name = "xscale",
79
80 .poll = xscale_poll,
81 .arch_state = xscale_arch_state,
82
83 .target_request_data = NULL,
84
85 .halt = xscale_halt,
86 .resume = xscale_resume,
87 .step = xscale_step,
88
89 .assert_reset = xscale_assert_reset,
90 .deassert_reset = xscale_deassert_reset,
91 .soft_reset_halt = xscale_soft_reset_halt,
92
93 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
94
95 .read_memory = xscale_read_memory,
96 .write_memory = xscale_write_memory,
97 .bulk_write_memory = xscale_bulk_write_memory,
98 .checksum_memory = arm7_9_checksum_memory,
99 .blank_check_memory = arm7_9_blank_check_memory,
100
101 .run_algorithm = armv4_5_run_algorithm,
102
103 .add_breakpoint = xscale_add_breakpoint,
104 .remove_breakpoint = xscale_remove_breakpoint,
105 .add_watchpoint = xscale_add_watchpoint,
106 .remove_watchpoint = xscale_remove_watchpoint,
107
108 .register_commands = xscale_register_commands,
109 .target_create = xscale_target_create,
110 .init_target = xscale_init_target,
111 .quit = xscale_quit,
112
113 .virt2phys = xscale_virt2phys,
114 .mmu = xscale_mmu
115 };
116
117 char* xscale_reg_list[] =
118 {
119 "XSCALE_MAINID", /* 0 */
120 "XSCALE_CACHETYPE",
121 "XSCALE_CTRL",
122 "XSCALE_AUXCTRL",
123 "XSCALE_TTB",
124 "XSCALE_DAC",
125 "XSCALE_FSR",
126 "XSCALE_FAR",
127 "XSCALE_PID",
128 "XSCALE_CPACCESS",
129 "XSCALE_IBCR0", /* 10 */
130 "XSCALE_IBCR1",
131 "XSCALE_DBR0",
132 "XSCALE_DBR1",
133 "XSCALE_DBCON",
134 "XSCALE_TBREG",
135 "XSCALE_CHKPT0",
136 "XSCALE_CHKPT1",
137 "XSCALE_DCSR",
138 "XSCALE_TX",
139 "XSCALE_RX", /* 20 */
140 "XSCALE_TXRXCTRL",
141 };
142
143 xscale_reg_t xscale_reg_arch_info[] =
144 {
145 {XSCALE_MAINID, NULL},
146 {XSCALE_CACHETYPE, NULL},
147 {XSCALE_CTRL, NULL},
148 {XSCALE_AUXCTRL, NULL},
149 {XSCALE_TTB, NULL},
150 {XSCALE_DAC, NULL},
151 {XSCALE_FSR, NULL},
152 {XSCALE_FAR, NULL},
153 {XSCALE_PID, NULL},
154 {XSCALE_CPACCESS, NULL},
155 {XSCALE_IBCR0, NULL},
156 {XSCALE_IBCR1, NULL},
157 {XSCALE_DBR0, NULL},
158 {XSCALE_DBR1, NULL},
159 {XSCALE_DBCON, NULL},
160 {XSCALE_TBREG, NULL},
161 {XSCALE_CHKPT0, NULL},
162 {XSCALE_CHKPT1, NULL},
163 {XSCALE_DCSR, NULL}, /* DCSR accessed via JTAG or SW */
164 {-1, NULL}, /* TX accessed via JTAG */
165 {-1, NULL}, /* RX accessed via JTAG */
166 {-1, NULL}, /* TXRXCTRL implicit access via JTAG */
167 };
168
169 int xscale_reg_arch_type = -1;
170
171 int xscale_get_reg(reg_t *reg);
172 int xscale_set_reg(reg_t *reg, u8 *buf);
173
174 int xscale_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, xscale_common_t **xscale_p)
175 {
176 armv4_5_common_t *armv4_5 = target->arch_info;
177 xscale_common_t *xscale = armv4_5->arch_info;
178
179 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
180 {
181 LOG_ERROR("target isn't an XScale target");
182 return -1;
183 }
184
185 if (xscale->common_magic != XSCALE_COMMON_MAGIC)
186 {
187 LOG_ERROR("target isn't an XScale target");
188 return -1;
189 }
190
191 *armv4_5_p = armv4_5;
192 *xscale_p = xscale;
193
194 return ERROR_OK;
195 }
196
197 int xscale_jtag_set_instr(jtag_tap_t *tap, u32 new_instr)
198 {
199 if (tap==NULL)
200 return ERROR_FAIL;
201
202 if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr)
203 {
204 scan_field_t field;
205
206 field.tap = tap;
207 field.num_bits = tap->ir_length;
208 field.out_value = calloc(CEIL(field.num_bits, 8), 1);
209 buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
210
211 u8 tmp[4];
212 field.in_value = tmp;
213
214 jtag_add_ir_scan(1, &field, TAP_INVALID);
215
216 jtag_check_value_mask(&field, tap->expected, tap->expected_mask);
217
218 free(field.out_value);
219 }
220
221 return ERROR_OK;
222 }
223
224 int xscale_read_dcsr(target_t *target)
225 {
226 armv4_5_common_t *armv4_5 = target->arch_info;
227 xscale_common_t *xscale = armv4_5->arch_info;
228
229 int retval;
230
231 scan_field_t fields[3];
232 u8 field0 = 0x0;
233 u8 field0_check_value = 0x2;
234 u8 field0_check_mask = 0x7;
235 u8 field2 = 0x0;
236 u8 field2_check_value = 0x0;
237 u8 field2_check_mask = 0x1;
238
239 jtag_add_end_state(TAP_DRPAUSE);
240 xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.dcsr);
241
242 buf_set_u32(&field0, 1, 1, xscale->hold_rst);
243 buf_set_u32(&field0, 2, 1, xscale->external_debug_break);
244
245 fields[0].tap = xscale->jtag_info.tap;
246 fields[0].num_bits = 3;
247 fields[0].out_value = &field0;
248 u8 tmp;
249 fields[0].in_value = &tmp;
250
251 fields[1].tap = xscale->jtag_info.tap;
252 fields[1].num_bits = 32;
253 fields[1].out_value = NULL;
254 fields[1].in_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value;
255
256
257 fields[2].tap = xscale->jtag_info.tap;
258 fields[2].num_bits = 1;
259 fields[2].out_value = &field2;
260 u8 tmp2;
261 fields[2].in_value = &tmp2;
262
263 jtag_add_dr_scan(3, fields, TAP_INVALID);
264
265 jtag_check_value_mask(fields+0, &field0_check_value, &field0_check_mask);
266 jtag_check_value_mask(fields+2, &field2_check_value, &field2_check_mask);
267
268 if ((retval = jtag_execute_queue()) != ERROR_OK)
269 {
270 LOG_ERROR("JTAG error while reading DCSR");
271 return retval;
272 }
273
274 xscale->reg_cache->reg_list[XSCALE_DCSR].dirty = 0;
275 xscale->reg_cache->reg_list[XSCALE_DCSR].valid = 1;
276
277 /* write the register with the value we just read
278 * on this second pass, only the first bit of field0 is guaranteed to be 0)
279 */
280 field0_check_mask = 0x1;
281 fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value;
282 fields[1].in_value = NULL;
283
284 jtag_add_end_state(TAP_IDLE);
285
286 jtag_add_dr_scan(3, fields, TAP_INVALID);
287
288 /* DANGER!!! this must be here. It will make sure that the arguments
289 * to jtag_set_check_value() does not go out of scope! */
290 return jtag_execute_queue();
291 }
292
293
294 static void xscale_getbuf(u8 *in)
295 {
296 *((u32 *)in)=buf_get_u32(in, 0, 32);
297 }
298
299 int xscale_receive(target_t *target, u32 *buffer, int num_words)
300 {
301 if (num_words==0)
302 return ERROR_INVALID_ARGUMENTS;
303
304 int retval=ERROR_OK;
305 armv4_5_common_t *armv4_5 = target->arch_info;
306 xscale_common_t *xscale = armv4_5->arch_info;
307
308 tap_state_t path[3];
309 scan_field_t fields[3];
310
311 u8 *field0 = malloc(num_words * 1);
312 u8 field0_check_value = 0x2;
313 u8 field0_check_mask = 0x6;
314 u32 *field1 = malloc(num_words * 4);
315 u8 field2_check_value = 0x0;
316 u8 field2_check_mask = 0x1;
317 int words_done = 0;
318 int words_scheduled = 0;
319
320 int i;
321
322 path[0] = TAP_DRSELECT;
323 path[1] = TAP_DRCAPTURE;
324 path[2] = TAP_DRSHIFT;
325
326 fields[0].tap = xscale->jtag_info.tap;
327 fields[0].num_bits = 3;
328 fields[0].out_value = NULL;
329 u8 tmp2;
330 fields[0].in_value = &tmp2;
331
332 fields[1].tap = xscale->jtag_info.tap;
333 fields[1].num_bits = 32;
334 fields[1].out_value = NULL;
335
336
337 fields[2].tap = xscale->jtag_info.tap;
338 fields[2].num_bits = 1;
339 fields[2].out_value = NULL;
340 u8 tmp3;
341 fields[2].in_value = &tmp3;
342
343 jtag_add_end_state(TAP_IDLE);
344 xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.dbgtx);
345 jtag_add_runtest(1, TAP_INVALID); /* ensures that we're in the TAP_IDLE state as the above could be a no-op */
346
347 /* repeat until all words have been collected */
348 int attempts=0;
349 while (words_done < num_words)
350 {
351 /* schedule reads */
352 words_scheduled = 0;
353 for (i = words_done; i < num_words; i++)
354 {
355 fields[0].in_value = &field0[i];
356
357 jtag_add_pathmove(3, path);
358
359 fields[1].in_value = (u8 *)(field1+i);
360 jtag_add_dr_scan(3, fields, TAP_IDLE);
361
362 jtag_add_callback(xscale_getbuf, (u8 *)(field1+i));
363
364 jtag_check_value_mask(fields+0, &field0_check_value, &field0_check_mask);
365 jtag_check_value_mask(fields+2, &field2_check_value, &field2_check_mask);
366
367 words_scheduled++;
368 }
369
370 if ((retval = jtag_execute_queue()) != ERROR_OK)
371 {
372 LOG_ERROR("JTAG error while receiving data from debug handler");
373 break;
374 }
375
376 /* examine results */
377 for (i = words_done; i < num_words; i++)
378 {
379 if (!(field0[0] & 1))
380 {
381 /* move backwards if necessary */
382 int j;
383 for (j = i; j < num_words - 1; j++)
384 {
385 field0[j] = field0[j+1];
386 field1[j] = field1[j+1];
387 }
388 words_scheduled--;
389 }
390 }
391 if (words_scheduled==0)
392 {
393 if (attempts++==1000)
394 {
395 LOG_ERROR("Failed to receiving data from debug handler after 1000 attempts");
396 retval=ERROR_TARGET_TIMEOUT;
397 break;
398 }
399 }
400
401 words_done += words_scheduled;
402 }
403
404 for (i = 0; i < num_words; i++)
405 *(buffer++) = buf_get_u32((u8*)&field1[i], 0, 32);
406
407 free(field1);
408
409 return retval;
410 }
411
412 int xscale_read_tx(target_t *target, int consume)
413 {
414 armv4_5_common_t *armv4_5 = target->arch_info;
415 xscale_common_t *xscale = armv4_5->arch_info;
416 tap_state_t path[3];
417 tap_state_t noconsume_path[6];
418
419 int retval;
420 struct timeval timeout, now;
421
422 scan_field_t fields[3];
423 u8 field0_in = 0x0;
424 u8 field0_check_value = 0x2;
425 u8 field0_check_mask = 0x6;
426 u8 field2_check_value = 0x0;
427 u8 field2_check_mask = 0x1;
428
429 jtag_add_end_state(TAP_IDLE);
430
431 xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.dbgtx);
432
433 path[0] = TAP_DRSELECT;
434 path[1] = TAP_DRCAPTURE;
435 path[2] = TAP_DRSHIFT;
436
437 noconsume_path[0] = TAP_DRSELECT;
438 noconsume_path[1] = TAP_DRCAPTURE;
439 noconsume_path[2] = TAP_DREXIT1;
440 noconsume_path[3] = TAP_DRPAUSE;
441 noconsume_path[4] = TAP_DREXIT2;
442 noconsume_path[5] = TAP_DRSHIFT;
443
444 fields[0].tap = xscale->jtag_info.tap;
445 fields[0].num_bits = 3;
446 fields[0].out_value = NULL;
447 fields[0].in_value = &field0_in;
448
449 fields[1].tap = xscale->jtag_info.tap;
450 fields[1].num_bits = 32;
451 fields[1].out_value = NULL;
452 fields[1].in_value = xscale->reg_cache->reg_list[XSCALE_TX].value;
453
454
455 fields[2].tap = xscale->jtag_info.tap;
456 fields[2].num_bits = 1;
457 fields[2].out_value = NULL;
458 u8 tmp;
459 fields[2].in_value = &tmp;
460
461 gettimeofday(&timeout, NULL);
462 timeval_add_time(&timeout, 1, 0);
463
464 for (;;)
465 {
466 /* if we want to consume the register content (i.e. clear TX_READY),
467 * we have to go straight from Capture-DR to Shift-DR
468 * otherwise, we go from Capture-DR to Exit1-DR to Pause-DR
469 */
470 if (consume)
471 jtag_add_pathmove(3, path);
472 else
473 {
474 jtag_add_pathmove(sizeof(noconsume_path)/sizeof(*noconsume_path), noconsume_path);
475 }
476
477 jtag_add_dr_scan(3, fields, TAP_IDLE);
478
479 jtag_check_value_mask(fields+0, &field0_check_value, &field0_check_mask);
480 jtag_check_value_mask(fields+2, &field2_check_value, &field2_check_mask);
481
482 if ((retval = jtag_execute_queue()) != ERROR_OK)
483 {
484 LOG_ERROR("JTAG error while reading TX");
485 return ERROR_TARGET_TIMEOUT;
486 }
487
488 gettimeofday(&now, NULL);
489 if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec)&& (now.tv_usec > timeout.tv_usec)))
490 {
491 LOG_ERROR("time out reading TX register");
492 return ERROR_TARGET_TIMEOUT;
493 }
494 if (!((!(field0_in & 1)) && consume))
495 {
496 goto done;
497 }
498 if (debug_level>=3)
499 {
500 LOG_DEBUG("waiting 100ms");
501 alive_sleep(100); /* avoid flooding the logs */
502 } else
503 {
504 keep_alive();
505 }
506 }
507 done:
508
509 if (!(field0_in & 1))
510 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
511
512 return ERROR_OK;
513 }
514
515 int xscale_write_rx(target_t *target)
516 {
517 armv4_5_common_t *armv4_5 = target->arch_info;
518 xscale_common_t *xscale = armv4_5->arch_info;
519
520 int retval;
521 struct timeval timeout, now;
522
523 scan_field_t fields[3];
524 u8 field0_out = 0x0;
525 u8 field0_in = 0x0;
526 u8 field0_check_value = 0x2;
527 u8 field0_check_mask = 0x6;
528 u8 field2 = 0x0;
529 u8 field2_check_value = 0x0;
530 u8 field2_check_mask = 0x1;
531
532 jtag_add_end_state(TAP_IDLE);
533
534 xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.dbgrx);
535
536 fields[0].tap = xscale->jtag_info.tap;
537 fields[0].num_bits = 3;
538 fields[0].out_value = &field0_out;
539 fields[0].in_value = &field0_in;
540
541 fields[1].tap = xscale->jtag_info.tap;
542 fields[1].num_bits = 32;
543 fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_RX].value;
544 fields[1].in_value = NULL;
545
546
547 fields[2].tap = xscale->jtag_info.tap;
548 fields[2].num_bits = 1;
549 fields[2].out_value = &field2;
550 u8 tmp;
551 fields[2].in_value = &tmp;
552
553 gettimeofday(&timeout, NULL);
554 timeval_add_time(&timeout, 1, 0);
555
556 /* poll until rx_read is low */
557 LOG_DEBUG("polling RX");
558 for (;;)
559 {
560 jtag_add_dr_scan(3, fields, TAP_IDLE);
561
562 jtag_check_value_mask(fields+0, &field0_check_value, &field0_check_mask);
563 jtag_check_value_mask(fields+2, &field2_check_value, &field2_check_mask);
564
565 if ((retval = jtag_execute_queue()) != ERROR_OK)
566 {
567 LOG_ERROR("JTAG error while writing RX");
568 return retval;
569 }
570
571 gettimeofday(&now, NULL);
572 if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec)&& (now.tv_usec > timeout.tv_usec)))
573 {
574 LOG_ERROR("time out writing RX register");
575 return ERROR_TARGET_TIMEOUT;
576 }
577 if (!(field0_in & 1))
578 goto done;
579 if (debug_level>=3)
580 {
581 LOG_DEBUG("waiting 100ms");
582 alive_sleep(100); /* avoid flooding the logs */
583 } else
584 {
585 keep_alive();
586 }
587 }
588 done:
589
590 /* set rx_valid */
591 field2 = 0x1;
592 jtag_add_dr_scan(3, fields, TAP_IDLE);
593
594 if ((retval = jtag_execute_queue()) != ERROR_OK)
595 {
596 LOG_ERROR("JTAG error while writing RX");
597 return retval;
598 }
599
600 return ERROR_OK;
601 }
602
603 /* send count elements of size byte to the debug handler */
604 int xscale_send(target_t *target, u8 *buffer, int count, int size)
605 {
606 armv4_5_common_t *armv4_5 = target->arch_info;
607 xscale_common_t *xscale = armv4_5->arch_info;
608 u32 t[3];
609 int bits[3];
610
611 int retval;
612
613 int done_count = 0;
614
615 jtag_add_end_state(TAP_IDLE);
616
617 xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.dbgrx);
618
619 bits[0]=3;
620 t[0]=0;
621 bits[1]=32;
622 t[2]=1;
623 bits[2]=1;
624 int endianness = target->endianness;
625 while (done_count++ < count)
626 {
627 switch (size)
628 {
629 case 4:
630 if (endianness == TARGET_LITTLE_ENDIAN)
631 {
632 t[1]=le_to_h_u32(buffer);
633 } else
634 {
635 t[1]=be_to_h_u32(buffer);
636 }
637 break;
638 case 2:
639 if (endianness == TARGET_LITTLE_ENDIAN)
640 {
641 t[1]=le_to_h_u16(buffer);
642 } else
643 {
644 t[1]=be_to_h_u16(buffer);
645 }
646 break;
647 case 1:
648 t[1]=buffer[0];
649 break;
650 default:
651 LOG_ERROR("BUG: size neither 4, 2 nor 1");
652 exit(-1);
653 }
654 jtag_add_dr_out(xscale->jtag_info.tap,
655 3,
656 bits,
657 t,
658 TAP_IDLE);
659 buffer += size;
660 }
661
662 if ((retval = jtag_execute_queue()) != ERROR_OK)
663 {
664 LOG_ERROR("JTAG error while sending data to debug handler");
665 return retval;
666 }
667
668 return ERROR_OK;
669 }
670
671 int xscale_send_u32(target_t *target, u32 value)
672 {
673 armv4_5_common_t *armv4_5 = target->arch_info;
674 xscale_common_t *xscale = armv4_5->arch_info;
675
676 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_RX].value, 0, 32, value);
677 return xscale_write_rx(target);
678 }
679
680 int xscale_write_dcsr(target_t *target, int hold_rst, int ext_dbg_brk)
681 {
682 armv4_5_common_t *armv4_5 = target->arch_info;
683 xscale_common_t *xscale = armv4_5->arch_info;
684
685 int retval;
686
687 scan_field_t fields[3];
688 u8 field0 = 0x0;
689 u8 field0_check_value = 0x2;
690 u8 field0_check_mask = 0x7;
691 u8 field2 = 0x0;
692 u8 field2_check_value = 0x0;
693 u8 field2_check_mask = 0x1;
694
695 if (hold_rst != -1)
696 xscale->hold_rst = hold_rst;
697
698 if (ext_dbg_brk != -1)
699 xscale->external_debug_break = ext_dbg_brk;
700
701 jtag_add_end_state(TAP_IDLE);
702 xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.dcsr);
703
704 buf_set_u32(&field0, 1, 1, xscale->hold_rst);
705 buf_set_u32(&field0, 2, 1, xscale->external_debug_break);
706
707 fields[0].tap = xscale->jtag_info.tap;
708 fields[0].num_bits = 3;
709 fields[0].out_value = &field0;
710 u8 tmp;
711 fields[0].in_value = &tmp;
712
713 fields[1].tap = xscale->jtag_info.tap;
714 fields[1].num_bits = 32;
715 fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value;
716 fields[1].in_value = NULL;
717
718
719 fields[2].tap = xscale->jtag_info.tap;
720 fields[2].num_bits = 1;
721 fields[2].out_value = &field2;
722 u8 tmp2;
723 fields[2].in_value = &tmp2;
724
725 jtag_add_dr_scan(3, fields, TAP_INVALID);
726
727 jtag_check_value_mask(fields+0, &field0_check_value, &field0_check_mask);
728 jtag_check_value_mask(fields+2, &field2_check_value, &field2_check_mask);
729
730 if ((retval = jtag_execute_queue()) != ERROR_OK)
731 {
732 LOG_ERROR("JTAG error while writing DCSR");
733 return retval;
734 }
735
736 xscale->reg_cache->reg_list[XSCALE_DCSR].dirty = 0;
737 xscale->reg_cache->reg_list[XSCALE_DCSR].valid = 1;
738
739 return ERROR_OK;
740 }
741
742 /* parity of the number of bits 0 if even; 1 if odd. for 32 bit words */
743 unsigned int parity (unsigned int v)
744 {
745 unsigned int ov = v;
746 v ^= v >> 16;
747 v ^= v >> 8;
748 v ^= v >> 4;
749 v &= 0xf;
750 LOG_DEBUG("parity of 0x%x is %i", ov, (0x6996 >> v) & 1);
751 return (0x6996 >> v) & 1;
752 }
753
754 int xscale_load_ic(target_t *target, int mini, u32 va, u32 buffer[8])
755 {
756 armv4_5_common_t *armv4_5 = target->arch_info;
757 xscale_common_t *xscale = armv4_5->arch_info;
758 u8 packet[4];
759 u8 cmd;
760 int word;
761
762 scan_field_t fields[2];
763
764 LOG_DEBUG("loading miniIC at 0x%8.8x", va);
765
766 jtag_add_end_state(TAP_IDLE);
767 xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.ldic); /* LDIC */
768
769 /* CMD is b010 for Main IC and b011 for Mini IC */
770 if (mini)
771 buf_set_u32(&cmd, 0, 3, 0x3);
772 else
773 buf_set_u32(&cmd, 0, 3, 0x2);
774
775 buf_set_u32(&cmd, 3, 3, 0x0);
776
777 /* virtual address of desired cache line */
778 buf_set_u32(packet, 0, 27, va >> 5);
779
780 fields[0].tap = xscale->jtag_info.tap;
781 fields[0].num_bits = 6;
782 fields[0].out_value = &cmd;
783
784 fields[0].in_value = NULL;
785
786
787
788
789
790 fields[1].tap = xscale->jtag_info.tap;
791 fields[1].num_bits = 27;
792 fields[1].out_value = packet;
793
794 fields[1].in_value = NULL;
795
796
797
798
799
800 jtag_add_dr_scan(2, fields, TAP_INVALID);
801
802 fields[0].num_bits = 32;
803 fields[0].out_value = packet;
804
805 fields[1].num_bits = 1;
806 fields[1].out_value = &cmd;
807
808 for (word = 0; word < 8; word++)
809 {
810 buf_set_u32(packet, 0, 32, buffer[word]);
811
812 u32 value;
813 memcpy(&value, packet, sizeof(u32));
814 cmd = parity(value);
815
816 jtag_add_dr_scan(2, fields, TAP_INVALID);
817 }
818
819 jtag_execute_queue();
820
821 return ERROR_OK;
822 }
823
824 int xscale_invalidate_ic_line(target_t *target, u32 va)
825 {
826 armv4_5_common_t *armv4_5 = target->arch_info;
827 xscale_common_t *xscale = armv4_5->arch_info;
828 u8 packet[4];
829 u8 cmd;
830
831 scan_field_t fields[2];
832
833 jtag_add_end_state(TAP_IDLE);
834 xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.ldic); /* LDIC */
835
836 /* CMD for invalidate IC line b000, bits [6:4] b000 */
837 buf_set_u32(&cmd, 0, 6, 0x0);
838
839 /* virtual address of desired cache line */
840 buf_set_u32(packet, 0, 27, va >> 5);
841
842 fields[0].tap = xscale->jtag_info.tap;
843 fields[0].num_bits = 6;
844 fields[0].out_value = &cmd;
845
846 fields[0].in_value = NULL;
847
848
849
850
851
852 fields[1].tap = xscale->jtag_info.tap;
853 fields[1].num_bits = 27;
854 fields[1].out_value = packet;
855
856 fields[1].in_value = NULL;
857
858
859
860
861
862 jtag_add_dr_scan(2, fields, TAP_INVALID);
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 u32 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 char *state[] =
938 {
939 "disabled", "enabled"
940 };
941
942 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.8x pc: 0x%8.8x\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 u32 pc;
1019 u32 buffer[10];
1020 int i;
1021 int retval;
1022
1023 u32 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[15].dirty = 1;
1037 armv4_5->core_cache->reg_list[15].valid = 1;
1038 LOG_DEBUG("r0: 0x%8.8x", 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.8x", 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.8x", 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.8x", 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 */
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 u32 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 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
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, u32 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, u32 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 u32 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 u32 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.8x", 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 u32 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.8x", 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.8x", 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.8x", 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.8x", 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.8x", 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.8x", 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.8x", 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.8x", 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, u32 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 u32 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 u32 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.8x", 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.8x", 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.8x", 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.8x", 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, u32 address, int handle_breakpoints)
1508 {
1509 armv4_5_common_t *armv4_5 = target->arch_info;
1510 breakpoint_t *breakpoint = target->breakpoints;
1511
1512 u32 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 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
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_add_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 u32 address;
1610 u32 binary_size;
1611
1612 u32 buf_cnt;
1613 u32 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, 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 u32 cache_line[8];
1678 u8 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 u32 */
1688 cache_line[i / 4] = le_to_h_u32(&buffer[i]);
1689 }
1690
1691 for (; buf_cnt < 32; buf_cnt += 4)
1692 {
1693 cache_line[buf_cnt / 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, 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_soft_reset_halt(struct target_s *target)
1745 {
1746 return ERROR_OK;
1747 }
1748
1749 int xscale_read_core_reg(struct target_s *target, int num, enum armv4_5_mode mode)
1750 {
1751 return ERROR_OK;
1752 }
1753
1754 int xscale_write_core_reg(struct target_s *target, int num, enum armv4_5_mode mode, u32 value)
1755 {
1756
1757 return ERROR_OK;
1758 }
1759
1760 int xscale_full_context(target_t *target)
1761 {
1762 armv4_5_common_t *armv4_5 = target->arch_info;
1763
1764 u32 *buffer;
1765
1766 int i, j;
1767
1768 LOG_DEBUG("-");
1769
1770 if (target->state != TARGET_HALTED)
1771 {
1772 LOG_WARNING("target not halted");
1773 return ERROR_TARGET_NOT_HALTED;
1774 }
1775
1776 buffer = malloc(4 * 8);
1777
1778 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1779 * we can't enter User mode on an XScale (unpredictable),
1780 * but User shares registers with SYS
1781 */
1782 for(i = 1; i < 7; i++)
1783 {
1784 int valid = 1;
1785
1786 /* check if there are invalid registers in the current mode
1787 */
1788 for (j = 0; j <= 16; j++)
1789 {
1790 if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).valid == 0)
1791 valid = 0;
1792 }
1793
1794 if (!valid)
1795 {
1796 u32 tmp_cpsr;
1797
1798 /* request banked registers */
1799 xscale_send_u32(target, 0x0);
1800
1801 tmp_cpsr = 0x0;
1802 tmp_cpsr |= armv4_5_number_to_mode(i);
1803 tmp_cpsr |= 0xc0; /* I/F bits */
1804
1805 /* send CPSR for desired mode */
1806 xscale_send_u32(target, tmp_cpsr);
1807
1808 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1809 if ((armv4_5_number_to_mode(i) != ARMV4_5_MODE_USR) && (armv4_5_number_to_mode(i) != ARMV4_5_MODE_SYS))
1810 {
1811 xscale_receive(target, buffer, 8);
1812 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32, buffer[7]);
1813 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty = 0;
1814 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).valid = 1;
1815 }
1816 else
1817 {
1818 xscale_receive(target, buffer, 7);
1819 }
1820
1821 /* move data from buffer to register cache */
1822 for (j = 8; j <= 14; j++)
1823 {
1824 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]);
1825 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty = 0;
1826 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).valid = 1;
1827 }
1828 }
1829 }
1830
1831 free(buffer);
1832
1833 return ERROR_OK;
1834 }
1835
1836 int xscale_restore_context(target_t *target)
1837 {
1838 armv4_5_common_t *armv4_5 = target->arch_info;
1839
1840 int i, j;
1841
1842 LOG_DEBUG("-");
1843
1844 if (target->state != TARGET_HALTED)
1845 {
1846 LOG_WARNING("target not halted");
1847 return ERROR_TARGET_NOT_HALTED;
1848 }
1849
1850 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1851 * we can't enter User mode on an XScale (unpredictable),
1852 * but User shares registers with SYS
1853 */
1854 for(i = 1; i < 7; i++)
1855 {
1856 int dirty = 0;
1857
1858 /* check if there are invalid registers in the current mode
1859 */
1860 for (j = 8; j <= 14; j++)
1861 {
1862 if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty == 1)
1863 dirty = 1;
1864 }
1865
1866 /* if not USR/SYS, check if the SPSR needs to be written */
1867 if ((armv4_5_number_to_mode(i) != ARMV4_5_MODE_USR) && (armv4_5_number_to_mode(i) != ARMV4_5_MODE_SYS))
1868 {
1869 if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty == 1)
1870 dirty = 1;
1871 }
1872
1873 if (dirty)
1874 {
1875 u32 tmp_cpsr;
1876
1877 /* send banked registers */
1878 xscale_send_u32(target, 0x1);
1879
1880 tmp_cpsr = 0x0;
1881 tmp_cpsr |= armv4_5_number_to_mode(i);
1882 tmp_cpsr |= 0xc0; /* I/F bits */
1883
1884 /* send CPSR for desired mode */
1885 xscale_send_u32(target, tmp_cpsr);
1886
1887 /* send banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1888 for (j = 8; j <= 14; j++)
1889 {
1890 xscale_send_u32(target, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, j).value, 0, 32));
1891 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty = 0;
1892 }
1893
1894 if ((armv4_5_number_to_mode(i) != ARMV4_5_MODE_USR) && (armv4_5_number_to_mode(i) != ARMV4_5_MODE_SYS))
1895 {
1896 xscale_send_u32(target, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32));
1897 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty = 0;
1898 }
1899 }
1900 }
1901
1902 return ERROR_OK;
1903 }
1904
1905 int xscale_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1906 {
1907 armv4_5_common_t *armv4_5 = target->arch_info;
1908 xscale_common_t *xscale = armv4_5->arch_info;
1909 u32 *buf32;
1910 u32 i;
1911 int retval;
1912
1913 LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
1914
1915 if (target->state != TARGET_HALTED)
1916 {
1917 LOG_WARNING("target not halted");
1918 return ERROR_TARGET_NOT_HALTED;
1919 }
1920
1921 /* sanitize arguments */
1922 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1923 return ERROR_INVALID_ARGUMENTS;
1924
1925 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
1926 return ERROR_TARGET_UNALIGNED_ACCESS;
1927
1928 /* send memory read request (command 0x1n, n: access size) */
1929 if ((retval=xscale_send_u32(target, 0x10 | size))!=ERROR_OK)
1930 return retval;
1931
1932 /* send base address for read request */
1933 if ((retval=xscale_send_u32(target, address))!=ERROR_OK)
1934 return retval;
1935
1936 /* send number of requested data words */
1937 if ((retval=xscale_send_u32(target, count))!=ERROR_OK)
1938 return retval;
1939
1940 /* receive data from target (count times 32-bit words in host endianness) */
1941 buf32 = malloc(4 * count);
1942 if ((retval=xscale_receive(target, buf32, count))!=ERROR_OK)
1943 return retval;
1944
1945 /* extract data from host-endian buffer into byte stream */
1946 for (i = 0; i < count; i++)
1947 {
1948 switch (size)
1949 {
1950 case 4:
1951 target_buffer_set_u32(target, buffer, buf32[i]);
1952 buffer += 4;
1953 break;
1954 case 2:
1955 target_buffer_set_u16(target, buffer, buf32[i] & 0xffff);
1956 buffer += 2;
1957 break;
1958 case 1:
1959 *buffer++ = buf32[i] & 0xff;
1960 break;
1961 default:
1962 LOG_ERROR("should never get here");
1963 exit(-1);
1964 }
1965 }
1966
1967 free(buf32);
1968
1969 /* examine DCSR, to see if Sticky Abort (SA) got set */
1970 if ((retval=xscale_read_dcsr(target))!=ERROR_OK)
1971 return retval;
1972 if (buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 5, 1) == 1)
1973 {
1974 /* clear SA bit */
1975 if ((retval=xscale_send_u32(target, 0x60))!=ERROR_OK)
1976 return retval;
1977
1978 return ERROR_TARGET_DATA_ABORT;
1979 }
1980
1981 return ERROR_OK;
1982 }
1983
1984 int xscale_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1985 {
1986 armv4_5_common_t *armv4_5 = target->arch_info;
1987 xscale_common_t *xscale = armv4_5->arch_info;
1988 int retval;
1989
1990 LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
1991
1992 if (target->state != TARGET_HALTED)
1993 {
1994 LOG_WARNING("target not halted");
1995 return ERROR_TARGET_NOT_HALTED;
1996 }
1997
1998 /* sanitize arguments */
1999 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
2000 return ERROR_INVALID_ARGUMENTS;
2001
2002 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
2003 return ERROR_TARGET_UNALIGNED_ACCESS;
2004
2005 /* send memory write request (command 0x2n, n: access size) */
2006 if ((retval=xscale_send_u32(target, 0x20 | size))!=ERROR_OK)
2007 return retval;
2008
2009 /* send base address for read request */
2010 if ((retval=xscale_send_u32(target, address))!=ERROR_OK)
2011 return retval;
2012
2013 /* send number of requested data words to be written*/
2014 if ((retval=xscale_send_u32(target, count))!=ERROR_OK)
2015 return retval;
2016
2017 /* extract data from host-endian buffer into byte stream */
2018 #if 0
2019 for (i = 0; i < count; i++)
2020 {
2021 switch (size)
2022 {
2023 case 4:
2024 value = target_buffer_get_u32(target, buffer);
2025 xscale_send_u32(target, value);
2026 buffer += 4;
2027 break;
2028 case 2:
2029 value = target_buffer_get_u16(target, buffer);
2030 xscale_send_u32(target, value);
2031 buffer += 2;
2032 break;
2033 case 1:
2034 value = *buffer;
2035 xscale_send_u32(target, value);
2036 buffer += 1;
2037 break;
2038 default:
2039 LOG_ERROR("should never get here");
2040 exit(-1);
2041 }
2042 }
2043 #endif
2044 if ((retval=xscale_send(target, buffer, count, size))!=ERROR_OK)
2045 return retval;
2046
2047 /* examine DCSR, to see if Sticky Abort (SA) got set */
2048 if ((retval=xscale_read_dcsr(target))!=ERROR_OK)
2049 return retval;
2050 if (buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 5, 1) == 1)
2051 {
2052 /* clear SA bit */
2053 if ((retval=xscale_send_u32(target, 0x60))!=ERROR_OK)
2054 return retval;
2055
2056 return ERROR_TARGET_DATA_ABORT;
2057 }
2058
2059 return ERROR_OK;
2060 }
2061
2062 int xscale_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
2063 {
2064 return xscale_write_memory(target, address, 4, count, buffer);
2065 }
2066
2067 u32 xscale_get_ttb(target_t *target)
2068 {
2069 armv4_5_common_t *armv4_5 = target->arch_info;
2070 xscale_common_t *xscale = armv4_5->arch_info;
2071 u32 ttb;
2072
2073 xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_TTB]);
2074 ttb = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_TTB].value, 0, 32);
2075
2076 return ttb;
2077 }
2078
2079 void xscale_disable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
2080 {
2081 armv4_5_common_t *armv4_5 = target->arch_info;
2082 xscale_common_t *xscale = armv4_5->arch_info;
2083 u32 cp15_control;
2084
2085 /* read cp15 control register */
2086 xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);
2087 cp15_control = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32);
2088
2089 if (mmu)
2090 cp15_control &= ~0x1U;
2091
2092 if (d_u_cache)
2093 {
2094 /* clean DCache */
2095 xscale_send_u32(target, 0x50);
2096 xscale_send_u32(target, xscale->cache_clean_address);
2097
2098 /* invalidate DCache */
2099 xscale_send_u32(target, 0x51);
2100
2101 cp15_control &= ~0x4U;
2102 }
2103
2104 if (i_cache)
2105 {
2106 /* invalidate ICache */
2107 xscale_send_u32(target, 0x52);
2108 cp15_control &= ~0x1000U;
2109 }
2110
2111 /* write new cp15 control register */
2112 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_CTRL], cp15_control);
2113
2114 /* execute cpwait to ensure outstanding operations complete */
2115 xscale_send_u32(target, 0x53);
2116 }
2117
2118 void xscale_enable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
2119 {
2120 armv4_5_common_t *armv4_5 = target->arch_info;
2121 xscale_common_t *xscale = armv4_5->arch_info;
2122 u32 cp15_control;
2123
2124 /* read cp15 control register */
2125 xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);
2126 cp15_control = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32);
2127
2128 if (mmu)
2129 cp15_control |= 0x1U;
2130
2131 if (d_u_cache)
2132 cp15_control |= 0x4U;
2133
2134 if (i_cache)
2135 cp15_control |= 0x1000U;
2136
2137 /* write new cp15 control register */
2138 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_CTRL], cp15_control);
2139
2140 /* execute cpwait to ensure outstanding operations complete */
2141 xscale_send_u32(target, 0x53);
2142 }
2143
2144 int xscale_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
2145 {
2146 int retval;
2147 armv4_5_common_t *armv4_5 = target->arch_info;
2148 xscale_common_t *xscale = armv4_5->arch_info;
2149
2150 if (target->state != TARGET_HALTED)
2151 {
2152 LOG_WARNING("target not halted");
2153 return ERROR_TARGET_NOT_HALTED;
2154 }
2155
2156 if (breakpoint->set)
2157 {
2158 LOG_WARNING("breakpoint already set");
2159 return ERROR_OK;
2160 }
2161
2162 if (breakpoint->type == BKPT_HARD)
2163 {
2164 u32 value = breakpoint->address | 1;
2165 if (!xscale->ibcr0_used)
2166 {
2167 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR0], value);
2168 xscale->ibcr0_used = 1;
2169 breakpoint->set = 1; /* breakpoint set on first breakpoint register */
2170 }
2171 else if (!xscale->ibcr1_used)
2172 {
2173 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR1], value);
2174 xscale->ibcr1_used = 1;
2175 breakpoint->set = 2; /* breakpoint set on second breakpoint register */
2176 }
2177 else
2178 {
2179 LOG_ERROR("BUG: no hardware comparator available");
2180 return ERROR_OK;
2181 }
2182 }
2183 else if (breakpoint->type == BKPT_SOFT)
2184 {
2185 if (breakpoint->length == 4)
2186 {
2187 /* keep the original instruction in target endianness */
2188 if((retval = target->type->read_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr)) != ERROR_OK)
2189 {
2190 return retval;
2191 }
2192 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2193 if((retval = target_write_u32(target, breakpoint->address, xscale->arm_bkpt)) != ERROR_OK)
2194 {
2195 return retval;
2196 }
2197 }
2198 else
2199 {
2200 /* keep the original instruction in target endianness */
2201 if((retval = target->type->read_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr)) != ERROR_OK)
2202 {
2203 return retval;
2204 }
2205 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2206 if((retval = target_write_u32(target, breakpoint->address, xscale->thumb_bkpt)) != ERROR_OK)
2207 {
2208 return retval;
2209 }
2210 }
2211 breakpoint->set = 1;
2212 }
2213
2214 return ERROR_OK;
2215 }
2216
2217 int xscale_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
2218 {
2219 armv4_5_common_t *armv4_5 = target->arch_info;
2220 xscale_common_t *xscale = armv4_5->arch_info;
2221
2222 if (target->state != TARGET_HALTED)
2223 {
2224 LOG_WARNING("target not halted");
2225 return ERROR_TARGET_NOT_HALTED;
2226 }
2227
2228 if ((breakpoint->type == BKPT_HARD) && (xscale->ibcr_available < 1))
2229 {
2230 LOG_INFO("no breakpoint unit available for hardware breakpoint");
2231 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2232 }
2233
2234 if ((breakpoint->length != 2) && (breakpoint->length != 4))
2235 {
2236 LOG_INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
2237 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2238 }
2239
2240 if (breakpoint->type == BKPT_HARD)
2241 {
2242 xscale->ibcr_available--;
2243 }
2244
2245 return ERROR_OK;
2246 }
2247
2248 int xscale_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
2249 {
2250 int retval;
2251 armv4_5_common_t *armv4_5 = target->arch_info;
2252 xscale_common_t *xscale = armv4_5->arch_info;
2253
2254 if (target->state != TARGET_HALTED)
2255 {
2256 LOG_WARNING("target not halted");
2257 return ERROR_TARGET_NOT_HALTED;
2258 }
2259
2260 if (!breakpoint->set)
2261 {
2262 LOG_WARNING("breakpoint not set");
2263 return ERROR_OK;
2264 }
2265
2266 if (breakpoint->type == BKPT_HARD)
2267 {
2268 if (breakpoint->set == 1)
2269 {
2270 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR0], 0x0);
2271 xscale->ibcr0_used = 0;
2272 }
2273 else if (breakpoint->set == 2)
2274 {
2275 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR1], 0x0);
2276 xscale->ibcr1_used = 0;
2277 }
2278 breakpoint->set = 0;
2279 }
2280 else
2281 {
2282 /* restore original instruction (kept in target endianness) */
2283 if (breakpoint->length == 4)
2284 {
2285 if((retval = target->type->write_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr)) != ERROR_OK)
2286 {
2287 return retval;
2288 }
2289 }
2290 else
2291 {
2292 if((retval = target->type->write_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr)) != ERROR_OK)
2293 {
2294 return retval;
2295 }
2296 }
2297 breakpoint->set = 0;
2298 }
2299
2300 return ERROR_OK;
2301 }
2302
2303 int xscale_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
2304 {
2305 armv4_5_common_t *armv4_5 = target->arch_info;
2306 xscale_common_t *xscale = armv4_5->arch_info;
2307
2308 if (target->state != TARGET_HALTED)
2309 {
2310 LOG_WARNING("target not halted");
2311 return ERROR_TARGET_NOT_HALTED;
2312 }
2313
2314 if (breakpoint->set)
2315 {
2316 xscale_unset_breakpoint(target, breakpoint);
2317 }
2318
2319 if (breakpoint->type == BKPT_HARD)
2320 xscale->ibcr_available++;
2321
2322 return ERROR_OK;
2323 }
2324
2325 int xscale_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
2326 {
2327 armv4_5_common_t *armv4_5 = target->arch_info;
2328 xscale_common_t *xscale = armv4_5->arch_info;
2329 u8 enable=0;
2330 reg_t *dbcon = &xscale->reg_cache->reg_list[XSCALE_DBCON];
2331 u32 dbcon_value = buf_get_u32(dbcon->value, 0, 32);
2332
2333 if (target->state != TARGET_HALTED)
2334 {
2335 LOG_WARNING("target not halted");
2336 return ERROR_TARGET_NOT_HALTED;
2337 }
2338
2339 xscale_get_reg(dbcon);
2340
2341 switch (watchpoint->rw)
2342 {
2343 case WPT_READ:
2344 enable = 0x3;
2345 break;
2346 case WPT_ACCESS:
2347 enable = 0x2;
2348 break;
2349 case WPT_WRITE:
2350 enable = 0x1;
2351 break;
2352 default:
2353 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
2354 }
2355
2356 if (!xscale->dbr0_used)
2357 {
2358 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR0], watchpoint->address);
2359 dbcon_value |= enable;
2360 xscale_set_reg_u32(dbcon, dbcon_value);
2361 watchpoint->set = 1;
2362 xscale->dbr0_used = 1;
2363 }
2364 else if (!xscale->dbr1_used)
2365 {
2366 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR1], watchpoint->address);
2367 dbcon_value |= enable << 2;
2368 xscale_set_reg_u32(dbcon, dbcon_value);
2369 watchpoint->set = 2;
2370 xscale->dbr1_used = 1;
2371 }
2372 else
2373 {
2374 LOG_ERROR("BUG: no hardware comparator available");
2375 return ERROR_OK;
2376 }
2377
2378 return ERROR_OK;
2379 }
2380
2381 int xscale_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
2382 {
2383 armv4_5_common_t *armv4_5 = target->arch_info;
2384 xscale_common_t *xscale = armv4_5->arch_info;
2385
2386 if (target->state != TARGET_HALTED)
2387 {
2388 LOG_WARNING("target not halted");
2389 return ERROR_TARGET_NOT_HALTED;
2390 }
2391
2392 if (xscale->dbr_available < 1)
2393 {
2394 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2395 }
2396
2397 if ((watchpoint->length != 1) && (watchpoint->length != 2) && (watchpoint->length != 4))
2398 {
2399 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2400 }
2401
2402 xscale->dbr_available--;
2403
2404 return ERROR_OK;
2405 }
2406
2407 int xscale_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
2408 {
2409 armv4_5_common_t *armv4_5 = target->arch_info;
2410 xscale_common_t *xscale = armv4_5->arch_info;
2411 reg_t *dbcon = &xscale->reg_cache->reg_list[XSCALE_DBCON];
2412 u32 dbcon_value = buf_get_u32(dbcon->value, 0, 32);
2413
2414 if (target->state != TARGET_HALTED)
2415 {
2416 LOG_WARNING("target not halted");
2417 return ERROR_TARGET_NOT_HALTED;
2418 }
2419
2420 if (!watchpoint->set)
2421 {
2422 LOG_WARNING("breakpoint not set");
2423 return ERROR_OK;
2424 }
2425
2426 if (watchpoint->set == 1)
2427 {
2428 dbcon_value &= ~0x3;
2429 xscale_set_reg_u32(dbcon, dbcon_value);
2430 xscale->dbr0_used = 0;
2431 }
2432 else if (watchpoint->set == 2)
2433 {
2434 dbcon_value &= ~0xc;
2435 xscale_set_reg_u32(dbcon, dbcon_value);
2436 xscale->dbr1_used = 0;
2437 }
2438 watchpoint->set = 0;
2439
2440 return ERROR_OK;
2441 }
2442
2443 int xscale_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
2444 {
2445 armv4_5_common_t *armv4_5 = target->arch_info;
2446 xscale_common_t *xscale = armv4_5->arch_info;
2447
2448 if (target->state != TARGET_HALTED)
2449 {
2450 LOG_WARNING("target not halted");
2451 return ERROR_TARGET_NOT_HALTED;
2452 }
2453
2454 if (watchpoint->set)
2455 {
2456 xscale_unset_watchpoint(target, watchpoint);
2457 }
2458
2459 xscale->dbr_available++;
2460
2461 return ERROR_OK;
2462 }
2463
2464 void xscale_enable_watchpoints(struct target_s *target)
2465 {
2466 watchpoint_t *watchpoint = target->watchpoints;
2467
2468 while (watchpoint)
2469 {
2470 if (watchpoint->set == 0)
2471 xscale_set_watchpoint(target, watchpoint);
2472 watchpoint = watchpoint->next;
2473 }
2474 }
2475
2476 void xscale_enable_breakpoints(struct target_s *target)
2477 {
2478 breakpoint_t *breakpoint = target->breakpoints;
2479
2480 /* set any pending breakpoints */
2481 while (breakpoint)
2482 {
2483 if (breakpoint->set == 0)
2484 xscale_set_breakpoint(target, breakpoint);
2485 breakpoint = breakpoint->next;
2486 }
2487 }
2488
2489 int xscale_get_reg(reg_t *reg)
2490 {
2491 xscale_reg_t *arch_info = reg->arch_info;
2492 target_t *target = arch_info->target;
2493 armv4_5_common_t *armv4_5 = target->arch_info;
2494 xscale_common_t *xscale = armv4_5->arch_info;
2495
2496 /* DCSR, TX and RX are accessible via JTAG */
2497 if (strcmp(reg->name, "XSCALE_DCSR") == 0)
2498 {
2499 return xscale_read_dcsr(arch_info->target);
2500 }
2501 else if (strcmp(reg->name, "XSCALE_TX") == 0)
2502 {
2503 /* 1 = consume register content */
2504 return xscale_read_tx(arch_info->target, 1);
2505 }
2506 else if (strcmp(reg->name, "XSCALE_RX") == 0)
2507 {
2508 /* can't read from RX register (host -> debug handler) */
2509 return ERROR_OK;
2510 }
2511 else if (strcmp(reg->name, "XSCALE_TXRXCTRL") == 0)
2512 {
2513 /* can't (explicitly) read from TXRXCTRL register */
2514 return ERROR_OK;
2515 }
2516 else /* Other DBG registers have to be transfered by the debug handler */
2517 {
2518 /* send CP read request (command 0x40) */
2519 xscale_send_u32(target, 0x40);
2520
2521 /* send CP register number */
2522 xscale_send_u32(target, arch_info->dbg_handler_number);
2523
2524 /* read register value */
2525 xscale_read_tx(target, 1);
2526 buf_cpy(xscale->reg_cache->reg_list[XSCALE_TX].value, reg->value, 32);
2527
2528 reg->dirty = 0;
2529 reg->valid = 1;
2530 }
2531
2532 return ERROR_OK;
2533 }
2534
2535 int xscale_set_reg(reg_t *reg, u8* buf)
2536 {
2537 xscale_reg_t *arch_info = reg->arch_info;
2538 target_t *target = arch_info->target;
2539 armv4_5_common_t *armv4_5 = target->arch_info;
2540 xscale_common_t *xscale = armv4_5->arch_info;
2541 u32 value = buf_get_u32(buf, 0, 32);
2542
2543 /* DCSR, TX and RX are accessible via JTAG */
2544 if (strcmp(reg->name, "XSCALE_DCSR") == 0)
2545 {
2546 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 0, 32, value);
2547 return xscale_write_dcsr(arch_info->target, -1, -1);
2548 }
2549 else if (strcmp(reg->name, "XSCALE_RX") == 0)
2550 {
2551 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_RX].value, 0, 32, value);
2552 return xscale_write_rx(arch_info->target);
2553 }
2554 else if (strcmp(reg->name, "XSCALE_TX") == 0)
2555 {
2556 /* can't write to TX register (debug-handler -> host) */
2557 return ERROR_OK;
2558 }
2559 else if (strcmp(reg->name, "XSCALE_TXRXCTRL") == 0)
2560 {
2561 /* can't (explicitly) write to TXRXCTRL register */
2562 return ERROR_OK;
2563 }
2564 else /* Other DBG registers have to be transfered by the debug handler */
2565 {
2566 /* send CP write request (command 0x41) */
2567 xscale_send_u32(target, 0x41);
2568
2569 /* send CP register number */
2570 xscale_send_u32(target, arch_info->dbg_handler_number);
2571
2572 /* send CP register value */
2573 xscale_send_u32(target, value);
2574 buf_set_u32(reg->value, 0, 32, value);
2575 }
2576
2577 return ERROR_OK;
2578 }
2579
2580 /* convenience wrapper to access XScale specific registers */
2581 int xscale_set_reg_u32(reg_t *reg, u32 value)
2582 {
2583 u8 buf[4];
2584
2585 buf_set_u32(buf, 0, 32, value);
2586
2587 return xscale_set_reg(reg, buf);
2588 }
2589
2590 int xscale_write_dcsr_sw(target_t *target, u32 value)
2591 {
2592 /* get pointers to arch-specific information */
2593 armv4_5_common_t *armv4_5 = target->arch_info;
2594 xscale_common_t *xscale = armv4_5->arch_info;
2595 reg_t *dcsr = &xscale->reg_cache->reg_list[XSCALE_DCSR];
2596 xscale_reg_t *dcsr_arch_info = dcsr->arch_info;
2597
2598 /* send CP write request (command 0x41) */
2599 xscale_send_u32(target, 0x41);
2600
2601 /* send CP register number */
2602 xscale_send_u32(target, dcsr_arch_info->dbg_handler_number);
2603
2604 /* send CP register value */
2605 xscale_send_u32(target, value);
2606 buf_set_u32(dcsr->value, 0, 32, value);
2607
2608 return ERROR_OK;
2609 }
2610
2611 int xscale_read_trace(target_t *target)
2612 {
2613 /* get pointers to arch-specific information */
2614 armv4_5_common_t *armv4_5 = target->arch_info;
2615 xscale_common_t *xscale = armv4_5->arch_info;
2616 xscale_trace_data_t **trace_data_p;
2617
2618 /* 258 words from debug handler
2619 * 256 trace buffer entries
2620 * 2 checkpoint addresses
2621 */
2622 u32 trace_buffer[258];
2623 int is_address[256];
2624 int i, j;
2625
2626 if (target->state != TARGET_HALTED)
2627 {
2628 LOG_WARNING("target must be stopped to read trace data");
2629 return ERROR_TARGET_NOT_HALTED;
2630 }
2631
2632 /* send read trace buffer command (command 0x61) */
2633 xscale_send_u32(target, 0x61);
2634
2635 /* receive trace buffer content */
2636 xscale_receive(target, trace_buffer, 258);
2637
2638 /* parse buffer backwards to identify address entries */
2639 for (i = 255; i >= 0; i--)
2640 {
2641 is_address[i] = 0;
2642 if (((trace_buffer[i] & 0xf0) == 0x90) ||
2643 ((trace_buffer[i] & 0xf0) == 0xd0))
2644 {
2645 if (i >= 3)
2646 is_address[--i] = 1;
2647 if (i >= 2)
2648 is_address[--i] = 1;
2649 if (i >= 1)
2650 is_address[--i] = 1;
2651 if (i >= 0)
2652 is_address[--i] = 1;
2653 }
2654 }
2655
2656
2657 /* search first non-zero entry */
2658 for (j = 0; (j < 256) && (trace_buffer[j] == 0) && (!is_address[j]); j++)
2659 ;
2660
2661 if (j == 256)
2662 {
2663 LOG_DEBUG("no trace data collected");
2664 return ERROR_XSCALE_NO_TRACE_DATA;
2665 }
2666
2667 for (trace_data_p = &xscale->trace.data; *trace_data_p; trace_data_p = &(*trace_data_p)->next)
2668 ;
2669
2670 *trace_data_p = malloc(sizeof(xscale_trace_data_t));
2671 (*trace_data_p)->next = NULL;
2672 (*trace_data_p)->chkpt0 = trace_buffer[256];
2673 (*trace_data_p)->chkpt1 = trace_buffer[257];
2674 (*trace_data_p)->last_instruction = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
2675 (*trace_data_p)->entries = malloc(sizeof(xscale_trace_entry_t) * (256 - j));
2676 (*trace_data_p)->depth = 256 - j;
2677
2678 for (i = j; i < 256; i++)
2679 {
2680 (*trace_data_p)->entries[i - j].data = trace_buffer[i];
2681 if (is_address[i])
2682 (*trace_data_p)->entries[i - j].type = XSCALE_TRACE_ADDRESS;
2683 else
2684 (*trace_data_p)->entries[i - j].type = XSCALE_TRACE_MESSAGE;
2685 }
2686
2687 return ERROR_OK;
2688 }
2689
2690 int xscale_read_instruction(target_t *target, arm_instruction_t *instruction)
2691 {
2692 /* get pointers to arch-specific information */
2693 armv4_5_common_t *armv4_5 = target->arch_info;
2694 xscale_common_t *xscale = armv4_5->arch_info;
2695 int i;
2696 int section = -1;
2697 u32 size_read;
2698 u32 opcode;
2699 int retval;
2700
2701 if (!xscale->trace.image)
2702 return ERROR_TRACE_IMAGE_UNAVAILABLE;
2703
2704 /* search for the section the current instruction belongs to */
2705 for (i = 0; i < xscale->trace.image->num_sections; i++)
2706 {
2707 if ((xscale->trace.image->sections[i].base_address <= xscale->trace.current_pc) &&
2708 (xscale->trace.image->sections[i].base_address + xscale->trace.image->sections[i].size > xscale->trace.current_pc))
2709 {
2710 section = i;
2711 break;
2712 }
2713 }
2714
2715 if (section == -1)
2716 {
2717 /* current instruction couldn't be found in the image */
2718 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
2719 }
2720
2721 if (xscale->trace.core_state == ARMV4_5_STATE_ARM)
2722 {
2723 u8 buf[4];
2724 if ((retval = image_read_section(xscale->trace.image, section,
2725 xscale->trace.current_pc - xscale->trace.image->sections[section].base_address,
2726 4, buf, &size_read)) != ERROR_OK)
2727 {
2728 LOG_ERROR("error while reading instruction: %i", retval);
2729 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
2730 }
2731 opcode = target_buffer_get_u32(target, buf);
2732 arm_evaluate_opcode(opcode, xscale->trace.current_pc, instruction);
2733 }
2734 else if (xscale->trace.core_state == ARMV4_5_STATE_THUMB)
2735 {
2736 u8 buf[2];
2737 if ((retval = image_read_section(xscale->trace.image, section,
2738 xscale->trace.current_pc - xscale->trace.image->sections[section].base_address,
2739 2, buf, &size_read)) != ERROR_OK)
2740 {
2741 LOG_ERROR("error while reading instruction: %i", retval);
2742 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
2743 }
2744 opcode = target_buffer_get_u16(target, buf);
2745 thumb_evaluate_opcode(opcode, xscale->trace.current_pc, instruction);
2746 }
2747 else
2748 {
2749 LOG_ERROR("BUG: unknown core state encountered");
2750 exit(-1);
2751 }
2752
2753 return ERROR_OK;
2754 }
2755
2756 int xscale_branch_address(xscale_trace_data_t *trace_data, int i, u32 *target)
2757 {
2758 /* if there are less than four entries prior to the indirect branch message
2759 * we can't extract the address */
2760 if (i < 4)
2761 {
2762 return -1;
2763 }
2764
2765 *target = (trace_data->entries[i-1].data) | (trace_data->entries[i-2].data << 8) |
2766 (trace_data->entries[i-3].data << 16) | (trace_data->entries[i-4].data << 24);
2767
2768 return 0;
2769 }
2770
2771 int xscale_analyze_trace(target_t *target, command_context_t *cmd_ctx)
2772 {
2773 /* get pointers to arch-specific information */
2774 armv4_5_common_t *armv4_5 = target->arch_info;
2775 xscale_common_t *xscale = armv4_5->arch_info;
2776 int next_pc_ok = 0;
2777 u32 next_pc = 0x0;
2778 xscale_trace_data_t *trace_data = xscale->trace.data;
2779 int retval;
2780
2781 while (trace_data)
2782 {
2783 int i, chkpt;
2784 int rollover;
2785 int branch;
2786 int exception;
2787 xscale->trace.core_state = ARMV4_5_STATE_ARM;
2788
2789 chkpt = 0;
2790 rollover = 0;
2791
2792 for (i = 0; i < trace_data->depth; i++)
2793 {
2794 next_pc_ok = 0;
2795 branch = 0;
2796 exception = 0;
2797
2798 if (trace_data->entries[i].type == XSCALE_TRACE_ADDRESS)
2799 continue;
2800
2801 switch ((trace_data->entries[i].data & 0xf0) >> 4)
2802 {
2803 case 0: /* Exceptions */
2804 case 1:
2805 case 2:
2806 case 3:
2807 case 4:
2808 case 5:
2809 case 6:
2810 case 7:
2811 exception = (trace_data->entries[i].data & 0x70) >> 4;
2812 next_pc_ok = 1;
2813 next_pc = (trace_data->entries[i].data & 0xf0) >> 2;
2814 command_print(cmd_ctx, "--- exception %i ---", (trace_data->entries[i].data & 0xf0) >> 4);
2815 break;
2816 case 8: /* Direct Branch */
2817 branch = 1;
2818 break;
2819 case 9: /* Indirect Branch */
2820 branch = 1;
2821 if (xscale_branch_address(trace_data, i, &next_pc) == 0)
2822 {
2823 next_pc_ok = 1;
2824 }
2825 break;
2826 case 13: /* Checkpointed Indirect Branch */
2827 if (xscale_branch_address(trace_data, i, &next_pc) == 0)
2828 {
2829 next_pc_ok = 1;
2830 if (((chkpt == 0) && (next_pc != trace_data->chkpt0))
2831 || ((chkpt == 1) && (next_pc != trace_data->chkpt1)))
2832 LOG_WARNING("checkpointed indirect branch target address doesn't match checkpoint");
2833 }
2834 /* explicit fall-through */
2835 case 12: /* Checkpointed Direct Branch */
2836 branch = 1;
2837 if (chkpt == 0)
2838 {
2839 next_pc_ok = 1;
2840 next_pc = trace_data->chkpt0;
2841 chkpt++;
2842 }
2843 else if (chkpt == 1)
2844 {
2845 next_pc_ok = 1;
2846 next_pc = trace_data->chkpt0;
2847 chkpt++;
2848 }
2849 else
2850 {
2851 LOG_WARNING("more than two checkpointed branches encountered");
2852 }
2853 break;
2854 case 15: /* Roll-over */
2855 rollover++;
2856 continue;
2857 default: /* Reserved */
2858 command_print(cmd_ctx, "--- reserved trace message ---");
2859 LOG_ERROR("BUG: trace message %i is reserved", (trace_data->entries[i].data & 0xf0) >> 4);
2860 return ERROR_OK;
2861 }
2862
2863 if (xscale->trace.pc_ok)
2864 {
2865 int executed = (trace_data->entries[i].data & 0xf) + rollover * 16;
2866 arm_instruction_t instruction;
2867
2868 if ((exception == 6) || (exception == 7))
2869 {
2870 /* IRQ or FIQ exception, no instruction executed */
2871 executed -= 1;
2872 }
2873
2874 while (executed-- >= 0)
2875 {
2876 if ((retval = xscale_read_instruction(target, &instruction)) != ERROR_OK)
2877 {
2878 /* can't continue tracing with no image available */
2879 if (retval == ERROR_TRACE_IMAGE_UNAVAILABLE)
2880 {
2881 return retval;
2882 }
2883 else if (retval == ERROR_TRACE_INSTRUCTION_UNAVAILABLE)
2884 {
2885 /* TODO: handle incomplete images */
2886 }
2887 }
2888
2889 /* a precise abort on a load to the PC is included in the incremental
2890 * word count, other instructions causing data aborts are not included
2891 */
2892 if ((executed == 0) && (exception == 4)
2893 && ((instruction.type >= ARM_LDR) && (instruction.type <= ARM_LDM)))
2894 {
2895 if ((instruction.type == ARM_LDM)
2896 && ((instruction.info.load_store_multiple.register_list & 0x8000) == 0))
2897 {
2898 executed--;
2899 }
2900 else if (((instruction.type >= ARM_LDR) && (instruction.type <= ARM_LDRSH))
2901 && (instruction.info.load_store.Rd != 15))
2902 {
2903 executed--;
2904 }
2905 }
2906
2907 /* only the last instruction executed
2908 * (the one that caused the control flow change)
2909 * could be a taken branch
2910 */
2911 if (((executed == -1) && (branch == 1)) &&
2912 (((instruction.type == ARM_B) ||
2913 (instruction.type == ARM_BL) ||
2914 (instruction.type == ARM_BLX)) &&
2915 (instruction.info.b_bl_bx_blx.target_address != 0xffffffff)))
2916 {
2917 xscale->trace.current_pc = instruction.info.b_bl_bx_blx.target_address;
2918 }
2919 else
2920 {
2921 xscale->trace.current_pc += (xscale->trace.core_state == ARMV4_5_STATE_ARM) ? 4 : 2;
2922 }
2923 command_print(cmd_ctx, "%s", instruction.text);
2924 }
2925
2926 rollover = 0;
2927 }
2928
2929 if (next_pc_ok)
2930 {
2931 xscale->trace.current_pc = next_pc;
2932 xscale->trace.pc_ok = 1;
2933 }
2934 }
2935
2936 for (; xscale->trace.current_pc < trace_data->last_instruction; xscale->trace.current_pc += (xscale->trace.core_state == ARMV4_5_STATE_ARM) ? 4 : 2)
2937 {
2938 arm_instruction_t instruction;
2939 if ((retval = xscale_read_instruction(target, &instruction)) != ERROR_OK)
2940 {
2941 /* can't continue tracing with no image available */
2942 if (retval == ERROR_TRACE_IMAGE_UNAVAILABLE)
2943 {
2944 return retval;
2945 }
2946 else if (retval == ERROR_TRACE_INSTRUCTION_UNAVAILABLE)
2947 {
2948 /* TODO: handle incomplete images */
2949 }
2950 }
2951 command_print(cmd_ctx, "%s", instruction.text);
2952 }
2953
2954 trace_data = trace_data->next;
2955 }
2956
2957 return ERROR_OK;
2958 }
2959
2960 void xscale_build_reg_cache(target_t *target)
2961 {
2962 /* get pointers to arch-specific information */
2963 armv4_5_common_t *armv4_5 = target->arch_info;
2964 xscale_common_t *xscale = armv4_5->arch_info;
2965
2966 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
2967 xscale_reg_t *arch_info = malloc(sizeof(xscale_reg_arch_info));
2968 int i;
2969 int num_regs = sizeof(xscale_reg_arch_info) / sizeof(xscale_reg_t);
2970
2971 (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
2972 armv4_5->core_cache = (*cache_p);
2973
2974 /* register a register arch-type for XScale dbg registers only once */
2975 if (xscale_reg_arch_type == -1)
2976 xscale_reg_arch_type = register_reg_arch_type(xscale_get_reg, xscale_set_reg);
2977
2978 (*cache_p)->next = malloc(sizeof(reg_cache_t));
2979 cache_p = &(*cache_p)->next;
2980
2981 /* fill in values for the xscale reg cache */
2982 (*cache_p)->name = "XScale registers";
2983 (*cache_p)->next = NULL;
2984 (*cache_p)->reg_list = malloc(num_regs * sizeof(reg_t));
2985 (*cache_p)->num_regs = num_regs;
2986
2987 for (i = 0; i < num_regs; i++)
2988 {
2989 (*cache_p)->reg_list[i].name = xscale_reg_list[i];
2990 (*cache_p)->reg_list[i].value = calloc(4, 1);
2991 (*cache_p)->reg_list[i].dirty = 0;
2992 (*cache_p)->reg_list[i].valid = 0;
2993 (*cache_p)->reg_list[i].size = 32;
2994 (*cache_p)->reg_list[i].bitfield_desc = NULL;
2995 (*cache_p)->reg_list[i].num_bitfields = 0;
2996 (*cache_p)->reg_list[i].arch_info = &arch_info[i];
2997 (*cache_p)->reg_list[i].arch_type = xscale_reg_arch_type;
2998 arch_info[i] = xscale_reg_arch_info[i];
2999 arch_info[i].target = target;
3000 }
3001
3002 xscale->reg_cache = (*cache_p);
3003 }
3004
3005 int xscale_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
3006 {
3007 return ERROR_OK;
3008 }
3009
3010 int xscale_quit(void)
3011 {
3012 return ERROR_OK;
3013 }
3014
3015 int xscale_init_arch_info(target_t *target, xscale_common_t *xscale, jtag_tap_t *tap, const char *variant)
3016 {
3017 armv4_5_common_t *armv4_5;
3018 u32 high_reset_branch, low_reset_branch;
3019 int i;
3020
3021 armv4_5 = &xscale->armv4_5_common;
3022
3023 /* store architecture specfic data (none so far) */
3024 xscale->arch_info = NULL;
3025 xscale->common_magic = XSCALE_COMMON_MAGIC;
3026
3027 /* remember the variant (PXA25x, PXA27x, IXP42x, ...) */
3028 xscale->variant = strdup(variant);
3029
3030 /* prepare JTAG information for the new target */
3031 xscale->jtag_info.tap = tap;
3032
3033 xscale->jtag_info.dbgrx = 0x02;
3034 xscale->jtag_info.dbgtx = 0x10;
3035 xscale->jtag_info.dcsr = 0x09;
3036 xscale->jtag_info.ldic = 0x07;
3037
3038 if ((strcmp(xscale->variant, "pxa250") == 0) ||
3039 (strcmp(xscale->variant, "pxa255") == 0) ||
3040 (strcmp(xscale->variant, "pxa26x") == 0))
3041 {
3042 xscale->jtag_info.ir_length = 5;
3043 }
3044 else if ((strcmp(xscale->variant, "pxa27x") == 0) ||
3045 (strcmp(xscale->variant, "ixp42x") == 0) ||
3046 (strcmp(xscale->variant, "ixp45x") == 0) ||
3047 (strcmp(xscale->variant, "ixp46x") == 0))
3048 {
3049 xscale->jtag_info.ir_length = 7;
3050 }
3051
3052 /* the debug handler isn't installed (and thus not running) at this time */
3053 xscale->handler_installed = 0;
3054 xscale->handler_running = 0;
3055 xscale->handler_address = 0xfe000800;
3056
3057 /* clear the vectors we keep locally for reference */
3058 memset(xscale->low_vectors, 0, sizeof(xscale->low_vectors));
3059 memset(xscale->high_vectors, 0, sizeof(xscale->high_vectors));
3060
3061 /* no user-specified vectors have been configured yet */
3062 xscale->static_low_vectors_set = 0x0;
3063 xscale->static_high_vectors_set = 0x0;
3064
3065 /* calculate branches to debug handler */
3066 low_reset_branch = (xscale->handler_address + 0x20 - 0x0 - 0x8) >> 2;
3067 high_reset_branch = (xscale->handler_address + 0x20 - 0xffff0000 - 0x8) >> 2;
3068
3069 xscale->low_vectors[0] = ARMV4_5_B((low_reset_branch & 0xffffff), 0);
3070 xscale->high_vectors[0] = ARMV4_5_B((high_reset_branch & 0xffffff), 0);
3071
3072 for (i = 1; i <= 7; i++)
3073 {
3074 xscale->low_vectors[i] = ARMV4_5_B(0xfffffe, 0);
3075 xscale->high_vectors[i] = ARMV4_5_B(0xfffffe, 0);
3076 }
3077
3078 /* 64kB aligned region used for DCache cleaning */
3079 xscale->cache_clean_address = 0xfffe0000;
3080
3081 xscale->hold_rst = 0;
3082 xscale->external_debug_break = 0;
3083
3084 xscale->ibcr_available = 2;
3085 xscale->ibcr0_used = 0;
3086 xscale->ibcr1_used = 0;
3087
3088 xscale->dbr_available = 2;
3089 xscale->dbr0_used = 0;
3090 xscale->dbr1_used = 0;
3091
3092 xscale->arm_bkpt = ARMV5_BKPT(0x0);
3093 xscale->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
3094
3095 xscale->vector_catch = 0x1;
3096
3097 xscale->trace.capture_status = TRACE_IDLE;
3098 xscale->trace.data = NULL;
3099 xscale->trace.image = NULL;
3100 xscale->trace.buffer_enabled = 0;
3101 xscale->trace.buffer_fill = 0;
3102
3103 /* prepare ARMv4/5 specific information */
3104 armv4_5->arch_info = xscale;
3105 armv4_5->read_core_reg = xscale_read_core_reg;
3106 armv4_5->write_core_reg = xscale_write_core_reg;
3107 armv4_5->full_context = xscale_full_context;
3108
3109 armv4_5_init_arch_info(target, armv4_5);
3110
3111 xscale->armv4_5_mmu.armv4_5_cache.ctype = -1;
3112 xscale->armv4_5_mmu.get_ttb = xscale_get_ttb;
3113 xscale->armv4_5_mmu.read_memory = xscale_read_memory;
3114 xscale->armv4_5_mmu.write_memory = xscale_write_memory;
3115 xscale->armv4_5_mmu.disable_mmu_caches = xscale_disable_mmu_caches;
3116 xscale->armv4_5_mmu.enable_mmu_caches = xscale_enable_mmu_caches;
3117 xscale->armv4_5_mmu.has_tiny_pages = 1;
3118 xscale->armv4_5_mmu.mmu_enabled = 0;
3119
3120 return ERROR_OK;
3121 }
3122
3123 /* target xscale <endianess> <startup_mode> <chain_pos> <variant> */
3124 int xscale_target_create(struct target_s *target, Jim_Interp *interp)
3125 {
3126 xscale_common_t *xscale = calloc(1,sizeof(xscale_common_t));
3127
3128 xscale_init_arch_info(target, xscale, target->tap, target->variant);
3129 xscale_build_reg_cache(target);
3130
3131 return ERROR_OK;
3132 }
3133
3134 int xscale_handle_debug_handler_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3135 {
3136 target_t *target = NULL;
3137 armv4_5_common_t *armv4_5;
3138 xscale_common_t *xscale;
3139
3140 u32 handler_address;
3141
3142 if (argc < 2)
3143 {
3144 LOG_ERROR("'xscale debug_handler <target#> <address>' command takes two required operands");
3145 return ERROR_OK;
3146 }
3147
3148 if ((target = get_target_by_num(strtoul(args[0], NULL, 0))) == NULL)
3149 {
3150 LOG_ERROR("no target '%s' configured", args[0]);
3151 return ERROR_FAIL;
3152 }
3153
3154 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3155 {
3156 return ERROR_FAIL;
3157 }
3158
3159 handler_address = strtoul(args[1], NULL, 0);
3160
3161 if (((handler_address >= 0x800) && (handler_address <= 0x1fef800)) ||
3162 ((handler_address >= 0xfe000800) && (handler_address <= 0xfffff800)))
3163 {
3164 xscale->handler_address = handler_address;
3165 }
3166 else
3167 {
3168 LOG_ERROR("xscale debug_handler <address> must be between 0x800 and 0x1fef800 or between 0xfe000800 and 0xfffff800");
3169 return ERROR_FAIL;
3170 }
3171
3172 return ERROR_OK;
3173 }
3174
3175 int xscale_handle_cache_clean_address_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3176 {
3177 target_t *target = NULL;
3178 armv4_5_common_t *armv4_5;
3179 xscale_common_t *xscale;
3180
3181 u32 cache_clean_address;
3182
3183 if (argc < 2)
3184 {
3185 return ERROR_COMMAND_SYNTAX_ERROR;
3186 }
3187
3188 if ((target = get_target_by_num(strtoul(args[0], NULL, 0))) == NULL)
3189 {
3190 LOG_ERROR("no target '%s' configured", args[0]);
3191 return ERROR_FAIL;
3192 }
3193
3194 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3195 {
3196 return ERROR_FAIL;
3197 }
3198
3199 cache_clean_address = strtoul(args[1], NULL, 0);
3200
3201 if (cache_clean_address & 0xffff)
3202 {
3203 LOG_ERROR("xscale cache_clean_address <address> must be 64kb aligned");
3204 }
3205 else
3206 {
3207 xscale->cache_clean_address = cache_clean_address;
3208 }
3209
3210 return ERROR_OK;
3211 }
3212
3213 int xscale_handle_cache_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3214 {
3215 target_t *target = get_current_target(cmd_ctx);
3216 armv4_5_common_t *armv4_5;
3217 xscale_common_t *xscale;
3218
3219 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3220 {
3221 return ERROR_OK;
3222 }
3223
3224 return armv4_5_handle_cache_info_command(cmd_ctx, &xscale->armv4_5_mmu.armv4_5_cache);
3225 }
3226
3227 static int xscale_virt2phys(struct target_s *target, u32 virtual, u32 *physical)
3228 {
3229 armv4_5_common_t *armv4_5;
3230 xscale_common_t *xscale;
3231 int retval;
3232 int type;
3233 u32 cb;
3234 int domain;
3235 u32 ap;
3236
3237 if ((retval = xscale_get_arch_pointers(target, &armv4_5, &xscale)) != ERROR_OK)
3238 {
3239 return retval;
3240 }
3241 u32 ret = armv4_5_mmu_translate_va(target, &xscale->armv4_5_mmu, virtual, &type, &cb, &domain, &ap);
3242 if (type == -1)
3243 {
3244 return ret;
3245 }
3246 *physical = ret;
3247 return ERROR_OK;
3248 }
3249
3250 static int xscale_mmu(struct target_s *target, int *enabled)
3251 {
3252 armv4_5_common_t *armv4_5 = target->arch_info;
3253 xscale_common_t *xscale = armv4_5->arch_info;
3254
3255 if (target->state != TARGET_HALTED)
3256 {
3257 LOG_ERROR("Target not halted");
3258 return ERROR_TARGET_INVALID;
3259 }
3260 *enabled = xscale->armv4_5_mmu.mmu_enabled;
3261 return ERROR_OK;
3262 }
3263
3264 int xscale_handle_mmu_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
3265 {
3266 target_t *target = get_current_target(cmd_ctx);
3267 armv4_5_common_t *armv4_5;
3268 xscale_common_t *xscale;
3269
3270 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3271 {
3272 return ERROR_OK;
3273 }
3274
3275 if (target->state != TARGET_HALTED)
3276 {
3277 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3278 return ERROR_OK;
3279 }
3280
3281 if (argc >= 1)
3282 {
3283 if (strcmp("enable", args[0]) == 0)
3284 {
3285 xscale_enable_mmu_caches(target, 1, 0, 0);
3286 xscale->armv4_5_mmu.mmu_enabled = 1;
3287 }
3288 else if (strcmp("disable", args[0]) == 0)
3289 {
3290 xscale_disable_mmu_caches(target, 1, 0, 0);
3291 xscale->armv4_5_mmu.mmu_enabled = 0;
3292 }
3293 }
3294
3295 command_print(cmd_ctx, "mmu %s", (xscale->armv4_5_mmu.mmu_enabled) ? "enabled" : "disabled");
3296
3297 return ERROR_OK;
3298 }
3299
3300 int xscale_handle_idcache_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
3301 {
3302 target_t *target = get_current_target(cmd_ctx);
3303 armv4_5_common_t *armv4_5;
3304 xscale_common_t *xscale;
3305 int icache = 0, dcache = 0;
3306
3307 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3308 {
3309 return ERROR_OK;
3310 }
3311
3312 if (target->state != TARGET_HALTED)
3313 {
3314 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3315 return ERROR_OK;
3316 }
3317
3318 if (strcmp(cmd, "icache") == 0)
3319 icache = 1;
3320 else if (strcmp(cmd, "dcache") == 0)
3321 dcache = 1;
3322
3323 if (argc >= 1)
3324 {
3325 if (strcmp("enable", args[0]) == 0)
3326 {
3327 xscale_enable_mmu_caches(target, 0, dcache, icache);
3328
3329 if (icache)
3330 xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 1;
3331 else if (dcache)
3332 xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 1;
3333 }
3334 else if (strcmp("disable", args[0]) == 0)
3335 {
3336 xscale_disable_mmu_caches(target, 0, dcache, icache);
3337
3338 if (icache)
3339 xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
3340 else if (dcache)
3341 xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
3342 }
3343 }
3344
3345 if (icache)
3346 command_print(cmd_ctx, "icache %s", (xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled) ? "enabled" : "disabled");
3347
3348 if (dcache)
3349 command_print(cmd_ctx, "dcache %s", (xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) ? "enabled" : "disabled");
3350
3351 return ERROR_OK;
3352 }
3353
3354 int xscale_handle_vector_catch_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
3355 {
3356 target_t *target = get_current_target(cmd_ctx);
3357 armv4_5_common_t *armv4_5;
3358 xscale_common_t *xscale;
3359
3360 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3361 {
3362 return ERROR_OK;
3363 }
3364
3365 if (argc < 1)
3366 {
3367 command_print(cmd_ctx, "usage: xscale vector_catch [mask]");
3368 }
3369 else
3370 {
3371 xscale->vector_catch = strtoul(args[0], NULL, 0);
3372 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 8, xscale->vector_catch);
3373 xscale_write_dcsr(target, -1, -1);
3374 }
3375
3376 command_print(cmd_ctx, "vector catch mask: 0x%2.2x", xscale->vector_catch);
3377
3378 return ERROR_OK;
3379 }
3380
3381
3382 int xscale_handle_trace_buffer_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3383 {
3384 target_t *target = get_current_target(cmd_ctx);
3385 armv4_5_common_t *armv4_5;
3386 xscale_common_t *xscale;
3387 u32 dcsr_value;
3388
3389 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3390 {
3391 return ERROR_OK;
3392 }
3393
3394 if (target->state != TARGET_HALTED)
3395 {
3396 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3397 return ERROR_OK;
3398 }
3399
3400 if ((argc >= 1) && (strcmp("enable", args[0]) == 0))
3401 {
3402 xscale_trace_data_t *td, *next_td;
3403 xscale->trace.buffer_enabled = 1;
3404
3405 /* free old trace data */
3406 td = xscale->trace.data;
3407 while (td)
3408 {
3409 next_td = td->next;
3410
3411 if (td->entries)
3412 free(td->entries);
3413 free(td);
3414 td = next_td;
3415 }
3416 xscale->trace.data = NULL;
3417 }
3418 else if ((argc >= 1) && (strcmp("disable", args[0]) == 0))
3419 {
3420 xscale->trace.buffer_enabled = 0;
3421 }
3422
3423 if ((argc >= 2) && (strcmp("fill", args[1]) == 0))
3424 {
3425 if (argc >= 3)
3426 xscale->trace.buffer_fill = strtoul(args[2], NULL, 0);
3427 else
3428 xscale->trace.buffer_fill = 1;
3429 }
3430 else if ((argc >= 2) && (strcmp("wrap", args[1]) == 0))
3431 {
3432 xscale->trace.buffer_fill = -1;
3433 }
3434
3435 if (xscale->trace.buffer_enabled)
3436 {
3437 /* if we enable the trace buffer in fill-once
3438 * mode we know the address of the first instruction */
3439 xscale->trace.pc_ok = 1;
3440 xscale->trace.current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
3441 }
3442 else
3443 {
3444 /* otherwise the address is unknown, and we have no known good PC */
3445 xscale->trace.pc_ok = 0;
3446 }
3447
3448 command_print(cmd_ctx, "trace buffer %s (%s)",
3449 (xscale->trace.buffer_enabled) ? "enabled" : "disabled",
3450 (xscale->trace.buffer_fill > 0) ? "fill" : "wrap");
3451
3452 dcsr_value = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 0, 32);
3453 if (xscale->trace.buffer_fill >= 0)
3454 xscale_write_dcsr_sw(target, (dcsr_value & 0xfffffffc) | 2);
3455 else
3456 xscale_write_dcsr_sw(target, dcsr_value & 0xfffffffc);
3457
3458 return ERROR_OK;
3459 }
3460
3461 int xscale_handle_trace_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3462 {
3463 target_t *target;
3464 armv4_5_common_t *armv4_5;
3465 xscale_common_t *xscale;
3466
3467 if (argc < 1)
3468 {
3469 command_print(cmd_ctx, "usage: xscale trace_image <file> [base address] [type]");
3470 return ERROR_OK;
3471 }
3472
3473 target = get_current_target(cmd_ctx);
3474
3475 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3476 {
3477 return ERROR_OK;
3478 }
3479
3480 if (xscale->trace.image)
3481 {
3482 image_close(xscale->trace.image);
3483 free(xscale->trace.image);
3484 command_print(cmd_ctx, "previously loaded image found and closed");
3485 }
3486
3487 xscale->trace.image = malloc(sizeof(image_t));
3488 xscale->trace.image->base_address_set = 0;
3489 xscale->trace.image->start_address_set = 0;
3490
3491 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
3492 if (argc >= 2)
3493 {
3494 xscale->trace.image->base_address_set = 1;
3495 xscale->trace.image->base_address = strtoul(args[1], NULL, 0);
3496 }
3497 else
3498 {
3499 xscale->trace.image->base_address_set = 0;
3500 }
3501
3502 if (image_open(xscale->trace.image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
3503 {
3504 free(xscale->trace.image);
3505 xscale->trace.image = NULL;
3506 return ERROR_OK;
3507 }
3508
3509 return ERROR_OK;
3510 }
3511
3512 int xscale_handle_dump_trace_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3513 {
3514 target_t *target = get_current_target(cmd_ctx);
3515 armv4_5_common_t *armv4_5;
3516 xscale_common_t *xscale;
3517 xscale_trace_data_t *trace_data;
3518 fileio_t file;
3519
3520 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3521 {
3522 return ERROR_OK;
3523 }
3524
3525 if (target->state != TARGET_HALTED)
3526 {
3527 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3528 return ERROR_OK;
3529 }
3530
3531 if (argc < 1)
3532 {
3533 command_print(cmd_ctx, "usage: xscale dump_trace <file>");
3534 return ERROR_OK;
3535 }
3536
3537 trace_data = xscale->trace.data;
3538
3539 if (!trace_data)
3540 {
3541 command_print(cmd_ctx, "no trace data collected");
3542 return ERROR_OK;
3543 }
3544
3545 if (fileio_open(&file, args[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)
3546 {
3547 return ERROR_OK;
3548 }
3549
3550 while (trace_data)
3551 {
3552 int i;
3553
3554 fileio_write_u32(&file, trace_data->chkpt0);
3555 fileio_write_u32(&file, trace_data->chkpt1);
3556 fileio_write_u32(&file, trace_data->last_instruction);
3557 fileio_write_u32(&file, trace_data->depth);
3558
3559 for (i = 0; i < trace_data->depth; i++)
3560 fileio_write_u32(&file, trace_data->entries[i].data | ((trace_data->entries[i].type & 0xffff) << 16));
3561
3562 trace_data = trace_data->next;
3563 }
3564
3565 fileio_close(&file);
3566
3567 return ERROR_OK;
3568 }
3569
3570 int xscale_handle_analyze_trace_buffer_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3571 {
3572 target_t *target = get_current_target(cmd_ctx);
3573 armv4_5_common_t *armv4_5;
3574 xscale_common_t *xscale;
3575
3576 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3577 {
3578 return ERROR_OK;
3579 }
3580
3581 xscale_analyze_trace(target, cmd_ctx);
3582
3583 return ERROR_OK;
3584 }
3585
3586 int xscale_handle_cp15(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
3587 {
3588 target_t *target = get_current_target(cmd_ctx);
3589 armv4_5_common_t *armv4_5;
3590 xscale_common_t *xscale;
3591
3592 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3593 {
3594 return ERROR_OK;
3595 }
3596
3597 if (target->state != TARGET_HALTED)
3598 {
3599 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3600 return ERROR_OK;
3601 }
3602 u32 reg_no = 0;
3603 reg_t *reg = NULL;
3604 if(argc > 0)
3605 {
3606 reg_no = strtoul(args[0], NULL, 0);
3607 /*translate from xscale cp15 register no to openocd register*/
3608 switch(reg_no)
3609 {
3610 case 0:
3611 reg_no = XSCALE_MAINID;
3612 break;
3613 case 1:
3614 reg_no = XSCALE_CTRL;
3615 break;
3616 case 2:
3617 reg_no = XSCALE_TTB;
3618 break;
3619 case 3:
3620 reg_no = XSCALE_DAC;
3621 break;
3622 case 5:
3623 reg_no = XSCALE_FSR;
3624 break;
3625 case 6:
3626 reg_no = XSCALE_FAR;
3627 break;
3628 case 13:
3629 reg_no = XSCALE_PID;
3630 break;
3631 case 15:
3632 reg_no = XSCALE_CPACCESS;
3633 break;
3634 default:
3635 command_print(cmd_ctx, "invalid register number");
3636 return ERROR_INVALID_ARGUMENTS;
3637 }
3638 reg = &xscale->reg_cache->reg_list[reg_no];
3639
3640 }
3641 if(argc == 1)
3642 {
3643 u32 value;
3644
3645 /* read cp15 control register */
3646 xscale_get_reg(reg);
3647 value = buf_get_u32(reg->value, 0, 32);
3648 command_print(cmd_ctx, "%s (/%i): 0x%x", reg->name, reg->size, value);
3649 }
3650 else if(argc == 2)
3651 {
3652
3653 u32 value = strtoul(args[1], NULL, 0);
3654
3655 /* send CP write request (command 0x41) */
3656 xscale_send_u32(target, 0x41);
3657
3658 /* send CP register number */
3659 xscale_send_u32(target, reg_no);
3660
3661 /* send CP register value */
3662 xscale_send_u32(target, value);
3663
3664 /* execute cpwait to ensure outstanding operations complete */
3665 xscale_send_u32(target, 0x53);
3666 }
3667 else
3668 {
3669 command_print(cmd_ctx, "usage: cp15 [register]<, [value]>");
3670 }
3671
3672 return ERROR_OK;
3673 }
3674
3675 int xscale_register_commands(struct command_context_s *cmd_ctx)
3676 {
3677 command_t *xscale_cmd;
3678
3679 xscale_cmd = register_command(cmd_ctx, NULL, "xscale", NULL, COMMAND_ANY, "xscale specific commands");
3680
3681 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");
3682 register_command(cmd_ctx, xscale_cmd, "cache_clean_address", xscale_handle_cache_clean_address_command, COMMAND_ANY, NULL);
3683
3684 register_command(cmd_ctx, xscale_cmd, "cache_info", xscale_handle_cache_info_command, COMMAND_EXEC, NULL);
3685 register_command(cmd_ctx, xscale_cmd, "mmu", xscale_handle_mmu_command, COMMAND_EXEC, "['enable'|'disable'] the MMU");
3686 register_command(cmd_ctx, xscale_cmd, "icache", xscale_handle_idcache_command, COMMAND_EXEC, "['enable'|'disable'] the ICache");
3687 register_command(cmd_ctx, xscale_cmd, "dcache", xscale_handle_idcache_command, COMMAND_EXEC, "['enable'|'disable'] the DCache");
3688
3689 register_command(cmd_ctx, xscale_cmd, "vector_catch", xscale_handle_vector_catch_command, COMMAND_EXEC, "<mask> of vectors that should be catched");
3690
3691 register_command(cmd_ctx, xscale_cmd, "trace_buffer", xscale_handle_trace_buffer_command, COMMAND_EXEC, "<enable|disable> ['fill' [n]|'wrap']");
3692
3693 register_command(cmd_ctx, xscale_cmd, "dump_trace", xscale_handle_dump_trace_command, COMMAND_EXEC, "dump content of trace buffer to <file>");
3694 register_command(cmd_ctx, xscale_cmd, "analyze_trace", xscale_handle_analyze_trace_buffer_command, COMMAND_EXEC, "analyze content of trace buffer");
3695 register_command(cmd_ctx, xscale_cmd, "trace_image", xscale_handle_trace_image_command,
3696 COMMAND_EXEC, "load image from <file> [base address]");
3697
3698 register_command(cmd_ctx, xscale_cmd, "cp15", xscale_handle_cp15, COMMAND_EXEC, "access coproc 15 <register> [value]");
3699
3700 armv4_5_register_commands(cmd_ctx);
3701
3702 return ERROR_OK;
3703 }

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)