- Fixes '>=' whitespace
[openocd.git] / src / target / xscale.c
blob71d365dd5ce5a2a1c76499a22b03b5e46649e4a2
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
27 #include "xscale.h"
28 #include "target_type.h"
29 #include "arm7_9_common.h"
30 #include "arm_simulator.h"
31 #include "arm_disassembler.h"
32 #include "time_support.h"
33 #include "image.h"
35 /* cli handling */
36 int xscale_register_commands(struct command_context_s *cmd_ctx);
38 /* forward declarations */
39 int xscale_target_create(struct target_s *target, Jim_Interp *interp);
40 int xscale_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
41 int xscale_quit(void);
43 int xscale_arch_state(struct target_s *target);
44 int xscale_poll(target_t *target);
45 int xscale_halt(target_t *target);
46 int xscale_resume(struct target_s *target, int current, uint32_t address, int handle_breakpoints, int debug_execution);
47 int xscale_step(struct target_s *target, int current, uint32_t address, int handle_breakpoints);
48 int xscale_debug_entry(target_t *target);
49 int xscale_restore_context(target_t *target);
51 int xscale_assert_reset(target_t *target);
52 int xscale_deassert_reset(target_t *target);
53 int xscale_soft_reset_halt(struct target_s *target);
55 int xscale_set_reg_u32(reg_t *reg, uint32_t value);
57 int xscale_read_core_reg(struct target_s *target, int num, enum armv4_5_mode mode);
58 int xscale_write_core_reg(struct target_s *target, int num, enum armv4_5_mode mode, uint32_t value);
60 int xscale_read_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
61 int xscale_write_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
62 int xscale_bulk_write_memory(target_t *target, uint32_t address, uint32_t count, uint8_t *buffer);
64 int xscale_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
65 int xscale_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
66 int xscale_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
67 int xscale_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
68 int xscale_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint);
69 int xscale_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint);
70 void xscale_enable_watchpoints(struct target_s *target);
71 void xscale_enable_breakpoints(struct target_s *target);
72 static int xscale_virt2phys(struct target_s *target, uint32_t virtual, uint32_t *physical);
73 static int xscale_mmu(struct target_s *target, int *enabled);
75 int xscale_read_trace(target_t *target);
77 target_type_t xscale_target =
79 .name = "xscale",
81 .poll = xscale_poll,
82 .arch_state = xscale_arch_state,
84 .target_request_data = NULL,
86 .halt = xscale_halt,
87 .resume = xscale_resume,
88 .step = xscale_step,
90 .assert_reset = xscale_assert_reset,
91 .deassert_reset = xscale_deassert_reset,
92 .soft_reset_halt = xscale_soft_reset_halt,
94 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
96 .read_memory = xscale_read_memory,
97 .write_memory = xscale_write_memory,
98 .bulk_write_memory = xscale_bulk_write_memory,
99 .checksum_memory = arm7_9_checksum_memory,
100 .blank_check_memory = arm7_9_blank_check_memory,
102 .run_algorithm = armv4_5_run_algorithm,
104 .add_breakpoint = xscale_add_breakpoint,
105 .remove_breakpoint = xscale_remove_breakpoint,
106 .add_watchpoint = xscale_add_watchpoint,
107 .remove_watchpoint = xscale_remove_watchpoint,
109 .register_commands = xscale_register_commands,
110 .target_create = xscale_target_create,
111 .init_target = xscale_init_target,
112 .quit = xscale_quit,
114 .virt2phys = xscale_virt2phys,
115 .mmu = xscale_mmu
118 char* xscale_reg_list[] =
120 "XSCALE_MAINID", /* 0 */
121 "XSCALE_CACHETYPE",
122 "XSCALE_CTRL",
123 "XSCALE_AUXCTRL",
124 "XSCALE_TTB",
125 "XSCALE_DAC",
126 "XSCALE_FSR",
127 "XSCALE_FAR",
128 "XSCALE_PID",
129 "XSCALE_CPACCESS",
130 "XSCALE_IBCR0", /* 10 */
131 "XSCALE_IBCR1",
132 "XSCALE_DBR0",
133 "XSCALE_DBR1",
134 "XSCALE_DBCON",
135 "XSCALE_TBREG",
136 "XSCALE_CHKPT0",
137 "XSCALE_CHKPT1",
138 "XSCALE_DCSR",
139 "XSCALE_TX",
140 "XSCALE_RX", /* 20 */
141 "XSCALE_TXRXCTRL",
144 xscale_reg_t xscale_reg_arch_info[] =
146 {XSCALE_MAINID, NULL},
147 {XSCALE_CACHETYPE, NULL},
148 {XSCALE_CTRL, NULL},
149 {XSCALE_AUXCTRL, NULL},
150 {XSCALE_TTB, NULL},
151 {XSCALE_DAC, NULL},
152 {XSCALE_FSR, NULL},
153 {XSCALE_FAR, NULL},
154 {XSCALE_PID, NULL},
155 {XSCALE_CPACCESS, NULL},
156 {XSCALE_IBCR0, NULL},
157 {XSCALE_IBCR1, NULL},
158 {XSCALE_DBR0, NULL},
159 {XSCALE_DBR1, NULL},
160 {XSCALE_DBCON, NULL},
161 {XSCALE_TBREG, NULL},
162 {XSCALE_CHKPT0, NULL},
163 {XSCALE_CHKPT1, NULL},
164 {XSCALE_DCSR, NULL}, /* DCSR accessed via JTAG or SW */
165 {-1, NULL}, /* TX accessed via JTAG */
166 {-1, NULL}, /* RX accessed via JTAG */
167 {-1, NULL}, /* TXRXCTRL implicit access via JTAG */
170 int xscale_reg_arch_type = -1;
172 int xscale_get_reg(reg_t *reg);
173 int xscale_set_reg(reg_t *reg, uint8_t *buf);
175 int xscale_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, xscale_common_t **xscale_p)
177 armv4_5_common_t *armv4_5 = target->arch_info;
178 xscale_common_t *xscale = armv4_5->arch_info;
180 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
182 LOG_ERROR("target isn't an XScale target");
183 return -1;
186 if (xscale->common_magic != XSCALE_COMMON_MAGIC)
188 LOG_ERROR("target isn't an XScale target");
189 return -1;
192 *armv4_5_p = armv4_5;
193 *xscale_p = xscale;
195 return ERROR_OK;
198 int xscale_jtag_set_instr(jtag_tap_t *tap, uint32_t new_instr)
200 if (tap==NULL)
201 return ERROR_FAIL;
203 if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr)
205 scan_field_t field;
207 field.tap = tap;
208 field.num_bits = tap->ir_length;
209 field.out_value = calloc(CEIL(field.num_bits, 8), 1);
210 buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
212 uint8_t tmp[4];
213 field.in_value = tmp;
215 jtag_add_ir_scan(1, &field, jtag_get_end_state());
217 /* FIX!!!! isn't this check superfluous? verify_ircapture handles this? */
218 jtag_check_value_mask(&field, tap->expected, tap->expected_mask);
220 free(field.out_value);
223 return ERROR_OK;
226 int xscale_read_dcsr(target_t *target)
228 armv4_5_common_t *armv4_5 = target->arch_info;
229 xscale_common_t *xscale = armv4_5->arch_info;
231 int retval;
233 scan_field_t fields[3];
234 uint8_t field0 = 0x0;
235 uint8_t field0_check_value = 0x2;
236 uint8_t field0_check_mask = 0x7;
237 uint8_t field2 = 0x0;
238 uint8_t field2_check_value = 0x0;
239 uint8_t field2_check_mask = 0x1;
241 jtag_set_end_state(TAP_DRPAUSE);
242 xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.dcsr);
244 buf_set_u32(&field0, 1, 1, xscale->hold_rst);
245 buf_set_u32(&field0, 2, 1, xscale->external_debug_break);
247 fields[0].tap = xscale->jtag_info.tap;
248 fields[0].num_bits = 3;
249 fields[0].out_value = &field0;
250 uint8_t tmp;
251 fields[0].in_value = &tmp;
253 fields[1].tap = xscale->jtag_info.tap;
254 fields[1].num_bits = 32;
255 fields[1].out_value = NULL;
256 fields[1].in_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value;
259 fields[2].tap = xscale->jtag_info.tap;
260 fields[2].num_bits = 1;
261 fields[2].out_value = &field2;
262 uint8_t tmp2;
263 fields[2].in_value = &tmp2;
265 jtag_add_dr_scan(3, fields, jtag_get_end_state());
267 jtag_check_value_mask(fields+0, &field0_check_value, &field0_check_mask);
268 jtag_check_value_mask(fields+2, &field2_check_value, &field2_check_mask);
270 if ((retval = jtag_execute_queue()) != ERROR_OK)
272 LOG_ERROR("JTAG error while reading DCSR");
273 return retval;
276 xscale->reg_cache->reg_list[XSCALE_DCSR].dirty = 0;
277 xscale->reg_cache->reg_list[XSCALE_DCSR].valid = 1;
279 /* write the register with the value we just read
280 * on this second pass, only the first bit of field0 is guaranteed to be 0)
282 field0_check_mask = 0x1;
283 fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value;
284 fields[1].in_value = NULL;
286 jtag_set_end_state(TAP_IDLE);
288 jtag_add_dr_scan(3, fields, jtag_get_end_state());
290 /* DANGER!!! this must be here. It will make sure that the arguments
291 * to jtag_set_check_value() does not go out of scope! */
292 return jtag_execute_queue();
296 static void xscale_getbuf(jtag_callback_data_t arg)
298 uint8_t *in=(uint8_t *)arg;
299 *((uint32_t *)in)=buf_get_u32(in, 0, 32);
302 int xscale_receive(target_t *target, uint32_t *buffer, int num_words)
304 if (num_words==0)
305 return ERROR_INVALID_ARGUMENTS;
307 int retval=ERROR_OK;
308 armv4_5_common_t *armv4_5 = target->arch_info;
309 xscale_common_t *xscale = armv4_5->arch_info;
311 tap_state_t path[3];
312 scan_field_t fields[3];
314 uint8_t *field0 = malloc(num_words * 1);
315 uint8_t field0_check_value = 0x2;
316 uint8_t field0_check_mask = 0x6;
317 uint32_t *field1 = malloc(num_words * 4);
318 uint8_t field2_check_value = 0x0;
319 uint8_t field2_check_mask = 0x1;
320 int words_done = 0;
321 int words_scheduled = 0;
323 int i;
325 path[0] = TAP_DRSELECT;
326 path[1] = TAP_DRCAPTURE;
327 path[2] = TAP_DRSHIFT;
329 fields[0].tap = xscale->jtag_info.tap;
330 fields[0].num_bits = 3;
331 fields[0].out_value = NULL;
332 fields[0].in_value = NULL;
333 fields[0].check_value = &field0_check_value;
334 fields[0].check_mask = &field0_check_mask;
336 fields[1].tap = xscale->jtag_info.tap;
337 fields[1].num_bits = 32;
338 fields[1].out_value = NULL;
339 fields[1].check_value = NULL;
340 fields[1].check_mask = NULL;
342 fields[2].tap = xscale->jtag_info.tap;
343 fields[2].num_bits = 1;
344 fields[2].out_value = NULL;
345 fields[2].in_value = NULL;
346 fields[2].check_value = &field2_check_value;
347 fields[2].check_mask = &field2_check_mask;
349 jtag_set_end_state(TAP_IDLE);
350 xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.dbgtx);
351 jtag_add_runtest(1, jtag_get_end_state()); /* ensures that we're in the TAP_IDLE state as the above could be a no-op */
353 /* repeat until all words have been collected */
354 int attempts=0;
355 while (words_done < num_words)
357 /* schedule reads */
358 words_scheduled = 0;
359 for (i = words_done; i < num_words; i++)
361 fields[0].in_value = &field0[i];
363 jtag_add_pathmove(3, path);
365 fields[1].in_value = (uint8_t *)(field1+i);
367 jtag_add_dr_scan_check(3, fields, jtag_set_end_state(TAP_IDLE));
369 jtag_add_callback(xscale_getbuf, (jtag_callback_data_t)(field1+i));
371 words_scheduled++;
374 if ((retval = jtag_execute_queue()) != ERROR_OK)
376 LOG_ERROR("JTAG error while receiving data from debug handler");
377 break;
380 /* examine results */
381 for (i = words_done; i < num_words; i++)
383 if (!(field0[0] & 1))
385 /* move backwards if necessary */
386 int j;
387 for (j = i; j < num_words - 1; j++)
389 field0[j] = field0[j+1];
390 field1[j] = field1[j+1];
392 words_scheduled--;
395 if (words_scheduled==0)
397 if (attempts++==1000)
399 LOG_ERROR("Failed to receiving data from debug handler after 1000 attempts");
400 retval=ERROR_TARGET_TIMEOUT;
401 break;
405 words_done += words_scheduled;
408 for (i = 0; i < num_words; i++)
409 *(buffer++) = buf_get_u32((uint8_t*)&field1[i], 0, 32);
411 free(field1);
413 return retval;
416 int xscale_read_tx(target_t *target, int consume)
418 armv4_5_common_t *armv4_5 = target->arch_info;
419 xscale_common_t *xscale = armv4_5->arch_info;
420 tap_state_t path[3];
421 tap_state_t noconsume_path[6];
423 int retval;
424 struct timeval timeout, now;
426 scan_field_t fields[3];
427 uint8_t field0_in = 0x0;
428 uint8_t field0_check_value = 0x2;
429 uint8_t field0_check_mask = 0x6;
430 uint8_t field2_check_value = 0x0;
431 uint8_t field2_check_mask = 0x1;
433 jtag_set_end_state(TAP_IDLE);
435 xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.dbgtx);
437 path[0] = TAP_DRSELECT;
438 path[1] = TAP_DRCAPTURE;
439 path[2] = TAP_DRSHIFT;
441 noconsume_path[0] = TAP_DRSELECT;
442 noconsume_path[1] = TAP_DRCAPTURE;
443 noconsume_path[2] = TAP_DREXIT1;
444 noconsume_path[3] = TAP_DRPAUSE;
445 noconsume_path[4] = TAP_DREXIT2;
446 noconsume_path[5] = TAP_DRSHIFT;
448 fields[0].tap = xscale->jtag_info.tap;
449 fields[0].num_bits = 3;
450 fields[0].out_value = NULL;
451 fields[0].in_value = &field0_in;
453 fields[1].tap = xscale->jtag_info.tap;
454 fields[1].num_bits = 32;
455 fields[1].out_value = NULL;
456 fields[1].in_value = xscale->reg_cache->reg_list[XSCALE_TX].value;
459 fields[2].tap = xscale->jtag_info.tap;
460 fields[2].num_bits = 1;
461 fields[2].out_value = NULL;
462 uint8_t tmp;
463 fields[2].in_value = &tmp;
465 gettimeofday(&timeout, NULL);
466 timeval_add_time(&timeout, 1, 0);
468 for (;;)
470 /* if we want to consume the register content (i.e. clear TX_READY),
471 * we have to go straight from Capture-DR to Shift-DR
472 * otherwise, we go from Capture-DR to Exit1-DR to Pause-DR
474 if (consume)
475 jtag_add_pathmove(3, path);
476 else
478 jtag_add_pathmove(sizeof(noconsume_path)/sizeof(*noconsume_path), noconsume_path);
481 jtag_add_dr_scan(3, fields, jtag_set_end_state(TAP_IDLE));
483 jtag_check_value_mask(fields+0, &field0_check_value, &field0_check_mask);
484 jtag_check_value_mask(fields+2, &field2_check_value, &field2_check_mask);
486 if ((retval = jtag_execute_queue()) != ERROR_OK)
488 LOG_ERROR("JTAG error while reading TX");
489 return ERROR_TARGET_TIMEOUT;
492 gettimeofday(&now, NULL);
493 if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec)&& (now.tv_usec > timeout.tv_usec)))
495 LOG_ERROR("time out reading TX register");
496 return ERROR_TARGET_TIMEOUT;
498 if (!((!(field0_in & 1)) && consume))
500 goto done;
502 if (debug_level >= 3)
504 LOG_DEBUG("waiting 100ms");
505 alive_sleep(100); /* avoid flooding the logs */
506 } else
508 keep_alive();
511 done:
513 if (!(field0_in & 1))
514 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
516 return ERROR_OK;
519 int xscale_write_rx(target_t *target)
521 armv4_5_common_t *armv4_5 = target->arch_info;
522 xscale_common_t *xscale = armv4_5->arch_info;
524 int retval;
525 struct timeval timeout, now;
527 scan_field_t fields[3];
528 uint8_t field0_out = 0x0;
529 uint8_t field0_in = 0x0;
530 uint8_t field0_check_value = 0x2;
531 uint8_t field0_check_mask = 0x6;
532 uint8_t field2 = 0x0;
533 uint8_t field2_check_value = 0x0;
534 uint8_t field2_check_mask = 0x1;
536 jtag_set_end_state(TAP_IDLE);
538 xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.dbgrx);
540 fields[0].tap = xscale->jtag_info.tap;
541 fields[0].num_bits = 3;
542 fields[0].out_value = &field0_out;
543 fields[0].in_value = &field0_in;
545 fields[1].tap = xscale->jtag_info.tap;
546 fields[1].num_bits = 32;
547 fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_RX].value;
548 fields[1].in_value = NULL;
551 fields[2].tap = xscale->jtag_info.tap;
552 fields[2].num_bits = 1;
553 fields[2].out_value = &field2;
554 uint8_t tmp;
555 fields[2].in_value = &tmp;
557 gettimeofday(&timeout, NULL);
558 timeval_add_time(&timeout, 1, 0);
560 /* poll until rx_read is low */
561 LOG_DEBUG("polling RX");
562 for (;;)
564 jtag_add_dr_scan(3, fields, jtag_set_end_state(TAP_IDLE));
566 jtag_check_value_mask(fields+0, &field0_check_value, &field0_check_mask);
567 jtag_check_value_mask(fields+2, &field2_check_value, &field2_check_mask);
569 if ((retval = jtag_execute_queue()) != ERROR_OK)
571 LOG_ERROR("JTAG error while writing RX");
572 return retval;
575 gettimeofday(&now, NULL);
576 if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec)&& (now.tv_usec > timeout.tv_usec)))
578 LOG_ERROR("time out writing RX register");
579 return ERROR_TARGET_TIMEOUT;
581 if (!(field0_in & 1))
582 goto done;
583 if (debug_level >= 3)
585 LOG_DEBUG("waiting 100ms");
586 alive_sleep(100); /* avoid flooding the logs */
587 } else
589 keep_alive();
592 done:
594 /* set rx_valid */
595 field2 = 0x1;
596 jtag_add_dr_scan(3, fields, jtag_set_end_state(TAP_IDLE));
598 if ((retval = jtag_execute_queue()) != ERROR_OK)
600 LOG_ERROR("JTAG error while writing RX");
601 return retval;
604 return ERROR_OK;
607 /* send count elements of size byte to the debug handler */
608 int xscale_send(target_t *target, uint8_t *buffer, int count, int size)
610 armv4_5_common_t *armv4_5 = target->arch_info;
611 xscale_common_t *xscale = armv4_5->arch_info;
612 uint32_t t[3];
613 int bits[3];
615 int retval;
617 int done_count = 0;
619 jtag_set_end_state(TAP_IDLE);
621 xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.dbgrx);
623 bits[0]=3;
624 t[0]=0;
625 bits[1]=32;
626 t[2]=1;
627 bits[2]=1;
628 int endianness = target->endianness;
629 while (done_count++ < count)
631 switch (size)
633 case 4:
634 if (endianness == TARGET_LITTLE_ENDIAN)
636 t[1]=le_to_h_u32(buffer);
637 } else
639 t[1]=be_to_h_u32(buffer);
641 break;
642 case 2:
643 if (endianness == TARGET_LITTLE_ENDIAN)
645 t[1]=le_to_h_u16(buffer);
646 } else
648 t[1]=be_to_h_u16(buffer);
650 break;
651 case 1:
652 t[1]=buffer[0];
653 break;
654 default:
655 LOG_ERROR("BUG: size neither 4, 2 nor 1");
656 exit(-1);
658 jtag_add_dr_out(xscale->jtag_info.tap,
660 bits,
662 jtag_set_end_state(TAP_IDLE));
663 buffer += size;
666 if ((retval = jtag_execute_queue()) != ERROR_OK)
668 LOG_ERROR("JTAG error while sending data to debug handler");
669 return retval;
672 return ERROR_OK;
675 int xscale_send_u32(target_t *target, uint32_t value)
677 armv4_5_common_t *armv4_5 = target->arch_info;
678 xscale_common_t *xscale = armv4_5->arch_info;
680 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_RX].value, 0, 32, value);
681 return xscale_write_rx(target);
684 int xscale_write_dcsr(target_t *target, int hold_rst, int ext_dbg_brk)
686 armv4_5_common_t *armv4_5 = target->arch_info;
687 xscale_common_t *xscale = armv4_5->arch_info;
689 int retval;
691 scan_field_t fields[3];
692 uint8_t field0 = 0x0;
693 uint8_t field0_check_value = 0x2;
694 uint8_t field0_check_mask = 0x7;
695 uint8_t field2 = 0x0;
696 uint8_t field2_check_value = 0x0;
697 uint8_t field2_check_mask = 0x1;
699 if (hold_rst != -1)
700 xscale->hold_rst = hold_rst;
702 if (ext_dbg_brk != -1)
703 xscale->external_debug_break = ext_dbg_brk;
705 jtag_set_end_state(TAP_IDLE);
706 xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.dcsr);
708 buf_set_u32(&field0, 1, 1, xscale->hold_rst);
709 buf_set_u32(&field0, 2, 1, xscale->external_debug_break);
711 fields[0].tap = xscale->jtag_info.tap;
712 fields[0].num_bits = 3;
713 fields[0].out_value = &field0;
714 uint8_t tmp;
715 fields[0].in_value = &tmp;
717 fields[1].tap = xscale->jtag_info.tap;
718 fields[1].num_bits = 32;
719 fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value;
720 fields[1].in_value = NULL;
723 fields[2].tap = xscale->jtag_info.tap;
724 fields[2].num_bits = 1;
725 fields[2].out_value = &field2;
726 uint8_t tmp2;
727 fields[2].in_value = &tmp2;
729 jtag_add_dr_scan(3, fields, jtag_get_end_state());
731 jtag_check_value_mask(fields+0, &field0_check_value, &field0_check_mask);
732 jtag_check_value_mask(fields+2, &field2_check_value, &field2_check_mask);
734 if ((retval = jtag_execute_queue()) != ERROR_OK)
736 LOG_ERROR("JTAG error while writing DCSR");
737 return retval;
740 xscale->reg_cache->reg_list[XSCALE_DCSR].dirty = 0;
741 xscale->reg_cache->reg_list[XSCALE_DCSR].valid = 1;
743 return ERROR_OK;
746 /* parity of the number of bits 0 if even; 1 if odd. for 32 bit words */
747 unsigned int parity (unsigned int v)
749 unsigned int ov = v;
750 v ^= v >> 16;
751 v ^= v >> 8;
752 v ^= v >> 4;
753 v &= 0xf;
754 LOG_DEBUG("parity of 0x%x is %i", ov, (0x6996 >> v) & 1);
755 return (0x6996 >> v) & 1;
758 int xscale_load_ic(target_t *target, int mini, uint32_t va, uint32_t buffer[8])
760 armv4_5_common_t *armv4_5 = target->arch_info;
761 xscale_common_t *xscale = armv4_5->arch_info;
762 uint8_t packet[4];
763 uint8_t cmd;
764 int word;
766 scan_field_t fields[2];
768 LOG_DEBUG("loading miniIC at 0x%8.8" PRIx32 "", va);
770 jtag_set_end_state(TAP_IDLE);
771 xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.ldic); /* LDIC */
773 /* CMD is b010 for Main IC and b011 for Mini IC */
774 if (mini)
775 buf_set_u32(&cmd, 0, 3, 0x3);
776 else
777 buf_set_u32(&cmd, 0, 3, 0x2);
779 buf_set_u32(&cmd, 3, 3, 0x0);
781 /* virtual address of desired cache line */
782 buf_set_u32(packet, 0, 27, va >> 5);
784 fields[0].tap = xscale->jtag_info.tap;
785 fields[0].num_bits = 6;
786 fields[0].out_value = &cmd;
788 fields[0].in_value = NULL;
794 fields[1].tap = xscale->jtag_info.tap;
795 fields[1].num_bits = 27;
796 fields[1].out_value = packet;
798 fields[1].in_value = NULL;
804 jtag_add_dr_scan(2, fields, jtag_get_end_state());
806 fields[0].num_bits = 32;
807 fields[0].out_value = packet;
809 fields[1].num_bits = 1;
810 fields[1].out_value = &cmd;
812 for (word = 0; word < 8; word++)
814 buf_set_u32(packet, 0, 32, buffer[word]);
816 uint32_t value;
817 memcpy(&value, packet, sizeof(uint32_t));
818 cmd = parity(value);
820 jtag_add_dr_scan(2, fields, jtag_get_end_state());
823 jtag_execute_queue();
825 return ERROR_OK;
828 int xscale_invalidate_ic_line(target_t *target, uint32_t va)
830 armv4_5_common_t *armv4_5 = target->arch_info;
831 xscale_common_t *xscale = armv4_5->arch_info;
832 uint8_t packet[4];
833 uint8_t cmd;
835 scan_field_t fields[2];
837 jtag_set_end_state(TAP_IDLE);
838 xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.ldic); /* LDIC */
840 /* CMD for invalidate IC line b000, bits [6:4] b000 */
841 buf_set_u32(&cmd, 0, 6, 0x0);
843 /* virtual address of desired cache line */
844 buf_set_u32(packet, 0, 27, va >> 5);
846 fields[0].tap = xscale->jtag_info.tap;
847 fields[0].num_bits = 6;
848 fields[0].out_value = &cmd;
850 fields[0].in_value = NULL;
856 fields[1].tap = xscale->jtag_info.tap;
857 fields[1].num_bits = 27;
858 fields[1].out_value = packet;
860 fields[1].in_value = NULL;
866 jtag_add_dr_scan(2, fields, jtag_get_end_state());
868 return ERROR_OK;
871 int xscale_update_vectors(target_t *target)
873 armv4_5_common_t *armv4_5 = target->arch_info;
874 xscale_common_t *xscale = armv4_5->arch_info;
875 int i;
876 int retval;
878 uint32_t low_reset_branch, high_reset_branch;
880 for (i = 1; i < 8; i++)
882 /* if there's a static vector specified for this exception, override */
883 if (xscale->static_high_vectors_set & (1 << i))
885 xscale->high_vectors[i] = xscale->static_high_vectors[i];
887 else
889 retval=target_read_u32(target, 0xffff0000 + 4*i, &xscale->high_vectors[i]);
890 if (retval == ERROR_TARGET_TIMEOUT)
891 return retval;
892 if (retval != ERROR_OK)
894 /* Some of these reads will fail as part of normal execution */
895 xscale->high_vectors[i] = ARMV4_5_B(0xfffffe, 0);
900 for (i = 1; i < 8; i++)
902 if (xscale->static_low_vectors_set & (1 << i))
904 xscale->low_vectors[i] = xscale->static_low_vectors[i];
906 else
908 retval=target_read_u32(target, 0x0 + 4*i, &xscale->low_vectors[i]);
909 if (retval == ERROR_TARGET_TIMEOUT)
910 return retval;
911 if (retval != ERROR_OK)
913 /* Some of these reads will fail as part of normal execution */
914 xscale->low_vectors[i] = ARMV4_5_B(0xfffffe, 0);
919 /* calculate branches to debug handler */
920 low_reset_branch = (xscale->handler_address + 0x20 - 0x0 - 0x8) >> 2;
921 high_reset_branch = (xscale->handler_address + 0x20 - 0xffff0000 - 0x8) >> 2;
923 xscale->low_vectors[0] = ARMV4_5_B((low_reset_branch & 0xffffff), 0);
924 xscale->high_vectors[0] = ARMV4_5_B((high_reset_branch & 0xffffff), 0);
926 /* invalidate and load exception vectors in mini i-cache */
927 xscale_invalidate_ic_line(target, 0x0);
928 xscale_invalidate_ic_line(target, 0xffff0000);
930 xscale_load_ic(target, 1, 0x0, xscale->low_vectors);
931 xscale_load_ic(target, 1, 0xffff0000, xscale->high_vectors);
933 return ERROR_OK;
936 int xscale_arch_state(struct target_s *target)
938 armv4_5_common_t *armv4_5 = target->arch_info;
939 xscale_common_t *xscale = armv4_5->arch_info;
941 char *state[] =
943 "disabled", "enabled"
946 char *arch_dbg_reason[] =
948 "", "\n(processor reset)", "\n(trace buffer full)"
951 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
953 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
954 exit(-1);
957 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
958 "cpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "\n"
959 "MMU: %s, D-Cache: %s, I-Cache: %s"
960 "%s",
961 armv4_5_state_strings[armv4_5->core_state],
962 Jim_Nvp_value2name_simple( nvp_target_debug_reason, target->debug_reason )->name ,
963 armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
964 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
965 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
966 state[xscale->armv4_5_mmu.mmu_enabled],
967 state[xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
968 state[xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled],
969 arch_dbg_reason[xscale->arch_debug_reason]);
971 return ERROR_OK;
974 int xscale_poll(target_t *target)
976 int retval=ERROR_OK;
977 armv4_5_common_t *armv4_5 = target->arch_info;
978 xscale_common_t *xscale = armv4_5->arch_info;
980 if ((target->state == TARGET_RUNNING) || (target->state == TARGET_DEBUG_RUNNING))
982 enum target_state previous_state = target->state;
983 if ((retval = xscale_read_tx(target, 0)) == ERROR_OK)
986 /* there's data to read from the tx register, we entered debug state */
987 xscale->handler_running = 1;
989 target->state = TARGET_HALTED;
991 /* process debug entry, fetching current mode regs */
992 retval = xscale_debug_entry(target);
994 else if (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
996 LOG_USER("error while polling TX register, reset CPU");
997 /* here we "lie" so GDB won't get stuck and a reset can be perfomed */
998 target->state = TARGET_HALTED;
1001 /* debug_entry could have overwritten target state (i.e. immediate resume)
1002 * don't signal event handlers in that case
1004 if (target->state != TARGET_HALTED)
1005 return ERROR_OK;
1007 /* if target was running, signal that we halted
1008 * otherwise we reentered from debug execution */
1009 if (previous_state == TARGET_RUNNING)
1010 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1011 else
1012 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
1015 return retval;
1018 int xscale_debug_entry(target_t *target)
1020 armv4_5_common_t *armv4_5 = target->arch_info;
1021 xscale_common_t *xscale = armv4_5->arch_info;
1022 uint32_t pc;
1023 uint32_t buffer[10];
1024 int i;
1025 int retval;
1027 uint32_t moe;
1029 /* clear external dbg break (will be written on next DCSR read) */
1030 xscale->external_debug_break = 0;
1031 if ((retval=xscale_read_dcsr(target)) != ERROR_OK)
1032 return retval;
1034 /* get r0, pc, r1 to r7 and cpsr */
1035 if ((retval=xscale_receive(target, buffer, 10)) != ERROR_OK)
1036 return retval;
1038 /* move r0 from buffer to register cache */
1039 buf_set_u32(armv4_5->core_cache->reg_list[0].value, 0, 32, buffer[0]);
1040 armv4_5->core_cache->reg_list[15].dirty = 1;
1041 armv4_5->core_cache->reg_list[15].valid = 1;
1042 LOG_DEBUG("r0: 0x%8.8" PRIx32 "", buffer[0]);
1044 /* move pc from buffer to register cache */
1045 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, buffer[1]);
1046 armv4_5->core_cache->reg_list[15].dirty = 1;
1047 armv4_5->core_cache->reg_list[15].valid = 1;
1048 LOG_DEBUG("pc: 0x%8.8" PRIx32 "", buffer[1]);
1050 /* move data from buffer to register cache */
1051 for (i = 1; i <= 7; i++)
1053 buf_set_u32(armv4_5->core_cache->reg_list[i].value, 0, 32, buffer[1 + i]);
1054 armv4_5->core_cache->reg_list[i].dirty = 1;
1055 armv4_5->core_cache->reg_list[i].valid = 1;
1056 LOG_DEBUG("r%i: 0x%8.8" PRIx32 "", i, buffer[i + 1]);
1059 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32, buffer[9]);
1060 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
1061 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
1062 LOG_DEBUG("cpsr: 0x%8.8" PRIx32 "", buffer[9]);
1064 armv4_5->core_mode = buffer[9] & 0x1f;
1065 if (armv4_5_mode_to_number(armv4_5->core_mode) == -1)
1067 target->state = TARGET_UNKNOWN;
1068 LOG_ERROR("cpsr contains invalid mode value - communication failure");
1069 return ERROR_TARGET_FAILURE;
1071 LOG_DEBUG("target entered debug state in %s mode", armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)]);
1073 if (buffer[9] & 0x20)
1074 armv4_5->core_state = ARMV4_5_STATE_THUMB;
1075 else
1076 armv4_5->core_state = ARMV4_5_STATE_ARM;
1079 if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
1080 return ERROR_FAIL;
1082 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1083 if ((armv4_5->core_mode != ARMV4_5_MODE_USR) && (armv4_5->core_mode != ARMV4_5_MODE_SYS))
1085 xscale_receive(target, buffer, 8);
1086 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32, buffer[7]);
1087 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).dirty = 0;
1088 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).valid = 1;
1090 else
1092 /* r8 to r14, but no spsr */
1093 xscale_receive(target, buffer, 7);
1096 /* move data from buffer to register cache */
1097 for (i = 8; i <= 14; i++)
1099 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).value, 0, 32, buffer[i - 8]);
1100 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = 0;
1101 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid = 1;
1104 /* examine debug reason */
1105 xscale_read_dcsr(target);
1106 moe = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 2, 3);
1108 /* stored PC (for calculating fixup) */
1109 pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
1111 switch (moe)
1113 case 0x0: /* Processor reset */
1114 target->debug_reason = DBG_REASON_DBGRQ;
1115 xscale->arch_debug_reason = XSCALE_DBG_REASON_RESET;
1116 pc -= 4;
1117 break;
1118 case 0x1: /* Instruction breakpoint hit */
1119 target->debug_reason = DBG_REASON_BREAKPOINT;
1120 xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;
1121 pc -= 4;
1122 break;
1123 case 0x2: /* Data breakpoint hit */
1124 target->debug_reason = DBG_REASON_WATCHPOINT;
1125 xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;
1126 pc -= 4;
1127 break;
1128 case 0x3: /* BKPT instruction executed */
1129 target->debug_reason = DBG_REASON_BREAKPOINT;
1130 xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;
1131 pc -= 4;
1132 break;
1133 case 0x4: /* Ext. debug event */
1134 target->debug_reason = DBG_REASON_DBGRQ;
1135 xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;
1136 pc -= 4;
1137 break;
1138 case 0x5: /* Vector trap occured */
1139 target->debug_reason = DBG_REASON_BREAKPOINT;
1140 xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;
1141 pc -= 4;
1142 break;
1143 case 0x6: /* Trace buffer full break */
1144 target->debug_reason = DBG_REASON_DBGRQ;
1145 xscale->arch_debug_reason = XSCALE_DBG_REASON_TB_FULL;
1146 pc -= 4;
1147 break;
1148 case 0x7: /* Reserved */
1149 default:
1150 LOG_ERROR("Method of Entry is 'Reserved'");
1151 exit(-1);
1152 break;
1155 /* apply PC fixup */
1156 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, pc);
1158 /* on the first debug entry, identify cache type */
1159 if (xscale->armv4_5_mmu.armv4_5_cache.ctype == -1)
1161 uint32_t cache_type_reg;
1163 /* read cp15 cache type register */
1164 xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CACHETYPE]);
1165 cache_type_reg = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CACHETYPE].value, 0, 32);
1167 armv4_5_identify_cache(cache_type_reg, &xscale->armv4_5_mmu.armv4_5_cache);
1170 /* examine MMU and Cache settings */
1171 /* read cp15 control register */
1172 xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);
1173 xscale->cp15_control_reg = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32);
1174 xscale->armv4_5_mmu.mmu_enabled = (xscale->cp15_control_reg & 0x1U) ? 1 : 0;
1175 xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = (xscale->cp15_control_reg & 0x4U) ? 1 : 0;
1176 xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = (xscale->cp15_control_reg & 0x1000U) ? 1 : 0;
1178 /* tracing enabled, read collected trace data */
1179 if (xscale->trace.buffer_enabled)
1181 xscale_read_trace(target);
1182 xscale->trace.buffer_fill--;
1184 /* resume if we're still collecting trace data */
1185 if ((xscale->arch_debug_reason == XSCALE_DBG_REASON_TB_FULL)
1186 && (xscale->trace.buffer_fill > 0))
1188 xscale_resume(target, 1, 0x0, 1, 0);
1190 else
1192 xscale->trace.buffer_enabled = 0;
1196 return ERROR_OK;
1199 int xscale_halt(target_t *target)
1201 armv4_5_common_t *armv4_5 = target->arch_info;
1202 xscale_common_t *xscale = armv4_5->arch_info;
1204 LOG_DEBUG("target->state: %s",
1205 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
1207 if (target->state == TARGET_HALTED)
1209 LOG_DEBUG("target was already halted");
1210 return ERROR_OK;
1212 else if (target->state == TARGET_UNKNOWN)
1214 /* this must not happen for a xscale target */
1215 LOG_ERROR("target was in unknown state when halt was requested");
1216 return ERROR_TARGET_INVALID;
1218 else if (target->state == TARGET_RESET)
1220 LOG_DEBUG("target->state == TARGET_RESET");
1222 else
1224 /* assert external dbg break */
1225 xscale->external_debug_break = 1;
1226 xscale_read_dcsr(target);
1228 target->debug_reason = DBG_REASON_DBGRQ;
1231 return ERROR_OK;
1234 int xscale_enable_single_step(struct target_s *target, uint32_t next_pc)
1236 armv4_5_common_t *armv4_5 = target->arch_info;
1237 xscale_common_t *xscale= armv4_5->arch_info;
1238 reg_t *ibcr0 = &xscale->reg_cache->reg_list[XSCALE_IBCR0];
1239 int retval;
1241 if (xscale->ibcr0_used)
1243 breakpoint_t *ibcr0_bp = breakpoint_find(target, buf_get_u32(ibcr0->value, 0, 32) & 0xfffffffe);
1245 if (ibcr0_bp)
1247 xscale_unset_breakpoint(target, ibcr0_bp);
1249 else
1251 LOG_ERROR("BUG: xscale->ibcr0_used is set, but no breakpoint with that address found");
1252 exit(-1);
1256 if ((retval=xscale_set_reg_u32(ibcr0, next_pc | 0x1)) != ERROR_OK)
1257 return retval;
1259 return ERROR_OK;
1262 int xscale_disable_single_step(struct target_s *target)
1264 armv4_5_common_t *armv4_5 = target->arch_info;
1265 xscale_common_t *xscale= armv4_5->arch_info;
1266 reg_t *ibcr0 = &xscale->reg_cache->reg_list[XSCALE_IBCR0];
1267 int retval;
1269 if ((retval=xscale_set_reg_u32(ibcr0, 0x0)) != ERROR_OK)
1270 return retval;
1272 return ERROR_OK;
1275 int xscale_resume(struct target_s *target, int current, uint32_t address, int handle_breakpoints, int debug_execution)
1277 armv4_5_common_t *armv4_5 = target->arch_info;
1278 xscale_common_t *xscale= armv4_5->arch_info;
1279 breakpoint_t *breakpoint = target->breakpoints;
1281 uint32_t current_pc;
1283 int retval;
1284 int i;
1286 LOG_DEBUG("-");
1288 if (target->state != TARGET_HALTED)
1290 LOG_WARNING("target not halted");
1291 return ERROR_TARGET_NOT_HALTED;
1294 if (!debug_execution)
1296 target_free_all_working_areas(target);
1299 /* update vector tables */
1300 if ((retval=xscale_update_vectors(target)) != ERROR_OK)
1301 return retval;
1303 /* current = 1: continue on current pc, otherwise continue at <address> */
1304 if (!current)
1305 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, address);
1307 current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
1309 /* if we're at the reset vector, we have to simulate the branch */
1310 if (current_pc == 0x0)
1312 arm_simulate_step(target, NULL);
1313 current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
1316 /* the front-end may request us not to handle breakpoints */
1317 if (handle_breakpoints)
1319 if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))))
1321 uint32_t next_pc;
1323 /* there's a breakpoint at the current PC, we have to step over it */
1324 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
1325 xscale_unset_breakpoint(target, breakpoint);
1327 /* calculate PC of next instruction */
1328 if ((retval = arm_simulate_step(target, &next_pc)) != ERROR_OK)
1330 uint32_t current_opcode;
1331 target_read_u32(target, current_pc, &current_opcode);
1332 LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8" PRIx32 "", current_opcode);
1335 LOG_DEBUG("enable single-step");
1336 xscale_enable_single_step(target, next_pc);
1338 /* restore banked registers */
1339 xscale_restore_context(target);
1341 /* send resume request (command 0x30 or 0x31)
1342 * clean the trace buffer if it is to be enabled (0x62) */
1343 if (xscale->trace.buffer_enabled)
1345 xscale_send_u32(target, 0x62);
1346 xscale_send_u32(target, 0x31);
1348 else
1349 xscale_send_u32(target, 0x30);
1351 /* send CPSR */
1352 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1353 LOG_DEBUG("writing cpsr with value 0x%8.8" PRIx32 "", buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1355 for (i = 7; i >= 0; i--)
1357 /* send register */
1358 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
1359 LOG_DEBUG("writing r%i with value 0x%8.8" PRIx32 "", i, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
1362 /* send PC */
1363 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1364 LOG_DEBUG("writing PC with value 0x%8.8" PRIx32 "", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1366 /* wait for and process debug entry */
1367 xscale_debug_entry(target);
1369 LOG_DEBUG("disable single-step");
1370 xscale_disable_single_step(target);
1372 LOG_DEBUG("set breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
1373 xscale_set_breakpoint(target, breakpoint);
1377 /* enable any pending breakpoints and watchpoints */
1378 xscale_enable_breakpoints(target);
1379 xscale_enable_watchpoints(target);
1381 /* restore banked registers */
1382 xscale_restore_context(target);
1384 /* send resume request (command 0x30 or 0x31)
1385 * clean the trace buffer if it is to be enabled (0x62) */
1386 if (xscale->trace.buffer_enabled)
1388 xscale_send_u32(target, 0x62);
1389 xscale_send_u32(target, 0x31);
1391 else
1392 xscale_send_u32(target, 0x30);
1394 /* send CPSR */
1395 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1396 LOG_DEBUG("writing cpsr with value 0x%8.8" PRIx32 "", buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1398 for (i = 7; i >= 0; i--)
1400 /* send register */
1401 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
1402 LOG_DEBUG("writing r%i with value 0x%8.8" PRIx32 "", i, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
1405 /* send PC */
1406 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1407 LOG_DEBUG("writing PC with value 0x%8.8" PRIx32 "", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1409 target->debug_reason = DBG_REASON_NOTHALTED;
1411 if (!debug_execution)
1413 /* registers are now invalid */
1414 armv4_5_invalidate_core_regs(target);
1415 target->state = TARGET_RUNNING;
1416 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1418 else
1420 target->state = TARGET_DEBUG_RUNNING;
1421 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
1424 LOG_DEBUG("target resumed");
1426 xscale->handler_running = 1;
1428 return ERROR_OK;
1431 static int xscale_step_inner(struct target_s *target, int current, uint32_t address, int handle_breakpoints)
1433 armv4_5_common_t *armv4_5 = target->arch_info;
1434 xscale_common_t *xscale = armv4_5->arch_info;
1436 uint32_t next_pc;
1437 int retval;
1438 int i;
1440 target->debug_reason = DBG_REASON_SINGLESTEP;
1442 /* calculate PC of next instruction */
1443 if ((retval = arm_simulate_step(target, &next_pc)) != ERROR_OK)
1445 uint32_t current_opcode, current_pc;
1446 current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
1448 target_read_u32(target, current_pc, &current_opcode);
1449 LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8" PRIx32 "", current_opcode);
1450 return retval;
1453 LOG_DEBUG("enable single-step");
1454 if ((retval=xscale_enable_single_step(target, next_pc)) != ERROR_OK)
1455 return retval;
1457 /* restore banked registers */
1458 if ((retval=xscale_restore_context(target)) != ERROR_OK)
1459 return retval;
1461 /* send resume request (command 0x30 or 0x31)
1462 * clean the trace buffer if it is to be enabled (0x62) */
1463 if (xscale->trace.buffer_enabled)
1465 if ((retval=xscale_send_u32(target, 0x62)) != ERROR_OK)
1466 return retval;
1467 if ((retval=xscale_send_u32(target, 0x31)) != ERROR_OK)
1468 return retval;
1470 else
1471 if ((retval=xscale_send_u32(target, 0x30)) != ERROR_OK)
1472 return retval;
1474 /* send CPSR */
1475 if ((retval=xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32))) != ERROR_OK)
1476 return retval;
1477 LOG_DEBUG("writing cpsr with value 0x%8.8" PRIx32 "", buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1479 for (i = 7; i >= 0; i--)
1481 /* send register */
1482 if ((retval=xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32))) != ERROR_OK)
1483 return retval;
1484 LOG_DEBUG("writing r%i with value 0x%8.8" PRIx32 "", i, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
1487 /* send PC */
1488 if ((retval=xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))) != ERROR_OK)
1489 return retval;
1490 LOG_DEBUG("writing PC with value 0x%8.8" PRIx32, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1492 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1494 /* registers are now invalid */
1495 if ((retval=armv4_5_invalidate_core_regs(target)) != ERROR_OK)
1496 return retval;
1498 /* wait for and process debug entry */
1499 if ((retval=xscale_debug_entry(target)) != ERROR_OK)
1500 return retval;
1502 LOG_DEBUG("disable single-step");
1503 if ((retval=xscale_disable_single_step(target)) != ERROR_OK)
1504 return retval;
1506 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1508 return ERROR_OK;
1511 int xscale_step(struct target_s *target, int current, uint32_t address, int handle_breakpoints)
1513 armv4_5_common_t *armv4_5 = target->arch_info;
1514 breakpoint_t *breakpoint = target->breakpoints;
1516 uint32_t current_pc;
1517 int retval;
1519 if (target->state != TARGET_HALTED)
1521 LOG_WARNING("target not halted");
1522 return ERROR_TARGET_NOT_HALTED;
1525 /* current = 1: continue on current pc, otherwise continue at <address> */
1526 if (!current)
1527 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, address);
1529 current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
1531 /* if we're at the reset vector, we have to simulate the step */
1532 if (current_pc == 0x0)
1534 if ((retval=arm_simulate_step(target, NULL)) != ERROR_OK)
1535 return retval;
1536 current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
1538 target->debug_reason = DBG_REASON_SINGLESTEP;
1539 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1541 return ERROR_OK;
1544 /* the front-end may request us not to handle breakpoints */
1545 if (handle_breakpoints)
1546 if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))))
1548 if ((retval=xscale_unset_breakpoint(target, breakpoint)) != ERROR_OK)
1549 return retval;
1552 retval = xscale_step_inner(target, current, address, handle_breakpoints);
1554 if (breakpoint)
1556 xscale_set_breakpoint(target, breakpoint);
1559 LOG_DEBUG("target stepped");
1561 return ERROR_OK;
1565 int xscale_assert_reset(target_t *target)
1567 armv4_5_common_t *armv4_5 = target->arch_info;
1568 xscale_common_t *xscale = armv4_5->arch_info;
1570 LOG_DEBUG("target->state: %s",
1571 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
1573 /* select DCSR instruction (set endstate to R-T-I to ensure we don't
1574 * end up in T-L-R, which would reset JTAG
1576 jtag_set_end_state(TAP_IDLE);
1577 xscale_jtag_set_instr(xscale->jtag_info.tap, xscale->jtag_info.dcsr);
1579 /* set Hold reset, Halt mode and Trap Reset */
1580 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
1581 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);
1582 xscale_write_dcsr(target, 1, 0);
1584 /* select BYPASS, because having DCSR selected caused problems on the PXA27x */
1585 xscale_jtag_set_instr(xscale->jtag_info.tap, 0x7f);
1586 jtag_execute_queue();
1588 /* assert reset */
1589 jtag_add_reset(0, 1);
1591 /* sleep 1ms, to be sure we fulfill any requirements */
1592 jtag_add_sleep(1000);
1593 jtag_execute_queue();
1595 target->state = TARGET_RESET;
1597 if (target->reset_halt)
1599 int retval;
1600 if ((retval = target_halt(target)) != ERROR_OK)
1601 return retval;
1604 return ERROR_OK;
1607 int xscale_deassert_reset(target_t *target)
1609 armv4_5_common_t *armv4_5 = target->arch_info;
1610 xscale_common_t *xscale = armv4_5->arch_info;
1612 fileio_t debug_handler;
1613 uint32_t address;
1614 uint32_t binary_size;
1616 uint32_t buf_cnt;
1617 uint32_t i;
1618 int retval;
1620 breakpoint_t *breakpoint = target->breakpoints;
1622 LOG_DEBUG("-");
1624 xscale->ibcr_available = 2;
1625 xscale->ibcr0_used = 0;
1626 xscale->ibcr1_used = 0;
1628 xscale->dbr_available = 2;
1629 xscale->dbr0_used = 0;
1630 xscale->dbr1_used = 0;
1632 /* mark all hardware breakpoints as unset */
1633 while (breakpoint)
1635 if (breakpoint->type == BKPT_HARD)
1637 breakpoint->set = 0;
1639 breakpoint = breakpoint->next;
1642 if (!xscale->handler_installed)
1644 /* release SRST */
1645 jtag_add_reset(0, 0);
1647 /* wait 300ms; 150 and 100ms were not enough */
1648 jtag_add_sleep(300*1000);
1650 jtag_add_runtest(2030, jtag_set_end_state(TAP_IDLE));
1651 jtag_execute_queue();
1653 /* set Hold reset, Halt mode and Trap Reset */
1654 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
1655 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);
1656 xscale_write_dcsr(target, 1, 0);
1658 /* Load debug handler */
1659 if (fileio_open(&debug_handler, "xscale/debug_handler.bin", FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
1661 return ERROR_OK;
1664 if ((binary_size = debug_handler.size) % 4)
1666 LOG_ERROR("debug_handler.bin: size not a multiple of 4");
1667 exit(-1);
1670 if (binary_size > 0x800)
1672 LOG_ERROR("debug_handler.bin: larger than 2kb");
1673 exit(-1);
1676 binary_size = CEIL(binary_size, 32) * 32;
1678 address = xscale->handler_address;
1679 while (binary_size > 0)
1681 uint32_t cache_line[8];
1682 uint8_t buffer[32];
1684 if ((retval = fileio_read(&debug_handler, 32, buffer, &buf_cnt)) != ERROR_OK)
1689 for (i = 0; i < buf_cnt; i += 4)
1691 /* convert LE buffer to host-endian uint32_t */
1692 cache_line[i / 4] = le_to_h_u32(&buffer[i]);
1695 for (; buf_cnt < 32; buf_cnt += 4)
1697 cache_line[buf_cnt / 4] = 0xe1a08008;
1700 /* only load addresses other than the reset vectors */
1701 if ((address % 0x400) != 0x0)
1703 xscale_load_ic(target, 1, address, cache_line);
1706 address += buf_cnt;
1707 binary_size -= buf_cnt;
1710 xscale_load_ic(target, 1, 0x0, xscale->low_vectors);
1711 xscale_load_ic(target, 1, 0xffff0000, xscale->high_vectors);
1713 jtag_add_runtest(30, jtag_set_end_state(TAP_IDLE));
1715 jtag_add_sleep(100000);
1717 /* set Hold reset, Halt mode and Trap Reset */
1718 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
1719 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);
1720 xscale_write_dcsr(target, 1, 0);
1722 /* clear Hold reset to let the target run (should enter debug handler) */
1723 xscale_write_dcsr(target, 0, 1);
1724 target->state = TARGET_RUNNING;
1726 if (!target->reset_halt)
1728 jtag_add_sleep(10000);
1730 /* we should have entered debug now */
1731 xscale_debug_entry(target);
1732 target->state = TARGET_HALTED;
1734 /* resume the target */
1735 xscale_resume(target, 1, 0x0, 1, 0);
1738 fileio_close(&debug_handler);
1740 else
1742 jtag_add_reset(0, 0);
1745 return ERROR_OK;
1748 int xscale_soft_reset_halt(struct target_s *target)
1750 return ERROR_OK;
1753 int xscale_read_core_reg(struct target_s *target, int num, enum armv4_5_mode mode)
1755 return ERROR_OK;
1758 int xscale_write_core_reg(struct target_s *target, int num, enum armv4_5_mode mode, uint32_t value)
1761 return ERROR_OK;
1764 int xscale_full_context(target_t *target)
1766 armv4_5_common_t *armv4_5 = target->arch_info;
1768 uint32_t *buffer;
1770 int i, j;
1772 LOG_DEBUG("-");
1774 if (target->state != TARGET_HALTED)
1776 LOG_WARNING("target not halted");
1777 return ERROR_TARGET_NOT_HALTED;
1780 buffer = malloc(4 * 8);
1782 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1783 * we can't enter User mode on an XScale (unpredictable),
1784 * but User shares registers with SYS
1786 for (i = 1; i < 7; i++)
1788 int valid = 1;
1790 /* check if there are invalid registers in the current mode
1792 for (j = 0; j <= 16; j++)
1794 if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).valid == 0)
1795 valid = 0;
1798 if (!valid)
1800 uint32_t tmp_cpsr;
1802 /* request banked registers */
1803 xscale_send_u32(target, 0x0);
1805 tmp_cpsr = 0x0;
1806 tmp_cpsr |= armv4_5_number_to_mode(i);
1807 tmp_cpsr |= 0xc0; /* I/F bits */
1809 /* send CPSR for desired mode */
1810 xscale_send_u32(target, tmp_cpsr);
1812 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1813 if ((armv4_5_number_to_mode(i) != ARMV4_5_MODE_USR) && (armv4_5_number_to_mode(i) != ARMV4_5_MODE_SYS))
1815 xscale_receive(target, buffer, 8);
1816 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32, buffer[7]);
1817 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty = 0;
1818 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).valid = 1;
1820 else
1822 xscale_receive(target, buffer, 7);
1825 /* move data from buffer to register cache */
1826 for (j = 8; j <= 14; j++)
1828 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]);
1829 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty = 0;
1830 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).valid = 1;
1835 free(buffer);
1837 return ERROR_OK;
1840 int xscale_restore_context(target_t *target)
1842 armv4_5_common_t *armv4_5 = target->arch_info;
1844 int i, j;
1846 LOG_DEBUG("-");
1848 if (target->state != TARGET_HALTED)
1850 LOG_WARNING("target not halted");
1851 return ERROR_TARGET_NOT_HALTED;
1854 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1855 * we can't enter User mode on an XScale (unpredictable),
1856 * but User shares registers with SYS
1858 for (i = 1; i < 7; i++)
1860 int dirty = 0;
1862 /* check if there are invalid registers in the current mode
1864 for (j = 8; j <= 14; j++)
1866 if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty == 1)
1867 dirty = 1;
1870 /* if not USR/SYS, check if the SPSR needs to be written */
1871 if ((armv4_5_number_to_mode(i) != ARMV4_5_MODE_USR) && (armv4_5_number_to_mode(i) != ARMV4_5_MODE_SYS))
1873 if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty == 1)
1874 dirty = 1;
1877 if (dirty)
1879 uint32_t tmp_cpsr;
1881 /* send banked registers */
1882 xscale_send_u32(target, 0x1);
1884 tmp_cpsr = 0x0;
1885 tmp_cpsr |= armv4_5_number_to_mode(i);
1886 tmp_cpsr |= 0xc0; /* I/F bits */
1888 /* send CPSR for desired mode */
1889 xscale_send_u32(target, tmp_cpsr);
1891 /* send banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1892 for (j = 8; j <= 14; j++)
1894 xscale_send_u32(target, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, j).value, 0, 32));
1895 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty = 0;
1898 if ((armv4_5_number_to_mode(i) != ARMV4_5_MODE_USR) && (armv4_5_number_to_mode(i) != ARMV4_5_MODE_SYS))
1900 xscale_send_u32(target, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32));
1901 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty = 0;
1906 return ERROR_OK;
1909 int xscale_read_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
1911 armv4_5_common_t *armv4_5 = target->arch_info;
1912 xscale_common_t *xscale = armv4_5->arch_info;
1913 uint32_t *buf32;
1914 uint32_t i;
1915 int retval;
1917 LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32, address, size, count);
1919 if (target->state != TARGET_HALTED)
1921 LOG_WARNING("target not halted");
1922 return ERROR_TARGET_NOT_HALTED;
1925 /* sanitize arguments */
1926 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1927 return ERROR_INVALID_ARGUMENTS;
1929 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
1930 return ERROR_TARGET_UNALIGNED_ACCESS;
1932 /* send memory read request (command 0x1n, n: access size) */
1933 if ((retval=xscale_send_u32(target, 0x10 | size)) != ERROR_OK)
1934 return retval;
1936 /* send base address for read request */
1937 if ((retval=xscale_send_u32(target, address)) != ERROR_OK)
1938 return retval;
1940 /* send number of requested data words */
1941 if ((retval=xscale_send_u32(target, count)) != ERROR_OK)
1942 return retval;
1944 /* receive data from target (count times 32-bit words in host endianness) */
1945 buf32 = malloc(4 * count);
1946 if ((retval=xscale_receive(target, buf32, count)) != ERROR_OK)
1947 return retval;
1949 /* extract data from host-endian buffer into byte stream */
1950 for (i = 0; i < count; i++)
1952 switch (size)
1954 case 4:
1955 target_buffer_set_u32(target, buffer, buf32[i]);
1956 buffer += 4;
1957 break;
1958 case 2:
1959 target_buffer_set_u16(target, buffer, buf32[i] & 0xffff);
1960 buffer += 2;
1961 break;
1962 case 1:
1963 *buffer++ = buf32[i] & 0xff;
1964 break;
1965 default:
1966 LOG_ERROR("should never get here");
1967 exit(-1);
1971 free(buf32);
1973 /* examine DCSR, to see if Sticky Abort (SA) got set */
1974 if ((retval=xscale_read_dcsr(target)) != ERROR_OK)
1975 return retval;
1976 if (buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 5, 1) == 1)
1978 /* clear SA bit */
1979 if ((retval=xscale_send_u32(target, 0x60)) != ERROR_OK)
1980 return retval;
1982 return ERROR_TARGET_DATA_ABORT;
1985 return ERROR_OK;
1988 int xscale_write_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
1990 armv4_5_common_t *armv4_5 = target->arch_info;
1991 xscale_common_t *xscale = armv4_5->arch_info;
1992 int retval;
1994 LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32, address, size, count);
1996 if (target->state != TARGET_HALTED)
1998 LOG_WARNING("target not halted");
1999 return ERROR_TARGET_NOT_HALTED;
2002 /* sanitize arguments */
2003 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
2004 return ERROR_INVALID_ARGUMENTS;
2006 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
2007 return ERROR_TARGET_UNALIGNED_ACCESS;
2009 /* send memory write request (command 0x2n, n: access size) */
2010 if ((retval=xscale_send_u32(target, 0x20 | size)) != ERROR_OK)
2011 return retval;
2013 /* send base address for read request */
2014 if ((retval=xscale_send_u32(target, address)) != ERROR_OK)
2015 return retval;
2017 /* send number of requested data words to be written*/
2018 if ((retval=xscale_send_u32(target, count)) != ERROR_OK)
2019 return retval;
2021 /* extract data from host-endian buffer into byte stream */
2022 #if 0
2023 for (i = 0; i < count; i++)
2025 switch (size)
2027 case 4:
2028 value = target_buffer_get_u32(target, buffer);
2029 xscale_send_u32(target, value);
2030 buffer += 4;
2031 break;
2032 case 2:
2033 value = target_buffer_get_u16(target, buffer);
2034 xscale_send_u32(target, value);
2035 buffer += 2;
2036 break;
2037 case 1:
2038 value = *buffer;
2039 xscale_send_u32(target, value);
2040 buffer += 1;
2041 break;
2042 default:
2043 LOG_ERROR("should never get here");
2044 exit(-1);
2047 #endif
2048 if ((retval=xscale_send(target, buffer, count, size)) != ERROR_OK)
2049 return retval;
2051 /* examine DCSR, to see if Sticky Abort (SA) got set */
2052 if ((retval=xscale_read_dcsr(target)) != ERROR_OK)
2053 return retval;
2054 if (buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 5, 1) == 1)
2056 /* clear SA bit */
2057 if ((retval=xscale_send_u32(target, 0x60)) != ERROR_OK)
2058 return retval;
2060 return ERROR_TARGET_DATA_ABORT;
2063 return ERROR_OK;
2066 int xscale_bulk_write_memory(target_t *target, uint32_t address, uint32_t count, uint8_t *buffer)
2068 return xscale_write_memory(target, address, 4, count, buffer);
2071 uint32_t xscale_get_ttb(target_t *target)
2073 armv4_5_common_t *armv4_5 = target->arch_info;
2074 xscale_common_t *xscale = armv4_5->arch_info;
2075 uint32_t ttb;
2077 xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_TTB]);
2078 ttb = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_TTB].value, 0, 32);
2080 return ttb;
2083 void xscale_disable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
2085 armv4_5_common_t *armv4_5 = target->arch_info;
2086 xscale_common_t *xscale = armv4_5->arch_info;
2087 uint32_t cp15_control;
2089 /* read cp15 control register */
2090 xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);
2091 cp15_control = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32);
2093 if (mmu)
2094 cp15_control &= ~0x1U;
2096 if (d_u_cache)
2098 /* clean DCache */
2099 xscale_send_u32(target, 0x50);
2100 xscale_send_u32(target, xscale->cache_clean_address);
2102 /* invalidate DCache */
2103 xscale_send_u32(target, 0x51);
2105 cp15_control &= ~0x4U;
2108 if (i_cache)
2110 /* invalidate ICache */
2111 xscale_send_u32(target, 0x52);
2112 cp15_control &= ~0x1000U;
2115 /* write new cp15 control register */
2116 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_CTRL], cp15_control);
2118 /* execute cpwait to ensure outstanding operations complete */
2119 xscale_send_u32(target, 0x53);
2122 void xscale_enable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
2124 armv4_5_common_t *armv4_5 = target->arch_info;
2125 xscale_common_t *xscale = armv4_5->arch_info;
2126 uint32_t cp15_control;
2128 /* read cp15 control register */
2129 xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);
2130 cp15_control = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32);
2132 if (mmu)
2133 cp15_control |= 0x1U;
2135 if (d_u_cache)
2136 cp15_control |= 0x4U;
2138 if (i_cache)
2139 cp15_control |= 0x1000U;
2141 /* write new cp15 control register */
2142 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_CTRL], cp15_control);
2144 /* execute cpwait to ensure outstanding operations complete */
2145 xscale_send_u32(target, 0x53);
2148 int xscale_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
2150 int retval;
2151 armv4_5_common_t *armv4_5 = target->arch_info;
2152 xscale_common_t *xscale = armv4_5->arch_info;
2154 if (target->state != TARGET_HALTED)
2156 LOG_WARNING("target not halted");
2157 return ERROR_TARGET_NOT_HALTED;
2160 if (breakpoint->set)
2162 LOG_WARNING("breakpoint already set");
2163 return ERROR_OK;
2166 if (breakpoint->type == BKPT_HARD)
2168 uint32_t value = breakpoint->address | 1;
2169 if (!xscale->ibcr0_used)
2171 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR0], value);
2172 xscale->ibcr0_used = 1;
2173 breakpoint->set = 1; /* breakpoint set on first breakpoint register */
2175 else if (!xscale->ibcr1_used)
2177 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR1], value);
2178 xscale->ibcr1_used = 1;
2179 breakpoint->set = 2; /* breakpoint set on second breakpoint register */
2181 else
2183 LOG_ERROR("BUG: no hardware comparator available");
2184 return ERROR_OK;
2187 else if (breakpoint->type == BKPT_SOFT)
2189 if (breakpoint->length == 4)
2191 /* keep the original instruction in target endianness */
2192 if ((retval = target_read_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr)) != ERROR_OK)
2194 return retval;
2196 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2197 if ((retval = target_write_u32(target, breakpoint->address, xscale->arm_bkpt)) != ERROR_OK)
2199 return retval;
2202 else
2204 /* keep the original instruction in target endianness */
2205 if ((retval = target_read_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr)) != ERROR_OK)
2207 return retval;
2209 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2210 if ((retval = target_write_u32(target, breakpoint->address, xscale->thumb_bkpt)) != ERROR_OK)
2212 return retval;
2215 breakpoint->set = 1;
2218 return ERROR_OK;
2221 int xscale_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
2223 armv4_5_common_t *armv4_5 = target->arch_info;
2224 xscale_common_t *xscale = armv4_5->arch_info;
2226 if (target->state != TARGET_HALTED)
2228 LOG_WARNING("target not halted");
2229 return ERROR_TARGET_NOT_HALTED;
2232 if ((breakpoint->type == BKPT_HARD) && (xscale->ibcr_available < 1))
2234 LOG_INFO("no breakpoint unit available for hardware breakpoint");
2235 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2238 if ((breakpoint->length != 2) && (breakpoint->length != 4))
2240 LOG_INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
2241 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2244 if (breakpoint->type == BKPT_HARD)
2246 xscale->ibcr_available--;
2249 return ERROR_OK;
2252 int xscale_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
2254 int retval;
2255 armv4_5_common_t *armv4_5 = target->arch_info;
2256 xscale_common_t *xscale = armv4_5->arch_info;
2258 if (target->state != TARGET_HALTED)
2260 LOG_WARNING("target not halted");
2261 return ERROR_TARGET_NOT_HALTED;
2264 if (!breakpoint->set)
2266 LOG_WARNING("breakpoint not set");
2267 return ERROR_OK;
2270 if (breakpoint->type == BKPT_HARD)
2272 if (breakpoint->set == 1)
2274 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR0], 0x0);
2275 xscale->ibcr0_used = 0;
2277 else if (breakpoint->set == 2)
2279 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR1], 0x0);
2280 xscale->ibcr1_used = 0;
2282 breakpoint->set = 0;
2284 else
2286 /* restore original instruction (kept in target endianness) */
2287 if (breakpoint->length == 4)
2289 if ((retval = target_write_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr)) != ERROR_OK)
2291 return retval;
2294 else
2296 if ((retval = target_write_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr)) != ERROR_OK)
2298 return retval;
2301 breakpoint->set = 0;
2304 return ERROR_OK;
2307 int xscale_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
2309 armv4_5_common_t *armv4_5 = target->arch_info;
2310 xscale_common_t *xscale = armv4_5->arch_info;
2312 if (target->state != TARGET_HALTED)
2314 LOG_WARNING("target not halted");
2315 return ERROR_TARGET_NOT_HALTED;
2318 if (breakpoint->set)
2320 xscale_unset_breakpoint(target, breakpoint);
2323 if (breakpoint->type == BKPT_HARD)
2324 xscale->ibcr_available++;
2326 return ERROR_OK;
2329 int xscale_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
2331 armv4_5_common_t *armv4_5 = target->arch_info;
2332 xscale_common_t *xscale = armv4_5->arch_info;
2333 uint8_t enable=0;
2334 reg_t *dbcon = &xscale->reg_cache->reg_list[XSCALE_DBCON];
2335 uint32_t dbcon_value = buf_get_u32(dbcon->value, 0, 32);
2337 if (target->state != TARGET_HALTED)
2339 LOG_WARNING("target not halted");
2340 return ERROR_TARGET_NOT_HALTED;
2343 xscale_get_reg(dbcon);
2345 switch (watchpoint->rw)
2347 case WPT_READ:
2348 enable = 0x3;
2349 break;
2350 case WPT_ACCESS:
2351 enable = 0x2;
2352 break;
2353 case WPT_WRITE:
2354 enable = 0x1;
2355 break;
2356 default:
2357 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
2360 if (!xscale->dbr0_used)
2362 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR0], watchpoint->address);
2363 dbcon_value |= enable;
2364 xscale_set_reg_u32(dbcon, dbcon_value);
2365 watchpoint->set = 1;
2366 xscale->dbr0_used = 1;
2368 else if (!xscale->dbr1_used)
2370 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR1], watchpoint->address);
2371 dbcon_value |= enable << 2;
2372 xscale_set_reg_u32(dbcon, dbcon_value);
2373 watchpoint->set = 2;
2374 xscale->dbr1_used = 1;
2376 else
2378 LOG_ERROR("BUG: no hardware comparator available");
2379 return ERROR_OK;
2382 return ERROR_OK;
2385 int xscale_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
2387 armv4_5_common_t *armv4_5 = target->arch_info;
2388 xscale_common_t *xscale = armv4_5->arch_info;
2390 if (target->state != TARGET_HALTED)
2392 LOG_WARNING("target not halted");
2393 return ERROR_TARGET_NOT_HALTED;
2396 if (xscale->dbr_available < 1)
2398 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2401 if ((watchpoint->length != 1) && (watchpoint->length != 2) && (watchpoint->length != 4))
2403 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2406 xscale->dbr_available--;
2408 return ERROR_OK;
2411 int xscale_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
2413 armv4_5_common_t *armv4_5 = target->arch_info;
2414 xscale_common_t *xscale = armv4_5->arch_info;
2415 reg_t *dbcon = &xscale->reg_cache->reg_list[XSCALE_DBCON];
2416 uint32_t dbcon_value = buf_get_u32(dbcon->value, 0, 32);
2418 if (target->state != TARGET_HALTED)
2420 LOG_WARNING("target not halted");
2421 return ERROR_TARGET_NOT_HALTED;
2424 if (!watchpoint->set)
2426 LOG_WARNING("breakpoint not set");
2427 return ERROR_OK;
2430 if (watchpoint->set == 1)
2432 dbcon_value &= ~0x3;
2433 xscale_set_reg_u32(dbcon, dbcon_value);
2434 xscale->dbr0_used = 0;
2436 else if (watchpoint->set == 2)
2438 dbcon_value &= ~0xc;
2439 xscale_set_reg_u32(dbcon, dbcon_value);
2440 xscale->dbr1_used = 0;
2442 watchpoint->set = 0;
2444 return ERROR_OK;
2447 int xscale_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
2449 armv4_5_common_t *armv4_5 = target->arch_info;
2450 xscale_common_t *xscale = armv4_5->arch_info;
2452 if (target->state != TARGET_HALTED)
2454 LOG_WARNING("target not halted");
2455 return ERROR_TARGET_NOT_HALTED;
2458 if (watchpoint->set)
2460 xscale_unset_watchpoint(target, watchpoint);
2463 xscale->dbr_available++;
2465 return ERROR_OK;
2468 void xscale_enable_watchpoints(struct target_s *target)
2470 watchpoint_t *watchpoint = target->watchpoints;
2472 while (watchpoint)
2474 if (watchpoint->set == 0)
2475 xscale_set_watchpoint(target, watchpoint);
2476 watchpoint = watchpoint->next;
2480 void xscale_enable_breakpoints(struct target_s *target)
2482 breakpoint_t *breakpoint = target->breakpoints;
2484 /* set any pending breakpoints */
2485 while (breakpoint)
2487 if (breakpoint->set == 0)
2488 xscale_set_breakpoint(target, breakpoint);
2489 breakpoint = breakpoint->next;
2493 int xscale_get_reg(reg_t *reg)
2495 xscale_reg_t *arch_info = reg->arch_info;
2496 target_t *target = arch_info->target;
2497 armv4_5_common_t *armv4_5 = target->arch_info;
2498 xscale_common_t *xscale = armv4_5->arch_info;
2500 /* DCSR, TX and RX are accessible via JTAG */
2501 if (strcmp(reg->name, "XSCALE_DCSR") == 0)
2503 return xscale_read_dcsr(arch_info->target);
2505 else if (strcmp(reg->name, "XSCALE_TX") == 0)
2507 /* 1 = consume register content */
2508 return xscale_read_tx(arch_info->target, 1);
2510 else if (strcmp(reg->name, "XSCALE_RX") == 0)
2512 /* can't read from RX register (host -> debug handler) */
2513 return ERROR_OK;
2515 else if (strcmp(reg->name, "XSCALE_TXRXCTRL") == 0)
2517 /* can't (explicitly) read from TXRXCTRL register */
2518 return ERROR_OK;
2520 else /* Other DBG registers have to be transfered by the debug handler */
2522 /* send CP read request (command 0x40) */
2523 xscale_send_u32(target, 0x40);
2525 /* send CP register number */
2526 xscale_send_u32(target, arch_info->dbg_handler_number);
2528 /* read register value */
2529 xscale_read_tx(target, 1);
2530 buf_cpy(xscale->reg_cache->reg_list[XSCALE_TX].value, reg->value, 32);
2532 reg->dirty = 0;
2533 reg->valid = 1;
2536 return ERROR_OK;
2539 int xscale_set_reg(reg_t *reg, uint8_t* buf)
2541 xscale_reg_t *arch_info = reg->arch_info;
2542 target_t *target = arch_info->target;
2543 armv4_5_common_t *armv4_5 = target->arch_info;
2544 xscale_common_t *xscale = armv4_5->arch_info;
2545 uint32_t value = buf_get_u32(buf, 0, 32);
2547 /* DCSR, TX and RX are accessible via JTAG */
2548 if (strcmp(reg->name, "XSCALE_DCSR") == 0)
2550 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 0, 32, value);
2551 return xscale_write_dcsr(arch_info->target, -1, -1);
2553 else if (strcmp(reg->name, "XSCALE_RX") == 0)
2555 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_RX].value, 0, 32, value);
2556 return xscale_write_rx(arch_info->target);
2558 else if (strcmp(reg->name, "XSCALE_TX") == 0)
2560 /* can't write to TX register (debug-handler -> host) */
2561 return ERROR_OK;
2563 else if (strcmp(reg->name, "XSCALE_TXRXCTRL") == 0)
2565 /* can't (explicitly) write to TXRXCTRL register */
2566 return ERROR_OK;
2568 else /* Other DBG registers have to be transfered by the debug handler */
2570 /* send CP write request (command 0x41) */
2571 xscale_send_u32(target, 0x41);
2573 /* send CP register number */
2574 xscale_send_u32(target, arch_info->dbg_handler_number);
2576 /* send CP register value */
2577 xscale_send_u32(target, value);
2578 buf_set_u32(reg->value, 0, 32, value);
2581 return ERROR_OK;
2584 /* convenience wrapper to access XScale specific registers */
2585 int xscale_set_reg_u32(reg_t *reg, uint32_t value)
2587 uint8_t buf[4];
2589 buf_set_u32(buf, 0, 32, value);
2591 return xscale_set_reg(reg, buf);
2594 int xscale_write_dcsr_sw(target_t *target, uint32_t value)
2596 /* get pointers to arch-specific information */
2597 armv4_5_common_t *armv4_5 = target->arch_info;
2598 xscale_common_t *xscale = armv4_5->arch_info;
2599 reg_t *dcsr = &xscale->reg_cache->reg_list[XSCALE_DCSR];
2600 xscale_reg_t *dcsr_arch_info = dcsr->arch_info;
2602 /* send CP write request (command 0x41) */
2603 xscale_send_u32(target, 0x41);
2605 /* send CP register number */
2606 xscale_send_u32(target, dcsr_arch_info->dbg_handler_number);
2608 /* send CP register value */
2609 xscale_send_u32(target, value);
2610 buf_set_u32(dcsr->value, 0, 32, value);
2612 return ERROR_OK;
2615 int xscale_read_trace(target_t *target)
2617 /* get pointers to arch-specific information */
2618 armv4_5_common_t *armv4_5 = target->arch_info;
2619 xscale_common_t *xscale = armv4_5->arch_info;
2620 xscale_trace_data_t **trace_data_p;
2622 /* 258 words from debug handler
2623 * 256 trace buffer entries
2624 * 2 checkpoint addresses
2626 uint32_t trace_buffer[258];
2627 int is_address[256];
2628 int i, j;
2630 if (target->state != TARGET_HALTED)
2632 LOG_WARNING("target must be stopped to read trace data");
2633 return ERROR_TARGET_NOT_HALTED;
2636 /* send read trace buffer command (command 0x61) */
2637 xscale_send_u32(target, 0x61);
2639 /* receive trace buffer content */
2640 xscale_receive(target, trace_buffer, 258);
2642 /* parse buffer backwards to identify address entries */
2643 for (i = 255; i >= 0; i--)
2645 is_address[i] = 0;
2646 if (((trace_buffer[i] & 0xf0) == 0x90) ||
2647 ((trace_buffer[i] & 0xf0) == 0xd0))
2649 if (i >= 3)
2650 is_address[--i] = 1;
2651 if (i >= 2)
2652 is_address[--i] = 1;
2653 if (i >= 1)
2654 is_address[--i] = 1;
2655 if (i >= 0)
2656 is_address[--i] = 1;
2661 /* search first non-zero entry */
2662 for (j = 0; (j < 256) && (trace_buffer[j] == 0) && (!is_address[j]); j++)
2665 if (j == 256)
2667 LOG_DEBUG("no trace data collected");
2668 return ERROR_XSCALE_NO_TRACE_DATA;
2671 for (trace_data_p = &xscale->trace.data; *trace_data_p; trace_data_p = &(*trace_data_p)->next)
2674 *trace_data_p = malloc(sizeof(xscale_trace_data_t));
2675 (*trace_data_p)->next = NULL;
2676 (*trace_data_p)->chkpt0 = trace_buffer[256];
2677 (*trace_data_p)->chkpt1 = trace_buffer[257];
2678 (*trace_data_p)->last_instruction = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
2679 (*trace_data_p)->entries = malloc(sizeof(xscale_trace_entry_t) * (256 - j));
2680 (*trace_data_p)->depth = 256 - j;
2682 for (i = j; i < 256; i++)
2684 (*trace_data_p)->entries[i - j].data = trace_buffer[i];
2685 if (is_address[i])
2686 (*trace_data_p)->entries[i - j].type = XSCALE_TRACE_ADDRESS;
2687 else
2688 (*trace_data_p)->entries[i - j].type = XSCALE_TRACE_MESSAGE;
2691 return ERROR_OK;
2694 int xscale_read_instruction(target_t *target, arm_instruction_t *instruction)
2696 /* get pointers to arch-specific information */
2697 armv4_5_common_t *armv4_5 = target->arch_info;
2698 xscale_common_t *xscale = armv4_5->arch_info;
2699 int i;
2700 int section = -1;
2701 uint32_t size_read;
2702 uint32_t opcode;
2703 int retval;
2705 if (!xscale->trace.image)
2706 return ERROR_TRACE_IMAGE_UNAVAILABLE;
2708 /* search for the section the current instruction belongs to */
2709 for (i = 0; i < xscale->trace.image->num_sections; i++)
2711 if ((xscale->trace.image->sections[i].base_address <= xscale->trace.current_pc) &&
2712 (xscale->trace.image->sections[i].base_address + xscale->trace.image->sections[i].size > xscale->trace.current_pc))
2714 section = i;
2715 break;
2719 if (section == -1)
2721 /* current instruction couldn't be found in the image */
2722 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
2725 if (xscale->trace.core_state == ARMV4_5_STATE_ARM)
2727 uint8_t buf[4];
2728 if ((retval = image_read_section(xscale->trace.image, section,
2729 xscale->trace.current_pc - xscale->trace.image->sections[section].base_address,
2730 4, buf, &size_read)) != ERROR_OK)
2732 LOG_ERROR("error while reading instruction: %i", retval);
2733 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
2735 opcode = target_buffer_get_u32(target, buf);
2736 arm_evaluate_opcode(opcode, xscale->trace.current_pc, instruction);
2738 else if (xscale->trace.core_state == ARMV4_5_STATE_THUMB)
2740 uint8_t buf[2];
2741 if ((retval = image_read_section(xscale->trace.image, section,
2742 xscale->trace.current_pc - xscale->trace.image->sections[section].base_address,
2743 2, buf, &size_read)) != ERROR_OK)
2745 LOG_ERROR("error while reading instruction: %i", retval);
2746 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
2748 opcode = target_buffer_get_u16(target, buf);
2749 thumb_evaluate_opcode(opcode, xscale->trace.current_pc, instruction);
2751 else
2753 LOG_ERROR("BUG: unknown core state encountered");
2754 exit(-1);
2757 return ERROR_OK;
2760 int xscale_branch_address(xscale_trace_data_t *trace_data, int i, uint32_t *target)
2762 /* if there are less than four entries prior to the indirect branch message
2763 * we can't extract the address */
2764 if (i < 4)
2766 return -1;
2769 *target = (trace_data->entries[i-1].data) | (trace_data->entries[i-2].data << 8) |
2770 (trace_data->entries[i-3].data << 16) | (trace_data->entries[i-4].data << 24);
2772 return 0;
2775 int xscale_analyze_trace(target_t *target, command_context_t *cmd_ctx)
2777 /* get pointers to arch-specific information */
2778 armv4_5_common_t *armv4_5 = target->arch_info;
2779 xscale_common_t *xscale = armv4_5->arch_info;
2780 int next_pc_ok = 0;
2781 uint32_t next_pc = 0x0;
2782 xscale_trace_data_t *trace_data = xscale->trace.data;
2783 int retval;
2785 while (trace_data)
2787 int i, chkpt;
2788 int rollover;
2789 int branch;
2790 int exception;
2791 xscale->trace.core_state = ARMV4_5_STATE_ARM;
2793 chkpt = 0;
2794 rollover = 0;
2796 for (i = 0; i < trace_data->depth; i++)
2798 next_pc_ok = 0;
2799 branch = 0;
2800 exception = 0;
2802 if (trace_data->entries[i].type == XSCALE_TRACE_ADDRESS)
2803 continue;
2805 switch ((trace_data->entries[i].data & 0xf0) >> 4)
2807 case 0: /* Exceptions */
2808 case 1:
2809 case 2:
2810 case 3:
2811 case 4:
2812 case 5:
2813 case 6:
2814 case 7:
2815 exception = (trace_data->entries[i].data & 0x70) >> 4;
2816 next_pc_ok = 1;
2817 next_pc = (trace_data->entries[i].data & 0xf0) >> 2;
2818 command_print(cmd_ctx, "--- exception %i ---", (trace_data->entries[i].data & 0xf0) >> 4);
2819 break;
2820 case 8: /* Direct Branch */
2821 branch = 1;
2822 break;
2823 case 9: /* Indirect Branch */
2824 branch = 1;
2825 if (xscale_branch_address(trace_data, i, &next_pc) == 0)
2827 next_pc_ok = 1;
2829 break;
2830 case 13: /* Checkpointed Indirect Branch */
2831 if (xscale_branch_address(trace_data, i, &next_pc) == 0)
2833 next_pc_ok = 1;
2834 if (((chkpt == 0) && (next_pc != trace_data->chkpt0))
2835 || ((chkpt == 1) && (next_pc != trace_data->chkpt1)))
2836 LOG_WARNING("checkpointed indirect branch target address doesn't match checkpoint");
2838 /* explicit fall-through */
2839 case 12: /* Checkpointed Direct Branch */
2840 branch = 1;
2841 if (chkpt == 0)
2843 next_pc_ok = 1;
2844 next_pc = trace_data->chkpt0;
2845 chkpt++;
2847 else if (chkpt == 1)
2849 next_pc_ok = 1;
2850 next_pc = trace_data->chkpt0;
2851 chkpt++;
2853 else
2855 LOG_WARNING("more than two checkpointed branches encountered");
2857 break;
2858 case 15: /* Roll-over */
2859 rollover++;
2860 continue;
2861 default: /* Reserved */
2862 command_print(cmd_ctx, "--- reserved trace message ---");
2863 LOG_ERROR("BUG: trace message %i is reserved", (trace_data->entries[i].data & 0xf0) >> 4);
2864 return ERROR_OK;
2867 if (xscale->trace.pc_ok)
2869 int executed = (trace_data->entries[i].data & 0xf) + rollover * 16;
2870 arm_instruction_t instruction;
2872 if ((exception == 6) || (exception == 7))
2874 /* IRQ or FIQ exception, no instruction executed */
2875 executed -= 1;
2878 while (executed-- >= 0)
2880 if ((retval = xscale_read_instruction(target, &instruction)) != ERROR_OK)
2882 /* can't continue tracing with no image available */
2883 if (retval == ERROR_TRACE_IMAGE_UNAVAILABLE)
2885 return retval;
2887 else if (retval == ERROR_TRACE_INSTRUCTION_UNAVAILABLE)
2889 /* TODO: handle incomplete images */
2893 /* a precise abort on a load to the PC is included in the incremental
2894 * word count, other instructions causing data aborts are not included
2896 if ((executed == 0) && (exception == 4)
2897 && ((instruction.type >= ARM_LDR) && (instruction.type <= ARM_LDM)))
2899 if ((instruction.type == ARM_LDM)
2900 && ((instruction.info.load_store_multiple.register_list & 0x8000) == 0))
2902 executed--;
2904 else if (((instruction.type >= ARM_LDR) && (instruction.type <= ARM_LDRSH))
2905 && (instruction.info.load_store.Rd != 15))
2907 executed--;
2911 /* only the last instruction executed
2912 * (the one that caused the control flow change)
2913 * could be a taken branch
2915 if (((executed == -1) && (branch == 1)) &&
2916 (((instruction.type == ARM_B) ||
2917 (instruction.type == ARM_BL) ||
2918 (instruction.type == ARM_BLX)) &&
2919 (instruction.info.b_bl_bx_blx.target_address != 0xffffffff)))
2921 xscale->trace.current_pc = instruction.info.b_bl_bx_blx.target_address;
2923 else
2925 xscale->trace.current_pc += (xscale->trace.core_state == ARMV4_5_STATE_ARM) ? 4 : 2;
2927 command_print(cmd_ctx, "%s", instruction.text);
2930 rollover = 0;
2933 if (next_pc_ok)
2935 xscale->trace.current_pc = next_pc;
2936 xscale->trace.pc_ok = 1;
2940 for (; xscale->trace.current_pc < trace_data->last_instruction; xscale->trace.current_pc += (xscale->trace.core_state == ARMV4_5_STATE_ARM) ? 4 : 2)
2942 arm_instruction_t instruction;
2943 if ((retval = xscale_read_instruction(target, &instruction)) != ERROR_OK)
2945 /* can't continue tracing with no image available */
2946 if (retval == ERROR_TRACE_IMAGE_UNAVAILABLE)
2948 return retval;
2950 else if (retval == ERROR_TRACE_INSTRUCTION_UNAVAILABLE)
2952 /* TODO: handle incomplete images */
2955 command_print(cmd_ctx, "%s", instruction.text);
2958 trace_data = trace_data->next;
2961 return ERROR_OK;
2964 void xscale_build_reg_cache(target_t *target)
2966 /* get pointers to arch-specific information */
2967 armv4_5_common_t *armv4_5 = target->arch_info;
2968 xscale_common_t *xscale = armv4_5->arch_info;
2970 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
2971 xscale_reg_t *arch_info = malloc(sizeof(xscale_reg_arch_info));
2972 int i;
2973 int num_regs = sizeof(xscale_reg_arch_info) / sizeof(xscale_reg_t);
2975 (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
2976 armv4_5->core_cache = (*cache_p);
2978 /* register a register arch-type for XScale dbg registers only once */
2979 if (xscale_reg_arch_type == -1)
2980 xscale_reg_arch_type = register_reg_arch_type(xscale_get_reg, xscale_set_reg);
2982 (*cache_p)->next = malloc(sizeof(reg_cache_t));
2983 cache_p = &(*cache_p)->next;
2985 /* fill in values for the xscale reg cache */
2986 (*cache_p)->name = "XScale registers";
2987 (*cache_p)->next = NULL;
2988 (*cache_p)->reg_list = malloc(num_regs * sizeof(reg_t));
2989 (*cache_p)->num_regs = num_regs;
2991 for (i = 0; i < num_regs; i++)
2993 (*cache_p)->reg_list[i].name = xscale_reg_list[i];
2994 (*cache_p)->reg_list[i].value = calloc(4, 1);
2995 (*cache_p)->reg_list[i].dirty = 0;
2996 (*cache_p)->reg_list[i].valid = 0;
2997 (*cache_p)->reg_list[i].size = 32;
2998 (*cache_p)->reg_list[i].bitfield_desc = NULL;
2999 (*cache_p)->reg_list[i].num_bitfields = 0;
3000 (*cache_p)->reg_list[i].arch_info = &arch_info[i];
3001 (*cache_p)->reg_list[i].arch_type = xscale_reg_arch_type;
3002 arch_info[i] = xscale_reg_arch_info[i];
3003 arch_info[i].target = target;
3006 xscale->reg_cache = (*cache_p);
3009 int xscale_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
3011 return ERROR_OK;
3014 int xscale_quit(void)
3016 return ERROR_OK;
3019 int xscale_init_arch_info(target_t *target, xscale_common_t *xscale, jtag_tap_t *tap, const char *variant)
3021 armv4_5_common_t *armv4_5;
3022 uint32_t high_reset_branch, low_reset_branch;
3023 int i;
3025 armv4_5 = &xscale->armv4_5_common;
3027 /* store architecture specfic data (none so far) */
3028 xscale->arch_info = NULL;
3029 xscale->common_magic = XSCALE_COMMON_MAGIC;
3031 /* remember the variant (PXA25x, PXA27x, IXP42x, ...) */
3032 xscale->variant = strdup(variant);
3034 /* prepare JTAG information for the new target */
3035 xscale->jtag_info.tap = tap;
3037 xscale->jtag_info.dbgrx = 0x02;
3038 xscale->jtag_info.dbgtx = 0x10;
3039 xscale->jtag_info.dcsr = 0x09;
3040 xscale->jtag_info.ldic = 0x07;
3042 if ((strcmp(xscale->variant, "pxa250") == 0) ||
3043 (strcmp(xscale->variant, "pxa255") == 0) ||
3044 (strcmp(xscale->variant, "pxa26x") == 0))
3046 xscale->jtag_info.ir_length = 5;
3048 else if ((strcmp(xscale->variant, "pxa27x") == 0) ||
3049 (strcmp(xscale->variant, "ixp42x") == 0) ||
3050 (strcmp(xscale->variant, "ixp45x") == 0) ||
3051 (strcmp(xscale->variant, "ixp46x") == 0))
3053 xscale->jtag_info.ir_length = 7;
3056 /* the debug handler isn't installed (and thus not running) at this time */
3057 xscale->handler_installed = 0;
3058 xscale->handler_running = 0;
3059 xscale->handler_address = 0xfe000800;
3061 /* clear the vectors we keep locally for reference */
3062 memset(xscale->low_vectors, 0, sizeof(xscale->low_vectors));
3063 memset(xscale->high_vectors, 0, sizeof(xscale->high_vectors));
3065 /* no user-specified vectors have been configured yet */
3066 xscale->static_low_vectors_set = 0x0;
3067 xscale->static_high_vectors_set = 0x0;
3069 /* calculate branches to debug handler */
3070 low_reset_branch = (xscale->handler_address + 0x20 - 0x0 - 0x8) >> 2;
3071 high_reset_branch = (xscale->handler_address + 0x20 - 0xffff0000 - 0x8) >> 2;
3073 xscale->low_vectors[0] = ARMV4_5_B((low_reset_branch & 0xffffff), 0);
3074 xscale->high_vectors[0] = ARMV4_5_B((high_reset_branch & 0xffffff), 0);
3076 for (i = 1; i <= 7; i++)
3078 xscale->low_vectors[i] = ARMV4_5_B(0xfffffe, 0);
3079 xscale->high_vectors[i] = ARMV4_5_B(0xfffffe, 0);
3082 /* 64kB aligned region used for DCache cleaning */
3083 xscale->cache_clean_address = 0xfffe0000;
3085 xscale->hold_rst = 0;
3086 xscale->external_debug_break = 0;
3088 xscale->ibcr_available = 2;
3089 xscale->ibcr0_used = 0;
3090 xscale->ibcr1_used = 0;
3092 xscale->dbr_available = 2;
3093 xscale->dbr0_used = 0;
3094 xscale->dbr1_used = 0;
3096 xscale->arm_bkpt = ARMV5_BKPT(0x0);
3097 xscale->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
3099 xscale->vector_catch = 0x1;
3101 xscale->trace.capture_status = TRACE_IDLE;
3102 xscale->trace.data = NULL;
3103 xscale->trace.image = NULL;
3104 xscale->trace.buffer_enabled = 0;
3105 xscale->trace.buffer_fill = 0;
3107 /* prepare ARMv4/5 specific information */
3108 armv4_5->arch_info = xscale;
3109 armv4_5->read_core_reg = xscale_read_core_reg;
3110 armv4_5->write_core_reg = xscale_write_core_reg;
3111 armv4_5->full_context = xscale_full_context;
3113 armv4_5_init_arch_info(target, armv4_5);
3115 xscale->armv4_5_mmu.armv4_5_cache.ctype = -1;
3116 xscale->armv4_5_mmu.get_ttb = xscale_get_ttb;
3117 xscale->armv4_5_mmu.read_memory = xscale_read_memory;
3118 xscale->armv4_5_mmu.write_memory = xscale_write_memory;
3119 xscale->armv4_5_mmu.disable_mmu_caches = xscale_disable_mmu_caches;
3120 xscale->armv4_5_mmu.enable_mmu_caches = xscale_enable_mmu_caches;
3121 xscale->armv4_5_mmu.has_tiny_pages = 1;
3122 xscale->armv4_5_mmu.mmu_enabled = 0;
3124 return ERROR_OK;
3127 /* target xscale <endianess> <startup_mode> <chain_pos> <variant> */
3128 int xscale_target_create(struct target_s *target, Jim_Interp *interp)
3130 xscale_common_t *xscale = calloc(1,sizeof(xscale_common_t));
3132 xscale_init_arch_info(target, xscale, target->tap, target->variant);
3133 xscale_build_reg_cache(target);
3135 return ERROR_OK;
3138 int xscale_handle_debug_handler_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3140 target_t *target = NULL;
3141 armv4_5_common_t *armv4_5;
3142 xscale_common_t *xscale;
3144 uint32_t handler_address;
3146 if (argc < 2)
3148 LOG_ERROR("'xscale debug_handler <target#> <address>' command takes two required operands");
3149 return ERROR_OK;
3152 if ((target = get_target(args[0])) == NULL)
3154 LOG_ERROR("target '%s' not defined", args[0]);
3155 return ERROR_FAIL;
3158 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3160 return ERROR_FAIL;
3163 handler_address = strtoul(args[1], NULL, 0);
3165 if (((handler_address >= 0x800) && (handler_address <= 0x1fef800)) ||
3166 ((handler_address >= 0xfe000800) && (handler_address <= 0xfffff800)))
3168 xscale->handler_address = handler_address;
3170 else
3172 LOG_ERROR("xscale debug_handler <address> must be between 0x800 and 0x1fef800 or between 0xfe000800 and 0xfffff800");
3173 return ERROR_FAIL;
3176 return ERROR_OK;
3179 int xscale_handle_cache_clean_address_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3181 target_t *target = NULL;
3182 armv4_5_common_t *armv4_5;
3183 xscale_common_t *xscale;
3185 uint32_t cache_clean_address;
3187 if (argc < 2)
3189 return ERROR_COMMAND_SYNTAX_ERROR;
3192 target = get_target(args[0]);
3193 if (target == NULL)
3195 LOG_ERROR("target '%s' not defined", args[0]);
3196 return ERROR_FAIL;
3199 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3201 return ERROR_FAIL;
3204 cache_clean_address = strtoul(args[1], NULL, 0);
3206 if (cache_clean_address & 0xffff)
3208 LOG_ERROR("xscale cache_clean_address <address> must be 64kb aligned");
3210 else
3212 xscale->cache_clean_address = cache_clean_address;
3215 return ERROR_OK;
3218 int xscale_handle_cache_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3220 target_t *target = get_current_target(cmd_ctx);
3221 armv4_5_common_t *armv4_5;
3222 xscale_common_t *xscale;
3224 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3226 return ERROR_OK;
3229 return armv4_5_handle_cache_info_command(cmd_ctx, &xscale->armv4_5_mmu.armv4_5_cache);
3232 static int xscale_virt2phys(struct target_s *target, uint32_t virtual, uint32_t *physical)
3234 armv4_5_common_t *armv4_5;
3235 xscale_common_t *xscale;
3236 int retval;
3237 int type;
3238 uint32_t cb;
3239 int domain;
3240 uint32_t ap;
3242 if ((retval = xscale_get_arch_pointers(target, &armv4_5, &xscale)) != ERROR_OK)
3244 return retval;
3246 uint32_t ret = armv4_5_mmu_translate_va(target, &xscale->armv4_5_mmu, virtual, &type, &cb, &domain, &ap);
3247 if (type == -1)
3249 return ret;
3251 *physical = ret;
3252 return ERROR_OK;
3255 static int xscale_mmu(struct target_s *target, int *enabled)
3257 armv4_5_common_t *armv4_5 = target->arch_info;
3258 xscale_common_t *xscale = armv4_5->arch_info;
3260 if (target->state != TARGET_HALTED)
3262 LOG_ERROR("Target not halted");
3263 return ERROR_TARGET_INVALID;
3265 *enabled = xscale->armv4_5_mmu.mmu_enabled;
3266 return ERROR_OK;
3269 int xscale_handle_mmu_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
3271 target_t *target = get_current_target(cmd_ctx);
3272 armv4_5_common_t *armv4_5;
3273 xscale_common_t *xscale;
3275 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3277 return ERROR_OK;
3280 if (target->state != TARGET_HALTED)
3282 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3283 return ERROR_OK;
3286 if (argc >= 1)
3288 if (strcmp("enable", args[0]) == 0)
3290 xscale_enable_mmu_caches(target, 1, 0, 0);
3291 xscale->armv4_5_mmu.mmu_enabled = 1;
3293 else if (strcmp("disable", args[0]) == 0)
3295 xscale_disable_mmu_caches(target, 1, 0, 0);
3296 xscale->armv4_5_mmu.mmu_enabled = 0;
3300 command_print(cmd_ctx, "mmu %s", (xscale->armv4_5_mmu.mmu_enabled) ? "enabled" : "disabled");
3302 return ERROR_OK;
3305 int xscale_handle_idcache_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
3307 target_t *target = get_current_target(cmd_ctx);
3308 armv4_5_common_t *armv4_5;
3309 xscale_common_t *xscale;
3310 int icache = 0, dcache = 0;
3312 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3314 return ERROR_OK;
3317 if (target->state != TARGET_HALTED)
3319 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3320 return ERROR_OK;
3323 if (strcmp(cmd, "icache") == 0)
3324 icache = 1;
3325 else if (strcmp(cmd, "dcache") == 0)
3326 dcache = 1;
3328 if (argc >= 1)
3330 if (strcmp("enable", args[0]) == 0)
3332 xscale_enable_mmu_caches(target, 0, dcache, icache);
3334 if (icache)
3335 xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 1;
3336 else if (dcache)
3337 xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 1;
3339 else if (strcmp("disable", args[0]) == 0)
3341 xscale_disable_mmu_caches(target, 0, dcache, icache);
3343 if (icache)
3344 xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
3345 else if (dcache)
3346 xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
3350 if (icache)
3351 command_print(cmd_ctx, "icache %s", (xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled) ? "enabled" : "disabled");
3353 if (dcache)
3354 command_print(cmd_ctx, "dcache %s", (xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) ? "enabled" : "disabled");
3356 return ERROR_OK;
3359 int xscale_handle_vector_catch_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
3361 target_t *target = get_current_target(cmd_ctx);
3362 armv4_5_common_t *armv4_5;
3363 xscale_common_t *xscale;
3365 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3367 return ERROR_OK;
3370 if (argc < 1)
3372 command_print(cmd_ctx, "usage: xscale vector_catch [mask]");
3374 else
3376 xscale->vector_catch = strtoul(args[0], NULL, 0);
3377 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 8, xscale->vector_catch);
3378 xscale_write_dcsr(target, -1, -1);
3381 command_print(cmd_ctx, "vector catch mask: 0x%2.2x", xscale->vector_catch);
3383 return ERROR_OK;
3387 int xscale_handle_trace_buffer_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3389 target_t *target = get_current_target(cmd_ctx);
3390 armv4_5_common_t *armv4_5;
3391 xscale_common_t *xscale;
3392 uint32_t dcsr_value;
3394 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3396 return ERROR_OK;
3399 if (target->state != TARGET_HALTED)
3401 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3402 return ERROR_OK;
3405 if ((argc >= 1) && (strcmp("enable", args[0]) == 0))
3407 xscale_trace_data_t *td, *next_td;
3408 xscale->trace.buffer_enabled = 1;
3410 /* free old trace data */
3411 td = xscale->trace.data;
3412 while (td)
3414 next_td = td->next;
3416 if (td->entries)
3417 free(td->entries);
3418 free(td);
3419 td = next_td;
3421 xscale->trace.data = NULL;
3423 else if ((argc >= 1) && (strcmp("disable", args[0]) == 0))
3425 xscale->trace.buffer_enabled = 0;
3428 if ((argc >= 2) && (strcmp("fill", args[1]) == 0))
3430 if (argc >= 3)
3431 xscale->trace.buffer_fill = strtoul(args[2], NULL, 0);
3432 else
3433 xscale->trace.buffer_fill = 1;
3435 else if ((argc >= 2) && (strcmp("wrap", args[1]) == 0))
3437 xscale->trace.buffer_fill = -1;
3440 if (xscale->trace.buffer_enabled)
3442 /* if we enable the trace buffer in fill-once
3443 * mode we know the address of the first instruction */
3444 xscale->trace.pc_ok = 1;
3445 xscale->trace.current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
3447 else
3449 /* otherwise the address is unknown, and we have no known good PC */
3450 xscale->trace.pc_ok = 0;
3453 command_print(cmd_ctx, "trace buffer %s (%s)",
3454 (xscale->trace.buffer_enabled) ? "enabled" : "disabled",
3455 (xscale->trace.buffer_fill > 0) ? "fill" : "wrap");
3457 dcsr_value = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 0, 32);
3458 if (xscale->trace.buffer_fill >= 0)
3459 xscale_write_dcsr_sw(target, (dcsr_value & 0xfffffffc) | 2);
3460 else
3461 xscale_write_dcsr_sw(target, dcsr_value & 0xfffffffc);
3463 return ERROR_OK;
3466 int xscale_handle_trace_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3468 target_t *target;
3469 armv4_5_common_t *armv4_5;
3470 xscale_common_t *xscale;
3472 if (argc < 1)
3474 command_print(cmd_ctx, "usage: xscale trace_image <file> [base address] [type]");
3475 return ERROR_OK;
3478 target = get_current_target(cmd_ctx);
3480 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3482 return ERROR_OK;
3485 if (xscale->trace.image)
3487 image_close(xscale->trace.image);
3488 free(xscale->trace.image);
3489 command_print(cmd_ctx, "previously loaded image found and closed");
3492 xscale->trace.image = malloc(sizeof(image_t));
3493 xscale->trace.image->base_address_set = 0;
3494 xscale->trace.image->start_address_set = 0;
3496 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
3497 if (argc >= 2)
3499 xscale->trace.image->base_address_set = 1;
3500 xscale->trace.image->base_address = strtoul(args[1], NULL, 0);
3502 else
3504 xscale->trace.image->base_address_set = 0;
3507 if (image_open(xscale->trace.image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
3509 free(xscale->trace.image);
3510 xscale->trace.image = NULL;
3511 return ERROR_OK;
3514 return ERROR_OK;
3517 int xscale_handle_dump_trace_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3519 target_t *target = get_current_target(cmd_ctx);
3520 armv4_5_common_t *armv4_5;
3521 xscale_common_t *xscale;
3522 xscale_trace_data_t *trace_data;
3523 fileio_t file;
3525 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3527 return ERROR_OK;
3530 if (target->state != TARGET_HALTED)
3532 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3533 return ERROR_OK;
3536 if (argc < 1)
3538 command_print(cmd_ctx, "usage: xscale dump_trace <file>");
3539 return ERROR_OK;
3542 trace_data = xscale->trace.data;
3544 if (!trace_data)
3546 command_print(cmd_ctx, "no trace data collected");
3547 return ERROR_OK;
3550 if (fileio_open(&file, args[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)
3552 return ERROR_OK;
3555 while (trace_data)
3557 int i;
3559 fileio_write_u32(&file, trace_data->chkpt0);
3560 fileio_write_u32(&file, trace_data->chkpt1);
3561 fileio_write_u32(&file, trace_data->last_instruction);
3562 fileio_write_u32(&file, trace_data->depth);
3564 for (i = 0; i < trace_data->depth; i++)
3565 fileio_write_u32(&file, trace_data->entries[i].data | ((trace_data->entries[i].type & 0xffff) << 16));
3567 trace_data = trace_data->next;
3570 fileio_close(&file);
3572 return ERROR_OK;
3575 int xscale_handle_analyze_trace_buffer_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3577 target_t *target = get_current_target(cmd_ctx);
3578 armv4_5_common_t *armv4_5;
3579 xscale_common_t *xscale;
3581 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3583 return ERROR_OK;
3586 xscale_analyze_trace(target, cmd_ctx);
3588 return ERROR_OK;
3591 int xscale_handle_cp15(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
3593 target_t *target = get_current_target(cmd_ctx);
3594 armv4_5_common_t *armv4_5;
3595 xscale_common_t *xscale;
3597 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3599 return ERROR_OK;
3602 if (target->state != TARGET_HALTED)
3604 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3605 return ERROR_OK;
3607 uint32_t reg_no = 0;
3608 reg_t *reg = NULL;
3609 if (argc > 0)
3611 reg_no = strtoul(args[0], NULL, 0);
3612 /*translate from xscale cp15 register no to openocd register*/
3613 switch (reg_no)
3615 case 0:
3616 reg_no = XSCALE_MAINID;
3617 break;
3618 case 1:
3619 reg_no = XSCALE_CTRL;
3620 break;
3621 case 2:
3622 reg_no = XSCALE_TTB;
3623 break;
3624 case 3:
3625 reg_no = XSCALE_DAC;
3626 break;
3627 case 5:
3628 reg_no = XSCALE_FSR;
3629 break;
3630 case 6:
3631 reg_no = XSCALE_FAR;
3632 break;
3633 case 13:
3634 reg_no = XSCALE_PID;
3635 break;
3636 case 15:
3637 reg_no = XSCALE_CPACCESS;
3638 break;
3639 default:
3640 command_print(cmd_ctx, "invalid register number");
3641 return ERROR_INVALID_ARGUMENTS;
3643 reg = &xscale->reg_cache->reg_list[reg_no];
3646 if (argc == 1)
3648 uint32_t value;
3650 /* read cp15 control register */
3651 xscale_get_reg(reg);
3652 value = buf_get_u32(reg->value, 0, 32);
3653 command_print(cmd_ctx, "%s (/%i): 0x%" PRIx32 "", reg->name, (int)(reg->size), value);
3655 else if (argc == 2)
3658 uint32_t value = strtoul(args[1], NULL, 0);
3660 /* send CP write request (command 0x41) */
3661 xscale_send_u32(target, 0x41);
3663 /* send CP register number */
3664 xscale_send_u32(target, reg_no);
3666 /* send CP register value */
3667 xscale_send_u32(target, value);
3669 /* execute cpwait to ensure outstanding operations complete */
3670 xscale_send_u32(target, 0x53);
3672 else
3674 command_print(cmd_ctx, "usage: cp15 [register]<, [value]>");
3677 return ERROR_OK;
3680 int xscale_register_commands(struct command_context_s *cmd_ctx)
3682 command_t *xscale_cmd;
3684 xscale_cmd = register_command(cmd_ctx, NULL, "xscale", NULL, COMMAND_ANY, "xscale specific commands");
3686 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");
3687 register_command(cmd_ctx, xscale_cmd, "cache_clean_address", xscale_handle_cache_clean_address_command, COMMAND_ANY, NULL);
3689 register_command(cmd_ctx, xscale_cmd, "cache_info", xscale_handle_cache_info_command, COMMAND_EXEC, NULL);
3690 register_command(cmd_ctx, xscale_cmd, "mmu", xscale_handle_mmu_command, COMMAND_EXEC, "['enable'|'disable'] the MMU");
3691 register_command(cmd_ctx, xscale_cmd, "icache", xscale_handle_idcache_command, COMMAND_EXEC, "['enable'|'disable'] the ICache");
3692 register_command(cmd_ctx, xscale_cmd, "dcache", xscale_handle_idcache_command, COMMAND_EXEC, "['enable'|'disable'] the DCache");
3694 register_command(cmd_ctx, xscale_cmd, "vector_catch", xscale_handle_vector_catch_command, COMMAND_EXEC, "<mask> of vectors that should be catched");
3696 register_command(cmd_ctx, xscale_cmd, "trace_buffer", xscale_handle_trace_buffer_command, COMMAND_EXEC, "<enable|disable> ['fill' [n]|'wrap']");
3698 register_command(cmd_ctx, xscale_cmd, "dump_trace", xscale_handle_dump_trace_command, COMMAND_EXEC, "dump content of trace buffer to <file>");
3699 register_command(cmd_ctx, xscale_cmd, "analyze_trace", xscale_handle_analyze_trace_buffer_command, COMMAND_EXEC, "analyze content of trace buffer");
3700 register_command(cmd_ctx, xscale_cmd, "trace_image", xscale_handle_trace_image_command,
3701 COMMAND_EXEC, "load image from <file> [base address]");
3703 register_command(cmd_ctx, xscale_cmd, "cp15", xscale_handle_cp15, COMMAND_EXEC, "access coproc 15 <register> [value]");
3705 armv4_5_register_commands(cmd_ctx);
3707 return ERROR_OK;