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
);
57 int 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
);
87 static int xscale_virt2phys(struct target_s
*target
, u32
virtual, u32
*physical
);
88 static int xscale_mmu(struct target_s
*target
, int *enabled
);
90 int xscale_read_trace(target_t
*target
);
92 target_type_t xscale_target
=
97 .arch_state
= xscale_arch_state
,
99 .target_request_data
= NULL
,
102 .resume
= xscale_resume
,
105 .assert_reset
= xscale_assert_reset
,
106 .deassert_reset
= xscale_deassert_reset
,
107 .soft_reset_halt
= xscale_soft_reset_halt
,
108 .prepare_reset_halt
= xscale_prepare_reset_halt
,
110 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
112 .read_memory
= xscale_read_memory
,
113 .write_memory
= xscale_write_memory
,
114 .bulk_write_memory
= xscale_bulk_write_memory
,
115 .checksum_memory
= xscale_checksum_memory
,
117 .run_algorithm
= armv4_5_run_algorithm
,
119 .add_breakpoint
= xscale_add_breakpoint
,
120 .remove_breakpoint
= xscale_remove_breakpoint
,
121 .add_watchpoint
= xscale_add_watchpoint
,
122 .remove_watchpoint
= xscale_remove_watchpoint
,
124 .register_commands
= xscale_register_commands
,
125 .target_command
= xscale_target_command
,
126 .init_target
= xscale_init_target
,
129 .virt2phys
= xscale_virt2phys
,
133 char* xscale_reg_list
[] =
135 "XSCALE_MAINID", /* 0 */
145 "XSCALE_IBCR0", /* 10 */
155 "XSCALE_RX", /* 20 */
159 xscale_reg_t xscale_reg_arch_info
[] =
161 {XSCALE_MAINID
, NULL
},
162 {XSCALE_CACHETYPE
, NULL
},
164 {XSCALE_AUXCTRL
, NULL
},
170 {XSCALE_CPACCESS
, NULL
},
171 {XSCALE_IBCR0
, NULL
},
172 {XSCALE_IBCR1
, NULL
},
175 {XSCALE_DBCON
, NULL
},
176 {XSCALE_TBREG
, NULL
},
177 {XSCALE_CHKPT0
, NULL
},
178 {XSCALE_CHKPT1
, NULL
},
179 {XSCALE_DCSR
, NULL
}, /* DCSR accessed via JTAG or SW */
180 {-1, NULL
}, /* TX accessed via JTAG */
181 {-1, NULL
}, /* RX accessed via JTAG */
182 {-1, NULL
}, /* TXRXCTRL implicit access via JTAG */
185 int xscale_reg_arch_type
= -1;
187 int xscale_get_reg(reg_t
*reg
);
188 int xscale_set_reg(reg_t
*reg
, u8
*buf
);
190 int xscale_get_arch_pointers(target_t
*target
, armv4_5_common_t
**armv4_5_p
, xscale_common_t
**xscale_p
)
192 armv4_5_common_t
*armv4_5
= target
->arch_info
;
193 xscale_common_t
*xscale
= armv4_5
->arch_info
;
195 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
197 ERROR("target isn't an XScale target");
201 if (xscale
->common_magic
!= XSCALE_COMMON_MAGIC
)
203 ERROR("target isn't an XScale target");
207 *armv4_5_p
= armv4_5
;
213 int xscale_jtag_set_instr(int chain_pos
, u32 new_instr
)
215 jtag_device_t
*device
= jtag_get_device(chain_pos
);
217 if (buf_get_u32(device
->cur_instr
, 0, device
->ir_length
) != new_instr
)
221 field
.device
= chain_pos
;
222 field
.num_bits
= device
->ir_length
;
223 field
.out_value
= calloc(CEIL(field
.num_bits
, 8), 1);
224 buf_set_u32(field
.out_value
, 0, field
.num_bits
, new_instr
);
225 field
.out_mask
= NULL
;
226 field
.in_value
= NULL
;
227 jtag_set_check_value(&field
, device
->expected
, device
->expected_mask
, NULL
);
229 jtag_add_ir_scan(1, &field
, -1);
231 free(field
.out_value
);
237 int xscale_jtag_callback(enum jtag_event event
, void *priv
)
241 case JTAG_TRST_ASSERTED
:
243 case JTAG_TRST_RELEASED
:
245 case JTAG_SRST_ASSERTED
:
247 case JTAG_SRST_RELEASED
:
250 WARNING("unhandled JTAG event");
256 int xscale_read_dcsr(target_t
*target
)
258 armv4_5_common_t
*armv4_5
= target
->arch_info
;
259 xscale_common_t
*xscale
= armv4_5
->arch_info
;
263 scan_field_t fields
[3];
265 u8 field0_check_value
= 0x2;
266 u8 field0_check_mask
= 0x7;
268 u8 field2_check_value
= 0x0;
269 u8 field2_check_mask
= 0x1;
271 jtag_add_end_state(TAP_PD
);
272 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dcsr
);
274 buf_set_u32(&field0
, 1, 1, xscale
->hold_rst
);
275 buf_set_u32(&field0
, 2, 1, xscale
->external_debug_break
);
277 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
278 fields
[0].num_bits
= 3;
279 fields
[0].out_value
= &field0
;
280 fields
[0].out_mask
= NULL
;
281 fields
[0].in_value
= NULL
;
282 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
284 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
285 fields
[1].num_bits
= 32;
286 fields
[1].out_value
= NULL
;
287 fields
[1].out_mask
= NULL
;
288 fields
[1].in_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
289 fields
[1].in_handler
= NULL
;
290 fields
[1].in_handler_priv
= NULL
;
291 fields
[1].in_check_value
= NULL
;
292 fields
[1].in_check_mask
= NULL
;
294 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
295 fields
[2].num_bits
= 1;
296 fields
[2].out_value
= &field2
;
297 fields
[2].out_mask
= NULL
;
298 fields
[2].in_value
= NULL
;
299 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
301 jtag_add_dr_scan(3, fields
, -1);
303 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
305 ERROR("JTAG error while reading DCSR");
309 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].dirty
= 0;
310 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].valid
= 1;
312 /* write the register with the value we just read
313 * on this second pass, only the first bit of field0 is guaranteed to be 0)
315 field0_check_mask
= 0x1;
316 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
317 fields
[1].in_value
= NULL
;
319 jtag_add_end_state(TAP_RTI
);
321 jtag_add_dr_scan(3, fields
, -1);
323 /* DANGER!!! this must be here. It will make sure that the arguments
324 * to jtag_set_check_value() does not go out of scope! */
325 return jtag_execute_queue();
328 int xscale_receive(target_t
*target
, u32
*buffer
, int num_words
)
331 return ERROR_INVALID_ARGUMENTS
;
334 armv4_5_common_t
*armv4_5
= target
->arch_info
;
335 xscale_common_t
*xscale
= armv4_5
->arch_info
;
337 enum tap_state path
[3];
338 scan_field_t fields
[3];
340 u8
*field0
= malloc(num_words
* 1);
341 u8 field0_check_value
= 0x2;
342 u8 field0_check_mask
= 0x6;
343 u32
*field1
= malloc(num_words
* 4);
344 u8 field2_check_value
= 0x0;
345 u8 field2_check_mask
= 0x1;
347 int words_scheduled
= 0;
355 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
356 fields
[0].num_bits
= 3;
357 fields
[0].out_value
= NULL
;
358 fields
[0].out_mask
= NULL
;
359 /* fields[0].in_value = field0; */
360 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
362 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
363 fields
[1].num_bits
= 32;
364 fields
[1].out_value
= NULL
;
365 fields
[1].out_mask
= NULL
;
366 fields
[1].in_value
= NULL
;
367 fields
[1].in_handler
= NULL
;
368 fields
[1].in_handler_priv
= NULL
;
369 fields
[1].in_check_value
= NULL
;
370 fields
[1].in_check_mask
= NULL
;
374 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
375 fields
[2].num_bits
= 1;
376 fields
[2].out_value
= NULL
;
377 fields
[2].out_mask
= NULL
;
378 fields
[2].in_value
= NULL
;
379 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
381 jtag_add_end_state(TAP_RTI
);
382 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dbgtx
);
383 jtag_add_runtest(1, -1);
385 /* repeat until all words have been collected */
387 while (words_done
< num_words
)
391 for (i
= words_done
; i
< num_words
; i
++)
393 fields
[0].in_value
= &field0
[i
];
394 fields
[1].in_handler
= buf_to_u32_handler
;
395 fields
[1].in_handler_priv
= (u8
*)&field1
[i
];
397 jtag_add_pathmove(3, path
);
398 jtag_add_dr_scan(3, fields
, TAP_RTI
);
402 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
404 ERROR("JTAG error while receiving data from debug handler");
408 /* examine results */
409 for (i
= words_done
; i
< num_words
; i
++)
411 if (!(field0
[0] & 1))
413 /* move backwards if necessary */
415 for (j
= i
; j
< num_words
- 1; j
++)
417 field0
[j
] = field0
[j
+1];
418 field1
[j
] = field1
[j
+1];
423 if (words_scheduled
==0)
425 if (attempts
++==1000)
427 ERROR("Failed to receiving data from debug handler after 1000 attempts");
428 retval
=ERROR_JTAG_QUEUE_FAILED
;
433 words_done
+= words_scheduled
;
436 for (i
= 0; i
< num_words
; i
++)
437 *(buffer
++) = buf_get_u32((u8
*)&field1
[i
], 0, 32);
444 int xscale_read_tx(target_t
*target
, int consume
)
446 armv4_5_common_t
*armv4_5
= target
->arch_info
;
447 xscale_common_t
*xscale
= armv4_5
->arch_info
;
448 enum tap_state path
[3];
449 enum tap_state noconsume_path
[9];
452 struct timeval timeout
, now
;
454 scan_field_t fields
[3];
456 u8 field0_check_value
= 0x2;
457 u8 field0_check_mask
= 0x6;
458 u8 field2_check_value
= 0x0;
459 u8 field2_check_mask
= 0x1;
461 jtag_add_end_state(TAP_RTI
);
463 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dbgtx
);
469 noconsume_path
[0] = TAP_SDS
;
470 noconsume_path
[1] = TAP_CD
;
471 noconsume_path
[2] = TAP_E1D
;
472 noconsume_path
[3] = TAP_PD
;
473 noconsume_path
[4] = TAP_E2D
;
474 noconsume_path
[5] = TAP_UD
;
475 noconsume_path
[6] = TAP_SDS
;
476 noconsume_path
[7] = TAP_CD
;
477 noconsume_path
[8] = TAP_SD
;
479 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
480 fields
[0].num_bits
= 3;
481 fields
[0].out_value
= NULL
;
482 fields
[0].out_mask
= NULL
;
483 fields
[0].in_value
= &field0_in
;
484 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
486 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
487 fields
[1].num_bits
= 32;
488 fields
[1].out_value
= NULL
;
489 fields
[1].out_mask
= NULL
;
490 fields
[1].in_value
= xscale
->reg_cache
->reg_list
[XSCALE_TX
].value
;
491 fields
[1].in_handler
= NULL
;
492 fields
[1].in_handler_priv
= NULL
;
493 fields
[1].in_check_value
= NULL
;
494 fields
[1].in_check_mask
= NULL
;
498 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
499 fields
[2].num_bits
= 1;
500 fields
[2].out_value
= NULL
;
501 fields
[2].out_mask
= NULL
;
502 fields
[2].in_value
= NULL
;
503 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
505 gettimeofday(&timeout
, NULL
);
506 timeval_add_time(&timeout
, 5, 0);
510 /* if we want to consume the register content (i.e. clear TX_READY),
511 * we have to go straight from Capture-DR to Shift-DR
512 * otherwise, we go from Capture-DR to Exit1-DR to Pause-DR
515 jtag_add_pathmove(3, path
);
517 jtag_add_pathmove(sizeof(noconsume_path
)/sizeof(*noconsume_path
), noconsume_path
);
519 jtag_add_dr_scan(3, fields
, TAP_RTI
);
521 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
523 ERROR("JTAG error while reading TX");
524 return ERROR_TARGET_TIMEOUT
;
527 gettimeofday(&now
, NULL
);
528 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
)&& (now
.tv_usec
> timeout
.tv_usec
)))
530 ERROR("time out reading TX register");
531 return ERROR_TARGET_TIMEOUT
;
533 } while ((!(field0_in
& 1)) && consume
);
535 if (!(field0_in
& 1))
536 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
541 int xscale_write_rx(target_t
*target
)
543 armv4_5_common_t
*armv4_5
= target
->arch_info
;
544 xscale_common_t
*xscale
= armv4_5
->arch_info
;
547 struct timeval timeout
, now
;
549 scan_field_t fields
[3];
552 u8 field0_check_value
= 0x2;
553 u8 field0_check_mask
= 0x6;
555 u8 field2_check_value
= 0x0;
556 u8 field2_check_mask
= 0x1;
558 jtag_add_end_state(TAP_RTI
);
560 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dbgrx
);
562 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
563 fields
[0].num_bits
= 3;
564 fields
[0].out_value
= &field0_out
;
565 fields
[0].out_mask
= NULL
;
566 fields
[0].in_value
= &field0_in
;
567 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
569 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
570 fields
[1].num_bits
= 32;
571 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
;
572 fields
[1].out_mask
= NULL
;
573 fields
[1].in_value
= NULL
;
574 fields
[1].in_handler
= NULL
;
575 fields
[1].in_handler_priv
= NULL
;
576 fields
[1].in_check_value
= NULL
;
577 fields
[1].in_check_mask
= NULL
;
581 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
582 fields
[2].num_bits
= 1;
583 fields
[2].out_value
= &field2
;
584 fields
[2].out_mask
= NULL
;
585 fields
[2].in_value
= NULL
;
586 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
588 gettimeofday(&timeout
, NULL
);
589 timeval_add_time(&timeout
, 5, 0);
591 /* poll until rx_read is low */
595 jtag_add_dr_scan(3, fields
, TAP_RTI
);
597 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
599 ERROR("JTAG error while writing RX");
603 gettimeofday(&now
, NULL
);
604 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
)&& (now
.tv_usec
> timeout
.tv_usec
)))
606 ERROR("time out writing RX register");
607 return ERROR_TARGET_TIMEOUT
;
609 } while (field0_in
& 1);
613 jtag_add_dr_scan(3, fields
, TAP_RTI
);
615 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
617 ERROR("JTAG error while writing RX");
624 /* send count elements of size byte to the debug handler */
625 int xscale_send(target_t
*target
, u8
*buffer
, int count
, int size
)
627 armv4_5_common_t
*armv4_5
= target
->arch_info
;
628 xscale_common_t
*xscale
= armv4_5
->arch_info
;
633 u8 output
[4] = {0, 0, 0, 0};
635 scan_field_t fields
[3];
637 u8 field0_check_value
= 0x2;
638 u8 field0_check_mask
= 0x6;
640 u8 field2_check_value
= 0x0;
641 u8 field2_check_mask
= 0x1;
643 jtag_add_end_state(TAP_RTI
);
645 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dbgrx
);
647 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
648 fields
[0].num_bits
= 3;
649 fields
[0].out_value
= &field0_out
;
650 fields
[0].out_mask
= NULL
;
651 fields
[0].in_handler
= NULL
;
652 if (!xscale
->fast_memory_access
)
654 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
657 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
658 fields
[1].num_bits
= 32;
659 fields
[1].out_value
= output
;
660 fields
[1].out_mask
= NULL
;
661 fields
[1].in_value
= NULL
;
662 fields
[1].in_handler
= NULL
;
663 fields
[1].in_handler_priv
= NULL
;
664 fields
[1].in_check_value
= NULL
;
665 fields
[1].in_check_mask
= NULL
;
669 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
670 fields
[2].num_bits
= 1;
671 fields
[2].out_value
= &field2
;
672 fields
[2].out_mask
= NULL
;
673 fields
[2].in_value
= NULL
;
674 fields
[2].in_handler
= NULL
;
675 if (!xscale
->fast_memory_access
)
677 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
682 int endianness
= target
->endianness
;
683 while (done_count
++ < count
)
685 if (endianness
== TARGET_LITTLE_ENDIAN
)
698 jtag_add_dr_scan(3, fields
, TAP_RTI
);
704 while (done_count
++ < count
)
706 /* extract sized element from target-endian buffer, and put it
707 * into little-endian output buffer
712 buf_set_u32(output
, 0, 32, target_buffer_get_u16(target
, buffer
));
718 ERROR("BUG: size neither 4, 2 nor 1");
722 jtag_add_dr_scan(3, fields
, TAP_RTI
);
728 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
730 ERROR("JTAG error while sending data to debug handler");
737 int xscale_send_u32(target_t
*target
, u32 value
)
739 armv4_5_common_t
*armv4_5
= target
->arch_info
;
740 xscale_common_t
*xscale
= armv4_5
->arch_info
;
742 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
743 return xscale_write_rx(target
);
746 int xscale_write_dcsr(target_t
*target
, int hold_rst
, int ext_dbg_brk
)
748 armv4_5_common_t
*armv4_5
= target
->arch_info
;
749 xscale_common_t
*xscale
= armv4_5
->arch_info
;
753 scan_field_t fields
[3];
755 u8 field0_check_value
= 0x2;
756 u8 field0_check_mask
= 0x7;
758 u8 field2_check_value
= 0x0;
759 u8 field2_check_mask
= 0x1;
762 xscale
->hold_rst
= hold_rst
;
764 if (ext_dbg_brk
!= -1)
765 xscale
->external_debug_break
= ext_dbg_brk
;
767 jtag_add_end_state(TAP_RTI
);
768 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dcsr
);
770 buf_set_u32(&field0
, 1, 1, xscale
->hold_rst
);
771 buf_set_u32(&field0
, 2, 1, xscale
->external_debug_break
);
773 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
774 fields
[0].num_bits
= 3;
775 fields
[0].out_value
= &field0
;
776 fields
[0].out_mask
= NULL
;
777 fields
[0].in_value
= NULL
;
778 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
780 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
781 fields
[1].num_bits
= 32;
782 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
783 fields
[1].out_mask
= NULL
;
784 fields
[1].in_value
= NULL
;
785 fields
[1].in_handler
= NULL
;
786 fields
[1].in_handler_priv
= NULL
;
787 fields
[1].in_check_value
= NULL
;
788 fields
[1].in_check_mask
= NULL
;
792 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
793 fields
[2].num_bits
= 1;
794 fields
[2].out_value
= &field2
;
795 fields
[2].out_mask
= NULL
;
796 fields
[2].in_value
= NULL
;
797 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
799 jtag_add_dr_scan(3, fields
, -1);
801 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
803 ERROR("JTAG error while writing DCSR");
807 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].dirty
= 0;
808 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].valid
= 1;
813 /* parity of the number of bits 0 if even; 1 if odd. for 32 bit words */
814 unsigned int parity (unsigned int v
)
821 DEBUG("parity of 0x%x is %i", ov
, (0x6996 >> v
) & 1);
822 return (0x6996 >> v
) & 1;
825 int xscale_load_ic(target_t
*target
, int mini
, u32 va
, u32 buffer
[8])
827 armv4_5_common_t
*armv4_5
= target
->arch_info
;
828 xscale_common_t
*xscale
= armv4_5
->arch_info
;
833 scan_field_t fields
[2];
835 DEBUG("loading miniIC at 0x%8.8x", va
);
837 jtag_add_end_state(TAP_RTI
);
838 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.ldic
); /* LDIC */
840 /* CMD is b010 for Main IC and b011 for Mini IC */
842 buf_set_u32(&cmd
, 0, 3, 0x3);
844 buf_set_u32(&cmd
, 0, 3, 0x2);
846 buf_set_u32(&cmd
, 3, 3, 0x0);
848 /* virtual address of desired cache line */
849 buf_set_u32(packet
, 0, 27, va
>> 5);
851 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
852 fields
[0].num_bits
= 6;
853 fields
[0].out_value
= &cmd
;
854 fields
[0].out_mask
= NULL
;
855 fields
[0].in_value
= NULL
;
856 fields
[0].in_check_value
= NULL
;
857 fields
[0].in_check_mask
= NULL
;
858 fields
[0].in_handler
= NULL
;
859 fields
[0].in_handler_priv
= NULL
;
861 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
862 fields
[1].num_bits
= 27;
863 fields
[1].out_value
= packet
;
864 fields
[1].out_mask
= NULL
;
865 fields
[1].in_value
= NULL
;
866 fields
[1].in_check_value
= NULL
;
867 fields
[1].in_check_mask
= NULL
;
868 fields
[1].in_handler
= NULL
;
869 fields
[1].in_handler_priv
= NULL
;
871 jtag_add_dr_scan(2, fields
, -1);
873 fields
[0].num_bits
= 32;
874 fields
[0].out_value
= packet
;
876 fields
[1].num_bits
= 1;
877 fields
[1].out_value
= &cmd
;
879 for (word
= 0; word
< 8; word
++)
881 buf_set_u32(packet
, 0, 32, buffer
[word
]);
882 cmd
= parity(*((u32
*)packet
));
883 jtag_add_dr_scan(2, fields
, -1);
886 jtag_execute_queue();
891 int xscale_invalidate_ic_line(target_t
*target
, u32 va
)
893 armv4_5_common_t
*armv4_5
= target
->arch_info
;
894 xscale_common_t
*xscale
= armv4_5
->arch_info
;
898 scan_field_t fields
[2];
900 jtag_add_end_state(TAP_RTI
);
901 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.ldic
); /* LDIC */
903 /* CMD for invalidate IC line b000, bits [6:4] b000 */
904 buf_set_u32(&cmd
, 0, 6, 0x0);
906 /* virtual address of desired cache line */
907 buf_set_u32(packet
, 0, 27, va
>> 5);
909 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
910 fields
[0].num_bits
= 6;
911 fields
[0].out_value
= &cmd
;
912 fields
[0].out_mask
= NULL
;
913 fields
[0].in_value
= NULL
;
914 fields
[0].in_check_value
= NULL
;
915 fields
[0].in_check_mask
= NULL
;
916 fields
[0].in_handler
= NULL
;
917 fields
[0].in_handler_priv
= NULL
;
919 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
920 fields
[1].num_bits
= 27;
921 fields
[1].out_value
= packet
;
922 fields
[1].out_mask
= NULL
;
923 fields
[1].in_value
= NULL
;
924 fields
[1].in_check_value
= NULL
;
925 fields
[1].in_check_mask
= NULL
;
926 fields
[1].in_handler
= NULL
;
927 fields
[1].in_handler_priv
= NULL
;
929 jtag_add_dr_scan(2, fields
, -1);
934 int xscale_update_vectors(target_t
*target
)
936 armv4_5_common_t
*armv4_5
= target
->arch_info
;
937 xscale_common_t
*xscale
= armv4_5
->arch_info
;
940 u32 low_reset_branch
, high_reset_branch
;
942 for (i
= 1; i
< 8; i
++)
944 /* if there's a static vector specified for this exception, override */
945 if (xscale
->static_high_vectors_set
& (1 << i
))
947 xscale
->high_vectors
[i
] = xscale
->static_high_vectors
[i
];
951 if (target_read_u32(target
, 0xffff0000 + 4*i
, &xscale
->high_vectors
[i
]) != ERROR_OK
)
953 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
958 for (i
= 1; i
< 8; i
++)
960 if (xscale
->static_low_vectors_set
& (1 << i
))
962 xscale
->low_vectors
[i
] = xscale
->static_low_vectors
[i
];
966 if (target_read_u32(target
, 0x0 + 4*i
, &xscale
->low_vectors
[i
]) != ERROR_OK
)
968 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
973 /* calculate branches to debug handler */
974 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
975 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
977 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
978 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
980 /* invalidate and load exception vectors in mini i-cache */
981 xscale_invalidate_ic_line(target
, 0x0);
982 xscale_invalidate_ic_line(target
, 0xffff0000);
984 xscale_load_ic(target
, 1, 0x0, xscale
->low_vectors
);
985 xscale_load_ic(target
, 1, 0xffff0000, xscale
->high_vectors
);
990 int xscale_arch_state(struct target_s
*target
)
992 armv4_5_common_t
*armv4_5
= target
->arch_info
;
993 xscale_common_t
*xscale
= armv4_5
->arch_info
;
997 "disabled", "enabled"
1000 char *arch_dbg_reason
[] =
1002 "", "\n(processor reset)", "\n(trace buffer full)"
1005 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
1007 ERROR("BUG: called for a non-ARMv4/5 target");
1011 USER("target halted in %s state due to %s, current mode: %s\n"
1012 "cpsr: 0x%8.8x pc: 0x%8.8x\n"
1013 "MMU: %s, D-Cache: %s, I-Cache: %s"
1015 armv4_5_state_strings
[armv4_5
->core_state
],
1016 target_debug_reason_strings
[target
->debug_reason
],
1017 armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)],
1018 buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32),
1019 buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32),
1020 state
[xscale
->armv4_5_mmu
.mmu_enabled
],
1021 state
[xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
],
1022 state
[xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
],
1023 arch_dbg_reason
[xscale
->arch_debug_reason
]);
1028 int xscale_poll(target_t
*target
)
1030 int retval
=ERROR_OK
;
1031 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1032 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1034 if ((target
->state
== TARGET_RUNNING
) || (target
->state
== TARGET_DEBUG_RUNNING
))
1036 enum target_state previous_state
= target
->state
;
1037 if ((retval
= xscale_read_tx(target
, 0)) == ERROR_OK
)
1040 /* there's data to read from the tx register, we entered debug state */
1041 xscale
->handler_running
= 1;
1043 target
->state
= TARGET_HALTED
;
1045 /* process debug entry, fetching current mode regs */
1046 retval
= xscale_debug_entry(target
);
1048 else if (retval
!= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
1050 USER("error while polling TX register, reset CPU");
1051 /* here we "lie" so GDB won't get stuck and a reset can be perfomed */
1052 target
->state
= TARGET_HALTED
;
1055 /* debug_entry could have overwritten target state (i.e. immediate resume)
1056 * don't signal event handlers in that case
1058 if (target
->state
!= TARGET_HALTED
)
1061 /* if target was running, signal that we halted
1062 * otherwise we reentered from debug execution */
1063 if (previous_state
== TARGET_RUNNING
)
1064 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1066 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
1072 int xscale_debug_entry(target_t
*target
)
1074 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1075 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1082 /* clear external dbg break (will be written on next DCSR read) */
1083 xscale
->external_debug_break
= 0;
1084 xscale_read_dcsr(target
);
1086 /* get r0, pc, r1 to r7 and cpsr */
1087 xscale_receive(target
, buffer
, 10);
1089 /* move r0 from buffer to register cache */
1090 buf_set_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32, buffer
[0]);
1091 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
1092 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
1093 DEBUG("r0: 0x%8.8x", buffer
[0]);
1095 /* move pc from buffer to register cache */
1096 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, buffer
[1]);
1097 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
1098 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
1099 DEBUG("pc: 0x%8.8x", buffer
[1]);
1101 /* move data from buffer to register cache */
1102 for (i
= 1; i
<= 7; i
++)
1104 buf_set_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32, buffer
[1 + i
]);
1105 armv4_5
->core_cache
->reg_list
[i
].dirty
= 1;
1106 armv4_5
->core_cache
->reg_list
[i
].valid
= 1;
1107 DEBUG("r%i: 0x%8.8x", i
, buffer
[i
+ 1]);
1110 buf_set_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32, buffer
[9]);
1111 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].dirty
= 1;
1112 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].valid
= 1;
1113 DEBUG("cpsr: 0x%8.8x", buffer
[9]);
1115 armv4_5
->core_mode
= buffer
[9] & 0x1f;
1116 if (armv4_5_mode_to_number(armv4_5
->core_mode
) == -1)
1118 target
->state
= TARGET_UNKNOWN
;
1119 ERROR("cpsr contains invalid mode value - communication failure");
1120 return ERROR_TARGET_FAILURE
;
1122 DEBUG("target entered debug state in %s mode", armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)]);
1124 if (buffer
[9] & 0x20)
1125 armv4_5
->core_state
= ARMV4_5_STATE_THUMB
;
1127 armv4_5
->core_state
= ARMV4_5_STATE_ARM
;
1129 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1130 if ((armv4_5
->core_mode
!= ARMV4_5_MODE_USR
) && (armv4_5
->core_mode
!= ARMV4_5_MODE_SYS
))
1132 xscale_receive(target
, buffer
, 8);
1133 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1134 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
1135 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
1139 /* r8 to r14, but no spsr */
1140 xscale_receive(target
, buffer
, 7);
1143 /* move data from buffer to register cache */
1144 for (i
= 8; i
<= 14; i
++)
1146 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).value
, 0, 32, buffer
[i
- 8]);
1147 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).dirty
= 0;
1148 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).valid
= 1;
1151 /* examine debug reason */
1152 xscale_read_dcsr(target
);
1153 moe
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 2, 3);
1155 /* stored PC (for calculating fixup) */
1156 pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1160 case 0x0: /* Processor reset */
1161 target
->debug_reason
= DBG_REASON_DBGRQ
;
1162 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_RESET
;
1165 case 0x1: /* Instruction breakpoint hit */
1166 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1167 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1170 case 0x2: /* Data breakpoint hit */
1171 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
1172 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1175 case 0x3: /* BKPT instruction executed */
1176 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1177 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1180 case 0x4: /* Ext. debug event */
1181 target
->debug_reason
= DBG_REASON_DBGRQ
;
1182 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1185 case 0x5: /* Vector trap occured */
1186 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1187 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1190 case 0x6: /* Trace buffer full break */
1191 target
->debug_reason
= DBG_REASON_DBGRQ
;
1192 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_TB_FULL
;
1195 case 0x7: /* Reserved */
1197 ERROR("Method of Entry is 'Reserved'");
1202 /* apply PC fixup */
1203 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, pc
);
1205 /* on the first debug entry, identify cache type */
1206 if (xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
1210 /* read cp15 cache type register */
1211 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
]);
1212 cache_type_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
].value
, 0, 32);
1214 armv4_5_identify_cache(cache_type_reg
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
1217 /* examine MMU and Cache settings */
1218 /* read cp15 control register */
1219 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
1220 xscale
->cp15_control_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
1221 xscale
->armv4_5_mmu
.mmu_enabled
= (xscale
->cp15_control_reg
& 0x1U
) ? 1 : 0;
1222 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= (xscale
->cp15_control_reg
& 0x4U
) ? 1 : 0;
1223 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= (xscale
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
1225 /* tracing enabled, read collected trace data */
1226 if (xscale
->trace
.buffer_enabled
)
1228 xscale_read_trace(target
);
1229 xscale
->trace
.buffer_fill
--;
1231 /* resume if we're still collecting trace data */
1232 if ((xscale
->arch_debug_reason
== XSCALE_DBG_REASON_TB_FULL
)
1233 && (xscale
->trace
.buffer_fill
> 0))
1235 xscale_resume(target
, 1, 0x0, 1, 0);
1239 xscale
->trace
.buffer_enabled
= 0;
1246 int xscale_halt(target_t
*target
)
1248 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1249 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1251 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
1253 if (target
->state
== TARGET_HALTED
)
1255 WARNING("target was already halted");
1256 return ERROR_TARGET_ALREADY_HALTED
;
1258 else if (target
->state
== TARGET_UNKNOWN
)
1260 /* this must not happen for a xscale target */
1261 ERROR("target was in unknown state when halt was requested");
1262 return ERROR_TARGET_INVALID
;
1264 else if (target
->state
== TARGET_RESET
)
1266 DEBUG("target->state == TARGET_RESET");
1270 /* assert external dbg break */
1271 xscale
->external_debug_break
= 1;
1272 xscale_read_dcsr(target
);
1274 target
->debug_reason
= DBG_REASON_DBGRQ
;
1280 int xscale_enable_single_step(struct target_s
*target
, u32 next_pc
)
1282 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1283 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1284 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1286 if (xscale
->ibcr0_used
)
1288 breakpoint_t
*ibcr0_bp
= breakpoint_find(target
, buf_get_u32(ibcr0
->value
, 0, 32) & 0xfffffffe);
1292 xscale_unset_breakpoint(target
, ibcr0_bp
);
1296 ERROR("BUG: xscale->ibcr0_used is set, but no breakpoint with that address found");
1301 xscale_set_reg_u32(ibcr0
, next_pc
| 0x1);
1306 int xscale_disable_single_step(struct target_s
*target
)
1308 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1309 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1310 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1312 xscale_set_reg_u32(ibcr0
, 0x0);
1317 int xscale_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
1319 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1320 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1321 breakpoint_t
*breakpoint
= target
->breakpoints
;
1330 if (target
->state
!= TARGET_HALTED
)
1332 WARNING("target not halted");
1333 return ERROR_TARGET_NOT_HALTED
;
1336 if (!debug_execution
)
1338 target_free_all_working_areas(target
);
1341 /* update vector tables */
1342 xscale_update_vectors(target
);
1344 /* current = 1: continue on current pc, otherwise continue at <address> */
1346 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1348 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1350 /* if we're at the reset vector, we have to simulate the branch */
1351 if (current_pc
== 0x0)
1353 arm_simulate_step(target
, NULL
);
1354 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1357 /* the front-end may request us not to handle breakpoints */
1358 if (handle_breakpoints
)
1360 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1364 /* there's a breakpoint at the current PC, we have to step over it */
1365 DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
1366 xscale_unset_breakpoint(target
, breakpoint
);
1368 /* calculate PC of next instruction */
1369 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1372 target_read_u32(target
, current_pc
, ¤t_opcode
);
1373 ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode
);
1376 DEBUG("enable single-step");
1377 xscale_enable_single_step(target
, next_pc
);
1379 /* restore banked registers */
1380 xscale_restore_context(target
);
1382 /* send resume request (command 0x30 or 0x31)
1383 * clean the trace buffer if it is to be enabled (0x62) */
1384 if (xscale
->trace
.buffer_enabled
)
1386 xscale_send_u32(target
, 0x62);
1387 xscale_send_u32(target
, 0x31);
1390 xscale_send_u32(target
, 0x30);
1393 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1394 DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1396 for (i
= 7; i
>= 0; i
--)
1399 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1400 DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1404 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1405 DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1407 /* wait for and process debug entry */
1408 xscale_debug_entry(target
);
1410 DEBUG("disable single-step");
1411 xscale_disable_single_step(target
);
1413 DEBUG("set breakpoint at 0x%8.8x", breakpoint
->address
);
1414 xscale_set_breakpoint(target
, breakpoint
);
1418 /* enable any pending breakpoints and watchpoints */
1419 xscale_enable_breakpoints(target
);
1420 xscale_enable_watchpoints(target
);
1422 /* restore banked registers */
1423 xscale_restore_context(target
);
1425 /* send resume request (command 0x30 or 0x31)
1426 * clean the trace buffer if it is to be enabled (0x62) */
1427 if (xscale
->trace
.buffer_enabled
)
1429 xscale_send_u32(target
, 0x62);
1430 xscale_send_u32(target
, 0x31);
1433 xscale_send_u32(target
, 0x30);
1436 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1437 DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1439 for (i
= 7; i
>= 0; i
--)
1442 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1443 DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1447 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1448 DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1450 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1452 if (!debug_execution
)
1454 /* registers are now invalid */
1455 armv4_5_invalidate_core_regs(target
);
1456 target
->state
= TARGET_RUNNING
;
1457 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1461 target
->state
= TARGET_DEBUG_RUNNING
;
1462 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1465 DEBUG("target resumed");
1467 xscale
->handler_running
= 1;
1472 int xscale_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
1474 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1475 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1476 breakpoint_t
*breakpoint
= target
->breakpoints
;
1478 u32 current_pc
, next_pc
;
1482 if (target
->state
!= TARGET_HALTED
)
1484 WARNING("target not halted");
1485 return ERROR_TARGET_NOT_HALTED
;
1488 /* current = 1: continue on current pc, otherwise continue at <address> */
1490 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1492 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1494 /* if we're at the reset vector, we have to simulate the step */
1495 if (current_pc
== 0x0)
1497 arm_simulate_step(target
, NULL
);
1498 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1500 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1501 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1506 /* the front-end may request us not to handle breakpoints */
1507 if (handle_breakpoints
)
1508 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1510 xscale_unset_breakpoint(target
, breakpoint
);
1513 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1515 /* calculate PC of next instruction */
1516 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1519 target_read_u32(target
, current_pc
, ¤t_opcode
);
1520 ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode
);
1523 DEBUG("enable single-step");
1524 xscale_enable_single_step(target
, next_pc
);
1526 /* restore banked registers */
1527 xscale_restore_context(target
);
1529 /* send resume request (command 0x30 or 0x31)
1530 * clean the trace buffer if it is to be enabled (0x62) */
1531 if (xscale
->trace
.buffer_enabled
)
1533 xscale_send_u32(target
, 0x62);
1534 xscale_send_u32(target
, 0x31);
1537 xscale_send_u32(target
, 0x30);
1540 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1541 DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1543 for (i
= 7; i
>= 0; i
--)
1546 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1547 DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1551 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1552 DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1554 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1556 /* registers are now invalid */
1557 armv4_5_invalidate_core_regs(target
);
1559 /* wait for and process debug entry */
1560 xscale_debug_entry(target
);
1562 DEBUG("disable single-step");
1563 xscale_disable_single_step(target
);
1565 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1569 xscale_set_breakpoint(target
, breakpoint
);
1572 DEBUG("target stepped");
1578 int xscale_assert_reset(target_t
*target
)
1580 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1581 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1583 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
1585 /* select DCSR instruction (set endstate to R-T-I to ensure we don't
1586 * end up in T-L-R, which would reset JTAG
1588 jtag_add_end_state(TAP_RTI
);
1589 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dcsr
);
1591 /* set Hold reset, Halt mode and Trap Reset */
1592 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1593 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1594 xscale_write_dcsr(target
, 1, 0);
1596 /* select BYPASS, because having DCSR selected caused problems on the PXA27x */
1597 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, 0x7f);
1598 jtag_execute_queue();
1601 jtag_add_reset(0, 1);
1603 /* sleep 1ms, to be sure we fulfill any requirements */
1604 jtag_add_sleep(1000);
1605 jtag_execute_queue();
1607 target
->state
= TARGET_RESET
;
1612 int xscale_deassert_reset(target_t
*target
)
1614 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1615 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1617 fileio_t debug_handler
;
1625 breakpoint_t
*breakpoint
= target
->breakpoints
;
1629 xscale
->ibcr_available
= 2;
1630 xscale
->ibcr0_used
= 0;
1631 xscale
->ibcr1_used
= 0;
1633 xscale
->dbr_available
= 2;
1634 xscale
->dbr0_used
= 0;
1635 xscale
->dbr1_used
= 0;
1637 /* mark all hardware breakpoints as unset */
1640 if (breakpoint
->type
== BKPT_HARD
)
1642 breakpoint
->set
= 0;
1644 breakpoint
= breakpoint
->next
;
1647 if (!xscale
->handler_installed
)
1650 jtag_add_reset(0, 0);
1652 /* wait 300ms; 150 and 100ms were not enough */
1653 jtag_add_sleep(300*1000);
1655 jtag_add_runtest(2030, TAP_RTI
);
1656 jtag_execute_queue();
1658 /* set Hold reset, Halt mode and Trap Reset */
1659 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1660 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1661 xscale_write_dcsr(target
, 1, 0);
1663 /* Load debug handler */
1664 if (fileio_open(&debug_handler
, "xscale/debug_handler.bin", FILEIO_READ
, FILEIO_BINARY
) != ERROR_OK
)
1669 if ((binary_size
= debug_handler
.size
) % 4)
1671 ERROR("debug_handler.bin: size not a multiple of 4");
1675 if (binary_size
> 0x800)
1677 ERROR("debug_handler.bin: larger than 2kb");
1681 binary_size
= CEIL(binary_size
, 32) * 32;
1683 address
= xscale
->handler_address
;
1684 while (binary_size
> 0)
1689 if ((retval
= fileio_read(&debug_handler
, 32, buffer
, &buf_cnt
)) != ERROR_OK
)
1694 for (i
= 0; i
< buf_cnt
; i
+= 4)
1696 /* convert LE buffer to host-endian u32 */
1697 cache_line
[i
/ 4] = le_to_h_u32(&buffer
[i
]);
1700 for (; buf_cnt
< 32; buf_cnt
+= 4)
1702 cache_line
[buf_cnt
/ 4] = 0xe1a08008;
1705 /* only load addresses other than the reset vectors */
1706 if ((address
% 0x400) != 0x0)
1708 xscale_load_ic(target
, 1, address
, cache_line
);
1712 binary_size
-= buf_cnt
;
1715 xscale_load_ic(target
, 1, 0x0, xscale
->low_vectors
);
1716 xscale_load_ic(target
, 1, 0xffff0000, xscale
->high_vectors
);
1718 jtag_add_runtest(30, TAP_RTI
);
1720 jtag_add_sleep(100000);
1722 /* set Hold reset, Halt mode and Trap Reset */
1723 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1724 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1725 xscale_write_dcsr(target
, 1, 0);
1727 /* clear Hold reset to let the target run (should enter debug handler) */
1728 xscale_write_dcsr(target
, 0, 1);
1729 target
->state
= TARGET_RUNNING
;
1731 if ((target
->reset_mode
!= RESET_HALT
) && (target
->reset_mode
!= RESET_INIT
))
1733 jtag_add_sleep(10000);
1735 /* we should have entered debug now */
1736 xscale_debug_entry(target
);
1737 target
->state
= TARGET_HALTED
;
1739 /* resume the target */
1740 xscale_resume(target
, 1, 0x0, 1, 0);
1743 fileio_close(&debug_handler
);
1747 jtag_add_reset(0, 0);
1754 int xscale_soft_reset_halt(struct target_s
*target
)
1760 int xscale_prepare_reset_halt(struct target_s
*target
)
1762 /* nothing to be done for reset_halt on XScale targets
1763 * we always halt after a reset to upload the debug handler
1768 int xscale_read_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
)
1774 int xscale_write_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
, u32 value
)
1780 int xscale_full_context(target_t
*target
)
1782 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1790 if (target
->state
!= TARGET_HALTED
)
1792 WARNING("target not halted");
1793 return ERROR_TARGET_NOT_HALTED
;
1796 buffer
= malloc(4 * 8);
1798 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1799 * we can't enter User mode on an XScale (unpredictable),
1800 * but User shares registers with SYS
1802 for(i
= 1; i
< 7; i
++)
1806 /* check if there are invalid registers in the current mode
1808 for (j
= 0; j
<= 16; j
++)
1810 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
== 0)
1818 /* request banked registers */
1819 xscale_send_u32(target
, 0x0);
1822 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1823 tmp_cpsr
|= 0xc0; /* I/F bits */
1825 /* send CPSR for desired mode */
1826 xscale_send_u32(target
, tmp_cpsr
);
1828 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1829 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1831 xscale_receive(target
, buffer
, 8);
1832 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1833 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1834 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).valid
= 1;
1838 xscale_receive(target
, buffer
, 7);
1841 /* move data from buffer to register cache */
1842 for (j
= 8; j
<= 14; j
++)
1844 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]);
1845 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1846 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
= 1;
1856 int xscale_restore_context(target_t
*target
)
1858 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1864 if (target
->state
!= TARGET_HALTED
)
1866 WARNING("target not halted");
1867 return ERROR_TARGET_NOT_HALTED
;
1870 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1871 * we can't enter User mode on an XScale (unpredictable),
1872 * but User shares registers with SYS
1874 for(i
= 1; i
< 7; i
++)
1878 /* check if there are invalid registers in the current mode
1880 for (j
= 8; j
<= 14; j
++)
1882 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
== 1)
1886 /* if not USR/SYS, check if the SPSR needs to be written */
1887 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1889 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
== 1)
1897 /* send banked registers */
1898 xscale_send_u32(target
, 0x1);
1901 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1902 tmp_cpsr
|= 0xc0; /* I/F bits */
1904 /* send CPSR for desired mode */
1905 xscale_send_u32(target
, tmp_cpsr
);
1907 /* send banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1908 for (j
= 8; j
<= 14; j
++)
1910 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, j
).value
, 0, 32));
1911 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1914 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1916 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32));
1917 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1925 int xscale_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1927 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1928 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1932 DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address
, size
, count
);
1934 if (target
->state
!= TARGET_HALTED
)
1936 WARNING("target not halted");
1937 return ERROR_TARGET_NOT_HALTED
;
1940 /* sanitize arguments */
1941 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1942 return ERROR_INVALID_ARGUMENTS
;
1944 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1945 return ERROR_TARGET_UNALIGNED_ACCESS
;
1947 /* send memory read request (command 0x1n, n: access size) */
1948 xscale_send_u32(target
, 0x10 | size
);
1950 /* send base address for read request */
1951 xscale_send_u32(target
, address
);
1953 /* send number of requested data words */
1954 xscale_send_u32(target
, count
);
1956 /* receive data from target (count times 32-bit words in host endianness) */
1957 buf32
= malloc(4 * count
);
1958 xscale_receive(target
, buf32
, count
);
1960 /* extract data from host-endian buffer into byte stream */
1961 for (i
= 0; i
< count
; i
++)
1966 target_buffer_set_u32(target
, buffer
, buf32
[i
]);
1970 target_buffer_set_u16(target
, buffer
, buf32
[i
] & 0xffff);
1974 *buffer
++ = buf32
[i
] & 0xff;
1977 ERROR("should never get here");
1984 /* examine DCSR, to see if Sticky Abort (SA) got set */
1985 xscale_read_dcsr(target
);
1986 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
1989 xscale_send_u32(target
, 0x60);
1991 return ERROR_TARGET_DATA_ABORT
;
1997 int xscale_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1999 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2000 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2002 DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address
, size
, count
);
2004 if (target
->state
!= TARGET_HALTED
)
2006 WARNING("target not halted");
2007 return ERROR_TARGET_NOT_HALTED
;
2010 /* sanitize arguments */
2011 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
2012 return ERROR_INVALID_ARGUMENTS
;
2014 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
2015 return ERROR_TARGET_UNALIGNED_ACCESS
;
2017 /* send memory write request (command 0x2n, n: access size) */
2018 xscale_send_u32(target
, 0x20 | size
);
2020 /* send base address for read request */
2021 xscale_send_u32(target
, address
);
2023 /* send number of requested data words to be written*/
2024 xscale_send_u32(target
, count
);
2026 /* extract data from host-endian buffer into byte stream */
2028 for (i
= 0; i
< count
; i
++)
2033 value
= target_buffer_get_u32(target
, buffer
);
2034 xscale_send_u32(target
, value
);
2038 value
= target_buffer_get_u16(target
, buffer
);
2039 xscale_send_u32(target
, value
);
2044 xscale_send_u32(target
, value
);
2048 ERROR("should never get here");
2053 xscale_send(target
, buffer
, count
, size
);
2055 /* examine DCSR, to see if Sticky Abort (SA) got set */
2056 xscale_read_dcsr(target
);
2057 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
2060 xscale_send_u32(target
, 0x60);
2062 return ERROR_TARGET_DATA_ABORT
;
2068 int xscale_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
2070 return xscale_write_memory(target
, address
, 4, count
, buffer
);
2073 int xscale_checksum_memory(struct target_s
*target
, u32 address
, u32 count
, u32
* checksum
)
2075 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2078 u32
xscale_get_ttb(target_t
*target
)
2080 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2081 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2084 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_TTB
]);
2085 ttb
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_TTB
].value
, 0, 32);
2090 void xscale_disable_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
;
2106 xscale_send_u32(target
, 0x50);
2107 xscale_send_u32(target
, xscale
->cache_clean_address
);
2109 /* invalidate DCache */
2110 xscale_send_u32(target
, 0x51);
2112 cp15_control
&= ~0x4U
;
2117 /* invalidate ICache */
2118 xscale_send_u32(target
, 0x52);
2119 cp15_control
&= ~0x1000U
;
2122 /* write new cp15 control register */
2123 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2125 /* execute cpwait to ensure outstanding operations complete */
2126 xscale_send_u32(target
, 0x53);
2129 void xscale_enable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
2131 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2132 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2135 /* read cp15 control register */
2136 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2137 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2140 cp15_control
|= 0x1U
;
2143 cp15_control
|= 0x4U
;
2146 cp15_control
|= 0x1000U
;
2148 /* write new cp15 control register */
2149 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2151 /* execute cpwait to ensure outstanding operations complete */
2152 xscale_send_u32(target
, 0x53);
2155 int xscale_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2157 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2158 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2160 if (target
->state
!= TARGET_HALTED
)
2162 WARNING("target not halted");
2163 return ERROR_TARGET_NOT_HALTED
;
2166 if (xscale
->force_hw_bkpts
)
2167 breakpoint
->type
= BKPT_HARD
;
2169 if (breakpoint
->set
)
2171 WARNING("breakpoint already set");
2175 if (breakpoint
->type
== BKPT_HARD
)
2177 u32 value
= breakpoint
->address
| 1;
2178 if (!xscale
->ibcr0_used
)
2180 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], value
);
2181 xscale
->ibcr0_used
= 1;
2182 breakpoint
->set
= 1; /* breakpoint set on first breakpoint register */
2184 else if (!xscale
->ibcr1_used
)
2186 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], value
);
2187 xscale
->ibcr1_used
= 1;
2188 breakpoint
->set
= 2; /* breakpoint set on second breakpoint register */
2192 ERROR("BUG: no hardware comparator available");
2196 else if (breakpoint
->type
== BKPT_SOFT
)
2198 if (breakpoint
->length
== 4)
2200 /* keep the original instruction in target endianness */
2201 target
->type
->read_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
);
2202 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2203 target_write_u32(target
, breakpoint
->address
, xscale
->arm_bkpt
);
2207 /* keep the original instruction in target endianness */
2208 target
->type
->read_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
);
2209 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2210 target_write_u32(target
, breakpoint
->address
, xscale
->thumb_bkpt
);
2212 breakpoint
->set
= 1;
2219 int xscale_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2221 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2222 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2224 if (target
->state
!= TARGET_HALTED
)
2226 WARNING("target not halted");
2227 return ERROR_TARGET_NOT_HALTED
;
2230 if (xscale
->force_hw_bkpts
)
2232 DEBUG("forcing use of hardware breakpoint at address 0x%8.8x", breakpoint
->address
);
2233 breakpoint
->type
= BKPT_HARD
;
2236 if ((breakpoint
->type
== BKPT_HARD
) && (xscale
->ibcr_available
< 1))
2238 INFO("no breakpoint unit available for hardware breakpoint");
2239 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2243 xscale
->ibcr_available
--;
2246 if ((breakpoint
->length
!= 2) && (breakpoint
->length
!= 4))
2248 INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
2249 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2255 int xscale_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2257 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2258 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2260 if (target
->state
!= TARGET_HALTED
)
2262 WARNING("target not halted");
2263 return ERROR_TARGET_NOT_HALTED
;
2266 if (!breakpoint
->set
)
2268 WARNING("breakpoint not set");
2272 if (breakpoint
->type
== BKPT_HARD
)
2274 if (breakpoint
->set
== 1)
2276 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], 0x0);
2277 xscale
->ibcr0_used
= 0;
2279 else if (breakpoint
->set
== 2)
2281 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], 0x0);
2282 xscale
->ibcr1_used
= 0;
2284 breakpoint
->set
= 0;
2288 /* restore original instruction (kept in target endianness) */
2289 if (breakpoint
->length
== 4)
2291 target
->type
->write_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
);
2295 target
->type
->write_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
);
2297 breakpoint
->set
= 0;
2303 int xscale_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2305 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2306 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2308 if (target
->state
!= TARGET_HALTED
)
2310 WARNING("target not halted");
2311 return ERROR_TARGET_NOT_HALTED
;
2314 if (breakpoint
->set
)
2316 xscale_unset_breakpoint(target
, breakpoint
);
2319 if (breakpoint
->type
== BKPT_HARD
)
2320 xscale
->ibcr_available
++;
2325 int xscale_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2327 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2328 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2330 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2331 u32 dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2333 if (target
->state
!= TARGET_HALTED
)
2335 WARNING("target not halted");
2336 return ERROR_TARGET_NOT_HALTED
;
2339 xscale_get_reg(dbcon
);
2341 switch (watchpoint
->rw
)
2353 ERROR("BUG: watchpoint->rw neither read, write nor access");
2356 if (!xscale
->dbr0_used
)
2358 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR0
], watchpoint
->address
);
2359 dbcon_value
|= enable
;
2360 xscale_set_reg_u32(dbcon
, dbcon_value
);
2361 watchpoint
->set
= 1;
2362 xscale
->dbr0_used
= 1;
2364 else if (!xscale
->dbr1_used
)
2366 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR1
], watchpoint
->address
);
2367 dbcon_value
|= enable
<< 2;
2368 xscale_set_reg_u32(dbcon
, dbcon_value
);
2369 watchpoint
->set
= 2;
2370 xscale
->dbr1_used
= 1;
2374 ERROR("BUG: no hardware comparator available");
2381 int xscale_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2383 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2384 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2386 if (target
->state
!= TARGET_HALTED
)
2388 WARNING("target not halted");
2389 return ERROR_TARGET_NOT_HALTED
;
2392 if (xscale
->dbr_available
< 1)
2394 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2397 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
2399 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2402 xscale
->dbr_available
--;
2407 int xscale_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2409 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2410 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2411 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2412 u32 dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2414 if (target
->state
!= TARGET_HALTED
)
2416 WARNING("target not halted");
2417 return ERROR_TARGET_NOT_HALTED
;
2420 if (!watchpoint
->set
)
2422 WARNING("breakpoint not set");
2426 if (watchpoint
->set
== 1)
2428 dbcon_value
&= ~0x3;
2429 xscale_set_reg_u32(dbcon
, dbcon_value
);
2430 xscale
->dbr0_used
= 0;
2432 else if (watchpoint
->set
== 2)
2434 dbcon_value
&= ~0xc;
2435 xscale_set_reg_u32(dbcon
, dbcon_value
);
2436 xscale
->dbr1_used
= 0;
2438 watchpoint
->set
= 0;
2443 int xscale_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2445 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2446 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2448 if (target
->state
!= TARGET_HALTED
)
2450 WARNING("target not halted");
2451 return ERROR_TARGET_NOT_HALTED
;
2454 if (watchpoint
->set
)
2456 xscale_unset_watchpoint(target
, watchpoint
);
2459 xscale
->dbr_available
++;
2464 void xscale_enable_watchpoints(struct target_s
*target
)
2466 watchpoint_t
*watchpoint
= target
->watchpoints
;
2470 if (watchpoint
->set
== 0)
2471 xscale_set_watchpoint(target
, watchpoint
);
2472 watchpoint
= watchpoint
->next
;
2476 void xscale_enable_breakpoints(struct target_s
*target
)
2478 breakpoint_t
*breakpoint
= target
->breakpoints
;
2480 /* set any pending breakpoints */
2483 if (breakpoint
->set
== 0)
2484 xscale_set_breakpoint(target
, breakpoint
);
2485 breakpoint
= breakpoint
->next
;
2489 int xscale_get_reg(reg_t
*reg
)
2491 xscale_reg_t
*arch_info
= reg
->arch_info
;
2492 target_t
*target
= arch_info
->target
;
2493 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2494 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2496 /* DCSR, TX and RX are accessible via JTAG */
2497 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2499 return xscale_read_dcsr(arch_info
->target
);
2501 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2503 /* 1 = consume register content */
2504 return xscale_read_tx(arch_info
->target
, 1);
2506 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2508 /* can't read from RX register (host -> debug handler) */
2511 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2513 /* can't (explicitly) read from TXRXCTRL register */
2516 else /* Other DBG registers have to be transfered by the debug handler */
2518 /* send CP read request (command 0x40) */
2519 xscale_send_u32(target
, 0x40);
2521 /* send CP register number */
2522 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2524 /* read register value */
2525 xscale_read_tx(target
, 1);
2526 buf_cpy(xscale
->reg_cache
->reg_list
[XSCALE_TX
].value
, reg
->value
, 32);
2535 int xscale_set_reg(reg_t
*reg
, u8
* buf
)
2537 xscale_reg_t
*arch_info
= reg
->arch_info
;
2538 target_t
*target
= arch_info
->target
;
2539 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2540 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2541 u32 value
= buf_get_u32(buf
, 0, 32);
2543 /* DCSR, TX and RX are accessible via JTAG */
2544 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2546 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32, value
);
2547 return xscale_write_dcsr(arch_info
->target
, -1, -1);
2549 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2551 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
2552 return xscale_write_rx(arch_info
->target
);
2554 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2556 /* can't write to TX register (debug-handler -> host) */
2559 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2561 /* can't (explicitly) write to TXRXCTRL register */
2564 else /* Other DBG registers have to be transfered by the debug handler */
2566 /* send CP write request (command 0x41) */
2567 xscale_send_u32(target
, 0x41);
2569 /* send CP register number */
2570 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2572 /* send CP register value */
2573 xscale_send_u32(target
, value
);
2574 buf_set_u32(reg
->value
, 0, 32, value
);
2580 /* convenience wrapper to access XScale specific registers */
2581 int xscale_set_reg_u32(reg_t
*reg
, u32 value
)
2585 buf_set_u32(buf
, 0, 32, value
);
2587 return xscale_set_reg(reg
, buf
);
2590 int xscale_write_dcsr_sw(target_t
*target
, u32 value
)
2592 /* get pointers to arch-specific information */
2593 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2594 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2595 reg_t
*dcsr
= &xscale
->reg_cache
->reg_list
[XSCALE_DCSR
];
2596 xscale_reg_t
*dcsr_arch_info
= dcsr
->arch_info
;
2598 /* send CP write request (command 0x41) */
2599 xscale_send_u32(target
, 0x41);
2601 /* send CP register number */
2602 xscale_send_u32(target
, dcsr_arch_info
->dbg_handler_number
);
2604 /* send CP register value */
2605 xscale_send_u32(target
, value
);
2606 buf_set_u32(dcsr
->value
, 0, 32, value
);
2611 int xscale_read_trace(target_t
*target
)
2613 /* get pointers to arch-specific information */
2614 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2615 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2616 xscale_trace_data_t
**trace_data_p
;
2618 /* 258 words from debug handler
2619 * 256 trace buffer entries
2620 * 2 checkpoint addresses
2622 u32 trace_buffer
[258];
2623 int is_address
[256];
2626 if (target
->state
!= TARGET_HALTED
)
2628 WARNING("target must be stopped to read trace data");
2629 return ERROR_TARGET_NOT_HALTED
;
2632 /* send read trace buffer command (command 0x61) */
2633 xscale_send_u32(target
, 0x61);
2635 /* receive trace buffer content */
2636 xscale_receive(target
, trace_buffer
, 258);
2638 /* parse buffer backwards to identify address entries */
2639 for (i
= 255; i
>= 0; i
--)
2642 if (((trace_buffer
[i
] & 0xf0) == 0x90) ||
2643 ((trace_buffer
[i
] & 0xf0) == 0xd0))
2646 is_address
[--i
] = 1;
2648 is_address
[--i
] = 1;
2650 is_address
[--i
] = 1;
2652 is_address
[--i
] = 1;
2657 /* search first non-zero entry */
2658 for (j
= 0; (j
< 256) && (trace_buffer
[j
] == 0) && (!is_address
[j
]); j
++)
2663 DEBUG("no trace data collected");
2664 return ERROR_XSCALE_NO_TRACE_DATA
;
2667 for (trace_data_p
= &xscale
->trace
.data
; *trace_data_p
; trace_data_p
= &(*trace_data_p
)->next
)
2670 *trace_data_p
= malloc(sizeof(xscale_trace_data_t
));
2671 (*trace_data_p
)->next
= NULL
;
2672 (*trace_data_p
)->chkpt0
= trace_buffer
[256];
2673 (*trace_data_p
)->chkpt1
= trace_buffer
[257];
2674 (*trace_data_p
)->last_instruction
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
2675 (*trace_data_p
)->entries
= malloc(sizeof(xscale_trace_entry_t
) * (256 - j
));
2676 (*trace_data_p
)->depth
= 256 - j
;
2678 for (i
= j
; i
< 256; i
++)
2680 (*trace_data_p
)->entries
[i
- j
].data
= trace_buffer
[i
];
2682 (*trace_data_p
)->entries
[i
- j
].type
= XSCALE_TRACE_ADDRESS
;
2684 (*trace_data_p
)->entries
[i
- j
].type
= XSCALE_TRACE_MESSAGE
;
2690 int xscale_read_instruction(target_t
*target
, arm_instruction_t
*instruction
)
2692 /* get pointers to arch-specific information */
2693 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2694 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2701 if (!xscale
->trace
.image
)
2702 return ERROR_TRACE_IMAGE_UNAVAILABLE
;
2704 /* search for the section the current instruction belongs to */
2705 for (i
= 0; i
< xscale
->trace
.image
->num_sections
; i
++)
2707 if ((xscale
->trace
.image
->sections
[i
].base_address
<= xscale
->trace
.current_pc
) &&
2708 (xscale
->trace
.image
->sections
[i
].base_address
+ xscale
->trace
.image
->sections
[i
].size
> xscale
->trace
.current_pc
))
2717 /* current instruction couldn't be found in the image */
2718 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2721 if (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
)
2724 if ((retval
= image_read_section(xscale
->trace
.image
, section
,
2725 xscale
->trace
.current_pc
- xscale
->trace
.image
->sections
[section
].base_address
,
2726 4, buf
, &size_read
)) != ERROR_OK
)
2728 ERROR("error while reading instruction: %i", retval
);
2729 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2731 opcode
= target_buffer_get_u32(target
, buf
);
2732 arm_evaluate_opcode(opcode
, xscale
->trace
.current_pc
, instruction
);
2734 else if (xscale
->trace
.core_state
== ARMV4_5_STATE_THUMB
)
2737 if ((retval
= image_read_section(xscale
->trace
.image
, section
,
2738 xscale
->trace
.current_pc
- xscale
->trace
.image
->sections
[section
].base_address
,
2739 2, buf
, &size_read
)) != ERROR_OK
)
2741 ERROR("error while reading instruction: %i", retval
);
2742 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2744 opcode
= target_buffer_get_u16(target
, buf
);
2745 thumb_evaluate_opcode(opcode
, xscale
->trace
.current_pc
, instruction
);
2749 ERROR("BUG: unknown core state encountered");
2756 int xscale_branch_address(xscale_trace_data_t
*trace_data
, int i
, u32
*target
)
2758 /* if there are less than four entries prior to the indirect branch message
2759 * we can't extract the address */
2765 *target
= (trace_data
->entries
[i
-1].data
) | (trace_data
->entries
[i
-2].data
<< 8) |
2766 (trace_data
->entries
[i
-3].data
<< 16) | (trace_data
->entries
[i
-4].data
<< 24);
2771 int xscale_analyze_trace(target_t
*target
, command_context_t
*cmd_ctx
)
2773 /* get pointers to arch-specific information */
2774 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2775 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2778 xscale_trace_data_t
*trace_data
= xscale
->trace
.data
;
2787 xscale
->trace
.core_state
= ARMV4_5_STATE_ARM
;
2792 for (i
= 0; i
< trace_data
->depth
; i
++)
2798 if (trace_data
->entries
[i
].type
== XSCALE_TRACE_ADDRESS
)
2801 switch ((trace_data
->entries
[i
].data
& 0xf0) >> 4)
2803 case 0: /* Exceptions */
2811 exception
= (trace_data
->entries
[i
].data
& 0x70) >> 4;
2813 next_pc
= (trace_data
->entries
[i
].data
& 0xf0) >> 2;
2814 command_print(cmd_ctx
, "--- exception %i ---", (trace_data
->entries
[i
].data
& 0xf0) >> 4);
2816 case 8: /* Direct Branch */
2819 case 9: /* Indirect Branch */
2821 if (xscale_branch_address(trace_data
, i
, &next_pc
) == 0)
2826 case 13: /* Checkpointed Indirect Branch */
2827 if (xscale_branch_address(trace_data
, i
, &next_pc
) == 0)
2830 if (((chkpt
== 0) && (next_pc
!= trace_data
->chkpt0
))
2831 || ((chkpt
== 1) && (next_pc
!= trace_data
->chkpt1
)))
2832 WARNING("checkpointed indirect branch target address doesn't match checkpoint");
2834 /* explicit fall-through */
2835 case 12: /* Checkpointed Direct Branch */
2840 next_pc
= trace_data
->chkpt0
;
2843 else if (chkpt
== 1)
2846 next_pc
= trace_data
->chkpt0
;
2851 WARNING("more than two checkpointed branches encountered");
2854 case 15: /* Roll-over */
2857 default: /* Reserved */
2858 command_print(cmd_ctx
, "--- reserved trace message ---");
2859 ERROR("BUG: trace message %i is reserved", (trace_data
->entries
[i
].data
& 0xf0) >> 4);
2863 if (xscale
->trace
.pc_ok
)
2865 int executed
= (trace_data
->entries
[i
].data
& 0xf) + rollover
* 16;
2866 arm_instruction_t instruction
;
2868 if ((exception
== 6) || (exception
== 7))
2870 /* IRQ or FIQ exception, no instruction executed */
2874 while (executed
-- >= 0)
2876 if ((retval
= xscale_read_instruction(target
, &instruction
)) != ERROR_OK
)
2878 /* can't continue tracing with no image available */
2879 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
2883 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
2885 /* TODO: handle incomplete images */
2889 /* a precise abort on a load to the PC is included in the incremental
2890 * word count, other instructions causing data aborts are not included
2892 if ((executed
== 0) && (exception
== 4)
2893 && ((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_LDM
)))
2895 if ((instruction
.type
== ARM_LDM
)
2896 && ((instruction
.info
.load_store_multiple
.register_list
& 0x8000) == 0))
2900 else if (((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_LDRSH
))
2901 && (instruction
.info
.load_store
.Rd
!= 15))
2907 /* only the last instruction executed
2908 * (the one that caused the control flow change)
2909 * could be a taken branch
2911 if (((executed
== -1) && (branch
== 1)) &&
2912 (((instruction
.type
== ARM_B
) ||
2913 (instruction
.type
== ARM_BL
) ||
2914 (instruction
.type
== ARM_BLX
)) &&
2915 (instruction
.info
.b_bl_bx_blx
.target_address
!= -1)))
2917 xscale
->trace
.current_pc
= instruction
.info
.b_bl_bx_blx
.target_address
;
2921 xscale
->trace
.current_pc
+= (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2;
2923 command_print(cmd_ctx
, "%s", instruction
.text
);
2931 xscale
->trace
.current_pc
= next_pc
;
2932 xscale
->trace
.pc_ok
= 1;
2936 for (; xscale
->trace
.current_pc
< trace_data
->last_instruction
; xscale
->trace
.current_pc
+= (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2)
2938 arm_instruction_t instruction
;
2939 if ((retval
= xscale_read_instruction(target
, &instruction
)) != ERROR_OK
)
2941 /* can't continue tracing with no image available */
2942 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
2946 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
2948 /* TODO: handle incomplete images */
2951 command_print(cmd_ctx
, "%s", instruction
.text
);
2954 trace_data
= trace_data
->next
;
2960 void xscale_build_reg_cache(target_t
*target
)
2962 /* get pointers to arch-specific information */
2963 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2964 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2966 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
2967 xscale_reg_t
*arch_info
= malloc(sizeof(xscale_reg_arch_info
));
2969 int num_regs
= sizeof(xscale_reg_arch_info
) / sizeof(xscale_reg_t
);
2971 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
2972 armv4_5
->core_cache
= (*cache_p
);
2974 /* register a register arch-type for XScale dbg registers only once */
2975 if (xscale_reg_arch_type
== -1)
2976 xscale_reg_arch_type
= register_reg_arch_type(xscale_get_reg
, xscale_set_reg
);
2978 (*cache_p
)->next
= malloc(sizeof(reg_cache_t
));
2979 cache_p
= &(*cache_p
)->next
;
2981 /* fill in values for the xscale reg cache */
2982 (*cache_p
)->name
= "XScale registers";
2983 (*cache_p
)->next
= NULL
;
2984 (*cache_p
)->reg_list
= malloc(num_regs
* sizeof(reg_t
));
2985 (*cache_p
)->num_regs
= num_regs
;
2987 for (i
= 0; i
< num_regs
; i
++)
2989 (*cache_p
)->reg_list
[i
].name
= xscale_reg_list
[i
];
2990 (*cache_p
)->reg_list
[i
].value
= calloc(4, 1);
2991 (*cache_p
)->reg_list
[i
].dirty
= 0;
2992 (*cache_p
)->reg_list
[i
].valid
= 0;
2993 (*cache_p
)->reg_list
[i
].size
= 32;
2994 (*cache_p
)->reg_list
[i
].bitfield_desc
= NULL
;
2995 (*cache_p
)->reg_list
[i
].num_bitfields
= 0;
2996 (*cache_p
)->reg_list
[i
].arch_info
= &arch_info
[i
];
2997 (*cache_p
)->reg_list
[i
].arch_type
= xscale_reg_arch_type
;
2998 arch_info
[i
] = xscale_reg_arch_info
[i
];
2999 arch_info
[i
].target
= target
;
3002 xscale
->reg_cache
= (*cache_p
);
3005 int xscale_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
3007 if (startup_mode
!= DAEMON_RESET
)
3009 ERROR("XScale target requires a reset");
3010 ERROR("Reset target to enable debug");
3013 /* assert TRST once during startup */
3014 jtag_add_reset(1, 0);
3015 jtag_add_sleep(5000);
3016 jtag_add_reset(0, 0);
3017 jtag_execute_queue();
3028 int xscale_init_arch_info(target_t
*target
, xscale_common_t
*xscale
, int chain_pos
, char *variant
)
3030 armv4_5_common_t
*armv4_5
;
3031 u32 high_reset_branch
, low_reset_branch
;
3034 armv4_5
= &xscale
->armv4_5_common
;
3036 /* store architecture specfic data (none so far) */
3037 xscale
->arch_info
= NULL
;
3038 xscale
->common_magic
= XSCALE_COMMON_MAGIC
;
3040 /* remember the variant (PXA25x, PXA27x, IXP42x, ...) */
3041 xscale
->variant
= strdup(variant
);
3043 /* prepare JTAG information for the new target */
3044 xscale
->jtag_info
.chain_pos
= chain_pos
;
3045 jtag_register_event_callback(xscale_jtag_callback
, target
);
3047 xscale
->jtag_info
.dbgrx
= 0x02;
3048 xscale
->jtag_info
.dbgtx
= 0x10;
3049 xscale
->jtag_info
.dcsr
= 0x09;
3050 xscale
->jtag_info
.ldic
= 0x07;
3052 if ((strcmp(xscale
->variant
, "pxa250") == 0) ||
3053 (strcmp(xscale
->variant
, "pxa255") == 0) ||
3054 (strcmp(xscale
->variant
, "pxa26x") == 0))
3056 xscale
->jtag_info
.ir_length
= 5;
3058 else if ((strcmp(xscale
->variant
, "pxa27x") == 0) ||
3059 (strcmp(xscale
->variant
, "ixp42x") == 0) ||
3060 (strcmp(xscale
->variant
, "ixp45x") == 0) ||
3061 (strcmp(xscale
->variant
, "ixp46x") == 0))
3063 xscale
->jtag_info
.ir_length
= 7;
3066 /* the debug handler isn't installed (and thus not running) at this time */
3067 xscale
->handler_installed
= 0;
3068 xscale
->handler_running
= 0;
3069 xscale
->handler_address
= 0xfe000800;
3071 /* clear the vectors we keep locally for reference */
3072 memset(xscale
->low_vectors
, 0, sizeof(xscale
->low_vectors
));
3073 memset(xscale
->high_vectors
, 0, sizeof(xscale
->high_vectors
));
3075 /* no user-specified vectors have been configured yet */
3076 xscale
->static_low_vectors_set
= 0x0;
3077 xscale
->static_high_vectors_set
= 0x0;
3079 /* calculate branches to debug handler */
3080 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
3081 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
3083 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
3084 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
3086 for (i
= 1; i
<= 7; i
++)
3088 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
3089 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
3092 /* 64kB aligned region used for DCache cleaning */
3093 xscale
->cache_clean_address
= 0xfffe0000;
3095 xscale
->hold_rst
= 0;
3096 xscale
->external_debug_break
= 0;
3098 xscale
->force_hw_bkpts
= 1;
3100 xscale
->ibcr_available
= 2;
3101 xscale
->ibcr0_used
= 0;
3102 xscale
->ibcr1_used
= 0;
3104 xscale
->dbr_available
= 2;
3105 xscale
->dbr0_used
= 0;
3106 xscale
->dbr1_used
= 0;
3108 xscale
->arm_bkpt
= ARMV5_BKPT(0x0);
3109 xscale
->thumb_bkpt
= ARMV5_T_BKPT(0x0) & 0xffff;
3111 xscale
->vector_catch
= 0x1;
3113 xscale
->trace
.capture_status
= TRACE_IDLE
;
3114 xscale
->trace
.data
= NULL
;
3115 xscale
->trace
.image
= NULL
;
3116 xscale
->trace
.buffer_enabled
= 0;
3117 xscale
->trace
.buffer_fill
= 0;
3119 /* prepare ARMv4/5 specific information */
3120 armv4_5
->arch_info
= xscale
;
3121 armv4_5
->read_core_reg
= xscale_read_core_reg
;
3122 armv4_5
->write_core_reg
= xscale_write_core_reg
;
3123 armv4_5
->full_context
= xscale_full_context
;
3125 armv4_5_init_arch_info(target
, armv4_5
);
3127 xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
3128 xscale
->armv4_5_mmu
.get_ttb
= xscale_get_ttb
;
3129 xscale
->armv4_5_mmu
.read_memory
= xscale_read_memory
;
3130 xscale
->armv4_5_mmu
.write_memory
= xscale_write_memory
;
3131 xscale
->armv4_5_mmu
.disable_mmu_caches
= xscale_disable_mmu_caches
;
3132 xscale
->armv4_5_mmu
.enable_mmu_caches
= xscale_enable_mmu_caches
;
3133 xscale
->armv4_5_mmu
.has_tiny_pages
= 1;
3134 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3136 xscale
->fast_memory_access
= 0;
3141 /* target xscale <endianess> <startup_mode> <chain_pos> <variant> */
3142 int xscale_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
)
3145 char *variant
= NULL
;
3146 xscale_common_t
*xscale
= malloc(sizeof(xscale_common_t
));
3150 ERROR("'target xscale' requires four arguments: <endianess> <startup_mode> <chain_pos> <variant>");
3154 chain_pos
= strtoul(args
[3], NULL
, 0);
3158 xscale_init_arch_info(target
, xscale
, chain_pos
, variant
);
3159 xscale_build_reg_cache(target
);
3164 int xscale_handle_debug_handler_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 handler_address
;
3174 ERROR("'xscale debug_handler <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
)
3189 handler_address
= strtoul(args
[1], NULL
, 0);
3191 if (((handler_address
>= 0x800) && (handler_address
<= 0x1fef800)) ||
3192 ((handler_address
>= 0xfe000800) && (handler_address
<= 0xfffff800)))
3194 xscale
->handler_address
= handler_address
;
3198 ERROR("xscale debug_handler <address> must be between 0x800 and 0x1fef800 or between 0xfe000800 and 0xfffff800");
3204 int xscale_handle_cache_clean_address_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3206 target_t
*target
= NULL
;
3207 armv4_5_common_t
*armv4_5
;
3208 xscale_common_t
*xscale
;
3210 u32 cache_clean_address
;
3214 ERROR("'xscale cache_clean_address <target#> <address>' command takes two required operands");
3218 if ((target
= get_target_by_num(strtoul(args
[0], NULL
, 0))) == NULL
)
3220 ERROR("no target '%s' configured", args
[0]);
3224 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3229 cache_clean_address
= strtoul(args
[1], NULL
, 0);
3231 if (cache_clean_address
& 0xffff)
3233 ERROR("xscale cache_clean_address <address> must be 64kb aligned");
3237 xscale
->cache_clean_address
= cache_clean_address
;
3243 int xscale_handle_cache_info_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3245 target_t
*target
= get_current_target(cmd_ctx
);
3246 armv4_5_common_t
*armv4_5
;
3247 xscale_common_t
*xscale
;
3249 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3254 return armv4_5_handle_cache_info_command(cmd_ctx
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
3257 static int xscale_virt2phys(struct target_s
*target
, u32
virtual, u32
*physical
)
3259 armv4_5_common_t
*armv4_5
;
3260 xscale_common_t
*xscale
;
3268 if ((retval
= xscale_get_arch_pointers(target
, &armv4_5
, &xscale
)) != ERROR_OK
)
3272 u32 ret
= armv4_5_mmu_translate_va(target
, &xscale
->armv4_5_mmu
, virtual, &type
, &cb
, &domain
, &ap
);
3281 static int xscale_mmu(struct target_s
*target
, int *enabled
)
3283 armv4_5_common_t
*armv4_5
= target
->arch_info
;
3284 xscale_common_t
*xscale
= armv4_5
->arch_info
;
3286 if (target
->state
!= TARGET_HALTED
)
3288 ERROR("Target not halted");
3289 return ERROR_TARGET_INVALID
;
3291 *enabled
= xscale
->armv4_5_mmu
.mmu_enabled
;
3296 int xscale_handle_mmu_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3298 target_t
*target
= get_current_target(cmd_ctx
);
3299 armv4_5_common_t
*armv4_5
;
3300 xscale_common_t
*xscale
;
3302 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3307 if (target
->state
!= TARGET_HALTED
)
3309 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3315 if (strcmp("enable", args
[0]) == 0)
3317 xscale_enable_mmu_caches(target
, 1, 0, 0);
3318 xscale
->armv4_5_mmu
.mmu_enabled
= 1;
3320 else if (strcmp("disable", args
[0]) == 0)
3322 xscale_disable_mmu_caches(target
, 1, 0, 0);
3323 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3327 command_print(cmd_ctx
, "mmu %s", (xscale
->armv4_5_mmu
.mmu_enabled
) ? "enabled" : "disabled");
3332 int xscale_handle_idcache_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
;
3337 int icache
= 0, dcache
= 0;
3339 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3344 if (target
->state
!= TARGET_HALTED
)
3346 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3350 if (strcmp(cmd
, "icache") == 0)
3352 else if (strcmp(cmd
, "dcache") == 0)
3357 if (strcmp("enable", args
[0]) == 0)
3359 xscale_enable_mmu_caches(target
, 0, dcache
, icache
);
3362 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 1;
3364 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 1;
3366 else if (strcmp("disable", args
[0]) == 0)
3368 xscale_disable_mmu_caches(target
, 0, dcache
, icache
);
3371 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 0;
3373 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 0;
3378 command_print(cmd_ctx
, "icache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
) ? "enabled" : "disabled");
3381 command_print(cmd_ctx
, "dcache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
) ? "enabled" : "disabled");
3386 int xscale_handle_vector_catch_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3388 target_t
*target
= get_current_target(cmd_ctx
);
3389 armv4_5_common_t
*armv4_5
;
3390 xscale_common_t
*xscale
;
3392 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3399 command_print(cmd_ctx
, "usage: xscale vector_catch [mask]");
3403 xscale
->vector_catch
= strtoul(args
[0], NULL
, 0);
3404 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 8, xscale
->vector_catch
);
3405 xscale_write_dcsr(target
, -1, -1);
3408 command_print(cmd_ctx
, "vector catch mask: 0x%2.2x", xscale
->vector_catch
);
3413 int xscale_handle_force_hw_bkpts_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3415 target_t
*target
= get_current_target(cmd_ctx
);
3416 armv4_5_common_t
*armv4_5
;
3417 xscale_common_t
*xscale
;
3419 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3424 if ((argc
>= 1) && (strcmp("enable", args
[0]) == 0))
3426 xscale
->force_hw_bkpts
= 1;
3428 else if ((argc
>= 1) && (strcmp("disable", args
[0]) == 0))
3430 xscale
->force_hw_bkpts
= 0;
3434 command_print(cmd_ctx
, "usage: xscale force_hw_bkpts <enable|disable>");
3437 command_print(cmd_ctx
, "force hardware breakpoints %s", (xscale
->force_hw_bkpts
) ? "enabled" : "disabled");
3442 int xscale_handle_trace_buffer_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3444 target_t
*target
= get_current_target(cmd_ctx
);
3445 armv4_5_common_t
*armv4_5
;
3446 xscale_common_t
*xscale
;
3449 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3454 if (target
->state
!= TARGET_HALTED
)
3456 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3460 if ((argc
>= 1) && (strcmp("enable", args
[0]) == 0))
3462 xscale_trace_data_t
*td
, *next_td
;
3463 xscale
->trace
.buffer_enabled
= 1;
3465 /* free old trace data */
3466 td
= xscale
->trace
.data
;
3476 xscale
->trace
.data
= NULL
;
3478 else if ((argc
>= 1) && (strcmp("disable", args
[0]) == 0))
3480 xscale
->trace
.buffer_enabled
= 0;
3483 if ((argc
>= 2) && (strcmp("fill", args
[1]) == 0))
3486 xscale
->trace
.buffer_fill
= strtoul(args
[2], NULL
, 0);
3488 xscale
->trace
.buffer_fill
= 1;
3490 else if ((argc
>= 2) && (strcmp("wrap", args
[1]) == 0))
3492 xscale
->trace
.buffer_fill
= -1;
3495 if (xscale
->trace
.buffer_enabled
)
3497 /* if we enable the trace buffer in fill-once
3498 * mode we know the address of the first instruction */
3499 xscale
->trace
.pc_ok
= 1;
3500 xscale
->trace
.current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
3504 /* otherwise the address is unknown, and we have no known good PC */
3505 xscale
->trace
.pc_ok
= 0;
3508 command_print(cmd_ctx
, "trace buffer %s (%s)",
3509 (xscale
->trace
.buffer_enabled
) ? "enabled" : "disabled",
3510 (xscale
->trace
.buffer_fill
> 0) ? "fill" : "wrap");
3512 dcsr_value
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32);
3513 if (xscale
->trace
.buffer_fill
>= 0)
3514 xscale_write_dcsr_sw(target
, (dcsr_value
& 0xfffffffc) | 2);
3516 xscale_write_dcsr_sw(target
, dcsr_value
& 0xfffffffc);
3521 int xscale_handle_trace_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3524 armv4_5_common_t
*armv4_5
;
3525 xscale_common_t
*xscale
;
3529 command_print(cmd_ctx
, "usage: xscale trace_image <file> [base address] [type]");
3533 target
= get_current_target(cmd_ctx
);
3535 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3540 if (xscale
->trace
.image
)
3542 image_close(xscale
->trace
.image
);
3543 free(xscale
->trace
.image
);
3544 command_print(cmd_ctx
, "previously loaded image found and closed");
3547 xscale
->trace
.image
= malloc(sizeof(image_t
));
3548 xscale
->trace
.image
->base_address_set
= 0;
3549 xscale
->trace
.image
->start_address_set
= 0;
3551 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
3554 xscale
->trace
.image
->base_address_set
= 1;
3555 xscale
->trace
.image
->base_address
= strtoul(args
[1], NULL
, 0);
3559 xscale
->trace
.image
->base_address_set
= 0;
3562 if (image_open(xscale
->trace
.image
, args
[0], (argc
>= 3) ? args
[2] : NULL
) != ERROR_OK
)
3564 free(xscale
->trace
.image
);
3565 xscale
->trace
.image
= NULL
;
3572 int xscale_handle_dump_trace_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3574 target_t
*target
= get_current_target(cmd_ctx
);
3575 armv4_5_common_t
*armv4_5
;
3576 xscale_common_t
*xscale
;
3577 xscale_trace_data_t
*trace_data
;
3580 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3585 if (target
->state
!= TARGET_HALTED
)
3587 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3593 command_print(cmd_ctx
, "usage: xscale dump_trace <file>");
3597 trace_data
= xscale
->trace
.data
;
3601 command_print(cmd_ctx
, "no trace data collected");
3605 if (fileio_open(&file
, args
[0], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
)
3614 fileio_write_u32(&file
, trace_data
->chkpt0
);
3615 fileio_write_u32(&file
, trace_data
->chkpt1
);
3616 fileio_write_u32(&file
, trace_data
->last_instruction
);
3617 fileio_write_u32(&file
, trace_data
->depth
);
3619 for (i
= 0; i
< trace_data
->depth
; i
++)
3620 fileio_write_u32(&file
, trace_data
->entries
[i
].data
| ((trace_data
->entries
[i
].type
& 0xffff) << 16));
3622 trace_data
= trace_data
->next
;
3625 fileio_close(&file
);
3630 int xscale_handle_analyze_trace_buffer_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3632 target_t
*target
= get_current_target(cmd_ctx
);
3633 armv4_5_common_t
*armv4_5
;
3634 xscale_common_t
*xscale
;
3636 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3641 xscale_analyze_trace(target
, cmd_ctx
);
3646 int xscale_handle_cp15(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3648 target_t
*target
= get_current_target(cmd_ctx
);
3649 armv4_5_common_t
*armv4_5
;
3650 xscale_common_t
*xscale
;
3652 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3657 if (target
->state
!= TARGET_HALTED
)
3659 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3666 reg_no
= strtoul(args
[0], NULL
, 0);
3667 /*translate from xscale cp15 register no to openocd register*/
3671 reg_no
= XSCALE_MAINID
;
3674 reg_no
= XSCALE_CTRL
;
3677 reg_no
= XSCALE_TTB
;
3680 reg_no
= XSCALE_DAC
;
3683 reg_no
= XSCALE_FSR
;
3686 reg_no
= XSCALE_FAR
;
3689 reg_no
= XSCALE_PID
;
3692 reg_no
= XSCALE_CPACCESS
;
3695 command_print(cmd_ctx
, "invalid register number");
3696 return ERROR_INVALID_ARGUMENTS
;
3698 reg
= &xscale
->reg_cache
->reg_list
[reg_no
];
3705 /* read cp15 control register */
3706 xscale_get_reg(reg
);
3707 value
= buf_get_u32(reg
->value
, 0, 32);
3708 command_print(cmd_ctx
, "%s (/%i): 0x%x", reg
->name
, reg
->size
, value
);
3713 u32 value
= strtoul(args
[1], NULL
, 0);
3715 /* send CP write request (command 0x41) */
3716 xscale_send_u32(target
, 0x41);
3718 /* send CP register number */
3719 xscale_send_u32(target
, reg_no
);
3721 /* send CP register value */
3722 xscale_send_u32(target
, value
);
3724 /* execute cpwait to ensure outstanding operations complete */
3725 xscale_send_u32(target
, 0x53);
3729 command_print(cmd_ctx
, "usage: cp15 [register]<, [value]>");
3735 int handle_xscale_fast_memory_access_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3737 target_t
*target
= get_current_target(cmd_ctx
);
3738 armv4_5_common_t
*armv4_5
;
3739 xscale_common_t
*xscale
;
3741 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3748 if (strcmp("enable", args
[0]) == 0)
3750 xscale
->fast_memory_access
= 1;
3752 else if (strcmp("disable", args
[0]) == 0)
3754 xscale
->fast_memory_access
= 0;
3758 return ERROR_COMMAND_SYNTAX_ERROR
;
3762 return ERROR_COMMAND_SYNTAX_ERROR
;
3765 command_print(cmd_ctx
, "fast memory access is %s", (xscale
->fast_memory_access
) ? "enabled" : "disabled");
3770 int xscale_register_commands(struct command_context_s
*cmd_ctx
)
3772 command_t
*xscale_cmd
;
3774 xscale_cmd
= register_command(cmd_ctx
, NULL
, "xscale", NULL
, COMMAND_ANY
, "xscale specific commands");
3776 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");
3777 register_command(cmd_ctx
, xscale_cmd
, "cache_clean_address", xscale_handle_cache_clean_address_command
, COMMAND_ANY
, NULL
);
3779 register_command(cmd_ctx
, xscale_cmd
, "cache_info", xscale_handle_cache_info_command
, COMMAND_EXEC
, NULL
);
3780 register_command(cmd_ctx
, xscale_cmd
, "mmu", xscale_handle_mmu_command
, COMMAND_EXEC
, "['enable'|'disable'] the MMU");
3781 register_command(cmd_ctx
, xscale_cmd
, "icache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the ICache");
3782 register_command(cmd_ctx
, xscale_cmd
, "dcache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the DCache");
3784 register_command(cmd_ctx
, xscale_cmd
, "vector_catch", xscale_handle_idcache_command
, COMMAND_EXEC
, "<mask> of vectors that should be catched");
3786 register_command(cmd_ctx
, xscale_cmd
, "trace_buffer", xscale_handle_trace_buffer_command
, COMMAND_EXEC
, "<enable|disable> ['fill' [n]|'wrap']");
3788 register_command(cmd_ctx
, xscale_cmd
, "dump_trace", xscale_handle_dump_trace_command
, COMMAND_EXEC
, "dump content of trace buffer to <file>");
3789 register_command(cmd_ctx
, xscale_cmd
, "analyze_trace", xscale_handle_analyze_trace_buffer_command
, COMMAND_EXEC
, "analyze content of trace buffer");
3790 register_command(cmd_ctx
, xscale_cmd
, "trace_image", xscale_handle_trace_image_command
,
3791 COMMAND_EXEC
, "load image from <file> [base address]");
3793 register_command(cmd_ctx
, xscale_cmd
, "cp15", xscale_handle_cp15
, COMMAND_EXEC
, "access coproc 15 <register> [value]");
3794 register_command(cmd_ctx
, xscale_cmd
, "fast_memory_access", handle_xscale_fast_memory_access_command
,
3795 COMMAND_ANY
, "use fast memory accesses instead of slower but potentially unsafe slow accesses <enable|disable>");
3798 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)