better polling debug_level 3 handling
[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_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
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_command = xscale_target_command,
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 target_debug_reason_strings[target->debug_reason],
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", target_state_strings[target->state]);
1229
1230 if (target->state == TARGET_HALTED)
1231 {
1232 LOG_DEBUG("target was already halted");
1233 return ERROR_OK;
1234 }
1235 else if (target->state == TARGET_UNKNOWN)
1236 {
1237 /* this must not happen for a xscale target */
1238 LOG_ERROR("target was in unknown state when halt was requested");
1239 return ERROR_TARGET_INVALID;
1240 }
1241 else if (target->state == TARGET_RESET)
1242 {
1243 LOG_DEBUG("target->state == TARGET_RESET");
1244 }
1245 else
1246 {
1247 /* assert external dbg break */
1248 xscale->external_debug_break = 1;
1249 xscale_read_dcsr(target);
1250
1251 target->debug_reason = DBG_REASON_DBGRQ;
1252 }
1253
1254 return ERROR_OK;
1255 }
1256
1257 int xscale_enable_single_step(struct target_s *target, u32 next_pc)
1258 {
1259 armv4_5_common_t *armv4_5 = target->arch_info;
1260 xscale_common_t *xscale= armv4_5->arch_info;
1261 reg_t *ibcr0 = &xscale->reg_cache->reg_list[XSCALE_IBCR0];
1262
1263 if (xscale->ibcr0_used)
1264 {
1265 breakpoint_t *ibcr0_bp = breakpoint_find(target, buf_get_u32(ibcr0->value, 0, 32) & 0xfffffffe);
1266
1267 if (ibcr0_bp)
1268 {
1269 xscale_unset_breakpoint(target, ibcr0_bp);
1270 }
1271 else
1272 {
1273 LOG_ERROR("BUG: xscale->ibcr0_used is set, but no breakpoint with that address found");
1274 exit(-1);
1275 }
1276 }
1277
1278 xscale_set_reg_u32(ibcr0, next_pc | 0x1);
1279
1280 return ERROR_OK;
1281 }
1282
1283 int xscale_disable_single_step(struct target_s *target)
1284 {
1285 armv4_5_common_t *armv4_5 = target->arch_info;
1286 xscale_common_t *xscale= armv4_5->arch_info;
1287 reg_t *ibcr0 = &xscale->reg_cache->reg_list[XSCALE_IBCR0];
1288
1289 xscale_set_reg_u32(ibcr0, 0x0);
1290
1291 return ERROR_OK;
1292 }
1293
1294 int xscale_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution)
1295 {
1296 armv4_5_common_t *armv4_5 = target->arch_info;
1297 xscale_common_t *xscale= armv4_5->arch_info;
1298 breakpoint_t *breakpoint = target->breakpoints;
1299
1300 u32 current_pc;
1301
1302 int retval;
1303 int i;
1304
1305 LOG_DEBUG("-");
1306
1307 if (target->state != TARGET_HALTED)
1308 {
1309 LOG_WARNING("target not halted");
1310 return ERROR_TARGET_NOT_HALTED;
1311 }
1312
1313 if (!debug_execution)
1314 {
1315 target_free_all_working_areas(target);
1316 }
1317
1318 /* update vector tables */
1319 if ((retval=xscale_update_vectors(target))!=ERROR_OK)
1320 return retval;
1321
1322 /* current = 1: continue on current pc, otherwise continue at <address> */
1323 if (!current)
1324 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, address);
1325
1326 current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
1327
1328 /* if we're at the reset vector, we have to simulate the branch */
1329 if (current_pc == 0x0)
1330 {
1331 arm_simulate_step(target, NULL);
1332 current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
1333 }
1334
1335 /* the front-end may request us not to handle breakpoints */
1336 if (handle_breakpoints)
1337 {
1338 if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))))
1339 {
1340 u32 next_pc;
1341
1342 /* there's a breakpoint at the current PC, we have to step over it */
1343 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint->address);
1344 xscale_unset_breakpoint(target, breakpoint);
1345
1346 /* calculate PC of next instruction */
1347 if ((retval = arm_simulate_step(target, &next_pc)) != ERROR_OK)
1348 {
1349 u32 current_opcode;
1350 target_read_u32(target, current_pc, &current_opcode);
1351 LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode);
1352 }
1353
1354 LOG_DEBUG("enable single-step");
1355 xscale_enable_single_step(target, next_pc);
1356
1357 /* restore banked registers */
1358 xscale_restore_context(target);
1359
1360 /* send resume request (command 0x30 or 0x31)
1361 * clean the trace buffer if it is to be enabled (0x62) */
1362 if (xscale->trace.buffer_enabled)
1363 {
1364 xscale_send_u32(target, 0x62);
1365 xscale_send_u32(target, 0x31);
1366 }
1367 else
1368 xscale_send_u32(target, 0x30);
1369
1370 /* send CPSR */
1371 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1372 LOG_DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1373
1374 for (i = 7; i >= 0; i--)
1375 {
1376 /* send register */
1377 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
1378 LOG_DEBUG("writing r%i with value 0x%8.8x", i, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
1379 }
1380
1381 /* send PC */
1382 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1383 LOG_DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1384
1385 /* wait for and process debug entry */
1386 xscale_debug_entry(target);
1387
1388 LOG_DEBUG("disable single-step");
1389 xscale_disable_single_step(target);
1390
1391 LOG_DEBUG("set breakpoint at 0x%8.8x", breakpoint->address);
1392 xscale_set_breakpoint(target, breakpoint);
1393 }
1394 }
1395
1396 /* enable any pending breakpoints and watchpoints */
1397 xscale_enable_breakpoints(target);
1398 xscale_enable_watchpoints(target);
1399
1400 /* restore banked registers */
1401 xscale_restore_context(target);
1402
1403 /* send resume request (command 0x30 or 0x31)
1404 * clean the trace buffer if it is to be enabled (0x62) */
1405 if (xscale->trace.buffer_enabled)
1406 {
1407 xscale_send_u32(target, 0x62);
1408 xscale_send_u32(target, 0x31);
1409 }
1410 else
1411 xscale_send_u32(target, 0x30);
1412
1413 /* send CPSR */
1414 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1415 LOG_DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1416
1417 for (i = 7; i >= 0; i--)
1418 {
1419 /* send register */
1420 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
1421 LOG_DEBUG("writing r%i with value 0x%8.8x", i, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
1422 }
1423
1424 /* send PC */
1425 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1426 LOG_DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1427
1428 target->debug_reason = DBG_REASON_NOTHALTED;
1429
1430 if (!debug_execution)
1431 {
1432 /* registers are now invalid */
1433 armv4_5_invalidate_core_regs(target);
1434 target->state = TARGET_RUNNING;
1435 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1436 }
1437 else
1438 {
1439 target->state = TARGET_DEBUG_RUNNING;
1440 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
1441 }
1442
1443 LOG_DEBUG("target resumed");
1444
1445 xscale->handler_running = 1;
1446
1447 return ERROR_OK;
1448 }
1449
1450 int xscale_step(struct target_s *target, int current, u32 address, int handle_breakpoints)
1451 {
1452 armv4_5_common_t *armv4_5 = target->arch_info;
1453 xscale_common_t *xscale = armv4_5->arch_info;
1454 breakpoint_t *breakpoint = target->breakpoints;
1455
1456 u32 current_pc, next_pc;
1457 int i;
1458 int retval;
1459
1460 if (target->state != TARGET_HALTED)
1461 {
1462 LOG_WARNING("target not halted");
1463 return ERROR_TARGET_NOT_HALTED;
1464 }
1465
1466 /* current = 1: continue on current pc, otherwise continue at <address> */
1467 if (!current)
1468 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, address);
1469
1470 current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
1471
1472 /* if we're at the reset vector, we have to simulate the step */
1473 if (current_pc == 0x0)
1474 {
1475 arm_simulate_step(target, NULL);
1476 current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
1477
1478 target->debug_reason = DBG_REASON_SINGLESTEP;
1479 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1480
1481 return ERROR_OK;
1482 }
1483
1484 /* the front-end may request us not to handle breakpoints */
1485 if (handle_breakpoints)
1486 if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))))
1487 {
1488 xscale_unset_breakpoint(target, breakpoint);
1489 }
1490
1491 target->debug_reason = DBG_REASON_SINGLESTEP;
1492
1493 /* calculate PC of next instruction */
1494 if ((retval = arm_simulate_step(target, &next_pc)) != ERROR_OK)
1495 {
1496 u32 current_opcode;
1497 target_read_u32(target, current_pc, &current_opcode);
1498 LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode);
1499 }
1500
1501 LOG_DEBUG("enable single-step");
1502 xscale_enable_single_step(target, next_pc);
1503
1504 /* restore banked registers */
1505 xscale_restore_context(target);
1506
1507 /* send resume request (command 0x30 or 0x31)
1508 * clean the trace buffer if it is to be enabled (0x62) */
1509 if (xscale->trace.buffer_enabled)
1510 {
1511 xscale_send_u32(target, 0x62);
1512 xscale_send_u32(target, 0x31);
1513 }
1514 else
1515 xscale_send_u32(target, 0x30);
1516
1517 /* send CPSR */
1518 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1519 LOG_DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1520
1521 for (i = 7; i >= 0; i--)
1522 {
1523 /* send register */
1524 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
1525 LOG_DEBUG("writing r%i with value 0x%8.8x", i, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
1526 }
1527
1528 /* send PC */
1529 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1530 LOG_DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1531
1532 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1533
1534 /* registers are now invalid */
1535 armv4_5_invalidate_core_regs(target);
1536
1537 /* wait for and process debug entry */
1538 xscale_debug_entry(target);
1539
1540 LOG_DEBUG("disable single-step");
1541 xscale_disable_single_step(target);
1542
1543 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1544
1545 if (breakpoint)
1546 {
1547 xscale_set_breakpoint(target, breakpoint);
1548 }
1549
1550 LOG_DEBUG("target stepped");
1551
1552 return ERROR_OK;
1553
1554 }
1555
1556 int xscale_assert_reset(target_t *target)
1557 {
1558 armv4_5_common_t *armv4_5 = target->arch_info;
1559 xscale_common_t *xscale = armv4_5->arch_info;
1560
1561 LOG_DEBUG("target->state: %s", target_state_strings[target->state]);
1562
1563 /* select DCSR instruction (set endstate to R-T-I to ensure we don't
1564 * end up in T-L-R, which would reset JTAG
1565 */
1566 jtag_add_end_state(TAP_RTI);
1567 xscale_jtag_set_instr(xscale->jtag_info.chain_pos, xscale->jtag_info.dcsr);
1568
1569 /* set Hold reset, Halt mode and Trap Reset */
1570 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
1571 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);
1572 xscale_write_dcsr(target, 1, 0);
1573
1574 /* select BYPASS, because having DCSR selected caused problems on the PXA27x */
1575 xscale_jtag_set_instr(xscale->jtag_info.chain_pos, 0x7f);
1576 jtag_execute_queue();
1577
1578 /* assert reset */
1579 jtag_add_reset(0, 1);
1580
1581 /* sleep 1ms, to be sure we fulfill any requirements */
1582 jtag_add_sleep(1000);
1583 jtag_execute_queue();
1584
1585 target->state = TARGET_RESET;
1586
1587 if (target->reset_halt)
1588 {
1589 int retval;
1590 if ((retval = target_halt(target))!=ERROR_OK)
1591 return retval;
1592 }
1593
1594 return ERROR_OK;
1595 }
1596
1597 int xscale_deassert_reset(target_t *target)
1598 {
1599 armv4_5_common_t *armv4_5 = target->arch_info;
1600 xscale_common_t *xscale = armv4_5->arch_info;
1601
1602 fileio_t debug_handler;
1603 u32 address;
1604 u32 binary_size;
1605
1606 u32 buf_cnt;
1607 int i;
1608 int retval;
1609
1610 breakpoint_t *breakpoint = target->breakpoints;
1611
1612 LOG_DEBUG("-");
1613
1614 xscale->ibcr_available = 2;
1615 xscale->ibcr0_used = 0;
1616 xscale->ibcr1_used = 0;
1617
1618 xscale->dbr_available = 2;
1619 xscale->dbr0_used = 0;
1620 xscale->dbr1_used = 0;
1621
1622 /* mark all hardware breakpoints as unset */
1623 while (breakpoint)
1624 {
1625 if (breakpoint->type == BKPT_HARD)
1626 {
1627 breakpoint->set = 0;
1628 }
1629 breakpoint = breakpoint->next;
1630 }
1631
1632 if (!xscale->handler_installed)
1633 {
1634 /* release SRST */
1635 jtag_add_reset(0, 0);
1636
1637 /* wait 300ms; 150 and 100ms were not enough */
1638 jtag_add_sleep(300*1000);
1639
1640 jtag_add_runtest(2030, TAP_RTI);
1641 jtag_execute_queue();
1642
1643 /* set Hold reset, Halt mode and Trap Reset */
1644 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
1645 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);
1646 xscale_write_dcsr(target, 1, 0);
1647
1648 /* Load debug handler */
1649 if (fileio_open(&debug_handler, "xscale/debug_handler.bin", FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
1650 {
1651 return ERROR_OK;
1652 }
1653
1654 if ((binary_size = debug_handler.size) % 4)
1655 {
1656 LOG_ERROR("debug_handler.bin: size not a multiple of 4");
1657 exit(-1);
1658 }
1659
1660 if (binary_size > 0x800)
1661 {
1662 LOG_ERROR("debug_handler.bin: larger than 2kb");
1663 exit(-1);
1664 }
1665
1666 binary_size = CEIL(binary_size, 32) * 32;
1667
1668 address = xscale->handler_address;
1669 while (binary_size > 0)
1670 {
1671 u32 cache_line[8];
1672 u8 buffer[32];
1673
1674 if ((retval = fileio_read(&debug_handler, 32, buffer, &buf_cnt)) != ERROR_OK)
1675 {
1676
1677 }
1678
1679 for (i = 0; i < buf_cnt; i += 4)
1680 {
1681 /* convert LE buffer to host-endian u32 */
1682 cache_line[i / 4] = le_to_h_u32(&buffer[i]);
1683 }
1684
1685 for (; buf_cnt < 32; buf_cnt += 4)
1686 {
1687 cache_line[buf_cnt / 4] = 0xe1a08008;
1688 }
1689
1690 /* only load addresses other than the reset vectors */
1691 if ((address % 0x400) != 0x0)
1692 {
1693 xscale_load_ic(target, 1, address, cache_line);
1694 }
1695
1696 address += buf_cnt;
1697 binary_size -= buf_cnt;
1698 };
1699
1700 xscale_load_ic(target, 1, 0x0, xscale->low_vectors);
1701 xscale_load_ic(target, 1, 0xffff0000, xscale->high_vectors);
1702
1703 jtag_add_runtest(30, TAP_RTI);
1704
1705 jtag_add_sleep(100000);
1706
1707 /* set Hold reset, Halt mode and Trap Reset */
1708 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
1709 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);
1710 xscale_write_dcsr(target, 1, 0);
1711
1712 /* clear Hold reset to let the target run (should enter debug handler) */
1713 xscale_write_dcsr(target, 0, 1);
1714 target->state = TARGET_RUNNING;
1715
1716 if (!target->reset_halt)
1717 {
1718 jtag_add_sleep(10000);
1719
1720 /* we should have entered debug now */
1721 xscale_debug_entry(target);
1722 target->state = TARGET_HALTED;
1723
1724 /* resume the target */
1725 xscale_resume(target, 1, 0x0, 1, 0);
1726 }
1727
1728 fileio_close(&debug_handler);
1729 }
1730 else
1731 {
1732 jtag_add_reset(0, 0);
1733 }
1734
1735
1736 return ERROR_OK;
1737 }
1738
1739 int xscale_soft_reset_halt(struct target_s *target)
1740 {
1741
1742 return ERROR_OK;
1743 }
1744
1745 int xscale_read_core_reg(struct target_s *target, int num, enum armv4_5_mode mode)
1746 {
1747
1748 return ERROR_OK;
1749 }
1750
1751 int xscale_write_core_reg(struct target_s *target, int num, enum armv4_5_mode mode, u32 value)
1752 {
1753
1754 return ERROR_OK;
1755 }
1756
1757 int xscale_full_context(target_t *target)
1758 {
1759 armv4_5_common_t *armv4_5 = target->arch_info;
1760
1761 u32 *buffer;
1762
1763 int i, j;
1764
1765 LOG_DEBUG("-");
1766
1767 if (target->state != TARGET_HALTED)
1768 {
1769 LOG_WARNING("target not halted");
1770 return ERROR_TARGET_NOT_HALTED;
1771 }
1772
1773 buffer = malloc(4 * 8);
1774
1775 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1776 * we can't enter User mode on an XScale (unpredictable),
1777 * but User shares registers with SYS
1778 */
1779 for(i = 1; i < 7; i++)
1780 {
1781 int valid = 1;
1782
1783 /* check if there are invalid registers in the current mode
1784 */
1785 for (j = 0; j <= 16; j++)
1786 {
1787 if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).valid == 0)
1788 valid = 0;
1789 }
1790
1791 if (!valid)
1792 {
1793 u32 tmp_cpsr;
1794
1795 /* request banked registers */
1796 xscale_send_u32(target, 0x0);
1797
1798 tmp_cpsr = 0x0;
1799 tmp_cpsr |= armv4_5_number_to_mode(i);
1800 tmp_cpsr |= 0xc0; /* I/F bits */
1801
1802 /* send CPSR for desired mode */
1803 xscale_send_u32(target, tmp_cpsr);
1804
1805 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1806 if ((armv4_5_number_to_mode(i) != ARMV4_5_MODE_USR) && (armv4_5_number_to_mode(i) != ARMV4_5_MODE_SYS))
1807 {
1808 xscale_receive(target, buffer, 8);
1809 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32, buffer[7]);
1810 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty = 0;
1811 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).valid = 1;
1812 }
1813 else
1814 {
1815 xscale_receive(target, buffer, 7);
1816 }
1817
1818 /* move data from buffer to register cache */
1819 for (j = 8; j <= 14; j++)
1820 {
1821 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]);
1822 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty = 0;
1823 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).valid = 1;
1824 }
1825 }
1826 }
1827
1828 free(buffer);
1829
1830 return ERROR_OK;
1831 }
1832
1833 int xscale_restore_context(target_t *target)
1834 {
1835 armv4_5_common_t *armv4_5 = target->arch_info;
1836
1837 int i, j;
1838
1839 LOG_DEBUG("-");
1840
1841 if (target->state != TARGET_HALTED)
1842 {
1843 LOG_WARNING("target not halted");
1844 return ERROR_TARGET_NOT_HALTED;
1845 }
1846
1847 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1848 * we can't enter User mode on an XScale (unpredictable),
1849 * but User shares registers with SYS
1850 */
1851 for(i = 1; i < 7; i++)
1852 {
1853 int dirty = 0;
1854
1855 /* check if there are invalid registers in the current mode
1856 */
1857 for (j = 8; j <= 14; j++)
1858 {
1859 if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty == 1)
1860 dirty = 1;
1861 }
1862
1863 /* if not USR/SYS, check if the SPSR needs to be written */
1864 if ((armv4_5_number_to_mode(i) != ARMV4_5_MODE_USR) && (armv4_5_number_to_mode(i) != ARMV4_5_MODE_SYS))
1865 {
1866 if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty == 1)
1867 dirty = 1;
1868 }
1869
1870 if (dirty)
1871 {
1872 u32 tmp_cpsr;
1873
1874 /* send banked registers */
1875 xscale_send_u32(target, 0x1);
1876
1877 tmp_cpsr = 0x0;
1878 tmp_cpsr |= armv4_5_number_to_mode(i);
1879 tmp_cpsr |= 0xc0; /* I/F bits */
1880
1881 /* send CPSR for desired mode */
1882 xscale_send_u32(target, tmp_cpsr);
1883
1884 /* send banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1885 for (j = 8; j <= 14; j++)
1886 {
1887 xscale_send_u32(target, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, j).value, 0, 32));
1888 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty = 0;
1889 }
1890
1891 if ((armv4_5_number_to_mode(i) != ARMV4_5_MODE_USR) && (armv4_5_number_to_mode(i) != ARMV4_5_MODE_SYS))
1892 {
1893 xscale_send_u32(target, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32));
1894 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty = 0;
1895 }
1896 }
1897 }
1898
1899 return ERROR_OK;
1900 }
1901
1902 int xscale_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1903 {
1904 armv4_5_common_t *armv4_5 = target->arch_info;
1905 xscale_common_t *xscale = armv4_5->arch_info;
1906 u32 *buf32;
1907 int i;
1908 int retval;
1909
1910 LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
1911
1912 if (target->state != TARGET_HALTED)
1913 {
1914 LOG_WARNING("target not halted");
1915 return ERROR_TARGET_NOT_HALTED;
1916 }
1917
1918 /* sanitize arguments */
1919 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1920 return ERROR_INVALID_ARGUMENTS;
1921
1922 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
1923 return ERROR_TARGET_UNALIGNED_ACCESS;
1924
1925 /* send memory read request (command 0x1n, n: access size) */
1926 if ((retval=xscale_send_u32(target, 0x10 | size))!=ERROR_OK)
1927 return retval;
1928
1929 /* send base address for read request */
1930 if ((retval=xscale_send_u32(target, address))!=ERROR_OK)
1931 return retval;
1932
1933 /* send number of requested data words */
1934 if ((retval=xscale_send_u32(target, count))!=ERROR_OK)
1935 return retval;
1936
1937 /* receive data from target (count times 32-bit words in host endianness) */
1938 buf32 = malloc(4 * count);
1939 if ((retval=xscale_receive(target, buf32, count))!=ERROR_OK)
1940 return retval;
1941
1942 /* extract data from host-endian buffer into byte stream */
1943 for (i = 0; i < count; i++)
1944 {
1945 switch (size)
1946 {
1947 case 4:
1948 target_buffer_set_u32(target, buffer, buf32[i]);
1949 buffer += 4;
1950 break;
1951 case 2:
1952 target_buffer_set_u16(target, buffer, buf32[i] & 0xffff);
1953 buffer += 2;
1954 break;
1955 case 1:
1956 *buffer++ = buf32[i] & 0xff;
1957 break;
1958 default:
1959 LOG_ERROR("should never get here");
1960 exit(-1);
1961 }
1962 }
1963
1964 free(buf32);
1965
1966 /* examine DCSR, to see if Sticky Abort (SA) got set */
1967 if ((retval=xscale_read_dcsr(target))!=ERROR_OK)
1968 return retval;
1969 if (buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 5, 1) == 1)
1970 {
1971 /* clear SA bit */
1972 if ((retval=xscale_send_u32(target, 0x60))!=ERROR_OK)
1973 return retval;
1974
1975 return ERROR_TARGET_DATA_ABORT;
1976 }
1977
1978 return ERROR_OK;
1979 }
1980
1981 int xscale_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1982 {
1983 armv4_5_common_t *armv4_5 = target->arch_info;
1984 xscale_common_t *xscale = armv4_5->arch_info;
1985 int retval;
1986
1987 LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
1988
1989 if (target->state != TARGET_HALTED)
1990 {
1991 LOG_WARNING("target not halted");
1992 return ERROR_TARGET_NOT_HALTED;
1993 }
1994
1995 /* sanitize arguments */
1996 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1997 return ERROR_INVALID_ARGUMENTS;
1998
1999 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
2000 return ERROR_TARGET_UNALIGNED_ACCESS;
2001
2002 /* send memory write request (command 0x2n, n: access size) */
2003 if ((retval=xscale_send_u32(target, 0x20 | size))!=ERROR_OK)
2004 return retval;
2005
2006 /* send base address for read request */
2007 if ((retval=xscale_send_u32(target, address))!=ERROR_OK)
2008 return retval;
2009
2010 /* send number of requested data words to be written*/
2011 if ((retval=xscale_send_u32(target, count))!=ERROR_OK)
2012 return retval;
2013
2014 /* extract data from host-endian buffer into byte stream */
2015 #if 0
2016 for (i = 0; i < count; i++)
2017 {
2018 switch (size)
2019 {
2020 case 4:
2021 value = target_buffer_get_u32(target, buffer);
2022 xscale_send_u32(target, value);
2023 buffer += 4;
2024 break;
2025 case 2:
2026 value = target_buffer_get_u16(target, buffer);
2027 xscale_send_u32(target, value);
2028 buffer += 2;
2029 break;
2030 case 1:
2031 value = *buffer;
2032 xscale_send_u32(target, value);
2033 buffer += 1;
2034 break;
2035 default:
2036 LOG_ERROR("should never get here");
2037 exit(-1);
2038 }
2039 }
2040 #endif
2041 if ((retval=xscale_send(target, buffer, count, size))!=ERROR_OK)
2042 return retval;
2043
2044 /* examine DCSR, to see if Sticky Abort (SA) got set */
2045 if ((retval=xscale_read_dcsr(target))!=ERROR_OK)
2046 return retval;
2047 if (buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 5, 1) == 1)
2048 {
2049 /* clear SA bit */
2050 if ((retval=xscale_send_u32(target, 0x60))!=ERROR_OK)
2051 return retval;
2052
2053 return ERROR_TARGET_DATA_ABORT;
2054 }
2055
2056 return ERROR_OK;
2057 }
2058
2059 int xscale_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
2060 {
2061 return xscale_write_memory(target, address, 4, count, buffer);
2062 }
2063
2064 u32 xscale_get_ttb(target_t *target)
2065 {
2066 armv4_5_common_t *armv4_5 = target->arch_info;
2067 xscale_common_t *xscale = armv4_5->arch_info;
2068 u32 ttb;
2069
2070 xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_TTB]);
2071 ttb = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_TTB].value, 0, 32);
2072
2073 return ttb;
2074 }
2075
2076 void xscale_disable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
2077 {
2078 armv4_5_common_t *armv4_5 = target->arch_info;
2079 xscale_common_t *xscale = armv4_5->arch_info;
2080 u32 cp15_control;
2081
2082 /* read cp15 control register */
2083 xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);
2084 cp15_control = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32);
2085
2086 if (mmu)
2087 cp15_control &= ~0x1U;
2088
2089 if (d_u_cache)
2090 {
2091 /* clean DCache */
2092 xscale_send_u32(target, 0x50);
2093 xscale_send_u32(target, xscale->cache_clean_address);
2094
2095 /* invalidate DCache */
2096 xscale_send_u32(target, 0x51);
2097
2098 cp15_control &= ~0x4U;
2099 }
2100
2101 if (i_cache)
2102 {
2103 /* invalidate ICache */
2104 xscale_send_u32(target, 0x52);
2105 cp15_control &= ~0x1000U;
2106 }
2107
2108 /* write new cp15 control register */
2109 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_CTRL], cp15_control);
2110
2111 /* execute cpwait to ensure outstanding operations complete */
2112 xscale_send_u32(target, 0x53);
2113 }
2114
2115 void xscale_enable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
2116 {
2117 armv4_5_common_t *armv4_5 = target->arch_info;
2118 xscale_common_t *xscale = armv4_5->arch_info;
2119 u32 cp15_control;
2120
2121 /* read cp15 control register */
2122 xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);
2123 cp15_control = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32);
2124
2125 if (mmu)
2126 cp15_control |= 0x1U;
2127
2128 if (d_u_cache)
2129 cp15_control |= 0x4U;
2130
2131 if (i_cache)
2132 cp15_control |= 0x1000U;
2133
2134 /* write new cp15 control register */
2135 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_CTRL], cp15_control);
2136
2137 /* execute cpwait to ensure outstanding operations complete */
2138 xscale_send_u32(target, 0x53);
2139 }
2140
2141 int xscale_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
2142 {
2143 armv4_5_common_t *armv4_5 = target->arch_info;
2144 xscale_common_t *xscale = armv4_5->arch_info;
2145
2146 if (target->state != TARGET_HALTED)
2147 {
2148 LOG_WARNING("target not halted");
2149 return ERROR_TARGET_NOT_HALTED;
2150 }
2151
2152 if (xscale->force_hw_bkpts)
2153 breakpoint->type = BKPT_HARD;
2154
2155 if (breakpoint->set)
2156 {
2157 LOG_WARNING("breakpoint already set");
2158 return ERROR_OK;
2159 }
2160
2161 if (breakpoint->type == BKPT_HARD)
2162 {
2163 u32 value = breakpoint->address | 1;
2164 if (!xscale->ibcr0_used)
2165 {
2166 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR0], value);
2167 xscale->ibcr0_used = 1;
2168 breakpoint->set = 1; /* breakpoint set on first breakpoint register */
2169 }
2170 else if (!xscale->ibcr1_used)
2171 {
2172 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR1], value);
2173 xscale->ibcr1_used = 1;
2174 breakpoint->set = 2; /* breakpoint set on second breakpoint register */
2175 }
2176 else
2177 {
2178 LOG_ERROR("BUG: no hardware comparator available");
2179 return ERROR_OK;
2180 }
2181 }
2182 else if (breakpoint->type == BKPT_SOFT)
2183 {
2184 if (breakpoint->length == 4)
2185 {
2186 /* keep the original instruction in target endianness */
2187 target->type->read_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr);
2188 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2189 target_write_u32(target, breakpoint->address, xscale->arm_bkpt);
2190 }
2191 else
2192 {
2193 /* keep the original instruction in target endianness */
2194 target->type->read_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr);
2195 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2196 target_write_u32(target, breakpoint->address, xscale->thumb_bkpt);
2197 }
2198 breakpoint->set = 1;
2199 }
2200
2201 return ERROR_OK;
2202
2203 }
2204
2205 int xscale_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
2206 {
2207 armv4_5_common_t *armv4_5 = target->arch_info;
2208 xscale_common_t *xscale = armv4_5->arch_info;
2209
2210 if (target->state != TARGET_HALTED)
2211 {
2212 LOG_WARNING("target not halted");
2213 return ERROR_TARGET_NOT_HALTED;
2214 }
2215
2216 if (xscale->force_hw_bkpts)
2217 {
2218 LOG_DEBUG("forcing use of hardware breakpoint at address 0x%8.8x", breakpoint->address);
2219 breakpoint->type = BKPT_HARD;
2220 }
2221
2222 if ((breakpoint->type == BKPT_HARD) && (xscale->ibcr_available < 1))
2223 {
2224 LOG_INFO("no breakpoint unit available for hardware breakpoint");
2225 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2226 }
2227 else
2228 {
2229 xscale->ibcr_available--;
2230 }
2231
2232 if ((breakpoint->length != 2) && (breakpoint->length != 4))
2233 {
2234 LOG_INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
2235 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2236 }
2237
2238 return ERROR_OK;
2239 }
2240
2241 int xscale_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
2242 {
2243 armv4_5_common_t *armv4_5 = target->arch_info;
2244 xscale_common_t *xscale = armv4_5->arch_info;
2245
2246 if (target->state != TARGET_HALTED)
2247 {
2248 LOG_WARNING("target not halted");
2249 return ERROR_TARGET_NOT_HALTED;
2250 }
2251
2252 if (!breakpoint->set)
2253 {
2254 LOG_WARNING("breakpoint not set");
2255 return ERROR_OK;
2256 }
2257
2258 if (breakpoint->type == BKPT_HARD)
2259 {
2260 if (breakpoint->set == 1)
2261 {
2262 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR0], 0x0);
2263 xscale->ibcr0_used = 0;
2264 }
2265 else if (breakpoint->set == 2)
2266 {
2267 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR1], 0x0);
2268 xscale->ibcr1_used = 0;
2269 }
2270 breakpoint->set = 0;
2271 }
2272 else
2273 {
2274 /* restore original instruction (kept in target endianness) */
2275 if (breakpoint->length == 4)
2276 {
2277 target->type->write_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr);
2278 }
2279 else
2280 {
2281 target->type->write_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr);
2282 }
2283 breakpoint->set = 0;
2284 }
2285
2286 return ERROR_OK;
2287 }
2288
2289 int xscale_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
2290 {
2291 armv4_5_common_t *armv4_5 = target->arch_info;
2292 xscale_common_t *xscale = armv4_5->arch_info;
2293
2294 if (target->state != TARGET_HALTED)
2295 {
2296 LOG_WARNING("target not halted");
2297 return ERROR_TARGET_NOT_HALTED;
2298 }
2299
2300 if (breakpoint->set)
2301 {
2302 xscale_unset_breakpoint(target, breakpoint);
2303 }
2304
2305 if (breakpoint->type == BKPT_HARD)
2306 xscale->ibcr_available++;
2307
2308 return ERROR_OK;
2309 }
2310
2311 int xscale_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
2312 {
2313 armv4_5_common_t *armv4_5 = target->arch_info;
2314 xscale_common_t *xscale = armv4_5->arch_info;
2315 u8 enable=0;
2316 reg_t *dbcon = &xscale->reg_cache->reg_list[XSCALE_DBCON];
2317 u32 dbcon_value = buf_get_u32(dbcon->value, 0, 32);
2318
2319 if (target->state != TARGET_HALTED)
2320 {
2321 LOG_WARNING("target not halted");
2322 return ERROR_TARGET_NOT_HALTED;
2323 }
2324
2325 xscale_get_reg(dbcon);
2326
2327 switch (watchpoint->rw)
2328 {
2329 case WPT_READ:
2330 enable = 0x3;
2331 break;
2332 case WPT_ACCESS:
2333 enable = 0x2;
2334 break;
2335 case WPT_WRITE:
2336 enable = 0x1;
2337 break;
2338 default:
2339 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
2340 }
2341
2342 if (!xscale->dbr0_used)
2343 {
2344 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR0], watchpoint->address);
2345 dbcon_value |= enable;
2346 xscale_set_reg_u32(dbcon, dbcon_value);
2347 watchpoint->set = 1;
2348 xscale->dbr0_used = 1;
2349 }
2350 else if (!xscale->dbr1_used)
2351 {
2352 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR1], watchpoint->address);
2353 dbcon_value |= enable << 2;
2354 xscale_set_reg_u32(dbcon, dbcon_value);
2355 watchpoint->set = 2;
2356 xscale->dbr1_used = 1;
2357 }
2358 else
2359 {
2360 LOG_ERROR("BUG: no hardware comparator available");
2361 return ERROR_OK;
2362 }
2363
2364 return ERROR_OK;
2365 }
2366
2367 int xscale_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
2368 {
2369 armv4_5_common_t *armv4_5 = target->arch_info;
2370 xscale_common_t *xscale = armv4_5->arch_info;
2371
2372 if (target->state != TARGET_HALTED)
2373 {
2374 LOG_WARNING("target not halted");
2375 return ERROR_TARGET_NOT_HALTED;
2376 }
2377
2378 if (xscale->dbr_available < 1)
2379 {
2380 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2381 }
2382
2383 if ((watchpoint->length != 1) && (watchpoint->length != 2) && (watchpoint->length != 4))
2384 {
2385 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2386 }
2387
2388 xscale->dbr_available--;
2389
2390 return ERROR_OK;
2391 }
2392
2393 int xscale_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
2394 {
2395 armv4_5_common_t *armv4_5 = target->arch_info;
2396 xscale_common_t *xscale = armv4_5->arch_info;
2397 reg_t *dbcon = &xscale->reg_cache->reg_list[XSCALE_DBCON];
2398 u32 dbcon_value = buf_get_u32(dbcon->value, 0, 32);
2399
2400 if (target->state != TARGET_HALTED)
2401 {
2402 LOG_WARNING("target not halted");
2403 return ERROR_TARGET_NOT_HALTED;
2404 }
2405
2406 if (!watchpoint->set)
2407 {
2408 LOG_WARNING("breakpoint not set");
2409 return ERROR_OK;
2410 }
2411
2412 if (watchpoint->set == 1)
2413 {
2414 dbcon_value &= ~0x3;
2415 xscale_set_reg_u32(dbcon, dbcon_value);
2416 xscale->dbr0_used = 0;
2417 }
2418 else if (watchpoint->set == 2)
2419 {
2420 dbcon_value &= ~0xc;
2421 xscale_set_reg_u32(dbcon, dbcon_value);
2422 xscale->dbr1_used = 0;
2423 }
2424 watchpoint->set = 0;
2425
2426 return ERROR_OK;
2427 }
2428
2429 int xscale_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
2430 {
2431 armv4_5_common_t *armv4_5 = target->arch_info;
2432 xscale_common_t *xscale = armv4_5->arch_info;
2433
2434 if (target->state != TARGET_HALTED)
2435 {
2436 LOG_WARNING("target not halted");
2437 return ERROR_TARGET_NOT_HALTED;
2438 }
2439
2440 if (watchpoint->set)
2441 {
2442 xscale_unset_watchpoint(target, watchpoint);
2443 }
2444
2445 xscale->dbr_available++;
2446
2447 return ERROR_OK;
2448 }
2449
2450 void xscale_enable_watchpoints(struct target_s *target)
2451 {
2452 watchpoint_t *watchpoint = target->watchpoints;
2453
2454 while (watchpoint)
2455 {
2456 if (watchpoint->set == 0)
2457 xscale_set_watchpoint(target, watchpoint);
2458 watchpoint = watchpoint->next;
2459 }
2460 }
2461
2462 void xscale_enable_breakpoints(struct target_s *target)
2463 {
2464 breakpoint_t *breakpoint = target->breakpoints;
2465
2466 /* set any pending breakpoints */
2467 while (breakpoint)
2468 {
2469 if (breakpoint->set == 0)
2470 xscale_set_breakpoint(target, breakpoint);
2471 breakpoint = breakpoint->next;
2472 }
2473 }
2474
2475 int xscale_get_reg(reg_t *reg)
2476 {
2477 xscale_reg_t *arch_info = reg->arch_info;
2478 target_t *target = arch_info->target;
2479 armv4_5_common_t *armv4_5 = target->arch_info;
2480 xscale_common_t *xscale = armv4_5->arch_info;
2481
2482 /* DCSR, TX and RX are accessible via JTAG */
2483 if (strcmp(reg->name, "XSCALE_DCSR") == 0)
2484 {
2485 return xscale_read_dcsr(arch_info->target);
2486 }
2487 else if (strcmp(reg->name, "XSCALE_TX") == 0)
2488 {
2489 /* 1 = consume register content */
2490 return xscale_read_tx(arch_info->target, 1);
2491 }
2492 else if (strcmp(reg->name, "XSCALE_RX") == 0)
2493 {
2494 /* can't read from RX register (host -> debug handler) */
2495 return ERROR_OK;
2496 }
2497 else if (strcmp(reg->name, "XSCALE_TXRXCTRL") == 0)
2498 {
2499 /* can't (explicitly) read from TXRXCTRL register */
2500 return ERROR_OK;
2501 }
2502 else /* Other DBG registers have to be transfered by the debug handler */
2503 {
2504 /* send CP read request (command 0x40) */
2505 xscale_send_u32(target, 0x40);
2506
2507 /* send CP register number */
2508 xscale_send_u32(target, arch_info->dbg_handler_number);
2509
2510 /* read register value */
2511 xscale_read_tx(target, 1);
2512 buf_cpy(xscale->reg_cache->reg_list[XSCALE_TX].value, reg->value, 32);
2513
2514 reg->dirty = 0;
2515 reg->valid = 1;
2516 }
2517
2518 return ERROR_OK;
2519 }
2520
2521 int xscale_set_reg(reg_t *reg, u8* buf)
2522 {
2523 xscale_reg_t *arch_info = reg->arch_info;
2524 target_t *target = arch_info->target;
2525 armv4_5_common_t *armv4_5 = target->arch_info;
2526 xscale_common_t *xscale = armv4_5->arch_info;
2527 u32 value = buf_get_u32(buf, 0, 32);
2528
2529 /* DCSR, TX and RX are accessible via JTAG */
2530 if (strcmp(reg->name, "XSCALE_DCSR") == 0)
2531 {
2532 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 0, 32, value);
2533 return xscale_write_dcsr(arch_info->target, -1, -1);
2534 }
2535 else if (strcmp(reg->name, "XSCALE_RX") == 0)
2536 {
2537 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_RX].value, 0, 32, value);
2538 return xscale_write_rx(arch_info->target);
2539 }
2540 else if (strcmp(reg->name, "XSCALE_TX") == 0)
2541 {
2542 /* can't write to TX register (debug-handler -> host) */
2543 return ERROR_OK;
2544 }
2545 else if (strcmp(reg->name, "XSCALE_TXRXCTRL") == 0)
2546 {
2547 /* can't (explicitly) write to TXRXCTRL register */
2548 return ERROR_OK;
2549 }
2550 else /* Other DBG registers have to be transfered by the debug handler */
2551 {
2552 /* send CP write request (command 0x41) */
2553 xscale_send_u32(target, 0x41);
2554
2555 /* send CP register number */
2556 xscale_send_u32(target, arch_info->dbg_handler_number);
2557
2558 /* send CP register value */
2559 xscale_send_u32(target, value);
2560 buf_set_u32(reg->value, 0, 32, value);
2561 }
2562
2563 return ERROR_OK;
2564 }
2565
2566 /* convenience wrapper to access XScale specific registers */
2567 int xscale_set_reg_u32(reg_t *reg, u32 value)
2568 {
2569 u8 buf[4];
2570
2571 buf_set_u32(buf, 0, 32, value);
2572
2573 return xscale_set_reg(reg, buf);
2574 }
2575
2576 int xscale_write_dcsr_sw(target_t *target, u32 value)
2577 {
2578 /* get pointers to arch-specific information */
2579 armv4_5_common_t *armv4_5 = target->arch_info;
2580 xscale_common_t *xscale = armv4_5->arch_info;
2581 reg_t *dcsr = &xscale->reg_cache->reg_list[XSCALE_DCSR];
2582 xscale_reg_t *dcsr_arch_info = dcsr->arch_info;
2583
2584 /* send CP write request (command 0x41) */
2585 xscale_send_u32(target, 0x41);
2586
2587 /* send CP register number */
2588 xscale_send_u32(target, dcsr_arch_info->dbg_handler_number);
2589
2590 /* send CP register value */
2591 xscale_send_u32(target, value);
2592 buf_set_u32(dcsr->value, 0, 32, value);
2593
2594 return ERROR_OK;
2595 }
2596
2597 int xscale_read_trace(target_t *target)
2598 {
2599 /* get pointers to arch-specific information */
2600 armv4_5_common_t *armv4_5 = target->arch_info;
2601 xscale_common_t *xscale = armv4_5->arch_info;
2602 xscale_trace_data_t **trace_data_p;
2603
2604 /* 258 words from debug handler
2605 * 256 trace buffer entries
2606 * 2 checkpoint addresses
2607 */
2608 u32 trace_buffer[258];
2609 int is_address[256];
2610 int i, j;
2611
2612 if (target->state != TARGET_HALTED)
2613 {
2614 LOG_WARNING("target must be stopped to read trace data");
2615 return ERROR_TARGET_NOT_HALTED;
2616 }
2617
2618 /* send read trace buffer command (command 0x61) */
2619 xscale_send_u32(target, 0x61);
2620
2621 /* receive trace buffer content */
2622 xscale_receive(target, trace_buffer, 258);
2623
2624 /* parse buffer backwards to identify address entries */
2625 for (i = 255; i >= 0; i--)
2626 {
2627 is_address[i] = 0;
2628 if (((trace_buffer[i] & 0xf0) == 0x90) ||
2629 ((trace_buffer[i] & 0xf0) == 0xd0))
2630 {
2631 if (i >= 3)
2632 is_address[--i] = 1;
2633 if (i >= 2)
2634 is_address[--i] = 1;
2635 if (i >= 1)
2636 is_address[--i] = 1;
2637 if (i >= 0)
2638 is_address[--i] = 1;
2639 }
2640 }
2641
2642
2643 /* search first non-zero entry */
2644 for (j = 0; (j < 256) && (trace_buffer[j] == 0) && (!is_address[j]); j++)
2645 ;
2646
2647 if (j == 256)
2648 {
2649 LOG_DEBUG("no trace data collected");
2650 return ERROR_XSCALE_NO_TRACE_DATA;
2651 }
2652
2653 for (trace_data_p = &xscale->trace.data; *trace_data_p; trace_data_p = &(*trace_data_p)->next)
2654 ;
2655
2656 *trace_data_p = malloc(sizeof(xscale_trace_data_t));
2657 (*trace_data_p)->next = NULL;
2658 (*trace_data_p)->chkpt0 = trace_buffer[256];
2659 (*trace_data_p)->chkpt1 = trace_buffer[257];
2660 (*trace_data_p)->last_instruction = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
2661 (*trace_data_p)->entries = malloc(sizeof(xscale_trace_entry_t) * (256 - j));
2662 (*trace_data_p)->depth = 256 - j;
2663
2664 for (i = j; i < 256; i++)
2665 {
2666 (*trace_data_p)->entries[i - j].data = trace_buffer[i];
2667 if (is_address[i])
2668 (*trace_data_p)->entries[i - j].type = XSCALE_TRACE_ADDRESS;
2669 else
2670 (*trace_data_p)->entries[i - j].type = XSCALE_TRACE_MESSAGE;
2671 }
2672
2673 return ERROR_OK;
2674 }
2675
2676 int xscale_read_instruction(target_t *target, arm_instruction_t *instruction)
2677 {
2678 /* get pointers to arch-specific information */
2679 armv4_5_common_t *armv4_5 = target->arch_info;
2680 xscale_common_t *xscale = armv4_5->arch_info;
2681 int i;
2682 int section = -1;
2683 u32 size_read;
2684 u32 opcode;
2685 int retval;
2686
2687 if (!xscale->trace.image)
2688 return ERROR_TRACE_IMAGE_UNAVAILABLE;
2689
2690 /* search for the section the current instruction belongs to */
2691 for (i = 0; i < xscale->trace.image->num_sections; i++)
2692 {
2693 if ((xscale->trace.image->sections[i].base_address <= xscale->trace.current_pc) &&
2694 (xscale->trace.image->sections[i].base_address + xscale->trace.image->sections[i].size > xscale->trace.current_pc))
2695 {
2696 section = i;
2697 break;
2698 }
2699 }
2700
2701 if (section == -1)
2702 {
2703 /* current instruction couldn't be found in the image */
2704 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
2705 }
2706
2707 if (xscale->trace.core_state == ARMV4_5_STATE_ARM)
2708 {
2709 u8 buf[4];
2710 if ((retval = image_read_section(xscale->trace.image, section,
2711 xscale->trace.current_pc - xscale->trace.image->sections[section].base_address,
2712 4, buf, &size_read)) != ERROR_OK)
2713 {
2714 LOG_ERROR("error while reading instruction: %i", retval);
2715 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
2716 }
2717 opcode = target_buffer_get_u32(target, buf);
2718 arm_evaluate_opcode(opcode, xscale->trace.current_pc, instruction);
2719 }
2720 else if (xscale->trace.core_state == ARMV4_5_STATE_THUMB)
2721 {
2722 u8 buf[2];
2723 if ((retval = image_read_section(xscale->trace.image, section,
2724 xscale->trace.current_pc - xscale->trace.image->sections[section].base_address,
2725 2, buf, &size_read)) != ERROR_OK)
2726 {
2727 LOG_ERROR("error while reading instruction: %i", retval);
2728 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
2729 }
2730 opcode = target_buffer_get_u16(target, buf);
2731 thumb_evaluate_opcode(opcode, xscale->trace.current_pc, instruction);
2732 }
2733 else
2734 {
2735 LOG_ERROR("BUG: unknown core state encountered");
2736 exit(-1);
2737 }
2738
2739 return ERROR_OK;
2740 }
2741
2742 int xscale_branch_address(xscale_trace_data_t *trace_data, int i, u32 *target)
2743 {
2744 /* if there are less than four entries prior to the indirect branch message
2745 * we can't extract the address */
2746 if (i < 4)
2747 {
2748 return -1;
2749 }
2750
2751 *target = (trace_data->entries[i-1].data) | (trace_data->entries[i-2].data << 8) |
2752 (trace_data->entries[i-3].data << 16) | (trace_data->entries[i-4].data << 24);
2753
2754 return 0;
2755 }
2756
2757 int xscale_analyze_trace(target_t *target, command_context_t *cmd_ctx)
2758 {
2759 /* get pointers to arch-specific information */
2760 armv4_5_common_t *armv4_5 = target->arch_info;
2761 xscale_common_t *xscale = armv4_5->arch_info;
2762 int next_pc_ok = 0;
2763 u32 next_pc = 0x0;
2764 xscale_trace_data_t *trace_data = xscale->trace.data;
2765 int retval;
2766
2767 while (trace_data)
2768 {
2769 int i, chkpt;
2770 int rollover;
2771 int branch;
2772 int exception;
2773 xscale->trace.core_state = ARMV4_5_STATE_ARM;
2774
2775 chkpt = 0;
2776 rollover = 0;
2777
2778 for (i = 0; i < trace_data->depth; i++)
2779 {
2780 next_pc_ok = 0;
2781 branch = 0;
2782 exception = 0;
2783
2784 if (trace_data->entries[i].type == XSCALE_TRACE_ADDRESS)
2785 continue;
2786
2787 switch ((trace_data->entries[i].data & 0xf0) >> 4)
2788 {
2789 case 0: /* Exceptions */
2790 case 1:
2791 case 2:
2792 case 3:
2793 case 4:
2794 case 5:
2795 case 6:
2796 case 7:
2797 exception = (trace_data->entries[i].data & 0x70) >> 4;
2798 next_pc_ok = 1;
2799 next_pc = (trace_data->entries[i].data & 0xf0) >> 2;
2800 command_print(cmd_ctx, "--- exception %i ---", (trace_data->entries[i].data & 0xf0) >> 4);
2801 break;
2802 case 8: /* Direct Branch */
2803 branch = 1;
2804 break;
2805 case 9: /* Indirect Branch */
2806 branch = 1;
2807 if (xscale_branch_address(trace_data, i, &next_pc) == 0)
2808 {
2809 next_pc_ok = 1;
2810 }
2811 break;
2812 case 13: /* Checkpointed Indirect Branch */
2813 if (xscale_branch_address(trace_data, i, &next_pc) == 0)
2814 {
2815 next_pc_ok = 1;
2816 if (((chkpt == 0) && (next_pc != trace_data->chkpt0))
2817 || ((chkpt == 1) && (next_pc != trace_data->chkpt1)))
2818 LOG_WARNING("checkpointed indirect branch target address doesn't match checkpoint");
2819 }
2820 /* explicit fall-through */
2821 case 12: /* Checkpointed Direct Branch */
2822 branch = 1;
2823 if (chkpt == 0)
2824 {
2825 next_pc_ok = 1;
2826 next_pc = trace_data->chkpt0;
2827 chkpt++;
2828 }
2829 else if (chkpt == 1)
2830 {
2831 next_pc_ok = 1;
2832 next_pc = trace_data->chkpt0;
2833 chkpt++;
2834 }
2835 else
2836 {
2837 LOG_WARNING("more than two checkpointed branches encountered");
2838 }
2839 break;
2840 case 15: /* Roll-over */
2841 rollover++;
2842 continue;
2843 default: /* Reserved */
2844 command_print(cmd_ctx, "--- reserved trace message ---");
2845 LOG_ERROR("BUG: trace message %i is reserved", (trace_data->entries[i].data & 0xf0) >> 4);
2846 return ERROR_OK;
2847 }
2848
2849 if (xscale->trace.pc_ok)
2850 {
2851 int executed = (trace_data->entries[i].data & 0xf) + rollover * 16;
2852 arm_instruction_t instruction;
2853
2854 if ((exception == 6) || (exception == 7))
2855 {
2856 /* IRQ or FIQ exception, no instruction executed */
2857 executed -= 1;
2858 }
2859
2860 while (executed-- >= 0)
2861 {
2862 if ((retval = xscale_read_instruction(target, &instruction)) != ERROR_OK)
2863 {
2864 /* can't continue tracing with no image available */
2865 if (retval == ERROR_TRACE_IMAGE_UNAVAILABLE)
2866 {
2867 return retval;
2868 }
2869 else if (retval == ERROR_TRACE_INSTRUCTION_UNAVAILABLE)
2870 {
2871 /* TODO: handle incomplete images */
2872 }
2873 }
2874
2875 /* a precise abort on a load to the PC is included in the incremental
2876 * word count, other instructions causing data aborts are not included
2877 */
2878 if ((executed == 0) && (exception == 4)
2879 && ((instruction.type >= ARM_LDR) && (instruction.type <= ARM_LDM)))
2880 {
2881 if ((instruction.type == ARM_LDM)
2882 && ((instruction.info.load_store_multiple.register_list & 0x8000) == 0))
2883 {
2884 executed--;
2885 }
2886 else if (((instruction.type >= ARM_LDR) && (instruction.type <= ARM_LDRSH))
2887 && (instruction.info.load_store.Rd != 15))
2888 {
2889 executed--;
2890 }
2891 }
2892
2893 /* only the last instruction executed
2894 * (the one that caused the control flow change)
2895 * could be a taken branch
2896 */
2897 if (((executed == -1) && (branch == 1)) &&
2898 (((instruction.type == ARM_B) ||
2899 (instruction.type == ARM_BL) ||
2900 (instruction.type == ARM_BLX)) &&
2901 (instruction.info.b_bl_bx_blx.target_address != -1)))
2902 {
2903 xscale->trace.current_pc = instruction.info.b_bl_bx_blx.target_address;
2904 }
2905 else
2906 {
2907 xscale->trace.current_pc += (xscale->trace.core_state == ARMV4_5_STATE_ARM) ? 4 : 2;
2908 }
2909 command_print(cmd_ctx, "%s", instruction.text);
2910 }
2911
2912 rollover = 0;
2913 }
2914
2915 if (next_pc_ok)
2916 {
2917 xscale->trace.current_pc = next_pc;
2918 xscale->trace.pc_ok = 1;
2919 }
2920 }
2921
2922 for (; xscale->trace.current_pc < trace_data->last_instruction; xscale->trace.current_pc += (xscale->trace.core_state == ARMV4_5_STATE_ARM) ? 4 : 2)
2923 {
2924 arm_instruction_t instruction;
2925 if ((retval = xscale_read_instruction(target, &instruction)) != ERROR_OK)
2926 {
2927 /* can't continue tracing with no image available */
2928 if (retval == ERROR_TRACE_IMAGE_UNAVAILABLE)
2929 {
2930 return retval;
2931 }
2932 else if (retval == ERROR_TRACE_INSTRUCTION_UNAVAILABLE)
2933 {
2934 /* TODO: handle incomplete images */
2935 }
2936 }
2937 command_print(cmd_ctx, "%s", instruction.text);
2938 }
2939
2940 trace_data = trace_data->next;
2941 }
2942
2943 return ERROR_OK;
2944 }
2945
2946 void xscale_build_reg_cache(target_t *target)
2947 {
2948 /* get pointers to arch-specific information */
2949 armv4_5_common_t *armv4_5 = target->arch_info;
2950 xscale_common_t *xscale = armv4_5->arch_info;
2951
2952 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
2953 xscale_reg_t *arch_info = malloc(sizeof(xscale_reg_arch_info));
2954 int i;
2955 int num_regs = sizeof(xscale_reg_arch_info) / sizeof(xscale_reg_t);
2956
2957 (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
2958 armv4_5->core_cache = (*cache_p);
2959
2960 /* register a register arch-type for XScale dbg registers only once */
2961 if (xscale_reg_arch_type == -1)
2962 xscale_reg_arch_type = register_reg_arch_type(xscale_get_reg, xscale_set_reg);
2963
2964 (*cache_p)->next = malloc(sizeof(reg_cache_t));
2965 cache_p = &(*cache_p)->next;
2966
2967 /* fill in values for the xscale reg cache */
2968 (*cache_p)->name = "XScale registers";
2969 (*cache_p)->next = NULL;
2970 (*cache_p)->reg_list = malloc(num_regs * sizeof(reg_t));
2971 (*cache_p)->num_regs = num_regs;
2972
2973 for (i = 0; i < num_regs; i++)
2974 {
2975 (*cache_p)->reg_list[i].name = xscale_reg_list[i];
2976 (*cache_p)->reg_list[i].value = calloc(4, 1);
2977 (*cache_p)->reg_list[i].dirty = 0;
2978 (*cache_p)->reg_list[i].valid = 0;
2979 (*cache_p)->reg_list[i].size = 32;
2980 (*cache_p)->reg_list[i].bitfield_desc = NULL;
2981 (*cache_p)->reg_list[i].num_bitfields = 0;
2982 (*cache_p)->reg_list[i].arch_info = &arch_info[i];
2983 (*cache_p)->reg_list[i].arch_type = xscale_reg_arch_type;
2984 arch_info[i] = xscale_reg_arch_info[i];
2985 arch_info[i].target = target;
2986 }
2987
2988 xscale->reg_cache = (*cache_p);
2989 }
2990
2991 int xscale_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
2992 {
2993 return ERROR_OK;
2994 }
2995
2996 int xscale_quit(void)
2997 {
2998
2999 return ERROR_OK;
3000 }
3001
3002 int xscale_init_arch_info(target_t *target, xscale_common_t *xscale, int chain_pos, char *variant)
3003 {
3004 armv4_5_common_t *armv4_5;
3005 u32 high_reset_branch, low_reset_branch;
3006 int i;
3007
3008 armv4_5 = &xscale->armv4_5_common;
3009
3010 /* store architecture specfic data (none so far) */
3011 xscale->arch_info = NULL;
3012 xscale->common_magic = XSCALE_COMMON_MAGIC;
3013
3014 /* remember the variant (PXA25x, PXA27x, IXP42x, ...) */
3015 xscale->variant = strdup(variant);
3016
3017 /* prepare JTAG information for the new target */
3018 xscale->jtag_info.chain_pos = chain_pos;
3019
3020 xscale->jtag_info.dbgrx = 0x02;
3021 xscale->jtag_info.dbgtx = 0x10;
3022 xscale->jtag_info.dcsr = 0x09;
3023 xscale->jtag_info.ldic = 0x07;
3024
3025 if ((strcmp(xscale->variant, "pxa250") == 0) ||
3026 (strcmp(xscale->variant, "pxa255") == 0) ||
3027 (strcmp(xscale->variant, "pxa26x") == 0))
3028 {
3029 xscale->jtag_info.ir_length = 5;
3030 }
3031 else if ((strcmp(xscale->variant, "pxa27x") == 0) ||
3032 (strcmp(xscale->variant, "ixp42x") == 0) ||
3033 (strcmp(xscale->variant, "ixp45x") == 0) ||
3034 (strcmp(xscale->variant, "ixp46x") == 0))
3035 {
3036 xscale->jtag_info.ir_length = 7;
3037 }
3038
3039 /* the debug handler isn't installed (and thus not running) at this time */
3040 xscale->handler_installed = 0;
3041 xscale->handler_running = 0;
3042 xscale->handler_address = 0xfe000800;
3043
3044 /* clear the vectors we keep locally for reference */
3045 memset(xscale->low_vectors, 0, sizeof(xscale->low_vectors));
3046 memset(xscale->high_vectors, 0, sizeof(xscale->high_vectors));
3047
3048 /* no user-specified vectors have been configured yet */
3049 xscale->static_low_vectors_set = 0x0;
3050 xscale->static_high_vectors_set = 0x0;
3051
3052 /* calculate branches to debug handler */
3053 low_reset_branch = (xscale->handler_address + 0x20 - 0x0 - 0x8) >> 2;
3054 high_reset_branch = (xscale->handler_address + 0x20 - 0xffff0000 - 0x8) >> 2;
3055
3056 xscale->low_vectors[0] = ARMV4_5_B((low_reset_branch & 0xffffff), 0);
3057 xscale->high_vectors[0] = ARMV4_5_B((high_reset_branch & 0xffffff), 0);
3058
3059 for (i = 1; i <= 7; i++)
3060 {
3061 xscale->low_vectors[i] = ARMV4_5_B(0xfffffe, 0);
3062 xscale->high_vectors[i] = ARMV4_5_B(0xfffffe, 0);
3063 }
3064
3065 /* 64kB aligned region used for DCache cleaning */
3066 xscale->cache_clean_address = 0xfffe0000;
3067
3068 xscale->hold_rst = 0;
3069 xscale->external_debug_break = 0;
3070
3071 xscale->force_hw_bkpts = 1;
3072
3073 xscale->ibcr_available = 2;
3074 xscale->ibcr0_used = 0;
3075 xscale->ibcr1_used = 0;
3076
3077 xscale->dbr_available = 2;
3078 xscale->dbr0_used = 0;
3079 xscale->dbr1_used = 0;
3080
3081 xscale->arm_bkpt = ARMV5_BKPT(0x0);
3082 xscale->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
3083
3084 xscale->vector_catch = 0x1;
3085
3086 xscale->trace.capture_status = TRACE_IDLE;
3087 xscale->trace.data = NULL;
3088 xscale->trace.image = NULL;
3089 xscale->trace.buffer_enabled = 0;
3090 xscale->trace.buffer_fill = 0;
3091
3092 /* prepare ARMv4/5 specific information */
3093 armv4_5->arch_info = xscale;
3094 armv4_5->read_core_reg = xscale_read_core_reg;
3095 armv4_5->write_core_reg = xscale_write_core_reg;
3096 armv4_5->full_context = xscale_full_context;
3097
3098 armv4_5_init_arch_info(target, armv4_5);
3099
3100 xscale->armv4_5_mmu.armv4_5_cache.ctype = -1;
3101 xscale->armv4_5_mmu.get_ttb = xscale_get_ttb;
3102 xscale->armv4_5_mmu.read_memory = xscale_read_memory;
3103 xscale->armv4_5_mmu.write_memory = xscale_write_memory;
3104 xscale->armv4_5_mmu.disable_mmu_caches = xscale_disable_mmu_caches;
3105 xscale->armv4_5_mmu.enable_mmu_caches = xscale_enable_mmu_caches;
3106 xscale->armv4_5_mmu.has_tiny_pages = 1;
3107 xscale->armv4_5_mmu.mmu_enabled = 0;
3108
3109 return ERROR_OK;
3110 }
3111
3112 /* target xscale <endianess> <startup_mode> <chain_pos> <variant> */
3113 int xscale_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
3114 {
3115 int chain_pos;
3116 char *variant = NULL;
3117 xscale_common_t *xscale = malloc(sizeof(xscale_common_t));
3118 memset(xscale, 0, sizeof(*xscale));
3119
3120 if (argc < 5)
3121 {
3122 LOG_ERROR("'target xscale' requires four arguments: <endianess> <startup_mode> <chain_pos> <variant>");
3123 return ERROR_OK;
3124 }
3125
3126 chain_pos = strtoul(args[3], NULL, 0);
3127
3128 variant = args[4];
3129
3130 xscale_init_arch_info(target, xscale, chain_pos, variant);
3131 xscale_build_reg_cache(target);
3132
3133 return ERROR_OK;
3134 }
3135
3136 int xscale_handle_debug_handler_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3137 {
3138 target_t *target = NULL;
3139 armv4_5_common_t *armv4_5;
3140 xscale_common_t *xscale;
3141
3142 u32 handler_address;
3143
3144 if (argc < 2)
3145 {
3146 LOG_ERROR("'xscale debug_handler <target#> <address>' command takes two required operands");
3147 return ERROR_OK;
3148 }
3149
3150 if ((target = get_target_by_num(strtoul(args[0], NULL, 0))) == NULL)
3151 {
3152 LOG_ERROR("no target '%s' configured", args[0]);
3153 return ERROR_OK;
3154 }
3155
3156 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3157 {
3158 return ERROR_OK;
3159 }
3160
3161 handler_address = strtoul(args[1], NULL, 0);
3162
3163 if (((handler_address >= 0x800) && (handler_address <= 0x1fef800)) ||
3164 ((handler_address >= 0xfe000800) && (handler_address <= 0xfffff800)))
3165 {
3166 xscale->handler_address = handler_address;
3167 }
3168 else
3169 {
3170 LOG_ERROR("xscale debug_handler <address> must be between 0x800 and 0x1fef800 or between 0xfe000800 and 0xfffff800");
3171 }
3172
3173 return ERROR_OK;
3174 }
3175
3176 int xscale_handle_cache_clean_address_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3177 {
3178 target_t *target = NULL;
3179 armv4_5_common_t *armv4_5;
3180 xscale_common_t *xscale;
3181
3182 u32 cache_clean_address;
3183
3184 if (argc < 2)
3185 {
3186 LOG_ERROR("'xscale cache_clean_address <target#> <address>' command takes two required operands");
3187 return ERROR_OK;
3188 }
3189
3190 if ((target = get_target_by_num(strtoul(args[0], NULL, 0))) == NULL)
3191 {
3192 LOG_ERROR("no target '%s' configured", args[0]);
3193 return ERROR_OK;
3194 }
3195
3196 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3197 {
3198 return ERROR_OK;
3199 }
3200
3201 cache_clean_address = strtoul(args[1], NULL, 0);
3202
3203 if (cache_clean_address & 0xffff)
3204 {
3205 LOG_ERROR("xscale cache_clean_address <address> must be 64kb aligned");
3206 }
3207 else
3208 {
3209 xscale->cache_clean_address = cache_clean_address;
3210 }
3211
3212 return ERROR_OK;
3213 }
3214
3215 int xscale_handle_cache_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3216 {
3217 target_t *target = get_current_target(cmd_ctx);
3218 armv4_5_common_t *armv4_5;
3219 xscale_common_t *xscale;
3220
3221 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3222 {
3223 return ERROR_OK;
3224 }
3225
3226 return armv4_5_handle_cache_info_command(cmd_ctx, &xscale->armv4_5_mmu.armv4_5_cache);
3227 }
3228
3229 static int xscale_virt2phys(struct target_s *target, u32 virtual, u32 *physical)
3230 {
3231 armv4_5_common_t *armv4_5;
3232 xscale_common_t *xscale;
3233 int retval;
3234 int type;
3235 u32 cb;
3236 int domain;
3237 u32 ap;
3238
3239
3240 if ((retval = xscale_get_arch_pointers(target, &armv4_5, &xscale)) != ERROR_OK)
3241 {
3242 return retval;
3243 }
3244 u32 ret = armv4_5_mmu_translate_va(target, &xscale->armv4_5_mmu, virtual, &type, &cb, &domain, &ap);
3245 if (type == -1)
3246 {
3247 return ret;
3248 }
3249 *physical = ret;
3250 return ERROR_OK;
3251 }
3252
3253 static int xscale_mmu(struct target_s *target, int *enabled)
3254 {
3255 armv4_5_common_t *armv4_5 = target->arch_info;
3256 xscale_common_t *xscale = armv4_5->arch_info;
3257
3258 if (target->state != TARGET_HALTED)
3259 {
3260 LOG_ERROR("Target not halted");
3261 return ERROR_TARGET_INVALID;
3262 }
3263 *enabled = xscale->armv4_5_mmu.mmu_enabled;
3264 return ERROR_OK;
3265 }
3266
3267
3268 int xscale_handle_mmu_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
3269 {
3270 target_t *target = get_current_target(cmd_ctx);
3271 armv4_5_common_t *armv4_5;
3272 xscale_common_t *xscale;
3273
3274 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3275 {
3276 return ERROR_OK;
3277 }
3278
3279 if (target->state != TARGET_HALTED)
3280 {
3281 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3282 return ERROR_OK;
3283 }
3284
3285 if (argc >= 1)
3286 {
3287 if (strcmp("enable", args[0]) == 0)
3288 {
3289 xscale_enable_mmu_caches(target, 1, 0, 0);
3290 xscale->armv4_5_mmu.mmu_enabled = 1;
3291 }
3292 else if (strcmp("disable", args[0]) == 0)
3293 {
3294 xscale_disable_mmu_caches(target, 1, 0, 0);
3295 xscale->armv4_5_mmu.mmu_enabled = 0;
3296 }
3297 }
3298
3299 command_print(cmd_ctx, "mmu %s", (xscale->armv4_5_mmu.mmu_enabled) ? "enabled" : "disabled");
3300
3301 return ERROR_OK;
3302 }
3303
3304 int xscale_handle_idcache_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
3305 {
3306 target_t *target = get_current_target(cmd_ctx);
3307 armv4_5_common_t *armv4_5;
3308 xscale_common_t *xscale;
3309 int icache = 0, dcache = 0;
3310
3311 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3312 {
3313 return ERROR_OK;
3314 }
3315
3316 if (target->state != TARGET_HALTED)
3317 {
3318 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3319 return ERROR_OK;
3320 }
3321
3322 if (strcmp(cmd, "icache") == 0)
3323 icache = 1;
3324 else if (strcmp(cmd, "dcache") == 0)
3325 dcache = 1;
3326
3327 if (argc >= 1)
3328 {
3329 if (strcmp("enable", args[0]) == 0)
3330 {
3331 xscale_enable_mmu_caches(target, 0, dcache, icache);
3332
3333 if (icache)
3334 xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 1;
3335 else if (dcache)
3336 xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 1;
3337 }
3338 else if (strcmp("disable", args[0]) == 0)
3339 {
3340 xscale_disable_mmu_caches(target, 0, dcache, icache);
3341
3342 if (icache)
3343 xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
3344 else if (dcache)
3345 xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
3346 }
3347 }
3348
3349 if (icache)
3350 command_print(cmd_ctx, "icache %s", (xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled) ? "enabled" : "disabled");
3351
3352 if (dcache)
3353 command_print(cmd_ctx, "dcache %s", (xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) ? "enabled" : "disabled");
3354
3355 return ERROR_OK;
3356 }
3357
3358 int xscale_handle_vector_catch_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
3359 {
3360 target_t *target = get_current_target(cmd_ctx);
3361 armv4_5_common_t *armv4_5;
3362 xscale_common_t *xscale;
3363
3364 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3365 {
3366 return ERROR_OK;
3367 }
3368
3369 if (argc < 1)
3370 {
3371 command_print(cmd_ctx, "usage: xscale vector_catch [mask]");
3372 }
3373 else
3374 {
3375 xscale->vector_catch = strtoul(args[0], NULL, 0);
3376 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 8, xscale->vector_catch);
3377 xscale_write_dcsr(target, -1, -1);
3378 }
3379
3380 command_print(cmd_ctx, "vector catch mask: 0x%2.2x", xscale->vector_catch);
3381
3382 return ERROR_OK;
3383 }
3384
3385 int xscale_handle_force_hw_bkpts_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3386 {
3387 target_t *target = get_current_target(cmd_ctx);
3388 armv4_5_common_t *armv4_5;
3389 xscale_common_t *xscale;
3390
3391 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3392 {
3393 return ERROR_OK;
3394 }
3395
3396 if ((argc >= 1) && (strcmp("enable", args[0]) == 0))
3397 {
3398 xscale->force_hw_bkpts = 1;
3399 }
3400 else if ((argc >= 1) && (strcmp("disable", args[0]) == 0))
3401 {
3402 xscale->force_hw_bkpts = 0;
3403 }
3404 else
3405 {
3406 command_print(cmd_ctx, "usage: xscale force_hw_bkpts <enable|disable>");
3407 }
3408
3409 command_print(cmd_ctx, "force hardware breakpoints %s", (xscale->force_hw_bkpts) ? "enabled" : "disabled");
3410
3411 return ERROR_OK;
3412 }
3413
3414 int xscale_handle_trace_buffer_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3415 {
3416 target_t *target = get_current_target(cmd_ctx);
3417 armv4_5_common_t *armv4_5;
3418 xscale_common_t *xscale;
3419 u32 dcsr_value;
3420
3421 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3422 {
3423 return ERROR_OK;
3424 }
3425
3426 if (target->state != TARGET_HALTED)
3427 {
3428 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3429 return ERROR_OK;
3430 }
3431
3432 if ((argc >= 1) && (strcmp("enable", args[0]) == 0))
3433 {
3434 xscale_trace_data_t *td, *next_td;
3435 xscale->trace.buffer_enabled = 1;
3436
3437 /* free old trace data */
3438 td = xscale->trace.data;
3439 while (td)
3440 {
3441 next_td = td->next;
3442
3443 if (td->entries)
3444 free(td->entries);
3445 free(td);
3446 td = next_td;
3447 }
3448 xscale->trace.data = NULL;
3449 }
3450 else if ((argc >= 1) && (strcmp("disable", args[0]) == 0))
3451 {
3452 xscale->trace.buffer_enabled = 0;
3453 }
3454
3455 if ((argc >= 2) && (strcmp("fill", args[1]) == 0))
3456 {
3457 if (argc >= 3)
3458 xscale->trace.buffer_fill = strtoul(args[2], NULL, 0);
3459 else
3460 xscale->trace.buffer_fill = 1;
3461 }
3462 else if ((argc >= 2) && (strcmp("wrap", args[1]) == 0))
3463 {
3464 xscale->trace.buffer_fill = -1;
3465 }
3466
3467 if (xscale->trace.buffer_enabled)
3468 {
3469 /* if we enable the trace buffer in fill-once
3470 * mode we know the address of the first instruction */
3471 xscale->trace.pc_ok = 1;
3472 xscale->trace.current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
3473 }
3474 else
3475 {
3476 /* otherwise the address is unknown, and we have no known good PC */
3477 xscale->trace.pc_ok = 0;
3478 }
3479
3480 command_print(cmd_ctx, "trace buffer %s (%s)",
3481 (xscale->trace.buffer_enabled) ? "enabled" : "disabled",
3482 (xscale->trace.buffer_fill > 0) ? "fill" : "wrap");
3483
3484 dcsr_value = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 0, 32);
3485 if (xscale->trace.buffer_fill >= 0)
3486 xscale_write_dcsr_sw(target, (dcsr_value & 0xfffffffc) | 2);
3487 else
3488 xscale_write_dcsr_sw(target, dcsr_value & 0xfffffffc);
3489
3490 return ERROR_OK;
3491 }
3492
3493 int xscale_handle_trace_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3494 {
3495 target_t *target;
3496 armv4_5_common_t *armv4_5;
3497 xscale_common_t *xscale;
3498
3499 if (argc < 1)
3500 {
3501 command_print(cmd_ctx, "usage: xscale trace_image <file> [base address] [type]");
3502 return ERROR_OK;
3503 }
3504
3505 target = get_current_target(cmd_ctx);
3506
3507 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3508 {
3509 return ERROR_OK;
3510 }
3511
3512 if (xscale->trace.image)
3513 {
3514 image_close(xscale->trace.image);
3515 free(xscale->trace.image);
3516 command_print(cmd_ctx, "previously loaded image found and closed");
3517 }
3518
3519 xscale->trace.image = malloc(sizeof(image_t));
3520 xscale->trace.image->base_address_set = 0;
3521 xscale->trace.image->start_address_set = 0;
3522
3523 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
3524 if (argc >= 2)
3525 {
3526 xscale->trace.image->base_address_set = 1;
3527 xscale->trace.image->base_address = strtoul(args[1], NULL, 0);
3528 }
3529 else
3530 {
3531 xscale->trace.image->base_address_set = 0;
3532 }
3533
3534 if (image_open(xscale->trace.image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
3535 {
3536 free(xscale->trace.image);
3537 xscale->trace.image = NULL;
3538 return ERROR_OK;
3539 }
3540
3541 return ERROR_OK;
3542 }
3543
3544 int xscale_handle_dump_trace_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3545 {
3546 target_t *target = get_current_target(cmd_ctx);
3547 armv4_5_common_t *armv4_5;
3548 xscale_common_t *xscale;
3549 xscale_trace_data_t *trace_data;
3550 fileio_t file;
3551
3552 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3553 {
3554 return ERROR_OK;
3555 }
3556
3557 if (target->state != TARGET_HALTED)
3558 {
3559 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3560 return ERROR_OK;
3561 }
3562
3563 if (argc < 1)
3564 {
3565 command_print(cmd_ctx, "usage: xscale dump_trace <file>");
3566 return ERROR_OK;
3567 }
3568
3569 trace_data = xscale->trace.data;
3570
3571 if (!trace_data)
3572 {
3573 command_print(cmd_ctx, "no trace data collected");
3574 return ERROR_OK;
3575 }
3576
3577 if (fileio_open(&file, args[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)
3578 {
3579 return ERROR_OK;
3580 }
3581
3582 while (trace_data)
3583 {
3584 int i;
3585
3586 fileio_write_u32(&file, trace_data->chkpt0);
3587 fileio_write_u32(&file, trace_data->chkpt1);
3588 fileio_write_u32(&file, trace_data->last_instruction);
3589 fileio_write_u32(&file, trace_data->depth);
3590
3591 for (i = 0; i < trace_data->depth; i++)
3592 fileio_write_u32(&file, trace_data->entries[i].data | ((trace_data->entries[i].type & 0xffff) << 16));
3593
3594 trace_data = trace_data->next;
3595 }
3596
3597 fileio_close(&file);
3598
3599 return ERROR_OK;
3600 }
3601
3602 int xscale_handle_analyze_trace_buffer_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3603 {
3604 target_t *target = get_current_target(cmd_ctx);
3605 armv4_5_common_t *armv4_5;
3606 xscale_common_t *xscale;
3607
3608 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3609 {
3610 return ERROR_OK;
3611 }
3612
3613 xscale_analyze_trace(target, cmd_ctx);
3614
3615 return ERROR_OK;
3616 }
3617
3618 int xscale_handle_cp15(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
3619 {
3620 target_t *target = get_current_target(cmd_ctx);
3621 armv4_5_common_t *armv4_5;
3622 xscale_common_t *xscale;
3623
3624 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3625 {
3626 return ERROR_OK;
3627 }
3628
3629 if (target->state != TARGET_HALTED)
3630 {
3631 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3632 return ERROR_OK;
3633 }
3634 u32 reg_no = 0;
3635 reg_t *reg = NULL;
3636 if(argc > 0)
3637 {
3638 reg_no = strtoul(args[0], NULL, 0);
3639 /*translate from xscale cp15 register no to openocd register*/
3640 switch(reg_no)
3641 {
3642 case 0:
3643 reg_no = XSCALE_MAINID;
3644 break;
3645 case 1:
3646 reg_no = XSCALE_CTRL;
3647 break;
3648 case 2:
3649 reg_no = XSCALE_TTB;
3650 break;
3651 case 3:
3652 reg_no = XSCALE_DAC;
3653 break;
3654 case 5:
3655 reg_no = XSCALE_FSR;
3656 break;
3657 case 6:
3658 reg_no = XSCALE_FAR;
3659 break;
3660 case 13:
3661 reg_no = XSCALE_PID;
3662 break;
3663 case 15:
3664 reg_no = XSCALE_CPACCESS;
3665 break;
3666 default:
3667 command_print(cmd_ctx, "invalid register number");
3668 return ERROR_INVALID_ARGUMENTS;
3669 }
3670 reg = &xscale->reg_cache->reg_list[reg_no];
3671
3672 }
3673 if(argc == 1)
3674 {
3675 u32 value;
3676
3677 /* read cp15 control register */
3678 xscale_get_reg(reg);
3679 value = buf_get_u32(reg->value, 0, 32);
3680 command_print(cmd_ctx, "%s (/%i): 0x%x", reg->name, reg->size, value);
3681 }
3682 else if(argc == 2)
3683 {
3684
3685 u32 value = strtoul(args[1], NULL, 0);
3686
3687 /* send CP write request (command 0x41) */
3688 xscale_send_u32(target, 0x41);
3689
3690 /* send CP register number */
3691 xscale_send_u32(target, reg_no);
3692
3693 /* send CP register value */
3694 xscale_send_u32(target, value);
3695
3696 /* execute cpwait to ensure outstanding operations complete */
3697 xscale_send_u32(target, 0x53);
3698 }
3699 else
3700 {
3701 command_print(cmd_ctx, "usage: cp15 [register]<, [value]>");
3702 }
3703
3704 return ERROR_OK;
3705 }
3706
3707 int xscale_register_commands(struct command_context_s *cmd_ctx)
3708 {
3709 command_t *xscale_cmd;
3710
3711 xscale_cmd = register_command(cmd_ctx, NULL, "xscale", NULL, COMMAND_ANY, "xscale specific commands");
3712
3713 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");
3714 register_command(cmd_ctx, xscale_cmd, "cache_clean_address", xscale_handle_cache_clean_address_command, COMMAND_ANY, NULL);
3715
3716 register_command(cmd_ctx, xscale_cmd, "cache_info", xscale_handle_cache_info_command, COMMAND_EXEC, NULL);
3717 register_command(cmd_ctx, xscale_cmd, "mmu", xscale_handle_mmu_command, COMMAND_EXEC, "['enable'|'disable'] the MMU");
3718 register_command(cmd_ctx, xscale_cmd, "icache", xscale_handle_idcache_command, COMMAND_EXEC, "['enable'|'disable'] the ICache");
3719 register_command(cmd_ctx, xscale_cmd, "dcache", xscale_handle_idcache_command, COMMAND_EXEC, "['enable'|'disable'] the DCache");
3720
3721 register_command(cmd_ctx, xscale_cmd, "vector_catch", xscale_handle_idcache_command, COMMAND_EXEC, "<mask> of vectors that should be catched");
3722
3723 register_command(cmd_ctx, xscale_cmd, "trace_buffer", xscale_handle_trace_buffer_command, COMMAND_EXEC, "<enable|disable> ['fill' [n]|'wrap']");
3724
3725 register_command(cmd_ctx, xscale_cmd, "dump_trace", xscale_handle_dump_trace_command, COMMAND_EXEC, "dump content of trace buffer to <file>");
3726 register_command(cmd_ctx, xscale_cmd, "analyze_trace", xscale_handle_analyze_trace_buffer_command, COMMAND_EXEC, "analyze content of trace buffer");
3727 register_command(cmd_ctx, xscale_cmd, "trace_image", xscale_handle_trace_image_command,
3728 COMMAND_EXEC, "load image from <file> [base address]");
3729
3730 register_command(cmd_ctx, xscale_cmd, "cp15", xscale_handle_cp15, COMMAND_EXEC, "access coproc 15 <register> [value]");
3731
3732 armv4_5_register_commands(cmd_ctx);
3733
3734 return ERROR_OK;
3735 }

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)