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
;
894 if ((target
->state
== TARGET_RUNNING
) || (target
->state
== TARGET_DEBUG_RUNNING
))
896 enum target_state previous_state
= target
->state
;
897 if ((retval
= xscale_read_tx(target
, 0)) == ERROR_OK
)
900 /* there's data to read from the tx register, we entered debug state */
901 target
->state
= TARGET_HALTED
;
903 /* process debug entry, fetching current mode regs */
904 retval
= xscale_debug_entry(target
);
906 else if (retval
!= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
908 LOG_USER("error while polling TX register, reset CPU");
909 /* here we "lie" so GDB won't get stuck and a reset can be perfomed */
910 target
->state
= TARGET_HALTED
;
913 /* debug_entry could have overwritten target state (i.e. immediate resume)
914 * don't signal event handlers in that case
916 if (target
->state
!= TARGET_HALTED
)
919 /* if target was running, signal that we halted
920 * otherwise we reentered from debug execution */
921 if (previous_state
== TARGET_RUNNING
)
922 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
924 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
930 static int xscale_debug_entry(target_t
*target
)
932 armv4_5_common_t
*armv4_5
= target
->arch_info
;
933 xscale_common_t
*xscale
= armv4_5
->arch_info
;
941 /* clear external dbg break (will be written on next DCSR read) */
942 xscale
->external_debug_break
= 0;
943 if ((retval
= xscale_read_dcsr(target
)) != ERROR_OK
)
946 /* get r0, pc, r1 to r7 and cpsr */
947 if ((retval
= xscale_receive(target
, buffer
, 10)) != ERROR_OK
)
950 /* move r0 from buffer to register cache */
951 buf_set_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32, buffer
[0]);
952 armv4_5
->core_cache
->reg_list
[0].dirty
= 1;
953 armv4_5
->core_cache
->reg_list
[0].valid
= 1;
954 LOG_DEBUG("r0: 0x%8.8" PRIx32
"", buffer
[0]);
956 /* move pc from buffer to register cache */
957 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, buffer
[1]);
958 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
959 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
960 LOG_DEBUG("pc: 0x%8.8" PRIx32
"", buffer
[1]);
962 /* move data from buffer to register cache */
963 for (i
= 1; i
<= 7; i
++)
965 buf_set_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32, buffer
[1 + i
]);
966 armv4_5
->core_cache
->reg_list
[i
].dirty
= 1;
967 armv4_5
->core_cache
->reg_list
[i
].valid
= 1;
968 LOG_DEBUG("r%i: 0x%8.8" PRIx32
"", i
, buffer
[i
+ 1]);
971 buf_set_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32, buffer
[9]);
972 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].dirty
= 1;
973 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].valid
= 1;
974 LOG_DEBUG("cpsr: 0x%8.8" PRIx32
"", buffer
[9]);
976 armv4_5
->core_mode
= buffer
[9] & 0x1f;
977 if (armv4_5_mode_to_number(armv4_5
->core_mode
) == -1)
979 target
->state
= TARGET_UNKNOWN
;
980 LOG_ERROR("cpsr contains invalid mode value - communication failure");
981 return ERROR_TARGET_FAILURE
;
983 LOG_DEBUG("target entered debug state in %s mode", armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)]);
985 if (buffer
[9] & 0x20)
986 armv4_5
->core_state
= ARMV4_5_STATE_THUMB
;
988 armv4_5
->core_state
= ARMV4_5_STATE_ARM
;
991 if (armv4_5_mode_to_number(armv4_5
->core_mode
)==-1)
994 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
995 if ((armv4_5
->core_mode
!= ARMV4_5_MODE_USR
) && (armv4_5
->core_mode
!= ARMV4_5_MODE_SYS
))
997 xscale_receive(target
, buffer
, 8);
998 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
999 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
1000 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
1004 /* r8 to r14, but no spsr */
1005 xscale_receive(target
, buffer
, 7);
1008 /* move data from buffer to register cache */
1009 for (i
= 8; i
<= 14; i
++)
1011 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).value
, 0, 32, buffer
[i
- 8]);
1012 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).dirty
= 0;
1013 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).valid
= 1;
1016 /* examine debug reason */
1017 xscale_read_dcsr(target
);
1018 moe
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 2, 3);
1020 /* stored PC (for calculating fixup) */
1021 pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1025 case 0x0: /* Processor reset */
1026 target
->debug_reason
= DBG_REASON_DBGRQ
;
1027 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_RESET
;
1030 case 0x1: /* Instruction breakpoint hit */
1031 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1032 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1035 case 0x2: /* Data breakpoint hit */
1036 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
1037 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1040 case 0x3: /* BKPT instruction executed */
1041 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1042 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1045 case 0x4: /* Ext. debug event */
1046 target
->debug_reason
= DBG_REASON_DBGRQ
;
1047 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1050 case 0x5: /* Vector trap occured */
1051 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1052 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1055 case 0x6: /* Trace buffer full break */
1056 target
->debug_reason
= DBG_REASON_DBGRQ
;
1057 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_TB_FULL
;
1060 case 0x7: /* Reserved (may flag Hot-Debug support) */
1062 LOG_ERROR("Method of Entry is 'Reserved'");
1067 /* apply PC fixup */
1068 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, pc
);
1070 /* on the first debug entry, identify cache type */
1071 if (xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
1073 uint32_t cache_type_reg
;
1075 /* read cp15 cache type register */
1076 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
]);
1077 cache_type_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
].value
, 0, 32);
1079 armv4_5_identify_cache(cache_type_reg
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
1082 /* examine MMU and Cache settings */
1083 /* read cp15 control register */
1084 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
1085 xscale
->cp15_control_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
1086 xscale
->armv4_5_mmu
.mmu_enabled
= (xscale
->cp15_control_reg
& 0x1U
) ? 1 : 0;
1087 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= (xscale
->cp15_control_reg
& 0x4U
) ? 1 : 0;
1088 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= (xscale
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
1090 /* tracing enabled, read collected trace data */
1091 if (xscale
->trace
.buffer_enabled
)
1093 xscale_read_trace(target
);
1094 xscale
->trace
.buffer_fill
--;
1096 /* resume if we're still collecting trace data */
1097 if ((xscale
->arch_debug_reason
== XSCALE_DBG_REASON_TB_FULL
)
1098 && (xscale
->trace
.buffer_fill
> 0))
1100 xscale_resume(target
, 1, 0x0, 1, 0);
1104 xscale
->trace
.buffer_enabled
= 0;
1111 static int xscale_halt(target_t
*target
)
1113 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1114 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1116 LOG_DEBUG("target->state: %s",
1117 target_state_name(target
));
1119 if (target
->state
== TARGET_HALTED
)
1121 LOG_DEBUG("target was already halted");
1124 else if (target
->state
== TARGET_UNKNOWN
)
1126 /* this must not happen for a xscale target */
1127 LOG_ERROR("target was in unknown state when halt was requested");
1128 return ERROR_TARGET_INVALID
;
1130 else if (target
->state
== TARGET_RESET
)
1132 LOG_DEBUG("target->state == TARGET_RESET");
1136 /* assert external dbg break */
1137 xscale
->external_debug_break
= 1;
1138 xscale_read_dcsr(target
);
1140 target
->debug_reason
= DBG_REASON_DBGRQ
;
1146 static int xscale_enable_single_step(struct target_s
*target
, uint32_t next_pc
)
1148 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1149 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1150 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1153 if (xscale
->ibcr0_used
)
1155 breakpoint_t
*ibcr0_bp
= breakpoint_find(target
, buf_get_u32(ibcr0
->value
, 0, 32) & 0xfffffffe);
1159 xscale_unset_breakpoint(target
, ibcr0_bp
);
1163 LOG_ERROR("BUG: xscale->ibcr0_used is set, but no breakpoint with that address found");
1168 if ((retval
= xscale_set_reg_u32(ibcr0
, next_pc
| 0x1)) != ERROR_OK
)
1174 static int xscale_disable_single_step(struct target_s
*target
)
1176 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1177 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1178 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1181 if ((retval
= xscale_set_reg_u32(ibcr0
, 0x0)) != ERROR_OK
)
1187 static void xscale_enable_watchpoints(struct target_s
*target
)
1189 watchpoint_t
*watchpoint
= target
->watchpoints
;
1193 if (watchpoint
->set
== 0)
1194 xscale_set_watchpoint(target
, watchpoint
);
1195 watchpoint
= watchpoint
->next
;
1199 static void xscale_enable_breakpoints(struct target_s
*target
)
1201 breakpoint_t
*breakpoint
= target
->breakpoints
;
1203 /* set any pending breakpoints */
1206 if (breakpoint
->set
== 0)
1207 xscale_set_breakpoint(target
, breakpoint
);
1208 breakpoint
= breakpoint
->next
;
1212 static int xscale_resume(struct target_s
*target
, int current
,
1213 uint32_t address
, int handle_breakpoints
, int debug_execution
)
1215 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1216 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1217 breakpoint_t
*breakpoint
= target
->breakpoints
;
1219 uint32_t current_pc
;
1226 if (target
->state
!= TARGET_HALTED
)
1228 LOG_WARNING("target not halted");
1229 return ERROR_TARGET_NOT_HALTED
;
1232 if (!debug_execution
)
1234 target_free_all_working_areas(target
);
1237 /* update vector tables */
1238 if ((retval
= xscale_update_vectors(target
)) != ERROR_OK
)
1241 /* current = 1: continue on current pc, otherwise continue at <address> */
1243 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1245 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1247 /* if we're at the reset vector, we have to simulate the branch */
1248 if (current_pc
== 0x0)
1250 arm_simulate_step(target
, NULL
);
1251 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1254 /* the front-end may request us not to handle breakpoints */
1255 if (handle_breakpoints
)
1257 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1261 /* there's a breakpoint at the current PC, we have to step over it */
1262 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
"", breakpoint
->address
);
1263 xscale_unset_breakpoint(target
, breakpoint
);
1265 /* calculate PC of next instruction */
1266 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1268 uint32_t current_opcode
;
1269 target_read_u32(target
, current_pc
, ¤t_opcode
);
1270 LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8" PRIx32
"", current_opcode
);
1273 LOG_DEBUG("enable single-step");
1274 xscale_enable_single_step(target
, next_pc
);
1276 /* restore banked registers */
1277 xscale_restore_context(target
);
1279 /* send resume request (command 0x30 or 0x31)
1280 * clean the trace buffer if it is to be enabled (0x62) */
1281 if (xscale
->trace
.buffer_enabled
)
1283 xscale_send_u32(target
, 0x62);
1284 xscale_send_u32(target
, 0x31);
1287 xscale_send_u32(target
, 0x30);
1290 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1291 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));
1293 for (i
= 7; i
>= 0; i
--)
1296 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1297 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));
1301 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1302 LOG_DEBUG("writing PC with value 0x%8.8" PRIx32
"", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1304 /* wait for and process debug entry */
1305 xscale_debug_entry(target
);
1307 LOG_DEBUG("disable single-step");
1308 xscale_disable_single_step(target
);
1310 LOG_DEBUG("set breakpoint at 0x%8.8" PRIx32
"", breakpoint
->address
);
1311 xscale_set_breakpoint(target
, breakpoint
);
1315 /* enable any pending breakpoints and watchpoints */
1316 xscale_enable_breakpoints(target
);
1317 xscale_enable_watchpoints(target
);
1319 /* restore banked registers */
1320 xscale_restore_context(target
);
1322 /* send resume request (command 0x30 or 0x31)
1323 * clean the trace buffer if it is to be enabled (0x62) */
1324 if (xscale
->trace
.buffer_enabled
)
1326 xscale_send_u32(target
, 0x62);
1327 xscale_send_u32(target
, 0x31);
1330 xscale_send_u32(target
, 0x30);
1333 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1334 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));
1336 for (i
= 7; i
>= 0; i
--)
1339 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1340 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));
1344 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1345 LOG_DEBUG("writing PC with value 0x%8.8" PRIx32
"", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1347 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1349 if (!debug_execution
)
1351 /* registers are now invalid */
1352 armv4_5_invalidate_core_regs(target
);
1353 target
->state
= TARGET_RUNNING
;
1354 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1358 target
->state
= TARGET_DEBUG_RUNNING
;
1359 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1362 LOG_DEBUG("target resumed");
1367 static int xscale_step_inner(struct target_s
*target
, int current
,
1368 uint32_t address
, int handle_breakpoints
)
1370 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1371 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1377 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1379 /* calculate PC of next instruction */
1380 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1382 uint32_t current_opcode
, current_pc
;
1383 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1385 target_read_u32(target
, current_pc
, ¤t_opcode
);
1386 LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8" PRIx32
"", current_opcode
);
1390 LOG_DEBUG("enable single-step");
1391 if ((retval
= xscale_enable_single_step(target
, next_pc
)) != ERROR_OK
)
1394 /* restore banked registers */
1395 if ((retval
= xscale_restore_context(target
)) != ERROR_OK
)
1398 /* send resume request (command 0x30 or 0x31)
1399 * clean the trace buffer if it is to be enabled (0x62) */
1400 if (xscale
->trace
.buffer_enabled
)
1402 if ((retval
= xscale_send_u32(target
, 0x62)) != ERROR_OK
)
1404 if ((retval
= xscale_send_u32(target
, 0x31)) != ERROR_OK
)
1408 if ((retval
= xscale_send_u32(target
, 0x30)) != ERROR_OK
)
1412 if ((retval
= xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32))) != ERROR_OK
)
1414 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));
1416 for (i
= 7; i
>= 0; i
--)
1419 if ((retval
= xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32))) != ERROR_OK
)
1421 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));
1425 if ((retval
= xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))) != ERROR_OK
)
1427 LOG_DEBUG("writing PC with value 0x%8.8" PRIx32
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1429 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1431 /* registers are now invalid */
1432 if ((retval
= armv4_5_invalidate_core_regs(target
)) != ERROR_OK
)
1435 /* wait for and process debug entry */
1436 if ((retval
= xscale_debug_entry(target
)) != ERROR_OK
)
1439 LOG_DEBUG("disable single-step");
1440 if ((retval
= xscale_disable_single_step(target
)) != ERROR_OK
)
1443 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1448 static int xscale_step(struct target_s
*target
, int current
,
1449 uint32_t address
, int handle_breakpoints
)
1451 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1452 breakpoint_t
*breakpoint
= target
->breakpoints
;
1454 uint32_t current_pc
;
1457 if (target
->state
!= TARGET_HALTED
)
1459 LOG_WARNING("target not halted");
1460 return ERROR_TARGET_NOT_HALTED
;
1463 /* current = 1: continue on current pc, otherwise continue at <address> */
1465 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1467 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1469 /* if we're at the reset vector, we have to simulate the step */
1470 if (current_pc
== 0x0)
1472 if ((retval
= arm_simulate_step(target
, NULL
)) != ERROR_OK
)
1474 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1476 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1477 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1482 /* the front-end may request us not to handle breakpoints */
1483 if (handle_breakpoints
)
1484 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1486 if ((retval
= xscale_unset_breakpoint(target
, breakpoint
)) != ERROR_OK
)
1490 retval
= xscale_step_inner(target
, current
, address
, handle_breakpoints
);
1494 xscale_set_breakpoint(target
, breakpoint
);
1497 LOG_DEBUG("target stepped");
1503 static int xscale_assert_reset(target_t
*target
)
1505 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1506 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1508 LOG_DEBUG("target->state: %s",
1509 target_state_name(target
));
1511 /* select DCSR instruction (set endstate to R-T-I to ensure we don't
1512 * end up in T-L-R, which would reset JTAG
1514 jtag_set_end_state(TAP_IDLE
);
1515 xscale_jtag_set_instr(target
->tap
, XSCALE_SELDCSR
);
1517 /* set Hold reset, Halt mode and Trap Reset */
1518 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1519 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1520 xscale_write_dcsr(target
, 1, 0);
1522 /* select BYPASS, because having DCSR selected caused problems on the PXA27x */
1523 xscale_jtag_set_instr(target
->tap
, 0x7f);
1524 jtag_execute_queue();
1527 jtag_add_reset(0, 1);
1529 /* sleep 1ms, to be sure we fulfill any requirements */
1530 jtag_add_sleep(1000);
1531 jtag_execute_queue();
1533 target
->state
= TARGET_RESET
;
1535 if (target
->reset_halt
)
1538 if ((retval
= target_halt(target
)) != ERROR_OK
)
1545 static int xscale_deassert_reset(target_t
*target
)
1547 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1548 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1549 breakpoint_t
*breakpoint
= target
->breakpoints
;
1553 xscale
->ibcr_available
= 2;
1554 xscale
->ibcr0_used
= 0;
1555 xscale
->ibcr1_used
= 0;
1557 xscale
->dbr_available
= 2;
1558 xscale
->dbr0_used
= 0;
1559 xscale
->dbr1_used
= 0;
1561 /* mark all hardware breakpoints as unset */
1564 if (breakpoint
->type
== BKPT_HARD
)
1566 breakpoint
->set
= 0;
1568 breakpoint
= breakpoint
->next
;
1571 armv4_5_invalidate_core_regs(target
);
1573 /* FIXME mark hardware watchpoints got unset too. Also,
1574 * at least some of the XScale registers are invalid...
1578 * REVISIT: *assumes* we had a SRST+TRST reset so the mini-icache
1579 * contents got invalidated. Safer to force that, so writing new
1580 * contents can't ever fail..
1585 const uint8_t *buffer
= xscale_debug_handler
;
1589 jtag_add_reset(0, 0);
1591 /* wait 300ms; 150 and 100ms were not enough */
1592 jtag_add_sleep(300*1000);
1594 jtag_add_runtest(2030, jtag_set_end_state(TAP_IDLE
));
1595 jtag_execute_queue();
1597 /* set Hold reset, Halt mode and Trap Reset */
1598 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1599 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1600 xscale_write_dcsr(target
, 1, 0);
1602 /* Load the debug handler into the mini-icache. Since
1603 * it's using halt mode (not monitor mode), it runs in
1604 * "Special Debug State" for access to registers, memory,
1605 * coprocessors, trace data, etc.
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);
1680 static int xscale_read_core_reg(struct target_s
*target
, int num
,
1681 enum armv4_5_mode mode
)
1683 LOG_ERROR("not implemented");
1687 static int xscale_write_core_reg(struct target_s
*target
, int num
,
1688 enum armv4_5_mode mode
, uint32_t value
)
1690 LOG_ERROR("not implemented");
1694 static int xscale_full_context(target_t
*target
)
1696 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1704 if (target
->state
!= TARGET_HALTED
)
1706 LOG_WARNING("target not halted");
1707 return ERROR_TARGET_NOT_HALTED
;
1710 buffer
= malloc(4 * 8);
1712 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1713 * we can't enter User mode on an XScale (unpredictable),
1714 * but User shares registers with SYS
1716 for (i
= 1; i
< 7; i
++)
1720 /* check if there are invalid registers in the current mode
1722 for (j
= 0; j
<= 16; j
++)
1724 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
== 0)
1732 /* request banked registers */
1733 xscale_send_u32(target
, 0x0);
1736 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1737 tmp_cpsr
|= 0xc0; /* I/F bits */
1739 /* send CPSR for desired mode */
1740 xscale_send_u32(target
, tmp_cpsr
);
1742 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1743 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1745 xscale_receive(target
, buffer
, 8);
1746 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1747 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1748 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).valid
= 1;
1752 xscale_receive(target
, buffer
, 7);
1755 /* move data from buffer to register cache */
1756 for (j
= 8; j
<= 14; j
++)
1758 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]);
1759 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1760 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
= 1;
1770 static int xscale_restore_context(target_t
*target
)
1772 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1776 if (target
->state
!= TARGET_HALTED
)
1778 LOG_WARNING("target not halted");
1779 return ERROR_TARGET_NOT_HALTED
;
1782 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1783 * we can't enter User mode on an XScale (unpredictable),
1784 * but User shares registers with SYS
1786 for (i
= 1; i
< 7; i
++)
1790 /* check if there are invalid registers in the current mode
1792 for (j
= 8; j
<= 14; j
++)
1794 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
== 1)
1798 /* if not USR/SYS, check if the SPSR needs to be written */
1799 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1801 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
== 1)
1809 /* send banked registers */
1810 xscale_send_u32(target
, 0x1);
1813 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1814 tmp_cpsr
|= 0xc0; /* I/F bits */
1816 /* send CPSR for desired mode */
1817 xscale_send_u32(target
, tmp_cpsr
);
1819 /* send banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1820 for (j
= 8; j
<= 14; j
++)
1822 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, j
).value
, 0, 32));
1823 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1826 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1828 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32));
1829 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1837 static int xscale_read_memory(struct target_s
*target
, uint32_t address
,
1838 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1840 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1841 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1846 LOG_DEBUG("address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
, address
, size
, count
);
1848 if (target
->state
!= TARGET_HALTED
)
1850 LOG_WARNING("target not halted");
1851 return ERROR_TARGET_NOT_HALTED
;
1854 /* sanitize arguments */
1855 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1856 return ERROR_INVALID_ARGUMENTS
;
1858 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1859 return ERROR_TARGET_UNALIGNED_ACCESS
;
1861 /* send memory read request (command 0x1n, n: access size) */
1862 if ((retval
= xscale_send_u32(target
, 0x10 | size
)) != ERROR_OK
)
1865 /* send base address for read request */
1866 if ((retval
= xscale_send_u32(target
, address
)) != ERROR_OK
)
1869 /* send number of requested data words */
1870 if ((retval
= xscale_send_u32(target
, count
)) != ERROR_OK
)
1873 /* receive data from target (count times 32-bit words in host endianness) */
1874 buf32
= malloc(4 * count
);
1875 if ((retval
= xscale_receive(target
, buf32
, count
)) != ERROR_OK
)
1878 /* extract data from host-endian buffer into byte stream */
1879 for (i
= 0; i
< count
; i
++)
1884 target_buffer_set_u32(target
, buffer
, buf32
[i
]);
1888 target_buffer_set_u16(target
, buffer
, buf32
[i
] & 0xffff);
1892 *buffer
++ = buf32
[i
] & 0xff;
1895 LOG_ERROR("should never get here");
1902 /* examine DCSR, to see if Sticky Abort (SA) got set */
1903 if ((retval
= xscale_read_dcsr(target
)) != ERROR_OK
)
1905 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
1908 if ((retval
= xscale_send_u32(target
, 0x60)) != ERROR_OK
)
1911 return ERROR_TARGET_DATA_ABORT
;
1917 static int xscale_write_memory(struct target_s
*target
, uint32_t address
,
1918 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1920 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1921 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1924 LOG_DEBUG("address: 0x%8.8" PRIx32
", size: 0x%8.8" PRIx32
", count: 0x%8.8" PRIx32
, address
, size
, count
);
1926 if (target
->state
!= TARGET_HALTED
)
1928 LOG_WARNING("target not halted");
1929 return ERROR_TARGET_NOT_HALTED
;
1932 /* sanitize arguments */
1933 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1934 return ERROR_INVALID_ARGUMENTS
;
1936 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1937 return ERROR_TARGET_UNALIGNED_ACCESS
;
1939 /* send memory write request (command 0x2n, n: access size) */
1940 if ((retval
= xscale_send_u32(target
, 0x20 | size
)) != ERROR_OK
)
1943 /* send base address for read request */
1944 if ((retval
= xscale_send_u32(target
, address
)) != ERROR_OK
)
1947 /* send number of requested data words to be written*/
1948 if ((retval
= xscale_send_u32(target
, count
)) != ERROR_OK
)
1951 /* extract data from host-endian buffer into byte stream */
1953 for (i
= 0; i
< count
; i
++)
1958 value
= target_buffer_get_u32(target
, buffer
);
1959 xscale_send_u32(target
, value
);
1963 value
= target_buffer_get_u16(target
, buffer
);
1964 xscale_send_u32(target
, value
);
1969 xscale_send_u32(target
, value
);
1973 LOG_ERROR("should never get here");
1978 if ((retval
= xscale_send(target
, buffer
, count
, size
)) != ERROR_OK
)
1981 /* examine DCSR, to see if Sticky Abort (SA) got set */
1982 if ((retval
= xscale_read_dcsr(target
)) != ERROR_OK
)
1984 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
1987 if ((retval
= xscale_send_u32(target
, 0x60)) != ERROR_OK
)
1990 return ERROR_TARGET_DATA_ABORT
;
1996 static int xscale_bulk_write_memory(target_t
*target
, uint32_t address
,
1997 uint32_t count
, uint8_t *buffer
)
1999 return xscale_write_memory(target
, address
, 4, count
, buffer
);
2002 static uint32_t xscale_get_ttb(target_t
*target
)
2004 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2005 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2008 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_TTB
]);
2009 ttb
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_TTB
].value
, 0, 32);
2014 static void xscale_disable_mmu_caches(target_t
*target
, int mmu
,
2015 int d_u_cache
, int i_cache
)
2017 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2018 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2019 uint32_t cp15_control
;
2021 /* read cp15 control register */
2022 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2023 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2026 cp15_control
&= ~0x1U
;
2031 xscale_send_u32(target
, 0x50);
2032 xscale_send_u32(target
, xscale
->cache_clean_address
);
2034 /* invalidate DCache */
2035 xscale_send_u32(target
, 0x51);
2037 cp15_control
&= ~0x4U
;
2042 /* invalidate ICache */
2043 xscale_send_u32(target
, 0x52);
2044 cp15_control
&= ~0x1000U
;
2047 /* write new cp15 control register */
2048 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2050 /* execute cpwait to ensure outstanding operations complete */
2051 xscale_send_u32(target
, 0x53);
2054 static void xscale_enable_mmu_caches(target_t
*target
, int mmu
,
2055 int d_u_cache
, int i_cache
)
2057 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2058 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2059 uint32_t cp15_control
;
2061 /* read cp15 control register */
2062 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2063 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2066 cp15_control
|= 0x1U
;
2069 cp15_control
|= 0x4U
;
2072 cp15_control
|= 0x1000U
;
2074 /* write new cp15 control register */
2075 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2077 /* execute cpwait to ensure outstanding operations complete */
2078 xscale_send_u32(target
, 0x53);
2081 static int xscale_set_breakpoint(struct target_s
*target
,
2082 breakpoint_t
*breakpoint
)
2085 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2086 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2088 if (target
->state
!= TARGET_HALTED
)
2090 LOG_WARNING("target not halted");
2091 return ERROR_TARGET_NOT_HALTED
;
2094 if (breakpoint
->set
)
2096 LOG_WARNING("breakpoint already set");
2100 if (breakpoint
->type
== BKPT_HARD
)
2102 uint32_t value
= breakpoint
->address
| 1;
2103 if (!xscale
->ibcr0_used
)
2105 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], value
);
2106 xscale
->ibcr0_used
= 1;
2107 breakpoint
->set
= 1; /* breakpoint set on first breakpoint register */
2109 else if (!xscale
->ibcr1_used
)
2111 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], value
);
2112 xscale
->ibcr1_used
= 1;
2113 breakpoint
->set
= 2; /* breakpoint set on second breakpoint register */
2117 LOG_ERROR("BUG: no hardware comparator available");
2121 else if (breakpoint
->type
== BKPT_SOFT
)
2123 if (breakpoint
->length
== 4)
2125 /* keep the original instruction in target endianness */
2126 if ((retval
= target_read_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
2130 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2131 if ((retval
= target_write_u32(target
, breakpoint
->address
, xscale
->arm_bkpt
)) != ERROR_OK
)
2138 /* keep the original instruction in target endianness */
2139 if ((retval
= target_read_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
2143 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2144 if ((retval
= target_write_u32(target
, breakpoint
->address
, xscale
->thumb_bkpt
)) != ERROR_OK
)
2149 breakpoint
->set
= 1;
2155 static int xscale_add_breakpoint(struct target_s
*target
,
2156 breakpoint_t
*breakpoint
)
2158 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2159 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2161 if (target
->state
!= TARGET_HALTED
)
2163 LOG_WARNING("target not halted");
2164 return ERROR_TARGET_NOT_HALTED
;
2167 if ((breakpoint
->type
== BKPT_HARD
) && (xscale
->ibcr_available
< 1))
2169 LOG_INFO("no breakpoint unit available for hardware breakpoint");
2170 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2173 if ((breakpoint
->length
!= 2) && (breakpoint
->length
!= 4))
2175 LOG_INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
2176 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2179 if (breakpoint
->type
== BKPT_HARD
)
2181 xscale
->ibcr_available
--;
2187 static int xscale_unset_breakpoint(struct target_s
*target
,
2188 breakpoint_t
*breakpoint
)
2191 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2192 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2194 if (target
->state
!= TARGET_HALTED
)
2196 LOG_WARNING("target not halted");
2197 return ERROR_TARGET_NOT_HALTED
;
2200 if (!breakpoint
->set
)
2202 LOG_WARNING("breakpoint not set");
2206 if (breakpoint
->type
== BKPT_HARD
)
2208 if (breakpoint
->set
== 1)
2210 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], 0x0);
2211 xscale
->ibcr0_used
= 0;
2213 else if (breakpoint
->set
== 2)
2215 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], 0x0);
2216 xscale
->ibcr1_used
= 0;
2218 breakpoint
->set
= 0;
2222 /* restore original instruction (kept in target endianness) */
2223 if (breakpoint
->length
== 4)
2225 if ((retval
= target_write_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
2232 if ((retval
= target_write_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
2237 breakpoint
->set
= 0;
2243 static int xscale_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2245 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2246 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2248 if (target
->state
!= TARGET_HALTED
)
2250 LOG_WARNING("target not halted");
2251 return ERROR_TARGET_NOT_HALTED
;
2254 if (breakpoint
->set
)
2256 xscale_unset_breakpoint(target
, breakpoint
);
2259 if (breakpoint
->type
== BKPT_HARD
)
2260 xscale
->ibcr_available
++;
2265 static int xscale_set_watchpoint(struct target_s
*target
,
2266 watchpoint_t
*watchpoint
)
2268 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2269 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2271 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2272 uint32_t dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2274 if (target
->state
!= TARGET_HALTED
)
2276 LOG_WARNING("target not halted");
2277 return ERROR_TARGET_NOT_HALTED
;
2280 xscale_get_reg(dbcon
);
2282 switch (watchpoint
->rw
)
2294 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
2297 if (!xscale
->dbr0_used
)
2299 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR0
], watchpoint
->address
);
2300 dbcon_value
|= enable
;
2301 xscale_set_reg_u32(dbcon
, dbcon_value
);
2302 watchpoint
->set
= 1;
2303 xscale
->dbr0_used
= 1;
2305 else if (!xscale
->dbr1_used
)
2307 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR1
], watchpoint
->address
);
2308 dbcon_value
|= enable
<< 2;
2309 xscale_set_reg_u32(dbcon
, dbcon_value
);
2310 watchpoint
->set
= 2;
2311 xscale
->dbr1_used
= 1;
2315 LOG_ERROR("BUG: no hardware comparator available");
2322 static int xscale_add_watchpoint(struct target_s
*target
,
2323 watchpoint_t
*watchpoint
)
2325 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2326 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2328 if (target
->state
!= TARGET_HALTED
)
2330 LOG_WARNING("target not halted");
2331 return ERROR_TARGET_NOT_HALTED
;
2334 if (xscale
->dbr_available
< 1)
2336 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2339 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
2341 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2344 xscale
->dbr_available
--;
2349 static int xscale_unset_watchpoint(struct target_s
*target
,
2350 watchpoint_t
*watchpoint
)
2352 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2353 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2354 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2355 uint32_t dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2357 if (target
->state
!= TARGET_HALTED
)
2359 LOG_WARNING("target not halted");
2360 return ERROR_TARGET_NOT_HALTED
;
2363 if (!watchpoint
->set
)
2365 LOG_WARNING("breakpoint not set");
2369 if (watchpoint
->set
== 1)
2371 dbcon_value
&= ~0x3;
2372 xscale_set_reg_u32(dbcon
, dbcon_value
);
2373 xscale
->dbr0_used
= 0;
2375 else if (watchpoint
->set
== 2)
2377 dbcon_value
&= ~0xc;
2378 xscale_set_reg_u32(dbcon
, dbcon_value
);
2379 xscale
->dbr1_used
= 0;
2381 watchpoint
->set
= 0;
2386 static int xscale_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2388 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2389 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2391 if (target
->state
!= TARGET_HALTED
)
2393 LOG_WARNING("target not halted");
2394 return ERROR_TARGET_NOT_HALTED
;
2397 if (watchpoint
->set
)
2399 xscale_unset_watchpoint(target
, watchpoint
);
2402 xscale
->dbr_available
++;
2407 static int xscale_get_reg(reg_t
*reg
)
2409 xscale_reg_t
*arch_info
= reg
->arch_info
;
2410 target_t
*target
= arch_info
->target
;
2411 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2412 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2414 /* DCSR, TX and RX are accessible via JTAG */
2415 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2417 return xscale_read_dcsr(arch_info
->target
);
2419 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2421 /* 1 = consume register content */
2422 return xscale_read_tx(arch_info
->target
, 1);
2424 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2426 /* can't read from RX register (host -> debug handler) */
2429 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2431 /* can't (explicitly) read from TXRXCTRL register */
2434 else /* Other DBG registers have to be transfered by the debug handler */
2436 /* send CP read request (command 0x40) */
2437 xscale_send_u32(target
, 0x40);
2439 /* send CP register number */
2440 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2442 /* read register value */
2443 xscale_read_tx(target
, 1);
2444 buf_cpy(xscale
->reg_cache
->reg_list
[XSCALE_TX
].value
, reg
->value
, 32);
2453 static int xscale_set_reg(reg_t
*reg
, uint8_t* buf
)
2455 xscale_reg_t
*arch_info
= reg
->arch_info
;
2456 target_t
*target
= arch_info
->target
;
2457 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2458 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2459 uint32_t value
= buf_get_u32(buf
, 0, 32);
2461 /* DCSR, TX and RX are accessible via JTAG */
2462 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2464 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32, value
);
2465 return xscale_write_dcsr(arch_info
->target
, -1, -1);
2467 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2469 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
2470 return xscale_write_rx(arch_info
->target
);
2472 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2474 /* can't write to TX register (debug-handler -> host) */
2477 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2479 /* can't (explicitly) write to TXRXCTRL register */
2482 else /* Other DBG registers have to be transfered by the debug handler */
2484 /* send CP write request (command 0x41) */
2485 xscale_send_u32(target
, 0x41);
2487 /* send CP register number */
2488 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2490 /* send CP register value */
2491 xscale_send_u32(target
, value
);
2492 buf_set_u32(reg
->value
, 0, 32, value
);
2498 static int xscale_write_dcsr_sw(target_t
*target
, uint32_t value
)
2500 /* get pointers to arch-specific information */
2501 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2502 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2503 reg_t
*dcsr
= &xscale
->reg_cache
->reg_list
[XSCALE_DCSR
];
2504 xscale_reg_t
*dcsr_arch_info
= dcsr
->arch_info
;
2506 /* send CP write request (command 0x41) */
2507 xscale_send_u32(target
, 0x41);
2509 /* send CP register number */
2510 xscale_send_u32(target
, dcsr_arch_info
->dbg_handler_number
);
2512 /* send CP register value */
2513 xscale_send_u32(target
, value
);
2514 buf_set_u32(dcsr
->value
, 0, 32, value
);
2519 static int xscale_read_trace(target_t
*target
)
2521 /* get pointers to arch-specific information */
2522 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2523 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2524 xscale_trace_data_t
**trace_data_p
;
2526 /* 258 words from debug handler
2527 * 256 trace buffer entries
2528 * 2 checkpoint addresses
2530 uint32_t trace_buffer
[258];
2531 int is_address
[256];
2534 if (target
->state
!= TARGET_HALTED
)
2536 LOG_WARNING("target must be stopped to read trace data");
2537 return ERROR_TARGET_NOT_HALTED
;
2540 /* send read trace buffer command (command 0x61) */
2541 xscale_send_u32(target
, 0x61);
2543 /* receive trace buffer content */
2544 xscale_receive(target
, trace_buffer
, 258);
2546 /* parse buffer backwards to identify address entries */
2547 for (i
= 255; i
>= 0; i
--)
2550 if (((trace_buffer
[i
] & 0xf0) == 0x90) ||
2551 ((trace_buffer
[i
] & 0xf0) == 0xd0))
2554 is_address
[--i
] = 1;
2556 is_address
[--i
] = 1;
2558 is_address
[--i
] = 1;
2560 is_address
[--i
] = 1;
2565 /* search first non-zero entry */
2566 for (j
= 0; (j
< 256) && (trace_buffer
[j
] == 0) && (!is_address
[j
]); j
++)
2571 LOG_DEBUG("no trace data collected");
2572 return ERROR_XSCALE_NO_TRACE_DATA
;
2575 for (trace_data_p
= &xscale
->trace
.data
; *trace_data_p
; trace_data_p
= &(*trace_data_p
)->next
)
2578 *trace_data_p
= malloc(sizeof(xscale_trace_data_t
));
2579 (*trace_data_p
)->next
= NULL
;
2580 (*trace_data_p
)->chkpt0
= trace_buffer
[256];
2581 (*trace_data_p
)->chkpt1
= trace_buffer
[257];
2582 (*trace_data_p
)->last_instruction
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
2583 (*trace_data_p
)->entries
= malloc(sizeof(xscale_trace_entry_t
) * (256 - j
));
2584 (*trace_data_p
)->depth
= 256 - j
;
2586 for (i
= j
; i
< 256; i
++)
2588 (*trace_data_p
)->entries
[i
- j
].data
= trace_buffer
[i
];
2590 (*trace_data_p
)->entries
[i
- j
].type
= XSCALE_TRACE_ADDRESS
;
2592 (*trace_data_p
)->entries
[i
- j
].type
= XSCALE_TRACE_MESSAGE
;
2598 static int xscale_read_instruction(target_t
*target
,
2599 arm_instruction_t
*instruction
)
2601 /* get pointers to arch-specific information */
2602 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2603 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2610 if (!xscale
->trace
.image
)
2611 return ERROR_TRACE_IMAGE_UNAVAILABLE
;
2613 /* search for the section the current instruction belongs to */
2614 for (i
= 0; i
< xscale
->trace
.image
->num_sections
; i
++)
2616 if ((xscale
->trace
.image
->sections
[i
].base_address
<= xscale
->trace
.current_pc
) &&
2617 (xscale
->trace
.image
->sections
[i
].base_address
+ xscale
->trace
.image
->sections
[i
].size
> xscale
->trace
.current_pc
))
2626 /* current instruction couldn't be found in the image */
2627 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2630 if (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
)
2633 if ((retval
= image_read_section(xscale
->trace
.image
, section
,
2634 xscale
->trace
.current_pc
- xscale
->trace
.image
->sections
[section
].base_address
,
2635 4, buf
, &size_read
)) != ERROR_OK
)
2637 LOG_ERROR("error while reading instruction: %i", retval
);
2638 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2640 opcode
= target_buffer_get_u32(target
, buf
);
2641 arm_evaluate_opcode(opcode
, xscale
->trace
.current_pc
, instruction
);
2643 else if (xscale
->trace
.core_state
== ARMV4_5_STATE_THUMB
)
2646 if ((retval
= image_read_section(xscale
->trace
.image
, section
,
2647 xscale
->trace
.current_pc
- xscale
->trace
.image
->sections
[section
].base_address
,
2648 2, buf
, &size_read
)) != ERROR_OK
)
2650 LOG_ERROR("error while reading instruction: %i", retval
);
2651 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2653 opcode
= target_buffer_get_u16(target
, buf
);
2654 thumb_evaluate_opcode(opcode
, xscale
->trace
.current_pc
, instruction
);
2658 LOG_ERROR("BUG: unknown core state encountered");
2665 static int xscale_branch_address(xscale_trace_data_t
*trace_data
,
2666 int i
, uint32_t *target
)
2668 /* if there are less than four entries prior to the indirect branch message
2669 * we can't extract the address */
2675 *target
= (trace_data
->entries
[i
-1].data
) | (trace_data
->entries
[i
-2].data
<< 8) |
2676 (trace_data
->entries
[i
-3].data
<< 16) | (trace_data
->entries
[i
-4].data
<< 24);
2681 static int xscale_analyze_trace(target_t
*target
, command_context_t
*cmd_ctx
)
2683 /* get pointers to arch-specific information */
2684 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2685 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2687 uint32_t next_pc
= 0x0;
2688 xscale_trace_data_t
*trace_data
= xscale
->trace
.data
;
2697 xscale
->trace
.core_state
= ARMV4_5_STATE_ARM
;
2702 for (i
= 0; i
< trace_data
->depth
; i
++)
2708 if (trace_data
->entries
[i
].type
== XSCALE_TRACE_ADDRESS
)
2711 switch ((trace_data
->entries
[i
].data
& 0xf0) >> 4)
2713 case 0: /* Exceptions */
2721 exception
= (trace_data
->entries
[i
].data
& 0x70) >> 4;
2723 next_pc
= (trace_data
->entries
[i
].data
& 0xf0) >> 2;
2724 command_print(cmd_ctx
, "--- exception %i ---", (trace_data
->entries
[i
].data
& 0xf0) >> 4);
2726 case 8: /* Direct Branch */
2729 case 9: /* Indirect Branch */
2731 if (xscale_branch_address(trace_data
, i
, &next_pc
) == 0)
2736 case 13: /* Checkpointed Indirect Branch */
2737 if (xscale_branch_address(trace_data
, i
, &next_pc
) == 0)
2740 if (((chkpt
== 0) && (next_pc
!= trace_data
->chkpt0
))
2741 || ((chkpt
== 1) && (next_pc
!= trace_data
->chkpt1
)))
2742 LOG_WARNING("checkpointed indirect branch target address doesn't match checkpoint");
2744 /* explicit fall-through */
2745 case 12: /* Checkpointed Direct Branch */
2750 next_pc
= trace_data
->chkpt0
;
2753 else if (chkpt
== 1)
2756 next_pc
= trace_data
->chkpt0
;
2761 LOG_WARNING("more than two checkpointed branches encountered");
2764 case 15: /* Roll-over */
2767 default: /* Reserved */
2768 command_print(cmd_ctx
, "--- reserved trace message ---");
2769 LOG_ERROR("BUG: trace message %i is reserved", (trace_data
->entries
[i
].data
& 0xf0) >> 4);
2773 if (xscale
->trace
.pc_ok
)
2775 int executed
= (trace_data
->entries
[i
].data
& 0xf) + rollover
* 16;
2776 arm_instruction_t instruction
;
2778 if ((exception
== 6) || (exception
== 7))
2780 /* IRQ or FIQ exception, no instruction executed */
2784 while (executed
-- >= 0)
2786 if ((retval
= xscale_read_instruction(target
, &instruction
)) != ERROR_OK
)
2788 /* can't continue tracing with no image available */
2789 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
2793 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
2795 /* TODO: handle incomplete images */
2799 /* a precise abort on a load to the PC is included in the incremental
2800 * word count, other instructions causing data aborts are not included
2802 if ((executed
== 0) && (exception
== 4)
2803 && ((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_LDM
)))
2805 if ((instruction
.type
== ARM_LDM
)
2806 && ((instruction
.info
.load_store_multiple
.register_list
& 0x8000) == 0))
2810 else if (((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_LDRSH
))
2811 && (instruction
.info
.load_store
.Rd
!= 15))
2817 /* only the last instruction executed
2818 * (the one that caused the control flow change)
2819 * could be a taken branch
2821 if (((executed
== -1) && (branch
== 1)) &&
2822 (((instruction
.type
== ARM_B
) ||
2823 (instruction
.type
== ARM_BL
) ||
2824 (instruction
.type
== ARM_BLX
)) &&
2825 (instruction
.info
.b_bl_bx_blx
.target_address
!= 0xffffffff)))
2827 xscale
->trace
.current_pc
= instruction
.info
.b_bl_bx_blx
.target_address
;
2831 xscale
->trace
.current_pc
+= (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2;
2833 command_print(cmd_ctx
, "%s", instruction
.text
);
2841 xscale
->trace
.current_pc
= next_pc
;
2842 xscale
->trace
.pc_ok
= 1;
2846 for (; xscale
->trace
.current_pc
< trace_data
->last_instruction
; xscale
->trace
.current_pc
+= (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2)
2848 arm_instruction_t instruction
;
2849 if ((retval
= xscale_read_instruction(target
, &instruction
)) != ERROR_OK
)
2851 /* can't continue tracing with no image available */
2852 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
2856 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
2858 /* TODO: handle incomplete images */
2861 command_print(cmd_ctx
, "%s", instruction
.text
);
2864 trace_data
= trace_data
->next
;
2870 static void xscale_build_reg_cache(target_t
*target
)
2872 /* get pointers to arch-specific information */
2873 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2874 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2876 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
2877 xscale_reg_t
*arch_info
= malloc(sizeof(xscale_reg_arch_info
));
2879 int num_regs
= sizeof(xscale_reg_arch_info
) / sizeof(xscale_reg_t
);
2881 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
2882 armv4_5
->core_cache
= (*cache_p
);
2884 /* register a register arch-type for XScale dbg registers only once */
2885 if (xscale_reg_arch_type
== -1)
2886 xscale_reg_arch_type
= register_reg_arch_type(xscale_get_reg
, xscale_set_reg
);
2888 (*cache_p
)->next
= malloc(sizeof(reg_cache_t
));
2889 cache_p
= &(*cache_p
)->next
;
2891 /* fill in values for the xscale reg cache */
2892 (*cache_p
)->name
= "XScale registers";
2893 (*cache_p
)->next
= NULL
;
2894 (*cache_p
)->reg_list
= malloc(num_regs
* sizeof(reg_t
));
2895 (*cache_p
)->num_regs
= num_regs
;
2897 for (i
= 0; i
< num_regs
; i
++)
2899 (*cache_p
)->reg_list
[i
].name
= xscale_reg_list
[i
];
2900 (*cache_p
)->reg_list
[i
].value
= calloc(4, 1);
2901 (*cache_p
)->reg_list
[i
].dirty
= 0;
2902 (*cache_p
)->reg_list
[i
].valid
= 0;
2903 (*cache_p
)->reg_list
[i
].size
= 32;
2904 (*cache_p
)->reg_list
[i
].bitfield_desc
= NULL
;
2905 (*cache_p
)->reg_list
[i
].num_bitfields
= 0;
2906 (*cache_p
)->reg_list
[i
].arch_info
= &arch_info
[i
];
2907 (*cache_p
)->reg_list
[i
].arch_type
= xscale_reg_arch_type
;
2908 arch_info
[i
] = xscale_reg_arch_info
[i
];
2909 arch_info
[i
].target
= target
;
2912 xscale
->reg_cache
= (*cache_p
);
2915 static int xscale_init_target(struct command_context_s
*cmd_ctx
,
2916 struct target_s
*target
)
2918 xscale_build_reg_cache(target
);
2922 static int xscale_quit(void)
2924 jtag_add_runtest(100, TAP_RESET
);
2928 static int xscale_init_arch_info(target_t
*target
,
2929 xscale_common_t
*xscale
, jtag_tap_t
*tap
, const char *variant
)
2931 armv4_5_common_t
*armv4_5
;
2932 uint32_t high_reset_branch
, low_reset_branch
;
2935 armv4_5
= &xscale
->armv4_5_common
;
2937 /* store architecture specfic data (none so far) */
2938 xscale
->arch_info
= NULL
;
2939 xscale
->common_magic
= XSCALE_COMMON_MAGIC
;
2941 /* we don't really *need* variant info ... */
2945 if (strcmp(variant
, "pxa250") == 0
2946 || strcmp(variant
, "pxa255") == 0
2947 || strcmp(variant
, "pxa26x") == 0)
2949 else if (strcmp(variant
, "pxa27x") == 0
2950 || strcmp(variant
, "ixp42x") == 0
2951 || strcmp(variant
, "ixp45x") == 0
2952 || strcmp(variant
, "ixp46x") == 0)
2955 LOG_WARNING("%s: unrecognized variant %s",
2956 tap
->dotted_name
, variant
);
2958 if (ir_length
&& ir_length
!= tap
->ir_length
) {
2959 LOG_WARNING("%s: IR length for %s is %d; fixing",
2960 tap
->dotted_name
, variant
, ir_length
);
2961 tap
->ir_length
= ir_length
;
2965 /* the debug handler isn't installed (and thus not running) at this time */
2966 xscale
->handler_address
= 0xfe000800;
2968 /* clear the vectors we keep locally for reference */
2969 memset(xscale
->low_vectors
, 0, sizeof(xscale
->low_vectors
));
2970 memset(xscale
->high_vectors
, 0, sizeof(xscale
->high_vectors
));
2972 /* no user-specified vectors have been configured yet */
2973 xscale
->static_low_vectors_set
= 0x0;
2974 xscale
->static_high_vectors_set
= 0x0;
2976 /* calculate branches to debug handler */
2977 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
2978 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
2980 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
2981 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
2983 for (i
= 1; i
<= 7; i
++)
2985 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
2986 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
2989 /* 64kB aligned region used for DCache cleaning */
2990 xscale
->cache_clean_address
= 0xfffe0000;
2992 xscale
->hold_rst
= 0;
2993 xscale
->external_debug_break
= 0;
2995 xscale
->ibcr_available
= 2;
2996 xscale
->ibcr0_used
= 0;
2997 xscale
->ibcr1_used
= 0;
2999 xscale
->dbr_available
= 2;
3000 xscale
->dbr0_used
= 0;
3001 xscale
->dbr1_used
= 0;
3003 xscale
->arm_bkpt
= ARMV5_BKPT(0x0);
3004 xscale
->thumb_bkpt
= ARMV5_T_BKPT(0x0) & 0xffff;
3006 xscale
->vector_catch
= 0x1;
3008 xscale
->trace
.capture_status
= TRACE_IDLE
;
3009 xscale
->trace
.data
= NULL
;
3010 xscale
->trace
.image
= NULL
;
3011 xscale
->trace
.buffer_enabled
= 0;
3012 xscale
->trace
.buffer_fill
= 0;
3014 /* prepare ARMv4/5 specific information */
3015 armv4_5
->arch_info
= xscale
;
3016 armv4_5
->read_core_reg
= xscale_read_core_reg
;
3017 armv4_5
->write_core_reg
= xscale_write_core_reg
;
3018 armv4_5
->full_context
= xscale_full_context
;
3020 armv4_5_init_arch_info(target
, armv4_5
);
3022 xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
3023 xscale
->armv4_5_mmu
.get_ttb
= xscale_get_ttb
;
3024 xscale
->armv4_5_mmu
.read_memory
= xscale_read_memory
;
3025 xscale
->armv4_5_mmu
.write_memory
= xscale_write_memory
;
3026 xscale
->armv4_5_mmu
.disable_mmu_caches
= xscale_disable_mmu_caches
;
3027 xscale
->armv4_5_mmu
.enable_mmu_caches
= xscale_enable_mmu_caches
;
3028 xscale
->armv4_5_mmu
.has_tiny_pages
= 1;
3029 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3034 static int xscale_target_create(struct target_s
*target
, Jim_Interp
*interp
)
3036 xscale_common_t
*xscale
;
3038 if (sizeof xscale_debug_handler
- 1 > 0x800) {
3039 LOG_ERROR("debug_handler.bin: larger than 2kb");
3043 xscale
= calloc(1, sizeof(*xscale
));
3047 return xscale_init_arch_info(target
, xscale
, target
->tap
,
3052 xscale_handle_debug_handler_command(struct command_context_s
*cmd_ctx
,
3053 char *cmd
, char **args
, int argc
)
3055 target_t
*target
= NULL
;
3056 armv4_5_common_t
*armv4_5
;
3057 xscale_common_t
*xscale
;
3059 uint32_t handler_address
;
3063 LOG_ERROR("'xscale debug_handler <target#> <address>' command takes two required operands");
3067 if ((target
= get_target(args
[0])) == NULL
)
3069 LOG_ERROR("target '%s' not defined", args
[0]);
3073 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3078 handler_address
= strtoul(args
[1], NULL
, 0);
3080 if (((handler_address
>= 0x800) && (handler_address
<= 0x1fef800)) ||
3081 ((handler_address
>= 0xfe000800) && (handler_address
<= 0xfffff800)))
3083 xscale
->handler_address
= handler_address
;
3087 LOG_ERROR("xscale debug_handler <address> must be between 0x800 and 0x1fef800 or between 0xfe000800 and 0xfffff800");
3095 xscale_handle_cache_clean_address_command(struct command_context_s
*cmd_ctx
,
3096 char *cmd
, char **args
, int argc
)
3098 target_t
*target
= NULL
;
3099 armv4_5_common_t
*armv4_5
;
3100 xscale_common_t
*xscale
;
3102 uint32_t cache_clean_address
;
3106 return ERROR_COMMAND_SYNTAX_ERROR
;
3109 target
= get_target(args
[0]);
3112 LOG_ERROR("target '%s' not defined", args
[0]);
3116 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3121 cache_clean_address
= strtoul(args
[1], NULL
, 0);
3123 if (cache_clean_address
& 0xffff)
3125 LOG_ERROR("xscale cache_clean_address <address> must be 64kb aligned");
3129 xscale
->cache_clean_address
= cache_clean_address
;
3136 xscale_handle_cache_info_command(struct command_context_s
*cmd_ctx
,
3137 char *cmd
, char **args
, int argc
)
3139 target_t
*target
= get_current_target(cmd_ctx
);
3140 armv4_5_common_t
*armv4_5
;
3141 xscale_common_t
*xscale
;
3143 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3148 return armv4_5_handle_cache_info_command(cmd_ctx
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
3151 static int xscale_virt2phys(struct target_s
*target
,
3152 uint32_t virtual, uint32_t *physical
)
3154 armv4_5_common_t
*armv4_5
;
3155 xscale_common_t
*xscale
;
3162 if ((retval
= xscale_get_arch_pointers(target
, &armv4_5
, &xscale
)) != ERROR_OK
)
3166 uint32_t ret
= armv4_5_mmu_translate_va(target
, &xscale
->armv4_5_mmu
, virtual, &type
, &cb
, &domain
, &ap
);
3175 static int xscale_mmu(struct target_s
*target
, int *enabled
)
3177 armv4_5_common_t
*armv4_5
= target
->arch_info
;
3178 xscale_common_t
*xscale
= armv4_5
->arch_info
;
3180 if (target
->state
!= TARGET_HALTED
)
3182 LOG_ERROR("Target not halted");
3183 return ERROR_TARGET_INVALID
;
3185 *enabled
= xscale
->armv4_5_mmu
.mmu_enabled
;
3189 static int xscale_handle_mmu_command(command_context_t
*cmd_ctx
,
3190 char *cmd
, char **args
, int argc
)
3192 target_t
*target
= get_current_target(cmd_ctx
);
3193 armv4_5_common_t
*armv4_5
;
3194 xscale_common_t
*xscale
;
3196 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3201 if (target
->state
!= TARGET_HALTED
)
3203 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3209 if (strcmp("enable", args
[0]) == 0)
3211 xscale_enable_mmu_caches(target
, 1, 0, 0);
3212 xscale
->armv4_5_mmu
.mmu_enabled
= 1;
3214 else if (strcmp("disable", args
[0]) == 0)
3216 xscale_disable_mmu_caches(target
, 1, 0, 0);
3217 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3221 command_print(cmd_ctx
, "mmu %s", (xscale
->armv4_5_mmu
.mmu_enabled
) ? "enabled" : "disabled");
3226 static int xscale_handle_idcache_command(command_context_t
*cmd_ctx
,
3227 char *cmd
, char **args
, int argc
)
3229 target_t
*target
= get_current_target(cmd_ctx
);
3230 armv4_5_common_t
*armv4_5
;
3231 xscale_common_t
*xscale
;
3232 int icache
= 0, dcache
= 0;
3234 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3239 if (target
->state
!= TARGET_HALTED
)
3241 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3245 if (strcmp(cmd
, "icache") == 0)
3247 else if (strcmp(cmd
, "dcache") == 0)
3252 if (strcmp("enable", args
[0]) == 0)
3254 xscale_enable_mmu_caches(target
, 0, dcache
, icache
);
3257 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 1;
3259 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 1;
3261 else if (strcmp("disable", args
[0]) == 0)
3263 xscale_disable_mmu_caches(target
, 0, dcache
, icache
);
3266 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 0;
3268 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 0;
3273 command_print(cmd_ctx
, "icache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
) ? "enabled" : "disabled");
3276 command_print(cmd_ctx
, "dcache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
) ? "enabled" : "disabled");
3281 static int xscale_handle_vector_catch_command(command_context_t
*cmd_ctx
,
3282 char *cmd
, char **args
, int argc
)
3284 target_t
*target
= get_current_target(cmd_ctx
);
3285 armv4_5_common_t
*armv4_5
;
3286 xscale_common_t
*xscale
;
3288 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3295 command_print(cmd_ctx
, "usage: xscale vector_catch [mask]");
3299 xscale
->vector_catch
= strtoul(args
[0], NULL
, 0);
3300 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 8, xscale
->vector_catch
);
3301 xscale_write_dcsr(target
, -1, -1);
3304 command_print(cmd_ctx
, "vector catch mask: 0x%2.2x", xscale
->vector_catch
);
3310 static int xscale_handle_vector_table_command(command_context_t
*cmd_ctx
,
3311 char *cmd
, char **args
, int argc
)
3313 target_t
*target
= get_current_target(cmd_ctx
);
3314 armv4_5_common_t
*armv4_5
;
3315 xscale_common_t
*xscale
;
3318 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3323 if (argc
== 0) /* print current settings */
3327 command_print(cmd_ctx
, "active user-set static vectors:");
3328 for (idx
= 1; idx
< 8; idx
++)
3329 if (xscale
->static_low_vectors_set
& (1 << idx
))
3330 command_print(cmd_ctx
, "low %d: 0x%" PRIx32
, idx
, xscale
->static_low_vectors
[idx
]);
3331 for (idx
= 1; idx
< 8; idx
++)
3332 if (xscale
->static_high_vectors_set
& (1 << idx
))
3333 command_print(cmd_ctx
, "high %d: 0x%" PRIx32
, idx
, xscale
->static_high_vectors
[idx
]);
3343 idx
= strtoul(args
[1], NULL
, 0);
3344 vec
= strtoul(args
[2], NULL
, 0);
3346 if (idx
< 1 || idx
>= 8)
3349 if (!err
&& strcmp(args
[0], "low") == 0)
3351 xscale
->static_low_vectors_set
|= (1<<idx
);
3352 xscale
->static_low_vectors
[idx
] = vec
;
3354 else if (!err
&& (strcmp(args
[0], "high") == 0))
3356 xscale
->static_high_vectors_set
|= (1<<idx
);
3357 xscale
->static_high_vectors
[idx
] = vec
;
3364 command_print(cmd_ctx
, "usage: xscale vector_table <high|low> <index> <code>");
3371 xscale_handle_trace_buffer_command(struct command_context_s
*cmd_ctx
,
3372 char *cmd
, char **args
, int argc
)
3374 target_t
*target
= get_current_target(cmd_ctx
);
3375 armv4_5_common_t
*armv4_5
;
3376 xscale_common_t
*xscale
;
3377 uint32_t dcsr_value
;
3379 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3384 if (target
->state
!= TARGET_HALTED
)
3386 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3390 if ((argc
>= 1) && (strcmp("enable", args
[0]) == 0))
3392 xscale_trace_data_t
*td
, *next_td
;
3393 xscale
->trace
.buffer_enabled
= 1;
3395 /* free old trace data */
3396 td
= xscale
->trace
.data
;
3406 xscale
->trace
.data
= NULL
;
3408 else if ((argc
>= 1) && (strcmp("disable", args
[0]) == 0))
3410 xscale
->trace
.buffer_enabled
= 0;
3413 if ((argc
>= 2) && (strcmp("fill", args
[1]) == 0))
3416 xscale
->trace
.buffer_fill
= strtoul(args
[2], NULL
, 0);
3418 xscale
->trace
.buffer_fill
= 1;
3420 else if ((argc
>= 2) && (strcmp("wrap", args
[1]) == 0))
3422 xscale
->trace
.buffer_fill
= -1;
3425 if (xscale
->trace
.buffer_enabled
)
3427 /* if we enable the trace buffer in fill-once
3428 * mode we know the address of the first instruction */
3429 xscale
->trace
.pc_ok
= 1;
3430 xscale
->trace
.current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
3434 /* otherwise the address is unknown, and we have no known good PC */
3435 xscale
->trace
.pc_ok
= 0;
3438 command_print(cmd_ctx
, "trace buffer %s (%s)",
3439 (xscale
->trace
.buffer_enabled
) ? "enabled" : "disabled",
3440 (xscale
->trace
.buffer_fill
> 0) ? "fill" : "wrap");
3442 dcsr_value
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32);
3443 if (xscale
->trace
.buffer_fill
>= 0)
3444 xscale_write_dcsr_sw(target
, (dcsr_value
& 0xfffffffc) | 2);
3446 xscale_write_dcsr_sw(target
, dcsr_value
& 0xfffffffc);
3452 xscale_handle_trace_image_command(struct command_context_s
*cmd_ctx
,
3453 char *cmd
, char **args
, int argc
)
3456 armv4_5_common_t
*armv4_5
;
3457 xscale_common_t
*xscale
;
3461 command_print(cmd_ctx
, "usage: xscale trace_image <file> [base address] [type]");
3465 target
= get_current_target(cmd_ctx
);
3467 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3472 if (xscale
->trace
.image
)
3474 image_close(xscale
->trace
.image
);
3475 free(xscale
->trace
.image
);
3476 command_print(cmd_ctx
, "previously loaded image found and closed");
3479 xscale
->trace
.image
= malloc(sizeof(image_t
));
3480 xscale
->trace
.image
->base_address_set
= 0;
3481 xscale
->trace
.image
->start_address_set
= 0;
3483 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
3486 xscale
->trace
.image
->base_address_set
= 1;
3487 xscale
->trace
.image
->base_address
= strtoul(args
[1], NULL
, 0);
3491 xscale
->trace
.image
->base_address_set
= 0;
3494 if (image_open(xscale
->trace
.image
, args
[0], (argc
>= 3) ? args
[2] : NULL
) != ERROR_OK
)
3496 free(xscale
->trace
.image
);
3497 xscale
->trace
.image
= NULL
;
3504 static int xscale_handle_dump_trace_command(struct command_context_s
*cmd_ctx
,
3505 char *cmd
, char **args
, int argc
)
3507 target_t
*target
= get_current_target(cmd_ctx
);
3508 armv4_5_common_t
*armv4_5
;
3509 xscale_common_t
*xscale
;
3510 xscale_trace_data_t
*trace_data
;
3513 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3518 if (target
->state
!= TARGET_HALTED
)
3520 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3526 command_print(cmd_ctx
, "usage: xscale dump_trace <file>");
3530 trace_data
= xscale
->trace
.data
;
3534 command_print(cmd_ctx
, "no trace data collected");
3538 if (fileio_open(&file
, args
[0], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
)
3547 fileio_write_u32(&file
, trace_data
->chkpt0
);
3548 fileio_write_u32(&file
, trace_data
->chkpt1
);
3549 fileio_write_u32(&file
, trace_data
->last_instruction
);
3550 fileio_write_u32(&file
, trace_data
->depth
);
3552 for (i
= 0; i
< trace_data
->depth
; i
++)
3553 fileio_write_u32(&file
, trace_data
->entries
[i
].data
| ((trace_data
->entries
[i
].type
& 0xffff) << 16));
3555 trace_data
= trace_data
->next
;
3558 fileio_close(&file
);
3564 xscale_handle_analyze_trace_buffer_command(struct command_context_s
*cmd_ctx
,
3565 char *cmd
, char **args
, int argc
)
3567 target_t
*target
= get_current_target(cmd_ctx
);
3568 armv4_5_common_t
*armv4_5
;
3569 xscale_common_t
*xscale
;
3571 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3576 xscale_analyze_trace(target
, cmd_ctx
);
3581 static int xscale_handle_cp15(command_context_t
*cmd_ctx
,
3582 char *cmd
, char **args
, int argc
)
3584 target_t
*target
= get_current_target(cmd_ctx
);
3585 armv4_5_common_t
*armv4_5
;
3586 xscale_common_t
*xscale
;
3588 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3593 if (target
->state
!= TARGET_HALTED
)
3595 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3598 uint32_t reg_no
= 0;
3602 reg_no
= strtoul(args
[0], NULL
, 0);
3603 /*translate from xscale cp15 register no to openocd register*/
3607 reg_no
= XSCALE_MAINID
;
3610 reg_no
= XSCALE_CTRL
;
3613 reg_no
= XSCALE_TTB
;
3616 reg_no
= XSCALE_DAC
;
3619 reg_no
= XSCALE_FSR
;
3622 reg_no
= XSCALE_FAR
;
3625 reg_no
= XSCALE_PID
;
3628 reg_no
= XSCALE_CPACCESS
;
3631 command_print(cmd_ctx
, "invalid register number");
3632 return ERROR_INVALID_ARGUMENTS
;
3634 reg
= &xscale
->reg_cache
->reg_list
[reg_no
];
3641 /* read cp15 control register */
3642 xscale_get_reg(reg
);
3643 value
= buf_get_u32(reg
->value
, 0, 32);
3644 command_print(cmd_ctx
, "%s (/%i): 0x%" PRIx32
"", reg
->name
, (int)(reg
->size
), value
);
3649 uint32_t value
= strtoul(args
[1], NULL
, 0);
3651 /* send CP write request (command 0x41) */
3652 xscale_send_u32(target
, 0x41);
3654 /* send CP register number */
3655 xscale_send_u32(target
, reg_no
);
3657 /* send CP register value */
3658 xscale_send_u32(target
, value
);
3660 /* execute cpwait to ensure outstanding operations complete */
3661 xscale_send_u32(target
, 0x53);
3665 command_print(cmd_ctx
, "usage: cp15 [register]<, [value]>");
3671 static int xscale_register_commands(struct command_context_s
*cmd_ctx
)
3673 command_t
*xscale_cmd
;
3675 xscale_cmd
= register_command(cmd_ctx
, NULL
, "xscale", NULL
, COMMAND_ANY
, "xscale specific commands");
3677 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");
3678 register_command(cmd_ctx
, xscale_cmd
, "cache_clean_address", xscale_handle_cache_clean_address_command
, COMMAND_ANY
, NULL
);
3680 register_command(cmd_ctx
, xscale_cmd
, "cache_info", xscale_handle_cache_info_command
, COMMAND_EXEC
, NULL
);
3681 register_command(cmd_ctx
, xscale_cmd
, "mmu", xscale_handle_mmu_command
, COMMAND_EXEC
, "['enable'|'disable'] the MMU");
3682 register_command(cmd_ctx
, xscale_cmd
, "icache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the ICache");
3683 register_command(cmd_ctx
, xscale_cmd
, "dcache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the DCache");
3685 register_command(cmd_ctx
, xscale_cmd
, "vector_catch", xscale_handle_vector_catch_command
, COMMAND_EXEC
, "<mask> of vectors that should be catched");
3686 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");
3688 register_command(cmd_ctx
, xscale_cmd
, "trace_buffer", xscale_handle_trace_buffer_command
, COMMAND_EXEC
, "<enable | disable> ['fill' [n]|'wrap']");
3690 register_command(cmd_ctx
, xscale_cmd
, "dump_trace", xscale_handle_dump_trace_command
, COMMAND_EXEC
, "dump content of trace buffer to <file>");
3691 register_command(cmd_ctx
, xscale_cmd
, "analyze_trace", xscale_handle_analyze_trace_buffer_command
, COMMAND_EXEC
, "analyze content of trace buffer");
3692 register_command(cmd_ctx
, xscale_cmd
, "trace_image", xscale_handle_trace_image_command
,
3693 COMMAND_EXEC
, "load image from <file> [base address]");
3695 register_command(cmd_ctx
, xscale_cmd
, "cp15", xscale_handle_cp15
, COMMAND_EXEC
, "access coproc 15 <register> [value]");
3697 armv4_5_register_commands(cmd_ctx
);
3702 target_type_t xscale_target
=
3706 .poll
= xscale_poll
,
3707 .arch_state
= xscale_arch_state
,
3709 .target_request_data
= NULL
,
3711 .halt
= xscale_halt
,
3712 .resume
= xscale_resume
,
3713 .step
= xscale_step
,
3715 .assert_reset
= xscale_assert_reset
,
3716 .deassert_reset
= xscale_deassert_reset
,
3717 .soft_reset_halt
= NULL
,
3719 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
3721 .read_memory
= xscale_read_memory
,
3722 .write_memory
= xscale_write_memory
,
3723 .bulk_write_memory
= xscale_bulk_write_memory
,
3724 .checksum_memory
= arm7_9_checksum_memory
,
3725 .blank_check_memory
= arm7_9_blank_check_memory
,
3727 .run_algorithm
= armv4_5_run_algorithm
,
3729 .add_breakpoint
= xscale_add_breakpoint
,
3730 .remove_breakpoint
= xscale_remove_breakpoint
,
3731 .add_watchpoint
= xscale_add_watchpoint
,
3732 .remove_watchpoint
= xscale_remove_watchpoint
,
3734 .register_commands
= xscale_register_commands
,
3735 .target_create
= xscale_target_create
,
3736 .init_target
= xscale_init_target
,
3737 .quit
= xscale_quit
,
3739 .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)