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_init_arch_info(target_t
*target
,
2923 xscale_common_t
*xscale
, jtag_tap_t
*tap
, const char *variant
)
2925 armv4_5_common_t
*armv4_5
;
2926 uint32_t high_reset_branch
, low_reset_branch
;
2929 armv4_5
= &xscale
->armv4_5_common
;
2931 /* store architecture specfic data (none so far) */
2932 xscale
->arch_info
= NULL
;
2933 xscale
->common_magic
= XSCALE_COMMON_MAGIC
;
2935 /* we don't really *need* variant info ... */
2939 if (strcmp(variant
, "pxa250") == 0
2940 || strcmp(variant
, "pxa255") == 0
2941 || strcmp(variant
, "pxa26x") == 0)
2943 else if (strcmp(variant
, "pxa27x") == 0
2944 || strcmp(variant
, "ixp42x") == 0
2945 || strcmp(variant
, "ixp45x") == 0
2946 || strcmp(variant
, "ixp46x") == 0)
2949 LOG_WARNING("%s: unrecognized variant %s",
2950 tap
->dotted_name
, variant
);
2952 if (ir_length
&& ir_length
!= tap
->ir_length
) {
2953 LOG_WARNING("%s: IR length for %s is %d; fixing",
2954 tap
->dotted_name
, variant
, ir_length
);
2955 tap
->ir_length
= ir_length
;
2959 /* the debug handler isn't installed (and thus not running) at this time */
2960 xscale
->handler_address
= 0xfe000800;
2962 /* clear the vectors we keep locally for reference */
2963 memset(xscale
->low_vectors
, 0, sizeof(xscale
->low_vectors
));
2964 memset(xscale
->high_vectors
, 0, sizeof(xscale
->high_vectors
));
2966 /* no user-specified vectors have been configured yet */
2967 xscale
->static_low_vectors_set
= 0x0;
2968 xscale
->static_high_vectors_set
= 0x0;
2970 /* calculate branches to debug handler */
2971 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
2972 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
2974 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
2975 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
2977 for (i
= 1; i
<= 7; i
++)
2979 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
2980 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
2983 /* 64kB aligned region used for DCache cleaning */
2984 xscale
->cache_clean_address
= 0xfffe0000;
2986 xscale
->hold_rst
= 0;
2987 xscale
->external_debug_break
= 0;
2989 xscale
->ibcr_available
= 2;
2990 xscale
->ibcr0_used
= 0;
2991 xscale
->ibcr1_used
= 0;
2993 xscale
->dbr_available
= 2;
2994 xscale
->dbr0_used
= 0;
2995 xscale
->dbr1_used
= 0;
2997 xscale
->arm_bkpt
= ARMV5_BKPT(0x0);
2998 xscale
->thumb_bkpt
= ARMV5_T_BKPT(0x0) & 0xffff;
3000 xscale
->vector_catch
= 0x1;
3002 xscale
->trace
.capture_status
= TRACE_IDLE
;
3003 xscale
->trace
.data
= NULL
;
3004 xscale
->trace
.image
= NULL
;
3005 xscale
->trace
.buffer_enabled
= 0;
3006 xscale
->trace
.buffer_fill
= 0;
3008 /* prepare ARMv4/5 specific information */
3009 armv4_5
->arch_info
= xscale
;
3010 armv4_5
->read_core_reg
= xscale_read_core_reg
;
3011 armv4_5
->write_core_reg
= xscale_write_core_reg
;
3012 armv4_5
->full_context
= xscale_full_context
;
3014 armv4_5_init_arch_info(target
, armv4_5
);
3016 xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
3017 xscale
->armv4_5_mmu
.get_ttb
= xscale_get_ttb
;
3018 xscale
->armv4_5_mmu
.read_memory
= xscale_read_memory
;
3019 xscale
->armv4_5_mmu
.write_memory
= xscale_write_memory
;
3020 xscale
->armv4_5_mmu
.disable_mmu_caches
= xscale_disable_mmu_caches
;
3021 xscale
->armv4_5_mmu
.enable_mmu_caches
= xscale_enable_mmu_caches
;
3022 xscale
->armv4_5_mmu
.has_tiny_pages
= 1;
3023 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3028 static int xscale_target_create(struct target_s
*target
, Jim_Interp
*interp
)
3030 xscale_common_t
*xscale
;
3032 if (sizeof xscale_debug_handler
- 1 > 0x800) {
3033 LOG_ERROR("debug_handler.bin: larger than 2kb");
3037 xscale
= calloc(1, sizeof(*xscale
));
3041 return xscale_init_arch_info(target
, xscale
, target
->tap
,
3046 xscale_handle_debug_handler_command(struct command_context_s
*cmd_ctx
,
3047 char *cmd
, char **args
, int argc
)
3049 target_t
*target
= NULL
;
3050 armv4_5_common_t
*armv4_5
;
3051 xscale_common_t
*xscale
;
3053 uint32_t handler_address
;
3057 LOG_ERROR("'xscale debug_handler <target#> <address>' command takes two required operands");
3061 if ((target
= get_target(args
[0])) == NULL
)
3063 LOG_ERROR("target '%s' not defined", args
[0]);
3067 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3072 handler_address
= strtoul(args
[1], NULL
, 0);
3074 if (((handler_address
>= 0x800) && (handler_address
<= 0x1fef800)) ||
3075 ((handler_address
>= 0xfe000800) && (handler_address
<= 0xfffff800)))
3077 xscale
->handler_address
= handler_address
;
3081 LOG_ERROR("xscale debug_handler <address> must be between 0x800 and 0x1fef800 or between 0xfe000800 and 0xfffff800");
3089 xscale_handle_cache_clean_address_command(struct command_context_s
*cmd_ctx
,
3090 char *cmd
, char **args
, int argc
)
3092 target_t
*target
= NULL
;
3093 armv4_5_common_t
*armv4_5
;
3094 xscale_common_t
*xscale
;
3096 uint32_t cache_clean_address
;
3100 return ERROR_COMMAND_SYNTAX_ERROR
;
3103 target
= get_target(args
[0]);
3106 LOG_ERROR("target '%s' not defined", args
[0]);
3110 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3115 cache_clean_address
= strtoul(args
[1], NULL
, 0);
3117 if (cache_clean_address
& 0xffff)
3119 LOG_ERROR("xscale cache_clean_address <address> must be 64kb aligned");
3123 xscale
->cache_clean_address
= cache_clean_address
;
3130 xscale_handle_cache_info_command(struct command_context_s
*cmd_ctx
,
3131 char *cmd
, char **args
, int argc
)
3133 target_t
*target
= get_current_target(cmd_ctx
);
3134 armv4_5_common_t
*armv4_5
;
3135 xscale_common_t
*xscale
;
3137 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3142 return armv4_5_handle_cache_info_command(cmd_ctx
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
3145 static int xscale_virt2phys(struct target_s
*target
,
3146 uint32_t virtual, uint32_t *physical
)
3148 armv4_5_common_t
*armv4_5
;
3149 xscale_common_t
*xscale
;
3156 if ((retval
= xscale_get_arch_pointers(target
, &armv4_5
, &xscale
)) != ERROR_OK
)
3160 uint32_t ret
= armv4_5_mmu_translate_va(target
, &xscale
->armv4_5_mmu
, virtual, &type
, &cb
, &domain
, &ap
);
3169 static int xscale_mmu(struct target_s
*target
, int *enabled
)
3171 armv4_5_common_t
*armv4_5
= target
->arch_info
;
3172 xscale_common_t
*xscale
= armv4_5
->arch_info
;
3174 if (target
->state
!= TARGET_HALTED
)
3176 LOG_ERROR("Target not halted");
3177 return ERROR_TARGET_INVALID
;
3179 *enabled
= xscale
->armv4_5_mmu
.mmu_enabled
;
3183 static int xscale_handle_mmu_command(command_context_t
*cmd_ctx
,
3184 char *cmd
, char **args
, int argc
)
3186 target_t
*target
= get_current_target(cmd_ctx
);
3187 armv4_5_common_t
*armv4_5
;
3188 xscale_common_t
*xscale
;
3190 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3195 if (target
->state
!= TARGET_HALTED
)
3197 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3203 if (strcmp("enable", args
[0]) == 0)
3205 xscale_enable_mmu_caches(target
, 1, 0, 0);
3206 xscale
->armv4_5_mmu
.mmu_enabled
= 1;
3208 else if (strcmp("disable", args
[0]) == 0)
3210 xscale_disable_mmu_caches(target
, 1, 0, 0);
3211 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3215 command_print(cmd_ctx
, "mmu %s", (xscale
->armv4_5_mmu
.mmu_enabled
) ? "enabled" : "disabled");
3220 static int xscale_handle_idcache_command(command_context_t
*cmd_ctx
,
3221 char *cmd
, char **args
, int argc
)
3223 target_t
*target
= get_current_target(cmd_ctx
);
3224 armv4_5_common_t
*armv4_5
;
3225 xscale_common_t
*xscale
;
3226 int icache
= 0, dcache
= 0;
3228 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3233 if (target
->state
!= TARGET_HALTED
)
3235 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3239 if (strcmp(cmd
, "icache") == 0)
3241 else if (strcmp(cmd
, "dcache") == 0)
3246 if (strcmp("enable", args
[0]) == 0)
3248 xscale_enable_mmu_caches(target
, 0, dcache
, icache
);
3251 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 1;
3253 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 1;
3255 else if (strcmp("disable", args
[0]) == 0)
3257 xscale_disable_mmu_caches(target
, 0, dcache
, icache
);
3260 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 0;
3262 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 0;
3267 command_print(cmd_ctx
, "icache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
) ? "enabled" : "disabled");
3270 command_print(cmd_ctx
, "dcache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
) ? "enabled" : "disabled");
3275 static int xscale_handle_vector_catch_command(command_context_t
*cmd_ctx
,
3276 char *cmd
, char **args
, int argc
)
3278 target_t
*target
= get_current_target(cmd_ctx
);
3279 armv4_5_common_t
*armv4_5
;
3280 xscale_common_t
*xscale
;
3282 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3289 command_print(cmd_ctx
, "usage: xscale vector_catch [mask]");
3293 xscale
->vector_catch
= strtoul(args
[0], NULL
, 0);
3294 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 8, xscale
->vector_catch
);
3295 xscale_write_dcsr(target
, -1, -1);
3298 command_print(cmd_ctx
, "vector catch mask: 0x%2.2x", xscale
->vector_catch
);
3304 static int xscale_handle_vector_table_command(command_context_t
*cmd_ctx
,
3305 char *cmd
, char **args
, int argc
)
3307 target_t
*target
= get_current_target(cmd_ctx
);
3308 armv4_5_common_t
*armv4_5
;
3309 xscale_common_t
*xscale
;
3312 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3317 if (argc
== 0) /* print current settings */
3321 command_print(cmd_ctx
, "active user-set static vectors:");
3322 for (idx
= 1; idx
< 8; idx
++)
3323 if (xscale
->static_low_vectors_set
& (1 << idx
))
3324 command_print(cmd_ctx
, "low %d: 0x%" PRIx32
, idx
, xscale
->static_low_vectors
[idx
]);
3325 for (idx
= 1; idx
< 8; idx
++)
3326 if (xscale
->static_high_vectors_set
& (1 << idx
))
3327 command_print(cmd_ctx
, "high %d: 0x%" PRIx32
, idx
, xscale
->static_high_vectors
[idx
]);
3337 idx
= strtoul(args
[1], NULL
, 0);
3338 vec
= strtoul(args
[2], NULL
, 0);
3340 if (idx
< 1 || idx
>= 8)
3343 if (!err
&& strcmp(args
[0], "low") == 0)
3345 xscale
->static_low_vectors_set
|= (1<<idx
);
3346 xscale
->static_low_vectors
[idx
] = vec
;
3348 else if (!err
&& (strcmp(args
[0], "high") == 0))
3350 xscale
->static_high_vectors_set
|= (1<<idx
);
3351 xscale
->static_high_vectors
[idx
] = vec
;
3358 command_print(cmd_ctx
, "usage: xscale vector_table <high|low> <index> <code>");
3365 xscale_handle_trace_buffer_command(struct command_context_s
*cmd_ctx
,
3366 char *cmd
, char **args
, int argc
)
3368 target_t
*target
= get_current_target(cmd_ctx
);
3369 armv4_5_common_t
*armv4_5
;
3370 xscale_common_t
*xscale
;
3371 uint32_t dcsr_value
;
3373 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3378 if (target
->state
!= TARGET_HALTED
)
3380 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3384 if ((argc
>= 1) && (strcmp("enable", args
[0]) == 0))
3386 xscale_trace_data_t
*td
, *next_td
;
3387 xscale
->trace
.buffer_enabled
= 1;
3389 /* free old trace data */
3390 td
= xscale
->trace
.data
;
3400 xscale
->trace
.data
= NULL
;
3402 else if ((argc
>= 1) && (strcmp("disable", args
[0]) == 0))
3404 xscale
->trace
.buffer_enabled
= 0;
3407 if ((argc
>= 2) && (strcmp("fill", args
[1]) == 0))
3410 xscale
->trace
.buffer_fill
= strtoul(args
[2], NULL
, 0);
3412 xscale
->trace
.buffer_fill
= 1;
3414 else if ((argc
>= 2) && (strcmp("wrap", args
[1]) == 0))
3416 xscale
->trace
.buffer_fill
= -1;
3419 if (xscale
->trace
.buffer_enabled
)
3421 /* if we enable the trace buffer in fill-once
3422 * mode we know the address of the first instruction */
3423 xscale
->trace
.pc_ok
= 1;
3424 xscale
->trace
.current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
3428 /* otherwise the address is unknown, and we have no known good PC */
3429 xscale
->trace
.pc_ok
= 0;
3432 command_print(cmd_ctx
, "trace buffer %s (%s)",
3433 (xscale
->trace
.buffer_enabled
) ? "enabled" : "disabled",
3434 (xscale
->trace
.buffer_fill
> 0) ? "fill" : "wrap");
3436 dcsr_value
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32);
3437 if (xscale
->trace
.buffer_fill
>= 0)
3438 xscale_write_dcsr_sw(target
, (dcsr_value
& 0xfffffffc) | 2);
3440 xscale_write_dcsr_sw(target
, dcsr_value
& 0xfffffffc);
3446 xscale_handle_trace_image_command(struct command_context_s
*cmd_ctx
,
3447 char *cmd
, char **args
, int argc
)
3450 armv4_5_common_t
*armv4_5
;
3451 xscale_common_t
*xscale
;
3455 command_print(cmd_ctx
, "usage: xscale trace_image <file> [base address] [type]");
3459 target
= get_current_target(cmd_ctx
);
3461 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3466 if (xscale
->trace
.image
)
3468 image_close(xscale
->trace
.image
);
3469 free(xscale
->trace
.image
);
3470 command_print(cmd_ctx
, "previously loaded image found and closed");
3473 xscale
->trace
.image
= malloc(sizeof(image_t
));
3474 xscale
->trace
.image
->base_address_set
= 0;
3475 xscale
->trace
.image
->start_address_set
= 0;
3477 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
3480 xscale
->trace
.image
->base_address_set
= 1;
3481 xscale
->trace
.image
->base_address
= strtoul(args
[1], NULL
, 0);
3485 xscale
->trace
.image
->base_address_set
= 0;
3488 if (image_open(xscale
->trace
.image
, args
[0], (argc
>= 3) ? args
[2] : NULL
) != ERROR_OK
)
3490 free(xscale
->trace
.image
);
3491 xscale
->trace
.image
= NULL
;
3498 static int xscale_handle_dump_trace_command(struct command_context_s
*cmd_ctx
,
3499 char *cmd
, char **args
, int argc
)
3501 target_t
*target
= get_current_target(cmd_ctx
);
3502 armv4_5_common_t
*armv4_5
;
3503 xscale_common_t
*xscale
;
3504 xscale_trace_data_t
*trace_data
;
3507 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3512 if (target
->state
!= TARGET_HALTED
)
3514 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3520 command_print(cmd_ctx
, "usage: xscale dump_trace <file>");
3524 trace_data
= xscale
->trace
.data
;
3528 command_print(cmd_ctx
, "no trace data collected");
3532 if (fileio_open(&file
, args
[0], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
)
3541 fileio_write_u32(&file
, trace_data
->chkpt0
);
3542 fileio_write_u32(&file
, trace_data
->chkpt1
);
3543 fileio_write_u32(&file
, trace_data
->last_instruction
);
3544 fileio_write_u32(&file
, trace_data
->depth
);
3546 for (i
= 0; i
< trace_data
->depth
; i
++)
3547 fileio_write_u32(&file
, trace_data
->entries
[i
].data
| ((trace_data
->entries
[i
].type
& 0xffff) << 16));
3549 trace_data
= trace_data
->next
;
3552 fileio_close(&file
);
3558 xscale_handle_analyze_trace_buffer_command(struct command_context_s
*cmd_ctx
,
3559 char *cmd
, char **args
, int argc
)
3561 target_t
*target
= get_current_target(cmd_ctx
);
3562 armv4_5_common_t
*armv4_5
;
3563 xscale_common_t
*xscale
;
3565 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3570 xscale_analyze_trace(target
, cmd_ctx
);
3575 static int xscale_handle_cp15(command_context_t
*cmd_ctx
,
3576 char *cmd
, char **args
, int argc
)
3578 target_t
*target
= get_current_target(cmd_ctx
);
3579 armv4_5_common_t
*armv4_5
;
3580 xscale_common_t
*xscale
;
3582 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3587 if (target
->state
!= TARGET_HALTED
)
3589 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3592 uint32_t reg_no
= 0;
3596 reg_no
= strtoul(args
[0], NULL
, 0);
3597 /*translate from xscale cp15 register no to openocd register*/
3601 reg_no
= XSCALE_MAINID
;
3604 reg_no
= XSCALE_CTRL
;
3607 reg_no
= XSCALE_TTB
;
3610 reg_no
= XSCALE_DAC
;
3613 reg_no
= XSCALE_FSR
;
3616 reg_no
= XSCALE_FAR
;
3619 reg_no
= XSCALE_PID
;
3622 reg_no
= XSCALE_CPACCESS
;
3625 command_print(cmd_ctx
, "invalid register number");
3626 return ERROR_INVALID_ARGUMENTS
;
3628 reg
= &xscale
->reg_cache
->reg_list
[reg_no
];
3635 /* read cp15 control register */
3636 xscale_get_reg(reg
);
3637 value
= buf_get_u32(reg
->value
, 0, 32);
3638 command_print(cmd_ctx
, "%s (/%i): 0x%" PRIx32
"", reg
->name
, (int)(reg
->size
), value
);
3643 uint32_t value
= strtoul(args
[1], NULL
, 0);
3645 /* send CP write request (command 0x41) */
3646 xscale_send_u32(target
, 0x41);
3648 /* send CP register number */
3649 xscale_send_u32(target
, reg_no
);
3651 /* send CP register value */
3652 xscale_send_u32(target
, value
);
3654 /* execute cpwait to ensure outstanding operations complete */
3655 xscale_send_u32(target
, 0x53);
3659 command_print(cmd_ctx
, "usage: cp15 [register]<, [value]>");
3665 static int xscale_register_commands(struct command_context_s
*cmd_ctx
)
3667 command_t
*xscale_cmd
;
3669 xscale_cmd
= register_command(cmd_ctx
, NULL
, "xscale", NULL
, COMMAND_ANY
, "xscale specific commands");
3671 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");
3672 register_command(cmd_ctx
, xscale_cmd
, "cache_clean_address", xscale_handle_cache_clean_address_command
, COMMAND_ANY
, NULL
);
3674 register_command(cmd_ctx
, xscale_cmd
, "cache_info", xscale_handle_cache_info_command
, COMMAND_EXEC
, NULL
);
3675 register_command(cmd_ctx
, xscale_cmd
, "mmu", xscale_handle_mmu_command
, COMMAND_EXEC
, "['enable'|'disable'] the MMU");
3676 register_command(cmd_ctx
, xscale_cmd
, "icache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the ICache");
3677 register_command(cmd_ctx
, xscale_cmd
, "dcache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the DCache");
3679 register_command(cmd_ctx
, xscale_cmd
, "vector_catch", xscale_handle_vector_catch_command
, COMMAND_EXEC
, "<mask> of vectors that should be catched");
3680 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");
3682 register_command(cmd_ctx
, xscale_cmd
, "trace_buffer", xscale_handle_trace_buffer_command
, COMMAND_EXEC
, "<enable | disable> ['fill' [n]|'wrap']");
3684 register_command(cmd_ctx
, xscale_cmd
, "dump_trace", xscale_handle_dump_trace_command
, COMMAND_EXEC
, "dump content of trace buffer to <file>");
3685 register_command(cmd_ctx
, xscale_cmd
, "analyze_trace", xscale_handle_analyze_trace_buffer_command
, COMMAND_EXEC
, "analyze content of trace buffer");
3686 register_command(cmd_ctx
, xscale_cmd
, "trace_image", xscale_handle_trace_image_command
,
3687 COMMAND_EXEC
, "load image from <file> [base address]");
3689 register_command(cmd_ctx
, xscale_cmd
, "cp15", xscale_handle_cp15
, COMMAND_EXEC
, "access coproc 15 <register> [value]");
3691 armv4_5_register_commands(cmd_ctx
);
3696 target_type_t xscale_target
=
3700 .poll
= xscale_poll
,
3701 .arch_state
= xscale_arch_state
,
3703 .target_request_data
= NULL
,
3705 .halt
= xscale_halt
,
3706 .resume
= xscale_resume
,
3707 .step
= xscale_step
,
3709 .assert_reset
= xscale_assert_reset
,
3710 .deassert_reset
= xscale_deassert_reset
,
3711 .soft_reset_halt
= NULL
,
3713 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
3715 .read_memory
= xscale_read_memory
,
3716 .write_memory
= xscale_write_memory
,
3717 .bulk_write_memory
= xscale_bulk_write_memory
,
3718 .checksum_memory
= arm7_9_checksum_memory
,
3719 .blank_check_memory
= arm7_9_blank_check_memory
,
3721 .run_algorithm
= armv4_5_run_algorithm
,
3723 .add_breakpoint
= xscale_add_breakpoint
,
3724 .remove_breakpoint
= xscale_remove_breakpoint
,
3725 .add_watchpoint
= xscale_add_watchpoint
,
3726 .remove_watchpoint
= xscale_remove_watchpoint
,
3728 .register_commands
= xscale_register_commands
,
3729 .target_create
= xscale_target_create
,
3730 .init_target
= xscale_init_target
,
3732 .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)