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 ***************************************************************************/
27 #include "replacements.h"
31 #include "arm7_9_common.h"
35 #include "arm_simulator.h"
36 #include "arm_disassembler.h"
39 #include "binarybuffer.h"
40 #include "time_support.h"
41 #include "breakpoints.h"
47 #include <sys/types.h>
53 int xscale_register_commands(struct command_context_s
*cmd_ctx
);
55 /* forward declarations */
56 int xscale_target_create(struct target_s
*target
, Jim_Interp
*interp
);
57 int xscale_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
);
58 int xscale_quit(void);
60 int xscale_arch_state(struct target_s
*target
);
61 int xscale_poll(target_t
*target
);
62 int xscale_halt(target_t
*target
);
63 int xscale_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
);
64 int xscale_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
);
65 int xscale_debug_entry(target_t
*target
);
66 int xscale_restore_context(target_t
*target
);
68 int xscale_assert_reset(target_t
*target
);
69 int xscale_deassert_reset(target_t
*target
);
70 int xscale_soft_reset_halt(struct target_s
*target
);
72 int xscale_set_reg_u32(reg_t
*reg
, u32 value
);
74 int xscale_read_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
);
75 int xscale_write_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
, u32 value
);
77 int xscale_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
);
78 int xscale_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
);
79 int xscale_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
);
81 int xscale_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
82 int xscale_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
83 int xscale_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
84 int xscale_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
85 int xscale_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
);
86 int xscale_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
);
87 void xscale_enable_watchpoints(struct target_s
*target
);
88 void xscale_enable_breakpoints(struct target_s
*target
);
89 static int xscale_virt2phys(struct target_s
*target
, u32
virtual, u32
*physical
);
90 static int xscale_mmu(struct target_s
*target
, int *enabled
);
92 int xscale_read_trace(target_t
*target
);
94 target_type_t xscale_target
=
99 .arch_state
= xscale_arch_state
,
101 .target_request_data
= NULL
,
104 .resume
= xscale_resume
,
107 .assert_reset
= xscale_assert_reset
,
108 .deassert_reset
= xscale_deassert_reset
,
109 .soft_reset_halt
= xscale_soft_reset_halt
,
111 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
113 .read_memory
= xscale_read_memory
,
114 .write_memory
= xscale_write_memory
,
115 .bulk_write_memory
= xscale_bulk_write_memory
,
116 .checksum_memory
= arm7_9_checksum_memory
,
117 .blank_check_memory
= arm7_9_blank_check_memory
,
119 .run_algorithm
= armv4_5_run_algorithm
,
121 .add_breakpoint
= xscale_add_breakpoint
,
122 .remove_breakpoint
= xscale_remove_breakpoint
,
123 .add_watchpoint
= xscale_add_watchpoint
,
124 .remove_watchpoint
= xscale_remove_watchpoint
,
126 .register_commands
= xscale_register_commands
,
127 .target_create
= xscale_target_create
,
128 .init_target
= xscale_init_target
,
131 .virt2phys
= xscale_virt2phys
,
135 char* xscale_reg_list
[] =
137 "XSCALE_MAINID", /* 0 */
147 "XSCALE_IBCR0", /* 10 */
157 "XSCALE_RX", /* 20 */
161 xscale_reg_t xscale_reg_arch_info
[] =
163 {XSCALE_MAINID
, NULL
},
164 {XSCALE_CACHETYPE
, NULL
},
166 {XSCALE_AUXCTRL
, NULL
},
172 {XSCALE_CPACCESS
, NULL
},
173 {XSCALE_IBCR0
, NULL
},
174 {XSCALE_IBCR1
, NULL
},
177 {XSCALE_DBCON
, NULL
},
178 {XSCALE_TBREG
, NULL
},
179 {XSCALE_CHKPT0
, NULL
},
180 {XSCALE_CHKPT1
, NULL
},
181 {XSCALE_DCSR
, NULL
}, /* DCSR accessed via JTAG or SW */
182 {-1, NULL
}, /* TX accessed via JTAG */
183 {-1, NULL
}, /* RX accessed via JTAG */
184 {-1, NULL
}, /* TXRXCTRL implicit access via JTAG */
187 int xscale_reg_arch_type
= -1;
189 int xscale_get_reg(reg_t
*reg
);
190 int xscale_set_reg(reg_t
*reg
, u8
*buf
);
192 int xscale_get_arch_pointers(target_t
*target
, armv4_5_common_t
**armv4_5_p
, xscale_common_t
**xscale_p
)
194 armv4_5_common_t
*armv4_5
= target
->arch_info
;
195 xscale_common_t
*xscale
= armv4_5
->arch_info
;
197 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
199 LOG_ERROR("target isn't an XScale target");
203 if (xscale
->common_magic
!= XSCALE_COMMON_MAGIC
)
205 LOG_ERROR("target isn't an XScale target");
209 *armv4_5_p
= armv4_5
;
215 int xscale_jtag_set_instr(jtag_tap_t
*tap
, u32 new_instr
)
220 if (buf_get_u32(tap
->cur_instr
, 0, tap
->ir_length
) != new_instr
)
225 field
.num_bits
= tap
->ir_length
;
226 field
.out_value
= calloc(CEIL(field
.num_bits
, 8), 1);
227 buf_set_u32(field
.out_value
, 0, field
.num_bits
, new_instr
);
229 field
.in_value
= NULL
;
230 jtag_set_check_value(&field
, tap
->expected
, tap
->expected_mask
, NULL
);
232 jtag_add_ir_scan(1, &field
, TAP_INVALID
);
234 free(field
.out_value
);
240 int xscale_read_dcsr(target_t
*target
)
242 armv4_5_common_t
*armv4_5
= target
->arch_info
;
243 xscale_common_t
*xscale
= armv4_5
->arch_info
;
247 scan_field_t fields
[3];
249 u8 field0_check_value
= 0x2;
250 u8 field0_check_mask
= 0x7;
252 u8 field2_check_value
= 0x0;
253 u8 field2_check_mask
= 0x1;
255 jtag_add_end_state(TAP_DRPAUSE
);
256 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dcsr
);
258 buf_set_u32(&field0
, 1, 1, xscale
->hold_rst
);
259 buf_set_u32(&field0
, 2, 1, xscale
->external_debug_break
);
261 fields
[0].tap
= xscale
->jtag_info
.tap
;
262 fields
[0].num_bits
= 3;
263 fields
[0].out_value
= &field0
;
265 fields
[0].in_value
= NULL
;
266 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
268 fields
[1].tap
= xscale
->jtag_info
.tap
;
269 fields
[1].num_bits
= 32;
270 fields
[1].out_value
= NULL
;
272 fields
[1].in_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
273 fields
[1].in_handler
= NULL
;
278 fields
[2].tap
= xscale
->jtag_info
.tap
;
279 fields
[2].num_bits
= 1;
280 fields
[2].out_value
= &field2
;
282 fields
[2].in_value
= NULL
;
283 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
285 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
287 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
289 LOG_ERROR("JTAG error while reading DCSR");
293 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].dirty
= 0;
294 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].valid
= 1;
296 /* write the register with the value we just read
297 * on this second pass, only the first bit of field0 is guaranteed to be 0)
299 field0_check_mask
= 0x1;
300 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
301 fields
[1].in_value
= NULL
;
303 jtag_add_end_state(TAP_IDLE
);
305 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
307 /* DANGER!!! this must be here. It will make sure that the arguments
308 * to jtag_set_check_value() does not go out of scope! */
309 return jtag_execute_queue();
312 int xscale_receive(target_t
*target
, u32
*buffer
, int num_words
)
315 return ERROR_INVALID_ARGUMENTS
;
318 armv4_5_common_t
*armv4_5
= target
->arch_info
;
319 xscale_common_t
*xscale
= armv4_5
->arch_info
;
322 scan_field_t fields
[3];
324 u8
*field0
= malloc(num_words
* 1);
325 u8 field0_check_value
= 0x2;
326 u8 field0_check_mask
= 0x6;
327 u32
*field1
= malloc(num_words
* 4);
328 u8 field2_check_value
= 0x0;
329 u8 field2_check_mask
= 0x1;
331 int words_scheduled
= 0;
335 path
[0] = TAP_DRSELECT
;
336 path
[1] = TAP_DRCAPTURE
;
337 path
[2] = TAP_DRSHIFT
;
339 fields
[0].tap
= xscale
->jtag_info
.tap
;
340 fields
[0].num_bits
= 3;
341 fields
[0].out_value
= NULL
;
343 fields
[0].in_value
= NULL
;
344 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
346 fields
[1].tap
= xscale
->jtag_info
.tap
;
347 fields
[1].num_bits
= 32;
348 fields
[1].out_value
= NULL
;
350 fields
[1].in_value
= NULL
;
351 fields
[1].in_handler
= NULL
;
356 fields
[2].tap
= xscale
->jtag_info
.tap
;
357 fields
[2].num_bits
= 1;
358 fields
[2].out_value
= NULL
;
360 fields
[2].in_value
= NULL
;
361 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
363 jtag_add_end_state(TAP_IDLE
);
364 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dbgtx
);
365 jtag_add_runtest(1, TAP_INVALID
); /* ensures that we're in the TAP_IDLE state as the above could be a no-op */
367 /* repeat until all words have been collected */
369 while (words_done
< num_words
)
373 for (i
= words_done
; i
< num_words
; i
++)
375 fields
[0].in_value
= &field0
[i
];
376 fields
[1].in_handler
= buf_to_u32_handler
; /* deprecated! invoke this from user code! */
377 fields
[1].in_handler_priv
= (u8
*)&field1
[i
];
379 jtag_add_pathmove(3, path
);
380 jtag_add_dr_scan(3, fields
, TAP_IDLE
);
384 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
386 LOG_ERROR("JTAG error while receiving data from debug handler");
390 /* examine results */
391 for (i
= words_done
; i
< num_words
; i
++)
393 if (!(field0
[0] & 1))
395 /* move backwards if necessary */
397 for (j
= i
; j
< num_words
- 1; j
++)
399 field0
[j
] = field0
[j
+1];
400 field1
[j
] = field1
[j
+1];
405 if (words_scheduled
==0)
407 if (attempts
++==1000)
409 LOG_ERROR("Failed to receiving data from debug handler after 1000 attempts");
410 retval
=ERROR_TARGET_TIMEOUT
;
415 words_done
+= words_scheduled
;
418 for (i
= 0; i
< num_words
; i
++)
419 *(buffer
++) = buf_get_u32((u8
*)&field1
[i
], 0, 32);
426 int xscale_read_tx(target_t
*target
, int consume
)
428 armv4_5_common_t
*armv4_5
= target
->arch_info
;
429 xscale_common_t
*xscale
= armv4_5
->arch_info
;
431 tap_state_t noconsume_path
[6];
434 struct timeval timeout
, now
;
436 scan_field_t fields
[3];
438 u8 field0_check_value
= 0x2;
439 u8 field0_check_mask
= 0x6;
440 u8 field2_check_value
= 0x0;
441 u8 field2_check_mask
= 0x1;
443 jtag_add_end_state(TAP_IDLE
);
445 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dbgtx
);
447 path
[0] = TAP_DRSELECT
;
448 path
[1] = TAP_DRCAPTURE
;
449 path
[2] = TAP_DRSHIFT
;
451 noconsume_path
[0] = TAP_DRSELECT
;
452 noconsume_path
[1] = TAP_DRCAPTURE
;
453 noconsume_path
[2] = TAP_DREXIT1
;
454 noconsume_path
[3] = TAP_DRPAUSE
;
455 noconsume_path
[4] = TAP_DREXIT2
;
456 noconsume_path
[5] = TAP_DRSHIFT
;
458 fields
[0].tap
= xscale
->jtag_info
.tap
;
459 fields
[0].num_bits
= 3;
460 fields
[0].out_value
= NULL
;
462 fields
[0].in_value
= &field0_in
;
463 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
465 fields
[1].tap
= xscale
->jtag_info
.tap
;
466 fields
[1].num_bits
= 32;
467 fields
[1].out_value
= NULL
;
469 fields
[1].in_value
= xscale
->reg_cache
->reg_list
[XSCALE_TX
].value
;
470 fields
[1].in_handler
= NULL
;
475 fields
[2].tap
= xscale
->jtag_info
.tap
;
476 fields
[2].num_bits
= 1;
477 fields
[2].out_value
= NULL
;
479 fields
[2].in_value
= NULL
;
480 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
482 gettimeofday(&timeout
, NULL
);
483 timeval_add_time(&timeout
, 1, 0);
487 /* if we want to consume the register content (i.e. clear TX_READY),
488 * we have to go straight from Capture-DR to Shift-DR
489 * otherwise, we go from Capture-DR to Exit1-DR to Pause-DR
492 jtag_add_pathmove(3, path
);
495 jtag_add_pathmove(sizeof(noconsume_path
)/sizeof(*noconsume_path
), noconsume_path
);
498 jtag_add_dr_scan(3, fields
, TAP_IDLE
);
500 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
502 LOG_ERROR("JTAG error while reading TX");
503 return ERROR_TARGET_TIMEOUT
;
506 gettimeofday(&now
, NULL
);
507 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
)&& (now
.tv_usec
> timeout
.tv_usec
)))
509 LOG_ERROR("time out reading TX register");
510 return ERROR_TARGET_TIMEOUT
;
512 if (!((!(field0_in
& 1)) && consume
))
518 LOG_DEBUG("waiting 100ms");
519 alive_sleep(100); /* avoid flooding the logs */
527 if (!(field0_in
& 1))
528 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
533 int xscale_write_rx(target_t
*target
)
535 armv4_5_common_t
*armv4_5
= target
->arch_info
;
536 xscale_common_t
*xscale
= armv4_5
->arch_info
;
539 struct timeval timeout
, now
;
541 scan_field_t fields
[3];
544 u8 field0_check_value
= 0x2;
545 u8 field0_check_mask
= 0x6;
547 u8 field2_check_value
= 0x0;
548 u8 field2_check_mask
= 0x1;
550 jtag_add_end_state(TAP_IDLE
);
552 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dbgrx
);
554 fields
[0].tap
= xscale
->jtag_info
.tap
;
555 fields
[0].num_bits
= 3;
556 fields
[0].out_value
= &field0_out
;
558 fields
[0].in_value
= &field0_in
;
559 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
561 fields
[1].tap
= xscale
->jtag_info
.tap
;
562 fields
[1].num_bits
= 32;
563 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
;
565 fields
[1].in_value
= NULL
;
566 fields
[1].in_handler
= NULL
;
571 fields
[2].tap
= xscale
->jtag_info
.tap
;
572 fields
[2].num_bits
= 1;
573 fields
[2].out_value
= &field2
;
575 fields
[2].in_value
= NULL
;
576 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
578 gettimeofday(&timeout
, NULL
);
579 timeval_add_time(&timeout
, 1, 0);
581 /* poll until rx_read is low */
582 LOG_DEBUG("polling RX");
585 jtag_add_dr_scan(3, fields
, TAP_IDLE
);
587 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
589 LOG_ERROR("JTAG error while writing RX");
593 gettimeofday(&now
, NULL
);
594 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
)&& (now
.tv_usec
> timeout
.tv_usec
)))
596 LOG_ERROR("time out writing RX register");
597 return ERROR_TARGET_TIMEOUT
;
599 if (!(field0_in
& 1))
603 LOG_DEBUG("waiting 100ms");
604 alive_sleep(100); /* avoid flooding the logs */
614 jtag_add_dr_scan(3, fields
, TAP_IDLE
);
616 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
618 LOG_ERROR("JTAG error while writing RX");
625 /* send count elements of size byte to the debug handler */
626 int xscale_send(target_t
*target
, u8
*buffer
, int count
, int size
)
628 armv4_5_common_t
*armv4_5
= target
->arch_info
;
629 xscale_common_t
*xscale
= armv4_5
->arch_info
;
637 jtag_add_end_state(TAP_IDLE
);
639 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dbgrx
);
646 int endianness
= target
->endianness
;
647 while (done_count
++ < count
)
652 if (endianness
== TARGET_LITTLE_ENDIAN
)
654 t
[1]=le_to_h_u32(buffer
);
657 t
[1]=be_to_h_u32(buffer
);
661 if (endianness
== TARGET_LITTLE_ENDIAN
)
663 t
[1]=le_to_h_u16(buffer
);
666 t
[1]=be_to_h_u16(buffer
);
673 LOG_ERROR("BUG: size neither 4, 2 nor 1");
676 jtag_add_dr_out(xscale
->jtag_info
.tap
,
684 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
686 LOG_ERROR("JTAG error while sending data to debug handler");
693 int xscale_send_u32(target_t
*target
, u32 value
)
695 armv4_5_common_t
*armv4_5
= target
->arch_info
;
696 xscale_common_t
*xscale
= armv4_5
->arch_info
;
698 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
699 return xscale_write_rx(target
);
702 int xscale_write_dcsr(target_t
*target
, int hold_rst
, int ext_dbg_brk
)
704 armv4_5_common_t
*armv4_5
= target
->arch_info
;
705 xscale_common_t
*xscale
= armv4_5
->arch_info
;
709 scan_field_t fields
[3];
711 u8 field0_check_value
= 0x2;
712 u8 field0_check_mask
= 0x7;
714 u8 field2_check_value
= 0x0;
715 u8 field2_check_mask
= 0x1;
718 xscale
->hold_rst
= hold_rst
;
720 if (ext_dbg_brk
!= -1)
721 xscale
->external_debug_break
= ext_dbg_brk
;
723 jtag_add_end_state(TAP_IDLE
);
724 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dcsr
);
726 buf_set_u32(&field0
, 1, 1, xscale
->hold_rst
);
727 buf_set_u32(&field0
, 2, 1, xscale
->external_debug_break
);
729 fields
[0].tap
= xscale
->jtag_info
.tap
;
730 fields
[0].num_bits
= 3;
731 fields
[0].out_value
= &field0
;
733 fields
[0].in_value
= NULL
;
734 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
736 fields
[1].tap
= xscale
->jtag_info
.tap
;
737 fields
[1].num_bits
= 32;
738 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
740 fields
[1].in_value
= NULL
;
741 fields
[1].in_handler
= NULL
;
746 fields
[2].tap
= xscale
->jtag_info
.tap
;
747 fields
[2].num_bits
= 1;
748 fields
[2].out_value
= &field2
;
750 fields
[2].in_value
= NULL
;
751 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
753 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
755 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
757 LOG_ERROR("JTAG error while writing DCSR");
761 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].dirty
= 0;
762 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].valid
= 1;
767 /* parity of the number of bits 0 if even; 1 if odd. for 32 bit words */
768 unsigned int parity (unsigned int v
)
775 LOG_DEBUG("parity of 0x%x is %i", ov
, (0x6996 >> v
) & 1);
776 return (0x6996 >> v
) & 1;
779 int xscale_load_ic(target_t
*target
, int mini
, u32 va
, u32 buffer
[8])
781 armv4_5_common_t
*armv4_5
= target
->arch_info
;
782 xscale_common_t
*xscale
= armv4_5
->arch_info
;
787 scan_field_t fields
[2];
789 LOG_DEBUG("loading miniIC at 0x%8.8x", va
);
791 jtag_add_end_state(TAP_IDLE
);
792 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.ldic
); /* LDIC */
794 /* CMD is b010 for Main IC and b011 for Mini IC */
796 buf_set_u32(&cmd
, 0, 3, 0x3);
798 buf_set_u32(&cmd
, 0, 3, 0x2);
800 buf_set_u32(&cmd
, 3, 3, 0x0);
802 /* virtual address of desired cache line */
803 buf_set_u32(packet
, 0, 27, va
>> 5);
805 fields
[0].tap
= xscale
->jtag_info
.tap
;
806 fields
[0].num_bits
= 6;
807 fields
[0].out_value
= &cmd
;
809 fields
[0].in_value
= NULL
;
812 fields
[0].in_handler
= NULL
;
815 fields
[1].tap
= xscale
->jtag_info
.tap
;
816 fields
[1].num_bits
= 27;
817 fields
[1].out_value
= packet
;
819 fields
[1].in_value
= NULL
;
822 fields
[1].in_handler
= NULL
;
825 jtag_add_dr_scan(2, fields
, TAP_INVALID
);
827 fields
[0].num_bits
= 32;
828 fields
[0].out_value
= packet
;
830 fields
[1].num_bits
= 1;
831 fields
[1].out_value
= &cmd
;
833 for (word
= 0; word
< 8; word
++)
835 buf_set_u32(packet
, 0, 32, buffer
[word
]);
838 memcpy(&value
, packet
, sizeof(u32
));
841 jtag_add_dr_scan(2, fields
, TAP_INVALID
);
844 jtag_execute_queue();
849 int xscale_invalidate_ic_line(target_t
*target
, u32 va
)
851 armv4_5_common_t
*armv4_5
= target
->arch_info
;
852 xscale_common_t
*xscale
= armv4_5
->arch_info
;
856 scan_field_t fields
[2];
858 jtag_add_end_state(TAP_IDLE
);
859 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.ldic
); /* LDIC */
861 /* CMD for invalidate IC line b000, bits [6:4] b000 */
862 buf_set_u32(&cmd
, 0, 6, 0x0);
864 /* virtual address of desired cache line */
865 buf_set_u32(packet
, 0, 27, va
>> 5);
867 fields
[0].tap
= xscale
->jtag_info
.tap
;
868 fields
[0].num_bits
= 6;
869 fields
[0].out_value
= &cmd
;
871 fields
[0].in_value
= NULL
;
874 fields
[0].in_handler
= NULL
;
877 fields
[1].tap
= xscale
->jtag_info
.tap
;
878 fields
[1].num_bits
= 27;
879 fields
[1].out_value
= packet
;
881 fields
[1].in_value
= NULL
;
884 fields
[1].in_handler
= NULL
;
887 jtag_add_dr_scan(2, fields
, TAP_INVALID
);
892 int xscale_update_vectors(target_t
*target
)
894 armv4_5_common_t
*armv4_5
= target
->arch_info
;
895 xscale_common_t
*xscale
= armv4_5
->arch_info
;
899 u32 low_reset_branch
, high_reset_branch
;
901 for (i
= 1; i
< 8; i
++)
903 /* if there's a static vector specified for this exception, override */
904 if (xscale
->static_high_vectors_set
& (1 << i
))
906 xscale
->high_vectors
[i
] = xscale
->static_high_vectors
[i
];
910 retval
=target_read_u32(target
, 0xffff0000 + 4*i
, &xscale
->high_vectors
[i
]);
911 if (retval
== ERROR_TARGET_TIMEOUT
)
913 if (retval
!=ERROR_OK
)
915 /* Some of these reads will fail as part of normal execution */
916 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
921 for (i
= 1; i
< 8; i
++)
923 if (xscale
->static_low_vectors_set
& (1 << i
))
925 xscale
->low_vectors
[i
] = xscale
->static_low_vectors
[i
];
929 retval
=target_read_u32(target
, 0x0 + 4*i
, &xscale
->low_vectors
[i
]);
930 if (retval
== ERROR_TARGET_TIMEOUT
)
932 if (retval
!=ERROR_OK
)
934 /* Some of these reads will fail as part of normal execution */
935 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
940 /* calculate branches to debug handler */
941 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
942 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
944 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
945 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
947 /* invalidate and load exception vectors in mini i-cache */
948 xscale_invalidate_ic_line(target
, 0x0);
949 xscale_invalidate_ic_line(target
, 0xffff0000);
951 xscale_load_ic(target
, 1, 0x0, xscale
->low_vectors
);
952 xscale_load_ic(target
, 1, 0xffff0000, xscale
->high_vectors
);
957 int xscale_arch_state(struct target_s
*target
)
959 armv4_5_common_t
*armv4_5
= target
->arch_info
;
960 xscale_common_t
*xscale
= armv4_5
->arch_info
;
964 "disabled", "enabled"
967 char *arch_dbg_reason
[] =
969 "", "\n(processor reset)", "\n(trace buffer full)"
972 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
974 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
978 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
979 "cpsr: 0x%8.8x pc: 0x%8.8x\n"
980 "MMU: %s, D-Cache: %s, I-Cache: %s"
982 armv4_5_state_strings
[armv4_5
->core_state
],
983 Jim_Nvp_value2name_simple( nvp_target_debug_reason
, target
->debug_reason
)->name
,
984 armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)],
985 buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32),
986 buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32),
987 state
[xscale
->armv4_5_mmu
.mmu_enabled
],
988 state
[xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
],
989 state
[xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
],
990 arch_dbg_reason
[xscale
->arch_debug_reason
]);
995 int xscale_poll(target_t
*target
)
998 armv4_5_common_t
*armv4_5
= target
->arch_info
;
999 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1001 if ((target
->state
== TARGET_RUNNING
) || (target
->state
== TARGET_DEBUG_RUNNING
))
1003 enum target_state previous_state
= target
->state
;
1004 if ((retval
= xscale_read_tx(target
, 0)) == ERROR_OK
)
1007 /* there's data to read from the tx register, we entered debug state */
1008 xscale
->handler_running
= 1;
1010 target
->state
= TARGET_HALTED
;
1012 /* process debug entry, fetching current mode regs */
1013 retval
= xscale_debug_entry(target
);
1015 else if (retval
!= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
1017 LOG_USER("error while polling TX register, reset CPU");
1018 /* here we "lie" so GDB won't get stuck and a reset can be perfomed */
1019 target
->state
= TARGET_HALTED
;
1022 /* debug_entry could have overwritten target state (i.e. immediate resume)
1023 * don't signal event handlers in that case
1025 if (target
->state
!= TARGET_HALTED
)
1028 /* if target was running, signal that we halted
1029 * otherwise we reentered from debug execution */
1030 if (previous_state
== TARGET_RUNNING
)
1031 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1033 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
1039 int xscale_debug_entry(target_t
*target
)
1041 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1042 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1050 /* clear external dbg break (will be written on next DCSR read) */
1051 xscale
->external_debug_break
= 0;
1052 if ((retval
=xscale_read_dcsr(target
))!=ERROR_OK
)
1055 /* get r0, pc, r1 to r7 and cpsr */
1056 if ((retval
=xscale_receive(target
, buffer
, 10))!=ERROR_OK
)
1059 /* move r0 from buffer to register cache */
1060 buf_set_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32, buffer
[0]);
1061 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
1062 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
1063 LOG_DEBUG("r0: 0x%8.8x", buffer
[0]);
1065 /* move pc from buffer to register cache */
1066 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, buffer
[1]);
1067 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
1068 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
1069 LOG_DEBUG("pc: 0x%8.8x", buffer
[1]);
1071 /* move data from buffer to register cache */
1072 for (i
= 1; i
<= 7; i
++)
1074 buf_set_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32, buffer
[1 + i
]);
1075 armv4_5
->core_cache
->reg_list
[i
].dirty
= 1;
1076 armv4_5
->core_cache
->reg_list
[i
].valid
= 1;
1077 LOG_DEBUG("r%i: 0x%8.8x", i
, buffer
[i
+ 1]);
1080 buf_set_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32, buffer
[9]);
1081 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].dirty
= 1;
1082 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].valid
= 1;
1083 LOG_DEBUG("cpsr: 0x%8.8x", buffer
[9]);
1085 armv4_5
->core_mode
= buffer
[9] & 0x1f;
1086 if (armv4_5_mode_to_number(armv4_5
->core_mode
) == -1)
1088 target
->state
= TARGET_UNKNOWN
;
1089 LOG_ERROR("cpsr contains invalid mode value - communication failure");
1090 return ERROR_TARGET_FAILURE
;
1092 LOG_DEBUG("target entered debug state in %s mode", armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)]);
1094 if (buffer
[9] & 0x20)
1095 armv4_5
->core_state
= ARMV4_5_STATE_THUMB
;
1097 armv4_5
->core_state
= ARMV4_5_STATE_ARM
;
1100 if (armv4_5_mode_to_number(armv4_5
->core_mode
)==-1)
1103 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1104 if ((armv4_5
->core_mode
!= ARMV4_5_MODE_USR
) && (armv4_5
->core_mode
!= ARMV4_5_MODE_SYS
))
1106 xscale_receive(target
, buffer
, 8);
1107 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1108 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
1109 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
1113 /* r8 to r14, but no spsr */
1114 xscale_receive(target
, buffer
, 7);
1117 /* move data from buffer to register cache */
1118 for (i
= 8; i
<= 14; i
++)
1120 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).value
, 0, 32, buffer
[i
- 8]);
1121 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).dirty
= 0;
1122 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).valid
= 1;
1125 /* examine debug reason */
1126 xscale_read_dcsr(target
);
1127 moe
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 2, 3);
1129 /* stored PC (for calculating fixup) */
1130 pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1134 case 0x0: /* Processor reset */
1135 target
->debug_reason
= DBG_REASON_DBGRQ
;
1136 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_RESET
;
1139 case 0x1: /* Instruction breakpoint hit */
1140 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1141 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1144 case 0x2: /* Data breakpoint hit */
1145 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
1146 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1149 case 0x3: /* BKPT instruction executed */
1150 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1151 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1154 case 0x4: /* Ext. debug event */
1155 target
->debug_reason
= DBG_REASON_DBGRQ
;
1156 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1159 case 0x5: /* Vector trap occured */
1160 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1161 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1164 case 0x6: /* Trace buffer full break */
1165 target
->debug_reason
= DBG_REASON_DBGRQ
;
1166 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_TB_FULL
;
1169 case 0x7: /* Reserved */
1171 LOG_ERROR("Method of Entry is 'Reserved'");
1176 /* apply PC fixup */
1177 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, pc
);
1179 /* on the first debug entry, identify cache type */
1180 if (xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
1184 /* read cp15 cache type register */
1185 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
]);
1186 cache_type_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
].value
, 0, 32);
1188 armv4_5_identify_cache(cache_type_reg
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
1191 /* examine MMU and Cache settings */
1192 /* read cp15 control register */
1193 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
1194 xscale
->cp15_control_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
1195 xscale
->armv4_5_mmu
.mmu_enabled
= (xscale
->cp15_control_reg
& 0x1U
) ? 1 : 0;
1196 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= (xscale
->cp15_control_reg
& 0x4U
) ? 1 : 0;
1197 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= (xscale
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
1199 /* tracing enabled, read collected trace data */
1200 if (xscale
->trace
.buffer_enabled
)
1202 xscale_read_trace(target
);
1203 xscale
->trace
.buffer_fill
--;
1205 /* resume if we're still collecting trace data */
1206 if ((xscale
->arch_debug_reason
== XSCALE_DBG_REASON_TB_FULL
)
1207 && (xscale
->trace
.buffer_fill
> 0))
1209 xscale_resume(target
, 1, 0x0, 1, 0);
1213 xscale
->trace
.buffer_enabled
= 0;
1220 int xscale_halt(target_t
*target
)
1222 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1223 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1225 LOG_DEBUG("target->state: %s",
1226 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
1228 if (target
->state
== TARGET_HALTED
)
1230 LOG_DEBUG("target was already halted");
1233 else if (target
->state
== TARGET_UNKNOWN
)
1235 /* this must not happen for a xscale target */
1236 LOG_ERROR("target was in unknown state when halt was requested");
1237 return ERROR_TARGET_INVALID
;
1239 else if (target
->state
== TARGET_RESET
)
1241 LOG_DEBUG("target->state == TARGET_RESET");
1245 /* assert external dbg break */
1246 xscale
->external_debug_break
= 1;
1247 xscale_read_dcsr(target
);
1249 target
->debug_reason
= DBG_REASON_DBGRQ
;
1255 int xscale_enable_single_step(struct target_s
*target
, u32 next_pc
)
1257 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1258 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1259 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1262 if (xscale
->ibcr0_used
)
1264 breakpoint_t
*ibcr0_bp
= breakpoint_find(target
, buf_get_u32(ibcr0
->value
, 0, 32) & 0xfffffffe);
1268 xscale_unset_breakpoint(target
, ibcr0_bp
);
1272 LOG_ERROR("BUG: xscale->ibcr0_used is set, but no breakpoint with that address found");
1277 if ((retval
=xscale_set_reg_u32(ibcr0
, next_pc
| 0x1))!=ERROR_OK
)
1283 int xscale_disable_single_step(struct target_s
*target
)
1285 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1286 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1287 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1290 if ((retval
=xscale_set_reg_u32(ibcr0
, 0x0))!=ERROR_OK
)
1296 int xscale_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
1298 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1299 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1300 breakpoint_t
*breakpoint
= target
->breakpoints
;
1309 if (target
->state
!= TARGET_HALTED
)
1311 LOG_WARNING("target not halted");
1312 return ERROR_TARGET_NOT_HALTED
;
1315 if (!debug_execution
)
1317 target_free_all_working_areas(target
);
1320 /* update vector tables */
1321 if ((retval
=xscale_update_vectors(target
))!=ERROR_OK
)
1324 /* current = 1: continue on current pc, otherwise continue at <address> */
1326 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1328 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1330 /* if we're at the reset vector, we have to simulate the branch */
1331 if (current_pc
== 0x0)
1333 arm_simulate_step(target
, NULL
);
1334 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1337 /* the front-end may request us not to handle breakpoints */
1338 if (handle_breakpoints
)
1340 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1344 /* there's a breakpoint at the current PC, we have to step over it */
1345 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
1346 xscale_unset_breakpoint(target
, breakpoint
);
1348 /* calculate PC of next instruction */
1349 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1352 target_read_u32(target
, current_pc
, ¤t_opcode
);
1353 LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode
);
1356 LOG_DEBUG("enable single-step");
1357 xscale_enable_single_step(target
, next_pc
);
1359 /* restore banked registers */
1360 xscale_restore_context(target
);
1362 /* send resume request (command 0x30 or 0x31)
1363 * clean the trace buffer if it is to be enabled (0x62) */
1364 if (xscale
->trace
.buffer_enabled
)
1366 xscale_send_u32(target
, 0x62);
1367 xscale_send_u32(target
, 0x31);
1370 xscale_send_u32(target
, 0x30);
1373 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1374 LOG_DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1376 for (i
= 7; i
>= 0; i
--)
1379 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1380 LOG_DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1384 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1385 LOG_DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1387 /* wait for and process debug entry */
1388 xscale_debug_entry(target
);
1390 LOG_DEBUG("disable single-step");
1391 xscale_disable_single_step(target
);
1393 LOG_DEBUG("set breakpoint at 0x%8.8x", breakpoint
->address
);
1394 xscale_set_breakpoint(target
, breakpoint
);
1398 /* enable any pending breakpoints and watchpoints */
1399 xscale_enable_breakpoints(target
);
1400 xscale_enable_watchpoints(target
);
1402 /* restore banked registers */
1403 xscale_restore_context(target
);
1405 /* send resume request (command 0x30 or 0x31)
1406 * clean the trace buffer if it is to be enabled (0x62) */
1407 if (xscale
->trace
.buffer_enabled
)
1409 xscale_send_u32(target
, 0x62);
1410 xscale_send_u32(target
, 0x31);
1413 xscale_send_u32(target
, 0x30);
1416 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1417 LOG_DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1419 for (i
= 7; i
>= 0; i
--)
1422 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1423 LOG_DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1427 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1428 LOG_DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1430 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1432 if (!debug_execution
)
1434 /* registers are now invalid */
1435 armv4_5_invalidate_core_regs(target
);
1436 target
->state
= TARGET_RUNNING
;
1437 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1441 target
->state
= TARGET_DEBUG_RUNNING
;
1442 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1445 LOG_DEBUG("target resumed");
1447 xscale
->handler_running
= 1;
1452 static int xscale_step_inner(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
1454 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1455 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1461 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1463 /* calculate PC of next instruction */
1464 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1466 u32 current_opcode
, current_pc
;
1467 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1469 target_read_u32(target
, current_pc
, ¤t_opcode
);
1470 LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode
);
1474 LOG_DEBUG("enable single-step");
1475 if ((retval
=xscale_enable_single_step(target
, next_pc
))!=ERROR_OK
)
1478 /* restore banked registers */
1479 if ((retval
=xscale_restore_context(target
))!=ERROR_OK
)
1482 /* send resume request (command 0x30 or 0x31)
1483 * clean the trace buffer if it is to be enabled (0x62) */
1484 if (xscale
->trace
.buffer_enabled
)
1486 if ((retval
=xscale_send_u32(target
, 0x62))!=ERROR_OK
)
1488 if ((retval
=xscale_send_u32(target
, 0x31))!=ERROR_OK
)
1492 if ((retval
=xscale_send_u32(target
, 0x30))!=ERROR_OK
)
1496 if ((retval
=xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32)))!=ERROR_OK
)
1498 LOG_DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1500 for (i
= 7; i
>= 0; i
--)
1503 if ((retval
=xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32)))!=ERROR_OK
)
1505 LOG_DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1509 if ((retval
=xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32)))!=ERROR_OK
)
1511 LOG_DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1513 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1515 /* registers are now invalid */
1516 if ((retval
=armv4_5_invalidate_core_regs(target
))!=ERROR_OK
)
1519 /* wait for and process debug entry */
1520 if ((retval
=xscale_debug_entry(target
))!=ERROR_OK
)
1523 LOG_DEBUG("disable single-step");
1524 if ((retval
=xscale_disable_single_step(target
))!=ERROR_OK
)
1527 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1532 int xscale_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
1534 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1535 breakpoint_t
*breakpoint
= target
->breakpoints
;
1540 if (target
->state
!= TARGET_HALTED
)
1542 LOG_WARNING("target not halted");
1543 return ERROR_TARGET_NOT_HALTED
;
1546 /* current = 1: continue on current pc, otherwise continue at <address> */
1548 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1550 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1552 /* if we're at the reset vector, we have to simulate the step */
1553 if (current_pc
== 0x0)
1555 if ((retval
=arm_simulate_step(target
, NULL
))!=ERROR_OK
)
1557 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1559 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1560 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1565 /* the front-end may request us not to handle breakpoints */
1566 if (handle_breakpoints
)
1567 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1569 if ((retval
=xscale_unset_breakpoint(target
, breakpoint
))!=ERROR_OK
)
1573 retval
= xscale_step_inner(target
, current
, address
, handle_breakpoints
);
1577 xscale_set_breakpoint(target
, breakpoint
);
1580 LOG_DEBUG("target stepped");
1586 int xscale_assert_reset(target_t
*target
)
1588 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1589 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1591 LOG_DEBUG("target->state: %s",
1592 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
1594 /* select DCSR instruction (set endstate to R-T-I to ensure we don't
1595 * end up in T-L-R, which would reset JTAG
1597 jtag_add_end_state(TAP_IDLE
);
1598 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dcsr
);
1600 /* set Hold reset, Halt mode and Trap Reset */
1601 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1602 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1603 xscale_write_dcsr(target
, 1, 0);
1605 /* select BYPASS, because having DCSR selected caused problems on the PXA27x */
1606 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, 0x7f);
1607 jtag_execute_queue();
1610 jtag_add_reset(0, 1);
1612 /* sleep 1ms, to be sure we fulfill any requirements */
1613 jtag_add_sleep(1000);
1614 jtag_execute_queue();
1616 target
->state
= TARGET_RESET
;
1618 if (target
->reset_halt
)
1621 if ((retval
= target_halt(target
))!=ERROR_OK
)
1628 int xscale_deassert_reset(target_t
*target
)
1630 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1631 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1633 fileio_t debug_handler
;
1641 breakpoint_t
*breakpoint
= target
->breakpoints
;
1645 xscale
->ibcr_available
= 2;
1646 xscale
->ibcr0_used
= 0;
1647 xscale
->ibcr1_used
= 0;
1649 xscale
->dbr_available
= 2;
1650 xscale
->dbr0_used
= 0;
1651 xscale
->dbr1_used
= 0;
1653 /* mark all hardware breakpoints as unset */
1656 if (breakpoint
->type
== BKPT_HARD
)
1658 breakpoint
->set
= 0;
1660 breakpoint
= breakpoint
->next
;
1663 if (!xscale
->handler_installed
)
1666 jtag_add_reset(0, 0);
1668 /* wait 300ms; 150 and 100ms were not enough */
1669 jtag_add_sleep(300*1000);
1671 jtag_add_runtest(2030, TAP_IDLE
);
1672 jtag_execute_queue();
1674 /* set Hold reset, Halt mode and Trap Reset */
1675 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1676 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1677 xscale_write_dcsr(target
, 1, 0);
1679 /* Load debug handler */
1680 if (fileio_open(&debug_handler
, "xscale/debug_handler.bin", FILEIO_READ
, FILEIO_BINARY
) != ERROR_OK
)
1685 if ((binary_size
= debug_handler
.size
) % 4)
1687 LOG_ERROR("debug_handler.bin: size not a multiple of 4");
1691 if (binary_size
> 0x800)
1693 LOG_ERROR("debug_handler.bin: larger than 2kb");
1697 binary_size
= CEIL(binary_size
, 32) * 32;
1699 address
= xscale
->handler_address
;
1700 while (binary_size
> 0)
1705 if ((retval
= fileio_read(&debug_handler
, 32, buffer
, &buf_cnt
)) != ERROR_OK
)
1710 for (i
= 0; i
< buf_cnt
; i
+= 4)
1712 /* convert LE buffer to host-endian u32 */
1713 cache_line
[i
/ 4] = le_to_h_u32(&buffer
[i
]);
1716 for (; buf_cnt
< 32; buf_cnt
+= 4)
1718 cache_line
[buf_cnt
/ 4] = 0xe1a08008;
1721 /* only load addresses other than the reset vectors */
1722 if ((address
% 0x400) != 0x0)
1724 xscale_load_ic(target
, 1, address
, cache_line
);
1728 binary_size
-= buf_cnt
;
1731 xscale_load_ic(target
, 1, 0x0, xscale
->low_vectors
);
1732 xscale_load_ic(target
, 1, 0xffff0000, xscale
->high_vectors
);
1734 jtag_add_runtest(30, TAP_IDLE
);
1736 jtag_add_sleep(100000);
1738 /* set Hold reset, Halt mode and Trap Reset */
1739 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1740 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1741 xscale_write_dcsr(target
, 1, 0);
1743 /* clear Hold reset to let the target run (should enter debug handler) */
1744 xscale_write_dcsr(target
, 0, 1);
1745 target
->state
= TARGET_RUNNING
;
1747 if (!target
->reset_halt
)
1749 jtag_add_sleep(10000);
1751 /* we should have entered debug now */
1752 xscale_debug_entry(target
);
1753 target
->state
= TARGET_HALTED
;
1755 /* resume the target */
1756 xscale_resume(target
, 1, 0x0, 1, 0);
1759 fileio_close(&debug_handler
);
1763 jtag_add_reset(0, 0);
1769 int xscale_soft_reset_halt(struct target_s
*target
)
1774 int xscale_read_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
)
1779 int xscale_write_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
, u32 value
)
1785 int xscale_full_context(target_t
*target
)
1787 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1795 if (target
->state
!= TARGET_HALTED
)
1797 LOG_WARNING("target not halted");
1798 return ERROR_TARGET_NOT_HALTED
;
1801 buffer
= malloc(4 * 8);
1803 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1804 * we can't enter User mode on an XScale (unpredictable),
1805 * but User shares registers with SYS
1807 for(i
= 1; i
< 7; i
++)
1811 /* check if there are invalid registers in the current mode
1813 for (j
= 0; j
<= 16; j
++)
1815 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
== 0)
1823 /* request banked registers */
1824 xscale_send_u32(target
, 0x0);
1827 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1828 tmp_cpsr
|= 0xc0; /* I/F bits */
1830 /* send CPSR for desired mode */
1831 xscale_send_u32(target
, tmp_cpsr
);
1833 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1834 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1836 xscale_receive(target
, buffer
, 8);
1837 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1838 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1839 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).valid
= 1;
1843 xscale_receive(target
, buffer
, 7);
1846 /* move data from buffer to register cache */
1847 for (j
= 8; j
<= 14; j
++)
1849 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]);
1850 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1851 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
= 1;
1861 int xscale_restore_context(target_t
*target
)
1863 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1869 if (target
->state
!= TARGET_HALTED
)
1871 LOG_WARNING("target not halted");
1872 return ERROR_TARGET_NOT_HALTED
;
1875 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1876 * we can't enter User mode on an XScale (unpredictable),
1877 * but User shares registers with SYS
1879 for(i
= 1; i
< 7; i
++)
1883 /* check if there are invalid registers in the current mode
1885 for (j
= 8; j
<= 14; j
++)
1887 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
== 1)
1891 /* if not USR/SYS, check if the SPSR needs to be written */
1892 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1894 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
== 1)
1902 /* send banked registers */
1903 xscale_send_u32(target
, 0x1);
1906 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1907 tmp_cpsr
|= 0xc0; /* I/F bits */
1909 /* send CPSR for desired mode */
1910 xscale_send_u32(target
, tmp_cpsr
);
1912 /* send banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1913 for (j
= 8; j
<= 14; j
++)
1915 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, j
).value
, 0, 32));
1916 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1919 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1921 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32));
1922 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1930 int xscale_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1932 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1933 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1938 LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address
, size
, count
);
1940 if (target
->state
!= TARGET_HALTED
)
1942 LOG_WARNING("target not halted");
1943 return ERROR_TARGET_NOT_HALTED
;
1946 /* sanitize arguments */
1947 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1948 return ERROR_INVALID_ARGUMENTS
;
1950 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1951 return ERROR_TARGET_UNALIGNED_ACCESS
;
1953 /* send memory read request (command 0x1n, n: access size) */
1954 if ((retval
=xscale_send_u32(target
, 0x10 | size
))!=ERROR_OK
)
1957 /* send base address for read request */
1958 if ((retval
=xscale_send_u32(target
, address
))!=ERROR_OK
)
1961 /* send number of requested data words */
1962 if ((retval
=xscale_send_u32(target
, count
))!=ERROR_OK
)
1965 /* receive data from target (count times 32-bit words in host endianness) */
1966 buf32
= malloc(4 * count
);
1967 if ((retval
=xscale_receive(target
, buf32
, count
))!=ERROR_OK
)
1970 /* extract data from host-endian buffer into byte stream */
1971 for (i
= 0; i
< count
; i
++)
1976 target_buffer_set_u32(target
, buffer
, buf32
[i
]);
1980 target_buffer_set_u16(target
, buffer
, buf32
[i
] & 0xffff);
1984 *buffer
++ = buf32
[i
] & 0xff;
1987 LOG_ERROR("should never get here");
1994 /* examine DCSR, to see if Sticky Abort (SA) got set */
1995 if ((retval
=xscale_read_dcsr(target
))!=ERROR_OK
)
1997 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
2000 if ((retval
=xscale_send_u32(target
, 0x60))!=ERROR_OK
)
2003 return ERROR_TARGET_DATA_ABORT
;
2009 int xscale_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
2011 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2012 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2015 LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address
, size
, count
);
2017 if (target
->state
!= TARGET_HALTED
)
2019 LOG_WARNING("target not halted");
2020 return ERROR_TARGET_NOT_HALTED
;
2023 /* sanitize arguments */
2024 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
2025 return ERROR_INVALID_ARGUMENTS
;
2027 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
2028 return ERROR_TARGET_UNALIGNED_ACCESS
;
2030 /* send memory write request (command 0x2n, n: access size) */
2031 if ((retval
=xscale_send_u32(target
, 0x20 | size
))!=ERROR_OK
)
2034 /* send base address for read request */
2035 if ((retval
=xscale_send_u32(target
, address
))!=ERROR_OK
)
2038 /* send number of requested data words to be written*/
2039 if ((retval
=xscale_send_u32(target
, count
))!=ERROR_OK
)
2042 /* extract data from host-endian buffer into byte stream */
2044 for (i
= 0; i
< count
; i
++)
2049 value
= target_buffer_get_u32(target
, buffer
);
2050 xscale_send_u32(target
, value
);
2054 value
= target_buffer_get_u16(target
, buffer
);
2055 xscale_send_u32(target
, value
);
2060 xscale_send_u32(target
, value
);
2064 LOG_ERROR("should never get here");
2069 if ((retval
=xscale_send(target
, buffer
, count
, size
))!=ERROR_OK
)
2072 /* examine DCSR, to see if Sticky Abort (SA) got set */
2073 if ((retval
=xscale_read_dcsr(target
))!=ERROR_OK
)
2075 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
2078 if ((retval
=xscale_send_u32(target
, 0x60))!=ERROR_OK
)
2081 return ERROR_TARGET_DATA_ABORT
;
2087 int xscale_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
2089 return xscale_write_memory(target
, address
, 4, count
, buffer
);
2092 u32
xscale_get_ttb(target_t
*target
)
2094 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2095 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2098 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_TTB
]);
2099 ttb
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_TTB
].value
, 0, 32);
2104 void xscale_disable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
2106 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2107 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2110 /* read cp15 control register */
2111 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2112 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2115 cp15_control
&= ~0x1U
;
2120 xscale_send_u32(target
, 0x50);
2121 xscale_send_u32(target
, xscale
->cache_clean_address
);
2123 /* invalidate DCache */
2124 xscale_send_u32(target
, 0x51);
2126 cp15_control
&= ~0x4U
;
2131 /* invalidate ICache */
2132 xscale_send_u32(target
, 0x52);
2133 cp15_control
&= ~0x1000U
;
2136 /* write new cp15 control register */
2137 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2139 /* execute cpwait to ensure outstanding operations complete */
2140 xscale_send_u32(target
, 0x53);
2143 void xscale_enable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
2145 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2146 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2149 /* read cp15 control register */
2150 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2151 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2154 cp15_control
|= 0x1U
;
2157 cp15_control
|= 0x4U
;
2160 cp15_control
|= 0x1000U
;
2162 /* write new cp15 control register */
2163 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2165 /* execute cpwait to ensure outstanding operations complete */
2166 xscale_send_u32(target
, 0x53);
2169 int xscale_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2172 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2173 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2175 if (target
->state
!= TARGET_HALTED
)
2177 LOG_WARNING("target not halted");
2178 return ERROR_TARGET_NOT_HALTED
;
2181 if (breakpoint
->set
)
2183 LOG_WARNING("breakpoint already set");
2187 if (breakpoint
->type
== BKPT_HARD
)
2189 u32 value
= breakpoint
->address
| 1;
2190 if (!xscale
->ibcr0_used
)
2192 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], value
);
2193 xscale
->ibcr0_used
= 1;
2194 breakpoint
->set
= 1; /* breakpoint set on first breakpoint register */
2196 else if (!xscale
->ibcr1_used
)
2198 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], value
);
2199 xscale
->ibcr1_used
= 1;
2200 breakpoint
->set
= 2; /* breakpoint set on second breakpoint register */
2204 LOG_ERROR("BUG: no hardware comparator available");
2208 else if (breakpoint
->type
== BKPT_SOFT
)
2210 if (breakpoint
->length
== 4)
2212 /* keep the original instruction in target endianness */
2213 if((retval
= target
->type
->read_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
2217 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2218 if((retval
= target_write_u32(target
, breakpoint
->address
, xscale
->arm_bkpt
)) != ERROR_OK
)
2225 /* keep the original instruction in target endianness */
2226 if((retval
= target
->type
->read_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
2230 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2231 if((retval
= target_write_u32(target
, breakpoint
->address
, xscale
->thumb_bkpt
)) != ERROR_OK
)
2236 breakpoint
->set
= 1;
2242 int xscale_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2244 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2245 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2247 if (target
->state
!= TARGET_HALTED
)
2249 LOG_WARNING("target not halted");
2250 return ERROR_TARGET_NOT_HALTED
;
2253 if ((breakpoint
->type
== BKPT_HARD
) && (xscale
->ibcr_available
< 1))
2255 LOG_INFO("no breakpoint unit available for hardware breakpoint");
2256 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2259 if ((breakpoint
->length
!= 2) && (breakpoint
->length
!= 4))
2261 LOG_INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
2262 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2265 if (breakpoint
->type
== BKPT_HARD
)
2267 xscale
->ibcr_available
--;
2273 int xscale_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2276 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2277 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2279 if (target
->state
!= TARGET_HALTED
)
2281 LOG_WARNING("target not halted");
2282 return ERROR_TARGET_NOT_HALTED
;
2285 if (!breakpoint
->set
)
2287 LOG_WARNING("breakpoint not set");
2291 if (breakpoint
->type
== BKPT_HARD
)
2293 if (breakpoint
->set
== 1)
2295 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], 0x0);
2296 xscale
->ibcr0_used
= 0;
2298 else if (breakpoint
->set
== 2)
2300 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], 0x0);
2301 xscale
->ibcr1_used
= 0;
2303 breakpoint
->set
= 0;
2307 /* restore original instruction (kept in target endianness) */
2308 if (breakpoint
->length
== 4)
2310 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
2317 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
2322 breakpoint
->set
= 0;
2328 int xscale_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2330 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2331 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2333 if (target
->state
!= TARGET_HALTED
)
2335 LOG_WARNING("target not halted");
2336 return ERROR_TARGET_NOT_HALTED
;
2339 if (breakpoint
->set
)
2341 xscale_unset_breakpoint(target
, breakpoint
);
2344 if (breakpoint
->type
== BKPT_HARD
)
2345 xscale
->ibcr_available
++;
2350 int xscale_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2352 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2353 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2355 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2356 u32 dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2358 if (target
->state
!= TARGET_HALTED
)
2360 LOG_WARNING("target not halted");
2361 return ERROR_TARGET_NOT_HALTED
;
2364 xscale_get_reg(dbcon
);
2366 switch (watchpoint
->rw
)
2378 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
2381 if (!xscale
->dbr0_used
)
2383 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR0
], watchpoint
->address
);
2384 dbcon_value
|= enable
;
2385 xscale_set_reg_u32(dbcon
, dbcon_value
);
2386 watchpoint
->set
= 1;
2387 xscale
->dbr0_used
= 1;
2389 else if (!xscale
->dbr1_used
)
2391 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR1
], watchpoint
->address
);
2392 dbcon_value
|= enable
<< 2;
2393 xscale_set_reg_u32(dbcon
, dbcon_value
);
2394 watchpoint
->set
= 2;
2395 xscale
->dbr1_used
= 1;
2399 LOG_ERROR("BUG: no hardware comparator available");
2406 int xscale_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2408 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2409 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2411 if (target
->state
!= TARGET_HALTED
)
2413 LOG_WARNING("target not halted");
2414 return ERROR_TARGET_NOT_HALTED
;
2417 if (xscale
->dbr_available
< 1)
2419 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2422 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
2424 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2427 xscale
->dbr_available
--;
2432 int xscale_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2434 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2435 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2436 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2437 u32 dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2439 if (target
->state
!= TARGET_HALTED
)
2441 LOG_WARNING("target not halted");
2442 return ERROR_TARGET_NOT_HALTED
;
2445 if (!watchpoint
->set
)
2447 LOG_WARNING("breakpoint not set");
2451 if (watchpoint
->set
== 1)
2453 dbcon_value
&= ~0x3;
2454 xscale_set_reg_u32(dbcon
, dbcon_value
);
2455 xscale
->dbr0_used
= 0;
2457 else if (watchpoint
->set
== 2)
2459 dbcon_value
&= ~0xc;
2460 xscale_set_reg_u32(dbcon
, dbcon_value
);
2461 xscale
->dbr1_used
= 0;
2463 watchpoint
->set
= 0;
2468 int xscale_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2470 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2471 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2473 if (target
->state
!= TARGET_HALTED
)
2475 LOG_WARNING("target not halted");
2476 return ERROR_TARGET_NOT_HALTED
;
2479 if (watchpoint
->set
)
2481 xscale_unset_watchpoint(target
, watchpoint
);
2484 xscale
->dbr_available
++;
2489 void xscale_enable_watchpoints(struct target_s
*target
)
2491 watchpoint_t
*watchpoint
= target
->watchpoints
;
2495 if (watchpoint
->set
== 0)
2496 xscale_set_watchpoint(target
, watchpoint
);
2497 watchpoint
= watchpoint
->next
;
2501 void xscale_enable_breakpoints(struct target_s
*target
)
2503 breakpoint_t
*breakpoint
= target
->breakpoints
;
2505 /* set any pending breakpoints */
2508 if (breakpoint
->set
== 0)
2509 xscale_set_breakpoint(target
, breakpoint
);
2510 breakpoint
= breakpoint
->next
;
2514 int xscale_get_reg(reg_t
*reg
)
2516 xscale_reg_t
*arch_info
= reg
->arch_info
;
2517 target_t
*target
= arch_info
->target
;
2518 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2519 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2521 /* DCSR, TX and RX are accessible via JTAG */
2522 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2524 return xscale_read_dcsr(arch_info
->target
);
2526 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2528 /* 1 = consume register content */
2529 return xscale_read_tx(arch_info
->target
, 1);
2531 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2533 /* can't read from RX register (host -> debug handler) */
2536 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2538 /* can't (explicitly) read from TXRXCTRL register */
2541 else /* Other DBG registers have to be transfered by the debug handler */
2543 /* send CP read request (command 0x40) */
2544 xscale_send_u32(target
, 0x40);
2546 /* send CP register number */
2547 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2549 /* read register value */
2550 xscale_read_tx(target
, 1);
2551 buf_cpy(xscale
->reg_cache
->reg_list
[XSCALE_TX
].value
, reg
->value
, 32);
2560 int xscale_set_reg(reg_t
*reg
, u8
* buf
)
2562 xscale_reg_t
*arch_info
= reg
->arch_info
;
2563 target_t
*target
= arch_info
->target
;
2564 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2565 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2566 u32 value
= buf_get_u32(buf
, 0, 32);
2568 /* DCSR, TX and RX are accessible via JTAG */
2569 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2571 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32, value
);
2572 return xscale_write_dcsr(arch_info
->target
, -1, -1);
2574 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2576 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
2577 return xscale_write_rx(arch_info
->target
);
2579 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2581 /* can't write to TX register (debug-handler -> host) */
2584 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2586 /* can't (explicitly) write to TXRXCTRL register */
2589 else /* Other DBG registers have to be transfered by the debug handler */
2591 /* send CP write request (command 0x41) */
2592 xscale_send_u32(target
, 0x41);
2594 /* send CP register number */
2595 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2597 /* send CP register value */
2598 xscale_send_u32(target
, value
);
2599 buf_set_u32(reg
->value
, 0, 32, value
);
2605 /* convenience wrapper to access XScale specific registers */
2606 int xscale_set_reg_u32(reg_t
*reg
, u32 value
)
2610 buf_set_u32(buf
, 0, 32, value
);
2612 return xscale_set_reg(reg
, buf
);
2615 int xscale_write_dcsr_sw(target_t
*target
, u32 value
)
2617 /* get pointers to arch-specific information */
2618 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2619 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2620 reg_t
*dcsr
= &xscale
->reg_cache
->reg_list
[XSCALE_DCSR
];
2621 xscale_reg_t
*dcsr_arch_info
= dcsr
->arch_info
;
2623 /* send CP write request (command 0x41) */
2624 xscale_send_u32(target
, 0x41);
2626 /* send CP register number */
2627 xscale_send_u32(target
, dcsr_arch_info
->dbg_handler_number
);
2629 /* send CP register value */
2630 xscale_send_u32(target
, value
);
2631 buf_set_u32(dcsr
->value
, 0, 32, value
);
2636 int xscale_read_trace(target_t
*target
)
2638 /* get pointers to arch-specific information */
2639 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2640 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2641 xscale_trace_data_t
**trace_data_p
;
2643 /* 258 words from debug handler
2644 * 256 trace buffer entries
2645 * 2 checkpoint addresses
2647 u32 trace_buffer
[258];
2648 int is_address
[256];
2651 if (target
->state
!= TARGET_HALTED
)
2653 LOG_WARNING("target must be stopped to read trace data");
2654 return ERROR_TARGET_NOT_HALTED
;
2657 /* send read trace buffer command (command 0x61) */
2658 xscale_send_u32(target
, 0x61);
2660 /* receive trace buffer content */
2661 xscale_receive(target
, trace_buffer
, 258);
2663 /* parse buffer backwards to identify address entries */
2664 for (i
= 255; i
>= 0; i
--)
2667 if (((trace_buffer
[i
] & 0xf0) == 0x90) ||
2668 ((trace_buffer
[i
] & 0xf0) == 0xd0))
2671 is_address
[--i
] = 1;
2673 is_address
[--i
] = 1;
2675 is_address
[--i
] = 1;
2677 is_address
[--i
] = 1;
2682 /* search first non-zero entry */
2683 for (j
= 0; (j
< 256) && (trace_buffer
[j
] == 0) && (!is_address
[j
]); j
++)
2688 LOG_DEBUG("no trace data collected");
2689 return ERROR_XSCALE_NO_TRACE_DATA
;
2692 for (trace_data_p
= &xscale
->trace
.data
; *trace_data_p
; trace_data_p
= &(*trace_data_p
)->next
)
2695 *trace_data_p
= malloc(sizeof(xscale_trace_data_t
));
2696 (*trace_data_p
)->next
= NULL
;
2697 (*trace_data_p
)->chkpt0
= trace_buffer
[256];
2698 (*trace_data_p
)->chkpt1
= trace_buffer
[257];
2699 (*trace_data_p
)->last_instruction
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
2700 (*trace_data_p
)->entries
= malloc(sizeof(xscale_trace_entry_t
) * (256 - j
));
2701 (*trace_data_p
)->depth
= 256 - j
;
2703 for (i
= j
; i
< 256; i
++)
2705 (*trace_data_p
)->entries
[i
- j
].data
= trace_buffer
[i
];
2707 (*trace_data_p
)->entries
[i
- j
].type
= XSCALE_TRACE_ADDRESS
;
2709 (*trace_data_p
)->entries
[i
- j
].type
= XSCALE_TRACE_MESSAGE
;
2715 int xscale_read_instruction(target_t
*target
, arm_instruction_t
*instruction
)
2717 /* get pointers to arch-specific information */
2718 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2719 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2726 if (!xscale
->trace
.image
)
2727 return ERROR_TRACE_IMAGE_UNAVAILABLE
;
2729 /* search for the section the current instruction belongs to */
2730 for (i
= 0; i
< xscale
->trace
.image
->num_sections
; i
++)
2732 if ((xscale
->trace
.image
->sections
[i
].base_address
<= xscale
->trace
.current_pc
) &&
2733 (xscale
->trace
.image
->sections
[i
].base_address
+ xscale
->trace
.image
->sections
[i
].size
> xscale
->trace
.current_pc
))
2742 /* current instruction couldn't be found in the image */
2743 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2746 if (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
)
2749 if ((retval
= image_read_section(xscale
->trace
.image
, section
,
2750 xscale
->trace
.current_pc
- xscale
->trace
.image
->sections
[section
].base_address
,
2751 4, buf
, &size_read
)) != ERROR_OK
)
2753 LOG_ERROR("error while reading instruction: %i", retval
);
2754 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2756 opcode
= target_buffer_get_u32(target
, buf
);
2757 arm_evaluate_opcode(opcode
, xscale
->trace
.current_pc
, instruction
);
2759 else if (xscale
->trace
.core_state
== ARMV4_5_STATE_THUMB
)
2762 if ((retval
= image_read_section(xscale
->trace
.image
, section
,
2763 xscale
->trace
.current_pc
- xscale
->trace
.image
->sections
[section
].base_address
,
2764 2, buf
, &size_read
)) != ERROR_OK
)
2766 LOG_ERROR("error while reading instruction: %i", retval
);
2767 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2769 opcode
= target_buffer_get_u16(target
, buf
);
2770 thumb_evaluate_opcode(opcode
, xscale
->trace
.current_pc
, instruction
);
2774 LOG_ERROR("BUG: unknown core state encountered");
2781 int xscale_branch_address(xscale_trace_data_t
*trace_data
, int i
, u32
*target
)
2783 /* if there are less than four entries prior to the indirect branch message
2784 * we can't extract the address */
2790 *target
= (trace_data
->entries
[i
-1].data
) | (trace_data
->entries
[i
-2].data
<< 8) |
2791 (trace_data
->entries
[i
-3].data
<< 16) | (trace_data
->entries
[i
-4].data
<< 24);
2796 int xscale_analyze_trace(target_t
*target
, command_context_t
*cmd_ctx
)
2798 /* get pointers to arch-specific information */
2799 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2800 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2803 xscale_trace_data_t
*trace_data
= xscale
->trace
.data
;
2812 xscale
->trace
.core_state
= ARMV4_5_STATE_ARM
;
2817 for (i
= 0; i
< trace_data
->depth
; i
++)
2823 if (trace_data
->entries
[i
].type
== XSCALE_TRACE_ADDRESS
)
2826 switch ((trace_data
->entries
[i
].data
& 0xf0) >> 4)
2828 case 0: /* Exceptions */
2836 exception
= (trace_data
->entries
[i
].data
& 0x70) >> 4;
2838 next_pc
= (trace_data
->entries
[i
].data
& 0xf0) >> 2;
2839 command_print(cmd_ctx
, "--- exception %i ---", (trace_data
->entries
[i
].data
& 0xf0) >> 4);
2841 case 8: /* Direct Branch */
2844 case 9: /* Indirect Branch */
2846 if (xscale_branch_address(trace_data
, i
, &next_pc
) == 0)
2851 case 13: /* Checkpointed Indirect Branch */
2852 if (xscale_branch_address(trace_data
, i
, &next_pc
) == 0)
2855 if (((chkpt
== 0) && (next_pc
!= trace_data
->chkpt0
))
2856 || ((chkpt
== 1) && (next_pc
!= trace_data
->chkpt1
)))
2857 LOG_WARNING("checkpointed indirect branch target address doesn't match checkpoint");
2859 /* explicit fall-through */
2860 case 12: /* Checkpointed Direct Branch */
2865 next_pc
= trace_data
->chkpt0
;
2868 else if (chkpt
== 1)
2871 next_pc
= trace_data
->chkpt0
;
2876 LOG_WARNING("more than two checkpointed branches encountered");
2879 case 15: /* Roll-over */
2882 default: /* Reserved */
2883 command_print(cmd_ctx
, "--- reserved trace message ---");
2884 LOG_ERROR("BUG: trace message %i is reserved", (trace_data
->entries
[i
].data
& 0xf0) >> 4);
2888 if (xscale
->trace
.pc_ok
)
2890 int executed
= (trace_data
->entries
[i
].data
& 0xf) + rollover
* 16;
2891 arm_instruction_t instruction
;
2893 if ((exception
== 6) || (exception
== 7))
2895 /* IRQ or FIQ exception, no instruction executed */
2899 while (executed
-- >= 0)
2901 if ((retval
= xscale_read_instruction(target
, &instruction
)) != ERROR_OK
)
2903 /* can't continue tracing with no image available */
2904 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
2908 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
2910 /* TODO: handle incomplete images */
2914 /* a precise abort on a load to the PC is included in the incremental
2915 * word count, other instructions causing data aborts are not included
2917 if ((executed
== 0) && (exception
== 4)
2918 && ((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_LDM
)))
2920 if ((instruction
.type
== ARM_LDM
)
2921 && ((instruction
.info
.load_store_multiple
.register_list
& 0x8000) == 0))
2925 else if (((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_LDRSH
))
2926 && (instruction
.info
.load_store
.Rd
!= 15))
2932 /* only the last instruction executed
2933 * (the one that caused the control flow change)
2934 * could be a taken branch
2936 if (((executed
== -1) && (branch
== 1)) &&
2937 (((instruction
.type
== ARM_B
) ||
2938 (instruction
.type
== ARM_BL
) ||
2939 (instruction
.type
== ARM_BLX
)) &&
2940 (instruction
.info
.b_bl_bx_blx
.target_address
!= 0xffffffff)))
2942 xscale
->trace
.current_pc
= instruction
.info
.b_bl_bx_blx
.target_address
;
2946 xscale
->trace
.current_pc
+= (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2;
2948 command_print(cmd_ctx
, "%s", instruction
.text
);
2956 xscale
->trace
.current_pc
= next_pc
;
2957 xscale
->trace
.pc_ok
= 1;
2961 for (; xscale
->trace
.current_pc
< trace_data
->last_instruction
; xscale
->trace
.current_pc
+= (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2)
2963 arm_instruction_t instruction
;
2964 if ((retval
= xscale_read_instruction(target
, &instruction
)) != ERROR_OK
)
2966 /* can't continue tracing with no image available */
2967 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
2971 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
2973 /* TODO: handle incomplete images */
2976 command_print(cmd_ctx
, "%s", instruction
.text
);
2979 trace_data
= trace_data
->next
;
2985 void xscale_build_reg_cache(target_t
*target
)
2987 /* get pointers to arch-specific information */
2988 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2989 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2991 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
2992 xscale_reg_t
*arch_info
= malloc(sizeof(xscale_reg_arch_info
));
2994 int num_regs
= sizeof(xscale_reg_arch_info
) / sizeof(xscale_reg_t
);
2996 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
2997 armv4_5
->core_cache
= (*cache_p
);
2999 /* register a register arch-type for XScale dbg registers only once */
3000 if (xscale_reg_arch_type
== -1)
3001 xscale_reg_arch_type
= register_reg_arch_type(xscale_get_reg
, xscale_set_reg
);
3003 (*cache_p
)->next
= malloc(sizeof(reg_cache_t
));
3004 cache_p
= &(*cache_p
)->next
;
3006 /* fill in values for the xscale reg cache */
3007 (*cache_p
)->name
= "XScale registers";
3008 (*cache_p
)->next
= NULL
;
3009 (*cache_p
)->reg_list
= malloc(num_regs
* sizeof(reg_t
));
3010 (*cache_p
)->num_regs
= num_regs
;
3012 for (i
= 0; i
< num_regs
; i
++)
3014 (*cache_p
)->reg_list
[i
].name
= xscale_reg_list
[i
];
3015 (*cache_p
)->reg_list
[i
].value
= calloc(4, 1);
3016 (*cache_p
)->reg_list
[i
].dirty
= 0;
3017 (*cache_p
)->reg_list
[i
].valid
= 0;
3018 (*cache_p
)->reg_list
[i
].size
= 32;
3019 (*cache_p
)->reg_list
[i
].bitfield_desc
= NULL
;
3020 (*cache_p
)->reg_list
[i
].num_bitfields
= 0;
3021 (*cache_p
)->reg_list
[i
].arch_info
= &arch_info
[i
];
3022 (*cache_p
)->reg_list
[i
].arch_type
= xscale_reg_arch_type
;
3023 arch_info
[i
] = xscale_reg_arch_info
[i
];
3024 arch_info
[i
].target
= target
;
3027 xscale
->reg_cache
= (*cache_p
);
3030 int xscale_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
3035 int xscale_quit(void)
3040 int xscale_init_arch_info(target_t
*target
, xscale_common_t
*xscale
, jtag_tap_t
*tap
, const char *variant
)
3042 armv4_5_common_t
*armv4_5
;
3043 u32 high_reset_branch
, low_reset_branch
;
3046 armv4_5
= &xscale
->armv4_5_common
;
3048 /* store architecture specfic data (none so far) */
3049 xscale
->arch_info
= NULL
;
3050 xscale
->common_magic
= XSCALE_COMMON_MAGIC
;
3052 /* remember the variant (PXA25x, PXA27x, IXP42x, ...) */
3053 xscale
->variant
= strdup(variant
);
3055 /* prepare JTAG information for the new target */
3056 xscale
->jtag_info
.tap
= tap
;
3058 xscale
->jtag_info
.dbgrx
= 0x02;
3059 xscale
->jtag_info
.dbgtx
= 0x10;
3060 xscale
->jtag_info
.dcsr
= 0x09;
3061 xscale
->jtag_info
.ldic
= 0x07;
3063 if ((strcmp(xscale
->variant
, "pxa250") == 0) ||
3064 (strcmp(xscale
->variant
, "pxa255") == 0) ||
3065 (strcmp(xscale
->variant
, "pxa26x") == 0))
3067 xscale
->jtag_info
.ir_length
= 5;
3069 else if ((strcmp(xscale
->variant
, "pxa27x") == 0) ||
3070 (strcmp(xscale
->variant
, "ixp42x") == 0) ||
3071 (strcmp(xscale
->variant
, "ixp45x") == 0) ||
3072 (strcmp(xscale
->variant
, "ixp46x") == 0))
3074 xscale
->jtag_info
.ir_length
= 7;
3077 /* the debug handler isn't installed (and thus not running) at this time */
3078 xscale
->handler_installed
= 0;
3079 xscale
->handler_running
= 0;
3080 xscale
->handler_address
= 0xfe000800;
3082 /* clear the vectors we keep locally for reference */
3083 memset(xscale
->low_vectors
, 0, sizeof(xscale
->low_vectors
));
3084 memset(xscale
->high_vectors
, 0, sizeof(xscale
->high_vectors
));
3086 /* no user-specified vectors have been configured yet */
3087 xscale
->static_low_vectors_set
= 0x0;
3088 xscale
->static_high_vectors_set
= 0x0;
3090 /* calculate branches to debug handler */
3091 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
3092 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
3094 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
3095 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
3097 for (i
= 1; i
<= 7; i
++)
3099 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
3100 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
3103 /* 64kB aligned region used for DCache cleaning */
3104 xscale
->cache_clean_address
= 0xfffe0000;
3106 xscale
->hold_rst
= 0;
3107 xscale
->external_debug_break
= 0;
3109 xscale
->ibcr_available
= 2;
3110 xscale
->ibcr0_used
= 0;
3111 xscale
->ibcr1_used
= 0;
3113 xscale
->dbr_available
= 2;
3114 xscale
->dbr0_used
= 0;
3115 xscale
->dbr1_used
= 0;
3117 xscale
->arm_bkpt
= ARMV5_BKPT(0x0);
3118 xscale
->thumb_bkpt
= ARMV5_T_BKPT(0x0) & 0xffff;
3120 xscale
->vector_catch
= 0x1;
3122 xscale
->trace
.capture_status
= TRACE_IDLE
;
3123 xscale
->trace
.data
= NULL
;
3124 xscale
->trace
.image
= NULL
;
3125 xscale
->trace
.buffer_enabled
= 0;
3126 xscale
->trace
.buffer_fill
= 0;
3128 /* prepare ARMv4/5 specific information */
3129 armv4_5
->arch_info
= xscale
;
3130 armv4_5
->read_core_reg
= xscale_read_core_reg
;
3131 armv4_5
->write_core_reg
= xscale_write_core_reg
;
3132 armv4_5
->full_context
= xscale_full_context
;
3134 armv4_5_init_arch_info(target
, armv4_5
);
3136 xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
3137 xscale
->armv4_5_mmu
.get_ttb
= xscale_get_ttb
;
3138 xscale
->armv4_5_mmu
.read_memory
= xscale_read_memory
;
3139 xscale
->armv4_5_mmu
.write_memory
= xscale_write_memory
;
3140 xscale
->armv4_5_mmu
.disable_mmu_caches
= xscale_disable_mmu_caches
;
3141 xscale
->armv4_5_mmu
.enable_mmu_caches
= xscale_enable_mmu_caches
;
3142 xscale
->armv4_5_mmu
.has_tiny_pages
= 1;
3143 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3148 /* target xscale <endianess> <startup_mode> <chain_pos> <variant> */
3149 int xscale_target_create(struct target_s
*target
, Jim_Interp
*interp
)
3151 xscale_common_t
*xscale
= calloc(1,sizeof(xscale_common_t
));
3153 xscale_init_arch_info(target
, xscale
, target
->tap
, target
->variant
);
3154 xscale_build_reg_cache(target
);
3159 int xscale_handle_debug_handler_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3161 target_t
*target
= NULL
;
3162 armv4_5_common_t
*armv4_5
;
3163 xscale_common_t
*xscale
;
3165 u32 handler_address
;
3169 LOG_ERROR("'xscale debug_handler <target#> <address>' command takes two required operands");
3173 if ((target
= get_target_by_num(strtoul(args
[0], NULL
, 0))) == NULL
)
3175 LOG_ERROR("no target '%s' configured", args
[0]);
3179 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3184 handler_address
= strtoul(args
[1], NULL
, 0);
3186 if (((handler_address
>= 0x800) && (handler_address
<= 0x1fef800)) ||
3187 ((handler_address
>= 0xfe000800) && (handler_address
<= 0xfffff800)))
3189 xscale
->handler_address
= handler_address
;
3193 LOG_ERROR("xscale debug_handler <address> must be between 0x800 and 0x1fef800 or between 0xfe000800 and 0xfffff800");
3200 int xscale_handle_cache_clean_address_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3202 target_t
*target
= NULL
;
3203 armv4_5_common_t
*armv4_5
;
3204 xscale_common_t
*xscale
;
3206 u32 cache_clean_address
;
3210 return ERROR_COMMAND_SYNTAX_ERROR
;
3213 if ((target
= get_target_by_num(strtoul(args
[0], NULL
, 0))) == NULL
)
3215 LOG_ERROR("no target '%s' configured", args
[0]);
3219 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3224 cache_clean_address
= strtoul(args
[1], NULL
, 0);
3226 if (cache_clean_address
& 0xffff)
3228 LOG_ERROR("xscale cache_clean_address <address> must be 64kb aligned");
3232 xscale
->cache_clean_address
= cache_clean_address
;
3238 int xscale_handle_cache_info_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3240 target_t
*target
= get_current_target(cmd_ctx
);
3241 armv4_5_common_t
*armv4_5
;
3242 xscale_common_t
*xscale
;
3244 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3249 return armv4_5_handle_cache_info_command(cmd_ctx
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
3252 static int xscale_virt2phys(struct target_s
*target
, u32
virtual, u32
*physical
)
3254 armv4_5_common_t
*armv4_5
;
3255 xscale_common_t
*xscale
;
3262 if ((retval
= xscale_get_arch_pointers(target
, &armv4_5
, &xscale
)) != ERROR_OK
)
3266 u32 ret
= armv4_5_mmu_translate_va(target
, &xscale
->armv4_5_mmu
, virtual, &type
, &cb
, &domain
, &ap
);
3275 static int xscale_mmu(struct target_s
*target
, int *enabled
)
3277 armv4_5_common_t
*armv4_5
= target
->arch_info
;
3278 xscale_common_t
*xscale
= armv4_5
->arch_info
;
3280 if (target
->state
!= TARGET_HALTED
)
3282 LOG_ERROR("Target not halted");
3283 return ERROR_TARGET_INVALID
;
3285 *enabled
= xscale
->armv4_5_mmu
.mmu_enabled
;
3289 int xscale_handle_mmu_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3291 target_t
*target
= get_current_target(cmd_ctx
);
3292 armv4_5_common_t
*armv4_5
;
3293 xscale_common_t
*xscale
;
3295 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3300 if (target
->state
!= TARGET_HALTED
)
3302 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3308 if (strcmp("enable", args
[0]) == 0)
3310 xscale_enable_mmu_caches(target
, 1, 0, 0);
3311 xscale
->armv4_5_mmu
.mmu_enabled
= 1;
3313 else if (strcmp("disable", args
[0]) == 0)
3315 xscale_disable_mmu_caches(target
, 1, 0, 0);
3316 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3320 command_print(cmd_ctx
, "mmu %s", (xscale
->armv4_5_mmu
.mmu_enabled
) ? "enabled" : "disabled");
3325 int xscale_handle_idcache_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3327 target_t
*target
= get_current_target(cmd_ctx
);
3328 armv4_5_common_t
*armv4_5
;
3329 xscale_common_t
*xscale
;
3330 int icache
= 0, dcache
= 0;
3332 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3337 if (target
->state
!= TARGET_HALTED
)
3339 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3343 if (strcmp(cmd
, "icache") == 0)
3345 else if (strcmp(cmd
, "dcache") == 0)
3350 if (strcmp("enable", args
[0]) == 0)
3352 xscale_enable_mmu_caches(target
, 0, dcache
, icache
);
3355 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 1;
3357 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 1;
3359 else if (strcmp("disable", args
[0]) == 0)
3361 xscale_disable_mmu_caches(target
, 0, dcache
, icache
);
3364 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 0;
3366 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 0;
3371 command_print(cmd_ctx
, "icache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
) ? "enabled" : "disabled");
3374 command_print(cmd_ctx
, "dcache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
) ? "enabled" : "disabled");
3379 int xscale_handle_vector_catch_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3381 target_t
*target
= get_current_target(cmd_ctx
);
3382 armv4_5_common_t
*armv4_5
;
3383 xscale_common_t
*xscale
;
3385 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3392 command_print(cmd_ctx
, "usage: xscale vector_catch [mask]");
3396 xscale
->vector_catch
= strtoul(args
[0], NULL
, 0);
3397 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 8, xscale
->vector_catch
);
3398 xscale_write_dcsr(target
, -1, -1);
3401 command_print(cmd_ctx
, "vector catch mask: 0x%2.2x", xscale
->vector_catch
);
3407 int xscale_handle_trace_buffer_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3409 target_t
*target
= get_current_target(cmd_ctx
);
3410 armv4_5_common_t
*armv4_5
;
3411 xscale_common_t
*xscale
;
3414 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3419 if (target
->state
!= TARGET_HALTED
)
3421 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3425 if ((argc
>= 1) && (strcmp("enable", args
[0]) == 0))
3427 xscale_trace_data_t
*td
, *next_td
;
3428 xscale
->trace
.buffer_enabled
= 1;
3430 /* free old trace data */
3431 td
= xscale
->trace
.data
;
3441 xscale
->trace
.data
= NULL
;
3443 else if ((argc
>= 1) && (strcmp("disable", args
[0]) == 0))
3445 xscale
->trace
.buffer_enabled
= 0;
3448 if ((argc
>= 2) && (strcmp("fill", args
[1]) == 0))
3451 xscale
->trace
.buffer_fill
= strtoul(args
[2], NULL
, 0);
3453 xscale
->trace
.buffer_fill
= 1;
3455 else if ((argc
>= 2) && (strcmp("wrap", args
[1]) == 0))
3457 xscale
->trace
.buffer_fill
= -1;
3460 if (xscale
->trace
.buffer_enabled
)
3462 /* if we enable the trace buffer in fill-once
3463 * mode we know the address of the first instruction */
3464 xscale
->trace
.pc_ok
= 1;
3465 xscale
->trace
.current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
3469 /* otherwise the address is unknown, and we have no known good PC */
3470 xscale
->trace
.pc_ok
= 0;
3473 command_print(cmd_ctx
, "trace buffer %s (%s)",
3474 (xscale
->trace
.buffer_enabled
) ? "enabled" : "disabled",
3475 (xscale
->trace
.buffer_fill
> 0) ? "fill" : "wrap");
3477 dcsr_value
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32);
3478 if (xscale
->trace
.buffer_fill
>= 0)
3479 xscale_write_dcsr_sw(target
, (dcsr_value
& 0xfffffffc) | 2);
3481 xscale_write_dcsr_sw(target
, dcsr_value
& 0xfffffffc);
3486 int xscale_handle_trace_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3489 armv4_5_common_t
*armv4_5
;
3490 xscale_common_t
*xscale
;
3494 command_print(cmd_ctx
, "usage: xscale trace_image <file> [base address] [type]");
3498 target
= get_current_target(cmd_ctx
);
3500 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3505 if (xscale
->trace
.image
)
3507 image_close(xscale
->trace
.image
);
3508 free(xscale
->trace
.image
);
3509 command_print(cmd_ctx
, "previously loaded image found and closed");
3512 xscale
->trace
.image
= malloc(sizeof(image_t
));
3513 xscale
->trace
.image
->base_address_set
= 0;
3514 xscale
->trace
.image
->start_address_set
= 0;
3516 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
3519 xscale
->trace
.image
->base_address_set
= 1;
3520 xscale
->trace
.image
->base_address
= strtoul(args
[1], NULL
, 0);
3524 xscale
->trace
.image
->base_address_set
= 0;
3527 if (image_open(xscale
->trace
.image
, args
[0], (argc
>= 3) ? args
[2] : NULL
) != ERROR_OK
)
3529 free(xscale
->trace
.image
);
3530 xscale
->trace
.image
= NULL
;
3537 int xscale_handle_dump_trace_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3539 target_t
*target
= get_current_target(cmd_ctx
);
3540 armv4_5_common_t
*armv4_5
;
3541 xscale_common_t
*xscale
;
3542 xscale_trace_data_t
*trace_data
;
3545 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3550 if (target
->state
!= TARGET_HALTED
)
3552 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3558 command_print(cmd_ctx
, "usage: xscale dump_trace <file>");
3562 trace_data
= xscale
->trace
.data
;
3566 command_print(cmd_ctx
, "no trace data collected");
3570 if (fileio_open(&file
, args
[0], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
)
3579 fileio_write_u32(&file
, trace_data
->chkpt0
);
3580 fileio_write_u32(&file
, trace_data
->chkpt1
);
3581 fileio_write_u32(&file
, trace_data
->last_instruction
);
3582 fileio_write_u32(&file
, trace_data
->depth
);
3584 for (i
= 0; i
< trace_data
->depth
; i
++)
3585 fileio_write_u32(&file
, trace_data
->entries
[i
].data
| ((trace_data
->entries
[i
].type
& 0xffff) << 16));
3587 trace_data
= trace_data
->next
;
3590 fileio_close(&file
);
3595 int xscale_handle_analyze_trace_buffer_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3597 target_t
*target
= get_current_target(cmd_ctx
);
3598 armv4_5_common_t
*armv4_5
;
3599 xscale_common_t
*xscale
;
3601 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3606 xscale_analyze_trace(target
, cmd_ctx
);
3611 int xscale_handle_cp15(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3613 target_t
*target
= get_current_target(cmd_ctx
);
3614 armv4_5_common_t
*armv4_5
;
3615 xscale_common_t
*xscale
;
3617 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3622 if (target
->state
!= TARGET_HALTED
)
3624 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3631 reg_no
= strtoul(args
[0], NULL
, 0);
3632 /*translate from xscale cp15 register no to openocd register*/
3636 reg_no
= XSCALE_MAINID
;
3639 reg_no
= XSCALE_CTRL
;
3642 reg_no
= XSCALE_TTB
;
3645 reg_no
= XSCALE_DAC
;
3648 reg_no
= XSCALE_FSR
;
3651 reg_no
= XSCALE_FAR
;
3654 reg_no
= XSCALE_PID
;
3657 reg_no
= XSCALE_CPACCESS
;
3660 command_print(cmd_ctx
, "invalid register number");
3661 return ERROR_INVALID_ARGUMENTS
;
3663 reg
= &xscale
->reg_cache
->reg_list
[reg_no
];
3670 /* read cp15 control register */
3671 xscale_get_reg(reg
);
3672 value
= buf_get_u32(reg
->value
, 0, 32);
3673 command_print(cmd_ctx
, "%s (/%i): 0x%x", reg
->name
, reg
->size
, value
);
3678 u32 value
= strtoul(args
[1], NULL
, 0);
3680 /* send CP write request (command 0x41) */
3681 xscale_send_u32(target
, 0x41);
3683 /* send CP register number */
3684 xscale_send_u32(target
, reg_no
);
3686 /* send CP register value */
3687 xscale_send_u32(target
, value
);
3689 /* execute cpwait to ensure outstanding operations complete */
3690 xscale_send_u32(target
, 0x53);
3694 command_print(cmd_ctx
, "usage: cp15 [register]<, [value]>");
3700 int xscale_register_commands(struct command_context_s
*cmd_ctx
)
3702 command_t
*xscale_cmd
;
3704 xscale_cmd
= register_command(cmd_ctx
, NULL
, "xscale", NULL
, COMMAND_ANY
, "xscale specific commands");
3706 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");
3707 register_command(cmd_ctx
, xscale_cmd
, "cache_clean_address", xscale_handle_cache_clean_address_command
, COMMAND_ANY
, NULL
);
3709 register_command(cmd_ctx
, xscale_cmd
, "cache_info", xscale_handle_cache_info_command
, COMMAND_EXEC
, NULL
);
3710 register_command(cmd_ctx
, xscale_cmd
, "mmu", xscale_handle_mmu_command
, COMMAND_EXEC
, "['enable'|'disable'] the MMU");
3711 register_command(cmd_ctx
, xscale_cmd
, "icache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the ICache");
3712 register_command(cmd_ctx
, xscale_cmd
, "dcache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the DCache");
3714 register_command(cmd_ctx
, xscale_cmd
, "vector_catch", xscale_handle_vector_catch_command
, COMMAND_EXEC
, "<mask> of vectors that should be catched");
3716 register_command(cmd_ctx
, xscale_cmd
, "trace_buffer", xscale_handle_trace_buffer_command
, COMMAND_EXEC
, "<enable|disable> ['fill' [n]|'wrap']");
3718 register_command(cmd_ctx
, xscale_cmd
, "dump_trace", xscale_handle_dump_trace_command
, COMMAND_EXEC
, "dump content of trace buffer to <file>");
3719 register_command(cmd_ctx
, xscale_cmd
, "analyze_trace", xscale_handle_analyze_trace_buffer_command
, COMMAND_EXEC
, "analyze content of trace buffer");
3720 register_command(cmd_ctx
, xscale_cmd
, "trace_image", xscale_handle_trace_image_command
,
3721 COMMAND_EXEC
, "load image from <file> [base address]");
3723 register_command(cmd_ctx
, xscale_cmd
, "cp15", xscale_handle_cp15
, COMMAND_EXEC
, "access coproc 15 <register> [value]");
3725 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)