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

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)