1 /***************************************************************************
2 * Copyright (C) 2006, 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
24 #include "replacements.h"
31 #include "arm_simulator.h"
32 #include "arm_disassembler.h"
35 #include "binarybuffer.h"
36 #include "time_support.h"
37 #include "breakpoints.h"
43 #include <sys/types.h>
49 int xscale_register_commands(struct command_context_s
*cmd_ctx
);
51 /* forward declarations */
52 int xscale_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
);
53 int xscale_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
);
56 int xscale_arch_state(struct target_s
*target
, char *buf
, int buf_size
);
57 enum target_state
xscale_poll(target_t
*target
);
58 int xscale_halt(target_t
*target
);
59 int xscale_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
);
60 int xscale_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
);
61 int xscale_debug_entry(target_t
*target
);
62 int xscale_restore_context(target_t
*target
);
64 int xscale_assert_reset(target_t
*target
);
65 int xscale_deassert_reset(target_t
*target
);
66 int xscale_soft_reset_halt(struct target_s
*target
);
67 int xscale_prepare_reset_halt(struct target_s
*target
);
69 int xscale_set_reg_u32(reg_t
*reg
, u32 value
);
71 int xscale_read_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
);
72 int xscale_write_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
, u32 value
);
74 int xscale_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
);
75 int xscale_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
);
76 int xscale_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
);
77 int xscale_checksum_memory(struct target_s
*target
, u32 address
, u32 count
, u32
* checksum
);
79 int xscale_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
80 int xscale_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
81 int xscale_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
82 int xscale_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
83 int xscale_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
);
84 int xscale_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
);
85 void xscale_enable_watchpoints(struct target_s
*target
);
86 void xscale_enable_breakpoints(struct target_s
*target
);
88 int xscale_read_trace(target_t
*target
);
90 target_type_t xscale_target
=
95 .arch_state
= xscale_arch_state
,
97 .target_request_data
= NULL
,
100 .resume
= xscale_resume
,
103 .assert_reset
= xscale_assert_reset
,
104 .deassert_reset
= xscale_deassert_reset
,
105 .soft_reset_halt
= xscale_soft_reset_halt
,
106 .prepare_reset_halt
= xscale_prepare_reset_halt
,
108 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
110 .read_memory
= xscale_read_memory
,
111 .write_memory
= xscale_write_memory
,
112 .bulk_write_memory
= xscale_bulk_write_memory
,
113 .checksum_memory
= xscale_checksum_memory
,
115 .run_algorithm
= armv4_5_run_algorithm
,
117 .add_breakpoint
= xscale_add_breakpoint
,
118 .remove_breakpoint
= xscale_remove_breakpoint
,
119 .add_watchpoint
= xscale_add_watchpoint
,
120 .remove_watchpoint
= xscale_remove_watchpoint
,
122 .register_commands
= xscale_register_commands
,
123 .target_command
= xscale_target_command
,
124 .init_target
= xscale_init_target
,
128 char* xscale_reg_list
[] =
130 "XSCALE_MAINID", /* 0 */
140 "XSCALE_IBCR0", /* 10 */
150 "XSCALE_RX", /* 20 */
154 xscale_reg_t xscale_reg_arch_info
[] =
156 {XSCALE_MAINID
, NULL
},
157 {XSCALE_CACHETYPE
, NULL
},
159 {XSCALE_AUXCTRL
, NULL
},
165 {XSCALE_CPACCESS
, NULL
},
166 {XSCALE_IBCR0
, NULL
},
167 {XSCALE_IBCR1
, NULL
},
170 {XSCALE_DBCON
, NULL
},
171 {XSCALE_TBREG
, NULL
},
172 {XSCALE_CHKPT0
, NULL
},
173 {XSCALE_CHKPT1
, NULL
},
174 {XSCALE_DCSR
, NULL
}, /* DCSR accessed via JTAG or SW */
175 {-1, NULL
}, /* TX accessed via JTAG */
176 {-1, NULL
}, /* RX accessed via JTAG */
177 {-1, NULL
}, /* TXRXCTRL implicit access via JTAG */
180 int xscale_reg_arch_type
= -1;
182 int xscale_get_reg(reg_t
*reg
);
183 int xscale_set_reg(reg_t
*reg
, u8
*buf
);
185 int xscale_get_arch_pointers(target_t
*target
, armv4_5_common_t
**armv4_5_p
, xscale_common_t
**xscale_p
)
187 armv4_5_common_t
*armv4_5
= target
->arch_info
;
188 xscale_common_t
*xscale
= armv4_5
->arch_info
;
190 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
195 if (xscale
->common_magic
!= XSCALE_COMMON_MAGIC
)
200 *armv4_5_p
= armv4_5
;
206 int xscale_jtag_set_instr(int chain_pos
, u32 new_instr
)
208 jtag_device_t
*device
= jtag_get_device(chain_pos
);
210 if (buf_get_u32(device
->cur_instr
, 0, device
->ir_length
) != new_instr
)
214 field
.device
= chain_pos
;
215 field
.num_bits
= device
->ir_length
;
216 field
.out_value
= calloc(CEIL(field
.num_bits
, 8), 1);
217 buf_set_u32(field
.out_value
, 0, field
.num_bits
, new_instr
);
218 field
.out_mask
= NULL
;
219 field
.in_value
= NULL
;
220 jtag_set_check_value(&field
, device
->expected
, device
->expected_mask
, NULL
);
222 jtag_add_ir_scan(1, &field
, -1, NULL
);
224 free(field
.out_value
);
230 int xscale_jtag_callback(enum jtag_event event
, void *priv
)
234 case JTAG_TRST_ASSERTED
:
236 case JTAG_TRST_RELEASED
:
238 case JTAG_SRST_ASSERTED
:
240 case JTAG_SRST_RELEASED
:
243 WARNING("unhandled JTAG event");
249 int xscale_read_dcsr(target_t
*target
)
251 armv4_5_common_t
*armv4_5
= target
->arch_info
;
252 xscale_common_t
*xscale
= armv4_5
->arch_info
;
256 scan_field_t fields
[3];
258 u8 field0_check_value
= 0x2;
259 u8 field0_check_mask
= 0x7;
261 u8 field2_check_value
= 0x0;
262 u8 field2_check_mask
= 0x1;
264 jtag_add_end_state(TAP_PD
);
265 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dcsr
);
267 buf_set_u32(&field0
, 1, 1, xscale
->hold_rst
);
268 buf_set_u32(&field0
, 2, 1, xscale
->external_debug_break
);
270 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
271 fields
[0].num_bits
= 3;
272 fields
[0].out_value
= &field0
;
273 fields
[0].out_mask
= NULL
;
274 fields
[0].in_value
= NULL
;
275 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
277 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
278 fields
[1].num_bits
= 32;
279 fields
[1].out_value
= NULL
;
280 fields
[1].out_mask
= NULL
;
281 fields
[1].in_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
282 fields
[1].in_handler
= NULL
;
283 fields
[1].in_handler_priv
= NULL
;
284 fields
[1].in_check_value
= NULL
;
285 fields
[1].in_check_mask
= NULL
;
289 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
290 fields
[2].num_bits
= 1;
291 fields
[2].out_value
= &field2
;
292 fields
[2].out_mask
= NULL
;
293 fields
[2].in_value
= NULL
;
294 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
296 jtag_add_dr_scan(3, fields
, -1, NULL
);
298 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
300 ERROR("JTAG error while reading DCSR");
304 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].dirty
= 0;
305 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].valid
= 1;
307 /* write the register with the value we just read
308 * on this second pass, only the first bit of field0 is guaranteed to be 0)
310 field0_check_mask
= 0x1;
311 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
312 fields
[1].in_value
= NULL
;
314 jtag_add_end_state(TAP_RTI
);
316 jtag_add_dr_scan(3, fields
, -1, NULL
);
321 int xscale_receive(target_t
*target
, u32
*buffer
, int num_words
)
323 int retval
= ERROR_OK
;
324 armv4_5_common_t
*armv4_5
= target
->arch_info
;
325 xscale_common_t
*xscale
= armv4_5
->arch_info
;
327 enum tap_state path
[3];
328 scan_field_t fields
[3];
330 u8
*field0
= malloc(num_words
* 1);
331 u8 field0_check_value
= 0x2;
332 u8 field0_check_mask
= 0x6;
333 u32
*field1
= malloc(num_words
* 4);
334 u8 field2_check_value
= 0x0;
335 u8 field2_check_mask
= 0x1;
337 int words_scheduled
= 0;
345 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
346 fields
[0].num_bits
= 3;
347 fields
[0].out_value
= NULL
;
348 fields
[0].out_mask
= NULL
;
349 /* fields[0].in_value = field0; */
350 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
352 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
353 fields
[1].num_bits
= 32;
354 fields
[1].out_value
= NULL
;
355 fields
[1].out_mask
= NULL
;
356 fields
[1].in_value
= NULL
;
357 fields
[1].in_handler
= NULL
;
358 fields
[1].in_handler_priv
= NULL
;
359 fields
[1].in_check_value
= NULL
;
360 fields
[1].in_check_mask
= NULL
;
364 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
365 fields
[2].num_bits
= 1;
366 fields
[2].out_value
= NULL
;
367 fields
[2].out_mask
= NULL
;
368 fields
[2].in_value
= NULL
;
369 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
371 jtag_add_end_state(TAP_RTI
);
372 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dbgtx
);
373 jtag_add_runtest(1, -1);
375 /* repeat until all words have been collected */
377 while (words_done
< num_words
)
381 for (i
= words_done
; i
< num_words
; i
++)
383 fields
[0].in_value
= &field0
[i
];
384 fields
[1].in_handler
= buf_to_u32_handler
;
385 fields
[1].in_handler_priv
= (u8
*)&field1
[i
];
387 jtag_add_pathmove(3, path
);
388 jtag_add_dr_scan(3, fields
, TAP_RTI
, NULL
);
392 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
394 ERROR("JTAG error while receiving data from debug handler");
398 /* examine results */
399 for (i
= words_done
; i
< num_words
; i
++)
401 if (!(field0
[0] & 1))
403 /* move backwards if necessary */
405 for (j
= i
; j
< num_words
- 1; j
++)
407 field0
[j
] = field0
[j
+1];
408 field1
[j
] = field1
[j
+1];
413 if (words_scheduled
== 0)
415 if (attempts
++ == 1000)
417 ERROR("Failed to receiving data from debug handler after 1000 attempts");
418 retval
= ERROR_JTAG_QUEUE_FAILED
;
423 words_done
+= words_scheduled
;
426 for (i
= 0; i
< num_words
; i
++)
427 *(buffer
++) = buf_get_u32((u8
*)&field1
[i
], 0, 32);
434 int xscale_read_tx(target_t
*target
, int consume
)
436 armv4_5_common_t
*armv4_5
= target
->arch_info
;
437 xscale_common_t
*xscale
= armv4_5
->arch_info
;
438 enum tap_state path
[3];
439 enum tap_state noconsume_path
[7];
442 struct timeval timeout
, now
;
444 scan_field_t fields
[3];
446 u8 field0_check_value
= 0x2;
447 u8 field0_check_mask
= 0x6;
448 u8 field2_check_value
= 0x0;
449 u8 field2_check_mask
= 0x1;
451 jtag_add_end_state(TAP_RTI
);
453 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dbgtx
);
459 noconsume_path
[0] = TAP_SDS
;
460 noconsume_path
[1] = TAP_CD
;
461 noconsume_path
[2] = TAP_E1D
;
462 noconsume_path
[3] = TAP_PD
;
463 noconsume_path
[4] = TAP_E2D
;
464 noconsume_path
[5] = TAP_CD
;
465 noconsume_path
[6] = TAP_SD
;
467 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
468 fields
[0].num_bits
= 3;
469 fields
[0].out_value
= NULL
;
470 fields
[0].out_mask
= NULL
;
471 fields
[0].in_value
= &field0_in
;
472 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
474 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
475 fields
[1].num_bits
= 32;
476 fields
[1].out_value
= NULL
;
477 fields
[1].out_mask
= NULL
;
478 fields
[1].in_value
= xscale
->reg_cache
->reg_list
[XSCALE_TX
].value
;
479 fields
[1].in_handler
= NULL
;
480 fields
[1].in_handler_priv
= NULL
;
481 fields
[1].in_check_value
= NULL
;
482 fields
[1].in_check_mask
= NULL
;
486 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
487 fields
[2].num_bits
= 1;
488 fields
[2].out_value
= NULL
;
489 fields
[2].out_mask
= NULL
;
490 fields
[2].in_value
= NULL
;
491 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
493 gettimeofday(&timeout
, NULL
);
494 timeval_add_time(&timeout
, 5, 0);
498 /* if we want to consume the register content (i.e. clear TX_READY),
499 * we have to go straight from Capture-DR to Shift-DR
500 * otherwise, we go from Capture-DR to Exit1-DR to Pause-DR
503 jtag_add_pathmove(3, path
);
505 jtag_add_pathmove(7, noconsume_path
);
507 jtag_add_dr_scan(3, fields
, TAP_RTI
, NULL
);
509 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
511 ERROR("JTAG error while reading TX");
512 return ERROR_TARGET_TIMEOUT
;
515 gettimeofday(&now
, NULL
);
516 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
)&& (now
.tv_usec
> timeout
.tv_usec
)))
518 ERROR("time out reading TX register");
519 return ERROR_TARGET_TIMEOUT
;
521 } while ((!(field0_in
& 1)) && consume
);
523 if (!(field0_in
& 1))
524 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
529 int xscale_write_rx(target_t
*target
)
531 armv4_5_common_t
*armv4_5
= target
->arch_info
;
532 xscale_common_t
*xscale
= armv4_5
->arch_info
;
535 struct timeval timeout
, now
;
537 scan_field_t fields
[3];
540 u8 field0_check_value
= 0x2;
541 u8 field0_check_mask
= 0x6;
543 u8 field2_check_value
= 0x0;
544 u8 field2_check_mask
= 0x1;
546 jtag_add_end_state(TAP_RTI
);
548 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dbgrx
);
550 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
551 fields
[0].num_bits
= 3;
552 fields
[0].out_value
= &field0_out
;
553 fields
[0].out_mask
= NULL
;
554 fields
[0].in_value
= &field0_in
;
555 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
557 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
558 fields
[1].num_bits
= 32;
559 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
;
560 fields
[1].out_mask
= NULL
;
561 fields
[1].in_value
= NULL
;
562 fields
[1].in_handler
= NULL
;
563 fields
[1].in_handler_priv
= NULL
;
564 fields
[1].in_check_value
= NULL
;
565 fields
[1].in_check_mask
= NULL
;
569 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
570 fields
[2].num_bits
= 1;
571 fields
[2].out_value
= &field2
;
572 fields
[2].out_mask
= NULL
;
573 fields
[2].in_value
= NULL
;
574 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
576 gettimeofday(&timeout
, NULL
);
577 timeval_add_time(&timeout
, 5, 0);
579 /* poll until rx_read is low */
583 jtag_add_dr_scan(3, fields
, TAP_RTI
, NULL
);
585 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
587 ERROR("JTAG error while writing RX");
591 gettimeofday(&now
, NULL
);
592 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
)&& (now
.tv_usec
> timeout
.tv_usec
)))
594 ERROR("time out writing RX register");
595 return ERROR_TARGET_TIMEOUT
;
597 } while (field0_in
& 1);
601 jtag_add_dr_scan(3, fields
, TAP_RTI
, NULL
);
603 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
605 ERROR("JTAG error while writing RX");
612 /* send count elements of size byte to the debug handler */
613 int xscale_send(target_t
*target
, u8
*buffer
, int count
, int size
)
615 armv4_5_common_t
*armv4_5
= target
->arch_info
;
616 xscale_common_t
*xscale
= armv4_5
->arch_info
;
621 u8 output
[4] = {0, 0, 0, 0};
623 scan_field_t fields
[3];
626 u8 field0_check_value
= 0x2;
627 u8 field0_check_mask
= 0x6;
629 u8 field2_check_value
= 0x0;
630 u8 field2_check_mask
= 0x1;
632 jtag_add_end_state(TAP_RTI
);
634 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dbgrx
);
636 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
637 fields
[0].num_bits
= 3;
638 fields
[0].out_value
= &field0_out
;
639 fields
[0].out_mask
= NULL
;
640 fields
[0].in_value
= &field0_in
;
641 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
643 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
644 fields
[1].num_bits
= 32;
645 fields
[1].out_value
= output
;
646 fields
[1].out_mask
= NULL
;
647 fields
[1].in_value
= NULL
;
648 fields
[1].in_handler
= NULL
;
649 fields
[1].in_handler_priv
= NULL
;
650 fields
[1].in_check_value
= NULL
;
651 fields
[1].in_check_mask
= NULL
;
655 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
656 fields
[2].num_bits
= 1;
657 fields
[2].out_value
= &field2
;
658 fields
[2].out_mask
= NULL
;
659 fields
[2].in_value
= NULL
;
660 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
662 while (done_count
++ < count
)
664 /* extract sized element from target-endian buffer, and put it
665 * into little-endian output buffer
670 buf_set_u32(output
, 0, 32, target_buffer_get_u32(target
, buffer
));
673 buf_set_u32(output
, 0, 32, target_buffer_get_u16(target
, buffer
));
679 ERROR("BUG: size neither 4, 2 nor 1");
683 jtag_add_dr_scan(3, fields
, TAP_RTI
, NULL
);
687 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
689 ERROR("JTAG error while sending data to debug handler");
696 int xscale_send_u32(target_t
*target
, u32 value
)
698 armv4_5_common_t
*armv4_5
= target
->arch_info
;
699 xscale_common_t
*xscale
= armv4_5
->arch_info
;
701 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
702 return xscale_write_rx(target
);
705 int xscale_write_dcsr(target_t
*target
, int hold_rst
, int ext_dbg_brk
)
707 armv4_5_common_t
*armv4_5
= target
->arch_info
;
708 xscale_common_t
*xscale
= armv4_5
->arch_info
;
712 scan_field_t fields
[3];
714 u8 field0_check_value
= 0x2;
715 u8 field0_check_mask
= 0x7;
717 u8 field2_check_value
= 0x0;
718 u8 field2_check_mask
= 0x1;
721 xscale
->hold_rst
= hold_rst
;
723 if (ext_dbg_brk
!= -1)
724 xscale
->external_debug_break
= ext_dbg_brk
;
726 jtag_add_end_state(TAP_RTI
);
727 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dcsr
);
729 buf_set_u32(&field0
, 1, 1, xscale
->hold_rst
);
730 buf_set_u32(&field0
, 2, 1, xscale
->external_debug_break
);
732 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
733 fields
[0].num_bits
= 3;
734 fields
[0].out_value
= &field0
;
735 fields
[0].out_mask
= NULL
;
736 fields
[0].in_value
= NULL
;
737 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
739 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
740 fields
[1].num_bits
= 32;
741 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
742 fields
[1].out_mask
= NULL
;
743 fields
[1].in_value
= NULL
;
744 fields
[1].in_handler
= NULL
;
745 fields
[1].in_handler_priv
= NULL
;
746 fields
[1].in_check_value
= NULL
;
747 fields
[1].in_check_mask
= NULL
;
751 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
752 fields
[2].num_bits
= 1;
753 fields
[2].out_value
= &field2
;
754 fields
[2].out_mask
= NULL
;
755 fields
[2].in_value
= NULL
;
756 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
758 jtag_add_dr_scan(3, fields
, -1, NULL
);
760 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
762 ERROR("JTAG error while writing DCSR");
766 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].dirty
= 0;
767 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].valid
= 1;
772 /* parity of the number of bits 0 if even; 1 if odd. for 32 bit words */
773 unsigned int parity (unsigned int v
)
780 DEBUG("parity of 0x%x is %i", ov
, (0x6996 >> v
) & 1);
781 return (0x6996 >> v
) & 1;
784 int xscale_load_ic(target_t
*target
, int mini
, u32 va
, u32 buffer
[8])
786 armv4_5_common_t
*armv4_5
= target
->arch_info
;
787 xscale_common_t
*xscale
= armv4_5
->arch_info
;
792 scan_field_t fields
[2];
794 DEBUG("loading miniIC at 0x%8.8x", va
);
796 jtag_add_end_state(TAP_RTI
);
797 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.ldic
); /* LDIC */
799 /* CMD is b010 for Main IC and b011 for Mini IC */
801 buf_set_u32(&cmd
, 0, 3, 0x3);
803 buf_set_u32(&cmd
, 0, 3, 0x2);
805 buf_set_u32(&cmd
, 3, 3, 0x0);
807 /* virtual address of desired cache line */
808 buf_set_u32(packet
, 0, 27, va
>> 5);
810 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
811 fields
[0].num_bits
= 6;
812 fields
[0].out_value
= &cmd
;
813 fields
[0].out_mask
= NULL
;
814 fields
[0].in_value
= NULL
;
815 fields
[0].in_check_value
= NULL
;
816 fields
[0].in_check_mask
= NULL
;
817 fields
[0].in_handler
= NULL
;
818 fields
[0].in_handler_priv
= NULL
;
820 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
821 fields
[1].num_bits
= 27;
822 fields
[1].out_value
= packet
;
823 fields
[1].out_mask
= NULL
;
824 fields
[1].in_value
= NULL
;
825 fields
[1].in_check_value
= NULL
;
826 fields
[1].in_check_mask
= NULL
;
827 fields
[1].in_handler
= NULL
;
828 fields
[1].in_handler_priv
= NULL
;
830 jtag_add_dr_scan(2, fields
, -1, NULL
);
832 fields
[0].num_bits
= 32;
833 fields
[0].out_value
= packet
;
835 fields
[1].num_bits
= 1;
836 fields
[1].out_value
= &cmd
;
838 for (word
= 0; word
< 8; word
++)
840 buf_set_u32(packet
, 0, 32, buffer
[word
]);
841 cmd
= parity(*((u32
*)packet
));
842 jtag_add_dr_scan(2, fields
, -1, NULL
);
845 jtag_execute_queue();
850 int xscale_invalidate_ic_line(target_t
*target
, u32 va
)
852 armv4_5_common_t
*armv4_5
= target
->arch_info
;
853 xscale_common_t
*xscale
= armv4_5
->arch_info
;
857 scan_field_t fields
[2];
859 jtag_add_end_state(TAP_RTI
);
860 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.ldic
); /* LDIC */
862 /* CMD for invalidate IC line b000, bits [6:4] b000 */
863 buf_set_u32(&cmd
, 0, 6, 0x0);
865 /* virtual address of desired cache line */
866 buf_set_u32(packet
, 0, 27, va
>> 5);
868 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
869 fields
[0].num_bits
= 6;
870 fields
[0].out_value
= &cmd
;
871 fields
[0].out_mask
= NULL
;
872 fields
[0].in_value
= NULL
;
873 fields
[0].in_check_value
= NULL
;
874 fields
[0].in_check_mask
= NULL
;
875 fields
[0].in_handler
= NULL
;
876 fields
[0].in_handler_priv
= NULL
;
878 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
879 fields
[1].num_bits
= 27;
880 fields
[1].out_value
= packet
;
881 fields
[1].out_mask
= NULL
;
882 fields
[1].in_value
= NULL
;
883 fields
[1].in_check_value
= NULL
;
884 fields
[1].in_check_mask
= NULL
;
885 fields
[1].in_handler
= NULL
;
886 fields
[1].in_handler_priv
= NULL
;
888 jtag_add_dr_scan(2, fields
, -1, NULL
);
893 int xscale_update_vectors(target_t
*target
)
895 armv4_5_common_t
*armv4_5
= target
->arch_info
;
896 xscale_common_t
*xscale
= armv4_5
->arch_info
;
899 u32 low_reset_branch
, high_reset_branch
;
901 for (i
= 1; i
< 8; i
++)
903 /* if there's a static vector specified for this exception, override */
904 if (xscale
->static_high_vectors_set
& (1 << i
))
906 xscale
->high_vectors
[i
] = xscale
->static_high_vectors
[i
];
910 if (target_read_u32(target
, 0xffff0000 + 4*i
, &xscale
->high_vectors
[i
]) != ERROR_OK
)
912 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
917 for (i
= 1; i
< 8; i
++)
919 if (xscale
->static_low_vectors_set
& (1 << i
))
921 xscale
->low_vectors
[i
] = xscale
->static_low_vectors
[i
];
925 if (target_read_u32(target
, 0x0 + 4*i
, &xscale
->low_vectors
[i
]) != ERROR_OK
)
927 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
932 /* calculate branches to debug handler */
933 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
934 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
936 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
937 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
939 /* invalidate and load exception vectors in mini i-cache */
940 xscale_invalidate_ic_line(target
, 0x0);
941 xscale_invalidate_ic_line(target
, 0xffff0000);
943 xscale_load_ic(target
, 1, 0x0, xscale
->low_vectors
);
944 xscale_load_ic(target
, 1, 0xffff0000, xscale
->high_vectors
);
949 int xscale_arch_state(struct target_s
*target
, char *buf
, int buf_size
)
951 armv4_5_common_t
*armv4_5
= target
->arch_info
;
952 xscale_common_t
*xscale
= armv4_5
->arch_info
;
956 "disabled", "enabled"
959 char *arch_dbg_reason
[] =
961 "", "\n(processor reset)", "\n(trace buffer full)"
964 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
966 ERROR("BUG: called for a non-ARMv4/5 target");
970 snprintf(buf
, buf_size
,
971 "target halted in %s state due to %s, current mode: %s\n"
972 "cpsr: 0x%8.8x pc: 0x%8.8x\n"
973 "MMU: %s, D-Cache: %s, I-Cache: %s"
975 armv4_5_state_strings
[armv4_5
->core_state
],
976 target_debug_reason_strings
[target
->debug_reason
],
977 armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)],
978 buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32),
979 buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32),
980 state
[xscale
->armv4_5_mmu
.mmu_enabled
],
981 state
[xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
],
982 state
[xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
],
983 arch_dbg_reason
[xscale
->arch_debug_reason
]);
988 enum target_state
xscale_poll(target_t
*target
)
991 armv4_5_common_t
*armv4_5
= target
->arch_info
;
992 xscale_common_t
*xscale
= armv4_5
->arch_info
;
994 if ((target
->state
== TARGET_RUNNING
) || (target
->state
== TARGET_DEBUG_RUNNING
))
996 if ((retval
= xscale_read_tx(target
, 0)) == ERROR_OK
)
998 enum target_state previous_state
= target
->state
;
1000 /* there's data to read from the tx register, we entered debug state */
1001 xscale
->handler_running
= 1;
1003 target
->state
= TARGET_HALTED
;
1005 /* process debug entry, fetching current mode regs */
1006 if ((retval
= xscale_debug_entry(target
)) != ERROR_OK
)
1009 /* debug_entry could have overwritten target state (i.e. immediate resume)
1010 * don't signal event handlers in that case
1012 if (target
->state
!= TARGET_HALTED
)
1013 return target
->state
;
1015 /* if target was running, signal that we halted
1016 * otherwise we reentered from debug execution */
1017 if (previous_state
== TARGET_RUNNING
)
1018 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1020 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
1022 else if (retval
!= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
1024 ERROR("error while polling TX register");
1029 return target
->state
;
1032 int xscale_debug_entry(target_t
*target
)
1034 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1035 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1042 /* clear external dbg break (will be written on next DCSR read) */
1043 xscale
->external_debug_break
= 0;
1044 xscale_read_dcsr(target
);
1046 /* get r0, pc, r1 to r7 and cpsr */
1047 xscale_receive(target
, buffer
, 10);
1049 /* move r0 from buffer to register cache */
1050 buf_set_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32, buffer
[0]);
1051 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
1052 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
1053 DEBUG("r0: 0x%8.8x", buffer
[0]);
1055 /* move pc from buffer to register cache */
1056 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, buffer
[1]);
1057 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
1058 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
1059 DEBUG("pc: 0x%8.8x", buffer
[1]);
1061 /* move data from buffer to register cache */
1062 for (i
= 1; i
<= 7; i
++)
1064 buf_set_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32, buffer
[1 + i
]);
1065 armv4_5
->core_cache
->reg_list
[i
].dirty
= 1;
1066 armv4_5
->core_cache
->reg_list
[i
].valid
= 1;
1067 DEBUG("r%i: 0x%8.8x", i
, buffer
[i
+ 1]);
1070 buf_set_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32, buffer
[9]);
1071 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].dirty
= 1;
1072 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].valid
= 1;
1073 DEBUG("cpsr: 0x%8.8x", buffer
[9]);
1075 armv4_5
->core_mode
= buffer
[9] & 0x1f;
1076 if (armv4_5_mode_to_number(armv4_5
->core_mode
) == -1)
1078 target
->state
= TARGET_UNKNOWN
;
1079 ERROR("cpsr contains invalid mode value - communication failure");
1080 return ERROR_TARGET_FAILURE
;
1082 DEBUG("target entered debug state in %s mode", armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)]);
1084 if (buffer
[9] & 0x20)
1085 armv4_5
->core_state
= ARMV4_5_STATE_THUMB
;
1087 armv4_5
->core_state
= ARMV4_5_STATE_ARM
;
1089 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1090 if ((armv4_5
->core_mode
!= ARMV4_5_MODE_USR
) && (armv4_5
->core_mode
!= ARMV4_5_MODE_SYS
))
1092 xscale_receive(target
, buffer
, 8);
1093 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1094 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
1095 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
1099 /* r8 to r14, but no spsr */
1100 xscale_receive(target
, buffer
, 7);
1103 /* move data from buffer to register cache */
1104 for (i
= 8; i
<= 14; i
++)
1106 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).value
, 0, 32, buffer
[i
- 8]);
1107 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).dirty
= 0;
1108 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).valid
= 1;
1111 /* examine debug reason */
1112 xscale_read_dcsr(target
);
1113 moe
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 2, 3);
1115 /* stored PC (for calculating fixup) */
1116 pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1120 case 0x0: /* Processor reset */
1121 target
->debug_reason
= DBG_REASON_DBGRQ
;
1122 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_RESET
;
1125 case 0x1: /* Instruction breakpoint hit */
1126 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1127 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1130 case 0x2: /* Data breakpoint hit */
1131 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
1132 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1135 case 0x3: /* BKPT instruction executed */
1136 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1137 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1140 case 0x4: /* Ext. debug event */
1141 target
->debug_reason
= DBG_REASON_DBGRQ
;
1142 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1145 case 0x5: /* Vector trap occured */
1146 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1147 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1150 case 0x6: /* Trace buffer full break */
1151 target
->debug_reason
= DBG_REASON_DBGRQ
;
1152 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_TB_FULL
;
1155 case 0x7: /* Reserved */
1157 ERROR("Method of Entry is 'Reserved'");
1162 /* apply PC fixup */
1163 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, pc
);
1165 /* on the first debug entry, identify cache type */
1166 if (xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
1170 /* read cp15 cache type register */
1171 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
]);
1172 cache_type_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
].value
, 0, 32);
1174 armv4_5_identify_cache(cache_type_reg
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
1177 /* examine MMU and Cache settings */
1178 /* read cp15 control register */
1179 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
1180 xscale
->cp15_control_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
1181 xscale
->armv4_5_mmu
.mmu_enabled
= (xscale
->cp15_control_reg
& 0x1U
) ? 1 : 0;
1182 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= (xscale
->cp15_control_reg
& 0x4U
) ? 1 : 0;
1183 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= (xscale
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
1185 /* tracing enabled, read collected trace data */
1186 if (xscale
->trace
.buffer_enabled
)
1188 xscale_read_trace(target
);
1189 xscale
->trace
.buffer_fill
--;
1191 /* resume if we're still collecting trace data */
1192 if ((xscale
->arch_debug_reason
== XSCALE_DBG_REASON_TB_FULL
)
1193 && (xscale
->trace
.buffer_fill
> 0))
1195 xscale_resume(target
, 1, 0x0, 1, 0);
1199 xscale
->trace
.buffer_enabled
= 0;
1206 int xscale_halt(target_t
*target
)
1208 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1209 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1211 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
1213 if (target
->state
== TARGET_HALTED
)
1215 WARNING("target was already halted");
1216 return ERROR_TARGET_ALREADY_HALTED
;
1218 else if (target
->state
== TARGET_UNKNOWN
)
1220 /* this must not happen for a xscale target */
1221 ERROR("target was in unknown state when halt was requested");
1222 return ERROR_TARGET_INVALID
;
1224 else if (target
->state
== TARGET_RESET
)
1226 DEBUG("target->state == TARGET_RESET");
1230 /* assert external dbg break */
1231 xscale
->external_debug_break
= 1;
1232 xscale_read_dcsr(target
);
1234 target
->debug_reason
= DBG_REASON_DBGRQ
;
1240 int xscale_enable_single_step(struct target_s
*target
, u32 next_pc
)
1242 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1243 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1244 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1246 if (xscale
->ibcr0_used
)
1248 breakpoint_t
*ibcr0_bp
= breakpoint_find(target
, buf_get_u32(ibcr0
->value
, 0, 32) & 0xfffffffe);
1252 xscale_unset_breakpoint(target
, ibcr0_bp
);
1256 ERROR("BUG: xscale->ibcr0_used is set, but no breakpoint with that address found");
1261 xscale_set_reg_u32(ibcr0
, next_pc
| 0x1);
1266 int xscale_disable_single_step(struct target_s
*target
)
1268 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1269 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1270 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1272 xscale_set_reg_u32(ibcr0
, 0x0);
1277 int xscale_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
1279 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1280 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1281 breakpoint_t
*breakpoint
= target
->breakpoints
;
1290 if (target
->state
!= TARGET_HALTED
)
1292 WARNING("target not halted");
1293 return ERROR_TARGET_NOT_HALTED
;
1296 if (!debug_execution
)
1298 target_free_all_working_areas(target
);
1301 /* update vector tables */
1302 xscale_update_vectors(target
);
1304 /* current = 1: continue on current pc, otherwise continue at <address> */
1306 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1308 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1310 /* if we're at the reset vector, we have to simulate the branch */
1311 if (current_pc
== 0x0)
1313 arm_simulate_step(target
, NULL
);
1314 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1317 /* the front-end may request us not to handle breakpoints */
1318 if (handle_breakpoints
)
1320 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1324 /* there's a breakpoint at the current PC, we have to step over it */
1325 DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
1326 xscale_unset_breakpoint(target
, breakpoint
);
1328 /* calculate PC of next instruction */
1329 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1332 target_read_u32(target
, current_pc
, ¤t_opcode
);
1333 ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode
);
1336 DEBUG("enable single-step");
1337 xscale_enable_single_step(target
, next_pc
);
1339 /* restore banked registers */
1340 xscale_restore_context(target
);
1342 /* send resume request (command 0x30 or 0x31)
1343 * clean the trace buffer if it is to be enabled (0x62) */
1344 if (xscale
->trace
.buffer_enabled
)
1346 xscale_send_u32(target
, 0x62);
1347 xscale_send_u32(target
, 0x31);
1350 xscale_send_u32(target
, 0x30);
1353 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1354 DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1356 for (i
= 7; i
>= 0; i
--)
1359 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1360 DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1364 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1365 DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1367 /* wait for and process debug entry */
1368 xscale_debug_entry(target
);
1370 DEBUG("disable single-step");
1371 xscale_disable_single_step(target
);
1373 DEBUG("set breakpoint at 0x%8.8x", breakpoint
->address
);
1374 xscale_set_breakpoint(target
, breakpoint
);
1378 /* enable any pending breakpoints and watchpoints */
1379 xscale_enable_breakpoints(target
);
1380 xscale_enable_watchpoints(target
);
1382 /* restore banked registers */
1383 xscale_restore_context(target
);
1385 /* send resume request (command 0x30 or 0x31)
1386 * clean the trace buffer if it is to be enabled (0x62) */
1387 if (xscale
->trace
.buffer_enabled
)
1389 xscale_send_u32(target
, 0x62);
1390 xscale_send_u32(target
, 0x31);
1393 xscale_send_u32(target
, 0x30);
1396 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1397 DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1399 for (i
= 7; i
>= 0; i
--)
1402 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1403 DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1407 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1408 DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1410 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1412 if (!debug_execution
)
1414 /* registers are now invalid */
1415 armv4_5_invalidate_core_regs(target
);
1416 target
->state
= TARGET_RUNNING
;
1417 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1421 target
->state
= TARGET_DEBUG_RUNNING
;
1422 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1425 DEBUG("target resumed");
1427 xscale
->handler_running
= 1;
1432 int xscale_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
1434 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1435 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1436 breakpoint_t
*breakpoint
= target
->breakpoints
;
1438 u32 current_pc
, next_pc
;
1442 if (target
->state
!= TARGET_HALTED
)
1444 WARNING("target not halted");
1445 return ERROR_TARGET_NOT_HALTED
;
1448 /* current = 1: continue on current pc, otherwise continue at <address> */
1450 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1452 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1454 /* if we're at the reset vector, we have to simulate the step */
1455 if (current_pc
== 0x0)
1457 arm_simulate_step(target
, NULL
);
1458 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1460 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1461 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1466 /* the front-end may request us not to handle breakpoints */
1467 if (handle_breakpoints
)
1468 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1470 xscale_unset_breakpoint(target
, breakpoint
);
1473 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1475 /* calculate PC of next instruction */
1476 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1479 target_read_u32(target
, current_pc
, ¤t_opcode
);
1480 ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode
);
1483 DEBUG("enable single-step");
1484 xscale_enable_single_step(target
, next_pc
);
1486 /* restore banked registers */
1487 xscale_restore_context(target
);
1489 /* send resume request (command 0x30 or 0x31)
1490 * clean the trace buffer if it is to be enabled (0x62) */
1491 if (xscale
->trace
.buffer_enabled
)
1493 xscale_send_u32(target
, 0x62);
1494 xscale_send_u32(target
, 0x31);
1497 xscale_send_u32(target
, 0x30);
1500 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1501 DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1503 for (i
= 7; i
>= 0; i
--)
1506 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1507 DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1511 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1512 DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1514 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1516 /* registers are now invalid */
1517 armv4_5_invalidate_core_regs(target
);
1519 /* wait for and process debug entry */
1520 xscale_debug_entry(target
);
1522 DEBUG("disable single-step");
1523 xscale_disable_single_step(target
);
1525 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1529 xscale_set_breakpoint(target
, breakpoint
);
1532 DEBUG("target stepped");
1538 int xscale_assert_reset(target_t
*target
)
1540 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1541 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1543 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
1545 /* select DCSR instruction (set endstate to R-T-I to ensure we don't
1546 * end up in T-L-R, which would reset JTAG
1548 jtag_add_end_state(TAP_RTI
);
1549 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dcsr
);
1551 /* set Hold reset, Halt mode and Trap Reset */
1552 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1553 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1554 xscale_write_dcsr(target
, 1, 0);
1556 /* select BYPASS, because having DCSR selected caused problems on the PXA27x */
1557 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, 0x7f);
1558 jtag_execute_queue();
1561 jtag_add_reset(0, 1);
1563 /* sleep 1ms, to be sure we fulfill any requirements */
1564 jtag_add_sleep(1000);
1565 jtag_execute_queue();
1567 target
->state
= TARGET_RESET
;
1572 int xscale_deassert_reset(target_t
*target
)
1574 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1575 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1577 fileio_t debug_handler
;
1585 breakpoint_t
*breakpoint
= target
->breakpoints
;
1589 xscale
->ibcr_available
= 2;
1590 xscale
->ibcr0_used
= 0;
1591 xscale
->ibcr1_used
= 0;
1593 xscale
->dbr_available
= 2;
1594 xscale
->dbr0_used
= 0;
1595 xscale
->dbr1_used
= 0;
1597 /* mark all hardware breakpoints as unset */
1600 if (breakpoint
->type
== BKPT_HARD
)
1602 breakpoint
->set
= 0;
1604 breakpoint
= breakpoint
->next
;
1607 if (!xscale
->handler_installed
)
1610 jtag_add_reset(0, 0);
1612 /* wait 300ms; 150 and 100ms were not enough */
1613 jtag_add_sleep(300*1000);
1615 jtag_add_runtest(2030, TAP_RTI
);
1616 jtag_execute_queue();
1618 /* set Hold reset, Halt mode and Trap Reset */
1619 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1620 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1621 xscale_write_dcsr(target
, 1, 0);
1623 /* Load debug handler */
1624 if (fileio_open(&debug_handler
, PKGLIBDIR
"/xscale/debug_handler.bin", FILEIO_READ
, FILEIO_BINARY
) != ERROR_OK
)
1626 ERROR("file open error: %s", debug_handler
.error_str
);
1630 if ((binary_size
= debug_handler
.size
) % 4)
1632 ERROR("debug_handler.bin: size not a multiple of 4");
1636 if (binary_size
> 0x800)
1638 ERROR("debug_handler.bin: larger than 2kb");
1642 binary_size
= CEIL(binary_size
, 32) * 32;
1644 address
= xscale
->handler_address
;
1645 while (binary_size
> 0)
1650 if ((retval
= fileio_read(&debug_handler
, 32, buffer
, &buf_cnt
)) != ERROR_OK
)
1652 ERROR("reading debug handler failed: %s", debug_handler
.error_str
);
1655 for (i
= 0; i
< buf_cnt
; i
+= 4)
1657 /* convert LE buffer to host-endian u32 */
1658 cache_line
[i
/ 4] = le_to_h_u32(&buffer
[i
]);
1661 for (; buf_cnt
< 32; buf_cnt
+= 4)
1663 cache_line
[buf_cnt
/ 4] = 0xe1a08008;
1666 /* only load addresses other than the reset vectors */
1667 if ((address
% 0x400) != 0x0)
1669 xscale_load_ic(target
, 1, address
, cache_line
);
1673 binary_size
-= buf_cnt
;
1676 xscale_load_ic(target
, 1, 0x0, xscale
->low_vectors
);
1677 xscale_load_ic(target
, 1, 0xffff0000, xscale
->high_vectors
);
1679 jtag_add_runtest(30, TAP_RTI
);
1681 jtag_add_sleep(100000);
1683 /* set Hold reset, Halt mode and Trap Reset */
1684 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1685 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1686 xscale_write_dcsr(target
, 1, 0);
1688 /* clear Hold reset to let the target run (should enter debug handler) */
1689 xscale_write_dcsr(target
, 0, 1);
1690 target
->state
= TARGET_RUNNING
;
1692 if ((target
->reset_mode
!= RESET_HALT
) && (target
->reset_mode
!= RESET_INIT
))
1694 jtag_add_sleep(10000);
1696 /* we should have entered debug now */
1697 xscale_debug_entry(target
);
1698 target
->state
= TARGET_HALTED
;
1700 /* resume the target */
1701 xscale_resume(target
, 1, 0x0, 1, 0);
1704 fileio_close(&debug_handler
);
1708 jtag_add_reset(0, 0);
1715 int xscale_soft_reset_halt(struct target_s
*target
)
1721 int xscale_prepare_reset_halt(struct target_s
*target
)
1723 /* nothing to be done for reset_halt on XScale targets
1724 * we always halt after a reset to upload the debug handler
1729 int xscale_read_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
)
1735 int xscale_write_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
, u32 value
)
1741 int xscale_full_context(target_t
*target
)
1743 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1751 if (target
->state
!= TARGET_HALTED
)
1753 WARNING("target not halted");
1754 return ERROR_TARGET_NOT_HALTED
;
1757 buffer
= malloc(4 * 8);
1759 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1760 * we can't enter User mode on an XScale (unpredictable),
1761 * but User shares registers with SYS
1763 for(i
= 1; i
< 7; i
++)
1767 /* check if there are invalid registers in the current mode
1769 for (j
= 0; j
<= 16; j
++)
1771 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
== 0)
1779 /* request banked registers */
1780 xscale_send_u32(target
, 0x0);
1783 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1784 tmp_cpsr
|= 0xc0; /* I/F bits */
1786 /* send CPSR for desired mode */
1787 xscale_send_u32(target
, tmp_cpsr
);
1789 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1790 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1792 xscale_receive(target
, buffer
, 8);
1793 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1794 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1795 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).valid
= 1;
1799 xscale_receive(target
, buffer
, 7);
1802 /* move data from buffer to register cache */
1803 for (j
= 8; j
<= 14; j
++)
1805 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]);
1806 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1807 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
= 1;
1817 int xscale_restore_context(target_t
*target
)
1819 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1825 if (target
->state
!= TARGET_HALTED
)
1827 WARNING("target not halted");
1828 return ERROR_TARGET_NOT_HALTED
;
1831 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1832 * we can't enter User mode on an XScale (unpredictable),
1833 * but User shares registers with SYS
1835 for(i
= 1; i
< 7; i
++)
1839 /* check if there are invalid registers in the current mode
1841 for (j
= 8; j
<= 14; j
++)
1843 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
== 1)
1847 /* if not USR/SYS, check if the SPSR needs to be written */
1848 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1850 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
== 1)
1858 /* send banked registers */
1859 xscale_send_u32(target
, 0x1);
1862 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1863 tmp_cpsr
|= 0xc0; /* I/F bits */
1865 /* send CPSR for desired mode */
1866 xscale_send_u32(target
, tmp_cpsr
);
1868 /* send banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1869 for (j
= 8; j
<= 14; j
++)
1871 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, j
).value
, 0, 32));
1872 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1875 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1877 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32));
1878 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1886 int xscale_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1888 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1889 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1893 DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address
, size
, count
);
1895 if (target
->state
!= TARGET_HALTED
)
1897 WARNING("target not halted");
1898 return ERROR_TARGET_NOT_HALTED
;
1901 /* sanitize arguments */
1902 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1903 return ERROR_INVALID_ARGUMENTS
;
1905 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1906 return ERROR_TARGET_UNALIGNED_ACCESS
;
1908 /* send memory read request (command 0x1n, n: access size) */
1909 xscale_send_u32(target
, 0x10 | size
);
1911 /* send base address for read request */
1912 xscale_send_u32(target
, address
);
1914 /* send number of requested data words */
1915 xscale_send_u32(target
, count
);
1917 /* receive data from target (count times 32-bit words in host endianness) */
1918 buf32
= malloc(4 * count
);
1919 xscale_receive(target
, buf32
, count
);
1921 /* extract data from host-endian buffer into byte stream */
1922 for (i
= 0; i
< count
; i
++)
1927 target_buffer_set_u32(target
, buffer
, buf32
[i
]);
1931 target_buffer_set_u16(target
, buffer
, buf32
[i
] & 0xffff);
1935 *buffer
++ = buf32
[i
] & 0xff;
1938 ERROR("should never get here");
1945 /* examine DCSR, to see if Sticky Abort (SA) got set */
1946 xscale_read_dcsr(target
);
1947 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
1950 xscale_send_u32(target
, 0x60);
1952 return ERROR_TARGET_DATA_ABORT
;
1958 int xscale_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1960 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1961 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1963 DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address
, size
, count
);
1965 if (target
->state
!= TARGET_HALTED
)
1967 WARNING("target not halted");
1968 return ERROR_TARGET_NOT_HALTED
;
1971 /* sanitize arguments */
1972 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1973 return ERROR_INVALID_ARGUMENTS
;
1975 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1976 return ERROR_TARGET_UNALIGNED_ACCESS
;
1978 /* send memory write request (command 0x2n, n: access size) */
1979 xscale_send_u32(target
, 0x20 | size
);
1981 /* send base address for read request */
1982 xscale_send_u32(target
, address
);
1984 /* send number of requested data words to be written*/
1985 xscale_send_u32(target
, count
);
1987 /* extract data from host-endian buffer into byte stream */
1989 for (i
= 0; i
< count
; i
++)
1994 value
= target_buffer_get_u32(target
, buffer
);
1995 xscale_send_u32(target
, value
);
1999 value
= target_buffer_get_u16(target
, buffer
);
2000 xscale_send_u32(target
, value
);
2005 xscale_send_u32(target
, value
);
2009 ERROR("should never get here");
2014 xscale_send(target
, buffer
, count
, size
);
2016 /* examine DCSR, to see if Sticky Abort (SA) got set */
2017 xscale_read_dcsr(target
);
2018 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
2021 xscale_send_u32(target
, 0x60);
2023 return ERROR_TARGET_DATA_ABORT
;
2029 int xscale_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
2031 return xscale_write_memory(target
, address
, 4, count
, buffer
);
2034 int xscale_checksum_memory(struct target_s
*target
, u32 address
, u32 count
, u32
* checksum
)
2036 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2039 u32
xscale_get_ttb(target_t
*target
)
2041 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2042 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2045 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_TTB
]);
2046 ttb
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_TTB
].value
, 0, 32);
2051 void xscale_disable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
2053 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2054 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2057 /* read cp15 control register */
2058 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2059 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2062 cp15_control
&= ~0x1U
;
2067 xscale_send_u32(target
, 0x50);
2068 xscale_send_u32(target
, xscale
->cache_clean_address
);
2070 /* invalidate DCache */
2071 xscale_send_u32(target
, 0x51);
2073 cp15_control
&= ~0x4U
;
2078 /* invalidate ICache */
2079 xscale_send_u32(target
, 0x52);
2080 cp15_control
&= ~0x1000U
;
2083 /* write new cp15 control register */
2084 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2086 /* execute cpwait to ensure outstanding operations complete */
2087 xscale_send_u32(target
, 0x53);
2090 void xscale_enable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
2092 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2093 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2096 /* read cp15 control register */
2097 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2098 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2101 cp15_control
|= 0x1U
;
2104 cp15_control
|= 0x4U
;
2107 cp15_control
|= 0x1000U
;
2109 /* write new cp15 control register */
2110 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2112 /* execute cpwait to ensure outstanding operations complete */
2113 xscale_send_u32(target
, 0x53);
2116 int xscale_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2118 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2119 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2121 if (target
->state
!= TARGET_HALTED
)
2123 WARNING("target not halted");
2124 return ERROR_TARGET_NOT_HALTED
;
2127 if (xscale
->force_hw_bkpts
)
2128 breakpoint
->type
= BKPT_HARD
;
2130 if (breakpoint
->set
)
2132 WARNING("breakpoint already set");
2136 if (breakpoint
->type
== BKPT_HARD
)
2138 u32 value
= breakpoint
->address
| 1;
2139 if (!xscale
->ibcr0_used
)
2141 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], value
);
2142 xscale
->ibcr0_used
= 1;
2143 breakpoint
->set
= 1; /* breakpoint set on first breakpoint register */
2145 else if (!xscale
->ibcr1_used
)
2147 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], value
);
2148 xscale
->ibcr1_used
= 1;
2149 breakpoint
->set
= 2; /* breakpoint set on second breakpoint register */
2153 ERROR("BUG: no hardware comparator available");
2157 else if (breakpoint
->type
== BKPT_SOFT
)
2159 if (breakpoint
->length
== 4)
2161 /* keep the original instruction in target endianness */
2162 target
->type
->read_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
);
2163 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2164 target_write_u32(target
, breakpoint
->address
, xscale
->arm_bkpt
);
2168 /* keep the original instruction in target endianness */
2169 target
->type
->read_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
);
2170 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2171 target_write_u32(target
, breakpoint
->address
, xscale
->thumb_bkpt
);
2173 breakpoint
->set
= 1;
2180 int xscale_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2182 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2183 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2185 if (target
->state
!= TARGET_HALTED
)
2187 WARNING("target not halted");
2188 return ERROR_TARGET_NOT_HALTED
;
2191 if (xscale
->force_hw_bkpts
)
2193 DEBUG("forcing use of hardware breakpoint at address 0x%8.8x", breakpoint
->address
);
2194 breakpoint
->type
= BKPT_HARD
;
2197 if ((breakpoint
->type
== BKPT_HARD
) && (xscale
->ibcr_available
< 1))
2199 INFO("no breakpoint unit available for hardware breakpoint");
2200 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2204 xscale
->ibcr_available
--;
2207 if ((breakpoint
->length
!= 2) && (breakpoint
->length
!= 4))
2209 INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
2210 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2216 int xscale_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2218 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2219 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2221 if (target
->state
!= TARGET_HALTED
)
2223 WARNING("target not halted");
2224 return ERROR_TARGET_NOT_HALTED
;
2227 if (!breakpoint
->set
)
2229 WARNING("breakpoint not set");
2233 if (breakpoint
->type
== BKPT_HARD
)
2235 if (breakpoint
->set
== 1)
2237 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], 0x0);
2238 xscale
->ibcr0_used
= 0;
2240 else if (breakpoint
->set
== 2)
2242 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], 0x0);
2243 xscale
->ibcr1_used
= 0;
2245 breakpoint
->set
= 0;
2249 /* restore original instruction (kept in target endianness) */
2250 if (breakpoint
->length
== 4)
2252 target
->type
->write_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
);
2256 target
->type
->write_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
);
2258 breakpoint
->set
= 0;
2264 int xscale_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2266 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2267 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2269 if (target
->state
!= TARGET_HALTED
)
2271 WARNING("target not halted");
2272 return ERROR_TARGET_NOT_HALTED
;
2275 if (breakpoint
->set
)
2277 xscale_unset_breakpoint(target
, breakpoint
);
2280 if (breakpoint
->type
== BKPT_HARD
)
2281 xscale
->ibcr_available
++;
2286 int xscale_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2288 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2289 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2291 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2292 u32 dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2294 if (target
->state
!= TARGET_HALTED
)
2296 WARNING("target not halted");
2297 return ERROR_TARGET_NOT_HALTED
;
2300 xscale_get_reg(dbcon
);
2302 switch (watchpoint
->rw
)
2314 ERROR("BUG: watchpoint->rw neither read, write nor access");
2317 if (!xscale
->dbr0_used
)
2319 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR0
], watchpoint
->address
);
2320 dbcon_value
|= enable
;
2321 xscale_set_reg_u32(dbcon
, dbcon_value
);
2322 watchpoint
->set
= 1;
2323 xscale
->dbr0_used
= 1;
2325 else if (!xscale
->dbr1_used
)
2327 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR1
], watchpoint
->address
);
2328 dbcon_value
|= enable
<< 2;
2329 xscale_set_reg_u32(dbcon
, dbcon_value
);
2330 watchpoint
->set
= 2;
2331 xscale
->dbr1_used
= 1;
2335 ERROR("BUG: no hardware comparator available");
2342 int xscale_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2344 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2345 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2347 if (target
->state
!= TARGET_HALTED
)
2349 WARNING("target not halted");
2350 return ERROR_TARGET_NOT_HALTED
;
2353 if (xscale
->dbr_available
< 1)
2355 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2358 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
2360 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2363 xscale
->dbr_available
--;
2368 int xscale_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2370 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2371 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2372 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2373 u32 dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2375 if (target
->state
!= TARGET_HALTED
)
2377 WARNING("target not halted");
2378 return ERROR_TARGET_NOT_HALTED
;
2381 if (!watchpoint
->set
)
2383 WARNING("breakpoint not set");
2387 if (watchpoint
->set
== 1)
2389 dbcon_value
&= ~0x3;
2390 xscale_set_reg_u32(dbcon
, dbcon_value
);
2391 xscale
->dbr0_used
= 0;
2393 else if (watchpoint
->set
== 2)
2395 dbcon_value
&= ~0xc;
2396 xscale_set_reg_u32(dbcon
, dbcon_value
);
2397 xscale
->dbr1_used
= 0;
2399 watchpoint
->set
= 0;
2404 int xscale_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2406 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2407 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2409 if (target
->state
!= TARGET_HALTED
)
2411 WARNING("target not halted");
2412 return ERROR_TARGET_NOT_HALTED
;
2415 if (watchpoint
->set
)
2417 xscale_unset_watchpoint(target
, watchpoint
);
2420 xscale
->dbr_available
++;
2425 void xscale_enable_watchpoints(struct target_s
*target
)
2427 watchpoint_t
*watchpoint
= target
->watchpoints
;
2431 if (watchpoint
->set
== 0)
2432 xscale_set_watchpoint(target
, watchpoint
);
2433 watchpoint
= watchpoint
->next
;
2437 void xscale_enable_breakpoints(struct target_s
*target
)
2439 breakpoint_t
*breakpoint
= target
->breakpoints
;
2441 /* set any pending breakpoints */
2444 if (breakpoint
->set
== 0)
2445 xscale_set_breakpoint(target
, breakpoint
);
2446 breakpoint
= breakpoint
->next
;
2450 int xscale_get_reg(reg_t
*reg
)
2452 xscale_reg_t
*arch_info
= reg
->arch_info
;
2453 target_t
*target
= arch_info
->target
;
2454 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2455 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2457 /* DCSR, TX and RX are accessible via JTAG */
2458 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2460 return xscale_read_dcsr(arch_info
->target
);
2462 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2464 /* 1 = consume register content */
2465 return xscale_read_tx(arch_info
->target
, 1);
2467 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2469 /* can't read from RX register (host -> debug handler) */
2472 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2474 /* can't (explicitly) read from TXRXCTRL register */
2477 else /* Other DBG registers have to be transfered by the debug handler */
2479 /* send CP read request (command 0x40) */
2480 xscale_send_u32(target
, 0x40);
2482 /* send CP register number */
2483 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2485 /* read register value */
2486 xscale_read_tx(target
, 1);
2487 buf_cpy(xscale
->reg_cache
->reg_list
[XSCALE_TX
].value
, reg
->value
, 32);
2496 int xscale_set_reg(reg_t
*reg
, u8
* buf
)
2498 xscale_reg_t
*arch_info
= reg
->arch_info
;
2499 target_t
*target
= arch_info
->target
;
2500 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2501 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2502 u32 value
= buf_get_u32(buf
, 0, 32);
2504 /* DCSR, TX and RX are accessible via JTAG */
2505 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2507 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32, value
);
2508 return xscale_write_dcsr(arch_info
->target
, -1, -1);
2510 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2512 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
2513 return xscale_write_rx(arch_info
->target
);
2515 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2517 /* can't write to TX register (debug-handler -> host) */
2520 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2522 /* can't (explicitly) write to TXRXCTRL register */
2525 else /* Other DBG registers have to be transfered by the debug handler */
2527 /* send CP write request (command 0x41) */
2528 xscale_send_u32(target
, 0x41);
2530 /* send CP register number */
2531 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2533 /* send CP register value */
2534 xscale_send_u32(target
, value
);
2535 buf_set_u32(reg
->value
, 0, 32, value
);
2541 /* convenience wrapper to access XScale specific registers */
2542 int xscale_set_reg_u32(reg_t
*reg
, u32 value
)
2546 buf_set_u32(buf
, 0, 32, value
);
2548 return xscale_set_reg(reg
, buf
);
2551 int xscale_write_dcsr_sw(target_t
*target
, u32 value
)
2553 /* get pointers to arch-specific information */
2554 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2555 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2556 reg_t
*dcsr
= &xscale
->reg_cache
->reg_list
[XSCALE_DCSR
];
2557 xscale_reg_t
*dcsr_arch_info
= dcsr
->arch_info
;
2559 /* send CP write request (command 0x41) */
2560 xscale_send_u32(target
, 0x41);
2562 /* send CP register number */
2563 xscale_send_u32(target
, dcsr_arch_info
->dbg_handler_number
);
2565 /* send CP register value */
2566 xscale_send_u32(target
, value
);
2567 buf_set_u32(dcsr
->value
, 0, 32, value
);
2572 int xscale_read_trace(target_t
*target
)
2574 /* get pointers to arch-specific information */
2575 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2576 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2577 xscale_trace_data_t
**trace_data_p
;
2579 /* 258 words from debug handler
2580 * 256 trace buffer entries
2581 * 2 checkpoint addresses
2583 u32 trace_buffer
[258];
2584 int is_address
[256];
2587 if (target
->state
!= TARGET_HALTED
)
2589 WARNING("target must be stopped to read trace data");
2590 return ERROR_TARGET_NOT_HALTED
;
2593 /* send read trace buffer command (command 0x61) */
2594 xscale_send_u32(target
, 0x61);
2596 /* receive trace buffer content */
2597 xscale_receive(target
, trace_buffer
, 258);
2599 /* parse buffer backwards to identify address entries */
2600 for (i
= 255; i
>= 0; i
--)
2603 if (((trace_buffer
[i
] & 0xf0) == 0x90) ||
2604 ((trace_buffer
[i
] & 0xf0) == 0xd0))
2607 is_address
[--i
] = 1;
2609 is_address
[--i
] = 1;
2611 is_address
[--i
] = 1;
2613 is_address
[--i
] = 1;
2618 /* search first non-zero entry */
2619 for (j
= 0; (j
< 256) && (trace_buffer
[j
] == 0) && (!is_address
[j
]); j
++)
2624 DEBUG("no trace data collected");
2625 return ERROR_XSCALE_NO_TRACE_DATA
;
2628 for (trace_data_p
= &xscale
->trace
.data
; *trace_data_p
; trace_data_p
= &(*trace_data_p
)->next
)
2631 *trace_data_p
= malloc(sizeof(xscale_trace_data_t
));
2632 (*trace_data_p
)->next
= NULL
;
2633 (*trace_data_p
)->chkpt0
= trace_buffer
[256];
2634 (*trace_data_p
)->chkpt1
= trace_buffer
[257];
2635 (*trace_data_p
)->last_instruction
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
2636 (*trace_data_p
)->entries
= malloc(sizeof(xscale_trace_entry_t
) * (256 - j
));
2637 (*trace_data_p
)->depth
= 256 - j
;
2639 for (i
= j
; i
< 256; i
++)
2641 (*trace_data_p
)->entries
[i
- j
].data
= trace_buffer
[i
];
2643 (*trace_data_p
)->entries
[i
- j
].type
= XSCALE_TRACE_ADDRESS
;
2645 (*trace_data_p
)->entries
[i
- j
].type
= XSCALE_TRACE_MESSAGE
;
2651 int xscale_read_instruction(target_t
*target
, arm_instruction_t
*instruction
)
2653 /* get pointers to arch-specific information */
2654 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2655 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2662 if (!xscale
->trace
.image
)
2663 return ERROR_TRACE_IMAGE_UNAVAILABLE
;
2665 /* search for the section the current instruction belongs to */
2666 for (i
= 0; i
< xscale
->trace
.image
->num_sections
; i
++)
2668 if ((xscale
->trace
.image
->sections
[i
].base_address
<= xscale
->trace
.current_pc
) &&
2669 (xscale
->trace
.image
->sections
[i
].base_address
+ xscale
->trace
.image
->sections
[i
].size
> xscale
->trace
.current_pc
))
2678 /* current instruction couldn't be found in the image */
2679 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2682 if (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
)
2685 if ((retval
= image_read_section(xscale
->trace
.image
, section
,
2686 xscale
->trace
.current_pc
- xscale
->trace
.image
->sections
[section
].base_address
,
2687 4, buf
, &size_read
)) != ERROR_OK
)
2689 ERROR("error while reading instruction: %i", retval
);
2690 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2692 opcode
= target_buffer_get_u32(target
, buf
);
2693 arm_evaluate_opcode(opcode
, xscale
->trace
.current_pc
, instruction
);
2695 else if (xscale
->trace
.core_state
== ARMV4_5_STATE_THUMB
)
2698 if ((retval
= image_read_section(xscale
->trace
.image
, section
,
2699 xscale
->trace
.current_pc
- xscale
->trace
.image
->sections
[section
].base_address
,
2700 2, buf
, &size_read
)) != ERROR_OK
)
2702 ERROR("error while reading instruction: %i", retval
);
2703 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2705 opcode
= target_buffer_get_u16(target
, buf
);
2706 thumb_evaluate_opcode(opcode
, xscale
->trace
.current_pc
, instruction
);
2710 ERROR("BUG: unknown core state encountered");
2717 int xscale_branch_address(xscale_trace_data_t
*trace_data
, int i
, u32
*target
)
2719 /* if there are less than four entries prior to the indirect branch message
2720 * we can't extract the address */
2726 *target
= (trace_data
->entries
[i
-1].data
) | (trace_data
->entries
[i
-2].data
<< 8) |
2727 (trace_data
->entries
[i
-3].data
<< 16) | (trace_data
->entries
[i
-4].data
<< 24);
2732 int xscale_analyze_trace(target_t
*target
, command_context_t
*cmd_ctx
)
2734 /* get pointers to arch-specific information */
2735 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2736 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2739 xscale_trace_data_t
*trace_data
= xscale
->trace
.data
;
2748 xscale
->trace
.core_state
= ARMV4_5_STATE_ARM
;
2753 for (i
= 0; i
< trace_data
->depth
; i
++)
2759 if (trace_data
->entries
[i
].type
== XSCALE_TRACE_ADDRESS
)
2762 switch ((trace_data
->entries
[i
].data
& 0xf0) >> 4)
2764 case 0: /* Exceptions */
2772 exception
= (trace_data
->entries
[i
].data
& 0x70) >> 4;
2774 next_pc
= (trace_data
->entries
[i
].data
& 0xf0) >> 2;
2775 command_print(cmd_ctx
, "--- exception %i ---", (trace_data
->entries
[i
].data
& 0xf0) >> 4);
2777 case 8: /* Direct Branch */
2780 case 9: /* Indirect Branch */
2782 if (xscale_branch_address(trace_data
, i
, &next_pc
) == 0)
2787 case 13: /* Checkpointed Indirect Branch */
2788 if (xscale_branch_address(trace_data
, i
, &next_pc
) == 0)
2791 if (((chkpt
== 0) && (next_pc
!= trace_data
->chkpt0
))
2792 || ((chkpt
== 1) && (next_pc
!= trace_data
->chkpt1
)))
2793 WARNING("checkpointed indirect branch target address doesn't match checkpoint");
2795 /* explicit fall-through */
2796 case 12: /* Checkpointed Direct Branch */
2801 next_pc
= trace_data
->chkpt0
;
2804 else if (chkpt
== 1)
2807 next_pc
= trace_data
->chkpt0
;
2812 WARNING("more than two checkpointed branches encountered");
2815 case 15: /* Roll-over */
2818 default: /* Reserved */
2819 command_print(cmd_ctx
, "--- reserved trace message ---");
2820 ERROR("BUG: trace message %i is reserved", (trace_data
->entries
[i
].data
& 0xf0) >> 4);
2824 if (xscale
->trace
.pc_ok
)
2826 int executed
= (trace_data
->entries
[i
].data
& 0xf) + rollover
* 16;
2827 arm_instruction_t instruction
;
2829 if ((exception
== 6) || (exception
== 7))
2831 /* IRQ or FIQ exception, no instruction executed */
2835 while (executed
-- >= 0)
2837 if ((retval
= xscale_read_instruction(target
, &instruction
)) != ERROR_OK
)
2839 /* can't continue tracing with no image available */
2840 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
2844 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
2846 /* TODO: handle incomplete images */
2850 /* a precise abort on a load to the PC is included in the incremental
2851 * word count, other instructions causing data aborts are not included
2853 if ((executed
== 0) && (exception
== 4)
2854 && ((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_LDM
)))
2856 if ((instruction
.type
== ARM_LDM
)
2857 && ((instruction
.info
.load_store_multiple
.register_list
& 0x8000) == 0))
2861 else if (((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_LDRSH
))
2862 && (instruction
.info
.load_store
.Rd
!= 15))
2868 /* only the last instruction executed
2869 * (the one that caused the control flow change)
2870 * could be a taken branch
2872 if (((executed
== -1) && (branch
== 1)) &&
2873 (((instruction
.type
== ARM_B
) ||
2874 (instruction
.type
== ARM_BL
) ||
2875 (instruction
.type
== ARM_BLX
)) &&
2876 (instruction
.info
.b_bl_bx_blx
.target_address
!= -1)))
2878 xscale
->trace
.current_pc
= instruction
.info
.b_bl_bx_blx
.target_address
;
2882 xscale
->trace
.current_pc
+= (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2;
2884 command_print(cmd_ctx
, "%s", instruction
.text
);
2892 xscale
->trace
.current_pc
= next_pc
;
2893 xscale
->trace
.pc_ok
= 1;
2897 for (; xscale
->trace
.current_pc
< trace_data
->last_instruction
; xscale
->trace
.current_pc
+= (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2)
2899 arm_instruction_t instruction
;
2900 if ((retval
= xscale_read_instruction(target
, &instruction
)) != ERROR_OK
)
2902 /* can't continue tracing with no image available */
2903 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
2907 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
2909 /* TODO: handle incomplete images */
2912 command_print(cmd_ctx
, "%s", instruction
.text
);
2915 trace_data
= trace_data
->next
;
2921 void xscale_build_reg_cache(target_t
*target
)
2923 /* get pointers to arch-specific information */
2924 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2925 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2927 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
2928 xscale_reg_t
*arch_info
= malloc(sizeof(xscale_reg_arch_info
));
2930 int num_regs
= sizeof(xscale_reg_arch_info
) / sizeof(xscale_reg_t
);
2932 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
2933 armv4_5
->core_cache
= (*cache_p
);
2935 /* register a register arch-type for XScale dbg registers only once */
2936 if (xscale_reg_arch_type
== -1)
2937 xscale_reg_arch_type
= register_reg_arch_type(xscale_get_reg
, xscale_set_reg
);
2939 (*cache_p
)->next
= malloc(sizeof(reg_cache_t
));
2940 cache_p
= &(*cache_p
)->next
;
2942 /* fill in values for the xscale reg cache */
2943 (*cache_p
)->name
= "XScale registers";
2944 (*cache_p
)->next
= NULL
;
2945 (*cache_p
)->reg_list
= malloc(num_regs
* sizeof(reg_t
));
2946 (*cache_p
)->num_regs
= num_regs
;
2948 for (i
= 0; i
< num_regs
; i
++)
2950 (*cache_p
)->reg_list
[i
].name
= xscale_reg_list
[i
];
2951 (*cache_p
)->reg_list
[i
].value
= calloc(4, 1);
2952 (*cache_p
)->reg_list
[i
].dirty
= 0;
2953 (*cache_p
)->reg_list
[i
].valid
= 0;
2954 (*cache_p
)->reg_list
[i
].size
= 32;
2955 (*cache_p
)->reg_list
[i
].bitfield_desc
= NULL
;
2956 (*cache_p
)->reg_list
[i
].num_bitfields
= 0;
2957 (*cache_p
)->reg_list
[i
].arch_info
= &arch_info
[i
];
2958 (*cache_p
)->reg_list
[i
].arch_type
= xscale_reg_arch_type
;
2959 arch_info
[i
] = xscale_reg_arch_info
[i
];
2960 arch_info
[i
].target
= target
;
2963 xscale
->reg_cache
= (*cache_p
);
2966 int xscale_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
2968 if (startup_mode
!= DAEMON_RESET
)
2970 ERROR("XScale target requires a reset");
2971 ERROR("Reset target to enable debug");
2974 /* assert TRST once during startup */
2975 jtag_add_reset(1, 0);
2976 jtag_add_sleep(5000);
2977 jtag_add_reset(0, 0);
2978 jtag_execute_queue();
2989 int xscale_init_arch_info(target_t
*target
, xscale_common_t
*xscale
, int chain_pos
, char *variant
)
2991 armv4_5_common_t
*armv4_5
;
2992 u32 high_reset_branch
, low_reset_branch
;
2995 armv4_5
= &xscale
->armv4_5_common
;
2997 /* store architecture specfic data (none so far) */
2998 xscale
->arch_info
= NULL
;
2999 xscale
->common_magic
= XSCALE_COMMON_MAGIC
;
3001 /* remember the variant (PXA25x, PXA27x, IXP42x, ...) */
3002 xscale
->variant
= strdup(variant
);
3004 /* prepare JTAG information for the new target */
3005 xscale
->jtag_info
.chain_pos
= chain_pos
;
3006 jtag_register_event_callback(xscale_jtag_callback
, target
);
3008 xscale
->jtag_info
.dbgrx
= 0x02;
3009 xscale
->jtag_info
.dbgtx
= 0x10;
3010 xscale
->jtag_info
.dcsr
= 0x09;
3011 xscale
->jtag_info
.ldic
= 0x07;
3013 if ((strcmp(xscale
->variant
, "pxa250") == 0) ||
3014 (strcmp(xscale
->variant
, "pxa255") == 0) ||
3015 (strcmp(xscale
->variant
, "pxa26x") == 0))
3017 xscale
->jtag_info
.ir_length
= 5;
3019 else if ((strcmp(xscale
->variant
, "pxa27x") == 0) ||
3020 (strcmp(xscale
->variant
, "ixp42x") == 0) ||
3021 (strcmp(xscale
->variant
, "ixp45x") == 0) ||
3022 (strcmp(xscale
->variant
, "ixp46x") == 0))
3024 xscale
->jtag_info
.ir_length
= 7;
3027 /* the debug handler isn't installed (and thus not running) at this time */
3028 xscale
->handler_installed
= 0;
3029 xscale
->handler_running
= 0;
3030 xscale
->handler_address
= 0xfe000800;
3032 /* clear the vectors we keep locally for reference */
3033 memset(xscale
->low_vectors
, 0, sizeof(xscale
->low_vectors
));
3034 memset(xscale
->high_vectors
, 0, sizeof(xscale
->high_vectors
));
3036 /* no user-specified vectors have been configured yet */
3037 xscale
->static_low_vectors_set
= 0x0;
3038 xscale
->static_high_vectors_set
= 0x0;
3040 /* calculate branches to debug handler */
3041 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
3042 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
3044 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
3045 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
3047 for (i
= 1; i
<= 7; i
++)
3049 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
3050 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
3053 /* 64kB aligned region used for DCache cleaning */
3054 xscale
->cache_clean_address
= 0xfffe0000;
3056 xscale
->hold_rst
= 0;
3057 xscale
->external_debug_break
= 0;
3059 xscale
->force_hw_bkpts
= 1;
3061 xscale
->ibcr_available
= 2;
3062 xscale
->ibcr0_used
= 0;
3063 xscale
->ibcr1_used
= 0;
3065 xscale
->dbr_available
= 2;
3066 xscale
->dbr0_used
= 0;
3067 xscale
->dbr1_used
= 0;
3069 xscale
->arm_bkpt
= ARMV5_BKPT(0x0);
3070 xscale
->thumb_bkpt
= ARMV5_T_BKPT(0x0) & 0xffff;
3072 xscale
->vector_catch
= 0x1;
3074 xscale
->trace
.capture_status
= TRACE_IDLE
;
3075 xscale
->trace
.data
= NULL
;
3076 xscale
->trace
.image
= NULL
;
3077 xscale
->trace
.buffer_enabled
= 0;
3078 xscale
->trace
.buffer_fill
= 0;
3080 /* prepare ARMv4/5 specific information */
3081 armv4_5
->arch_info
= xscale
;
3082 armv4_5
->read_core_reg
= xscale_read_core_reg
;
3083 armv4_5
->write_core_reg
= xscale_write_core_reg
;
3084 armv4_5
->full_context
= xscale_full_context
;
3086 armv4_5_init_arch_info(target
, armv4_5
);
3088 xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
3089 xscale
->armv4_5_mmu
.get_ttb
= xscale_get_ttb
;
3090 xscale
->armv4_5_mmu
.read_memory
= xscale_read_memory
;
3091 xscale
->armv4_5_mmu
.write_memory
= xscale_write_memory
;
3092 xscale
->armv4_5_mmu
.disable_mmu_caches
= xscale_disable_mmu_caches
;
3093 xscale
->armv4_5_mmu
.enable_mmu_caches
= xscale_enable_mmu_caches
;
3094 xscale
->armv4_5_mmu
.has_tiny_pages
= 1;
3095 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3100 /* target xscale <endianess> <startup_mode> <chain_pos> <variant> */
3101 int xscale_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
)
3104 char *variant
= NULL
;
3105 xscale_common_t
*xscale
= malloc(sizeof(xscale_common_t
));
3109 ERROR("'target xscale' requires four arguments: <endianess> <startup_mode> <chain_pos> <variant>");
3113 chain_pos
= strtoul(args
[3], NULL
, 0);
3117 xscale_init_arch_info(target
, xscale
, chain_pos
, variant
);
3118 xscale_build_reg_cache(target
);
3123 int xscale_handle_debug_handler_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3125 target_t
*target
= NULL
;
3126 armv4_5_common_t
*armv4_5
;
3127 xscale_common_t
*xscale
;
3129 u32 handler_address
;
3133 ERROR("'xscale debug_handler <target#> <address>' command takes two required operands");
3137 if ((target
= get_target_by_num(strtoul(args
[0], NULL
, 0))) == NULL
)
3139 ERROR("no target '%s' configured", args
[0]);
3143 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3145 command_print(cmd_ctx
, "target isn't an ARM920t target");
3149 handler_address
= strtoul(args
[1], NULL
, 0);
3151 if (((handler_address
>= 0x800) && (handler_address
<= 0x1fef800)) ||
3152 ((handler_address
>= 0xfe000800) && (handler_address
<= 0xfffff800)))
3154 xscale
->handler_address
= handler_address
;
3158 ERROR("xscale debug_handler <address> must be between 0x800 and 0x1fef800 or between 0xfe000800 and 0xfffff800");
3164 int xscale_handle_cache_clean_address_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3166 target_t
*target
= NULL
;
3167 armv4_5_common_t
*armv4_5
;
3168 xscale_common_t
*xscale
;
3170 u32 cache_clean_address
;
3174 ERROR("'xscale cache_clean_address <target#> <address>' command takes two required operands");
3178 if ((target
= get_target_by_num(strtoul(args
[0], NULL
, 0))) == NULL
)
3180 ERROR("no target '%s' configured", args
[0]);
3184 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3186 command_print(cmd_ctx
, "target isn't an XScale target");
3190 cache_clean_address
= strtoul(args
[1], NULL
, 0);
3192 if (cache_clean_address
& 0xffff)
3194 ERROR("xscale cache_clean_address <address> must be 64kb aligned");
3198 xscale
->cache_clean_address
= cache_clean_address
;
3204 int xscale_handle_cache_info_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3206 target_t
*target
= get_current_target(cmd_ctx
);
3207 armv4_5_common_t
*armv4_5
;
3208 xscale_common_t
*xscale
;
3210 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3212 command_print(cmd_ctx
, "target isn't an XScale target");
3216 return armv4_5_handle_cache_info_command(cmd_ctx
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
3219 int xscale_handle_virt2phys_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3221 target_t
*target
= get_current_target(cmd_ctx
);
3222 armv4_5_common_t
*armv4_5
;
3223 xscale_common_t
*xscale
;
3225 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3227 command_print(cmd_ctx
, "target isn't an XScale target");
3231 if (target
->state
!= TARGET_HALTED
)
3233 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3237 return armv4_5_mmu_handle_virt2phys_command(cmd_ctx
, cmd
, args
, argc
, target
, &xscale
->armv4_5_mmu
);
3240 int xscale_handle_mmu_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3242 target_t
*target
= get_current_target(cmd_ctx
);
3243 armv4_5_common_t
*armv4_5
;
3244 xscale_common_t
*xscale
;
3246 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3248 command_print(cmd_ctx
, "target isn't an XScale target");
3252 if (target
->state
!= TARGET_HALTED
)
3254 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3260 if (strcmp("enable", args
[0]) == 0)
3262 xscale_enable_mmu_caches(target
, 1, 0, 0);
3263 xscale
->armv4_5_mmu
.mmu_enabled
= 1;
3265 else if (strcmp("disable", args
[0]) == 0)
3267 xscale_disable_mmu_caches(target
, 1, 0, 0);
3268 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3272 command_print(cmd_ctx
, "mmu %s", (xscale
->armv4_5_mmu
.mmu_enabled
) ? "enabled" : "disabled");
3277 int xscale_handle_idcache_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3279 target_t
*target
= get_current_target(cmd_ctx
);
3280 armv4_5_common_t
*armv4_5
;
3281 xscale_common_t
*xscale
;
3282 int icache
= 0, dcache
= 0;
3284 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3286 command_print(cmd_ctx
, "target isn't an XScale target");
3290 if (target
->state
!= TARGET_HALTED
)
3292 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3296 if (strcmp(cmd
, "icache") == 0)
3298 else if (strcmp(cmd
, "dcache") == 0)
3303 if (strcmp("enable", args
[0]) == 0)
3305 xscale_enable_mmu_caches(target
, 0, dcache
, icache
);
3308 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 1;
3310 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 1;
3312 else if (strcmp("disable", args
[0]) == 0)
3314 xscale_disable_mmu_caches(target
, 0, dcache
, icache
);
3317 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 0;
3319 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 0;
3324 command_print(cmd_ctx
, "icache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
) ? "enabled" : "disabled");
3327 command_print(cmd_ctx
, "dcache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
) ? "enabled" : "disabled");
3332 int xscale_handle_vector_catch_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3334 target_t
*target
= get_current_target(cmd_ctx
);
3335 armv4_5_common_t
*armv4_5
;
3336 xscale_common_t
*xscale
;
3338 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3340 command_print(cmd_ctx
, "target isn't an XScale target");
3346 command_print(cmd_ctx
, "usage: xscale vector_catch [mask]");
3350 xscale
->vector_catch
= strtoul(args
[0], NULL
, 0);
3351 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 8, xscale
->vector_catch
);
3352 xscale_write_dcsr(target
, -1, -1);
3355 command_print(cmd_ctx
, "vector catch mask: 0x%2.2x", xscale
->vector_catch
);
3360 int xscale_handle_force_hw_bkpts_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3362 target_t
*target
= get_current_target(cmd_ctx
);
3363 armv4_5_common_t
*armv4_5
;
3364 xscale_common_t
*xscale
;
3366 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3368 command_print(cmd_ctx
, "target isn't an XScale target");
3372 if ((argc
>= 1) && (strcmp("enable", args
[0]) == 0))
3374 xscale
->force_hw_bkpts
= 1;
3376 else if ((argc
>= 1) && (strcmp("disable", args
[0]) == 0))
3378 xscale
->force_hw_bkpts
= 0;
3382 command_print(cmd_ctx
, "usage: xscale force_hw_bkpts <enable|disable>");
3385 command_print(cmd_ctx
, "force hardware breakpoints %s", (xscale
->force_hw_bkpts
) ? "enabled" : "disabled");
3390 int xscale_handle_trace_buffer_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3392 target_t
*target
= get_current_target(cmd_ctx
);
3393 armv4_5_common_t
*armv4_5
;
3394 xscale_common_t
*xscale
;
3397 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3399 command_print(cmd_ctx
, "target isn't an XScale target");
3403 if (target
->state
!= TARGET_HALTED
)
3405 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3409 if ((argc
>= 1) && (strcmp("enable", args
[0]) == 0))
3411 xscale_trace_data_t
*td
, *next_td
;
3412 xscale
->trace
.buffer_enabled
= 1;
3414 /* free old trace data */
3415 td
= xscale
->trace
.data
;
3425 xscale
->trace
.data
= NULL
;
3427 else if ((argc
>= 1) && (strcmp("disable", args
[0]) == 0))
3429 xscale
->trace
.buffer_enabled
= 0;
3432 if ((argc
>= 2) && (strcmp("fill", args
[1]) == 0))
3435 xscale
->trace
.buffer_fill
= strtoul(args
[2], NULL
, 0);
3437 xscale
->trace
.buffer_fill
= 1;
3439 else if ((argc
>= 2) && (strcmp("wrap", args
[1]) == 0))
3441 xscale
->trace
.buffer_fill
= -1;
3444 if (xscale
->trace
.buffer_enabled
)
3446 /* if we enable the trace buffer in fill-once
3447 * mode we know the address of the first instruction */
3448 xscale
->trace
.pc_ok
= 1;
3449 xscale
->trace
.current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
3453 /* otherwise the address is unknown, and we have no known good PC */
3454 xscale
->trace
.pc_ok
= 0;
3457 command_print(cmd_ctx
, "trace buffer %s (%s)",
3458 (xscale
->trace
.buffer_enabled
) ? "enabled" : "disabled",
3459 (xscale
->trace
.buffer_fill
> 0) ? "fill" : "wrap");
3461 dcsr_value
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32);
3462 if (xscale
->trace
.buffer_fill
>= 0)
3463 xscale_write_dcsr_sw(target
, (dcsr_value
& 0xfffffffc) | 2);
3465 xscale_write_dcsr_sw(target
, dcsr_value
& 0xfffffffc);
3470 int xscale_handle_trace_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3473 armv4_5_common_t
*armv4_5
;
3474 xscale_common_t
*xscale
;
3478 command_print(cmd_ctx
, "usage: xscale trace_image <file> [base address] [type]");
3482 target
= get_current_target(cmd_ctx
);
3484 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3486 command_print(cmd_ctx
, "target isn't an XScale target");
3490 if (xscale
->trace
.image
)
3492 image_close(xscale
->trace
.image
);
3493 free(xscale
->trace
.image
);
3494 command_print(cmd_ctx
, "previously loaded image found and closed");
3497 xscale
->trace
.image
= malloc(sizeof(image_t
));
3498 xscale
->trace
.image
->base_address_set
= 0;
3499 xscale
->trace
.image
->start_address_set
= 0;
3501 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
3504 xscale
->trace
.image
->base_address_set
= 1;
3505 xscale
->trace
.image
->base_address
= strtoul(args
[1], NULL
, 0);
3509 xscale
->trace
.image
->base_address_set
= 0;
3512 if (image_open(xscale
->trace
.image
, args
[0], (argc
>= 3) ? args
[2] : NULL
) != ERROR_OK
)
3514 command_print(cmd_ctx
, "image opening error: %s", xscale
->trace
.image
->error_str
);
3515 free(xscale
->trace
.image
);
3516 xscale
->trace
.image
= NULL
;
3523 int xscale_handle_dump_trace_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3525 target_t
*target
= get_current_target(cmd_ctx
);
3526 armv4_5_common_t
*armv4_5
;
3527 xscale_common_t
*xscale
;
3528 xscale_trace_data_t
*trace_data
;
3531 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3533 command_print(cmd_ctx
, "target isn't an XScale target");
3537 if (target
->state
!= TARGET_HALTED
)
3539 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3545 command_print(cmd_ctx
, "usage: xscale dump_trace <file>");
3549 trace_data
= xscale
->trace
.data
;
3553 command_print(cmd_ctx
, "no trace data collected");
3557 if (fileio_open(&file
, args
[0], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
)
3559 command_print(cmd_ctx
, "file open error: %s", file
.error_str
);
3567 fileio_write_u32(&file
, trace_data
->chkpt0
);
3568 fileio_write_u32(&file
, trace_data
->chkpt1
);
3569 fileio_write_u32(&file
, trace_data
->last_instruction
);
3570 fileio_write_u32(&file
, trace_data
->depth
);
3572 for (i
= 0; i
< trace_data
->depth
; i
++)
3573 fileio_write_u32(&file
, trace_data
->entries
[i
].data
| ((trace_data
->entries
[i
].type
& 0xffff) << 16));
3575 trace_data
= trace_data
->next
;
3578 fileio_close(&file
);
3583 int xscale_handle_analyze_trace_buffer_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3585 target_t
*target
= get_current_target(cmd_ctx
);
3586 armv4_5_common_t
*armv4_5
;
3587 xscale_common_t
*xscale
;
3589 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3591 command_print(cmd_ctx
, "target isn't an XScale target");
3595 xscale_analyze_trace(target
, cmd_ctx
);
3600 int xscale_handle_cp15(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3602 target_t
*target
= get_current_target(cmd_ctx
);
3603 armv4_5_common_t
*armv4_5
;
3604 xscale_common_t
*xscale
;
3606 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3608 command_print(cmd_ctx
, "target isn't an XScale target");
3612 if (target
->state
!= TARGET_HALTED
)
3614 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3621 reg_no
= strtoul(args
[0], NULL
, 0);
3622 /*translate from xscale cp15 register no to openocd register*/
3626 reg_no
= XSCALE_MAINID
;
3629 reg_no
= XSCALE_CTRL
;
3632 reg_no
= XSCALE_TTB
;
3635 reg_no
= XSCALE_DAC
;
3638 reg_no
= XSCALE_FSR
;
3641 reg_no
= XSCALE_FAR
;
3644 reg_no
= XSCALE_PID
;
3647 reg_no
= XSCALE_CPACCESS
;
3650 command_print(cmd_ctx
, "invalid register number");
3651 return ERROR_INVALID_ARGUMENTS
;
3653 reg
= &xscale
->reg_cache
->reg_list
[reg_no
];
3660 /* read cp15 control register */
3661 xscale_get_reg(reg
);
3662 value
= buf_get_u32(reg
->value
, 0, 32);
3663 command_print(cmd_ctx
, "%s (/%i): 0x%x", reg
->name
, reg
->size
, value
);
3668 u32 value
= strtoul(args
[1], NULL
, 0);
3670 /* send CP write request (command 0x41) */
3671 xscale_send_u32(target
, 0x41);
3673 /* send CP register number */
3674 xscale_send_u32(target
, reg_no
);
3676 /* send CP register value */
3677 xscale_send_u32(target
, value
);
3679 /* execute cpwait to ensure outstanding operations complete */
3680 xscale_send_u32(target
, 0x53);
3684 command_print(cmd_ctx
, "usage: cp15 [register]<, [value]>");
3690 int xscale_register_commands(struct command_context_s
*cmd_ctx
)
3692 command_t
*xscale_cmd
;
3694 xscale_cmd
= register_command(cmd_ctx
, NULL
, "xscale", NULL
, COMMAND_ANY
, "xscale specific commands");
3696 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");
3697 register_command(cmd_ctx
, xscale_cmd
, "cache_clean_address", xscale_handle_cache_clean_address_command
, COMMAND_ANY
, NULL
);
3699 register_command(cmd_ctx
, xscale_cmd
, "cache_info", xscale_handle_cache_info_command
, COMMAND_EXEC
, NULL
);
3700 register_command(cmd_ctx
, xscale_cmd
, "virt2phys", xscale_handle_virt2phys_command
, COMMAND_EXEC
, NULL
);
3701 register_command(cmd_ctx
, xscale_cmd
, "mmu", xscale_handle_mmu_command
, COMMAND_EXEC
, "['enable'|'disable'] the MMU");
3702 register_command(cmd_ctx
, xscale_cmd
, "icache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the ICache");
3703 register_command(cmd_ctx
, xscale_cmd
, "dcache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the DCache");
3705 register_command(cmd_ctx
, xscale_cmd
, "vector_catch", xscale_handle_idcache_command
, COMMAND_EXEC
, "<mask> of vectors that should be catched");
3707 register_command(cmd_ctx
, xscale_cmd
, "trace_buffer", xscale_handle_trace_buffer_command
, COMMAND_EXEC
, "<enable|disable> ['fill' [n]|'wrap']");
3709 register_command(cmd_ctx
, xscale_cmd
, "dump_trace", xscale_handle_dump_trace_command
, COMMAND_EXEC
, "dump content of trace buffer to <file>");
3710 register_command(cmd_ctx
, xscale_cmd
, "analyze_trace", xscale_handle_analyze_trace_buffer_command
, COMMAND_EXEC
, "analyze content of trace buffer");
3711 register_command(cmd_ctx
, xscale_cmd
, "trace_image", xscale_handle_trace_image_command
,
3712 COMMAND_EXEC
, "load image from <file> [base address]");
3714 register_command(cmd_ctx
, xscale_cmd
, "cp15", xscale_handle_cp15
, COMMAND_EXEC
, "access coproc 15 <register> [value]");
3716 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)