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

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)