1 /***************************************************************************
2 * Copyright (C) 2006, 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2007,2008 Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
28 #include "arm7_9_common.h"
29 #include "arm_simulator.h"
30 #include "arm_disassembler.h"
31 #include "time_support.h"
35 int xscale_register_commands(struct command_context_s
*cmd_ctx
);
37 /* forward declarations */
38 int xscale_target_create(struct target_s
*target
, Jim_Interp
*interp
);
39 int xscale_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
);
40 int xscale_quit(void);
42 int xscale_arch_state(struct target_s
*target
);
43 int xscale_poll(target_t
*target
);
44 int xscale_halt(target_t
*target
);
45 int xscale_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
);
46 int xscale_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
);
47 int xscale_debug_entry(target_t
*target
);
48 int xscale_restore_context(target_t
*target
);
50 int xscale_assert_reset(target_t
*target
);
51 int xscale_deassert_reset(target_t
*target
);
52 int xscale_soft_reset_halt(struct target_s
*target
);
54 int xscale_set_reg_u32(reg_t
*reg
, u32 value
);
56 int xscale_read_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
);
57 int xscale_write_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
, u32 value
);
59 int xscale_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
);
60 int xscale_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
);
61 int xscale_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
);
63 int xscale_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
64 int xscale_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
65 int xscale_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
66 int xscale_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
67 int xscale_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
);
68 int xscale_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
);
69 void xscale_enable_watchpoints(struct target_s
*target
);
70 void xscale_enable_breakpoints(struct target_s
*target
);
71 static int xscale_virt2phys(struct target_s
*target
, u32
virtual, u32
*physical
);
72 static int xscale_mmu(struct target_s
*target
, int *enabled
);
74 int xscale_read_trace(target_t
*target
);
76 target_type_t xscale_target
=
81 .arch_state
= xscale_arch_state
,
83 .target_request_data
= NULL
,
86 .resume
= xscale_resume
,
89 .assert_reset
= xscale_assert_reset
,
90 .deassert_reset
= xscale_deassert_reset
,
91 .soft_reset_halt
= xscale_soft_reset_halt
,
93 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
95 .read_memory
= xscale_read_memory
,
96 .write_memory
= xscale_write_memory
,
97 .bulk_write_memory
= xscale_bulk_write_memory
,
98 .checksum_memory
= arm7_9_checksum_memory
,
99 .blank_check_memory
= arm7_9_blank_check_memory
,
101 .run_algorithm
= armv4_5_run_algorithm
,
103 .add_breakpoint
= xscale_add_breakpoint
,
104 .remove_breakpoint
= xscale_remove_breakpoint
,
105 .add_watchpoint
= xscale_add_watchpoint
,
106 .remove_watchpoint
= xscale_remove_watchpoint
,
108 .register_commands
= xscale_register_commands
,
109 .target_create
= xscale_target_create
,
110 .init_target
= xscale_init_target
,
113 .virt2phys
= xscale_virt2phys
,
117 char* xscale_reg_list
[] =
119 "XSCALE_MAINID", /* 0 */
129 "XSCALE_IBCR0", /* 10 */
139 "XSCALE_RX", /* 20 */
143 xscale_reg_t xscale_reg_arch_info
[] =
145 {XSCALE_MAINID
, NULL
},
146 {XSCALE_CACHETYPE
, NULL
},
148 {XSCALE_AUXCTRL
, NULL
},
154 {XSCALE_CPACCESS
, NULL
},
155 {XSCALE_IBCR0
, NULL
},
156 {XSCALE_IBCR1
, NULL
},
159 {XSCALE_DBCON
, NULL
},
160 {XSCALE_TBREG
, NULL
},
161 {XSCALE_CHKPT0
, NULL
},
162 {XSCALE_CHKPT1
, NULL
},
163 {XSCALE_DCSR
, NULL
}, /* DCSR accessed via JTAG or SW */
164 {-1, NULL
}, /* TX accessed via JTAG */
165 {-1, NULL
}, /* RX accessed via JTAG */
166 {-1, NULL
}, /* TXRXCTRL implicit access via JTAG */
169 int xscale_reg_arch_type
= -1;
171 int xscale_get_reg(reg_t
*reg
);
172 int xscale_set_reg(reg_t
*reg
, u8
*buf
);
174 int xscale_get_arch_pointers(target_t
*target
, armv4_5_common_t
**armv4_5_p
, xscale_common_t
**xscale_p
)
176 armv4_5_common_t
*armv4_5
= target
->arch_info
;
177 xscale_common_t
*xscale
= armv4_5
->arch_info
;
179 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
181 LOG_ERROR("target isn't an XScale target");
185 if (xscale
->common_magic
!= XSCALE_COMMON_MAGIC
)
187 LOG_ERROR("target isn't an XScale target");
191 *armv4_5_p
= armv4_5
;
197 int xscale_jtag_set_instr(jtag_tap_t
*tap
, u32 new_instr
)
202 if (buf_get_u32(tap
->cur_instr
, 0, tap
->ir_length
) != new_instr
)
207 field
.num_bits
= tap
->ir_length
;
208 field
.out_value
= calloc(CEIL(field
.num_bits
, 8), 1);
209 buf_set_u32(field
.out_value
, 0, field
.num_bits
, new_instr
);
212 field
.in_value
= tmp
;
214 jtag_add_ir_scan(1, &field
, TAP_INVALID
);
216 /* FIX!!!! isn't this check superfluous? verify_ircapture handles this? */
217 jtag_check_value_mask(&field
, tap
->expected
, tap
->expected_mask
);
219 free(field
.out_value
);
225 int xscale_read_dcsr(target_t
*target
)
227 armv4_5_common_t
*armv4_5
= target
->arch_info
;
228 xscale_common_t
*xscale
= armv4_5
->arch_info
;
232 scan_field_t fields
[3];
234 u8 field0_check_value
= 0x2;
235 u8 field0_check_mask
= 0x7;
237 u8 field2_check_value
= 0x0;
238 u8 field2_check_mask
= 0x1;
240 jtag_add_end_state(TAP_DRPAUSE
);
241 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dcsr
);
243 buf_set_u32(&field0
, 1, 1, xscale
->hold_rst
);
244 buf_set_u32(&field0
, 2, 1, xscale
->external_debug_break
);
246 fields
[0].tap
= xscale
->jtag_info
.tap
;
247 fields
[0].num_bits
= 3;
248 fields
[0].out_value
= &field0
;
250 fields
[0].in_value
= &tmp
;
252 fields
[1].tap
= xscale
->jtag_info
.tap
;
253 fields
[1].num_bits
= 32;
254 fields
[1].out_value
= NULL
;
255 fields
[1].in_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
258 fields
[2].tap
= xscale
->jtag_info
.tap
;
259 fields
[2].num_bits
= 1;
260 fields
[2].out_value
= &field2
;
262 fields
[2].in_value
= &tmp2
;
264 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
266 jtag_check_value_mask(fields
+0, &field0_check_value
, &field0_check_mask
);
267 jtag_check_value_mask(fields
+2, &field2_check_value
, &field2_check_mask
);
269 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
271 LOG_ERROR("JTAG error while reading DCSR");
275 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].dirty
= 0;
276 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].valid
= 1;
278 /* write the register with the value we just read
279 * on this second pass, only the first bit of field0 is guaranteed to be 0)
281 field0_check_mask
= 0x1;
282 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
283 fields
[1].in_value
= NULL
;
285 jtag_add_end_state(TAP_IDLE
);
287 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
289 /* DANGER!!! this must be here. It will make sure that the arguments
290 * to jtag_set_check_value() does not go out of scope! */
291 return jtag_execute_queue();
295 static void xscale_getbuf(u8
*in
)
297 *((u32
*)in
)=buf_get_u32(in
, 0, 32);
300 int xscale_receive(target_t
*target
, u32
*buffer
, int num_words
)
303 return ERROR_INVALID_ARGUMENTS
;
306 armv4_5_common_t
*armv4_5
= target
->arch_info
;
307 xscale_common_t
*xscale
= armv4_5
->arch_info
;
310 scan_field_t fields
[3];
312 u8
*field0
= malloc(num_words
* 1);
313 u8 field0_check_value
= 0x2;
314 u8 field0_check_mask
= 0x6;
315 u32
*field1
= malloc(num_words
* 4);
316 u8 field2_check_value
= 0x0;
317 u8 field2_check_mask
= 0x1;
319 int words_scheduled
= 0;
323 path
[0] = TAP_DRSELECT
;
324 path
[1] = TAP_DRCAPTURE
;
325 path
[2] = TAP_DRSHIFT
;
327 fields
[0].tap
= xscale
->jtag_info
.tap
;
328 fields
[0].num_bits
= 3;
329 fields
[0].out_value
= NULL
;
330 fields
[0].in_value
= NULL
;
331 fields
[0].check_value
= &field0_check_value
;
332 fields
[0].check_mask
= &field0_check_mask
;
334 fields
[1].tap
= xscale
->jtag_info
.tap
;
335 fields
[1].num_bits
= 32;
336 fields
[1].out_value
= NULL
;
337 fields
[1].check_value
= NULL
;
338 fields
[1].check_mask
= NULL
;
340 fields
[2].tap
= xscale
->jtag_info
.tap
;
341 fields
[2].num_bits
= 1;
342 fields
[2].out_value
= NULL
;
343 fields
[2].in_value
= NULL
;
344 fields
[2].check_value
= &field2_check_value
;
345 fields
[2].check_mask
= &field2_check_mask
;
347 jtag_add_end_state(TAP_IDLE
);
348 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dbgtx
);
349 jtag_add_runtest(1, TAP_INVALID
); /* ensures that we're in the TAP_IDLE state as the above could be a no-op */
351 /* repeat until all words have been collected */
353 while (words_done
< num_words
)
357 for (i
= words_done
; i
< num_words
; i
++)
359 fields
[0].in_value
= &field0
[i
];
361 jtag_add_pathmove(3, path
);
363 fields
[1].in_value
= (u8
*)(field1
+i
);
365 jtag_add_dr_scan_check(3, fields
, TAP_IDLE
);
367 jtag_add_callback(xscale_getbuf
, (u8
*)(field1
+i
));
372 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
374 LOG_ERROR("JTAG error while receiving data from debug handler");
378 /* examine results */
379 for (i
= words_done
; i
< num_words
; i
++)
381 if (!(field0
[0] & 1))
383 /* move backwards if necessary */
385 for (j
= i
; j
< num_words
- 1; j
++)
387 field0
[j
] = field0
[j
+1];
388 field1
[j
] = field1
[j
+1];
393 if (words_scheduled
==0)
395 if (attempts
++==1000)
397 LOG_ERROR("Failed to receiving data from debug handler after 1000 attempts");
398 retval
=ERROR_TARGET_TIMEOUT
;
403 words_done
+= words_scheduled
;
406 for (i
= 0; i
< num_words
; i
++)
407 *(buffer
++) = buf_get_u32((u8
*)&field1
[i
], 0, 32);
414 int xscale_read_tx(target_t
*target
, int consume
)
416 armv4_5_common_t
*armv4_5
= target
->arch_info
;
417 xscale_common_t
*xscale
= armv4_5
->arch_info
;
419 tap_state_t noconsume_path
[6];
422 struct timeval timeout
, now
;
424 scan_field_t fields
[3];
426 u8 field0_check_value
= 0x2;
427 u8 field0_check_mask
= 0x6;
428 u8 field2_check_value
= 0x0;
429 u8 field2_check_mask
= 0x1;
431 jtag_add_end_state(TAP_IDLE
);
433 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dbgtx
);
435 path
[0] = TAP_DRSELECT
;
436 path
[1] = TAP_DRCAPTURE
;
437 path
[2] = TAP_DRSHIFT
;
439 noconsume_path
[0] = TAP_DRSELECT
;
440 noconsume_path
[1] = TAP_DRCAPTURE
;
441 noconsume_path
[2] = TAP_DREXIT1
;
442 noconsume_path
[3] = TAP_DRPAUSE
;
443 noconsume_path
[4] = TAP_DREXIT2
;
444 noconsume_path
[5] = TAP_DRSHIFT
;
446 fields
[0].tap
= xscale
->jtag_info
.tap
;
447 fields
[0].num_bits
= 3;
448 fields
[0].out_value
= NULL
;
449 fields
[0].in_value
= &field0_in
;
451 fields
[1].tap
= xscale
->jtag_info
.tap
;
452 fields
[1].num_bits
= 32;
453 fields
[1].out_value
= NULL
;
454 fields
[1].in_value
= xscale
->reg_cache
->reg_list
[XSCALE_TX
].value
;
457 fields
[2].tap
= xscale
->jtag_info
.tap
;
458 fields
[2].num_bits
= 1;
459 fields
[2].out_value
= NULL
;
461 fields
[2].in_value
= &tmp
;
463 gettimeofday(&timeout
, NULL
);
464 timeval_add_time(&timeout
, 1, 0);
468 /* if we want to consume the register content (i.e. clear TX_READY),
469 * we have to go straight from Capture-DR to Shift-DR
470 * otherwise, we go from Capture-DR to Exit1-DR to Pause-DR
473 jtag_add_pathmove(3, path
);
476 jtag_add_pathmove(sizeof(noconsume_path
)/sizeof(*noconsume_path
), noconsume_path
);
479 jtag_add_dr_scan(3, fields
, TAP_IDLE
);
481 jtag_check_value_mask(fields
+0, &field0_check_value
, &field0_check_mask
);
482 jtag_check_value_mask(fields
+2, &field2_check_value
, &field2_check_mask
);
484 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
486 LOG_ERROR("JTAG error while reading TX");
487 return ERROR_TARGET_TIMEOUT
;
490 gettimeofday(&now
, NULL
);
491 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
)&& (now
.tv_usec
> timeout
.tv_usec
)))
493 LOG_ERROR("time out reading TX register");
494 return ERROR_TARGET_TIMEOUT
;
496 if (!((!(field0_in
& 1)) && consume
))
502 LOG_DEBUG("waiting 100ms");
503 alive_sleep(100); /* avoid flooding the logs */
511 if (!(field0_in
& 1))
512 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
517 int xscale_write_rx(target_t
*target
)
519 armv4_5_common_t
*armv4_5
= target
->arch_info
;
520 xscale_common_t
*xscale
= armv4_5
->arch_info
;
523 struct timeval timeout
, now
;
525 scan_field_t fields
[3];
528 u8 field0_check_value
= 0x2;
529 u8 field0_check_mask
= 0x6;
531 u8 field2_check_value
= 0x0;
532 u8 field2_check_mask
= 0x1;
534 jtag_add_end_state(TAP_IDLE
);
536 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dbgrx
);
538 fields
[0].tap
= xscale
->jtag_info
.tap
;
539 fields
[0].num_bits
= 3;
540 fields
[0].out_value
= &field0_out
;
541 fields
[0].in_value
= &field0_in
;
543 fields
[1].tap
= xscale
->jtag_info
.tap
;
544 fields
[1].num_bits
= 32;
545 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
;
546 fields
[1].in_value
= NULL
;
549 fields
[2].tap
= xscale
->jtag_info
.tap
;
550 fields
[2].num_bits
= 1;
551 fields
[2].out_value
= &field2
;
553 fields
[2].in_value
= &tmp
;
555 gettimeofday(&timeout
, NULL
);
556 timeval_add_time(&timeout
, 1, 0);
558 /* poll until rx_read is low */
559 LOG_DEBUG("polling RX");
562 jtag_add_dr_scan(3, fields
, TAP_IDLE
);
564 jtag_check_value_mask(fields
+0, &field0_check_value
, &field0_check_mask
);
565 jtag_check_value_mask(fields
+2, &field2_check_value
, &field2_check_mask
);
567 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
569 LOG_ERROR("JTAG error while writing RX");
573 gettimeofday(&now
, NULL
);
574 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
)&& (now
.tv_usec
> timeout
.tv_usec
)))
576 LOG_ERROR("time out writing RX register");
577 return ERROR_TARGET_TIMEOUT
;
579 if (!(field0_in
& 1))
583 LOG_DEBUG("waiting 100ms");
584 alive_sleep(100); /* avoid flooding the logs */
594 jtag_add_dr_scan(3, fields
, TAP_IDLE
);
596 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
598 LOG_ERROR("JTAG error while writing RX");
605 /* send count elements of size byte to the debug handler */
606 int xscale_send(target_t
*target
, u8
*buffer
, int count
, int size
)
608 armv4_5_common_t
*armv4_5
= target
->arch_info
;
609 xscale_common_t
*xscale
= armv4_5
->arch_info
;
617 jtag_add_end_state(TAP_IDLE
);
619 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dbgrx
);
626 int endianness
= target
->endianness
;
627 while (done_count
++ < count
)
632 if (endianness
== TARGET_LITTLE_ENDIAN
)
634 t
[1]=le_to_h_u32(buffer
);
637 t
[1]=be_to_h_u32(buffer
);
641 if (endianness
== TARGET_LITTLE_ENDIAN
)
643 t
[1]=le_to_h_u16(buffer
);
646 t
[1]=be_to_h_u16(buffer
);
653 LOG_ERROR("BUG: size neither 4, 2 nor 1");
656 jtag_add_dr_out(xscale
->jtag_info
.tap
,
664 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
666 LOG_ERROR("JTAG error while sending data to debug handler");
673 int xscale_send_u32(target_t
*target
, u32 value
)
675 armv4_5_common_t
*armv4_5
= target
->arch_info
;
676 xscale_common_t
*xscale
= armv4_5
->arch_info
;
678 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
679 return xscale_write_rx(target
);
682 int xscale_write_dcsr(target_t
*target
, int hold_rst
, int ext_dbg_brk
)
684 armv4_5_common_t
*armv4_5
= target
->arch_info
;
685 xscale_common_t
*xscale
= armv4_5
->arch_info
;
689 scan_field_t fields
[3];
691 u8 field0_check_value
= 0x2;
692 u8 field0_check_mask
= 0x7;
694 u8 field2_check_value
= 0x0;
695 u8 field2_check_mask
= 0x1;
698 xscale
->hold_rst
= hold_rst
;
700 if (ext_dbg_brk
!= -1)
701 xscale
->external_debug_break
= ext_dbg_brk
;
703 jtag_add_end_state(TAP_IDLE
);
704 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dcsr
);
706 buf_set_u32(&field0
, 1, 1, xscale
->hold_rst
);
707 buf_set_u32(&field0
, 2, 1, xscale
->external_debug_break
);
709 fields
[0].tap
= xscale
->jtag_info
.tap
;
710 fields
[0].num_bits
= 3;
711 fields
[0].out_value
= &field0
;
713 fields
[0].in_value
= &tmp
;
715 fields
[1].tap
= xscale
->jtag_info
.tap
;
716 fields
[1].num_bits
= 32;
717 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
718 fields
[1].in_value
= NULL
;
721 fields
[2].tap
= xscale
->jtag_info
.tap
;
722 fields
[2].num_bits
= 1;
723 fields
[2].out_value
= &field2
;
725 fields
[2].in_value
= &tmp2
;
727 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
729 jtag_check_value_mask(fields
+0, &field0_check_value
, &field0_check_mask
);
730 jtag_check_value_mask(fields
+2, &field2_check_value
, &field2_check_mask
);
732 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
734 LOG_ERROR("JTAG error while writing DCSR");
738 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].dirty
= 0;
739 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].valid
= 1;
744 /* parity of the number of bits 0 if even; 1 if odd. for 32 bit words */
745 unsigned int parity (unsigned int v
)
752 LOG_DEBUG("parity of 0x%x is %i", ov
, (0x6996 >> v
) & 1);
753 return (0x6996 >> v
) & 1;
756 int xscale_load_ic(target_t
*target
, int mini
, u32 va
, u32 buffer
[8])
758 armv4_5_common_t
*armv4_5
= target
->arch_info
;
759 xscale_common_t
*xscale
= armv4_5
->arch_info
;
764 scan_field_t fields
[2];
766 LOG_DEBUG("loading miniIC at 0x%8.8x", va
);
768 jtag_add_end_state(TAP_IDLE
);
769 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.ldic
); /* LDIC */
771 /* CMD is b010 for Main IC and b011 for Mini IC */
773 buf_set_u32(&cmd
, 0, 3, 0x3);
775 buf_set_u32(&cmd
, 0, 3, 0x2);
777 buf_set_u32(&cmd
, 3, 3, 0x0);
779 /* virtual address of desired cache line */
780 buf_set_u32(packet
, 0, 27, va
>> 5);
782 fields
[0].tap
= xscale
->jtag_info
.tap
;
783 fields
[0].num_bits
= 6;
784 fields
[0].out_value
= &cmd
;
786 fields
[0].in_value
= NULL
;
792 fields
[1].tap
= xscale
->jtag_info
.tap
;
793 fields
[1].num_bits
= 27;
794 fields
[1].out_value
= packet
;
796 fields
[1].in_value
= NULL
;
802 jtag_add_dr_scan(2, fields
, TAP_INVALID
);
804 fields
[0].num_bits
= 32;
805 fields
[0].out_value
= packet
;
807 fields
[1].num_bits
= 1;
808 fields
[1].out_value
= &cmd
;
810 for (word
= 0; word
< 8; word
++)
812 buf_set_u32(packet
, 0, 32, buffer
[word
]);
815 memcpy(&value
, packet
, sizeof(u32
));
818 jtag_add_dr_scan(2, fields
, TAP_INVALID
);
821 jtag_execute_queue();
826 int xscale_invalidate_ic_line(target_t
*target
, u32 va
)
828 armv4_5_common_t
*armv4_5
= target
->arch_info
;
829 xscale_common_t
*xscale
= armv4_5
->arch_info
;
833 scan_field_t fields
[2];
835 jtag_add_end_state(TAP_IDLE
);
836 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.ldic
); /* LDIC */
838 /* CMD for invalidate IC line b000, bits [6:4] b000 */
839 buf_set_u32(&cmd
, 0, 6, 0x0);
841 /* virtual address of desired cache line */
842 buf_set_u32(packet
, 0, 27, va
>> 5);
844 fields
[0].tap
= xscale
->jtag_info
.tap
;
845 fields
[0].num_bits
= 6;
846 fields
[0].out_value
= &cmd
;
848 fields
[0].in_value
= NULL
;
854 fields
[1].tap
= xscale
->jtag_info
.tap
;
855 fields
[1].num_bits
= 27;
856 fields
[1].out_value
= packet
;
858 fields
[1].in_value
= NULL
;
864 jtag_add_dr_scan(2, fields
, TAP_INVALID
);
869 int xscale_update_vectors(target_t
*target
)
871 armv4_5_common_t
*armv4_5
= target
->arch_info
;
872 xscale_common_t
*xscale
= armv4_5
->arch_info
;
876 u32 low_reset_branch
, high_reset_branch
;
878 for (i
= 1; i
< 8; i
++)
880 /* if there's a static vector specified for this exception, override */
881 if (xscale
->static_high_vectors_set
& (1 << i
))
883 xscale
->high_vectors
[i
] = xscale
->static_high_vectors
[i
];
887 retval
=target_read_u32(target
, 0xffff0000 + 4*i
, &xscale
->high_vectors
[i
]);
888 if (retval
== ERROR_TARGET_TIMEOUT
)
890 if (retval
!=ERROR_OK
)
892 /* Some of these reads will fail as part of normal execution */
893 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
898 for (i
= 1; i
< 8; i
++)
900 if (xscale
->static_low_vectors_set
& (1 << i
))
902 xscale
->low_vectors
[i
] = xscale
->static_low_vectors
[i
];
906 retval
=target_read_u32(target
, 0x0 + 4*i
, &xscale
->low_vectors
[i
]);
907 if (retval
== ERROR_TARGET_TIMEOUT
)
909 if (retval
!=ERROR_OK
)
911 /* Some of these reads will fail as part of normal execution */
912 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
917 /* calculate branches to debug handler */
918 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
919 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
921 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
922 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
924 /* invalidate and load exception vectors in mini i-cache */
925 xscale_invalidate_ic_line(target
, 0x0);
926 xscale_invalidate_ic_line(target
, 0xffff0000);
928 xscale_load_ic(target
, 1, 0x0, xscale
->low_vectors
);
929 xscale_load_ic(target
, 1, 0xffff0000, xscale
->high_vectors
);
934 int xscale_arch_state(struct target_s
*target
)
936 armv4_5_common_t
*armv4_5
= target
->arch_info
;
937 xscale_common_t
*xscale
= armv4_5
->arch_info
;
941 "disabled", "enabled"
944 char *arch_dbg_reason
[] =
946 "", "\n(processor reset)", "\n(trace buffer full)"
949 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
951 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
955 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
956 "cpsr: 0x%8.8x pc: 0x%8.8x\n"
957 "MMU: %s, D-Cache: %s, I-Cache: %s"
959 armv4_5_state_strings
[armv4_5
->core_state
],
960 Jim_Nvp_value2name_simple( nvp_target_debug_reason
, target
->debug_reason
)->name
,
961 armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)],
962 buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32),
963 buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32),
964 state
[xscale
->armv4_5_mmu
.mmu_enabled
],
965 state
[xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
],
966 state
[xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
],
967 arch_dbg_reason
[xscale
->arch_debug_reason
]);
972 int xscale_poll(target_t
*target
)
975 armv4_5_common_t
*armv4_5
= target
->arch_info
;
976 xscale_common_t
*xscale
= armv4_5
->arch_info
;
978 if ((target
->state
== TARGET_RUNNING
) || (target
->state
== TARGET_DEBUG_RUNNING
))
980 enum target_state previous_state
= target
->state
;
981 if ((retval
= xscale_read_tx(target
, 0)) == ERROR_OK
)
984 /* there's data to read from the tx register, we entered debug state */
985 xscale
->handler_running
= 1;
987 target
->state
= TARGET_HALTED
;
989 /* process debug entry, fetching current mode regs */
990 retval
= xscale_debug_entry(target
);
992 else if (retval
!= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
994 LOG_USER("error while polling TX register, reset CPU");
995 /* here we "lie" so GDB won't get stuck and a reset can be perfomed */
996 target
->state
= TARGET_HALTED
;
999 /* debug_entry could have overwritten target state (i.e. immediate resume)
1000 * don't signal event handlers in that case
1002 if (target
->state
!= TARGET_HALTED
)
1005 /* if target was running, signal that we halted
1006 * otherwise we reentered from debug execution */
1007 if (previous_state
== TARGET_RUNNING
)
1008 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1010 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
1016 int xscale_debug_entry(target_t
*target
)
1018 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1019 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1027 /* clear external dbg break (will be written on next DCSR read) */
1028 xscale
->external_debug_break
= 0;
1029 if ((retval
=xscale_read_dcsr(target
))!=ERROR_OK
)
1032 /* get r0, pc, r1 to r7 and cpsr */
1033 if ((retval
=xscale_receive(target
, buffer
, 10))!=ERROR_OK
)
1036 /* move r0 from buffer to register cache */
1037 buf_set_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32, buffer
[0]);
1038 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
1039 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
1040 LOG_DEBUG("r0: 0x%8.8x", buffer
[0]);
1042 /* move pc from buffer to register cache */
1043 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, buffer
[1]);
1044 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
1045 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
1046 LOG_DEBUG("pc: 0x%8.8x", buffer
[1]);
1048 /* move data from buffer to register cache */
1049 for (i
= 1; i
<= 7; i
++)
1051 buf_set_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32, buffer
[1 + i
]);
1052 armv4_5
->core_cache
->reg_list
[i
].dirty
= 1;
1053 armv4_5
->core_cache
->reg_list
[i
].valid
= 1;
1054 LOG_DEBUG("r%i: 0x%8.8x", i
, buffer
[i
+ 1]);
1057 buf_set_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32, buffer
[9]);
1058 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].dirty
= 1;
1059 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].valid
= 1;
1060 LOG_DEBUG("cpsr: 0x%8.8x", buffer
[9]);
1062 armv4_5
->core_mode
= buffer
[9] & 0x1f;
1063 if (armv4_5_mode_to_number(armv4_5
->core_mode
) == -1)
1065 target
->state
= TARGET_UNKNOWN
;
1066 LOG_ERROR("cpsr contains invalid mode value - communication failure");
1067 return ERROR_TARGET_FAILURE
;
1069 LOG_DEBUG("target entered debug state in %s mode", armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)]);
1071 if (buffer
[9] & 0x20)
1072 armv4_5
->core_state
= ARMV4_5_STATE_THUMB
;
1074 armv4_5
->core_state
= ARMV4_5_STATE_ARM
;
1077 if (armv4_5_mode_to_number(armv4_5
->core_mode
)==-1)
1080 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1081 if ((armv4_5
->core_mode
!= ARMV4_5_MODE_USR
) && (armv4_5
->core_mode
!= ARMV4_5_MODE_SYS
))
1083 xscale_receive(target
, buffer
, 8);
1084 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1085 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
1086 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
1090 /* r8 to r14, but no spsr */
1091 xscale_receive(target
, buffer
, 7);
1094 /* move data from buffer to register cache */
1095 for (i
= 8; i
<= 14; i
++)
1097 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).value
, 0, 32, buffer
[i
- 8]);
1098 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).dirty
= 0;
1099 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).valid
= 1;
1102 /* examine debug reason */
1103 xscale_read_dcsr(target
);
1104 moe
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 2, 3);
1106 /* stored PC (for calculating fixup) */
1107 pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1111 case 0x0: /* Processor reset */
1112 target
->debug_reason
= DBG_REASON_DBGRQ
;
1113 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_RESET
;
1116 case 0x1: /* Instruction breakpoint hit */
1117 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1118 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1121 case 0x2: /* Data breakpoint hit */
1122 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
1123 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1126 case 0x3: /* BKPT instruction executed */
1127 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1128 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1131 case 0x4: /* Ext. debug event */
1132 target
->debug_reason
= DBG_REASON_DBGRQ
;
1133 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1136 case 0x5: /* Vector trap occured */
1137 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1138 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1141 case 0x6: /* Trace buffer full break */
1142 target
->debug_reason
= DBG_REASON_DBGRQ
;
1143 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_TB_FULL
;
1146 case 0x7: /* Reserved */
1148 LOG_ERROR("Method of Entry is 'Reserved'");
1153 /* apply PC fixup */
1154 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, pc
);
1156 /* on the first debug entry, identify cache type */
1157 if (xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
1161 /* read cp15 cache type register */
1162 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
]);
1163 cache_type_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
].value
, 0, 32);
1165 armv4_5_identify_cache(cache_type_reg
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
1168 /* examine MMU and Cache settings */
1169 /* read cp15 control register */
1170 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
1171 xscale
->cp15_control_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
1172 xscale
->armv4_5_mmu
.mmu_enabled
= (xscale
->cp15_control_reg
& 0x1U
) ? 1 : 0;
1173 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= (xscale
->cp15_control_reg
& 0x4U
) ? 1 : 0;
1174 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= (xscale
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
1176 /* tracing enabled, read collected trace data */
1177 if (xscale
->trace
.buffer_enabled
)
1179 xscale_read_trace(target
);
1180 xscale
->trace
.buffer_fill
--;
1182 /* resume if we're still collecting trace data */
1183 if ((xscale
->arch_debug_reason
== XSCALE_DBG_REASON_TB_FULL
)
1184 && (xscale
->trace
.buffer_fill
> 0))
1186 xscale_resume(target
, 1, 0x0, 1, 0);
1190 xscale
->trace
.buffer_enabled
= 0;
1197 int xscale_halt(target_t
*target
)
1199 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1200 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1202 LOG_DEBUG("target->state: %s",
1203 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
1205 if (target
->state
== TARGET_HALTED
)
1207 LOG_DEBUG("target was already halted");
1210 else if (target
->state
== TARGET_UNKNOWN
)
1212 /* this must not happen for a xscale target */
1213 LOG_ERROR("target was in unknown state when halt was requested");
1214 return ERROR_TARGET_INVALID
;
1216 else if (target
->state
== TARGET_RESET
)
1218 LOG_DEBUG("target->state == TARGET_RESET");
1222 /* assert external dbg break */
1223 xscale
->external_debug_break
= 1;
1224 xscale_read_dcsr(target
);
1226 target
->debug_reason
= DBG_REASON_DBGRQ
;
1232 int xscale_enable_single_step(struct target_s
*target
, u32 next_pc
)
1234 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1235 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1236 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1239 if (xscale
->ibcr0_used
)
1241 breakpoint_t
*ibcr0_bp
= breakpoint_find(target
, buf_get_u32(ibcr0
->value
, 0, 32) & 0xfffffffe);
1245 xscale_unset_breakpoint(target
, ibcr0_bp
);
1249 LOG_ERROR("BUG: xscale->ibcr0_used is set, but no breakpoint with that address found");
1254 if ((retval
=xscale_set_reg_u32(ibcr0
, next_pc
| 0x1))!=ERROR_OK
)
1260 int xscale_disable_single_step(struct target_s
*target
)
1262 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1263 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1264 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1267 if ((retval
=xscale_set_reg_u32(ibcr0
, 0x0))!=ERROR_OK
)
1273 int xscale_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
1275 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1276 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1277 breakpoint_t
*breakpoint
= target
->breakpoints
;
1286 if (target
->state
!= TARGET_HALTED
)
1288 LOG_WARNING("target not halted");
1289 return ERROR_TARGET_NOT_HALTED
;
1292 if (!debug_execution
)
1294 target_free_all_working_areas(target
);
1297 /* update vector tables */
1298 if ((retval
=xscale_update_vectors(target
))!=ERROR_OK
)
1301 /* current = 1: continue on current pc, otherwise continue at <address> */
1303 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1305 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1307 /* if we're at the reset vector, we have to simulate the branch */
1308 if (current_pc
== 0x0)
1310 arm_simulate_step(target
, NULL
);
1311 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1314 /* the front-end may request us not to handle breakpoints */
1315 if (handle_breakpoints
)
1317 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1321 /* there's a breakpoint at the current PC, we have to step over it */
1322 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
1323 xscale_unset_breakpoint(target
, breakpoint
);
1325 /* calculate PC of next instruction */
1326 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1329 target_read_u32(target
, current_pc
, ¤t_opcode
);
1330 LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode
);
1333 LOG_DEBUG("enable single-step");
1334 xscale_enable_single_step(target
, next_pc
);
1336 /* restore banked registers */
1337 xscale_restore_context(target
);
1339 /* send resume request (command 0x30 or 0x31)
1340 * clean the trace buffer if it is to be enabled (0x62) */
1341 if (xscale
->trace
.buffer_enabled
)
1343 xscale_send_u32(target
, 0x62);
1344 xscale_send_u32(target
, 0x31);
1347 xscale_send_u32(target
, 0x30);
1350 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1351 LOG_DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1353 for (i
= 7; i
>= 0; i
--)
1356 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1357 LOG_DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1361 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1362 LOG_DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1364 /* wait for and process debug entry */
1365 xscale_debug_entry(target
);
1367 LOG_DEBUG("disable single-step");
1368 xscale_disable_single_step(target
);
1370 LOG_DEBUG("set breakpoint at 0x%8.8x", breakpoint
->address
);
1371 xscale_set_breakpoint(target
, breakpoint
);
1375 /* enable any pending breakpoints and watchpoints */
1376 xscale_enable_breakpoints(target
);
1377 xscale_enable_watchpoints(target
);
1379 /* restore banked registers */
1380 xscale_restore_context(target
);
1382 /* send resume request (command 0x30 or 0x31)
1383 * clean the trace buffer if it is to be enabled (0x62) */
1384 if (xscale
->trace
.buffer_enabled
)
1386 xscale_send_u32(target
, 0x62);
1387 xscale_send_u32(target
, 0x31);
1390 xscale_send_u32(target
, 0x30);
1393 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1394 LOG_DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1396 for (i
= 7; i
>= 0; i
--)
1399 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1400 LOG_DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1404 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1405 LOG_DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1407 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1409 if (!debug_execution
)
1411 /* registers are now invalid */
1412 armv4_5_invalidate_core_regs(target
);
1413 target
->state
= TARGET_RUNNING
;
1414 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1418 target
->state
= TARGET_DEBUG_RUNNING
;
1419 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1422 LOG_DEBUG("target resumed");
1424 xscale
->handler_running
= 1;
1429 static int xscale_step_inner(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
1431 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1432 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1438 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1440 /* calculate PC of next instruction */
1441 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1443 u32 current_opcode
, current_pc
;
1444 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1446 target_read_u32(target
, current_pc
, ¤t_opcode
);
1447 LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode
);
1451 LOG_DEBUG("enable single-step");
1452 if ((retval
=xscale_enable_single_step(target
, next_pc
))!=ERROR_OK
)
1455 /* restore banked registers */
1456 if ((retval
=xscale_restore_context(target
))!=ERROR_OK
)
1459 /* send resume request (command 0x30 or 0x31)
1460 * clean the trace buffer if it is to be enabled (0x62) */
1461 if (xscale
->trace
.buffer_enabled
)
1463 if ((retval
=xscale_send_u32(target
, 0x62))!=ERROR_OK
)
1465 if ((retval
=xscale_send_u32(target
, 0x31))!=ERROR_OK
)
1469 if ((retval
=xscale_send_u32(target
, 0x30))!=ERROR_OK
)
1473 if ((retval
=xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32)))!=ERROR_OK
)
1475 LOG_DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1477 for (i
= 7; i
>= 0; i
--)
1480 if ((retval
=xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32)))!=ERROR_OK
)
1482 LOG_DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1486 if ((retval
=xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32)))!=ERROR_OK
)
1488 LOG_DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1490 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1492 /* registers are now invalid */
1493 if ((retval
=armv4_5_invalidate_core_regs(target
))!=ERROR_OK
)
1496 /* wait for and process debug entry */
1497 if ((retval
=xscale_debug_entry(target
))!=ERROR_OK
)
1500 LOG_DEBUG("disable single-step");
1501 if ((retval
=xscale_disable_single_step(target
))!=ERROR_OK
)
1504 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1509 int xscale_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
1511 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1512 breakpoint_t
*breakpoint
= target
->breakpoints
;
1517 if (target
->state
!= TARGET_HALTED
)
1519 LOG_WARNING("target not halted");
1520 return ERROR_TARGET_NOT_HALTED
;
1523 /* current = 1: continue on current pc, otherwise continue at <address> */
1525 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1527 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1529 /* if we're at the reset vector, we have to simulate the step */
1530 if (current_pc
== 0x0)
1532 if ((retval
=arm_simulate_step(target
, NULL
))!=ERROR_OK
)
1534 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1536 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1537 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1542 /* the front-end may request us not to handle breakpoints */
1543 if (handle_breakpoints
)
1544 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1546 if ((retval
=xscale_unset_breakpoint(target
, breakpoint
))!=ERROR_OK
)
1550 retval
= xscale_step_inner(target
, current
, address
, handle_breakpoints
);
1554 xscale_set_breakpoint(target
, breakpoint
);
1557 LOG_DEBUG("target stepped");
1563 int xscale_assert_reset(target_t
*target
)
1565 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1566 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1568 LOG_DEBUG("target->state: %s",
1569 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
1571 /* select DCSR instruction (set endstate to R-T-I to ensure we don't
1572 * end up in T-L-R, which would reset JTAG
1574 jtag_add_end_state(TAP_IDLE
);
1575 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dcsr
);
1577 /* set Hold reset, Halt mode and Trap Reset */
1578 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1579 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1580 xscale_write_dcsr(target
, 1, 0);
1582 /* select BYPASS, because having DCSR selected caused problems on the PXA27x */
1583 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, 0x7f);
1584 jtag_execute_queue();
1587 jtag_add_reset(0, 1);
1589 /* sleep 1ms, to be sure we fulfill any requirements */
1590 jtag_add_sleep(1000);
1591 jtag_execute_queue();
1593 target
->state
= TARGET_RESET
;
1595 if (target
->reset_halt
)
1598 if ((retval
= target_halt(target
))!=ERROR_OK
)
1605 int xscale_deassert_reset(target_t
*target
)
1607 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1608 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1610 fileio_t debug_handler
;
1618 breakpoint_t
*breakpoint
= target
->breakpoints
;
1622 xscale
->ibcr_available
= 2;
1623 xscale
->ibcr0_used
= 0;
1624 xscale
->ibcr1_used
= 0;
1626 xscale
->dbr_available
= 2;
1627 xscale
->dbr0_used
= 0;
1628 xscale
->dbr1_used
= 0;
1630 /* mark all hardware breakpoints as unset */
1633 if (breakpoint
->type
== BKPT_HARD
)
1635 breakpoint
->set
= 0;
1637 breakpoint
= breakpoint
->next
;
1640 if (!xscale
->handler_installed
)
1643 jtag_add_reset(0, 0);
1645 /* wait 300ms; 150 and 100ms were not enough */
1646 jtag_add_sleep(300*1000);
1648 jtag_add_runtest(2030, TAP_IDLE
);
1649 jtag_execute_queue();
1651 /* set Hold reset, Halt mode and Trap Reset */
1652 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1653 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1654 xscale_write_dcsr(target
, 1, 0);
1656 /* Load debug handler */
1657 if (fileio_open(&debug_handler
, "xscale/debug_handler.bin", FILEIO_READ
, FILEIO_BINARY
) != ERROR_OK
)
1662 if ((binary_size
= debug_handler
.size
) % 4)
1664 LOG_ERROR("debug_handler.bin: size not a multiple of 4");
1668 if (binary_size
> 0x800)
1670 LOG_ERROR("debug_handler.bin: larger than 2kb");
1674 binary_size
= CEIL(binary_size
, 32) * 32;
1676 address
= xscale
->handler_address
;
1677 while (binary_size
> 0)
1682 if ((retval
= fileio_read(&debug_handler
, 32, buffer
, &buf_cnt
)) != ERROR_OK
)
1687 for (i
= 0; i
< buf_cnt
; i
+= 4)
1689 /* convert LE buffer to host-endian u32 */
1690 cache_line
[i
/ 4] = le_to_h_u32(&buffer
[i
]);
1693 for (; buf_cnt
< 32; buf_cnt
+= 4)
1695 cache_line
[buf_cnt
/ 4] = 0xe1a08008;
1698 /* only load addresses other than the reset vectors */
1699 if ((address
% 0x400) != 0x0)
1701 xscale_load_ic(target
, 1, address
, cache_line
);
1705 binary_size
-= buf_cnt
;
1708 xscale_load_ic(target
, 1, 0x0, xscale
->low_vectors
);
1709 xscale_load_ic(target
, 1, 0xffff0000, xscale
->high_vectors
);
1711 jtag_add_runtest(30, TAP_IDLE
);
1713 jtag_add_sleep(100000);
1715 /* set Hold reset, Halt mode and Trap Reset */
1716 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1717 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1718 xscale_write_dcsr(target
, 1, 0);
1720 /* clear Hold reset to let the target run (should enter debug handler) */
1721 xscale_write_dcsr(target
, 0, 1);
1722 target
->state
= TARGET_RUNNING
;
1724 if (!target
->reset_halt
)
1726 jtag_add_sleep(10000);
1728 /* we should have entered debug now */
1729 xscale_debug_entry(target
);
1730 target
->state
= TARGET_HALTED
;
1732 /* resume the target */
1733 xscale_resume(target
, 1, 0x0, 1, 0);
1736 fileio_close(&debug_handler
);
1740 jtag_add_reset(0, 0);
1746 int xscale_soft_reset_halt(struct target_s
*target
)
1751 int xscale_read_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
)
1756 int xscale_write_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
, u32 value
)
1762 int xscale_full_context(target_t
*target
)
1764 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1772 if (target
->state
!= TARGET_HALTED
)
1774 LOG_WARNING("target not halted");
1775 return ERROR_TARGET_NOT_HALTED
;
1778 buffer
= malloc(4 * 8);
1780 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1781 * we can't enter User mode on an XScale (unpredictable),
1782 * but User shares registers with SYS
1784 for(i
= 1; i
< 7; i
++)
1788 /* check if there are invalid registers in the current mode
1790 for (j
= 0; j
<= 16; j
++)
1792 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
== 0)
1800 /* request banked registers */
1801 xscale_send_u32(target
, 0x0);
1804 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1805 tmp_cpsr
|= 0xc0; /* I/F bits */
1807 /* send CPSR for desired mode */
1808 xscale_send_u32(target
, tmp_cpsr
);
1810 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1811 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1813 xscale_receive(target
, buffer
, 8);
1814 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1815 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1816 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).valid
= 1;
1820 xscale_receive(target
, buffer
, 7);
1823 /* move data from buffer to register cache */
1824 for (j
= 8; j
<= 14; j
++)
1826 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]);
1827 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1828 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
= 1;
1838 int xscale_restore_context(target_t
*target
)
1840 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1846 if (target
->state
!= TARGET_HALTED
)
1848 LOG_WARNING("target not halted");
1849 return ERROR_TARGET_NOT_HALTED
;
1852 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1853 * we can't enter User mode on an XScale (unpredictable),
1854 * but User shares registers with SYS
1856 for(i
= 1; i
< 7; i
++)
1860 /* check if there are invalid registers in the current mode
1862 for (j
= 8; j
<= 14; j
++)
1864 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
== 1)
1868 /* if not USR/SYS, check if the SPSR needs to be written */
1869 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1871 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
== 1)
1879 /* send banked registers */
1880 xscale_send_u32(target
, 0x1);
1883 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1884 tmp_cpsr
|= 0xc0; /* I/F bits */
1886 /* send CPSR for desired mode */
1887 xscale_send_u32(target
, tmp_cpsr
);
1889 /* send banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1890 for (j
= 8; j
<= 14; j
++)
1892 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, j
).value
, 0, 32));
1893 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1896 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1898 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32));
1899 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1907 int xscale_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1909 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1910 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1915 LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address
, size
, count
);
1917 if (target
->state
!= TARGET_HALTED
)
1919 LOG_WARNING("target not halted");
1920 return ERROR_TARGET_NOT_HALTED
;
1923 /* sanitize arguments */
1924 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1925 return ERROR_INVALID_ARGUMENTS
;
1927 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1928 return ERROR_TARGET_UNALIGNED_ACCESS
;
1930 /* send memory read request (command 0x1n, n: access size) */
1931 if ((retval
=xscale_send_u32(target
, 0x10 | size
))!=ERROR_OK
)
1934 /* send base address for read request */
1935 if ((retval
=xscale_send_u32(target
, address
))!=ERROR_OK
)
1938 /* send number of requested data words */
1939 if ((retval
=xscale_send_u32(target
, count
))!=ERROR_OK
)
1942 /* receive data from target (count times 32-bit words in host endianness) */
1943 buf32
= malloc(4 * count
);
1944 if ((retval
=xscale_receive(target
, buf32
, count
))!=ERROR_OK
)
1947 /* extract data from host-endian buffer into byte stream */
1948 for (i
= 0; i
< count
; i
++)
1953 target_buffer_set_u32(target
, buffer
, buf32
[i
]);
1957 target_buffer_set_u16(target
, buffer
, buf32
[i
] & 0xffff);
1961 *buffer
++ = buf32
[i
] & 0xff;
1964 LOG_ERROR("should never get here");
1971 /* examine DCSR, to see if Sticky Abort (SA) got set */
1972 if ((retval
=xscale_read_dcsr(target
))!=ERROR_OK
)
1974 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
1977 if ((retval
=xscale_send_u32(target
, 0x60))!=ERROR_OK
)
1980 return ERROR_TARGET_DATA_ABORT
;
1986 int xscale_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1988 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1989 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1992 LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address
, size
, count
);
1994 if (target
->state
!= TARGET_HALTED
)
1996 LOG_WARNING("target not halted");
1997 return ERROR_TARGET_NOT_HALTED
;
2000 /* sanitize arguments */
2001 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
2002 return ERROR_INVALID_ARGUMENTS
;
2004 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
2005 return ERROR_TARGET_UNALIGNED_ACCESS
;
2007 /* send memory write request (command 0x2n, n: access size) */
2008 if ((retval
=xscale_send_u32(target
, 0x20 | size
))!=ERROR_OK
)
2011 /* send base address for read request */
2012 if ((retval
=xscale_send_u32(target
, address
))!=ERROR_OK
)
2015 /* send number of requested data words to be written*/
2016 if ((retval
=xscale_send_u32(target
, count
))!=ERROR_OK
)
2019 /* extract data from host-endian buffer into byte stream */
2021 for (i
= 0; i
< count
; i
++)
2026 value
= target_buffer_get_u32(target
, buffer
);
2027 xscale_send_u32(target
, value
);
2031 value
= target_buffer_get_u16(target
, buffer
);
2032 xscale_send_u32(target
, value
);
2037 xscale_send_u32(target
, value
);
2041 LOG_ERROR("should never get here");
2046 if ((retval
=xscale_send(target
, buffer
, count
, size
))!=ERROR_OK
)
2049 /* examine DCSR, to see if Sticky Abort (SA) got set */
2050 if ((retval
=xscale_read_dcsr(target
))!=ERROR_OK
)
2052 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
2055 if ((retval
=xscale_send_u32(target
, 0x60))!=ERROR_OK
)
2058 return ERROR_TARGET_DATA_ABORT
;
2064 int xscale_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
2066 return xscale_write_memory(target
, address
, 4, count
, buffer
);
2069 u32
xscale_get_ttb(target_t
*target
)
2071 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2072 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2075 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_TTB
]);
2076 ttb
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_TTB
].value
, 0, 32);
2081 void xscale_disable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
2083 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2084 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2087 /* read cp15 control register */
2088 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2089 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2092 cp15_control
&= ~0x1U
;
2097 xscale_send_u32(target
, 0x50);
2098 xscale_send_u32(target
, xscale
->cache_clean_address
);
2100 /* invalidate DCache */
2101 xscale_send_u32(target
, 0x51);
2103 cp15_control
&= ~0x4U
;
2108 /* invalidate ICache */
2109 xscale_send_u32(target
, 0x52);
2110 cp15_control
&= ~0x1000U
;
2113 /* write new cp15 control register */
2114 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2116 /* execute cpwait to ensure outstanding operations complete */
2117 xscale_send_u32(target
, 0x53);
2120 void xscale_enable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
2122 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2123 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2126 /* read cp15 control register */
2127 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2128 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2131 cp15_control
|= 0x1U
;
2134 cp15_control
|= 0x4U
;
2137 cp15_control
|= 0x1000U
;
2139 /* write new cp15 control register */
2140 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2142 /* execute cpwait to ensure outstanding operations complete */
2143 xscale_send_u32(target
, 0x53);
2146 int xscale_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2149 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2150 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2152 if (target
->state
!= TARGET_HALTED
)
2154 LOG_WARNING("target not halted");
2155 return ERROR_TARGET_NOT_HALTED
;
2158 if (breakpoint
->set
)
2160 LOG_WARNING("breakpoint already set");
2164 if (breakpoint
->type
== BKPT_HARD
)
2166 u32 value
= breakpoint
->address
| 1;
2167 if (!xscale
->ibcr0_used
)
2169 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], value
);
2170 xscale
->ibcr0_used
= 1;
2171 breakpoint
->set
= 1; /* breakpoint set on first breakpoint register */
2173 else if (!xscale
->ibcr1_used
)
2175 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], value
);
2176 xscale
->ibcr1_used
= 1;
2177 breakpoint
->set
= 2; /* breakpoint set on second breakpoint register */
2181 LOG_ERROR("BUG: no hardware comparator available");
2185 else if (breakpoint
->type
== BKPT_SOFT
)
2187 if (breakpoint
->length
== 4)
2189 /* keep the original instruction in target endianness */
2190 if((retval
= target
->type
->read_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
2194 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2195 if((retval
= target_write_u32(target
, breakpoint
->address
, xscale
->arm_bkpt
)) != ERROR_OK
)
2202 /* keep the original instruction in target endianness */
2203 if((retval
= target
->type
->read_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
2207 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2208 if((retval
= target_write_u32(target
, breakpoint
->address
, xscale
->thumb_bkpt
)) != ERROR_OK
)
2213 breakpoint
->set
= 1;
2219 int xscale_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2221 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2222 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2224 if (target
->state
!= TARGET_HALTED
)
2226 LOG_WARNING("target not halted");
2227 return ERROR_TARGET_NOT_HALTED
;
2230 if ((breakpoint
->type
== BKPT_HARD
) && (xscale
->ibcr_available
< 1))
2232 LOG_INFO("no breakpoint unit available for hardware breakpoint");
2233 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2236 if ((breakpoint
->length
!= 2) && (breakpoint
->length
!= 4))
2238 LOG_INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
2239 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2242 if (breakpoint
->type
== BKPT_HARD
)
2244 xscale
->ibcr_available
--;
2250 int xscale_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2253 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2254 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2256 if (target
->state
!= TARGET_HALTED
)
2258 LOG_WARNING("target not halted");
2259 return ERROR_TARGET_NOT_HALTED
;
2262 if (!breakpoint
->set
)
2264 LOG_WARNING("breakpoint not set");
2268 if (breakpoint
->type
== BKPT_HARD
)
2270 if (breakpoint
->set
== 1)
2272 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], 0x0);
2273 xscale
->ibcr0_used
= 0;
2275 else if (breakpoint
->set
== 2)
2277 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], 0x0);
2278 xscale
->ibcr1_used
= 0;
2280 breakpoint
->set
= 0;
2284 /* restore original instruction (kept in target endianness) */
2285 if (breakpoint
->length
== 4)
2287 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
2294 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
2299 breakpoint
->set
= 0;
2305 int xscale_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2307 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2308 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2310 if (target
->state
!= TARGET_HALTED
)
2312 LOG_WARNING("target not halted");
2313 return ERROR_TARGET_NOT_HALTED
;
2316 if (breakpoint
->set
)
2318 xscale_unset_breakpoint(target
, breakpoint
);
2321 if (breakpoint
->type
== BKPT_HARD
)
2322 xscale
->ibcr_available
++;
2327 int xscale_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2329 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2330 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2332 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2333 u32 dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2335 if (target
->state
!= TARGET_HALTED
)
2337 LOG_WARNING("target not halted");
2338 return ERROR_TARGET_NOT_HALTED
;
2341 xscale_get_reg(dbcon
);
2343 switch (watchpoint
->rw
)
2355 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
2358 if (!xscale
->dbr0_used
)
2360 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR0
], watchpoint
->address
);
2361 dbcon_value
|= enable
;
2362 xscale_set_reg_u32(dbcon
, dbcon_value
);
2363 watchpoint
->set
= 1;
2364 xscale
->dbr0_used
= 1;
2366 else if (!xscale
->dbr1_used
)
2368 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR1
], watchpoint
->address
);
2369 dbcon_value
|= enable
<< 2;
2370 xscale_set_reg_u32(dbcon
, dbcon_value
);
2371 watchpoint
->set
= 2;
2372 xscale
->dbr1_used
= 1;
2376 LOG_ERROR("BUG: no hardware comparator available");
2383 int xscale_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2385 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2386 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2388 if (target
->state
!= TARGET_HALTED
)
2390 LOG_WARNING("target not halted");
2391 return ERROR_TARGET_NOT_HALTED
;
2394 if (xscale
->dbr_available
< 1)
2396 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2399 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
2401 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2404 xscale
->dbr_available
--;
2409 int xscale_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2411 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2412 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2413 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2414 u32 dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2416 if (target
->state
!= TARGET_HALTED
)
2418 LOG_WARNING("target not halted");
2419 return ERROR_TARGET_NOT_HALTED
;
2422 if (!watchpoint
->set
)
2424 LOG_WARNING("breakpoint not set");
2428 if (watchpoint
->set
== 1)
2430 dbcon_value
&= ~0x3;
2431 xscale_set_reg_u32(dbcon
, dbcon_value
);
2432 xscale
->dbr0_used
= 0;
2434 else if (watchpoint
->set
== 2)
2436 dbcon_value
&= ~0xc;
2437 xscale_set_reg_u32(dbcon
, dbcon_value
);
2438 xscale
->dbr1_used
= 0;
2440 watchpoint
->set
= 0;
2445 int xscale_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2447 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2448 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2450 if (target
->state
!= TARGET_HALTED
)
2452 LOG_WARNING("target not halted");
2453 return ERROR_TARGET_NOT_HALTED
;
2456 if (watchpoint
->set
)
2458 xscale_unset_watchpoint(target
, watchpoint
);
2461 xscale
->dbr_available
++;
2466 void xscale_enable_watchpoints(struct target_s
*target
)
2468 watchpoint_t
*watchpoint
= target
->watchpoints
;
2472 if (watchpoint
->set
== 0)
2473 xscale_set_watchpoint(target
, watchpoint
);
2474 watchpoint
= watchpoint
->next
;
2478 void xscale_enable_breakpoints(struct target_s
*target
)
2480 breakpoint_t
*breakpoint
= target
->breakpoints
;
2482 /* set any pending breakpoints */
2485 if (breakpoint
->set
== 0)
2486 xscale_set_breakpoint(target
, breakpoint
);
2487 breakpoint
= breakpoint
->next
;
2491 int xscale_get_reg(reg_t
*reg
)
2493 xscale_reg_t
*arch_info
= reg
->arch_info
;
2494 target_t
*target
= arch_info
->target
;
2495 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2496 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2498 /* DCSR, TX and RX are accessible via JTAG */
2499 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2501 return xscale_read_dcsr(arch_info
->target
);
2503 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2505 /* 1 = consume register content */
2506 return xscale_read_tx(arch_info
->target
, 1);
2508 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2510 /* can't read from RX register (host -> debug handler) */
2513 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2515 /* can't (explicitly) read from TXRXCTRL register */
2518 else /* Other DBG registers have to be transfered by the debug handler */
2520 /* send CP read request (command 0x40) */
2521 xscale_send_u32(target
, 0x40);
2523 /* send CP register number */
2524 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2526 /* read register value */
2527 xscale_read_tx(target
, 1);
2528 buf_cpy(xscale
->reg_cache
->reg_list
[XSCALE_TX
].value
, reg
->value
, 32);
2537 int xscale_set_reg(reg_t
*reg
, u8
* buf
)
2539 xscale_reg_t
*arch_info
= reg
->arch_info
;
2540 target_t
*target
= arch_info
->target
;
2541 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2542 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2543 u32 value
= buf_get_u32(buf
, 0, 32);
2545 /* DCSR, TX and RX are accessible via JTAG */
2546 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2548 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32, value
);
2549 return xscale_write_dcsr(arch_info
->target
, -1, -1);
2551 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2553 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
2554 return xscale_write_rx(arch_info
->target
);
2556 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2558 /* can't write to TX register (debug-handler -> host) */
2561 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2563 /* can't (explicitly) write to TXRXCTRL register */
2566 else /* Other DBG registers have to be transfered by the debug handler */
2568 /* send CP write request (command 0x41) */
2569 xscale_send_u32(target
, 0x41);
2571 /* send CP register number */
2572 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2574 /* send CP register value */
2575 xscale_send_u32(target
, value
);
2576 buf_set_u32(reg
->value
, 0, 32, value
);
2582 /* convenience wrapper to access XScale specific registers */
2583 int xscale_set_reg_u32(reg_t
*reg
, u32 value
)
2587 buf_set_u32(buf
, 0, 32, value
);
2589 return xscale_set_reg(reg
, buf
);
2592 int xscale_write_dcsr_sw(target_t
*target
, u32 value
)
2594 /* get pointers to arch-specific information */
2595 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2596 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2597 reg_t
*dcsr
= &xscale
->reg_cache
->reg_list
[XSCALE_DCSR
];
2598 xscale_reg_t
*dcsr_arch_info
= dcsr
->arch_info
;
2600 /* send CP write request (command 0x41) */
2601 xscale_send_u32(target
, 0x41);
2603 /* send CP register number */
2604 xscale_send_u32(target
, dcsr_arch_info
->dbg_handler_number
);
2606 /* send CP register value */
2607 xscale_send_u32(target
, value
);
2608 buf_set_u32(dcsr
->value
, 0, 32, value
);
2613 int xscale_read_trace(target_t
*target
)
2615 /* get pointers to arch-specific information */
2616 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2617 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2618 xscale_trace_data_t
**trace_data_p
;
2620 /* 258 words from debug handler
2621 * 256 trace buffer entries
2622 * 2 checkpoint addresses
2624 u32 trace_buffer
[258];
2625 int is_address
[256];
2628 if (target
->state
!= TARGET_HALTED
)
2630 LOG_WARNING("target must be stopped to read trace data");
2631 return ERROR_TARGET_NOT_HALTED
;
2634 /* send read trace buffer command (command 0x61) */
2635 xscale_send_u32(target
, 0x61);
2637 /* receive trace buffer content */
2638 xscale_receive(target
, trace_buffer
, 258);
2640 /* parse buffer backwards to identify address entries */
2641 for (i
= 255; i
>= 0; i
--)
2644 if (((trace_buffer
[i
] & 0xf0) == 0x90) ||
2645 ((trace_buffer
[i
] & 0xf0) == 0xd0))
2648 is_address
[--i
] = 1;
2650 is_address
[--i
] = 1;
2652 is_address
[--i
] = 1;
2654 is_address
[--i
] = 1;
2659 /* search first non-zero entry */
2660 for (j
= 0; (j
< 256) && (trace_buffer
[j
] == 0) && (!is_address
[j
]); j
++)
2665 LOG_DEBUG("no trace data collected");
2666 return ERROR_XSCALE_NO_TRACE_DATA
;
2669 for (trace_data_p
= &xscale
->trace
.data
; *trace_data_p
; trace_data_p
= &(*trace_data_p
)->next
)
2672 *trace_data_p
= malloc(sizeof(xscale_trace_data_t
));
2673 (*trace_data_p
)->next
= NULL
;
2674 (*trace_data_p
)->chkpt0
= trace_buffer
[256];
2675 (*trace_data_p
)->chkpt1
= trace_buffer
[257];
2676 (*trace_data_p
)->last_instruction
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
2677 (*trace_data_p
)->entries
= malloc(sizeof(xscale_trace_entry_t
) * (256 - j
));
2678 (*trace_data_p
)->depth
= 256 - j
;
2680 for (i
= j
; i
< 256; i
++)
2682 (*trace_data_p
)->entries
[i
- j
].data
= trace_buffer
[i
];
2684 (*trace_data_p
)->entries
[i
- j
].type
= XSCALE_TRACE_ADDRESS
;
2686 (*trace_data_p
)->entries
[i
- j
].type
= XSCALE_TRACE_MESSAGE
;
2692 int xscale_read_instruction(target_t
*target
, arm_instruction_t
*instruction
)
2694 /* get pointers to arch-specific information */
2695 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2696 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2703 if (!xscale
->trace
.image
)
2704 return ERROR_TRACE_IMAGE_UNAVAILABLE
;
2706 /* search for the section the current instruction belongs to */
2707 for (i
= 0; i
< xscale
->trace
.image
->num_sections
; i
++)
2709 if ((xscale
->trace
.image
->sections
[i
].base_address
<= xscale
->trace
.current_pc
) &&
2710 (xscale
->trace
.image
->sections
[i
].base_address
+ xscale
->trace
.image
->sections
[i
].size
> xscale
->trace
.current_pc
))
2719 /* current instruction couldn't be found in the image */
2720 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2723 if (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
)
2726 if ((retval
= image_read_section(xscale
->trace
.image
, section
,
2727 xscale
->trace
.current_pc
- xscale
->trace
.image
->sections
[section
].base_address
,
2728 4, buf
, &size_read
)) != ERROR_OK
)
2730 LOG_ERROR("error while reading instruction: %i", retval
);
2731 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2733 opcode
= target_buffer_get_u32(target
, buf
);
2734 arm_evaluate_opcode(opcode
, xscale
->trace
.current_pc
, instruction
);
2736 else if (xscale
->trace
.core_state
== ARMV4_5_STATE_THUMB
)
2739 if ((retval
= image_read_section(xscale
->trace
.image
, section
,
2740 xscale
->trace
.current_pc
- xscale
->trace
.image
->sections
[section
].base_address
,
2741 2, buf
, &size_read
)) != ERROR_OK
)
2743 LOG_ERROR("error while reading instruction: %i", retval
);
2744 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2746 opcode
= target_buffer_get_u16(target
, buf
);
2747 thumb_evaluate_opcode(opcode
, xscale
->trace
.current_pc
, instruction
);
2751 LOG_ERROR("BUG: unknown core state encountered");
2758 int xscale_branch_address(xscale_trace_data_t
*trace_data
, int i
, u32
*target
)
2760 /* if there are less than four entries prior to the indirect branch message
2761 * we can't extract the address */
2767 *target
= (trace_data
->entries
[i
-1].data
) | (trace_data
->entries
[i
-2].data
<< 8) |
2768 (trace_data
->entries
[i
-3].data
<< 16) | (trace_data
->entries
[i
-4].data
<< 24);
2773 int xscale_analyze_trace(target_t
*target
, command_context_t
*cmd_ctx
)
2775 /* get pointers to arch-specific information */
2776 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2777 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2780 xscale_trace_data_t
*trace_data
= xscale
->trace
.data
;
2789 xscale
->trace
.core_state
= ARMV4_5_STATE_ARM
;
2794 for (i
= 0; i
< trace_data
->depth
; i
++)
2800 if (trace_data
->entries
[i
].type
== XSCALE_TRACE_ADDRESS
)
2803 switch ((trace_data
->entries
[i
].data
& 0xf0) >> 4)
2805 case 0: /* Exceptions */
2813 exception
= (trace_data
->entries
[i
].data
& 0x70) >> 4;
2815 next_pc
= (trace_data
->entries
[i
].data
& 0xf0) >> 2;
2816 command_print(cmd_ctx
, "--- exception %i ---", (trace_data
->entries
[i
].data
& 0xf0) >> 4);
2818 case 8: /* Direct Branch */
2821 case 9: /* Indirect Branch */
2823 if (xscale_branch_address(trace_data
, i
, &next_pc
) == 0)
2828 case 13: /* Checkpointed Indirect Branch */
2829 if (xscale_branch_address(trace_data
, i
, &next_pc
) == 0)
2832 if (((chkpt
== 0) && (next_pc
!= trace_data
->chkpt0
))
2833 || ((chkpt
== 1) && (next_pc
!= trace_data
->chkpt1
)))
2834 LOG_WARNING("checkpointed indirect branch target address doesn't match checkpoint");
2836 /* explicit fall-through */
2837 case 12: /* Checkpointed Direct Branch */
2842 next_pc
= trace_data
->chkpt0
;
2845 else if (chkpt
== 1)
2848 next_pc
= trace_data
->chkpt0
;
2853 LOG_WARNING("more than two checkpointed branches encountered");
2856 case 15: /* Roll-over */
2859 default: /* Reserved */
2860 command_print(cmd_ctx
, "--- reserved trace message ---");
2861 LOG_ERROR("BUG: trace message %i is reserved", (trace_data
->entries
[i
].data
& 0xf0) >> 4);
2865 if (xscale
->trace
.pc_ok
)
2867 int executed
= (trace_data
->entries
[i
].data
& 0xf) + rollover
* 16;
2868 arm_instruction_t instruction
;
2870 if ((exception
== 6) || (exception
== 7))
2872 /* IRQ or FIQ exception, no instruction executed */
2876 while (executed
-- >= 0)
2878 if ((retval
= xscale_read_instruction(target
, &instruction
)) != ERROR_OK
)
2880 /* can't continue tracing with no image available */
2881 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
2885 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
2887 /* TODO: handle incomplete images */
2891 /* a precise abort on a load to the PC is included in the incremental
2892 * word count, other instructions causing data aborts are not included
2894 if ((executed
== 0) && (exception
== 4)
2895 && ((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_LDM
)))
2897 if ((instruction
.type
== ARM_LDM
)
2898 && ((instruction
.info
.load_store_multiple
.register_list
& 0x8000) == 0))
2902 else if (((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_LDRSH
))
2903 && (instruction
.info
.load_store
.Rd
!= 15))
2909 /* only the last instruction executed
2910 * (the one that caused the control flow change)
2911 * could be a taken branch
2913 if (((executed
== -1) && (branch
== 1)) &&
2914 (((instruction
.type
== ARM_B
) ||
2915 (instruction
.type
== ARM_BL
) ||
2916 (instruction
.type
== ARM_BLX
)) &&
2917 (instruction
.info
.b_bl_bx_blx
.target_address
!= 0xffffffff)))
2919 xscale
->trace
.current_pc
= instruction
.info
.b_bl_bx_blx
.target_address
;
2923 xscale
->trace
.current_pc
+= (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2;
2925 command_print(cmd_ctx
, "%s", instruction
.text
);
2933 xscale
->trace
.current_pc
= next_pc
;
2934 xscale
->trace
.pc_ok
= 1;
2938 for (; xscale
->trace
.current_pc
< trace_data
->last_instruction
; xscale
->trace
.current_pc
+= (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2)
2940 arm_instruction_t instruction
;
2941 if ((retval
= xscale_read_instruction(target
, &instruction
)) != ERROR_OK
)
2943 /* can't continue tracing with no image available */
2944 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
2948 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
2950 /* TODO: handle incomplete images */
2953 command_print(cmd_ctx
, "%s", instruction
.text
);
2956 trace_data
= trace_data
->next
;
2962 void xscale_build_reg_cache(target_t
*target
)
2964 /* get pointers to arch-specific information */
2965 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2966 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2968 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
2969 xscale_reg_t
*arch_info
= malloc(sizeof(xscale_reg_arch_info
));
2971 int num_regs
= sizeof(xscale_reg_arch_info
) / sizeof(xscale_reg_t
);
2973 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
2974 armv4_5
->core_cache
= (*cache_p
);
2976 /* register a register arch-type for XScale dbg registers only once */
2977 if (xscale_reg_arch_type
== -1)
2978 xscale_reg_arch_type
= register_reg_arch_type(xscale_get_reg
, xscale_set_reg
);
2980 (*cache_p
)->next
= malloc(sizeof(reg_cache_t
));
2981 cache_p
= &(*cache_p
)->next
;
2983 /* fill in values for the xscale reg cache */
2984 (*cache_p
)->name
= "XScale registers";
2985 (*cache_p
)->next
= NULL
;
2986 (*cache_p
)->reg_list
= malloc(num_regs
* sizeof(reg_t
));
2987 (*cache_p
)->num_regs
= num_regs
;
2989 for (i
= 0; i
< num_regs
; i
++)
2991 (*cache_p
)->reg_list
[i
].name
= xscale_reg_list
[i
];
2992 (*cache_p
)->reg_list
[i
].value
= calloc(4, 1);
2993 (*cache_p
)->reg_list
[i
].dirty
= 0;
2994 (*cache_p
)->reg_list
[i
].valid
= 0;
2995 (*cache_p
)->reg_list
[i
].size
= 32;
2996 (*cache_p
)->reg_list
[i
].bitfield_desc
= NULL
;
2997 (*cache_p
)->reg_list
[i
].num_bitfields
= 0;
2998 (*cache_p
)->reg_list
[i
].arch_info
= &arch_info
[i
];
2999 (*cache_p
)->reg_list
[i
].arch_type
= xscale_reg_arch_type
;
3000 arch_info
[i
] = xscale_reg_arch_info
[i
];
3001 arch_info
[i
].target
= target
;
3004 xscale
->reg_cache
= (*cache_p
);
3007 int xscale_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
3012 int xscale_quit(void)
3017 int xscale_init_arch_info(target_t
*target
, xscale_common_t
*xscale
, jtag_tap_t
*tap
, const char *variant
)
3019 armv4_5_common_t
*armv4_5
;
3020 u32 high_reset_branch
, low_reset_branch
;
3023 armv4_5
= &xscale
->armv4_5_common
;
3025 /* store architecture specfic data (none so far) */
3026 xscale
->arch_info
= NULL
;
3027 xscale
->common_magic
= XSCALE_COMMON_MAGIC
;
3029 /* remember the variant (PXA25x, PXA27x, IXP42x, ...) */
3030 xscale
->variant
= strdup(variant
);
3032 /* prepare JTAG information for the new target */
3033 xscale
->jtag_info
.tap
= tap
;
3035 xscale
->jtag_info
.dbgrx
= 0x02;
3036 xscale
->jtag_info
.dbgtx
= 0x10;
3037 xscale
->jtag_info
.dcsr
= 0x09;
3038 xscale
->jtag_info
.ldic
= 0x07;
3040 if ((strcmp(xscale
->variant
, "pxa250") == 0) ||
3041 (strcmp(xscale
->variant
, "pxa255") == 0) ||
3042 (strcmp(xscale
->variant
, "pxa26x") == 0))
3044 xscale
->jtag_info
.ir_length
= 5;
3046 else if ((strcmp(xscale
->variant
, "pxa27x") == 0) ||
3047 (strcmp(xscale
->variant
, "ixp42x") == 0) ||
3048 (strcmp(xscale
->variant
, "ixp45x") == 0) ||
3049 (strcmp(xscale
->variant
, "ixp46x") == 0))
3051 xscale
->jtag_info
.ir_length
= 7;
3054 /* the debug handler isn't installed (and thus not running) at this time */
3055 xscale
->handler_installed
= 0;
3056 xscale
->handler_running
= 0;
3057 xscale
->handler_address
= 0xfe000800;
3059 /* clear the vectors we keep locally for reference */
3060 memset(xscale
->low_vectors
, 0, sizeof(xscale
->low_vectors
));
3061 memset(xscale
->high_vectors
, 0, sizeof(xscale
->high_vectors
));
3063 /* no user-specified vectors have been configured yet */
3064 xscale
->static_low_vectors_set
= 0x0;
3065 xscale
->static_high_vectors_set
= 0x0;
3067 /* calculate branches to debug handler */
3068 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
3069 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
3071 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
3072 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
3074 for (i
= 1; i
<= 7; i
++)
3076 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
3077 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
3080 /* 64kB aligned region used for DCache cleaning */
3081 xscale
->cache_clean_address
= 0xfffe0000;
3083 xscale
->hold_rst
= 0;
3084 xscale
->external_debug_break
= 0;
3086 xscale
->ibcr_available
= 2;
3087 xscale
->ibcr0_used
= 0;
3088 xscale
->ibcr1_used
= 0;
3090 xscale
->dbr_available
= 2;
3091 xscale
->dbr0_used
= 0;
3092 xscale
->dbr1_used
= 0;
3094 xscale
->arm_bkpt
= ARMV5_BKPT(0x0);
3095 xscale
->thumb_bkpt
= ARMV5_T_BKPT(0x0) & 0xffff;
3097 xscale
->vector_catch
= 0x1;
3099 xscale
->trace
.capture_status
= TRACE_IDLE
;
3100 xscale
->trace
.data
= NULL
;
3101 xscale
->trace
.image
= NULL
;
3102 xscale
->trace
.buffer_enabled
= 0;
3103 xscale
->trace
.buffer_fill
= 0;
3105 /* prepare ARMv4/5 specific information */
3106 armv4_5
->arch_info
= xscale
;
3107 armv4_5
->read_core_reg
= xscale_read_core_reg
;
3108 armv4_5
->write_core_reg
= xscale_write_core_reg
;
3109 armv4_5
->full_context
= xscale_full_context
;
3111 armv4_5_init_arch_info(target
, armv4_5
);
3113 xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
3114 xscale
->armv4_5_mmu
.get_ttb
= xscale_get_ttb
;
3115 xscale
->armv4_5_mmu
.read_memory
= xscale_read_memory
;
3116 xscale
->armv4_5_mmu
.write_memory
= xscale_write_memory
;
3117 xscale
->armv4_5_mmu
.disable_mmu_caches
= xscale_disable_mmu_caches
;
3118 xscale
->armv4_5_mmu
.enable_mmu_caches
= xscale_enable_mmu_caches
;
3119 xscale
->armv4_5_mmu
.has_tiny_pages
= 1;
3120 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3125 /* target xscale <endianess> <startup_mode> <chain_pos> <variant> */
3126 int xscale_target_create(struct target_s
*target
, Jim_Interp
*interp
)
3128 xscale_common_t
*xscale
= calloc(1,sizeof(xscale_common_t
));
3130 xscale_init_arch_info(target
, xscale
, target
->tap
, target
->variant
);
3131 xscale_build_reg_cache(target
);
3136 int xscale_handle_debug_handler_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3138 target_t
*target
= NULL
;
3139 armv4_5_common_t
*armv4_5
;
3140 xscale_common_t
*xscale
;
3142 u32 handler_address
;
3146 LOG_ERROR("'xscale debug_handler <target#> <address>' command takes two required operands");
3150 if ((target
= get_target(args
[0])) == NULL
)
3152 LOG_ERROR("target '%s' not defined", args
[0]);
3156 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3161 handler_address
= strtoul(args
[1], NULL
, 0);
3163 if (((handler_address
>= 0x800) && (handler_address
<= 0x1fef800)) ||
3164 ((handler_address
>= 0xfe000800) && (handler_address
<= 0xfffff800)))
3166 xscale
->handler_address
= handler_address
;
3170 LOG_ERROR("xscale debug_handler <address> must be between 0x800 and 0x1fef800 or between 0xfe000800 and 0xfffff800");
3177 int xscale_handle_cache_clean_address_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3179 target_t
*target
= NULL
;
3180 armv4_5_common_t
*armv4_5
;
3181 xscale_common_t
*xscale
;
3183 u32 cache_clean_address
;
3187 return ERROR_COMMAND_SYNTAX_ERROR
;
3190 target
= get_target(args
[0]);
3193 LOG_ERROR("target '%s' not defined", args
[0]);
3197 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3202 cache_clean_address
= strtoul(args
[1], NULL
, 0);
3204 if (cache_clean_address
& 0xffff)
3206 LOG_ERROR("xscale cache_clean_address <address> must be 64kb aligned");
3210 xscale
->cache_clean_address
= cache_clean_address
;
3216 int xscale_handle_cache_info_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3218 target_t
*target
= get_current_target(cmd_ctx
);
3219 armv4_5_common_t
*armv4_5
;
3220 xscale_common_t
*xscale
;
3222 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3227 return armv4_5_handle_cache_info_command(cmd_ctx
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
3230 static int xscale_virt2phys(struct target_s
*target
, u32
virtual, u32
*physical
)
3232 armv4_5_common_t
*armv4_5
;
3233 xscale_common_t
*xscale
;
3240 if ((retval
= xscale_get_arch_pointers(target
, &armv4_5
, &xscale
)) != ERROR_OK
)
3244 u32 ret
= armv4_5_mmu_translate_va(target
, &xscale
->armv4_5_mmu
, virtual, &type
, &cb
, &domain
, &ap
);
3253 static int xscale_mmu(struct target_s
*target
, int *enabled
)
3255 armv4_5_common_t
*armv4_5
= target
->arch_info
;
3256 xscale_common_t
*xscale
= armv4_5
->arch_info
;
3258 if (target
->state
!= TARGET_HALTED
)
3260 LOG_ERROR("Target not halted");
3261 return ERROR_TARGET_INVALID
;
3263 *enabled
= xscale
->armv4_5_mmu
.mmu_enabled
;
3267 int xscale_handle_mmu_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3269 target_t
*target
= get_current_target(cmd_ctx
);
3270 armv4_5_common_t
*armv4_5
;
3271 xscale_common_t
*xscale
;
3273 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3278 if (target
->state
!= TARGET_HALTED
)
3280 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3286 if (strcmp("enable", args
[0]) == 0)
3288 xscale_enable_mmu_caches(target
, 1, 0, 0);
3289 xscale
->armv4_5_mmu
.mmu_enabled
= 1;
3291 else if (strcmp("disable", args
[0]) == 0)
3293 xscale_disable_mmu_caches(target
, 1, 0, 0);
3294 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3298 command_print(cmd_ctx
, "mmu %s", (xscale
->armv4_5_mmu
.mmu_enabled
) ? "enabled" : "disabled");
3303 int xscale_handle_idcache_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3305 target_t
*target
= get_current_target(cmd_ctx
);
3306 armv4_5_common_t
*armv4_5
;
3307 xscale_common_t
*xscale
;
3308 int icache
= 0, dcache
= 0;
3310 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3315 if (target
->state
!= TARGET_HALTED
)
3317 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3321 if (strcmp(cmd
, "icache") == 0)
3323 else if (strcmp(cmd
, "dcache") == 0)
3328 if (strcmp("enable", args
[0]) == 0)
3330 xscale_enable_mmu_caches(target
, 0, dcache
, icache
);
3333 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 1;
3335 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 1;
3337 else if (strcmp("disable", args
[0]) == 0)
3339 xscale_disable_mmu_caches(target
, 0, dcache
, icache
);
3342 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 0;
3344 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 0;
3349 command_print(cmd_ctx
, "icache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
) ? "enabled" : "disabled");
3352 command_print(cmd_ctx
, "dcache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
) ? "enabled" : "disabled");
3357 int xscale_handle_vector_catch_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3359 target_t
*target
= get_current_target(cmd_ctx
);
3360 armv4_5_common_t
*armv4_5
;
3361 xscale_common_t
*xscale
;
3363 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3370 command_print(cmd_ctx
, "usage: xscale vector_catch [mask]");
3374 xscale
->vector_catch
= strtoul(args
[0], NULL
, 0);
3375 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 8, xscale
->vector_catch
);
3376 xscale_write_dcsr(target
, -1, -1);
3379 command_print(cmd_ctx
, "vector catch mask: 0x%2.2x", xscale
->vector_catch
);
3385 int xscale_handle_trace_buffer_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3387 target_t
*target
= get_current_target(cmd_ctx
);
3388 armv4_5_common_t
*armv4_5
;
3389 xscale_common_t
*xscale
;
3392 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3397 if (target
->state
!= TARGET_HALTED
)
3399 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3403 if ((argc
>= 1) && (strcmp("enable", args
[0]) == 0))
3405 xscale_trace_data_t
*td
, *next_td
;
3406 xscale
->trace
.buffer_enabled
= 1;
3408 /* free old trace data */
3409 td
= xscale
->trace
.data
;
3419 xscale
->trace
.data
= NULL
;
3421 else if ((argc
>= 1) && (strcmp("disable", args
[0]) == 0))
3423 xscale
->trace
.buffer_enabled
= 0;
3426 if ((argc
>= 2) && (strcmp("fill", args
[1]) == 0))
3429 xscale
->trace
.buffer_fill
= strtoul(args
[2], NULL
, 0);
3431 xscale
->trace
.buffer_fill
= 1;
3433 else if ((argc
>= 2) && (strcmp("wrap", args
[1]) == 0))
3435 xscale
->trace
.buffer_fill
= -1;
3438 if (xscale
->trace
.buffer_enabled
)
3440 /* if we enable the trace buffer in fill-once
3441 * mode we know the address of the first instruction */
3442 xscale
->trace
.pc_ok
= 1;
3443 xscale
->trace
.current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
3447 /* otherwise the address is unknown, and we have no known good PC */
3448 xscale
->trace
.pc_ok
= 0;
3451 command_print(cmd_ctx
, "trace buffer %s (%s)",
3452 (xscale
->trace
.buffer_enabled
) ? "enabled" : "disabled",
3453 (xscale
->trace
.buffer_fill
> 0) ? "fill" : "wrap");
3455 dcsr_value
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32);
3456 if (xscale
->trace
.buffer_fill
>= 0)
3457 xscale_write_dcsr_sw(target
, (dcsr_value
& 0xfffffffc) | 2);
3459 xscale_write_dcsr_sw(target
, dcsr_value
& 0xfffffffc);
3464 int xscale_handle_trace_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3467 armv4_5_common_t
*armv4_5
;
3468 xscale_common_t
*xscale
;
3472 command_print(cmd_ctx
, "usage: xscale trace_image <file> [base address] [type]");
3476 target
= get_current_target(cmd_ctx
);
3478 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3483 if (xscale
->trace
.image
)
3485 image_close(xscale
->trace
.image
);
3486 free(xscale
->trace
.image
);
3487 command_print(cmd_ctx
, "previously loaded image found and closed");
3490 xscale
->trace
.image
= malloc(sizeof(image_t
));
3491 xscale
->trace
.image
->base_address_set
= 0;
3492 xscale
->trace
.image
->start_address_set
= 0;
3494 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
3497 xscale
->trace
.image
->base_address_set
= 1;
3498 xscale
->trace
.image
->base_address
= strtoul(args
[1], NULL
, 0);
3502 xscale
->trace
.image
->base_address_set
= 0;
3505 if (image_open(xscale
->trace
.image
, args
[0], (argc
>= 3) ? args
[2] : NULL
) != ERROR_OK
)
3507 free(xscale
->trace
.image
);
3508 xscale
->trace
.image
= NULL
;
3515 int xscale_handle_dump_trace_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3517 target_t
*target
= get_current_target(cmd_ctx
);
3518 armv4_5_common_t
*armv4_5
;
3519 xscale_common_t
*xscale
;
3520 xscale_trace_data_t
*trace_data
;
3523 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3528 if (target
->state
!= TARGET_HALTED
)
3530 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3536 command_print(cmd_ctx
, "usage: xscale dump_trace <file>");
3540 trace_data
= xscale
->trace
.data
;
3544 command_print(cmd_ctx
, "no trace data collected");
3548 if (fileio_open(&file
, args
[0], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
)
3557 fileio_write_u32(&file
, trace_data
->chkpt0
);
3558 fileio_write_u32(&file
, trace_data
->chkpt1
);
3559 fileio_write_u32(&file
, trace_data
->last_instruction
);
3560 fileio_write_u32(&file
, trace_data
->depth
);
3562 for (i
= 0; i
< trace_data
->depth
; i
++)
3563 fileio_write_u32(&file
, trace_data
->entries
[i
].data
| ((trace_data
->entries
[i
].type
& 0xffff) << 16));
3565 trace_data
= trace_data
->next
;
3568 fileio_close(&file
);
3573 int xscale_handle_analyze_trace_buffer_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3575 target_t
*target
= get_current_target(cmd_ctx
);
3576 armv4_5_common_t
*armv4_5
;
3577 xscale_common_t
*xscale
;
3579 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3584 xscale_analyze_trace(target
, cmd_ctx
);
3589 int xscale_handle_cp15(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3591 target_t
*target
= get_current_target(cmd_ctx
);
3592 armv4_5_common_t
*armv4_5
;
3593 xscale_common_t
*xscale
;
3595 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3600 if (target
->state
!= TARGET_HALTED
)
3602 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3609 reg_no
= strtoul(args
[0], NULL
, 0);
3610 /*translate from xscale cp15 register no to openocd register*/
3614 reg_no
= XSCALE_MAINID
;
3617 reg_no
= XSCALE_CTRL
;
3620 reg_no
= XSCALE_TTB
;
3623 reg_no
= XSCALE_DAC
;
3626 reg_no
= XSCALE_FSR
;
3629 reg_no
= XSCALE_FAR
;
3632 reg_no
= XSCALE_PID
;
3635 reg_no
= XSCALE_CPACCESS
;
3638 command_print(cmd_ctx
, "invalid register number");
3639 return ERROR_INVALID_ARGUMENTS
;
3641 reg
= &xscale
->reg_cache
->reg_list
[reg_no
];
3648 /* read cp15 control register */
3649 xscale_get_reg(reg
);
3650 value
= buf_get_u32(reg
->value
, 0, 32);
3651 command_print(cmd_ctx
, "%s (/%i): 0x%x", reg
->name
, reg
->size
, value
);
3656 u32 value
= strtoul(args
[1], NULL
, 0);
3658 /* send CP write request (command 0x41) */
3659 xscale_send_u32(target
, 0x41);
3661 /* send CP register number */
3662 xscale_send_u32(target
, reg_no
);
3664 /* send CP register value */
3665 xscale_send_u32(target
, value
);
3667 /* execute cpwait to ensure outstanding operations complete */
3668 xscale_send_u32(target
, 0x53);
3672 command_print(cmd_ctx
, "usage: cp15 [register]<, [value]>");
3678 int xscale_register_commands(struct command_context_s
*cmd_ctx
)
3680 command_t
*xscale_cmd
;
3682 xscale_cmd
= register_command(cmd_ctx
, NULL
, "xscale", NULL
, COMMAND_ANY
, "xscale specific commands");
3684 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");
3685 register_command(cmd_ctx
, xscale_cmd
, "cache_clean_address", xscale_handle_cache_clean_address_command
, COMMAND_ANY
, NULL
);
3687 register_command(cmd_ctx
, xscale_cmd
, "cache_info", xscale_handle_cache_info_command
, COMMAND_EXEC
, NULL
);
3688 register_command(cmd_ctx
, xscale_cmd
, "mmu", xscale_handle_mmu_command
, COMMAND_EXEC
, "['enable'|'disable'] the MMU");
3689 register_command(cmd_ctx
, xscale_cmd
, "icache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the ICache");
3690 register_command(cmd_ctx
, xscale_cmd
, "dcache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the DCache");
3692 register_command(cmd_ctx
, xscale_cmd
, "vector_catch", xscale_handle_vector_catch_command
, COMMAND_EXEC
, "<mask> of vectors that should be catched");
3694 register_command(cmd_ctx
, xscale_cmd
, "trace_buffer", xscale_handle_trace_buffer_command
, COMMAND_EXEC
, "<enable|disable> ['fill' [n]|'wrap']");
3696 register_command(cmd_ctx
, xscale_cmd
, "dump_trace", xscale_handle_dump_trace_command
, COMMAND_EXEC
, "dump content of trace buffer to <file>");
3697 register_command(cmd_ctx
, xscale_cmd
, "analyze_trace", xscale_handle_analyze_trace_buffer_command
, COMMAND_EXEC
, "analyze content of trace buffer");
3698 register_command(cmd_ctx
, xscale_cmd
, "trace_image", xscale_handle_trace_image_command
,
3699 COMMAND_EXEC
, "load image from <file> [base address]");
3701 register_command(cmd_ctx
, xscale_cmd
, "cp15", xscale_handle_cp15
, COMMAND_EXEC
, "access coproc 15 <register> [value]");
3703 armv4_5_register_commands(cmd_ctx
);
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)