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

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)