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 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
28 #include "arm7_9_common.h"
29 #include "arm_simulator.h"
30 #include "arm_disassembler.h"
31 #include "time_support.h"
35 int xscale_register_commands(struct command_context_s
*cmd_ctx
);
37 /* forward declarations */
38 int xscale_target_create(struct target_s
*target
, Jim_Interp
*interp
);
39 int xscale_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
);
40 int xscale_quit(void);
42 int xscale_arch_state(struct target_s
*target
);
43 int xscale_poll(target_t
*target
);
44 int xscale_halt(target_t
*target
);
45 int xscale_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
);
46 int xscale_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
);
47 int xscale_debug_entry(target_t
*target
);
48 int xscale_restore_context(target_t
*target
);
50 int xscale_assert_reset(target_t
*target
);
51 int xscale_deassert_reset(target_t
*target
);
52 int xscale_soft_reset_halt(struct target_s
*target
);
54 int xscale_set_reg_u32(reg_t
*reg
, u32 value
);
56 int xscale_read_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
);
57 int xscale_write_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
, u32 value
);
59 int xscale_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
);
60 int xscale_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
);
61 int xscale_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
);
63 int xscale_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
64 int xscale_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
65 int xscale_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
66 int xscale_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
67 int xscale_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
);
68 int xscale_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
);
69 void xscale_enable_watchpoints(struct target_s
*target
);
70 void xscale_enable_breakpoints(struct target_s
*target
);
71 static int xscale_virt2phys(struct target_s
*target
, u32
virtual, u32
*physical
);
72 static int xscale_mmu(struct target_s
*target
, int *enabled
);
74 int xscale_read_trace(target_t
*target
);
76 target_type_t xscale_target
=
81 .arch_state
= xscale_arch_state
,
83 .target_request_data
= NULL
,
86 .resume
= xscale_resume
,
89 .assert_reset
= xscale_assert_reset
,
90 .deassert_reset
= xscale_deassert_reset
,
91 .soft_reset_halt
= xscale_soft_reset_halt
,
93 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
95 .read_memory
= xscale_read_memory
,
96 .write_memory
= xscale_write_memory
,
97 .bulk_write_memory
= xscale_bulk_write_memory
,
98 .checksum_memory
= arm7_9_checksum_memory
,
99 .blank_check_memory
= arm7_9_blank_check_memory
,
101 .run_algorithm
= armv4_5_run_algorithm
,
103 .add_breakpoint
= xscale_add_breakpoint
,
104 .remove_breakpoint
= xscale_remove_breakpoint
,
105 .add_watchpoint
= xscale_add_watchpoint
,
106 .remove_watchpoint
= xscale_remove_watchpoint
,
108 .register_commands
= xscale_register_commands
,
109 .target_create
= xscale_target_create
,
110 .init_target
= xscale_init_target
,
113 .virt2phys
= xscale_virt2phys
,
117 char* xscale_reg_list
[] =
119 "XSCALE_MAINID", /* 0 */
129 "XSCALE_IBCR0", /* 10 */
139 "XSCALE_RX", /* 20 */
143 xscale_reg_t xscale_reg_arch_info
[] =
145 {XSCALE_MAINID
, NULL
},
146 {XSCALE_CACHETYPE
, NULL
},
148 {XSCALE_AUXCTRL
, NULL
},
154 {XSCALE_CPACCESS
, NULL
},
155 {XSCALE_IBCR0
, NULL
},
156 {XSCALE_IBCR1
, NULL
},
159 {XSCALE_DBCON
, NULL
},
160 {XSCALE_TBREG
, NULL
},
161 {XSCALE_CHKPT0
, NULL
},
162 {XSCALE_CHKPT1
, NULL
},
163 {XSCALE_DCSR
, NULL
}, /* DCSR accessed via JTAG or SW */
164 {-1, NULL
}, /* TX accessed via JTAG */
165 {-1, NULL
}, /* RX accessed via JTAG */
166 {-1, NULL
}, /* TXRXCTRL implicit access via JTAG */
169 int xscale_reg_arch_type
= -1;
171 int xscale_get_reg(reg_t
*reg
);
172 int xscale_set_reg(reg_t
*reg
, u8
*buf
);
174 int xscale_get_arch_pointers(target_t
*target
, armv4_5_common_t
**armv4_5_p
, xscale_common_t
**xscale_p
)
176 armv4_5_common_t
*armv4_5
= target
->arch_info
;
177 xscale_common_t
*xscale
= armv4_5
->arch_info
;
179 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
181 LOG_ERROR("target isn't an XScale target");
185 if (xscale
->common_magic
!= XSCALE_COMMON_MAGIC
)
187 LOG_ERROR("target isn't an XScale target");
191 *armv4_5_p
= armv4_5
;
197 int xscale_jtag_set_instr(jtag_tap_t
*tap
, u32 new_instr
)
202 if (buf_get_u32(tap
->cur_instr
, 0, tap
->ir_length
) != new_instr
)
207 field
.num_bits
= tap
->ir_length
;
208 field
.out_value
= calloc(CEIL(field
.num_bits
, 8), 1);
209 buf_set_u32(field
.out_value
, 0, field
.num_bits
, new_instr
);
212 field
.in_value
= tmp
;
214 jtag_add_ir_scan(1, &field
, TAP_INVALID
);
216 jtag_check_value_mask(&field
, tap
->expected
, tap
->expected_mask
);
218 free(field
.out_value
);
224 int xscale_read_dcsr(target_t
*target
)
226 armv4_5_common_t
*armv4_5
= target
->arch_info
;
227 xscale_common_t
*xscale
= armv4_5
->arch_info
;
231 scan_field_t fields
[3];
233 u8 field0_check_value
= 0x2;
234 u8 field0_check_mask
= 0x7;
236 u8 field2_check_value
= 0x0;
237 u8 field2_check_mask
= 0x1;
239 jtag_add_end_state(TAP_DRPAUSE
);
240 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dcsr
);
242 buf_set_u32(&field0
, 1, 1, xscale
->hold_rst
);
243 buf_set_u32(&field0
, 2, 1, xscale
->external_debug_break
);
245 fields
[0].tap
= xscale
->jtag_info
.tap
;
246 fields
[0].num_bits
= 3;
247 fields
[0].out_value
= &field0
;
249 fields
[0].in_value
= &tmp
;
251 fields
[1].tap
= xscale
->jtag_info
.tap
;
252 fields
[1].num_bits
= 32;
253 fields
[1].out_value
= NULL
;
254 fields
[1].in_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
257 fields
[2].tap
= xscale
->jtag_info
.tap
;
258 fields
[2].num_bits
= 1;
259 fields
[2].out_value
= &field2
;
261 fields
[2].in_value
= &tmp2
;
263 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
265 jtag_check_value_mask(fields
+0, &field0_check_value
, &field0_check_mask
);
266 jtag_check_value_mask(fields
+2, &field2_check_value
, &field2_check_mask
);
268 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
270 LOG_ERROR("JTAG error while reading DCSR");
274 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].dirty
= 0;
275 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].valid
= 1;
277 /* write the register with the value we just read
278 * on this second pass, only the first bit of field0 is guaranteed to be 0)
280 field0_check_mask
= 0x1;
281 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
282 fields
[1].in_value
= NULL
;
284 jtag_add_end_state(TAP_IDLE
);
286 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
288 /* DANGER!!! this must be here. It will make sure that the arguments
289 * to jtag_set_check_value() does not go out of scope! */
290 return jtag_execute_queue();
293 int xscale_receive(target_t
*target
, u32
*buffer
, int num_words
)
296 return ERROR_INVALID_ARGUMENTS
;
299 armv4_5_common_t
*armv4_5
= target
->arch_info
;
300 xscale_common_t
*xscale
= armv4_5
->arch_info
;
303 scan_field_t fields
[3];
305 u8
*field0
= malloc(num_words
* 1);
306 u8 field0_check_value
= 0x2;
307 u8 field0_check_mask
= 0x6;
308 u32
*field1
= malloc(num_words
* 4);
309 u8 field2_check_value
= 0x0;
310 u8 field2_check_mask
= 0x1;
312 int words_scheduled
= 0;
316 path
[0] = TAP_DRSELECT
;
317 path
[1] = TAP_DRCAPTURE
;
318 path
[2] = TAP_DRSHIFT
;
320 fields
[0].tap
= xscale
->jtag_info
.tap
;
321 fields
[0].num_bits
= 3;
322 fields
[0].out_value
= NULL
;
324 fields
[0].in_value
= &tmp2
;
326 fields
[1].tap
= xscale
->jtag_info
.tap
;
327 fields
[1].num_bits
= 32;
328 fields
[1].out_value
= NULL
;
330 fields
[1].in_value
= tmp
;
333 fields
[2].tap
= xscale
->jtag_info
.tap
;
334 fields
[2].num_bits
= 1;
335 fields
[2].out_value
= NULL
;
337 fields
[2].in_value
= &tmp3
;
339 jtag_add_end_state(TAP_IDLE
);
340 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dbgtx
);
341 jtag_add_runtest(1, TAP_INVALID
); /* ensures that we're in the TAP_IDLE state as the above could be a no-op */
343 /* repeat until all words have been collected */
345 while (words_done
< num_words
)
349 for (i
= words_done
; i
< num_words
; i
++)
351 fields
[0].in_value
= &field0
[i
];
353 jtag_add_pathmove(3, path
);
354 jtag_add_dr_scan_now(3, fields
, TAP_IDLE
);
356 jtag_check_value_mask(fields
+0, &field0_check_value
, &field0_check_mask
);
357 jtag_check_value_mask(fields
+2, &field2_check_value
, &field2_check_mask
);
359 field1
[i
]=buf_get_u32(tmp
, 0, 32);
364 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
366 LOG_ERROR("JTAG error while receiving data from debug handler");
370 /* examine results */
371 for (i
= words_done
; i
< num_words
; i
++)
373 if (!(field0
[0] & 1))
375 /* move backwards if necessary */
377 for (j
= i
; j
< num_words
- 1; j
++)
379 field0
[j
] = field0
[j
+1];
380 field1
[j
] = field1
[j
+1];
385 if (words_scheduled
==0)
387 if (attempts
++==1000)
389 LOG_ERROR("Failed to receiving data from debug handler after 1000 attempts");
390 retval
=ERROR_TARGET_TIMEOUT
;
395 words_done
+= words_scheduled
;
398 for (i
= 0; i
< num_words
; i
++)
399 *(buffer
++) = buf_get_u32((u8
*)&field1
[i
], 0, 32);
406 int xscale_read_tx(target_t
*target
, int consume
)
408 armv4_5_common_t
*armv4_5
= target
->arch_info
;
409 xscale_common_t
*xscale
= armv4_5
->arch_info
;
411 tap_state_t noconsume_path
[6];
414 struct timeval timeout
, now
;
416 scan_field_t fields
[3];
418 u8 field0_check_value
= 0x2;
419 u8 field0_check_mask
= 0x6;
420 u8 field2_check_value
= 0x0;
421 u8 field2_check_mask
= 0x1;
423 jtag_add_end_state(TAP_IDLE
);
425 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dbgtx
);
427 path
[0] = TAP_DRSELECT
;
428 path
[1] = TAP_DRCAPTURE
;
429 path
[2] = TAP_DRSHIFT
;
431 noconsume_path
[0] = TAP_DRSELECT
;
432 noconsume_path
[1] = TAP_DRCAPTURE
;
433 noconsume_path
[2] = TAP_DREXIT1
;
434 noconsume_path
[3] = TAP_DRPAUSE
;
435 noconsume_path
[4] = TAP_DREXIT2
;
436 noconsume_path
[5] = TAP_DRSHIFT
;
438 fields
[0].tap
= xscale
->jtag_info
.tap
;
439 fields
[0].num_bits
= 3;
440 fields
[0].out_value
= NULL
;
441 fields
[0].in_value
= &field0_in
;
443 fields
[1].tap
= xscale
->jtag_info
.tap
;
444 fields
[1].num_bits
= 32;
445 fields
[1].out_value
= NULL
;
446 fields
[1].in_value
= xscale
->reg_cache
->reg_list
[XSCALE_TX
].value
;
449 fields
[2].tap
= xscale
->jtag_info
.tap
;
450 fields
[2].num_bits
= 1;
451 fields
[2].out_value
= NULL
;
453 fields
[2].in_value
= &tmp
;
455 gettimeofday(&timeout
, NULL
);
456 timeval_add_time(&timeout
, 1, 0);
460 /* if we want to consume the register content (i.e. clear TX_READY),
461 * we have to go straight from Capture-DR to Shift-DR
462 * otherwise, we go from Capture-DR to Exit1-DR to Pause-DR
465 jtag_add_pathmove(3, path
);
468 jtag_add_pathmove(sizeof(noconsume_path
)/sizeof(*noconsume_path
), noconsume_path
);
471 jtag_add_dr_scan(3, fields
, TAP_IDLE
);
473 jtag_check_value_mask(fields
+0, &field0_check_value
, &field0_check_mask
);
474 jtag_check_value_mask(fields
+2, &field2_check_value
, &field2_check_mask
);
476 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
478 LOG_ERROR("JTAG error while reading TX");
479 return ERROR_TARGET_TIMEOUT
;
482 gettimeofday(&now
, NULL
);
483 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
)&& (now
.tv_usec
> timeout
.tv_usec
)))
485 LOG_ERROR("time out reading TX register");
486 return ERROR_TARGET_TIMEOUT
;
488 if (!((!(field0_in
& 1)) && consume
))
494 LOG_DEBUG("waiting 100ms");
495 alive_sleep(100); /* avoid flooding the logs */
503 if (!(field0_in
& 1))
504 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
509 int xscale_write_rx(target_t
*target
)
511 armv4_5_common_t
*armv4_5
= target
->arch_info
;
512 xscale_common_t
*xscale
= armv4_5
->arch_info
;
515 struct timeval timeout
, now
;
517 scan_field_t fields
[3];
520 u8 field0_check_value
= 0x2;
521 u8 field0_check_mask
= 0x6;
523 u8 field2_check_value
= 0x0;
524 u8 field2_check_mask
= 0x1;
526 jtag_add_end_state(TAP_IDLE
);
528 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dbgrx
);
530 fields
[0].tap
= xscale
->jtag_info
.tap
;
531 fields
[0].num_bits
= 3;
532 fields
[0].out_value
= &field0_out
;
533 fields
[0].in_value
= &field0_in
;
535 fields
[1].tap
= xscale
->jtag_info
.tap
;
536 fields
[1].num_bits
= 32;
537 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
;
538 fields
[1].in_value
= NULL
;
541 fields
[2].tap
= xscale
->jtag_info
.tap
;
542 fields
[2].num_bits
= 1;
543 fields
[2].out_value
= &field2
;
545 fields
[2].in_value
= &tmp
;
547 gettimeofday(&timeout
, NULL
);
548 timeval_add_time(&timeout
, 1, 0);
550 /* poll until rx_read is low */
551 LOG_DEBUG("polling RX");
554 jtag_add_dr_scan(3, fields
, TAP_IDLE
);
556 jtag_check_value_mask(fields
+0, &field0_check_value
, &field0_check_mask
);
557 jtag_check_value_mask(fields
+2, &field2_check_value
, &field2_check_mask
);
559 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
561 LOG_ERROR("JTAG error while writing RX");
565 gettimeofday(&now
, NULL
);
566 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
)&& (now
.tv_usec
> timeout
.tv_usec
)))
568 LOG_ERROR("time out writing RX register");
569 return ERROR_TARGET_TIMEOUT
;
571 if (!(field0_in
& 1))
575 LOG_DEBUG("waiting 100ms");
576 alive_sleep(100); /* avoid flooding the logs */
586 jtag_add_dr_scan(3, fields
, TAP_IDLE
);
588 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
590 LOG_ERROR("JTAG error while writing RX");
597 /* send count elements of size byte to the debug handler */
598 int xscale_send(target_t
*target
, u8
*buffer
, int count
, int size
)
600 armv4_5_common_t
*armv4_5
= target
->arch_info
;
601 xscale_common_t
*xscale
= armv4_5
->arch_info
;
609 jtag_add_end_state(TAP_IDLE
);
611 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dbgrx
);
618 int endianness
= target
->endianness
;
619 while (done_count
++ < count
)
624 if (endianness
== TARGET_LITTLE_ENDIAN
)
626 t
[1]=le_to_h_u32(buffer
);
629 t
[1]=be_to_h_u32(buffer
);
633 if (endianness
== TARGET_LITTLE_ENDIAN
)
635 t
[1]=le_to_h_u16(buffer
);
638 t
[1]=be_to_h_u16(buffer
);
645 LOG_ERROR("BUG: size neither 4, 2 nor 1");
648 jtag_add_dr_out(xscale
->jtag_info
.tap
,
656 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
658 LOG_ERROR("JTAG error while sending data to debug handler");
665 int xscale_send_u32(target_t
*target
, u32 value
)
667 armv4_5_common_t
*armv4_5
= target
->arch_info
;
668 xscale_common_t
*xscale
= armv4_5
->arch_info
;
670 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
671 return xscale_write_rx(target
);
674 int xscale_write_dcsr(target_t
*target
, int hold_rst
, int ext_dbg_brk
)
676 armv4_5_common_t
*armv4_5
= target
->arch_info
;
677 xscale_common_t
*xscale
= armv4_5
->arch_info
;
681 scan_field_t fields
[3];
683 u8 field0_check_value
= 0x2;
684 u8 field0_check_mask
= 0x7;
686 u8 field2_check_value
= 0x0;
687 u8 field2_check_mask
= 0x1;
690 xscale
->hold_rst
= hold_rst
;
692 if (ext_dbg_brk
!= -1)
693 xscale
->external_debug_break
= ext_dbg_brk
;
695 jtag_add_end_state(TAP_IDLE
);
696 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dcsr
);
698 buf_set_u32(&field0
, 1, 1, xscale
->hold_rst
);
699 buf_set_u32(&field0
, 2, 1, xscale
->external_debug_break
);
701 fields
[0].tap
= xscale
->jtag_info
.tap
;
702 fields
[0].num_bits
= 3;
703 fields
[0].out_value
= &field0
;
705 fields
[0].in_value
= &tmp
;
707 fields
[1].tap
= xscale
->jtag_info
.tap
;
708 fields
[1].num_bits
= 32;
709 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
710 fields
[1].in_value
= NULL
;
713 fields
[2].tap
= xscale
->jtag_info
.tap
;
714 fields
[2].num_bits
= 1;
715 fields
[2].out_value
= &field2
;
717 fields
[2].in_value
= &tmp2
;
719 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
721 jtag_check_value_mask(fields
+0, &field0_check_value
, &field0_check_mask
);
722 jtag_check_value_mask(fields
+2, &field2_check_value
, &field2_check_mask
);
724 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
726 LOG_ERROR("JTAG error while writing DCSR");
730 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].dirty
= 0;
731 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].valid
= 1;
736 /* parity of the number of bits 0 if even; 1 if odd. for 32 bit words */
737 unsigned int parity (unsigned int v
)
744 LOG_DEBUG("parity of 0x%x is %i", ov
, (0x6996 >> v
) & 1);
745 return (0x6996 >> v
) & 1;
748 int xscale_load_ic(target_t
*target
, int mini
, u32 va
, u32 buffer
[8])
750 armv4_5_common_t
*armv4_5
= target
->arch_info
;
751 xscale_common_t
*xscale
= armv4_5
->arch_info
;
756 scan_field_t fields
[2];
758 LOG_DEBUG("loading miniIC at 0x%8.8x", va
);
760 jtag_add_end_state(TAP_IDLE
);
761 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.ldic
); /* LDIC */
763 /* CMD is b010 for Main IC and b011 for Mini IC */
765 buf_set_u32(&cmd
, 0, 3, 0x3);
767 buf_set_u32(&cmd
, 0, 3, 0x2);
769 buf_set_u32(&cmd
, 3, 3, 0x0);
771 /* virtual address of desired cache line */
772 buf_set_u32(packet
, 0, 27, va
>> 5);
774 fields
[0].tap
= xscale
->jtag_info
.tap
;
775 fields
[0].num_bits
= 6;
776 fields
[0].out_value
= &cmd
;
778 fields
[0].in_value
= NULL
;
784 fields
[1].tap
= xscale
->jtag_info
.tap
;
785 fields
[1].num_bits
= 27;
786 fields
[1].out_value
= packet
;
788 fields
[1].in_value
= NULL
;
794 jtag_add_dr_scan(2, fields
, TAP_INVALID
);
796 fields
[0].num_bits
= 32;
797 fields
[0].out_value
= packet
;
799 fields
[1].num_bits
= 1;
800 fields
[1].out_value
= &cmd
;
802 for (word
= 0; word
< 8; word
++)
804 buf_set_u32(packet
, 0, 32, buffer
[word
]);
807 memcpy(&value
, packet
, sizeof(u32
));
810 jtag_add_dr_scan(2, fields
, TAP_INVALID
);
813 jtag_execute_queue();
818 int xscale_invalidate_ic_line(target_t
*target
, u32 va
)
820 armv4_5_common_t
*armv4_5
= target
->arch_info
;
821 xscale_common_t
*xscale
= armv4_5
->arch_info
;
825 scan_field_t fields
[2];
827 jtag_add_end_state(TAP_IDLE
);
828 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.ldic
); /* LDIC */
830 /* CMD for invalidate IC line b000, bits [6:4] b000 */
831 buf_set_u32(&cmd
, 0, 6, 0x0);
833 /* virtual address of desired cache line */
834 buf_set_u32(packet
, 0, 27, va
>> 5);
836 fields
[0].tap
= xscale
->jtag_info
.tap
;
837 fields
[0].num_bits
= 6;
838 fields
[0].out_value
= &cmd
;
840 fields
[0].in_value
= NULL
;
846 fields
[1].tap
= xscale
->jtag_info
.tap
;
847 fields
[1].num_bits
= 27;
848 fields
[1].out_value
= packet
;
850 fields
[1].in_value
= NULL
;
856 jtag_add_dr_scan(2, fields
, TAP_INVALID
);
861 int xscale_update_vectors(target_t
*target
)
863 armv4_5_common_t
*armv4_5
= target
->arch_info
;
864 xscale_common_t
*xscale
= armv4_5
->arch_info
;
868 u32 low_reset_branch
, high_reset_branch
;
870 for (i
= 1; i
< 8; i
++)
872 /* if there's a static vector specified for this exception, override */
873 if (xscale
->static_high_vectors_set
& (1 << i
))
875 xscale
->high_vectors
[i
] = xscale
->static_high_vectors
[i
];
879 retval
=target_read_u32(target
, 0xffff0000 + 4*i
, &xscale
->high_vectors
[i
]);
880 if (retval
== ERROR_TARGET_TIMEOUT
)
882 if (retval
!=ERROR_OK
)
884 /* Some of these reads will fail as part of normal execution */
885 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
890 for (i
= 1; i
< 8; i
++)
892 if (xscale
->static_low_vectors_set
& (1 << i
))
894 xscale
->low_vectors
[i
] = xscale
->static_low_vectors
[i
];
898 retval
=target_read_u32(target
, 0x0 + 4*i
, &xscale
->low_vectors
[i
]);
899 if (retval
== ERROR_TARGET_TIMEOUT
)
901 if (retval
!=ERROR_OK
)
903 /* Some of these reads will fail as part of normal execution */
904 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
909 /* calculate branches to debug handler */
910 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
911 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
913 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
914 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
916 /* invalidate and load exception vectors in mini i-cache */
917 xscale_invalidate_ic_line(target
, 0x0);
918 xscale_invalidate_ic_line(target
, 0xffff0000);
920 xscale_load_ic(target
, 1, 0x0, xscale
->low_vectors
);
921 xscale_load_ic(target
, 1, 0xffff0000, xscale
->high_vectors
);
926 int xscale_arch_state(struct target_s
*target
)
928 armv4_5_common_t
*armv4_5
= target
->arch_info
;
929 xscale_common_t
*xscale
= armv4_5
->arch_info
;
933 "disabled", "enabled"
936 char *arch_dbg_reason
[] =
938 "", "\n(processor reset)", "\n(trace buffer full)"
941 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
943 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
947 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
948 "cpsr: 0x%8.8x pc: 0x%8.8x\n"
949 "MMU: %s, D-Cache: %s, I-Cache: %s"
951 armv4_5_state_strings
[armv4_5
->core_state
],
952 Jim_Nvp_value2name_simple( nvp_target_debug_reason
, target
->debug_reason
)->name
,
953 armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)],
954 buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32),
955 buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32),
956 state
[xscale
->armv4_5_mmu
.mmu_enabled
],
957 state
[xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
],
958 state
[xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
],
959 arch_dbg_reason
[xscale
->arch_debug_reason
]);
964 int xscale_poll(target_t
*target
)
967 armv4_5_common_t
*armv4_5
= target
->arch_info
;
968 xscale_common_t
*xscale
= armv4_5
->arch_info
;
970 if ((target
->state
== TARGET_RUNNING
) || (target
->state
== TARGET_DEBUG_RUNNING
))
972 enum target_state previous_state
= target
->state
;
973 if ((retval
= xscale_read_tx(target
, 0)) == ERROR_OK
)
976 /* there's data to read from the tx register, we entered debug state */
977 xscale
->handler_running
= 1;
979 target
->state
= TARGET_HALTED
;
981 /* process debug entry, fetching current mode regs */
982 retval
= xscale_debug_entry(target
);
984 else if (retval
!= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
986 LOG_USER("error while polling TX register, reset CPU");
987 /* here we "lie" so GDB won't get stuck and a reset can be perfomed */
988 target
->state
= TARGET_HALTED
;
991 /* debug_entry could have overwritten target state (i.e. immediate resume)
992 * don't signal event handlers in that case
994 if (target
->state
!= TARGET_HALTED
)
997 /* if target was running, signal that we halted
998 * otherwise we reentered from debug execution */
999 if (previous_state
== TARGET_RUNNING
)
1000 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1002 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
1008 int xscale_debug_entry(target_t
*target
)
1010 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1011 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1019 /* clear external dbg break (will be written on next DCSR read) */
1020 xscale
->external_debug_break
= 0;
1021 if ((retval
=xscale_read_dcsr(target
))!=ERROR_OK
)
1024 /* get r0, pc, r1 to r7 and cpsr */
1025 if ((retval
=xscale_receive(target
, buffer
, 10))!=ERROR_OK
)
1028 /* move r0 from buffer to register cache */
1029 buf_set_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32, buffer
[0]);
1030 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
1031 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
1032 LOG_DEBUG("r0: 0x%8.8x", buffer
[0]);
1034 /* move pc from buffer to register cache */
1035 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, buffer
[1]);
1036 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
1037 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
1038 LOG_DEBUG("pc: 0x%8.8x", buffer
[1]);
1040 /* move data from buffer to register cache */
1041 for (i
= 1; i
<= 7; i
++)
1043 buf_set_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32, buffer
[1 + i
]);
1044 armv4_5
->core_cache
->reg_list
[i
].dirty
= 1;
1045 armv4_5
->core_cache
->reg_list
[i
].valid
= 1;
1046 LOG_DEBUG("r%i: 0x%8.8x", i
, buffer
[i
+ 1]);
1049 buf_set_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32, buffer
[9]);
1050 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].dirty
= 1;
1051 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].valid
= 1;
1052 LOG_DEBUG("cpsr: 0x%8.8x", buffer
[9]);
1054 armv4_5
->core_mode
= buffer
[9] & 0x1f;
1055 if (armv4_5_mode_to_number(armv4_5
->core_mode
) == -1)
1057 target
->state
= TARGET_UNKNOWN
;
1058 LOG_ERROR("cpsr contains invalid mode value - communication failure");
1059 return ERROR_TARGET_FAILURE
;
1061 LOG_DEBUG("target entered debug state in %s mode", armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)]);
1063 if (buffer
[9] & 0x20)
1064 armv4_5
->core_state
= ARMV4_5_STATE_THUMB
;
1066 armv4_5
->core_state
= ARMV4_5_STATE_ARM
;
1069 if (armv4_5_mode_to_number(armv4_5
->core_mode
)==-1)
1072 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1073 if ((armv4_5
->core_mode
!= ARMV4_5_MODE_USR
) && (armv4_5
->core_mode
!= ARMV4_5_MODE_SYS
))
1075 xscale_receive(target
, buffer
, 8);
1076 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1077 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
1078 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
1082 /* r8 to r14, but no spsr */
1083 xscale_receive(target
, buffer
, 7);
1086 /* move data from buffer to register cache */
1087 for (i
= 8; i
<= 14; i
++)
1089 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).value
, 0, 32, buffer
[i
- 8]);
1090 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).dirty
= 0;
1091 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).valid
= 1;
1094 /* examine debug reason */
1095 xscale_read_dcsr(target
);
1096 moe
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 2, 3);
1098 /* stored PC (for calculating fixup) */
1099 pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1103 case 0x0: /* Processor reset */
1104 target
->debug_reason
= DBG_REASON_DBGRQ
;
1105 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_RESET
;
1108 case 0x1: /* Instruction breakpoint hit */
1109 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1110 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1113 case 0x2: /* Data breakpoint hit */
1114 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
1115 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1118 case 0x3: /* BKPT instruction executed */
1119 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1120 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1123 case 0x4: /* Ext. debug event */
1124 target
->debug_reason
= DBG_REASON_DBGRQ
;
1125 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1128 case 0x5: /* Vector trap occured */
1129 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1130 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1133 case 0x6: /* Trace buffer full break */
1134 target
->debug_reason
= DBG_REASON_DBGRQ
;
1135 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_TB_FULL
;
1138 case 0x7: /* Reserved */
1140 LOG_ERROR("Method of Entry is 'Reserved'");
1145 /* apply PC fixup */
1146 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, pc
);
1148 /* on the first debug entry, identify cache type */
1149 if (xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
1153 /* read cp15 cache type register */
1154 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
]);
1155 cache_type_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
].value
, 0, 32);
1157 armv4_5_identify_cache(cache_type_reg
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
1160 /* examine MMU and Cache settings */
1161 /* read cp15 control register */
1162 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
1163 xscale
->cp15_control_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
1164 xscale
->armv4_5_mmu
.mmu_enabled
= (xscale
->cp15_control_reg
& 0x1U
) ? 1 : 0;
1165 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= (xscale
->cp15_control_reg
& 0x4U
) ? 1 : 0;
1166 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= (xscale
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
1168 /* tracing enabled, read collected trace data */
1169 if (xscale
->trace
.buffer_enabled
)
1171 xscale_read_trace(target
);
1172 xscale
->trace
.buffer_fill
--;
1174 /* resume if we're still collecting trace data */
1175 if ((xscale
->arch_debug_reason
== XSCALE_DBG_REASON_TB_FULL
)
1176 && (xscale
->trace
.buffer_fill
> 0))
1178 xscale_resume(target
, 1, 0x0, 1, 0);
1182 xscale
->trace
.buffer_enabled
= 0;
1189 int xscale_halt(target_t
*target
)
1191 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1192 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1194 LOG_DEBUG("target->state: %s",
1195 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
1197 if (target
->state
== TARGET_HALTED
)
1199 LOG_DEBUG("target was already halted");
1202 else if (target
->state
== TARGET_UNKNOWN
)
1204 /* this must not happen for a xscale target */
1205 LOG_ERROR("target was in unknown state when halt was requested");
1206 return ERROR_TARGET_INVALID
;
1208 else if (target
->state
== TARGET_RESET
)
1210 LOG_DEBUG("target->state == TARGET_RESET");
1214 /* assert external dbg break */
1215 xscale
->external_debug_break
= 1;
1216 xscale_read_dcsr(target
);
1218 target
->debug_reason
= DBG_REASON_DBGRQ
;
1224 int xscale_enable_single_step(struct target_s
*target
, u32 next_pc
)
1226 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1227 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1228 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1231 if (xscale
->ibcr0_used
)
1233 breakpoint_t
*ibcr0_bp
= breakpoint_find(target
, buf_get_u32(ibcr0
->value
, 0, 32) & 0xfffffffe);
1237 xscale_unset_breakpoint(target
, ibcr0_bp
);
1241 LOG_ERROR("BUG: xscale->ibcr0_used is set, but no breakpoint with that address found");
1246 if ((retval
=xscale_set_reg_u32(ibcr0
, next_pc
| 0x1))!=ERROR_OK
)
1252 int xscale_disable_single_step(struct target_s
*target
)
1254 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1255 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1256 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1259 if ((retval
=xscale_set_reg_u32(ibcr0
, 0x0))!=ERROR_OK
)
1265 int xscale_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
1267 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1268 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1269 breakpoint_t
*breakpoint
= target
->breakpoints
;
1278 if (target
->state
!= TARGET_HALTED
)
1280 LOG_WARNING("target not halted");
1281 return ERROR_TARGET_NOT_HALTED
;
1284 if (!debug_execution
)
1286 target_free_all_working_areas(target
);
1289 /* update vector tables */
1290 if ((retval
=xscale_update_vectors(target
))!=ERROR_OK
)
1293 /* current = 1: continue on current pc, otherwise continue at <address> */
1295 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1297 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1299 /* if we're at the reset vector, we have to simulate the branch */
1300 if (current_pc
== 0x0)
1302 arm_simulate_step(target
, NULL
);
1303 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1306 /* the front-end may request us not to handle breakpoints */
1307 if (handle_breakpoints
)
1309 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1313 /* there's a breakpoint at the current PC, we have to step over it */
1314 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
1315 xscale_unset_breakpoint(target
, breakpoint
);
1317 /* calculate PC of next instruction */
1318 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1321 target_read_u32(target
, current_pc
, ¤t_opcode
);
1322 LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode
);
1325 LOG_DEBUG("enable single-step");
1326 xscale_enable_single_step(target
, next_pc
);
1328 /* restore banked registers */
1329 xscale_restore_context(target
);
1331 /* send resume request (command 0x30 or 0x31)
1332 * clean the trace buffer if it is to be enabled (0x62) */
1333 if (xscale
->trace
.buffer_enabled
)
1335 xscale_send_u32(target
, 0x62);
1336 xscale_send_u32(target
, 0x31);
1339 xscale_send_u32(target
, 0x30);
1342 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1343 LOG_DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1345 for (i
= 7; i
>= 0; i
--)
1348 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1349 LOG_DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1353 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1354 LOG_DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1356 /* wait for and process debug entry */
1357 xscale_debug_entry(target
);
1359 LOG_DEBUG("disable single-step");
1360 xscale_disable_single_step(target
);
1362 LOG_DEBUG("set breakpoint at 0x%8.8x", breakpoint
->address
);
1363 xscale_set_breakpoint(target
, breakpoint
);
1367 /* enable any pending breakpoints and watchpoints */
1368 xscale_enable_breakpoints(target
);
1369 xscale_enable_watchpoints(target
);
1371 /* restore banked registers */
1372 xscale_restore_context(target
);
1374 /* send resume request (command 0x30 or 0x31)
1375 * clean the trace buffer if it is to be enabled (0x62) */
1376 if (xscale
->trace
.buffer_enabled
)
1378 xscale_send_u32(target
, 0x62);
1379 xscale_send_u32(target
, 0x31);
1382 xscale_send_u32(target
, 0x30);
1385 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1386 LOG_DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1388 for (i
= 7; i
>= 0; i
--)
1391 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1392 LOG_DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1396 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1397 LOG_DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1399 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1401 if (!debug_execution
)
1403 /* registers are now invalid */
1404 armv4_5_invalidate_core_regs(target
);
1405 target
->state
= TARGET_RUNNING
;
1406 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1410 target
->state
= TARGET_DEBUG_RUNNING
;
1411 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1414 LOG_DEBUG("target resumed");
1416 xscale
->handler_running
= 1;
1421 static int xscale_step_inner(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
1423 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1424 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1430 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1432 /* calculate PC of next instruction */
1433 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1435 u32 current_opcode
, current_pc
;
1436 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1438 target_read_u32(target
, current_pc
, ¤t_opcode
);
1439 LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode
);
1443 LOG_DEBUG("enable single-step");
1444 if ((retval
=xscale_enable_single_step(target
, next_pc
))!=ERROR_OK
)
1447 /* restore banked registers */
1448 if ((retval
=xscale_restore_context(target
))!=ERROR_OK
)
1451 /* send resume request (command 0x30 or 0x31)
1452 * clean the trace buffer if it is to be enabled (0x62) */
1453 if (xscale
->trace
.buffer_enabled
)
1455 if ((retval
=xscale_send_u32(target
, 0x62))!=ERROR_OK
)
1457 if ((retval
=xscale_send_u32(target
, 0x31))!=ERROR_OK
)
1461 if ((retval
=xscale_send_u32(target
, 0x30))!=ERROR_OK
)
1465 if ((retval
=xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32)))!=ERROR_OK
)
1467 LOG_DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1469 for (i
= 7; i
>= 0; i
--)
1472 if ((retval
=xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32)))!=ERROR_OK
)
1474 LOG_DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1478 if ((retval
=xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32)))!=ERROR_OK
)
1480 LOG_DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1482 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1484 /* registers are now invalid */
1485 if ((retval
=armv4_5_invalidate_core_regs(target
))!=ERROR_OK
)
1488 /* wait for and process debug entry */
1489 if ((retval
=xscale_debug_entry(target
))!=ERROR_OK
)
1492 LOG_DEBUG("disable single-step");
1493 if ((retval
=xscale_disable_single_step(target
))!=ERROR_OK
)
1496 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1501 int xscale_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
1503 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1504 breakpoint_t
*breakpoint
= target
->breakpoints
;
1509 if (target
->state
!= TARGET_HALTED
)
1511 LOG_WARNING("target not halted");
1512 return ERROR_TARGET_NOT_HALTED
;
1515 /* current = 1: continue on current pc, otherwise continue at <address> */
1517 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1519 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1521 /* if we're at the reset vector, we have to simulate the step */
1522 if (current_pc
== 0x0)
1524 if ((retval
=arm_simulate_step(target
, NULL
))!=ERROR_OK
)
1526 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1528 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1529 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1534 /* the front-end may request us not to handle breakpoints */
1535 if (handle_breakpoints
)
1536 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1538 if ((retval
=xscale_unset_breakpoint(target
, breakpoint
))!=ERROR_OK
)
1542 retval
= xscale_step_inner(target
, current
, address
, handle_breakpoints
);
1546 xscale_set_breakpoint(target
, breakpoint
);
1549 LOG_DEBUG("target stepped");
1555 int xscale_assert_reset(target_t
*target
)
1557 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1558 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1560 LOG_DEBUG("target->state: %s",
1561 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
1563 /* select DCSR instruction (set endstate to R-T-I to ensure we don't
1564 * end up in T-L-R, which would reset JTAG
1566 jtag_add_end_state(TAP_IDLE
);
1567 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dcsr
);
1569 /* set Hold reset, Halt mode and Trap Reset */
1570 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1571 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1572 xscale_write_dcsr(target
, 1, 0);
1574 /* select BYPASS, because having DCSR selected caused problems on the PXA27x */
1575 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, 0x7f);
1576 jtag_execute_queue();
1579 jtag_add_reset(0, 1);
1581 /* sleep 1ms, to be sure we fulfill any requirements */
1582 jtag_add_sleep(1000);
1583 jtag_execute_queue();
1585 target
->state
= TARGET_RESET
;
1587 if (target
->reset_halt
)
1590 if ((retval
= target_halt(target
))!=ERROR_OK
)
1597 int xscale_deassert_reset(target_t
*target
)
1599 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1600 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1602 fileio_t debug_handler
;
1610 breakpoint_t
*breakpoint
= target
->breakpoints
;
1614 xscale
->ibcr_available
= 2;
1615 xscale
->ibcr0_used
= 0;
1616 xscale
->ibcr1_used
= 0;
1618 xscale
->dbr_available
= 2;
1619 xscale
->dbr0_used
= 0;
1620 xscale
->dbr1_used
= 0;
1622 /* mark all hardware breakpoints as unset */
1625 if (breakpoint
->type
== BKPT_HARD
)
1627 breakpoint
->set
= 0;
1629 breakpoint
= breakpoint
->next
;
1632 if (!xscale
->handler_installed
)
1635 jtag_add_reset(0, 0);
1637 /* wait 300ms; 150 and 100ms were not enough */
1638 jtag_add_sleep(300*1000);
1640 jtag_add_runtest(2030, TAP_IDLE
);
1641 jtag_execute_queue();
1643 /* set Hold reset, Halt mode and Trap Reset */
1644 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1645 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1646 xscale_write_dcsr(target
, 1, 0);
1648 /* Load debug handler */
1649 if (fileio_open(&debug_handler
, "xscale/debug_handler.bin", FILEIO_READ
, FILEIO_BINARY
) != ERROR_OK
)
1654 if ((binary_size
= debug_handler
.size
) % 4)
1656 LOG_ERROR("debug_handler.bin: size not a multiple of 4");
1660 if (binary_size
> 0x800)
1662 LOG_ERROR("debug_handler.bin: larger than 2kb");
1666 binary_size
= CEIL(binary_size
, 32) * 32;
1668 address
= xscale
->handler_address
;
1669 while (binary_size
> 0)
1674 if ((retval
= fileio_read(&debug_handler
, 32, buffer
, &buf_cnt
)) != ERROR_OK
)
1679 for (i
= 0; i
< buf_cnt
; i
+= 4)
1681 /* convert LE buffer to host-endian u32 */
1682 cache_line
[i
/ 4] = le_to_h_u32(&buffer
[i
]);
1685 for (; buf_cnt
< 32; buf_cnt
+= 4)
1687 cache_line
[buf_cnt
/ 4] = 0xe1a08008;
1690 /* only load addresses other than the reset vectors */
1691 if ((address
% 0x400) != 0x0)
1693 xscale_load_ic(target
, 1, address
, cache_line
);
1697 binary_size
-= buf_cnt
;
1700 xscale_load_ic(target
, 1, 0x0, xscale
->low_vectors
);
1701 xscale_load_ic(target
, 1, 0xffff0000, xscale
->high_vectors
);
1703 jtag_add_runtest(30, TAP_IDLE
);
1705 jtag_add_sleep(100000);
1707 /* set Hold reset, Halt mode and Trap Reset */
1708 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1709 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1710 xscale_write_dcsr(target
, 1, 0);
1712 /* clear Hold reset to let the target run (should enter debug handler) */
1713 xscale_write_dcsr(target
, 0, 1);
1714 target
->state
= TARGET_RUNNING
;
1716 if (!target
->reset_halt
)
1718 jtag_add_sleep(10000);
1720 /* we should have entered debug now */
1721 xscale_debug_entry(target
);
1722 target
->state
= TARGET_HALTED
;
1724 /* resume the target */
1725 xscale_resume(target
, 1, 0x0, 1, 0);
1728 fileio_close(&debug_handler
);
1732 jtag_add_reset(0, 0);
1738 int xscale_soft_reset_halt(struct target_s
*target
)
1743 int xscale_read_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
)
1748 int xscale_write_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
, u32 value
)
1754 int xscale_full_context(target_t
*target
)
1756 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1764 if (target
->state
!= TARGET_HALTED
)
1766 LOG_WARNING("target not halted");
1767 return ERROR_TARGET_NOT_HALTED
;
1770 buffer
= malloc(4 * 8);
1772 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1773 * we can't enter User mode on an XScale (unpredictable),
1774 * but User shares registers with SYS
1776 for(i
= 1; i
< 7; i
++)
1780 /* check if there are invalid registers in the current mode
1782 for (j
= 0; j
<= 16; j
++)
1784 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
== 0)
1792 /* request banked registers */
1793 xscale_send_u32(target
, 0x0);
1796 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1797 tmp_cpsr
|= 0xc0; /* I/F bits */
1799 /* send CPSR for desired mode */
1800 xscale_send_u32(target
, tmp_cpsr
);
1802 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1803 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1805 xscale_receive(target
, buffer
, 8);
1806 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1807 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1808 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).valid
= 1;
1812 xscale_receive(target
, buffer
, 7);
1815 /* move data from buffer to register cache */
1816 for (j
= 8; j
<= 14; j
++)
1818 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]);
1819 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1820 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
= 1;
1830 int xscale_restore_context(target_t
*target
)
1832 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1838 if (target
->state
!= TARGET_HALTED
)
1840 LOG_WARNING("target not halted");
1841 return ERROR_TARGET_NOT_HALTED
;
1844 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1845 * we can't enter User mode on an XScale (unpredictable),
1846 * but User shares registers with SYS
1848 for(i
= 1; i
< 7; i
++)
1852 /* check if there are invalid registers in the current mode
1854 for (j
= 8; j
<= 14; j
++)
1856 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
== 1)
1860 /* if not USR/SYS, check if the SPSR needs to be written */
1861 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1863 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
== 1)
1871 /* send banked registers */
1872 xscale_send_u32(target
, 0x1);
1875 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1876 tmp_cpsr
|= 0xc0; /* I/F bits */
1878 /* send CPSR for desired mode */
1879 xscale_send_u32(target
, tmp_cpsr
);
1881 /* send banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1882 for (j
= 8; j
<= 14; j
++)
1884 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, j
).value
, 0, 32));
1885 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1888 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1890 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32));
1891 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1899 int xscale_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1901 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1902 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1907 LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address
, size
, count
);
1909 if (target
->state
!= TARGET_HALTED
)
1911 LOG_WARNING("target not halted");
1912 return ERROR_TARGET_NOT_HALTED
;
1915 /* sanitize arguments */
1916 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1917 return ERROR_INVALID_ARGUMENTS
;
1919 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1920 return ERROR_TARGET_UNALIGNED_ACCESS
;
1922 /* send memory read request (command 0x1n, n: access size) */
1923 if ((retval
=xscale_send_u32(target
, 0x10 | size
))!=ERROR_OK
)
1926 /* send base address for read request */
1927 if ((retval
=xscale_send_u32(target
, address
))!=ERROR_OK
)
1930 /* send number of requested data words */
1931 if ((retval
=xscale_send_u32(target
, count
))!=ERROR_OK
)
1934 /* receive data from target (count times 32-bit words in host endianness) */
1935 buf32
= malloc(4 * count
);
1936 if ((retval
=xscale_receive(target
, buf32
, count
))!=ERROR_OK
)
1939 /* extract data from host-endian buffer into byte stream */
1940 for (i
= 0; i
< count
; i
++)
1945 target_buffer_set_u32(target
, buffer
, buf32
[i
]);
1949 target_buffer_set_u16(target
, buffer
, buf32
[i
] & 0xffff);
1953 *buffer
++ = buf32
[i
] & 0xff;
1956 LOG_ERROR("should never get here");
1963 /* examine DCSR, to see if Sticky Abort (SA) got set */
1964 if ((retval
=xscale_read_dcsr(target
))!=ERROR_OK
)
1966 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
1969 if ((retval
=xscale_send_u32(target
, 0x60))!=ERROR_OK
)
1972 return ERROR_TARGET_DATA_ABORT
;
1978 int xscale_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1980 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1981 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1984 LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address
, size
, count
);
1986 if (target
->state
!= TARGET_HALTED
)
1988 LOG_WARNING("target not halted");
1989 return ERROR_TARGET_NOT_HALTED
;
1992 /* sanitize arguments */
1993 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1994 return ERROR_INVALID_ARGUMENTS
;
1996 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1997 return ERROR_TARGET_UNALIGNED_ACCESS
;
1999 /* send memory write request (command 0x2n, n: access size) */
2000 if ((retval
=xscale_send_u32(target
, 0x20 | size
))!=ERROR_OK
)
2003 /* send base address for read request */
2004 if ((retval
=xscale_send_u32(target
, address
))!=ERROR_OK
)
2007 /* send number of requested data words to be written*/
2008 if ((retval
=xscale_send_u32(target
, count
))!=ERROR_OK
)
2011 /* extract data from host-endian buffer into byte stream */
2013 for (i
= 0; i
< count
; i
++)
2018 value
= target_buffer_get_u32(target
, buffer
);
2019 xscale_send_u32(target
, value
);
2023 value
= target_buffer_get_u16(target
, buffer
);
2024 xscale_send_u32(target
, value
);
2029 xscale_send_u32(target
, value
);
2033 LOG_ERROR("should never get here");
2038 if ((retval
=xscale_send(target
, buffer
, count
, size
))!=ERROR_OK
)
2041 /* examine DCSR, to see if Sticky Abort (SA) got set */
2042 if ((retval
=xscale_read_dcsr(target
))!=ERROR_OK
)
2044 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
2047 if ((retval
=xscale_send_u32(target
, 0x60))!=ERROR_OK
)
2050 return ERROR_TARGET_DATA_ABORT
;
2056 int xscale_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
2058 return xscale_write_memory(target
, address
, 4, count
, buffer
);
2061 u32
xscale_get_ttb(target_t
*target
)
2063 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2064 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2067 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_TTB
]);
2068 ttb
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_TTB
].value
, 0, 32);
2073 void xscale_disable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
2075 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2076 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2079 /* read cp15 control register */
2080 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2081 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2084 cp15_control
&= ~0x1U
;
2089 xscale_send_u32(target
, 0x50);
2090 xscale_send_u32(target
, xscale
->cache_clean_address
);
2092 /* invalidate DCache */
2093 xscale_send_u32(target
, 0x51);
2095 cp15_control
&= ~0x4U
;
2100 /* invalidate ICache */
2101 xscale_send_u32(target
, 0x52);
2102 cp15_control
&= ~0x1000U
;
2105 /* write new cp15 control register */
2106 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2108 /* execute cpwait to ensure outstanding operations complete */
2109 xscale_send_u32(target
, 0x53);
2112 void xscale_enable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
2114 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2115 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2118 /* read cp15 control register */
2119 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2120 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2123 cp15_control
|= 0x1U
;
2126 cp15_control
|= 0x4U
;
2129 cp15_control
|= 0x1000U
;
2131 /* write new cp15 control register */
2132 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2134 /* execute cpwait to ensure outstanding operations complete */
2135 xscale_send_u32(target
, 0x53);
2138 int xscale_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2141 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2142 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2144 if (target
->state
!= TARGET_HALTED
)
2146 LOG_WARNING("target not halted");
2147 return ERROR_TARGET_NOT_HALTED
;
2150 if (breakpoint
->set
)
2152 LOG_WARNING("breakpoint already set");
2156 if (breakpoint
->type
== BKPT_HARD
)
2158 u32 value
= breakpoint
->address
| 1;
2159 if (!xscale
->ibcr0_used
)
2161 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], value
);
2162 xscale
->ibcr0_used
= 1;
2163 breakpoint
->set
= 1; /* breakpoint set on first breakpoint register */
2165 else if (!xscale
->ibcr1_used
)
2167 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], value
);
2168 xscale
->ibcr1_used
= 1;
2169 breakpoint
->set
= 2; /* breakpoint set on second breakpoint register */
2173 LOG_ERROR("BUG: no hardware comparator available");
2177 else if (breakpoint
->type
== BKPT_SOFT
)
2179 if (breakpoint
->length
== 4)
2181 /* keep the original instruction in target endianness */
2182 if((retval
= target
->type
->read_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
2186 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2187 if((retval
= target_write_u32(target
, breakpoint
->address
, xscale
->arm_bkpt
)) != ERROR_OK
)
2194 /* keep the original instruction in target endianness */
2195 if((retval
= target
->type
->read_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
2199 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2200 if((retval
= target_write_u32(target
, breakpoint
->address
, xscale
->thumb_bkpt
)) != ERROR_OK
)
2205 breakpoint
->set
= 1;
2211 int xscale_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2213 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2214 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2216 if (target
->state
!= TARGET_HALTED
)
2218 LOG_WARNING("target not halted");
2219 return ERROR_TARGET_NOT_HALTED
;
2222 if ((breakpoint
->type
== BKPT_HARD
) && (xscale
->ibcr_available
< 1))
2224 LOG_INFO("no breakpoint unit available for hardware breakpoint");
2225 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2228 if ((breakpoint
->length
!= 2) && (breakpoint
->length
!= 4))
2230 LOG_INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
2231 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2234 if (breakpoint
->type
== BKPT_HARD
)
2236 xscale
->ibcr_available
--;
2242 int xscale_unset_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 LOG_WARNING("breakpoint not set");
2260 if (breakpoint
->type
== BKPT_HARD
)
2262 if (breakpoint
->set
== 1)
2264 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], 0x0);
2265 xscale
->ibcr0_used
= 0;
2267 else if (breakpoint
->set
== 2)
2269 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], 0x0);
2270 xscale
->ibcr1_used
= 0;
2272 breakpoint
->set
= 0;
2276 /* restore original instruction (kept in target endianness) */
2277 if (breakpoint
->length
== 4)
2279 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
2286 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
2291 breakpoint
->set
= 0;
2297 int xscale_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2299 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2300 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2302 if (target
->state
!= TARGET_HALTED
)
2304 LOG_WARNING("target not halted");
2305 return ERROR_TARGET_NOT_HALTED
;
2308 if (breakpoint
->set
)
2310 xscale_unset_breakpoint(target
, breakpoint
);
2313 if (breakpoint
->type
== BKPT_HARD
)
2314 xscale
->ibcr_available
++;
2319 int xscale_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2321 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2322 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2324 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2325 u32 dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2327 if (target
->state
!= TARGET_HALTED
)
2329 LOG_WARNING("target not halted");
2330 return ERROR_TARGET_NOT_HALTED
;
2333 xscale_get_reg(dbcon
);
2335 switch (watchpoint
->rw
)
2347 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
2350 if (!xscale
->dbr0_used
)
2352 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR0
], watchpoint
->address
);
2353 dbcon_value
|= enable
;
2354 xscale_set_reg_u32(dbcon
, dbcon_value
);
2355 watchpoint
->set
= 1;
2356 xscale
->dbr0_used
= 1;
2358 else if (!xscale
->dbr1_used
)
2360 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR1
], watchpoint
->address
);
2361 dbcon_value
|= enable
<< 2;
2362 xscale_set_reg_u32(dbcon
, dbcon_value
);
2363 watchpoint
->set
= 2;
2364 xscale
->dbr1_used
= 1;
2368 LOG_ERROR("BUG: no hardware comparator available");
2375 int xscale_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2377 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2378 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2380 if (target
->state
!= TARGET_HALTED
)
2382 LOG_WARNING("target not halted");
2383 return ERROR_TARGET_NOT_HALTED
;
2386 if (xscale
->dbr_available
< 1)
2388 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2391 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
2393 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2396 xscale
->dbr_available
--;
2401 int xscale_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2403 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2404 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2405 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2406 u32 dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2408 if (target
->state
!= TARGET_HALTED
)
2410 LOG_WARNING("target not halted");
2411 return ERROR_TARGET_NOT_HALTED
;
2414 if (!watchpoint
->set
)
2416 LOG_WARNING("breakpoint not set");
2420 if (watchpoint
->set
== 1)
2422 dbcon_value
&= ~0x3;
2423 xscale_set_reg_u32(dbcon
, dbcon_value
);
2424 xscale
->dbr0_used
= 0;
2426 else if (watchpoint
->set
== 2)
2428 dbcon_value
&= ~0xc;
2429 xscale_set_reg_u32(dbcon
, dbcon_value
);
2430 xscale
->dbr1_used
= 0;
2432 watchpoint
->set
= 0;
2437 int xscale_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2439 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2440 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2442 if (target
->state
!= TARGET_HALTED
)
2444 LOG_WARNING("target not halted");
2445 return ERROR_TARGET_NOT_HALTED
;
2448 if (watchpoint
->set
)
2450 xscale_unset_watchpoint(target
, watchpoint
);
2453 xscale
->dbr_available
++;
2458 void xscale_enable_watchpoints(struct target_s
*target
)
2460 watchpoint_t
*watchpoint
= target
->watchpoints
;
2464 if (watchpoint
->set
== 0)
2465 xscale_set_watchpoint(target
, watchpoint
);
2466 watchpoint
= watchpoint
->next
;
2470 void xscale_enable_breakpoints(struct target_s
*target
)
2472 breakpoint_t
*breakpoint
= target
->breakpoints
;
2474 /* set any pending breakpoints */
2477 if (breakpoint
->set
== 0)
2478 xscale_set_breakpoint(target
, breakpoint
);
2479 breakpoint
= breakpoint
->next
;
2483 int xscale_get_reg(reg_t
*reg
)
2485 xscale_reg_t
*arch_info
= reg
->arch_info
;
2486 target_t
*target
= arch_info
->target
;
2487 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2488 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2490 /* DCSR, TX and RX are accessible via JTAG */
2491 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2493 return xscale_read_dcsr(arch_info
->target
);
2495 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2497 /* 1 = consume register content */
2498 return xscale_read_tx(arch_info
->target
, 1);
2500 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2502 /* can't read from RX register (host -> debug handler) */
2505 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2507 /* can't (explicitly) read from TXRXCTRL register */
2510 else /* Other DBG registers have to be transfered by the debug handler */
2512 /* send CP read request (command 0x40) */
2513 xscale_send_u32(target
, 0x40);
2515 /* send CP register number */
2516 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2518 /* read register value */
2519 xscale_read_tx(target
, 1);
2520 buf_cpy(xscale
->reg_cache
->reg_list
[XSCALE_TX
].value
, reg
->value
, 32);
2529 int xscale_set_reg(reg_t
*reg
, u8
* buf
)
2531 xscale_reg_t
*arch_info
= reg
->arch_info
;
2532 target_t
*target
= arch_info
->target
;
2533 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2534 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2535 u32 value
= buf_get_u32(buf
, 0, 32);
2537 /* DCSR, TX and RX are accessible via JTAG */
2538 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2540 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32, value
);
2541 return xscale_write_dcsr(arch_info
->target
, -1, -1);
2543 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2545 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
2546 return xscale_write_rx(arch_info
->target
);
2548 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2550 /* can't write to TX register (debug-handler -> host) */
2553 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2555 /* can't (explicitly) write to TXRXCTRL register */
2558 else /* Other DBG registers have to be transfered by the debug handler */
2560 /* send CP write request (command 0x41) */
2561 xscale_send_u32(target
, 0x41);
2563 /* send CP register number */
2564 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2566 /* send CP register value */
2567 xscale_send_u32(target
, value
);
2568 buf_set_u32(reg
->value
, 0, 32, value
);
2574 /* convenience wrapper to access XScale specific registers */
2575 int xscale_set_reg_u32(reg_t
*reg
, u32 value
)
2579 buf_set_u32(buf
, 0, 32, value
);
2581 return xscale_set_reg(reg
, buf
);
2584 int xscale_write_dcsr_sw(target_t
*target
, u32 value
)
2586 /* get pointers to arch-specific information */
2587 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2588 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2589 reg_t
*dcsr
= &xscale
->reg_cache
->reg_list
[XSCALE_DCSR
];
2590 xscale_reg_t
*dcsr_arch_info
= dcsr
->arch_info
;
2592 /* send CP write request (command 0x41) */
2593 xscale_send_u32(target
, 0x41);
2595 /* send CP register number */
2596 xscale_send_u32(target
, dcsr_arch_info
->dbg_handler_number
);
2598 /* send CP register value */
2599 xscale_send_u32(target
, value
);
2600 buf_set_u32(dcsr
->value
, 0, 32, value
);
2605 int xscale_read_trace(target_t
*target
)
2607 /* get pointers to arch-specific information */
2608 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2609 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2610 xscale_trace_data_t
**trace_data_p
;
2612 /* 258 words from debug handler
2613 * 256 trace buffer entries
2614 * 2 checkpoint addresses
2616 u32 trace_buffer
[258];
2617 int is_address
[256];
2620 if (target
->state
!= TARGET_HALTED
)
2622 LOG_WARNING("target must be stopped to read trace data");
2623 return ERROR_TARGET_NOT_HALTED
;
2626 /* send read trace buffer command (command 0x61) */
2627 xscale_send_u32(target
, 0x61);
2629 /* receive trace buffer content */
2630 xscale_receive(target
, trace_buffer
, 258);
2632 /* parse buffer backwards to identify address entries */
2633 for (i
= 255; i
>= 0; i
--)
2636 if (((trace_buffer
[i
] & 0xf0) == 0x90) ||
2637 ((trace_buffer
[i
] & 0xf0) == 0xd0))
2640 is_address
[--i
] = 1;
2642 is_address
[--i
] = 1;
2644 is_address
[--i
] = 1;
2646 is_address
[--i
] = 1;
2651 /* search first non-zero entry */
2652 for (j
= 0; (j
< 256) && (trace_buffer
[j
] == 0) && (!is_address
[j
]); j
++)
2657 LOG_DEBUG("no trace data collected");
2658 return ERROR_XSCALE_NO_TRACE_DATA
;
2661 for (trace_data_p
= &xscale
->trace
.data
; *trace_data_p
; trace_data_p
= &(*trace_data_p
)->next
)
2664 *trace_data_p
= malloc(sizeof(xscale_trace_data_t
));
2665 (*trace_data_p
)->next
= NULL
;
2666 (*trace_data_p
)->chkpt0
= trace_buffer
[256];
2667 (*trace_data_p
)->chkpt1
= trace_buffer
[257];
2668 (*trace_data_p
)->last_instruction
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
2669 (*trace_data_p
)->entries
= malloc(sizeof(xscale_trace_entry_t
) * (256 - j
));
2670 (*trace_data_p
)->depth
= 256 - j
;
2672 for (i
= j
; i
< 256; i
++)
2674 (*trace_data_p
)->entries
[i
- j
].data
= trace_buffer
[i
];
2676 (*trace_data_p
)->entries
[i
- j
].type
= XSCALE_TRACE_ADDRESS
;
2678 (*trace_data_p
)->entries
[i
- j
].type
= XSCALE_TRACE_MESSAGE
;
2684 int xscale_read_instruction(target_t
*target
, arm_instruction_t
*instruction
)
2686 /* get pointers to arch-specific information */
2687 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2688 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2695 if (!xscale
->trace
.image
)
2696 return ERROR_TRACE_IMAGE_UNAVAILABLE
;
2698 /* search for the section the current instruction belongs to */
2699 for (i
= 0; i
< xscale
->trace
.image
->num_sections
; i
++)
2701 if ((xscale
->trace
.image
->sections
[i
].base_address
<= xscale
->trace
.current_pc
) &&
2702 (xscale
->trace
.image
->sections
[i
].base_address
+ xscale
->trace
.image
->sections
[i
].size
> xscale
->trace
.current_pc
))
2711 /* current instruction couldn't be found in the image */
2712 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2715 if (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
)
2718 if ((retval
= image_read_section(xscale
->trace
.image
, section
,
2719 xscale
->trace
.current_pc
- xscale
->trace
.image
->sections
[section
].base_address
,
2720 4, buf
, &size_read
)) != ERROR_OK
)
2722 LOG_ERROR("error while reading instruction: %i", retval
);
2723 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2725 opcode
= target_buffer_get_u32(target
, buf
);
2726 arm_evaluate_opcode(opcode
, xscale
->trace
.current_pc
, instruction
);
2728 else if (xscale
->trace
.core_state
== ARMV4_5_STATE_THUMB
)
2731 if ((retval
= image_read_section(xscale
->trace
.image
, section
,
2732 xscale
->trace
.current_pc
- xscale
->trace
.image
->sections
[section
].base_address
,
2733 2, buf
, &size_read
)) != ERROR_OK
)
2735 LOG_ERROR("error while reading instruction: %i", retval
);
2736 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2738 opcode
= target_buffer_get_u16(target
, buf
);
2739 thumb_evaluate_opcode(opcode
, xscale
->trace
.current_pc
, instruction
);
2743 LOG_ERROR("BUG: unknown core state encountered");
2750 int xscale_branch_address(xscale_trace_data_t
*trace_data
, int i
, u32
*target
)
2752 /* if there are less than four entries prior to the indirect branch message
2753 * we can't extract the address */
2759 *target
= (trace_data
->entries
[i
-1].data
) | (trace_data
->entries
[i
-2].data
<< 8) |
2760 (trace_data
->entries
[i
-3].data
<< 16) | (trace_data
->entries
[i
-4].data
<< 24);
2765 int xscale_analyze_trace(target_t
*target
, command_context_t
*cmd_ctx
)
2767 /* get pointers to arch-specific information */
2768 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2769 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2772 xscale_trace_data_t
*trace_data
= xscale
->trace
.data
;
2781 xscale
->trace
.core_state
= ARMV4_5_STATE_ARM
;
2786 for (i
= 0; i
< trace_data
->depth
; i
++)
2792 if (trace_data
->entries
[i
].type
== XSCALE_TRACE_ADDRESS
)
2795 switch ((trace_data
->entries
[i
].data
& 0xf0) >> 4)
2797 case 0: /* Exceptions */
2805 exception
= (trace_data
->entries
[i
].data
& 0x70) >> 4;
2807 next_pc
= (trace_data
->entries
[i
].data
& 0xf0) >> 2;
2808 command_print(cmd_ctx
, "--- exception %i ---", (trace_data
->entries
[i
].data
& 0xf0) >> 4);
2810 case 8: /* Direct Branch */
2813 case 9: /* Indirect Branch */
2815 if (xscale_branch_address(trace_data
, i
, &next_pc
) == 0)
2820 case 13: /* Checkpointed Indirect Branch */
2821 if (xscale_branch_address(trace_data
, i
, &next_pc
) == 0)
2824 if (((chkpt
== 0) && (next_pc
!= trace_data
->chkpt0
))
2825 || ((chkpt
== 1) && (next_pc
!= trace_data
->chkpt1
)))
2826 LOG_WARNING("checkpointed indirect branch target address doesn't match checkpoint");
2828 /* explicit fall-through */
2829 case 12: /* Checkpointed Direct Branch */
2834 next_pc
= trace_data
->chkpt0
;
2837 else if (chkpt
== 1)
2840 next_pc
= trace_data
->chkpt0
;
2845 LOG_WARNING("more than two checkpointed branches encountered");
2848 case 15: /* Roll-over */
2851 default: /* Reserved */
2852 command_print(cmd_ctx
, "--- reserved trace message ---");
2853 LOG_ERROR("BUG: trace message %i is reserved", (trace_data
->entries
[i
].data
& 0xf0) >> 4);
2857 if (xscale
->trace
.pc_ok
)
2859 int executed
= (trace_data
->entries
[i
].data
& 0xf) + rollover
* 16;
2860 arm_instruction_t instruction
;
2862 if ((exception
== 6) || (exception
== 7))
2864 /* IRQ or FIQ exception, no instruction executed */
2868 while (executed
-- >= 0)
2870 if ((retval
= xscale_read_instruction(target
, &instruction
)) != ERROR_OK
)
2872 /* can't continue tracing with no image available */
2873 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
2877 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
2879 /* TODO: handle incomplete images */
2883 /* a precise abort on a load to the PC is included in the incremental
2884 * word count, other instructions causing data aborts are not included
2886 if ((executed
== 0) && (exception
== 4)
2887 && ((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_LDM
)))
2889 if ((instruction
.type
== ARM_LDM
)
2890 && ((instruction
.info
.load_store_multiple
.register_list
& 0x8000) == 0))
2894 else if (((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_LDRSH
))
2895 && (instruction
.info
.load_store
.Rd
!= 15))
2901 /* only the last instruction executed
2902 * (the one that caused the control flow change)
2903 * could be a taken branch
2905 if (((executed
== -1) && (branch
== 1)) &&
2906 (((instruction
.type
== ARM_B
) ||
2907 (instruction
.type
== ARM_BL
) ||
2908 (instruction
.type
== ARM_BLX
)) &&
2909 (instruction
.info
.b_bl_bx_blx
.target_address
!= 0xffffffff)))
2911 xscale
->trace
.current_pc
= instruction
.info
.b_bl_bx_blx
.target_address
;
2915 xscale
->trace
.current_pc
+= (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2;
2917 command_print(cmd_ctx
, "%s", instruction
.text
);
2925 xscale
->trace
.current_pc
= next_pc
;
2926 xscale
->trace
.pc_ok
= 1;
2930 for (; xscale
->trace
.current_pc
< trace_data
->last_instruction
; xscale
->trace
.current_pc
+= (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2)
2932 arm_instruction_t instruction
;
2933 if ((retval
= xscale_read_instruction(target
, &instruction
)) != ERROR_OK
)
2935 /* can't continue tracing with no image available */
2936 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
2940 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
2942 /* TODO: handle incomplete images */
2945 command_print(cmd_ctx
, "%s", instruction
.text
);
2948 trace_data
= trace_data
->next
;
2954 void xscale_build_reg_cache(target_t
*target
)
2956 /* get pointers to arch-specific information */
2957 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2958 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2960 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
2961 xscale_reg_t
*arch_info
= malloc(sizeof(xscale_reg_arch_info
));
2963 int num_regs
= sizeof(xscale_reg_arch_info
) / sizeof(xscale_reg_t
);
2965 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
2966 armv4_5
->core_cache
= (*cache_p
);
2968 /* register a register arch-type for XScale dbg registers only once */
2969 if (xscale_reg_arch_type
== -1)
2970 xscale_reg_arch_type
= register_reg_arch_type(xscale_get_reg
, xscale_set_reg
);
2972 (*cache_p
)->next
= malloc(sizeof(reg_cache_t
));
2973 cache_p
= &(*cache_p
)->next
;
2975 /* fill in values for the xscale reg cache */
2976 (*cache_p
)->name
= "XScale registers";
2977 (*cache_p
)->next
= NULL
;
2978 (*cache_p
)->reg_list
= malloc(num_regs
* sizeof(reg_t
));
2979 (*cache_p
)->num_regs
= num_regs
;
2981 for (i
= 0; i
< num_regs
; i
++)
2983 (*cache_p
)->reg_list
[i
].name
= xscale_reg_list
[i
];
2984 (*cache_p
)->reg_list
[i
].value
= calloc(4, 1);
2985 (*cache_p
)->reg_list
[i
].dirty
= 0;
2986 (*cache_p
)->reg_list
[i
].valid
= 0;
2987 (*cache_p
)->reg_list
[i
].size
= 32;
2988 (*cache_p
)->reg_list
[i
].bitfield_desc
= NULL
;
2989 (*cache_p
)->reg_list
[i
].num_bitfields
= 0;
2990 (*cache_p
)->reg_list
[i
].arch_info
= &arch_info
[i
];
2991 (*cache_p
)->reg_list
[i
].arch_type
= xscale_reg_arch_type
;
2992 arch_info
[i
] = xscale_reg_arch_info
[i
];
2993 arch_info
[i
].target
= target
;
2996 xscale
->reg_cache
= (*cache_p
);
2999 int xscale_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
3004 int xscale_quit(void)
3009 int xscale_init_arch_info(target_t
*target
, xscale_common_t
*xscale
, jtag_tap_t
*tap
, const char *variant
)
3011 armv4_5_common_t
*armv4_5
;
3012 u32 high_reset_branch
, low_reset_branch
;
3015 armv4_5
= &xscale
->armv4_5_common
;
3017 /* store architecture specfic data (none so far) */
3018 xscale
->arch_info
= NULL
;
3019 xscale
->common_magic
= XSCALE_COMMON_MAGIC
;
3021 /* remember the variant (PXA25x, PXA27x, IXP42x, ...) */
3022 xscale
->variant
= strdup(variant
);
3024 /* prepare JTAG information for the new target */
3025 xscale
->jtag_info
.tap
= tap
;
3027 xscale
->jtag_info
.dbgrx
= 0x02;
3028 xscale
->jtag_info
.dbgtx
= 0x10;
3029 xscale
->jtag_info
.dcsr
= 0x09;
3030 xscale
->jtag_info
.ldic
= 0x07;
3032 if ((strcmp(xscale
->variant
, "pxa250") == 0) ||
3033 (strcmp(xscale
->variant
, "pxa255") == 0) ||
3034 (strcmp(xscale
->variant
, "pxa26x") == 0))
3036 xscale
->jtag_info
.ir_length
= 5;
3038 else if ((strcmp(xscale
->variant
, "pxa27x") == 0) ||
3039 (strcmp(xscale
->variant
, "ixp42x") == 0) ||
3040 (strcmp(xscale
->variant
, "ixp45x") == 0) ||
3041 (strcmp(xscale
->variant
, "ixp46x") == 0))
3043 xscale
->jtag_info
.ir_length
= 7;
3046 /* the debug handler isn't installed (and thus not running) at this time */
3047 xscale
->handler_installed
= 0;
3048 xscale
->handler_running
= 0;
3049 xscale
->handler_address
= 0xfe000800;
3051 /* clear the vectors we keep locally for reference */
3052 memset(xscale
->low_vectors
, 0, sizeof(xscale
->low_vectors
));
3053 memset(xscale
->high_vectors
, 0, sizeof(xscale
->high_vectors
));
3055 /* no user-specified vectors have been configured yet */
3056 xscale
->static_low_vectors_set
= 0x0;
3057 xscale
->static_high_vectors_set
= 0x0;
3059 /* calculate branches to debug handler */
3060 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
3061 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
3063 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
3064 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
3066 for (i
= 1; i
<= 7; i
++)
3068 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
3069 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
3072 /* 64kB aligned region used for DCache cleaning */
3073 xscale
->cache_clean_address
= 0xfffe0000;
3075 xscale
->hold_rst
= 0;
3076 xscale
->external_debug_break
= 0;
3078 xscale
->ibcr_available
= 2;
3079 xscale
->ibcr0_used
= 0;
3080 xscale
->ibcr1_used
= 0;
3082 xscale
->dbr_available
= 2;
3083 xscale
->dbr0_used
= 0;
3084 xscale
->dbr1_used
= 0;
3086 xscale
->arm_bkpt
= ARMV5_BKPT(0x0);
3087 xscale
->thumb_bkpt
= ARMV5_T_BKPT(0x0) & 0xffff;
3089 xscale
->vector_catch
= 0x1;
3091 xscale
->trace
.capture_status
= TRACE_IDLE
;
3092 xscale
->trace
.data
= NULL
;
3093 xscale
->trace
.image
= NULL
;
3094 xscale
->trace
.buffer_enabled
= 0;
3095 xscale
->trace
.buffer_fill
= 0;
3097 /* prepare ARMv4/5 specific information */
3098 armv4_5
->arch_info
= xscale
;
3099 armv4_5
->read_core_reg
= xscale_read_core_reg
;
3100 armv4_5
->write_core_reg
= xscale_write_core_reg
;
3101 armv4_5
->full_context
= xscale_full_context
;
3103 armv4_5_init_arch_info(target
, armv4_5
);
3105 xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
3106 xscale
->armv4_5_mmu
.get_ttb
= xscale_get_ttb
;
3107 xscale
->armv4_5_mmu
.read_memory
= xscale_read_memory
;
3108 xscale
->armv4_5_mmu
.write_memory
= xscale_write_memory
;
3109 xscale
->armv4_5_mmu
.disable_mmu_caches
= xscale_disable_mmu_caches
;
3110 xscale
->armv4_5_mmu
.enable_mmu_caches
= xscale_enable_mmu_caches
;
3111 xscale
->armv4_5_mmu
.has_tiny_pages
= 1;
3112 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3117 /* target xscale <endianess> <startup_mode> <chain_pos> <variant> */
3118 int xscale_target_create(struct target_s
*target
, Jim_Interp
*interp
)
3120 xscale_common_t
*xscale
= calloc(1,sizeof(xscale_common_t
));
3122 xscale_init_arch_info(target
, xscale
, target
->tap
, target
->variant
);
3123 xscale_build_reg_cache(target
);
3128 int xscale_handle_debug_handler_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3130 target_t
*target
= NULL
;
3131 armv4_5_common_t
*armv4_5
;
3132 xscale_common_t
*xscale
;
3134 u32 handler_address
;
3138 LOG_ERROR("'xscale debug_handler <target#> <address>' command takes two required operands");
3142 if ((target
= get_target_by_num(strtoul(args
[0], NULL
, 0))) == NULL
)
3144 LOG_ERROR("no target '%s' configured", args
[0]);
3148 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3153 handler_address
= strtoul(args
[1], NULL
, 0);
3155 if (((handler_address
>= 0x800) && (handler_address
<= 0x1fef800)) ||
3156 ((handler_address
>= 0xfe000800) && (handler_address
<= 0xfffff800)))
3158 xscale
->handler_address
= handler_address
;
3162 LOG_ERROR("xscale debug_handler <address> must be between 0x800 and 0x1fef800 or between 0xfe000800 and 0xfffff800");
3169 int xscale_handle_cache_clean_address_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3171 target_t
*target
= NULL
;
3172 armv4_5_common_t
*armv4_5
;
3173 xscale_common_t
*xscale
;
3175 u32 cache_clean_address
;
3179 return ERROR_COMMAND_SYNTAX_ERROR
;
3182 if ((target
= get_target_by_num(strtoul(args
[0], NULL
, 0))) == NULL
)
3184 LOG_ERROR("no target '%s' configured", args
[0]);
3188 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3193 cache_clean_address
= strtoul(args
[1], NULL
, 0);
3195 if (cache_clean_address
& 0xffff)
3197 LOG_ERROR("xscale cache_clean_address <address> must be 64kb aligned");
3201 xscale
->cache_clean_address
= cache_clean_address
;
3207 int xscale_handle_cache_info_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3209 target_t
*target
= get_current_target(cmd_ctx
);
3210 armv4_5_common_t
*armv4_5
;
3211 xscale_common_t
*xscale
;
3213 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3218 return armv4_5_handle_cache_info_command(cmd_ctx
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
3221 static int xscale_virt2phys(struct target_s
*target
, u32
virtual, u32
*physical
)
3223 armv4_5_common_t
*armv4_5
;
3224 xscale_common_t
*xscale
;
3231 if ((retval
= xscale_get_arch_pointers(target
, &armv4_5
, &xscale
)) != ERROR_OK
)
3235 u32 ret
= armv4_5_mmu_translate_va(target
, &xscale
->armv4_5_mmu
, virtual, &type
, &cb
, &domain
, &ap
);
3244 static int xscale_mmu(struct target_s
*target
, int *enabled
)
3246 armv4_5_common_t
*armv4_5
= target
->arch_info
;
3247 xscale_common_t
*xscale
= armv4_5
->arch_info
;
3249 if (target
->state
!= TARGET_HALTED
)
3251 LOG_ERROR("Target not halted");
3252 return ERROR_TARGET_INVALID
;
3254 *enabled
= xscale
->armv4_5_mmu
.mmu_enabled
;
3258 int xscale_handle_mmu_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3260 target_t
*target
= get_current_target(cmd_ctx
);
3261 armv4_5_common_t
*armv4_5
;
3262 xscale_common_t
*xscale
;
3264 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3269 if (target
->state
!= TARGET_HALTED
)
3271 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3277 if (strcmp("enable", args
[0]) == 0)
3279 xscale_enable_mmu_caches(target
, 1, 0, 0);
3280 xscale
->armv4_5_mmu
.mmu_enabled
= 1;
3282 else if (strcmp("disable", args
[0]) == 0)
3284 xscale_disable_mmu_caches(target
, 1, 0, 0);
3285 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3289 command_print(cmd_ctx
, "mmu %s", (xscale
->armv4_5_mmu
.mmu_enabled
) ? "enabled" : "disabled");
3294 int xscale_handle_idcache_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3296 target_t
*target
= get_current_target(cmd_ctx
);
3297 armv4_5_common_t
*armv4_5
;
3298 xscale_common_t
*xscale
;
3299 int icache
= 0, dcache
= 0;
3301 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3306 if (target
->state
!= TARGET_HALTED
)
3308 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3312 if (strcmp(cmd
, "icache") == 0)
3314 else if (strcmp(cmd
, "dcache") == 0)
3319 if (strcmp("enable", args
[0]) == 0)
3321 xscale_enable_mmu_caches(target
, 0, dcache
, icache
);
3324 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 1;
3326 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 1;
3328 else if (strcmp("disable", args
[0]) == 0)
3330 xscale_disable_mmu_caches(target
, 0, dcache
, icache
);
3333 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 0;
3335 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 0;
3340 command_print(cmd_ctx
, "icache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
) ? "enabled" : "disabled");
3343 command_print(cmd_ctx
, "dcache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
) ? "enabled" : "disabled");
3348 int xscale_handle_vector_catch_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3350 target_t
*target
= get_current_target(cmd_ctx
);
3351 armv4_5_common_t
*armv4_5
;
3352 xscale_common_t
*xscale
;
3354 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3361 command_print(cmd_ctx
, "usage: xscale vector_catch [mask]");
3365 xscale
->vector_catch
= strtoul(args
[0], NULL
, 0);
3366 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 8, xscale
->vector_catch
);
3367 xscale_write_dcsr(target
, -1, -1);
3370 command_print(cmd_ctx
, "vector catch mask: 0x%2.2x", xscale
->vector_catch
);
3376 int xscale_handle_trace_buffer_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3378 target_t
*target
= get_current_target(cmd_ctx
);
3379 armv4_5_common_t
*armv4_5
;
3380 xscale_common_t
*xscale
;
3383 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3388 if (target
->state
!= TARGET_HALTED
)
3390 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3394 if ((argc
>= 1) && (strcmp("enable", args
[0]) == 0))
3396 xscale_trace_data_t
*td
, *next_td
;
3397 xscale
->trace
.buffer_enabled
= 1;
3399 /* free old trace data */
3400 td
= xscale
->trace
.data
;
3410 xscale
->trace
.data
= NULL
;
3412 else if ((argc
>= 1) && (strcmp("disable", args
[0]) == 0))
3414 xscale
->trace
.buffer_enabled
= 0;
3417 if ((argc
>= 2) && (strcmp("fill", args
[1]) == 0))
3420 xscale
->trace
.buffer_fill
= strtoul(args
[2], NULL
, 0);
3422 xscale
->trace
.buffer_fill
= 1;
3424 else if ((argc
>= 2) && (strcmp("wrap", args
[1]) == 0))
3426 xscale
->trace
.buffer_fill
= -1;
3429 if (xscale
->trace
.buffer_enabled
)
3431 /* if we enable the trace buffer in fill-once
3432 * mode we know the address of the first instruction */
3433 xscale
->trace
.pc_ok
= 1;
3434 xscale
->trace
.current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
3438 /* otherwise the address is unknown, and we have no known good PC */
3439 xscale
->trace
.pc_ok
= 0;
3442 command_print(cmd_ctx
, "trace buffer %s (%s)",
3443 (xscale
->trace
.buffer_enabled
) ? "enabled" : "disabled",
3444 (xscale
->trace
.buffer_fill
> 0) ? "fill" : "wrap");
3446 dcsr_value
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32);
3447 if (xscale
->trace
.buffer_fill
>= 0)
3448 xscale_write_dcsr_sw(target
, (dcsr_value
& 0xfffffffc) | 2);
3450 xscale_write_dcsr_sw(target
, dcsr_value
& 0xfffffffc);
3455 int xscale_handle_trace_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3458 armv4_5_common_t
*armv4_5
;
3459 xscale_common_t
*xscale
;
3463 command_print(cmd_ctx
, "usage: xscale trace_image <file> [base address] [type]");
3467 target
= get_current_target(cmd_ctx
);
3469 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3474 if (xscale
->trace
.image
)
3476 image_close(xscale
->trace
.image
);
3477 free(xscale
->trace
.image
);
3478 command_print(cmd_ctx
, "previously loaded image found and closed");
3481 xscale
->trace
.image
= malloc(sizeof(image_t
));
3482 xscale
->trace
.image
->base_address_set
= 0;
3483 xscale
->trace
.image
->start_address_set
= 0;
3485 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
3488 xscale
->trace
.image
->base_address_set
= 1;
3489 xscale
->trace
.image
->base_address
= strtoul(args
[1], NULL
, 0);
3493 xscale
->trace
.image
->base_address_set
= 0;
3496 if (image_open(xscale
->trace
.image
, args
[0], (argc
>= 3) ? args
[2] : NULL
) != ERROR_OK
)
3498 free(xscale
->trace
.image
);
3499 xscale
->trace
.image
= NULL
;
3506 int xscale_handle_dump_trace_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3508 target_t
*target
= get_current_target(cmd_ctx
);
3509 armv4_5_common_t
*armv4_5
;
3510 xscale_common_t
*xscale
;
3511 xscale_trace_data_t
*trace_data
;
3514 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3519 if (target
->state
!= TARGET_HALTED
)
3521 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3527 command_print(cmd_ctx
, "usage: xscale dump_trace <file>");
3531 trace_data
= xscale
->trace
.data
;
3535 command_print(cmd_ctx
, "no trace data collected");
3539 if (fileio_open(&file
, args
[0], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
)
3548 fileio_write_u32(&file
, trace_data
->chkpt0
);
3549 fileio_write_u32(&file
, trace_data
->chkpt1
);
3550 fileio_write_u32(&file
, trace_data
->last_instruction
);
3551 fileio_write_u32(&file
, trace_data
->depth
);
3553 for (i
= 0; i
< trace_data
->depth
; i
++)
3554 fileio_write_u32(&file
, trace_data
->entries
[i
].data
| ((trace_data
->entries
[i
].type
& 0xffff) << 16));
3556 trace_data
= trace_data
->next
;
3559 fileio_close(&file
);
3564 int xscale_handle_analyze_trace_buffer_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3566 target_t
*target
= get_current_target(cmd_ctx
);
3567 armv4_5_common_t
*armv4_5
;
3568 xscale_common_t
*xscale
;
3570 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3575 xscale_analyze_trace(target
, cmd_ctx
);
3580 int xscale_handle_cp15(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3582 target_t
*target
= get_current_target(cmd_ctx
);
3583 armv4_5_common_t
*armv4_5
;
3584 xscale_common_t
*xscale
;
3586 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3591 if (target
->state
!= TARGET_HALTED
)
3593 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3600 reg_no
= strtoul(args
[0], NULL
, 0);
3601 /*translate from xscale cp15 register no to openocd register*/
3605 reg_no
= XSCALE_MAINID
;
3608 reg_no
= XSCALE_CTRL
;
3611 reg_no
= XSCALE_TTB
;
3614 reg_no
= XSCALE_DAC
;
3617 reg_no
= XSCALE_FSR
;
3620 reg_no
= XSCALE_FAR
;
3623 reg_no
= XSCALE_PID
;
3626 reg_no
= XSCALE_CPACCESS
;
3629 command_print(cmd_ctx
, "invalid register number");
3630 return ERROR_INVALID_ARGUMENTS
;
3632 reg
= &xscale
->reg_cache
->reg_list
[reg_no
];
3639 /* read cp15 control register */
3640 xscale_get_reg(reg
);
3641 value
= buf_get_u32(reg
->value
, 0, 32);
3642 command_print(cmd_ctx
, "%s (/%i): 0x%x", reg
->name
, reg
->size
, value
);
3647 u32 value
= strtoul(args
[1], NULL
, 0);
3649 /* send CP write request (command 0x41) */
3650 xscale_send_u32(target
, 0x41);
3652 /* send CP register number */
3653 xscale_send_u32(target
, reg_no
);
3655 /* send CP register value */
3656 xscale_send_u32(target
, value
);
3658 /* execute cpwait to ensure outstanding operations complete */
3659 xscale_send_u32(target
, 0x53);
3663 command_print(cmd_ctx
, "usage: cp15 [register]<, [value]>");
3669 int xscale_register_commands(struct command_context_s
*cmd_ctx
)
3671 command_t
*xscale_cmd
;
3673 xscale_cmd
= register_command(cmd_ctx
, NULL
, "xscale", NULL
, COMMAND_ANY
, "xscale specific commands");
3675 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");
3676 register_command(cmd_ctx
, xscale_cmd
, "cache_clean_address", xscale_handle_cache_clean_address_command
, COMMAND_ANY
, NULL
);
3678 register_command(cmd_ctx
, xscale_cmd
, "cache_info", xscale_handle_cache_info_command
, COMMAND_EXEC
, NULL
);
3679 register_command(cmd_ctx
, xscale_cmd
, "mmu", xscale_handle_mmu_command
, COMMAND_EXEC
, "['enable'|'disable'] the MMU");
3680 register_command(cmd_ctx
, xscale_cmd
, "icache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the ICache");
3681 register_command(cmd_ctx
, xscale_cmd
, "dcache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the DCache");
3683 register_command(cmd_ctx
, xscale_cmd
, "vector_catch", xscale_handle_vector_catch_command
, COMMAND_EXEC
, "<mask> of vectors that should be catched");
3685 register_command(cmd_ctx
, xscale_cmd
, "trace_buffer", xscale_handle_trace_buffer_command
, COMMAND_EXEC
, "<enable|disable> ['fill' [n]|'wrap']");
3687 register_command(cmd_ctx
, xscale_cmd
, "dump_trace", xscale_handle_dump_trace_command
, COMMAND_EXEC
, "dump content of trace buffer to <file>");
3688 register_command(cmd_ctx
, xscale_cmd
, "analyze_trace", xscale_handle_analyze_trace_buffer_command
, COMMAND_EXEC
, "analyze content of trace buffer");
3689 register_command(cmd_ctx
, xscale_cmd
, "trace_image", xscale_handle_trace_image_command
,
3690 COMMAND_EXEC
, "load image from <file> [base address]");
3692 register_command(cmd_ctx
, xscale_cmd
, "cp15", xscale_handle_cp15
, COMMAND_EXEC
, "access coproc 15 <register> [value]");
3694 armv4_5_register_commands(cmd_ctx
);
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)