1 /***************************************************************************
2 * Copyright (C) 2006, 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2007,2008 Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
8 * Copyright (C) 2009 Michael Schwingen *
9 * michael@schwingen.org *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 ***************************************************************************/
31 #include "target_type.h"
32 #include "arm7_9_common.h"
33 #include "arm_simulator.h"
34 #include "arm_disassembler.h"
35 #include "time_support.h"
40 * Important XScale documents available as of October 2009 include:
42 * Intel XScale® Core Developer’s Manual, January 2004
43 * Order Number: 273473-002
44 * This has a chapter detailing debug facilities, and punts some
45 * details to chip-specific microarchitecture documents.
47 * Hot-Debug for Intel XScale® Core Debug White Paper, May 2005
48 * Document Number: 273539-005
49 * Less detailed than the developer's manual, but summarizes those
50 * missing details (for most XScales) and gives LOTS of notes about
51 * debugger/handler interaction issues. Presents a simpler reset
52 * and load-handler sequence than the arch doc. (Note, OpenOCD
53 * doesn't currently support "Hot-Debug" as defined there.)
55 * Chip-specific microarchitecture documents may also be useful.
59 /* forward declarations */
60 static int xscale_resume(struct target_s
*, int current
,
61 uint32_t address
, int handle_breakpoints
, int debug_execution
);
62 static int xscale_debug_entry(target_t
*);
63 static int xscale_restore_context(target_t
*);
64 static int xscale_get_reg(reg_t
*reg
);
65 static int xscale_set_reg(reg_t
*reg
, uint8_t *buf
);
66 static int xscale_set_breakpoint(struct target_s
*, breakpoint_t
*);
67 static int xscale_set_watchpoint(struct target_s
*, watchpoint_t
*);
68 static int xscale_unset_breakpoint(struct target_s
*, breakpoint_t
*);
69 static int xscale_read_trace(target_t
*);
72 /* This XScale "debug handler" is loaded into the processor's
73 * mini-ICache, which is 2K of code writable only via JTAG.
75 * FIXME the OpenOCD "bin2char" utility currently doesn't handle
76 * binary files cleanly. It's string oriented, and terminates them
77 * with a NUL character. Better would be to generate the constants
78 * and let other code decide names, scoping, and other housekeeping.
80 static /* unsigned const char xscale_debug_handler[] = ... */
81 #include "xscale_debug.h"
83 static char *const xscale_reg_list
[] =
85 "XSCALE_MAINID", /* 0 */
95 "XSCALE_IBCR0", /* 10 */
105 "XSCALE_RX", /* 20 */
109 static const xscale_reg_t xscale_reg_arch_info
[] =
111 {XSCALE_MAINID
, NULL
},
112 {XSCALE_CACHETYPE
, NULL
},
114 {XSCALE_AUXCTRL
, NULL
},
120 {XSCALE_CPACCESS
, NULL
},
121 {XSCALE_IBCR0
, NULL
},
122 {XSCALE_IBCR1
, NULL
},
125 {XSCALE_DBCON
, NULL
},
126 {XSCALE_TBREG
, NULL
},
127 {XSCALE_CHKPT0
, NULL
},
128 {XSCALE_CHKPT1
, NULL
},
129 {XSCALE_DCSR
, NULL
}, /* DCSR accessed via JTAG or SW */
130 {-1, NULL
}, /* TX accessed via JTAG */
131 {-1, NULL
}, /* RX accessed via JTAG */
132 {-1, NULL
}, /* TXRXCTRL implicit access via JTAG */
135 static int xscale_reg_arch_type
= -1;
137 /* convenience wrapper to access XScale specific registers */
138 static int xscale_set_reg_u32(reg_t
*reg
, uint32_t value
)
142 buf_set_u32(buf
, 0, 32, value
);
144 return xscale_set_reg(reg
, buf
);
148 static int xscale_get_arch_pointers(target_t
*target
,
149 armv4_5_common_t
**armv4_5_p
, xscale_common_t
**xscale_p
)
151 armv4_5_common_t
*armv4_5
= target
->arch_info
;
152 xscale_common_t
*xscale
= armv4_5
->arch_info
;
154 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
156 LOG_ERROR("target isn't an XScale target");
160 if (xscale
->common_magic
!= XSCALE_COMMON_MAGIC
)
162 LOG_ERROR("target isn't an XScale target");
166 *armv4_5_p
= armv4_5
;
172 static int xscale_jtag_set_instr(jtag_tap_t
*tap
, uint32_t new_instr
)
177 if (buf_get_u32(tap
->cur_instr
, 0, tap
->ir_length
) != new_instr
)
182 memset(&field
, 0, sizeof field
);
184 field
.num_bits
= tap
->ir_length
;
185 field
.out_value
= scratch
;
186 buf_set_u32(field
.out_value
, 0, field
.num_bits
, new_instr
);
188 jtag_add_ir_scan(1, &field
, jtag_get_end_state());
194 static int xscale_read_dcsr(target_t
*target
)
196 armv4_5_common_t
*armv4_5
= target
->arch_info
;
197 xscale_common_t
*xscale
= armv4_5
->arch_info
;
199 scan_field_t fields
[3];
200 uint8_t field0
= 0x0;
201 uint8_t field0_check_value
= 0x2;
202 uint8_t field0_check_mask
= 0x7;
203 uint8_t field2
= 0x0;
204 uint8_t field2_check_value
= 0x0;
205 uint8_t field2_check_mask
= 0x1;
207 jtag_set_end_state(TAP_DRPAUSE
);
208 xscale_jtag_set_instr(target
->tap
, XSCALE_SELDCSR
);
210 buf_set_u32(&field0
, 1, 1, xscale
->hold_rst
);
211 buf_set_u32(&field0
, 2, 1, xscale
->external_debug_break
);
213 memset(&fields
, 0, sizeof fields
);
215 fields
[0].tap
= target
->tap
;
216 fields
[0].num_bits
= 3;
217 fields
[0].out_value
= &field0
;
219 fields
[0].in_value
= &tmp
;
221 fields
[1].tap
= target
->tap
;
222 fields
[1].num_bits
= 32;
223 fields
[1].in_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
225 fields
[2].tap
= target
->tap
;
226 fields
[2].num_bits
= 1;
227 fields
[2].out_value
= &field2
;
229 fields
[2].in_value
= &tmp2
;
231 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
233 jtag_check_value_mask(fields
+ 0, &field0_check_value
, &field0_check_mask
);
234 jtag_check_value_mask(fields
+ 2, &field2_check_value
, &field2_check_mask
);
236 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
238 LOG_ERROR("JTAG error while reading DCSR");
242 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].dirty
= 0;
243 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].valid
= 1;
245 /* write the register with the value we just read
246 * on this second pass, only the first bit of field0 is guaranteed to be 0)
248 field0_check_mask
= 0x1;
249 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
250 fields
[1].in_value
= NULL
;
252 jtag_set_end_state(TAP_IDLE
);
254 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
256 /* DANGER!!! this must be here. It will make sure that the arguments
257 * to jtag_set_check_value() does not go out of scope! */
258 return jtag_execute_queue();
262 static void xscale_getbuf(jtag_callback_data_t arg
)
264 uint8_t *in
= (uint8_t *)arg
;
265 *((uint32_t *)in
) = buf_get_u32(in
, 0, 32);
268 static int xscale_receive(target_t
*target
, uint32_t *buffer
, int num_words
)
271 return ERROR_INVALID_ARGUMENTS
;
273 int retval
= ERROR_OK
;
275 scan_field_t fields
[3];
276 uint8_t *field0
= malloc(num_words
* 1);
277 uint8_t field0_check_value
= 0x2;
278 uint8_t field0_check_mask
= 0x6;
279 uint32_t *field1
= malloc(num_words
* 4);
280 uint8_t field2_check_value
= 0x0;
281 uint8_t field2_check_mask
= 0x1;
283 int words_scheduled
= 0;
286 path
[0] = TAP_DRSELECT
;
287 path
[1] = TAP_DRCAPTURE
;
288 path
[2] = TAP_DRSHIFT
;
290 memset(&fields
, 0, sizeof fields
);
292 fields
[0].tap
= target
->tap
;
293 fields
[0].num_bits
= 3;
294 fields
[0].check_value
= &field0_check_value
;
295 fields
[0].check_mask
= &field0_check_mask
;
297 fields
[1].tap
= target
->tap
;
298 fields
[1].num_bits
= 32;
300 fields
[2].tap
= target
->tap
;
301 fields
[2].num_bits
= 1;
302 fields
[2].check_value
= &field2_check_value
;
303 fields
[2].check_mask
= &field2_check_mask
;
305 jtag_set_end_state(TAP_IDLE
);
306 xscale_jtag_set_instr(target
->tap
, XSCALE_DBGTX
);
307 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 */
309 /* repeat until all words have been collected */
311 while (words_done
< num_words
)
315 for (i
= words_done
; i
< num_words
; i
++)
317 fields
[0].in_value
= &field0
[i
];
319 jtag_add_pathmove(3, path
);
321 fields
[1].in_value
= (uint8_t *)(field1
+ i
);
323 jtag_add_dr_scan_check(3, fields
, jtag_set_end_state(TAP_IDLE
));
325 jtag_add_callback(xscale_getbuf
, (jtag_callback_data_t
)(field1
+ i
));
330 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
332 LOG_ERROR("JTAG error while receiving data from debug handler");
336 /* examine results */
337 for (i
= words_done
; i
< num_words
; i
++)
339 if (!(field0
[0] & 1))
341 /* move backwards if necessary */
343 for (j
= i
; j
< num_words
- 1; j
++)
345 field0
[j
] = field0
[j
+ 1];
346 field1
[j
] = field1
[j
+ 1];
351 if (words_scheduled
== 0)
353 if (attempts
++==1000)
355 LOG_ERROR("Failed to receiving data from debug handler after 1000 attempts");
356 retval
= ERROR_TARGET_TIMEOUT
;
361 words_done
+= words_scheduled
;
364 for (i
= 0; i
< num_words
; i
++)
365 *(buffer
++) = buf_get_u32((uint8_t*)&field1
[i
], 0, 32);
372 static int xscale_read_tx(target_t
*target
, int consume
)
374 armv4_5_common_t
*armv4_5
= target
->arch_info
;
375 xscale_common_t
*xscale
= armv4_5
->arch_info
;
377 tap_state_t noconsume_path
[6];
379 struct timeval timeout
, now
;
380 scan_field_t fields
[3];
381 uint8_t field0_in
= 0x0;
382 uint8_t field0_check_value
= 0x2;
383 uint8_t field0_check_mask
= 0x6;
384 uint8_t field2_check_value
= 0x0;
385 uint8_t field2_check_mask
= 0x1;
387 jtag_set_end_state(TAP_IDLE
);
389 xscale_jtag_set_instr(target
->tap
, XSCALE_DBGTX
);
391 path
[0] = TAP_DRSELECT
;
392 path
[1] = TAP_DRCAPTURE
;
393 path
[2] = TAP_DRSHIFT
;
395 noconsume_path
[0] = TAP_DRSELECT
;
396 noconsume_path
[1] = TAP_DRCAPTURE
;
397 noconsume_path
[2] = TAP_DREXIT1
;
398 noconsume_path
[3] = TAP_DRPAUSE
;
399 noconsume_path
[4] = TAP_DREXIT2
;
400 noconsume_path
[5] = TAP_DRSHIFT
;
402 memset(&fields
, 0, sizeof fields
);
404 fields
[0].tap
= target
->tap
;
405 fields
[0].num_bits
= 3;
406 fields
[0].in_value
= &field0_in
;
408 fields
[1].tap
= target
->tap
;
409 fields
[1].num_bits
= 32;
410 fields
[1].in_value
= xscale
->reg_cache
->reg_list
[XSCALE_TX
].value
;
412 fields
[2].tap
= target
->tap
;
413 fields
[2].num_bits
= 1;
415 fields
[2].in_value
= &tmp
;
417 gettimeofday(&timeout
, NULL
);
418 timeval_add_time(&timeout
, 1, 0);
422 /* if we want to consume the register content (i.e. clear TX_READY),
423 * we have to go straight from Capture-DR to Shift-DR
424 * otherwise, we go from Capture-DR to Exit1-DR to Pause-DR
427 jtag_add_pathmove(3, path
);
430 jtag_add_pathmove(sizeof(noconsume_path
)/sizeof(*noconsume_path
), noconsume_path
);
433 jtag_add_dr_scan(3, fields
, jtag_set_end_state(TAP_IDLE
));
435 jtag_check_value_mask(fields
+ 0, &field0_check_value
, &field0_check_mask
);
436 jtag_check_value_mask(fields
+ 2, &field2_check_value
, &field2_check_mask
);
438 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
440 LOG_ERROR("JTAG error while reading TX");
441 return ERROR_TARGET_TIMEOUT
;
444 gettimeofday(&now
, NULL
);
445 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
)&& (now
.tv_usec
> timeout
.tv_usec
)))
447 LOG_ERROR("time out reading TX register");
448 return ERROR_TARGET_TIMEOUT
;
450 if (!((!(field0_in
& 1)) && consume
))
454 if (debug_level
>= 3)
456 LOG_DEBUG("waiting 100ms");
457 alive_sleep(100); /* avoid flooding the logs */
465 if (!(field0_in
& 1))
466 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
471 static int xscale_write_rx(target_t
*target
)
473 armv4_5_common_t
*armv4_5
= target
->arch_info
;
474 xscale_common_t
*xscale
= armv4_5
->arch_info
;
476 struct timeval timeout
, now
;
477 scan_field_t fields
[3];
478 uint8_t field0_out
= 0x0;
479 uint8_t field0_in
= 0x0;
480 uint8_t field0_check_value
= 0x2;
481 uint8_t field0_check_mask
= 0x6;
482 uint8_t field2
= 0x0;
483 uint8_t field2_check_value
= 0x0;
484 uint8_t field2_check_mask
= 0x1;
486 jtag_set_end_state(TAP_IDLE
);
488 xscale_jtag_set_instr(target
->tap
, XSCALE_DBGRX
);
490 memset(&fields
, 0, sizeof fields
);
492 fields
[0].tap
= target
->tap
;
493 fields
[0].num_bits
= 3;
494 fields
[0].out_value
= &field0_out
;
495 fields
[0].in_value
= &field0_in
;
497 fields
[1].tap
= target
->tap
;
498 fields
[1].num_bits
= 32;
499 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
;
501 fields
[2].tap
= target
->tap
;
502 fields
[2].num_bits
= 1;
503 fields
[2].out_value
= &field2
;
505 fields
[2].in_value
= &tmp
;
507 gettimeofday(&timeout
, NULL
);
508 timeval_add_time(&timeout
, 1, 0);
510 /* poll until rx_read is low */
511 LOG_DEBUG("polling RX");
514 jtag_add_dr_scan(3, fields
, jtag_set_end_state(TAP_IDLE
));
516 jtag_check_value_mask(fields
+ 0, &field0_check_value
, &field0_check_mask
);
517 jtag_check_value_mask(fields
+ 2, &field2_check_value
, &field2_check_mask
);
519 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
521 LOG_ERROR("JTAG error while writing RX");
525 gettimeofday(&now
, NULL
);
526 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
)&& (now
.tv_usec
> timeout
.tv_usec
)))
528 LOG_ERROR("time out writing RX register");
529 return ERROR_TARGET_TIMEOUT
;
531 if (!(field0_in
& 1))
533 if (debug_level
>= 3)
535 LOG_DEBUG("waiting 100ms");
536 alive_sleep(100); /* avoid flooding the logs */
546 jtag_add_dr_scan(3, fields
, jtag_set_end_state(TAP_IDLE
));
548 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
550 LOG_ERROR("JTAG error while writing RX");
557 /* send count elements of size byte to the debug handler */
558 static int xscale_send(target_t
*target
, uint8_t *buffer
, int count
, int size
)
565 jtag_set_end_state(TAP_IDLE
);
567 xscale_jtag_set_instr(target
->tap
, XSCALE_DBGRX
);
574 int endianness
= target
->endianness
;
575 while (done_count
++ < count
)
580 if (endianness
== TARGET_LITTLE_ENDIAN
)
582 t
[1]=le_to_h_u32(buffer
);
585 t
[1]=be_to_h_u32(buffer
);
589 if (endianness
== TARGET_LITTLE_ENDIAN
)
591 t
[1]=le_to_h_u16(buffer
);
594 t
[1]=be_to_h_u16(buffer
);
601 LOG_ERROR("BUG: size neither 4, 2 nor 1");
604 jtag_add_dr_out(target
->tap
,
608 jtag_set_end_state(TAP_IDLE
));
612 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
614 LOG_ERROR("JTAG error while sending data to debug handler");
621 static int xscale_send_u32(target_t
*target
, uint32_t value
)
623 armv4_5_common_t
*armv4_5
= target
->arch_info
;
624 xscale_common_t
*xscale
= armv4_5
->arch_info
;
626 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
627 return xscale_write_rx(target
);
630 static int xscale_write_dcsr(target_t
*target
, int hold_rst
, int ext_dbg_brk
)
632 armv4_5_common_t
*armv4_5
= target
->arch_info
;
633 xscale_common_t
*xscale
= armv4_5
->arch_info
;
635 scan_field_t fields
[3];
636 uint8_t field0
= 0x0;
637 uint8_t field0_check_value
= 0x2;
638 uint8_t field0_check_mask
= 0x7;
639 uint8_t field2
= 0x0;
640 uint8_t field2_check_value
= 0x0;
641 uint8_t field2_check_mask
= 0x1;
644 xscale
->hold_rst
= hold_rst
;
646 if (ext_dbg_brk
!= -1)
647 xscale
->external_debug_break
= ext_dbg_brk
;
649 jtag_set_end_state(TAP_IDLE
);
650 xscale_jtag_set_instr(target
->tap
, XSCALE_SELDCSR
);
652 buf_set_u32(&field0
, 1, 1, xscale
->hold_rst
);
653 buf_set_u32(&field0
, 2, 1, xscale
->external_debug_break
);
655 memset(&fields
, 0, sizeof fields
);
657 fields
[0].tap
= target
->tap
;
658 fields
[0].num_bits
= 3;
659 fields
[0].out_value
= &field0
;
661 fields
[0].in_value
= &tmp
;
663 fields
[1].tap
= target
->tap
;
664 fields
[1].num_bits
= 32;
665 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
667 fields
[2].tap
= target
->tap
;
668 fields
[2].num_bits
= 1;
669 fields
[2].out_value
= &field2
;
671 fields
[2].in_value
= &tmp2
;
673 jtag_add_dr_scan(3, fields
, jtag_get_end_state());
675 jtag_check_value_mask(fields
+ 0, &field0_check_value
, &field0_check_mask
);
676 jtag_check_value_mask(fields
+ 2, &field2_check_value
, &field2_check_mask
);
678 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
680 LOG_ERROR("JTAG error while writing DCSR");
684 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].dirty
= 0;
685 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].valid
= 1;
690 /* parity of the number of bits 0 if even; 1 if odd. for 32 bit words */
691 static unsigned int parity (unsigned int v
)
693 // unsigned int ov = v;
698 // LOG_DEBUG("parity of 0x%x is %i", ov, (0x6996 >> v) & 1);
699 return (0x6996 >> v
) & 1;
702 static int xscale_load_ic(target_t
*target
, uint32_t va
, uint32_t buffer
[8])
707 scan_field_t fields
[2];
709 LOG_DEBUG("loading miniIC at 0x%8.8" PRIx32
"", va
);
712 jtag_set_end_state(TAP_IDLE
);
713 xscale_jtag_set_instr(target
->tap
, XSCALE_LDIC
);
715 /* CMD is b011 to load a cacheline into the Mini ICache.
716 * Loading into the main ICache is deprecated, and unused.
717 * It's followed by three zero bits, and 27 address bits.
719 buf_set_u32(&cmd
, 0, 6, 0x3);
721 /* virtual address of desired cache line */
722 buf_set_u32(packet
, 0, 27, va
>> 5);
724 memset(&fields
, 0, sizeof fields
);
726 fields
[0].tap
= target
->tap
;
727 fields
[0].num_bits
= 6;
728 fields
[0].out_value
= &cmd
;
730 fields
[1].tap
= target
->tap
;
731 fields
[1].num_bits
= 27;
732 fields
[1].out_value
= packet
;
734 jtag_add_dr_scan(2, fields
, jtag_get_end_state());
736 /* rest of packet is a cacheline: 8 instructions, with parity */
737 fields
[0].num_bits
= 32;
738 fields
[0].out_value
= packet
;
740 fields
[1].num_bits
= 1;
741 fields
[1].out_value
= &cmd
;
743 for (word
= 0; word
< 8; word
++)
745 buf_set_u32(packet
, 0, 32, buffer
[word
]);
748 memcpy(&value
, packet
, sizeof(uint32_t));
751 jtag_add_dr_scan(2, fields
, jtag_get_end_state());
754 return jtag_execute_queue();
757 static int xscale_invalidate_ic_line(target_t
*target
, uint32_t va
)
761 scan_field_t fields
[2];
763 jtag_set_end_state(TAP_IDLE
);
764 xscale_jtag_set_instr(target
->tap
, XSCALE_LDIC
);
766 /* CMD for invalidate IC line b000, bits [6:4] b000 */
767 buf_set_u32(&cmd
, 0, 6, 0x0);
769 /* virtual address of desired cache line */
770 buf_set_u32(packet
, 0, 27, va
>> 5);
772 memset(&fields
, 0, sizeof fields
);
774 fields
[0].tap
= target
->tap
;
775 fields
[0].num_bits
= 6;
776 fields
[0].out_value
= &cmd
;
778 fields
[1].tap
= target
->tap
;
779 fields
[1].num_bits
= 27;
780 fields
[1].out_value
= packet
;
782 jtag_add_dr_scan(2, fields
, jtag_get_end_state());
787 static int xscale_update_vectors(target_t
*target
)
789 armv4_5_common_t
*armv4_5
= target
->arch_info
;
790 xscale_common_t
*xscale
= armv4_5
->arch_info
;
794 uint32_t low_reset_branch
, high_reset_branch
;
796 for (i
= 1; i
< 8; i
++)
798 /* if there's a static vector specified for this exception, override */
799 if (xscale
->static_high_vectors_set
& (1 << i
))
801 xscale
->high_vectors
[i
] = xscale
->static_high_vectors
[i
];
805 retval
= target_read_u32(target
, 0xffff0000 + 4*i
, &xscale
->high_vectors
[i
]);
806 if (retval
== ERROR_TARGET_TIMEOUT
)
808 if (retval
!= ERROR_OK
)
810 /* Some of these reads will fail as part of normal execution */
811 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
816 for (i
= 1; i
< 8; i
++)
818 if (xscale
->static_low_vectors_set
& (1 << i
))
820 xscale
->low_vectors
[i
] = xscale
->static_low_vectors
[i
];
824 retval
= target_read_u32(target
, 0x0 + 4*i
, &xscale
->low_vectors
[i
]);
825 if (retval
== ERROR_TARGET_TIMEOUT
)
827 if (retval
!= ERROR_OK
)
829 /* Some of these reads will fail as part of normal execution */
830 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
835 /* calculate branches to debug handler */
836 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
837 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
839 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
840 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
842 /* invalidate and load exception vectors in mini i-cache */
843 xscale_invalidate_ic_line(target
, 0x0);
844 xscale_invalidate_ic_line(target
, 0xffff0000);
846 xscale_load_ic(target
, 0x0, xscale
->low_vectors
);
847 xscale_load_ic(target
, 0xffff0000, xscale
->high_vectors
);
852 static int xscale_arch_state(struct target_s
*target
)
854 armv4_5_common_t
*armv4_5
= target
->arch_info
;
855 xscale_common_t
*xscale
= armv4_5
->arch_info
;
857 static const char *state
[] =
859 "disabled", "enabled"
862 static const char *arch_dbg_reason
[] =
864 "", "\n(processor reset)", "\n(trace buffer full)"
867 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
869 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
873 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
874 "cpsr: 0x%8.8" PRIx32
" pc: 0x%8.8" PRIx32
"\n"
875 "MMU: %s, D-Cache: %s, I-Cache: %s"
877 armv4_5_state_strings
[armv4_5
->core_state
],
878 Jim_Nvp_value2name_simple(nvp_target_debug_reason
, target
->debug_reason
)->name
,
879 armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)],
880 buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32),
881 buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32),
882 state
[xscale
->armv4_5_mmu
.mmu_enabled
],
883 state
[xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
],
884 state
[xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
],
885 arch_dbg_reason
[xscale
->arch_debug_reason
]);
890 static int xscale_poll(target_t
*target
)
892 int retval
= ERROR_OK
;
893 armv4_5_common_t
*armv4_5
= target
->arch_info
;
894 xscale_common_t
*xscale
= armv4_5
->arch_info
;
896 if ((target
->state
== TARGET_RUNNING
) || (target
->state
== TARGET_DEBUG_RUNNING
))
898 enum target_state previous_state
= target
->state
;
899 if ((retval
= xscale_read_tx(target
, 0)) == ERROR_OK
)
902 /* there's data to read from the tx register, we entered debug state */
903 xscale
->handler_running
= 1;
905 target
->state
= TARGET_HALTED
;
907 /* process debug entry, fetching current mode regs */
908 retval
= xscale_debug_entry(target
);
910 else if (retval
!= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
912 LOG_USER("error while polling TX register, reset CPU");
913 /* here we "lie" so GDB won't get stuck and a reset can be perfomed */
914 target
->state
= TARGET_HALTED
;
917 /* debug_entry could have overwritten target state (i.e. immediate resume)
918 * don't signal event handlers in that case
920 if (target
->state
!= TARGET_HALTED
)
923 /* if target was running, signal that we halted
924 * otherwise we reentered from debug execution */
925 if (previous_state
== TARGET_RUNNING
)
926 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
928 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
934 static int xscale_debug_entry(target_t
*target
)
936 armv4_5_common_t
*armv4_5
= target
->arch_info
;
937 xscale_common_t
*xscale
= armv4_5
->arch_info
;
945 /* clear external dbg break (will be written on next DCSR read) */
946 xscale
->external_debug_break
= 0;
947 if ((retval
= xscale_read_dcsr(target
)) != ERROR_OK
)
950 /* get r0, pc, r1 to r7 and cpsr */
951 if ((retval
= xscale_receive(target
, buffer
, 10)) != ERROR_OK
)
954 /* move r0 from buffer to register cache */
955 buf_set_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32, buffer
[0]);
956 armv4_5
->core_cache
->reg_list
[0].dirty
= 1;
957 armv4_5
->core_cache
->reg_list
[0].valid
= 1;
958 LOG_DEBUG("r0: 0x%8.8" PRIx32
"", buffer
[0]);
960 /* move pc from buffer to register cache */
961 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, buffer
[1]);
962 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
963 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
964 LOG_DEBUG("pc: 0x%8.8" PRIx32
"", buffer
[1]);
966 /* move data from buffer to register cache */
967 for (i
= 1; i
<= 7; i
++)
969 buf_set_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32, buffer
[1 + i
]);
970 armv4_5
->core_cache
->reg_list
[i
].dirty
= 1;
971 armv4_5
->core_cache
->reg_list
[i
].valid
= 1;
972 LOG_DEBUG("r%i: 0x%8.8" PRIx32
"", i
, buffer
[i
+ 1]);
975 buf_set_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32, buffer
[9]);
976 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].dirty
= 1;
977 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].valid
= 1;
978 LOG_DEBUG("cpsr: 0x%8.8" PRIx32
"", buffer
[9]);
980 armv4_5
->core_mode
= buffer
[9] & 0x1f;
981 if (armv4_5_mode_to_number(armv4_5
->core_mode
) == -1)
983 target
->state
= TARGET_UNKNOWN
;
984 LOG_ERROR("cpsr contains invalid mode value - communication failure");
985 return ERROR_TARGET_FAILURE
;
987 LOG_DEBUG("target entered debug state in %s mode", armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)]);
989 if (buffer
[9] & 0x20)
990 armv4_5
->core_state
= ARMV4_5_STATE_THUMB
;
992 armv4_5
->core_state
= ARMV4_5_STATE_ARM
;
995 if (armv4_5_mode_to_number(armv4_5
->core_mode
)==-1)
998 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
999 if ((armv4_5
->core_mode
!= ARMV4_5_MODE_USR
) && (armv4_5
->core_mode
!= ARMV4_5_MODE_SYS
))
1001 xscale_receive(target
, buffer
, 8);
1002 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1003 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
1004 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
1008 /* r8 to r14, but no spsr */
1009 xscale_receive(target
, buffer
, 7);
1012 /* move data from buffer to register cache */
1013 for (i
= 8; i
<= 14; i
++)
1015 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).value
, 0, 32, buffer
[i
- 8]);
1016 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).dirty
= 0;
1017 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).valid
= 1;
1020 /* examine debug reason */
1021 xscale_read_dcsr(target
);
1022 moe
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 2, 3);
1024 /* stored PC (for calculating fixup) */
1025 pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1029 case 0x0: /* Processor reset */
1030 target
->debug_reason
= DBG_REASON_DBGRQ
;
1031 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_RESET
;
1034 case 0x1: /* Instruction breakpoint hit */
1035 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1036 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1039 case 0x2: /* Data breakpoint hit */
1040 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
1041 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1044 case 0x3: /* BKPT instruction executed */
1045 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1046 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1049 case 0x4: /* Ext. debug event */
1050 target
->debug_reason
= DBG_REASON_DBGRQ
;
1051 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1054 case 0x5: /* Vector trap occured */
1055 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1056 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1059 case 0x6: /* Trace buffer full break */
1060 target
->debug_reason
= DBG_REASON_DBGRQ
;
1061 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_TB_FULL
;
1064 case 0x7: /* Reserved (may flag Hot-Debug support) */
1066 LOG_ERROR("Method of Entry is 'Reserved'");
1071 /* apply PC fixup */
1072 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, pc
);
1074 /* on the first debug entry, identify cache type */
1075 if (xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
1077 uint32_t cache_type_reg
;
1079 /* read cp15 cache type register */
1080 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
]);
1081 cache_type_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
].value
, 0, 32);
1083 armv4_5_identify_cache(cache_type_reg
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
1086 /* examine MMU and Cache settings */
1087 /* read cp15 control register */
1088 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
1089 xscale
->cp15_control_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
1090 xscale
->armv4_5_mmu
.mmu_enabled
= (xscale
->cp15_control_reg
& 0x1U
) ? 1 : 0;
1091 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= (xscale
->cp15_control_reg
& 0x4U
) ? 1 : 0;
1092 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= (xscale
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
1094 /* tracing enabled, read collected trace data */
1095 if (xscale
->trace
.buffer_enabled
)
1097 xscale_read_trace(target
);
1098 xscale
->trace
.buffer_fill
--;
1100 /* resume if we're still collecting trace data */
1101 if ((xscale
->arch_debug_reason
== XSCALE_DBG_REASON_TB_FULL
)
1102 && (xscale
->trace
.buffer_fill
> 0))
1104 xscale_resume(target
, 1, 0x0, 1, 0);
1108 xscale
->trace
.buffer_enabled
= 0;
1115 static int xscale_halt(target_t
*target
)
1117 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1118 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1120 LOG_DEBUG("target->state: %s",
1121 target_state_name(target
));
1123 if (target
->state
== TARGET_HALTED
)
1125 LOG_DEBUG("target was already halted");
1128 else if (target
->state
== TARGET_UNKNOWN
)
1130 /* this must not happen for a xscale target */
1131 LOG_ERROR("target was in unknown state when halt was requested");
1132 return ERROR_TARGET_INVALID
;
1134 else if (target
->state
== TARGET_RESET
)
1136 LOG_DEBUG("target->state == TARGET_RESET");
1140 /* assert external dbg break */
1141 xscale
->external_debug_break
= 1;
1142 xscale_read_dcsr(target
);
1144 target
->debug_reason
= DBG_REASON_DBGRQ
;
1150 static int xscale_enable_single_step(struct target_s
*target
, uint32_t next_pc
)
1152 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1153 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1154 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1157 if (xscale
->ibcr0_used
)
1159 breakpoint_t
*ibcr0_bp
= breakpoint_find(target
, buf_get_u32(ibcr0
->value
, 0, 32) & 0xfffffffe);
1163 xscale_unset_breakpoint(target
, ibcr0_bp
);
1167 LOG_ERROR("BUG: xscale->ibcr0_used is set, but no breakpoint with that address found");
1172 if ((retval
= xscale_set_reg_u32(ibcr0
, next_pc
| 0x1)) != ERROR_OK
)
1178 static int xscale_disable_single_step(struct target_s
*target
)
1180 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1181 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1182 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1185 if ((retval
= xscale_set_reg_u32(ibcr0
, 0x0)) != ERROR_OK
)
1191 static void xscale_enable_watchpoints(struct target_s
*target
)
1193 watchpoint_t
*watchpoint
= target
->watchpoints
;
1197 if (watchpoint
->set
== 0)
1198 xscale_set_watchpoint(target
, watchpoint
);
1199 watchpoint
= watchpoint
->next
;
1203 static void xscale_enable_breakpoints(struct target_s
*target
)
1205 breakpoint_t
*breakpoint
= target
->breakpoints
;
1207 /* set any pending breakpoints */
1210 if (breakpoint
->set
== 0)
1211 xscale_set_breakpoint(target
, breakpoint
);
1212 breakpoint
= breakpoint
->next
;
1216 static int xscale_resume(struct target_s
*target
, int current
,
1217 uint32_t address
, int handle_breakpoints
, int debug_execution
)
1219 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1220 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1221 breakpoint_t
*breakpoint
= target
->breakpoints
;
1223 uint32_t current_pc
;
1230 if (target
->state
!= TARGET_HALTED
)
1232 LOG_WARNING("target not halted");
1233 return ERROR_TARGET_NOT_HALTED
;
1236 if (!debug_execution
)
1238 target_free_all_working_areas(target
);
1241 /* update vector tables */
1242 if ((retval
= xscale_update_vectors(target
)) != ERROR_OK
)
1245 /* current = 1: continue on current pc, otherwise continue at <address> */
1247 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1249 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1251 /* if we're at the reset vector, we have to simulate the branch */
1252 if (current_pc
== 0x0)
1254 arm_simulate_step(target
, NULL
);
1255 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1258 /* the front-end may request us not to handle breakpoints */
1259 if (handle_breakpoints
)
1261 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1265 /* there's a breakpoint at the current PC, we have to step over it */
1266 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
"", breakpoint
->address
);
1267 xscale_unset_breakpoint(target
, breakpoint
);
1269 /* calculate PC of next instruction */
1270 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1272 uint32_t current_opcode
;
1273 target_read_u32(target
, current_pc
, ¤t_opcode
);
1274 LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8" PRIx32
"", current_opcode
);
1277 LOG_DEBUG("enable single-step");
1278 xscale_enable_single_step(target
, next_pc
);
1280 /* restore banked registers */
1281 xscale_restore_context(target
);
1283 /* send resume request (command 0x30 or 0x31)
1284 * clean the trace buffer if it is to be enabled (0x62) */
1285 if (xscale
->trace
.buffer_enabled
)
1287 xscale_send_u32(target
, 0x62);
1288 xscale_send_u32(target
, 0x31);
1291 xscale_send_u32(target
, 0x30);
1294 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1295 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));
1297 for (i
= 7; i
>= 0; i
--)
1300 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1301 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));
1305 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1306 LOG_DEBUG("writing PC with value 0x%8.8" PRIx32
"", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1308 /* wait for and process debug entry */
1309 xscale_debug_entry(target
);
1311 LOG_DEBUG("disable single-step");
1312 xscale_disable_single_step(target
);
1314 LOG_DEBUG("set breakpoint at 0x%8.8" PRIx32
"", breakpoint
->address
);
1315 xscale_set_breakpoint(target
, breakpoint
);
1319 /* enable any pending breakpoints and watchpoints */
1320 xscale_enable_breakpoints(target
);
1321 xscale_enable_watchpoints(target
);
1323 /* restore banked registers */
1324 xscale_restore_context(target
);
1326 /* send resume request (command 0x30 or 0x31)
1327 * clean the trace buffer if it is to be enabled (0x62) */
1328 if (xscale
->trace
.buffer_enabled
)
1330 xscale_send_u32(target
, 0x62);
1331 xscale_send_u32(target
, 0x31);
1334 xscale_send_u32(target
, 0x30);
1337 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1338 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));
1340 for (i
= 7; i
>= 0; i
--)
1343 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1344 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));
1348 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1349 LOG_DEBUG("writing PC with value 0x%8.8" PRIx32
"", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1351 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1353 if (!debug_execution
)
1355 /* registers are now invalid */
1356 armv4_5_invalidate_core_regs(target
);
1357 target
->state
= TARGET_RUNNING
;
1358 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1362 target
->state
= TARGET_DEBUG_RUNNING
;
1363 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1366 LOG_DEBUG("target resumed");
1368 xscale
->handler_running
= 1;
1373 static int xscale_step_inner(struct target_s
*target
, int current
,
1374 uint32_t address
, int handle_breakpoints
)
1376 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1377 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1383 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1385 /* calculate PC of next instruction */
1386 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1388 uint32_t current_opcode
, current_pc
;
1389 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1391 target_read_u32(target
, current_pc
, ¤t_opcode
);
1392 LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8" PRIx32
"", current_opcode
);
1396 LOG_DEBUG("enable single-step");
1397 if ((retval
= xscale_enable_single_step(target
, next_pc
)) != ERROR_OK
)
1400 /* restore banked registers */
1401 if ((retval
= xscale_restore_context(target
)) != ERROR_OK
)
1404 /* send resume request (command 0x30 or 0x31)
1405 * clean the trace buffer if it is to be enabled (0x62) */
1406 if (xscale
->trace
.buffer_enabled
)
1408 if ((retval
= xscale_send_u32(target
, 0x62)) != ERROR_OK
)
1410 if ((retval
= xscale_send_u32(target
, 0x31)) != ERROR_OK
)
1414 if ((retval
= xscale_send_u32(target
, 0x30)) != ERROR_OK
)
1418 if ((retval
= xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32))) != ERROR_OK
)
1420 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));
1422 for (i
= 7; i
>= 0; i
--)
1425 if ((retval
= xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32))) != ERROR_OK
)
1427 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));
1431 if ((retval
= xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))) != ERROR_OK
)
1433 LOG_DEBUG("writing PC with value 0x%8.8" PRIx32
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1435 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1437 /* registers are now invalid */
1438 if ((retval
= armv4_5_invalidate_core_regs(target
)) != ERROR_OK
)
1441 /* wait for and process debug entry */
1442 if ((retval
= xscale_debug_entry(target
)) != ERROR_OK
)
1445 LOG_DEBUG("disable single-step");
1446 if ((retval
= xscale_disable_single_step(target
)) != ERROR_OK
)
1449 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1454 static int xscale_step(struct target_s
*target
, int current
,
1455 uint32_t address
, int handle_breakpoints
)
1457 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1458 breakpoint_t
*breakpoint
= target
->breakpoints
;
1460 uint32_t current_pc
;
1463 if (target
->state
!= TARGET_HALTED
)
1465 LOG_WARNING("target not halted");
1466 return ERROR_TARGET_NOT_HALTED
;
1469 /* current = 1: continue on current pc, otherwise continue at <address> */
1471 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1473 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1475 /* if we're at the reset vector, we have to simulate the step */
1476 if (current_pc
== 0x0)
1478 if ((retval
= arm_simulate_step(target
, NULL
)) != ERROR_OK
)
1480 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1482 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1483 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1488 /* the front-end may request us not to handle breakpoints */
1489 if (handle_breakpoints
)
1490 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1492 if ((retval
= xscale_unset_breakpoint(target
, breakpoint
)) != ERROR_OK
)
1496 retval
= xscale_step_inner(target
, current
, address
, handle_breakpoints
);
1500 xscale_set_breakpoint(target
, breakpoint
);
1503 LOG_DEBUG("target stepped");
1509 static int xscale_assert_reset(target_t
*target
)
1511 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1512 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1514 LOG_DEBUG("target->state: %s",
1515 target_state_name(target
));
1517 /* select DCSR instruction (set endstate to R-T-I to ensure we don't
1518 * end up in T-L-R, which would reset JTAG
1520 jtag_set_end_state(TAP_IDLE
);
1521 xscale_jtag_set_instr(target
->tap
, XSCALE_SELDCSR
);
1523 /* set Hold reset, Halt mode and Trap Reset */
1524 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1525 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1526 xscale_write_dcsr(target
, 1, 0);
1528 /* select BYPASS, because having DCSR selected caused problems on the PXA27x */
1529 xscale_jtag_set_instr(target
->tap
, 0x7f);
1530 jtag_execute_queue();
1533 jtag_add_reset(0, 1);
1535 /* sleep 1ms, to be sure we fulfill any requirements */
1536 jtag_add_sleep(1000);
1537 jtag_execute_queue();
1539 target
->state
= TARGET_RESET
;
1541 if (target
->reset_halt
)
1544 if ((retval
= target_halt(target
)) != ERROR_OK
)
1551 static int xscale_deassert_reset(target_t
*target
)
1553 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1554 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1555 breakpoint_t
*breakpoint
= target
->breakpoints
;
1559 xscale
->ibcr_available
= 2;
1560 xscale
->ibcr0_used
= 0;
1561 xscale
->ibcr1_used
= 0;
1563 xscale
->dbr_available
= 2;
1564 xscale
->dbr0_used
= 0;
1565 xscale
->dbr1_used
= 0;
1567 /* mark all hardware breakpoints as unset */
1570 if (breakpoint
->type
== BKPT_HARD
)
1572 breakpoint
->set
= 0;
1574 breakpoint
= breakpoint
->next
;
1577 if (!xscale
->handler_installed
)
1581 const uint8_t *buffer
= xscale_debug_handler
;
1585 jtag_add_reset(0, 0);
1587 /* wait 300ms; 150 and 100ms were not enough */
1588 jtag_add_sleep(300*1000);
1590 jtag_add_runtest(2030, jtag_set_end_state(TAP_IDLE
));
1591 jtag_execute_queue();
1593 /* set Hold reset, Halt mode and Trap Reset */
1594 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1595 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1596 xscale_write_dcsr(target
, 1, 0);
1598 /* Load the debug handler into the mini-icache. Since
1599 * it's using halt mode (not monitor mode), it runs in
1600 * "Special Debug State" for access to registers, memory,
1601 * coprocessors, trace data, etc.
1603 * REVISIT: *assumes* we've had a SRST+TRST reset so the
1604 * mini-icache contents have been invalidated. Safest to
1605 * force that, so writing new contents is reliable...
1607 address
= xscale
->handler_address
;
1608 for (unsigned binary_size
= sizeof xscale_debug_handler
- 1;
1610 binary_size
-= buf_cnt
, buffer
+= buf_cnt
)
1612 uint32_t cache_line
[8];
1615 buf_cnt
= binary_size
;
1619 for (i
= 0; i
< buf_cnt
; i
+= 4)
1621 /* convert LE buffer to host-endian uint32_t */
1622 cache_line
[i
/ 4] = le_to_h_u32(&buffer
[i
]);
1625 for (; i
< 32; i
+= 4)
1627 cache_line
[i
/ 4] = 0xe1a08008;
1630 /* only load addresses other than the reset vectors */
1631 if ((address
% 0x400) != 0x0)
1633 retval
= xscale_load_ic(target
, address
,
1635 if (retval
!= ERROR_OK
)
1642 retval
= xscale_load_ic(target
, 0x0,
1643 xscale
->low_vectors
);
1644 if (retval
!= ERROR_OK
)
1646 retval
= xscale_load_ic(target
, 0xffff0000,
1647 xscale
->high_vectors
);
1648 if (retval
!= ERROR_OK
)
1651 jtag_add_runtest(30, jtag_set_end_state(TAP_IDLE
));
1653 jtag_add_sleep(100000);
1655 /* set Hold reset, Halt mode and Trap Reset */
1656 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1657 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1658 xscale_write_dcsr(target
, 1, 0);
1660 /* clear Hold reset to let the target run (should enter debug handler) */
1661 xscale_write_dcsr(target
, 0, 1);
1662 target
->state
= TARGET_RUNNING
;
1664 if (!target
->reset_halt
)
1666 jtag_add_sleep(10000);
1668 /* we should have entered debug now */
1669 xscale_debug_entry(target
);
1670 target
->state
= TARGET_HALTED
;
1672 /* resume the target */
1673 xscale_resume(target
, 1, 0x0, 1, 0);
1678 jtag_add_reset(0, 0);
1684 static int xscale_read_core_reg(struct target_s
*target
, int num
,
1685 enum armv4_5_mode mode
)
1687 LOG_ERROR("not implemented");
1691 static int xscale_write_core_reg(struct target_s
*target
, int num
,
1692 enum armv4_5_mode mode
, uint32_t value
)
1694 LOG_ERROR("not implemented");
1698 static int xscale_full_context(target_t
*target
)
1700 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1708 if (target
->state
!= TARGET_HALTED
)
1710 LOG_WARNING("target not halted");
1711 return ERROR_TARGET_NOT_HALTED
;
1714 buffer
= malloc(4 * 8);
1716 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1717 * we can't enter User mode on an XScale (unpredictable),
1718 * but User shares registers with SYS
1720 for (i
= 1; i
< 7; i
++)
1724 /* check if there are invalid registers in the current mode
1726 for (j
= 0; j
<= 16; j
++)
1728 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
== 0)
1736 /* request banked registers */
1737 xscale_send_u32(target
, 0x0);
1740 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1741 tmp_cpsr
|= 0xc0; /* I/F bits */
1743 /* send CPSR for desired mode */
1744 xscale_send_u32(target
, tmp_cpsr
);
1746 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1747 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1749 xscale_receive(target
, buffer
, 8);
1750 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1751 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1752 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).valid
= 1;
1756 xscale_receive(target
, buffer
, 7);
1759 /* move data from buffer to register cache */
1760 for (j
= 8; j
<= 14; j
++)
1762 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]);
1763 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1764 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
= 1;
1774 static int xscale_restore_context(target_t
*target
)
1776 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1780 if (target
->state
!= TARGET_HALTED
)
1782 LOG_WARNING("target not halted");
1783 return ERROR_TARGET_NOT_HALTED
;
1786 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1787 * we can't enter User mode on an XScale (unpredictable),
1788 * but User shares registers with SYS
1790 for (i
= 1; i
< 7; i
++)
1794 /* check if there are invalid registers in the current mode
1796 for (j
= 8; j
<= 14; j
++)
1798 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
== 1)
1802 /* if not USR/SYS, check if the SPSR needs to be written */
1803 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1805 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
== 1)
1813 /* send banked registers */
1814 xscale_send_u32(target
, 0x1);
1817 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1818 tmp_cpsr
|= 0xc0; /* I/F bits */
1820 /* send CPSR for desired mode */
1821 xscale_send_u32(target
, tmp_cpsr
);
1823 /* send banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1824 for (j
= 8; j
<= 14; j
++)
1826 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, j
).value
, 0, 32));
1827 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1830 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1832 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32));
1833 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1841 static int xscale_read_memory(struct target_s
*target
, uint32_t address
,
1842 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1844 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1845 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1850 LOG_DEBUG("address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
, address
, size
, count
);
1852 if (target
->state
!= TARGET_HALTED
)
1854 LOG_WARNING("target not halted");
1855 return ERROR_TARGET_NOT_HALTED
;
1858 /* sanitize arguments */
1859 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1860 return ERROR_INVALID_ARGUMENTS
;
1862 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1863 return ERROR_TARGET_UNALIGNED_ACCESS
;
1865 /* send memory read request (command 0x1n, n: access size) */
1866 if ((retval
= xscale_send_u32(target
, 0x10 | size
)) != ERROR_OK
)
1869 /* send base address for read request */
1870 if ((retval
= xscale_send_u32(target
, address
)) != ERROR_OK
)
1873 /* send number of requested data words */
1874 if ((retval
= xscale_send_u32(target
, count
)) != ERROR_OK
)
1877 /* receive data from target (count times 32-bit words in host endianness) */
1878 buf32
= malloc(4 * count
);
1879 if ((retval
= xscale_receive(target
, buf32
, count
)) != ERROR_OK
)
1882 /* extract data from host-endian buffer into byte stream */
1883 for (i
= 0; i
< count
; i
++)
1888 target_buffer_set_u32(target
, buffer
, buf32
[i
]);
1892 target_buffer_set_u16(target
, buffer
, buf32
[i
] & 0xffff);
1896 *buffer
++ = buf32
[i
] & 0xff;
1899 LOG_ERROR("should never get here");
1906 /* examine DCSR, to see if Sticky Abort (SA) got set */
1907 if ((retval
= xscale_read_dcsr(target
)) != ERROR_OK
)
1909 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
1912 if ((retval
= xscale_send_u32(target
, 0x60)) != ERROR_OK
)
1915 return ERROR_TARGET_DATA_ABORT
;
1921 static int xscale_write_memory(struct target_s
*target
, uint32_t address
,
1922 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1924 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1925 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1928 LOG_DEBUG("address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
, address
, size
, count
);
1930 if (target
->state
!= TARGET_HALTED
)
1932 LOG_WARNING("target not halted");
1933 return ERROR_TARGET_NOT_HALTED
;
1936 /* sanitize arguments */
1937 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1938 return ERROR_INVALID_ARGUMENTS
;
1940 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1941 return ERROR_TARGET_UNALIGNED_ACCESS
;
1943 /* send memory write request (command 0x2n, n: access size) */
1944 if ((retval
= xscale_send_u32(target
, 0x20 | size
)) != ERROR_OK
)
1947 /* send base address for read request */
1948 if ((retval
= xscale_send_u32(target
, address
)) != ERROR_OK
)
1951 /* send number of requested data words to be written*/
1952 if ((retval
= xscale_send_u32(target
, count
)) != ERROR_OK
)
1955 /* extract data from host-endian buffer into byte stream */
1957 for (i
= 0; i
< count
; i
++)
1962 value
= target_buffer_get_u32(target
, buffer
);
1963 xscale_send_u32(target
, value
);
1967 value
= target_buffer_get_u16(target
, buffer
);
1968 xscale_send_u32(target
, value
);
1973 xscale_send_u32(target
, value
);
1977 LOG_ERROR("should never get here");
1982 if ((retval
= xscale_send(target
, buffer
, count
, size
)) != ERROR_OK
)
1985 /* examine DCSR, to see if Sticky Abort (SA) got set */
1986 if ((retval
= xscale_read_dcsr(target
)) != ERROR_OK
)
1988 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
1991 if ((retval
= xscale_send_u32(target
, 0x60)) != ERROR_OK
)
1994 return ERROR_TARGET_DATA_ABORT
;
2000 static int xscale_bulk_write_memory(target_t
*target
, uint32_t address
,
2001 uint32_t count
, uint8_t *buffer
)
2003 return xscale_write_memory(target
, address
, 4, count
, buffer
);
2006 static uint32_t xscale_get_ttb(target_t
*target
)
2008 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2009 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2012 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_TTB
]);
2013 ttb
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_TTB
].value
, 0, 32);
2018 static void xscale_disable_mmu_caches(target_t
*target
, int mmu
,
2019 int d_u_cache
, int i_cache
)
2021 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2022 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2023 uint32_t cp15_control
;
2025 /* read cp15 control register */
2026 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2027 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2030 cp15_control
&= ~0x1U
;
2035 xscale_send_u32(target
, 0x50);
2036 xscale_send_u32(target
, xscale
->cache_clean_address
);
2038 /* invalidate DCache */
2039 xscale_send_u32(target
, 0x51);
2041 cp15_control
&= ~0x4U
;
2046 /* invalidate ICache */
2047 xscale_send_u32(target
, 0x52);
2048 cp15_control
&= ~0x1000U
;
2051 /* write new cp15 control register */
2052 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2054 /* execute cpwait to ensure outstanding operations complete */
2055 xscale_send_u32(target
, 0x53);
2058 static void xscale_enable_mmu_caches(target_t
*target
, int mmu
,
2059 int d_u_cache
, int i_cache
)
2061 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2062 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2063 uint32_t cp15_control
;
2065 /* read cp15 control register */
2066 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2067 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2070 cp15_control
|= 0x1U
;
2073 cp15_control
|= 0x4U
;
2076 cp15_control
|= 0x1000U
;
2078 /* write new cp15 control register */
2079 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2081 /* execute cpwait to ensure outstanding operations complete */
2082 xscale_send_u32(target
, 0x53);
2085 static int xscale_set_breakpoint(struct target_s
*target
,
2086 breakpoint_t
*breakpoint
)
2089 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2090 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2092 if (target
->state
!= TARGET_HALTED
)
2094 LOG_WARNING("target not halted");
2095 return ERROR_TARGET_NOT_HALTED
;
2098 if (breakpoint
->set
)
2100 LOG_WARNING("breakpoint already set");
2104 if (breakpoint
->type
== BKPT_HARD
)
2106 uint32_t value
= breakpoint
->address
| 1;
2107 if (!xscale
->ibcr0_used
)
2109 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], value
);
2110 xscale
->ibcr0_used
= 1;
2111 breakpoint
->set
= 1; /* breakpoint set on first breakpoint register */
2113 else if (!xscale
->ibcr1_used
)
2115 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], value
);
2116 xscale
->ibcr1_used
= 1;
2117 breakpoint
->set
= 2; /* breakpoint set on second breakpoint register */
2121 LOG_ERROR("BUG: no hardware comparator available");
2125 else if (breakpoint
->type
== BKPT_SOFT
)
2127 if (breakpoint
->length
== 4)
2129 /* keep the original instruction in target endianness */
2130 if ((retval
= target_read_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
2134 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2135 if ((retval
= target_write_u32(target
, breakpoint
->address
, xscale
->arm_bkpt
)) != ERROR_OK
)
2142 /* keep the original instruction in target endianness */
2143 if ((retval
= target_read_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
2147 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2148 if ((retval
= target_write_u32(target
, breakpoint
->address
, xscale
->thumb_bkpt
)) != ERROR_OK
)
2153 breakpoint
->set
= 1;
2159 static int xscale_add_breakpoint(struct target_s
*target
,
2160 breakpoint_t
*breakpoint
)
2162 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2163 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2165 if (target
->state
!= TARGET_HALTED
)
2167 LOG_WARNING("target not halted");
2168 return ERROR_TARGET_NOT_HALTED
;
2171 if ((breakpoint
->type
== BKPT_HARD
) && (xscale
->ibcr_available
< 1))
2173 LOG_INFO("no breakpoint unit available for hardware breakpoint");
2174 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2177 if ((breakpoint
->length
!= 2) && (breakpoint
->length
!= 4))
2179 LOG_INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
2180 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2183 if (breakpoint
->type
== BKPT_HARD
)
2185 xscale
->ibcr_available
--;
2191 static int xscale_unset_breakpoint(struct target_s
*target
,
2192 breakpoint_t
*breakpoint
)
2195 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2196 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2198 if (target
->state
!= TARGET_HALTED
)
2200 LOG_WARNING("target not halted");
2201 return ERROR_TARGET_NOT_HALTED
;
2204 if (!breakpoint
->set
)
2206 LOG_WARNING("breakpoint not set");
2210 if (breakpoint
->type
== BKPT_HARD
)
2212 if (breakpoint
->set
== 1)
2214 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], 0x0);
2215 xscale
->ibcr0_used
= 0;
2217 else if (breakpoint
->set
== 2)
2219 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], 0x0);
2220 xscale
->ibcr1_used
= 0;
2222 breakpoint
->set
= 0;
2226 /* restore original instruction (kept in target endianness) */
2227 if (breakpoint
->length
== 4)
2229 if ((retval
= target_write_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
2236 if ((retval
= target_write_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
2241 breakpoint
->set
= 0;
2247 static int xscale_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2249 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2250 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2252 if (target
->state
!= TARGET_HALTED
)
2254 LOG_WARNING("target not halted");
2255 return ERROR_TARGET_NOT_HALTED
;
2258 if (breakpoint
->set
)
2260 xscale_unset_breakpoint(target
, breakpoint
);
2263 if (breakpoint
->type
== BKPT_HARD
)
2264 xscale
->ibcr_available
++;
2269 static int xscale_set_watchpoint(struct target_s
*target
,
2270 watchpoint_t
*watchpoint
)
2272 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2273 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2275 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2276 uint32_t dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2278 if (target
->state
!= TARGET_HALTED
)
2280 LOG_WARNING("target not halted");
2281 return ERROR_TARGET_NOT_HALTED
;
2284 xscale_get_reg(dbcon
);
2286 switch (watchpoint
->rw
)
2298 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
2301 if (!xscale
->dbr0_used
)
2303 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR0
], watchpoint
->address
);
2304 dbcon_value
|= enable
;
2305 xscale_set_reg_u32(dbcon
, dbcon_value
);
2306 watchpoint
->set
= 1;
2307 xscale
->dbr0_used
= 1;
2309 else if (!xscale
->dbr1_used
)
2311 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR1
], watchpoint
->address
);
2312 dbcon_value
|= enable
<< 2;
2313 xscale_set_reg_u32(dbcon
, dbcon_value
);
2314 watchpoint
->set
= 2;
2315 xscale
->dbr1_used
= 1;
2319 LOG_ERROR("BUG: no hardware comparator available");
2326 static int xscale_add_watchpoint(struct target_s
*target
,
2327 watchpoint_t
*watchpoint
)
2329 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2330 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2332 if (target
->state
!= TARGET_HALTED
)
2334 LOG_WARNING("target not halted");
2335 return ERROR_TARGET_NOT_HALTED
;
2338 if (xscale
->dbr_available
< 1)
2340 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2343 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
2345 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2348 xscale
->dbr_available
--;
2353 static int xscale_unset_watchpoint(struct target_s
*target
,
2354 watchpoint_t
*watchpoint
)
2356 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2357 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2358 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2359 uint32_t dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2361 if (target
->state
!= TARGET_HALTED
)
2363 LOG_WARNING("target not halted");
2364 return ERROR_TARGET_NOT_HALTED
;
2367 if (!watchpoint
->set
)
2369 LOG_WARNING("breakpoint not set");
2373 if (watchpoint
->set
== 1)
2375 dbcon_value
&= ~0x3;
2376 xscale_set_reg_u32(dbcon
, dbcon_value
);
2377 xscale
->dbr0_used
= 0;
2379 else if (watchpoint
->set
== 2)
2381 dbcon_value
&= ~0xc;
2382 xscale_set_reg_u32(dbcon
, dbcon_value
);
2383 xscale
->dbr1_used
= 0;
2385 watchpoint
->set
= 0;
2390 static int xscale_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2392 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2393 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2395 if (target
->state
!= TARGET_HALTED
)
2397 LOG_WARNING("target not halted");
2398 return ERROR_TARGET_NOT_HALTED
;
2401 if (watchpoint
->set
)
2403 xscale_unset_watchpoint(target
, watchpoint
);
2406 xscale
->dbr_available
++;
2411 static int xscale_get_reg(reg_t
*reg
)
2413 xscale_reg_t
*arch_info
= reg
->arch_info
;
2414 target_t
*target
= arch_info
->target
;
2415 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2416 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2418 /* DCSR, TX and RX are accessible via JTAG */
2419 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2421 return xscale_read_dcsr(arch_info
->target
);
2423 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2425 /* 1 = consume register content */
2426 return xscale_read_tx(arch_info
->target
, 1);
2428 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2430 /* can't read from RX register (host -> debug handler) */
2433 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2435 /* can't (explicitly) read from TXRXCTRL register */
2438 else /* Other DBG registers have to be transfered by the debug handler */
2440 /* send CP read request (command 0x40) */
2441 xscale_send_u32(target
, 0x40);
2443 /* send CP register number */
2444 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2446 /* read register value */
2447 xscale_read_tx(target
, 1);
2448 buf_cpy(xscale
->reg_cache
->reg_list
[XSCALE_TX
].value
, reg
->value
, 32);
2457 static int xscale_set_reg(reg_t
*reg
, uint8_t* buf
)
2459 xscale_reg_t
*arch_info
= reg
->arch_info
;
2460 target_t
*target
= arch_info
->target
;
2461 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2462 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2463 uint32_t value
= buf_get_u32(buf
, 0, 32);
2465 /* DCSR, TX and RX are accessible via JTAG */
2466 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2468 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32, value
);
2469 return xscale_write_dcsr(arch_info
->target
, -1, -1);
2471 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2473 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
2474 return xscale_write_rx(arch_info
->target
);
2476 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2478 /* can't write to TX register (debug-handler -> host) */
2481 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2483 /* can't (explicitly) write to TXRXCTRL register */
2486 else /* Other DBG registers have to be transfered by the debug handler */
2488 /* send CP write request (command 0x41) */
2489 xscale_send_u32(target
, 0x41);
2491 /* send CP register number */
2492 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2494 /* send CP register value */
2495 xscale_send_u32(target
, value
);
2496 buf_set_u32(reg
->value
, 0, 32, value
);
2502 static int xscale_write_dcsr_sw(target_t
*target
, uint32_t value
)
2504 /* get pointers to arch-specific information */
2505 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2506 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2507 reg_t
*dcsr
= &xscale
->reg_cache
->reg_list
[XSCALE_DCSR
];
2508 xscale_reg_t
*dcsr_arch_info
= dcsr
->arch_info
;
2510 /* send CP write request (command 0x41) */
2511 xscale_send_u32(target
, 0x41);
2513 /* send CP register number */
2514 xscale_send_u32(target
, dcsr_arch_info
->dbg_handler_number
);
2516 /* send CP register value */
2517 xscale_send_u32(target
, value
);
2518 buf_set_u32(dcsr
->value
, 0, 32, value
);
2523 static int xscale_read_trace(target_t
*target
)
2525 /* get pointers to arch-specific information */
2526 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2527 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2528 xscale_trace_data_t
**trace_data_p
;
2530 /* 258 words from debug handler
2531 * 256 trace buffer entries
2532 * 2 checkpoint addresses
2534 uint32_t trace_buffer
[258];
2535 int is_address
[256];
2538 if (target
->state
!= TARGET_HALTED
)
2540 LOG_WARNING("target must be stopped to read trace data");
2541 return ERROR_TARGET_NOT_HALTED
;
2544 /* send read trace buffer command (command 0x61) */
2545 xscale_send_u32(target
, 0x61);
2547 /* receive trace buffer content */
2548 xscale_receive(target
, trace_buffer
, 258);
2550 /* parse buffer backwards to identify address entries */
2551 for (i
= 255; i
>= 0; i
--)
2554 if (((trace_buffer
[i
] & 0xf0) == 0x90) ||
2555 ((trace_buffer
[i
] & 0xf0) == 0xd0))
2558 is_address
[--i
] = 1;
2560 is_address
[--i
] = 1;
2562 is_address
[--i
] = 1;
2564 is_address
[--i
] = 1;
2569 /* search first non-zero entry */
2570 for (j
= 0; (j
< 256) && (trace_buffer
[j
] == 0) && (!is_address
[j
]); j
++)
2575 LOG_DEBUG("no trace data collected");
2576 return ERROR_XSCALE_NO_TRACE_DATA
;
2579 for (trace_data_p
= &xscale
->trace
.data
; *trace_data_p
; trace_data_p
= &(*trace_data_p
)->next
)
2582 *trace_data_p
= malloc(sizeof(xscale_trace_data_t
));
2583 (*trace_data_p
)->next
= NULL
;
2584 (*trace_data_p
)->chkpt0
= trace_buffer
[256];
2585 (*trace_data_p
)->chkpt1
= trace_buffer
[257];
2586 (*trace_data_p
)->last_instruction
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
2587 (*trace_data_p
)->entries
= malloc(sizeof(xscale_trace_entry_t
) * (256 - j
));
2588 (*trace_data_p
)->depth
= 256 - j
;
2590 for (i
= j
; i
< 256; i
++)
2592 (*trace_data_p
)->entries
[i
- j
].data
= trace_buffer
[i
];
2594 (*trace_data_p
)->entries
[i
- j
].type
= XSCALE_TRACE_ADDRESS
;
2596 (*trace_data_p
)->entries
[i
- j
].type
= XSCALE_TRACE_MESSAGE
;
2602 static int xscale_read_instruction(target_t
*target
,
2603 arm_instruction_t
*instruction
)
2605 /* get pointers to arch-specific information */
2606 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2607 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2614 if (!xscale
->trace
.image
)
2615 return ERROR_TRACE_IMAGE_UNAVAILABLE
;
2617 /* search for the section the current instruction belongs to */
2618 for (i
= 0; i
< xscale
->trace
.image
->num_sections
; i
++)
2620 if ((xscale
->trace
.image
->sections
[i
].base_address
<= xscale
->trace
.current_pc
) &&
2621 (xscale
->trace
.image
->sections
[i
].base_address
+ xscale
->trace
.image
->sections
[i
].size
> xscale
->trace
.current_pc
))
2630 /* current instruction couldn't be found in the image */
2631 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2634 if (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
)
2637 if ((retval
= image_read_section(xscale
->trace
.image
, section
,
2638 xscale
->trace
.current_pc
- xscale
->trace
.image
->sections
[section
].base_address
,
2639 4, buf
, &size_read
)) != ERROR_OK
)
2641 LOG_ERROR("error while reading instruction: %i", retval
);
2642 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2644 opcode
= target_buffer_get_u32(target
, buf
);
2645 arm_evaluate_opcode(opcode
, xscale
->trace
.current_pc
, instruction
);
2647 else if (xscale
->trace
.core_state
== ARMV4_5_STATE_THUMB
)
2650 if ((retval
= image_read_section(xscale
->trace
.image
, section
,
2651 xscale
->trace
.current_pc
- xscale
->trace
.image
->sections
[section
].base_address
,
2652 2, buf
, &size_read
)) != ERROR_OK
)
2654 LOG_ERROR("error while reading instruction: %i", retval
);
2655 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2657 opcode
= target_buffer_get_u16(target
, buf
);
2658 thumb_evaluate_opcode(opcode
, xscale
->trace
.current_pc
, instruction
);
2662 LOG_ERROR("BUG: unknown core state encountered");
2669 static int xscale_branch_address(xscale_trace_data_t
*trace_data
,
2670 int i
, uint32_t *target
)
2672 /* if there are less than four entries prior to the indirect branch message
2673 * we can't extract the address */
2679 *target
= (trace_data
->entries
[i
-1].data
) | (trace_data
->entries
[i
-2].data
<< 8) |
2680 (trace_data
->entries
[i
-3].data
<< 16) | (trace_data
->entries
[i
-4].data
<< 24);
2685 static int xscale_analyze_trace(target_t
*target
, command_context_t
*cmd_ctx
)
2687 /* get pointers to arch-specific information */
2688 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2689 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2691 uint32_t next_pc
= 0x0;
2692 xscale_trace_data_t
*trace_data
= xscale
->trace
.data
;
2701 xscale
->trace
.core_state
= ARMV4_5_STATE_ARM
;
2706 for (i
= 0; i
< trace_data
->depth
; i
++)
2712 if (trace_data
->entries
[i
].type
== XSCALE_TRACE_ADDRESS
)
2715 switch ((trace_data
->entries
[i
].data
& 0xf0) >> 4)
2717 case 0: /* Exceptions */
2725 exception
= (trace_data
->entries
[i
].data
& 0x70) >> 4;
2727 next_pc
= (trace_data
->entries
[i
].data
& 0xf0) >> 2;
2728 command_print(cmd_ctx
, "--- exception %i ---", (trace_data
->entries
[i
].data
& 0xf0) >> 4);
2730 case 8: /* Direct Branch */
2733 case 9: /* Indirect Branch */
2735 if (xscale_branch_address(trace_data
, i
, &next_pc
) == 0)
2740 case 13: /* Checkpointed Indirect Branch */
2741 if (xscale_branch_address(trace_data
, i
, &next_pc
) == 0)
2744 if (((chkpt
== 0) && (next_pc
!= trace_data
->chkpt0
))
2745 || ((chkpt
== 1) && (next_pc
!= trace_data
->chkpt1
)))
2746 LOG_WARNING("checkpointed indirect branch target address doesn't match checkpoint");
2748 /* explicit fall-through */
2749 case 12: /* Checkpointed Direct Branch */
2754 next_pc
= trace_data
->chkpt0
;
2757 else if (chkpt
== 1)
2760 next_pc
= trace_data
->chkpt0
;
2765 LOG_WARNING("more than two checkpointed branches encountered");
2768 case 15: /* Roll-over */
2771 default: /* Reserved */
2772 command_print(cmd_ctx
, "--- reserved trace message ---");
2773 LOG_ERROR("BUG: trace message %i is reserved", (trace_data
->entries
[i
].data
& 0xf0) >> 4);
2777 if (xscale
->trace
.pc_ok
)
2779 int executed
= (trace_data
->entries
[i
].data
& 0xf) + rollover
* 16;
2780 arm_instruction_t instruction
;
2782 if ((exception
== 6) || (exception
== 7))
2784 /* IRQ or FIQ exception, no instruction executed */
2788 while (executed
-- >= 0)
2790 if ((retval
= xscale_read_instruction(target
, &instruction
)) != ERROR_OK
)
2792 /* can't continue tracing with no image available */
2793 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
2797 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
2799 /* TODO: handle incomplete images */
2803 /* a precise abort on a load to the PC is included in the incremental
2804 * word count, other instructions causing data aborts are not included
2806 if ((executed
== 0) && (exception
== 4)
2807 && ((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_LDM
)))
2809 if ((instruction
.type
== ARM_LDM
)
2810 && ((instruction
.info
.load_store_multiple
.register_list
& 0x8000) == 0))
2814 else if (((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_LDRSH
))
2815 && (instruction
.info
.load_store
.Rd
!= 15))
2821 /* only the last instruction executed
2822 * (the one that caused the control flow change)
2823 * could be a taken branch
2825 if (((executed
== -1) && (branch
== 1)) &&
2826 (((instruction
.type
== ARM_B
) ||
2827 (instruction
.type
== ARM_BL
) ||
2828 (instruction
.type
== ARM_BLX
)) &&
2829 (instruction
.info
.b_bl_bx_blx
.target_address
!= 0xffffffff)))
2831 xscale
->trace
.current_pc
= instruction
.info
.b_bl_bx_blx
.target_address
;
2835 xscale
->trace
.current_pc
+= (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2;
2837 command_print(cmd_ctx
, "%s", instruction
.text
);
2845 xscale
->trace
.current_pc
= next_pc
;
2846 xscale
->trace
.pc_ok
= 1;
2850 for (; xscale
->trace
.current_pc
< trace_data
->last_instruction
; xscale
->trace
.current_pc
+= (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2)
2852 arm_instruction_t instruction
;
2853 if ((retval
= xscale_read_instruction(target
, &instruction
)) != ERROR_OK
)
2855 /* can't continue tracing with no image available */
2856 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
2860 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
2862 /* TODO: handle incomplete images */
2865 command_print(cmd_ctx
, "%s", instruction
.text
);
2868 trace_data
= trace_data
->next
;
2874 static void xscale_build_reg_cache(target_t
*target
)
2876 /* get pointers to arch-specific information */
2877 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2878 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2880 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
2881 xscale_reg_t
*arch_info
= malloc(sizeof(xscale_reg_arch_info
));
2883 int num_regs
= sizeof(xscale_reg_arch_info
) / sizeof(xscale_reg_t
);
2885 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
2886 armv4_5
->core_cache
= (*cache_p
);
2888 /* register a register arch-type for XScale dbg registers only once */
2889 if (xscale_reg_arch_type
== -1)
2890 xscale_reg_arch_type
= register_reg_arch_type(xscale_get_reg
, xscale_set_reg
);
2892 (*cache_p
)->next
= malloc(sizeof(reg_cache_t
));
2893 cache_p
= &(*cache_p
)->next
;
2895 /* fill in values for the xscale reg cache */
2896 (*cache_p
)->name
= "XScale registers";
2897 (*cache_p
)->next
= NULL
;
2898 (*cache_p
)->reg_list
= malloc(num_regs
* sizeof(reg_t
));
2899 (*cache_p
)->num_regs
= num_regs
;
2901 for (i
= 0; i
< num_regs
; i
++)
2903 (*cache_p
)->reg_list
[i
].name
= xscale_reg_list
[i
];
2904 (*cache_p
)->reg_list
[i
].value
= calloc(4, 1);
2905 (*cache_p
)->reg_list
[i
].dirty
= 0;
2906 (*cache_p
)->reg_list
[i
].valid
= 0;
2907 (*cache_p
)->reg_list
[i
].size
= 32;
2908 (*cache_p
)->reg_list
[i
].bitfield_desc
= NULL
;
2909 (*cache_p
)->reg_list
[i
].num_bitfields
= 0;
2910 (*cache_p
)->reg_list
[i
].arch_info
= &arch_info
[i
];
2911 (*cache_p
)->reg_list
[i
].arch_type
= xscale_reg_arch_type
;
2912 arch_info
[i
] = xscale_reg_arch_info
[i
];
2913 arch_info
[i
].target
= target
;
2916 xscale
->reg_cache
= (*cache_p
);
2919 static int xscale_init_target(struct command_context_s
*cmd_ctx
,
2920 struct target_s
*target
)
2922 xscale_build_reg_cache(target
);
2926 static int xscale_quit(void)
2928 jtag_add_runtest(100, TAP_RESET
);
2932 static int xscale_init_arch_info(target_t
*target
,
2933 xscale_common_t
*xscale
, jtag_tap_t
*tap
, const char *variant
)
2935 armv4_5_common_t
*armv4_5
;
2936 uint32_t high_reset_branch
, low_reset_branch
;
2939 armv4_5
= &xscale
->armv4_5_common
;
2941 /* store architecture specfic data (none so far) */
2942 xscale
->arch_info
= NULL
;
2943 xscale
->common_magic
= XSCALE_COMMON_MAGIC
;
2945 /* we don't really *need* variant info ... */
2949 if (strcmp(variant
, "pxa250") == 0
2950 || strcmp(variant
, "pxa255") == 0
2951 || strcmp(variant
, "pxa26x") == 0)
2953 else if (strcmp(variant
, "pxa27x") == 0
2954 || strcmp(variant
, "ixp42x") == 0
2955 || strcmp(variant
, "ixp45x") == 0
2956 || strcmp(variant
, "ixp46x") == 0)
2959 LOG_WARNING("%s: unrecognized variant %s",
2960 tap
->dotted_name
, variant
);
2962 if (ir_length
&& ir_length
!= tap
->ir_length
) {
2963 LOG_WARNING("%s: IR length for %s is %d; fixing",
2964 tap
->dotted_name
, variant
, ir_length
);
2965 tap
->ir_length
= ir_length
;
2969 /* the debug handler isn't installed (and thus not running) at this time */
2970 xscale
->handler_installed
= 0;
2971 xscale
->handler_running
= 0;
2972 xscale
->handler_address
= 0xfe000800;
2974 /* clear the vectors we keep locally for reference */
2975 memset(xscale
->low_vectors
, 0, sizeof(xscale
->low_vectors
));
2976 memset(xscale
->high_vectors
, 0, sizeof(xscale
->high_vectors
));
2978 /* no user-specified vectors have been configured yet */
2979 xscale
->static_low_vectors_set
= 0x0;
2980 xscale
->static_high_vectors_set
= 0x0;
2982 /* calculate branches to debug handler */
2983 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
2984 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
2986 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
2987 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
2989 for (i
= 1; i
<= 7; i
++)
2991 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
2992 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
2995 /* 64kB aligned region used for DCache cleaning */
2996 xscale
->cache_clean_address
= 0xfffe0000;
2998 xscale
->hold_rst
= 0;
2999 xscale
->external_debug_break
= 0;
3001 xscale
->ibcr_available
= 2;
3002 xscale
->ibcr0_used
= 0;
3003 xscale
->ibcr1_used
= 0;
3005 xscale
->dbr_available
= 2;
3006 xscale
->dbr0_used
= 0;
3007 xscale
->dbr1_used
= 0;
3009 xscale
->arm_bkpt
= ARMV5_BKPT(0x0);
3010 xscale
->thumb_bkpt
= ARMV5_T_BKPT(0x0) & 0xffff;
3012 xscale
->vector_catch
= 0x1;
3014 xscale
->trace
.capture_status
= TRACE_IDLE
;
3015 xscale
->trace
.data
= NULL
;
3016 xscale
->trace
.image
= NULL
;
3017 xscale
->trace
.buffer_enabled
= 0;
3018 xscale
->trace
.buffer_fill
= 0;
3020 /* prepare ARMv4/5 specific information */
3021 armv4_5
->arch_info
= xscale
;
3022 armv4_5
->read_core_reg
= xscale_read_core_reg
;
3023 armv4_5
->write_core_reg
= xscale_write_core_reg
;
3024 armv4_5
->full_context
= xscale_full_context
;
3026 armv4_5_init_arch_info(target
, armv4_5
);
3028 xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
3029 xscale
->armv4_5_mmu
.get_ttb
= xscale_get_ttb
;
3030 xscale
->armv4_5_mmu
.read_memory
= xscale_read_memory
;
3031 xscale
->armv4_5_mmu
.write_memory
= xscale_write_memory
;
3032 xscale
->armv4_5_mmu
.disable_mmu_caches
= xscale_disable_mmu_caches
;
3033 xscale
->armv4_5_mmu
.enable_mmu_caches
= xscale_enable_mmu_caches
;
3034 xscale
->armv4_5_mmu
.has_tiny_pages
= 1;
3035 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3040 static int xscale_target_create(struct target_s
*target
, Jim_Interp
*interp
)
3042 xscale_common_t
*xscale
;
3044 if (sizeof xscale_debug_handler
- 1 > 0x800) {
3045 LOG_ERROR("debug_handler.bin: larger than 2kb");
3049 xscale
= calloc(1, sizeof(*xscale
));
3053 return xscale_init_arch_info(target
, xscale
, target
->tap
,
3058 xscale_handle_debug_handler_command(struct command_context_s
*cmd_ctx
,
3059 char *cmd
, char **args
, int argc
)
3061 target_t
*target
= NULL
;
3062 armv4_5_common_t
*armv4_5
;
3063 xscale_common_t
*xscale
;
3065 uint32_t handler_address
;
3069 LOG_ERROR("'xscale debug_handler <target#> <address>' command takes two required operands");
3073 if ((target
= get_target(args
[0])) == NULL
)
3075 LOG_ERROR("target '%s' not defined", args
[0]);
3079 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3084 handler_address
= strtoul(args
[1], NULL
, 0);
3086 if (((handler_address
>= 0x800) && (handler_address
<= 0x1fef800)) ||
3087 ((handler_address
>= 0xfe000800) && (handler_address
<= 0xfffff800)))
3089 xscale
->handler_address
= handler_address
;
3093 LOG_ERROR("xscale debug_handler <address> must be between 0x800 and 0x1fef800 or between 0xfe000800 and 0xfffff800");
3101 xscale_handle_cache_clean_address_command(struct command_context_s
*cmd_ctx
,
3102 char *cmd
, char **args
, int argc
)
3104 target_t
*target
= NULL
;
3105 armv4_5_common_t
*armv4_5
;
3106 xscale_common_t
*xscale
;
3108 uint32_t cache_clean_address
;
3112 return ERROR_COMMAND_SYNTAX_ERROR
;
3115 target
= get_target(args
[0]);
3118 LOG_ERROR("target '%s' not defined", args
[0]);
3122 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3127 cache_clean_address
= strtoul(args
[1], NULL
, 0);
3129 if (cache_clean_address
& 0xffff)
3131 LOG_ERROR("xscale cache_clean_address <address> must be 64kb aligned");
3135 xscale
->cache_clean_address
= cache_clean_address
;
3142 xscale_handle_cache_info_command(struct command_context_s
*cmd_ctx
,
3143 char *cmd
, char **args
, int argc
)
3145 target_t
*target
= get_current_target(cmd_ctx
);
3146 armv4_5_common_t
*armv4_5
;
3147 xscale_common_t
*xscale
;
3149 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3154 return armv4_5_handle_cache_info_command(cmd_ctx
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
3157 static int xscale_virt2phys(struct target_s
*target
,
3158 uint32_t virtual, uint32_t *physical
)
3160 armv4_5_common_t
*armv4_5
;
3161 xscale_common_t
*xscale
;
3168 if ((retval
= xscale_get_arch_pointers(target
, &armv4_5
, &xscale
)) != ERROR_OK
)
3172 uint32_t ret
= armv4_5_mmu_translate_va(target
, &xscale
->armv4_5_mmu
, virtual, &type
, &cb
, &domain
, &ap
);
3181 static int xscale_mmu(struct target_s
*target
, int *enabled
)
3183 armv4_5_common_t
*armv4_5
= target
->arch_info
;
3184 xscale_common_t
*xscale
= armv4_5
->arch_info
;
3186 if (target
->state
!= TARGET_HALTED
)
3188 LOG_ERROR("Target not halted");
3189 return ERROR_TARGET_INVALID
;
3191 *enabled
= xscale
->armv4_5_mmu
.mmu_enabled
;
3195 static int xscale_handle_mmu_command(command_context_t
*cmd_ctx
,
3196 char *cmd
, char **args
, int argc
)
3198 target_t
*target
= get_current_target(cmd_ctx
);
3199 armv4_5_common_t
*armv4_5
;
3200 xscale_common_t
*xscale
;
3202 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3207 if (target
->state
!= TARGET_HALTED
)
3209 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3215 if (strcmp("enable", args
[0]) == 0)
3217 xscale_enable_mmu_caches(target
, 1, 0, 0);
3218 xscale
->armv4_5_mmu
.mmu_enabled
= 1;
3220 else if (strcmp("disable", args
[0]) == 0)
3222 xscale_disable_mmu_caches(target
, 1, 0, 0);
3223 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3227 command_print(cmd_ctx
, "mmu %s", (xscale
->armv4_5_mmu
.mmu_enabled
) ? "enabled" : "disabled");
3232 static int xscale_handle_idcache_command(command_context_t
*cmd_ctx
,
3233 char *cmd
, char **args
, int argc
)
3235 target_t
*target
= get_current_target(cmd_ctx
);
3236 armv4_5_common_t
*armv4_5
;
3237 xscale_common_t
*xscale
;
3238 int icache
= 0, dcache
= 0;
3240 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3245 if (target
->state
!= TARGET_HALTED
)
3247 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3251 if (strcmp(cmd
, "icache") == 0)
3253 else if (strcmp(cmd
, "dcache") == 0)
3258 if (strcmp("enable", args
[0]) == 0)
3260 xscale_enable_mmu_caches(target
, 0, dcache
, icache
);
3263 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 1;
3265 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 1;
3267 else if (strcmp("disable", args
[0]) == 0)
3269 xscale_disable_mmu_caches(target
, 0, dcache
, icache
);
3272 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 0;
3274 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 0;
3279 command_print(cmd_ctx
, "icache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
) ? "enabled" : "disabled");
3282 command_print(cmd_ctx
, "dcache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
) ? "enabled" : "disabled");
3287 static int xscale_handle_vector_catch_command(command_context_t
*cmd_ctx
,
3288 char *cmd
, char **args
, int argc
)
3290 target_t
*target
= get_current_target(cmd_ctx
);
3291 armv4_5_common_t
*armv4_5
;
3292 xscale_common_t
*xscale
;
3294 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3301 command_print(cmd_ctx
, "usage: xscale vector_catch [mask]");
3305 xscale
->vector_catch
= strtoul(args
[0], NULL
, 0);
3306 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 8, xscale
->vector_catch
);
3307 xscale_write_dcsr(target
, -1, -1);
3310 command_print(cmd_ctx
, "vector catch mask: 0x%2.2x", xscale
->vector_catch
);
3316 static int xscale_handle_vector_table_command(command_context_t
*cmd_ctx
,
3317 char *cmd
, char **args
, int argc
)
3319 target_t
*target
= get_current_target(cmd_ctx
);
3320 armv4_5_common_t
*armv4_5
;
3321 xscale_common_t
*xscale
;
3324 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3329 if (argc
== 0) /* print current settings */
3333 command_print(cmd_ctx
, "active user-set static vectors:");
3334 for (idx
= 1; idx
< 8; idx
++)
3335 if (xscale
->static_low_vectors_set
& (1 << idx
))
3336 command_print(cmd_ctx
, "low %d: 0x%" PRIx32
, idx
, xscale
->static_low_vectors
[idx
]);
3337 for (idx
= 1; idx
< 8; idx
++)
3338 if (xscale
->static_high_vectors_set
& (1 << idx
))
3339 command_print(cmd_ctx
, "high %d: 0x%" PRIx32
, idx
, xscale
->static_high_vectors
[idx
]);
3349 idx
= strtoul(args
[1], NULL
, 0);
3350 vec
= strtoul(args
[2], NULL
, 0);
3352 if (idx
< 1 || idx
>= 8)
3355 if (!err
&& strcmp(args
[0], "low") == 0)
3357 xscale
->static_low_vectors_set
|= (1<<idx
);
3358 xscale
->static_low_vectors
[idx
] = vec
;
3360 else if (!err
&& (strcmp(args
[0], "high") == 0))
3362 xscale
->static_high_vectors_set
|= (1<<idx
);
3363 xscale
->static_high_vectors
[idx
] = vec
;
3370 command_print(cmd_ctx
, "usage: xscale vector_table <high|low> <index> <code>");
3377 xscale_handle_trace_buffer_command(struct command_context_s
*cmd_ctx
,
3378 char *cmd
, char **args
, int argc
)
3380 target_t
*target
= get_current_target(cmd_ctx
);
3381 armv4_5_common_t
*armv4_5
;
3382 xscale_common_t
*xscale
;
3383 uint32_t dcsr_value
;
3385 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3390 if (target
->state
!= TARGET_HALTED
)
3392 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3396 if ((argc
>= 1) && (strcmp("enable", args
[0]) == 0))
3398 xscale_trace_data_t
*td
, *next_td
;
3399 xscale
->trace
.buffer_enabled
= 1;
3401 /* free old trace data */
3402 td
= xscale
->trace
.data
;
3412 xscale
->trace
.data
= NULL
;
3414 else if ((argc
>= 1) && (strcmp("disable", args
[0]) == 0))
3416 xscale
->trace
.buffer_enabled
= 0;
3419 if ((argc
>= 2) && (strcmp("fill", args
[1]) == 0))
3422 xscale
->trace
.buffer_fill
= strtoul(args
[2], NULL
, 0);
3424 xscale
->trace
.buffer_fill
= 1;
3426 else if ((argc
>= 2) && (strcmp("wrap", args
[1]) == 0))
3428 xscale
->trace
.buffer_fill
= -1;
3431 if (xscale
->trace
.buffer_enabled
)
3433 /* if we enable the trace buffer in fill-once
3434 * mode we know the address of the first instruction */
3435 xscale
->trace
.pc_ok
= 1;
3436 xscale
->trace
.current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
3440 /* otherwise the address is unknown, and we have no known good PC */
3441 xscale
->trace
.pc_ok
= 0;
3444 command_print(cmd_ctx
, "trace buffer %s (%s)",
3445 (xscale
->trace
.buffer_enabled
) ? "enabled" : "disabled",
3446 (xscale
->trace
.buffer_fill
> 0) ? "fill" : "wrap");
3448 dcsr_value
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32);
3449 if (xscale
->trace
.buffer_fill
>= 0)
3450 xscale_write_dcsr_sw(target
, (dcsr_value
& 0xfffffffc) | 2);
3452 xscale_write_dcsr_sw(target
, dcsr_value
& 0xfffffffc);
3458 xscale_handle_trace_image_command(struct command_context_s
*cmd_ctx
,
3459 char *cmd
, char **args
, int argc
)
3462 armv4_5_common_t
*armv4_5
;
3463 xscale_common_t
*xscale
;
3467 command_print(cmd_ctx
, "usage: xscale trace_image <file> [base address] [type]");
3471 target
= get_current_target(cmd_ctx
);
3473 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3478 if (xscale
->trace
.image
)
3480 image_close(xscale
->trace
.image
);
3481 free(xscale
->trace
.image
);
3482 command_print(cmd_ctx
, "previously loaded image found and closed");
3485 xscale
->trace
.image
= malloc(sizeof(image_t
));
3486 xscale
->trace
.image
->base_address_set
= 0;
3487 xscale
->trace
.image
->start_address_set
= 0;
3489 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
3492 xscale
->trace
.image
->base_address_set
= 1;
3493 xscale
->trace
.image
->base_address
= strtoul(args
[1], NULL
, 0);
3497 xscale
->trace
.image
->base_address_set
= 0;
3500 if (image_open(xscale
->trace
.image
, args
[0], (argc
>= 3) ? args
[2] : NULL
) != ERROR_OK
)
3502 free(xscale
->trace
.image
);
3503 xscale
->trace
.image
= NULL
;
3510 static int xscale_handle_dump_trace_command(struct command_context_s
*cmd_ctx
,
3511 char *cmd
, char **args
, int argc
)
3513 target_t
*target
= get_current_target(cmd_ctx
);
3514 armv4_5_common_t
*armv4_5
;
3515 xscale_common_t
*xscale
;
3516 xscale_trace_data_t
*trace_data
;
3519 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3524 if (target
->state
!= TARGET_HALTED
)
3526 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3532 command_print(cmd_ctx
, "usage: xscale dump_trace <file>");
3536 trace_data
= xscale
->trace
.data
;
3540 command_print(cmd_ctx
, "no trace data collected");
3544 if (fileio_open(&file
, args
[0], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
)
3553 fileio_write_u32(&file
, trace_data
->chkpt0
);
3554 fileio_write_u32(&file
, trace_data
->chkpt1
);
3555 fileio_write_u32(&file
, trace_data
->last_instruction
);
3556 fileio_write_u32(&file
, trace_data
->depth
);
3558 for (i
= 0; i
< trace_data
->depth
; i
++)
3559 fileio_write_u32(&file
, trace_data
->entries
[i
].data
| ((trace_data
->entries
[i
].type
& 0xffff) << 16));
3561 trace_data
= trace_data
->next
;
3564 fileio_close(&file
);
3570 xscale_handle_analyze_trace_buffer_command(struct command_context_s
*cmd_ctx
,
3571 char *cmd
, char **args
, int argc
)
3573 target_t
*target
= get_current_target(cmd_ctx
);
3574 armv4_5_common_t
*armv4_5
;
3575 xscale_common_t
*xscale
;
3577 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3582 xscale_analyze_trace(target
, cmd_ctx
);
3587 static int xscale_handle_cp15(command_context_t
*cmd_ctx
,
3588 char *cmd
, char **args
, int argc
)
3590 target_t
*target
= get_current_target(cmd_ctx
);
3591 armv4_5_common_t
*armv4_5
;
3592 xscale_common_t
*xscale
;
3594 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3599 if (target
->state
!= TARGET_HALTED
)
3601 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3604 uint32_t reg_no
= 0;
3608 reg_no
= strtoul(args
[0], NULL
, 0);
3609 /*translate from xscale cp15 register no to openocd register*/
3613 reg_no
= XSCALE_MAINID
;
3616 reg_no
= XSCALE_CTRL
;
3619 reg_no
= XSCALE_TTB
;
3622 reg_no
= XSCALE_DAC
;
3625 reg_no
= XSCALE_FSR
;
3628 reg_no
= XSCALE_FAR
;
3631 reg_no
= XSCALE_PID
;
3634 reg_no
= XSCALE_CPACCESS
;
3637 command_print(cmd_ctx
, "invalid register number");
3638 return ERROR_INVALID_ARGUMENTS
;
3640 reg
= &xscale
->reg_cache
->reg_list
[reg_no
];
3647 /* read cp15 control register */
3648 xscale_get_reg(reg
);
3649 value
= buf_get_u32(reg
->value
, 0, 32);
3650 command_print(cmd_ctx
, "%s (/%i): 0x%" PRIx32
"", reg
->name
, (int)(reg
->size
), value
);
3655 uint32_t value
= strtoul(args
[1], NULL
, 0);
3657 /* send CP write request (command 0x41) */
3658 xscale_send_u32(target
, 0x41);
3660 /* send CP register number */
3661 xscale_send_u32(target
, reg_no
);
3663 /* send CP register value */
3664 xscale_send_u32(target
, value
);
3666 /* execute cpwait to ensure outstanding operations complete */
3667 xscale_send_u32(target
, 0x53);
3671 command_print(cmd_ctx
, "usage: cp15 [register]<, [value]>");
3677 static int xscale_register_commands(struct command_context_s
*cmd_ctx
)
3679 command_t
*xscale_cmd
;
3681 xscale_cmd
= register_command(cmd_ctx
, NULL
, "xscale", NULL
, COMMAND_ANY
, "xscale specific commands");
3683 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");
3684 register_command(cmd_ctx
, xscale_cmd
, "cache_clean_address", xscale_handle_cache_clean_address_command
, COMMAND_ANY
, NULL
);
3686 register_command(cmd_ctx
, xscale_cmd
, "cache_info", xscale_handle_cache_info_command
, COMMAND_EXEC
, NULL
);
3687 register_command(cmd_ctx
, xscale_cmd
, "mmu", xscale_handle_mmu_command
, COMMAND_EXEC
, "['enable'|'disable'] the MMU");
3688 register_command(cmd_ctx
, xscale_cmd
, "icache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the ICache");
3689 register_command(cmd_ctx
, xscale_cmd
, "dcache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the DCache");
3691 register_command(cmd_ctx
, xscale_cmd
, "vector_catch", xscale_handle_vector_catch_command
, COMMAND_EXEC
, "<mask> of vectors that should be catched");
3692 register_command(cmd_ctx
, xscale_cmd
, "vector_table", xscale_handle_vector_table_command
, COMMAND_EXEC
, "<high|low> <index> <code> set static code for exception handler entry");
3694 register_command(cmd_ctx
, xscale_cmd
, "trace_buffer", xscale_handle_trace_buffer_command
, COMMAND_EXEC
, "<enable | disable> ['fill' [n]|'wrap']");
3696 register_command(cmd_ctx
, xscale_cmd
, "dump_trace", xscale_handle_dump_trace_command
, COMMAND_EXEC
, "dump content of trace buffer to <file>");
3697 register_command(cmd_ctx
, xscale_cmd
, "analyze_trace", xscale_handle_analyze_trace_buffer_command
, COMMAND_EXEC
, "analyze content of trace buffer");
3698 register_command(cmd_ctx
, xscale_cmd
, "trace_image", xscale_handle_trace_image_command
,
3699 COMMAND_EXEC
, "load image from <file> [base address]");
3701 register_command(cmd_ctx
, xscale_cmd
, "cp15", xscale_handle_cp15
, COMMAND_EXEC
, "access coproc 15 <register> [value]");
3703 armv4_5_register_commands(cmd_ctx
);
3708 target_type_t xscale_target
=
3712 .poll
= xscale_poll
,
3713 .arch_state
= xscale_arch_state
,
3715 .target_request_data
= NULL
,
3717 .halt
= xscale_halt
,
3718 .resume
= xscale_resume
,
3719 .step
= xscale_step
,
3721 .assert_reset
= xscale_assert_reset
,
3722 .deassert_reset
= xscale_deassert_reset
,
3723 .soft_reset_halt
= NULL
,
3725 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
3727 .read_memory
= xscale_read_memory
,
3728 .write_memory
= xscale_write_memory
,
3729 .bulk_write_memory
= xscale_bulk_write_memory
,
3730 .checksum_memory
= arm7_9_checksum_memory
,
3731 .blank_check_memory
= arm7_9_blank_check_memory
,
3733 .run_algorithm
= armv4_5_run_algorithm
,
3735 .add_breakpoint
= xscale_add_breakpoint
,
3736 .remove_breakpoint
= xscale_remove_breakpoint
,
3737 .add_watchpoint
= xscale_add_watchpoint
,
3738 .remove_watchpoint
= xscale_remove_watchpoint
,
3740 .register_commands
= xscale_register_commands
,
3741 .target_create
= xscale_target_create
,
3742 .init_target
= xscale_init_target
,
3743 .quit
= xscale_quit
,
3745 .virt2phys
= xscale_virt2phys
,
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)