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
= NULL
;
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); /* ensures that we're in the TAP_RTI state as the above could be a no-op */
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 fields
[0].in_value
= NULL
;
653 if (!xscale
->fast_memory_access
)
655 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
658 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
659 fields
[1].num_bits
= 32;
660 fields
[1].out_value
= output
;
661 fields
[1].out_mask
= NULL
;
662 fields
[1].in_value
= NULL
;
663 fields
[1].in_handler
= NULL
;
664 fields
[1].in_handler_priv
= NULL
;
665 fields
[1].in_check_value
= NULL
;
666 fields
[1].in_check_mask
= NULL
;
670 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
671 fields
[2].num_bits
= 1;
672 fields
[2].out_value
= &field2
;
673 fields
[2].out_mask
= NULL
;
674 fields
[2].in_value
= NULL
;
675 fields
[2].in_handler
= NULL
;
676 if (!xscale
->fast_memory_access
)
678 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
683 int endianness
= target
->endianness
;
684 while (done_count
++ < count
)
686 if (endianness
== TARGET_LITTLE_ENDIAN
)
699 jtag_add_dr_scan(3, fields
, TAP_RTI
);
705 while (done_count
++ < count
)
707 /* extract sized element from target-endian buffer, and put it
708 * into little-endian output buffer
713 buf_set_u32(output
, 0, 32, target_buffer_get_u16(target
, buffer
));
719 ERROR("BUG: size neither 4, 2 nor 1");
723 jtag_add_dr_scan(3, fields
, TAP_RTI
);
729 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
731 ERROR("JTAG error while sending data to debug handler");
738 int xscale_send_u32(target_t
*target
, u32 value
)
740 armv4_5_common_t
*armv4_5
= target
->arch_info
;
741 xscale_common_t
*xscale
= armv4_5
->arch_info
;
743 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
744 return xscale_write_rx(target
);
747 int xscale_write_dcsr(target_t
*target
, int hold_rst
, int ext_dbg_brk
)
749 armv4_5_common_t
*armv4_5
= target
->arch_info
;
750 xscale_common_t
*xscale
= armv4_5
->arch_info
;
754 scan_field_t fields
[3];
756 u8 field0_check_value
= 0x2;
757 u8 field0_check_mask
= 0x7;
759 u8 field2_check_value
= 0x0;
760 u8 field2_check_mask
= 0x1;
763 xscale
->hold_rst
= hold_rst
;
765 if (ext_dbg_brk
!= -1)
766 xscale
->external_debug_break
= ext_dbg_brk
;
768 jtag_add_end_state(TAP_RTI
);
769 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dcsr
);
771 buf_set_u32(&field0
, 1, 1, xscale
->hold_rst
);
772 buf_set_u32(&field0
, 2, 1, xscale
->external_debug_break
);
774 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
775 fields
[0].num_bits
= 3;
776 fields
[0].out_value
= &field0
;
777 fields
[0].out_mask
= NULL
;
778 fields
[0].in_value
= NULL
;
779 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
781 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
782 fields
[1].num_bits
= 32;
783 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
784 fields
[1].out_mask
= NULL
;
785 fields
[1].in_value
= NULL
;
786 fields
[1].in_handler
= NULL
;
787 fields
[1].in_handler_priv
= NULL
;
788 fields
[1].in_check_value
= NULL
;
789 fields
[1].in_check_mask
= NULL
;
793 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
794 fields
[2].num_bits
= 1;
795 fields
[2].out_value
= &field2
;
796 fields
[2].out_mask
= NULL
;
797 fields
[2].in_value
= NULL
;
798 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
800 jtag_add_dr_scan(3, fields
, -1);
802 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
804 ERROR("JTAG error while writing DCSR");
808 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].dirty
= 0;
809 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].valid
= 1;
814 /* parity of the number of bits 0 if even; 1 if odd. for 32 bit words */
815 unsigned int parity (unsigned int v
)
822 DEBUG("parity of 0x%x is %i", ov
, (0x6996 >> v
) & 1);
823 return (0x6996 >> v
) & 1;
826 int xscale_load_ic(target_t
*target
, int mini
, u32 va
, u32 buffer
[8])
828 armv4_5_common_t
*armv4_5
= target
->arch_info
;
829 xscale_common_t
*xscale
= armv4_5
->arch_info
;
834 scan_field_t fields
[2];
836 DEBUG("loading miniIC at 0x%8.8x", va
);
838 jtag_add_end_state(TAP_RTI
);
839 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.ldic
); /* LDIC */
841 /* CMD is b010 for Main IC and b011 for Mini IC */
843 buf_set_u32(&cmd
, 0, 3, 0x3);
845 buf_set_u32(&cmd
, 0, 3, 0x2);
847 buf_set_u32(&cmd
, 3, 3, 0x0);
849 /* virtual address of desired cache line */
850 buf_set_u32(packet
, 0, 27, va
>> 5);
852 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
853 fields
[0].num_bits
= 6;
854 fields
[0].out_value
= &cmd
;
855 fields
[0].out_mask
= NULL
;
856 fields
[0].in_value
= NULL
;
857 fields
[0].in_check_value
= NULL
;
858 fields
[0].in_check_mask
= NULL
;
859 fields
[0].in_handler
= NULL
;
860 fields
[0].in_handler_priv
= NULL
;
862 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
863 fields
[1].num_bits
= 27;
864 fields
[1].out_value
= packet
;
865 fields
[1].out_mask
= NULL
;
866 fields
[1].in_value
= NULL
;
867 fields
[1].in_check_value
= NULL
;
868 fields
[1].in_check_mask
= NULL
;
869 fields
[1].in_handler
= NULL
;
870 fields
[1].in_handler_priv
= NULL
;
872 jtag_add_dr_scan(2, fields
, -1);
874 fields
[0].num_bits
= 32;
875 fields
[0].out_value
= packet
;
877 fields
[1].num_bits
= 1;
878 fields
[1].out_value
= &cmd
;
880 for (word
= 0; word
< 8; word
++)
882 buf_set_u32(packet
, 0, 32, buffer
[word
]);
883 cmd
= parity(*((u32
*)packet
));
884 jtag_add_dr_scan(2, fields
, -1);
887 jtag_execute_queue();
892 int xscale_invalidate_ic_line(target_t
*target
, u32 va
)
894 armv4_5_common_t
*armv4_5
= target
->arch_info
;
895 xscale_common_t
*xscale
= armv4_5
->arch_info
;
899 scan_field_t fields
[2];
901 jtag_add_end_state(TAP_RTI
);
902 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.ldic
); /* LDIC */
904 /* CMD for invalidate IC line b000, bits [6:4] b000 */
905 buf_set_u32(&cmd
, 0, 6, 0x0);
907 /* virtual address of desired cache line */
908 buf_set_u32(packet
, 0, 27, va
>> 5);
910 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
911 fields
[0].num_bits
= 6;
912 fields
[0].out_value
= &cmd
;
913 fields
[0].out_mask
= NULL
;
914 fields
[0].in_value
= NULL
;
915 fields
[0].in_check_value
= NULL
;
916 fields
[0].in_check_mask
= NULL
;
917 fields
[0].in_handler
= NULL
;
918 fields
[0].in_handler_priv
= NULL
;
920 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
921 fields
[1].num_bits
= 27;
922 fields
[1].out_value
= packet
;
923 fields
[1].out_mask
= NULL
;
924 fields
[1].in_value
= NULL
;
925 fields
[1].in_check_value
= NULL
;
926 fields
[1].in_check_mask
= NULL
;
927 fields
[1].in_handler
= NULL
;
928 fields
[1].in_handler_priv
= NULL
;
930 jtag_add_dr_scan(2, fields
, -1);
935 int xscale_update_vectors(target_t
*target
)
937 armv4_5_common_t
*armv4_5
= target
->arch_info
;
938 xscale_common_t
*xscale
= armv4_5
->arch_info
;
941 u32 low_reset_branch
, high_reset_branch
;
943 for (i
= 1; i
< 8; i
++)
945 /* if there's a static vector specified for this exception, override */
946 if (xscale
->static_high_vectors_set
& (1 << i
))
948 xscale
->high_vectors
[i
] = xscale
->static_high_vectors
[i
];
952 if (target_read_u32(target
, 0xffff0000 + 4*i
, &xscale
->high_vectors
[i
]) != ERROR_OK
)
954 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
959 for (i
= 1; i
< 8; i
++)
961 if (xscale
->static_low_vectors_set
& (1 << i
))
963 xscale
->low_vectors
[i
] = xscale
->static_low_vectors
[i
];
967 if (target_read_u32(target
, 0x0 + 4*i
, &xscale
->low_vectors
[i
]) != ERROR_OK
)
969 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
974 /* calculate branches to debug handler */
975 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
976 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
978 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
979 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
981 /* invalidate and load exception vectors in mini i-cache */
982 xscale_invalidate_ic_line(target
, 0x0);
983 xscale_invalidate_ic_line(target
, 0xffff0000);
985 xscale_load_ic(target
, 1, 0x0, xscale
->low_vectors
);
986 xscale_load_ic(target
, 1, 0xffff0000, xscale
->high_vectors
);
991 int xscale_arch_state(struct target_s
*target
)
993 armv4_5_common_t
*armv4_5
= target
->arch_info
;
994 xscale_common_t
*xscale
= armv4_5
->arch_info
;
998 "disabled", "enabled"
1001 char *arch_dbg_reason
[] =
1003 "", "\n(processor reset)", "\n(trace buffer full)"
1006 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
1008 ERROR("BUG: called for a non-ARMv4/5 target");
1012 USER("target halted in %s state due to %s, current mode: %s\n"
1013 "cpsr: 0x%8.8x pc: 0x%8.8x\n"
1014 "MMU: %s, D-Cache: %s, I-Cache: %s"
1016 armv4_5_state_strings
[armv4_5
->core_state
],
1017 target_debug_reason_strings
[target
->debug_reason
],
1018 armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)],
1019 buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32),
1020 buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32),
1021 state
[xscale
->armv4_5_mmu
.mmu_enabled
],
1022 state
[xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
],
1023 state
[xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
],
1024 arch_dbg_reason
[xscale
->arch_debug_reason
]);
1029 int xscale_poll(target_t
*target
)
1031 int retval
=ERROR_OK
;
1032 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1033 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1035 if ((target
->state
== TARGET_RUNNING
) || (target
->state
== TARGET_DEBUG_RUNNING
))
1037 enum target_state previous_state
= target
->state
;
1038 if ((retval
= xscale_read_tx(target
, 0)) == ERROR_OK
)
1041 /* there's data to read from the tx register, we entered debug state */
1042 xscale
->handler_running
= 1;
1044 target
->state
= TARGET_HALTED
;
1046 /* process debug entry, fetching current mode regs */
1047 retval
= xscale_debug_entry(target
);
1049 else if (retval
!= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
1051 USER("error while polling TX register, reset CPU");
1052 /* here we "lie" so GDB won't get stuck and a reset can be perfomed */
1053 target
->state
= TARGET_HALTED
;
1056 /* debug_entry could have overwritten target state (i.e. immediate resume)
1057 * don't signal event handlers in that case
1059 if (target
->state
!= TARGET_HALTED
)
1062 /* if target was running, signal that we halted
1063 * otherwise we reentered from debug execution */
1064 if (previous_state
== TARGET_RUNNING
)
1065 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1067 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
1073 int xscale_debug_entry(target_t
*target
)
1075 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1076 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1083 /* clear external dbg break (will be written on next DCSR read) */
1084 xscale
->external_debug_break
= 0;
1085 xscale_read_dcsr(target
);
1087 /* get r0, pc, r1 to r7 and cpsr */
1088 xscale_receive(target
, buffer
, 10);
1090 /* move r0 from buffer to register cache */
1091 buf_set_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32, buffer
[0]);
1092 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
1093 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
1094 DEBUG("r0: 0x%8.8x", buffer
[0]);
1096 /* move pc from buffer to register cache */
1097 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, buffer
[1]);
1098 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
1099 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
1100 DEBUG("pc: 0x%8.8x", buffer
[1]);
1102 /* move data from buffer to register cache */
1103 for (i
= 1; i
<= 7; i
++)
1105 buf_set_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32, buffer
[1 + i
]);
1106 armv4_5
->core_cache
->reg_list
[i
].dirty
= 1;
1107 armv4_5
->core_cache
->reg_list
[i
].valid
= 1;
1108 DEBUG("r%i: 0x%8.8x", i
, buffer
[i
+ 1]);
1111 buf_set_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32, buffer
[9]);
1112 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].dirty
= 1;
1113 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].valid
= 1;
1114 DEBUG("cpsr: 0x%8.8x", buffer
[9]);
1116 armv4_5
->core_mode
= buffer
[9] & 0x1f;
1117 if (armv4_5_mode_to_number(armv4_5
->core_mode
) == -1)
1119 target
->state
= TARGET_UNKNOWN
;
1120 ERROR("cpsr contains invalid mode value - communication failure");
1121 return ERROR_TARGET_FAILURE
;
1123 DEBUG("target entered debug state in %s mode", armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)]);
1125 if (buffer
[9] & 0x20)
1126 armv4_5
->core_state
= ARMV4_5_STATE_THUMB
;
1128 armv4_5
->core_state
= ARMV4_5_STATE_ARM
;
1130 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1131 if ((armv4_5
->core_mode
!= ARMV4_5_MODE_USR
) && (armv4_5
->core_mode
!= ARMV4_5_MODE_SYS
))
1133 xscale_receive(target
, buffer
, 8);
1134 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1135 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
1136 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
1140 /* r8 to r14, but no spsr */
1141 xscale_receive(target
, buffer
, 7);
1144 /* move data from buffer to register cache */
1145 for (i
= 8; i
<= 14; i
++)
1147 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).value
, 0, 32, buffer
[i
- 8]);
1148 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).dirty
= 0;
1149 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).valid
= 1;
1152 /* examine debug reason */
1153 xscale_read_dcsr(target
);
1154 moe
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 2, 3);
1156 /* stored PC (for calculating fixup) */
1157 pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1161 case 0x0: /* Processor reset */
1162 target
->debug_reason
= DBG_REASON_DBGRQ
;
1163 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_RESET
;
1166 case 0x1: /* Instruction breakpoint hit */
1167 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1168 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1171 case 0x2: /* Data breakpoint hit */
1172 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
1173 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1176 case 0x3: /* BKPT instruction executed */
1177 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1178 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1181 case 0x4: /* Ext. debug event */
1182 target
->debug_reason
= DBG_REASON_DBGRQ
;
1183 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1186 case 0x5: /* Vector trap occured */
1187 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1188 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1191 case 0x6: /* Trace buffer full break */
1192 target
->debug_reason
= DBG_REASON_DBGRQ
;
1193 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_TB_FULL
;
1196 case 0x7: /* Reserved */
1198 ERROR("Method of Entry is 'Reserved'");
1203 /* apply PC fixup */
1204 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, pc
);
1206 /* on the first debug entry, identify cache type */
1207 if (xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
1211 /* read cp15 cache type register */
1212 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
]);
1213 cache_type_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
].value
, 0, 32);
1215 armv4_5_identify_cache(cache_type_reg
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
1218 /* examine MMU and Cache settings */
1219 /* read cp15 control register */
1220 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
1221 xscale
->cp15_control_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
1222 xscale
->armv4_5_mmu
.mmu_enabled
= (xscale
->cp15_control_reg
& 0x1U
) ? 1 : 0;
1223 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= (xscale
->cp15_control_reg
& 0x4U
) ? 1 : 0;
1224 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= (xscale
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
1226 /* tracing enabled, read collected trace data */
1227 if (xscale
->trace
.buffer_enabled
)
1229 xscale_read_trace(target
);
1230 xscale
->trace
.buffer_fill
--;
1232 /* resume if we're still collecting trace data */
1233 if ((xscale
->arch_debug_reason
== XSCALE_DBG_REASON_TB_FULL
)
1234 && (xscale
->trace
.buffer_fill
> 0))
1236 xscale_resume(target
, 1, 0x0, 1, 0);
1240 xscale
->trace
.buffer_enabled
= 0;
1247 int xscale_halt(target_t
*target
)
1249 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1250 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1252 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
1254 if (target
->state
== TARGET_HALTED
)
1256 WARNING("target was already halted");
1257 return ERROR_TARGET_ALREADY_HALTED
;
1259 else if (target
->state
== TARGET_UNKNOWN
)
1261 /* this must not happen for a xscale target */
1262 ERROR("target was in unknown state when halt was requested");
1263 return ERROR_TARGET_INVALID
;
1265 else if (target
->state
== TARGET_RESET
)
1267 DEBUG("target->state == TARGET_RESET");
1271 /* assert external dbg break */
1272 xscale
->external_debug_break
= 1;
1273 xscale_read_dcsr(target
);
1275 target
->debug_reason
= DBG_REASON_DBGRQ
;
1281 int xscale_enable_single_step(struct target_s
*target
, u32 next_pc
)
1283 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1284 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1285 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1287 if (xscale
->ibcr0_used
)
1289 breakpoint_t
*ibcr0_bp
= breakpoint_find(target
, buf_get_u32(ibcr0
->value
, 0, 32) & 0xfffffffe);
1293 xscale_unset_breakpoint(target
, ibcr0_bp
);
1297 ERROR("BUG: xscale->ibcr0_used is set, but no breakpoint with that address found");
1302 xscale_set_reg_u32(ibcr0
, next_pc
| 0x1);
1307 int xscale_disable_single_step(struct target_s
*target
)
1309 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1310 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1311 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1313 xscale_set_reg_u32(ibcr0
, 0x0);
1318 int xscale_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
1320 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1321 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1322 breakpoint_t
*breakpoint
= target
->breakpoints
;
1331 if (target
->state
!= TARGET_HALTED
)
1333 WARNING("target not halted");
1334 return ERROR_TARGET_NOT_HALTED
;
1337 if (!debug_execution
)
1339 target_free_all_working_areas(target
);
1342 /* update vector tables */
1343 xscale_update_vectors(target
);
1345 /* current = 1: continue on current pc, otherwise continue at <address> */
1347 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1349 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1351 /* if we're at the reset vector, we have to simulate the branch */
1352 if (current_pc
== 0x0)
1354 arm_simulate_step(target
, NULL
);
1355 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1358 /* the front-end may request us not to handle breakpoints */
1359 if (handle_breakpoints
)
1361 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1365 /* there's a breakpoint at the current PC, we have to step over it */
1366 DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
1367 xscale_unset_breakpoint(target
, breakpoint
);
1369 /* calculate PC of next instruction */
1370 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1373 target_read_u32(target
, current_pc
, ¤t_opcode
);
1374 ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode
);
1377 DEBUG("enable single-step");
1378 xscale_enable_single_step(target
, next_pc
);
1380 /* restore banked registers */
1381 xscale_restore_context(target
);
1383 /* send resume request (command 0x30 or 0x31)
1384 * clean the trace buffer if it is to be enabled (0x62) */
1385 if (xscale
->trace
.buffer_enabled
)
1387 xscale_send_u32(target
, 0x62);
1388 xscale_send_u32(target
, 0x31);
1391 xscale_send_u32(target
, 0x30);
1394 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1395 DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1397 for (i
= 7; i
>= 0; i
--)
1400 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1401 DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1405 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1406 DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1408 /* wait for and process debug entry */
1409 xscale_debug_entry(target
);
1411 DEBUG("disable single-step");
1412 xscale_disable_single_step(target
);
1414 DEBUG("set breakpoint at 0x%8.8x", breakpoint
->address
);
1415 xscale_set_breakpoint(target
, breakpoint
);
1419 /* enable any pending breakpoints and watchpoints */
1420 xscale_enable_breakpoints(target
);
1421 xscale_enable_watchpoints(target
);
1423 /* restore banked registers */
1424 xscale_restore_context(target
);
1426 /* send resume request (command 0x30 or 0x31)
1427 * clean the trace buffer if it is to be enabled (0x62) */
1428 if (xscale
->trace
.buffer_enabled
)
1430 xscale_send_u32(target
, 0x62);
1431 xscale_send_u32(target
, 0x31);
1434 xscale_send_u32(target
, 0x30);
1437 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1438 DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1440 for (i
= 7; i
>= 0; i
--)
1443 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1444 DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1448 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1449 DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1451 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1453 if (!debug_execution
)
1455 /* registers are now invalid */
1456 armv4_5_invalidate_core_regs(target
);
1457 target
->state
= TARGET_RUNNING
;
1458 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1462 target
->state
= TARGET_DEBUG_RUNNING
;
1463 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1466 DEBUG("target resumed");
1468 xscale
->handler_running
= 1;
1473 int xscale_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
1475 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1476 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1477 breakpoint_t
*breakpoint
= target
->breakpoints
;
1479 u32 current_pc
, next_pc
;
1483 if (target
->state
!= TARGET_HALTED
)
1485 WARNING("target not halted");
1486 return ERROR_TARGET_NOT_HALTED
;
1489 /* current = 1: continue on current pc, otherwise continue at <address> */
1491 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1493 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1495 /* if we're at the reset vector, we have to simulate the step */
1496 if (current_pc
== 0x0)
1498 arm_simulate_step(target
, NULL
);
1499 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1501 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1502 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1507 /* the front-end may request us not to handle breakpoints */
1508 if (handle_breakpoints
)
1509 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1511 xscale_unset_breakpoint(target
, breakpoint
);
1514 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1516 /* calculate PC of next instruction */
1517 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1520 target_read_u32(target
, current_pc
, ¤t_opcode
);
1521 ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode
);
1524 DEBUG("enable single-step");
1525 xscale_enable_single_step(target
, next_pc
);
1527 /* restore banked registers */
1528 xscale_restore_context(target
);
1530 /* send resume request (command 0x30 or 0x31)
1531 * clean the trace buffer if it is to be enabled (0x62) */
1532 if (xscale
->trace
.buffer_enabled
)
1534 xscale_send_u32(target
, 0x62);
1535 xscale_send_u32(target
, 0x31);
1538 xscale_send_u32(target
, 0x30);
1541 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1542 DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1544 for (i
= 7; i
>= 0; i
--)
1547 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1548 DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1552 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1553 DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1555 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1557 /* registers are now invalid */
1558 armv4_5_invalidate_core_regs(target
);
1560 /* wait for and process debug entry */
1561 xscale_debug_entry(target
);
1563 DEBUG("disable single-step");
1564 xscale_disable_single_step(target
);
1566 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1570 xscale_set_breakpoint(target
, breakpoint
);
1573 DEBUG("target stepped");
1579 int xscale_assert_reset(target_t
*target
)
1581 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1582 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1584 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
1586 /* select DCSR instruction (set endstate to R-T-I to ensure we don't
1587 * end up in T-L-R, which would reset JTAG
1589 jtag_add_end_state(TAP_RTI
);
1590 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dcsr
);
1592 /* set Hold reset, Halt mode and Trap Reset */
1593 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1594 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1595 xscale_write_dcsr(target
, 1, 0);
1597 /* select BYPASS, because having DCSR selected caused problems on the PXA27x */
1598 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, 0x7f);
1599 jtag_execute_queue();
1602 jtag_add_reset(0, 1);
1604 /* sleep 1ms, to be sure we fulfill any requirements */
1605 jtag_add_sleep(1000);
1606 jtag_execute_queue();
1608 target
->state
= TARGET_RESET
;
1613 int xscale_deassert_reset(target_t
*target
)
1615 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1616 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1618 fileio_t debug_handler
;
1626 breakpoint_t
*breakpoint
= target
->breakpoints
;
1630 xscale
->ibcr_available
= 2;
1631 xscale
->ibcr0_used
= 0;
1632 xscale
->ibcr1_used
= 0;
1634 xscale
->dbr_available
= 2;
1635 xscale
->dbr0_used
= 0;
1636 xscale
->dbr1_used
= 0;
1638 /* mark all hardware breakpoints as unset */
1641 if (breakpoint
->type
== BKPT_HARD
)
1643 breakpoint
->set
= 0;
1645 breakpoint
= breakpoint
->next
;
1648 if (!xscale
->handler_installed
)
1651 jtag_add_reset(0, 0);
1653 /* wait 300ms; 150 and 100ms were not enough */
1654 jtag_add_sleep(300*1000);
1656 jtag_add_runtest(2030, TAP_RTI
);
1657 jtag_execute_queue();
1659 /* set Hold reset, Halt mode and Trap Reset */
1660 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1661 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1662 xscale_write_dcsr(target
, 1, 0);
1664 /* Load debug handler */
1665 if (fileio_open(&debug_handler
, "xscale/debug_handler.bin", FILEIO_READ
, FILEIO_BINARY
) != ERROR_OK
)
1670 if ((binary_size
= debug_handler
.size
) % 4)
1672 ERROR("debug_handler.bin: size not a multiple of 4");
1676 if (binary_size
> 0x800)
1678 ERROR("debug_handler.bin: larger than 2kb");
1682 binary_size
= CEIL(binary_size
, 32) * 32;
1684 address
= xscale
->handler_address
;
1685 while (binary_size
> 0)
1690 if ((retval
= fileio_read(&debug_handler
, 32, buffer
, &buf_cnt
)) != ERROR_OK
)
1695 for (i
= 0; i
< buf_cnt
; i
+= 4)
1697 /* convert LE buffer to host-endian u32 */
1698 cache_line
[i
/ 4] = le_to_h_u32(&buffer
[i
]);
1701 for (; buf_cnt
< 32; buf_cnt
+= 4)
1703 cache_line
[buf_cnt
/ 4] = 0xe1a08008;
1706 /* only load addresses other than the reset vectors */
1707 if ((address
% 0x400) != 0x0)
1709 xscale_load_ic(target
, 1, address
, cache_line
);
1713 binary_size
-= buf_cnt
;
1716 xscale_load_ic(target
, 1, 0x0, xscale
->low_vectors
);
1717 xscale_load_ic(target
, 1, 0xffff0000, xscale
->high_vectors
);
1719 jtag_add_runtest(30, TAP_RTI
);
1721 jtag_add_sleep(100000);
1723 /* set Hold reset, Halt mode and Trap Reset */
1724 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1725 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1726 xscale_write_dcsr(target
, 1, 0);
1728 /* clear Hold reset to let the target run (should enter debug handler) */
1729 xscale_write_dcsr(target
, 0, 1);
1730 target
->state
= TARGET_RUNNING
;
1732 if ((target
->reset_mode
!= RESET_HALT
) && (target
->reset_mode
!= RESET_INIT
))
1734 jtag_add_sleep(10000);
1736 /* we should have entered debug now */
1737 xscale_debug_entry(target
);
1738 target
->state
= TARGET_HALTED
;
1740 /* resume the target */
1741 xscale_resume(target
, 1, 0x0, 1, 0);
1744 fileio_close(&debug_handler
);
1748 jtag_add_reset(0, 0);
1755 int xscale_soft_reset_halt(struct target_s
*target
)
1761 int xscale_prepare_reset_halt(struct target_s
*target
)
1763 /* nothing to be done for reset_halt on XScale targets
1764 * we always halt after a reset to upload the debug handler
1769 int xscale_read_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
)
1775 int xscale_write_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
, u32 value
)
1781 int xscale_full_context(target_t
*target
)
1783 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1791 if (target
->state
!= TARGET_HALTED
)
1793 WARNING("target not halted");
1794 return ERROR_TARGET_NOT_HALTED
;
1797 buffer
= malloc(4 * 8);
1799 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1800 * we can't enter User mode on an XScale (unpredictable),
1801 * but User shares registers with SYS
1803 for(i
= 1; i
< 7; i
++)
1807 /* check if there are invalid registers in the current mode
1809 for (j
= 0; j
<= 16; j
++)
1811 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
== 0)
1819 /* request banked registers */
1820 xscale_send_u32(target
, 0x0);
1823 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1824 tmp_cpsr
|= 0xc0; /* I/F bits */
1826 /* send CPSR for desired mode */
1827 xscale_send_u32(target
, tmp_cpsr
);
1829 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1830 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1832 xscale_receive(target
, buffer
, 8);
1833 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1834 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1835 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).valid
= 1;
1839 xscale_receive(target
, buffer
, 7);
1842 /* move data from buffer to register cache */
1843 for (j
= 8; j
<= 14; j
++)
1845 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]);
1846 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1847 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
= 1;
1857 int xscale_restore_context(target_t
*target
)
1859 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1865 if (target
->state
!= TARGET_HALTED
)
1867 WARNING("target not halted");
1868 return ERROR_TARGET_NOT_HALTED
;
1871 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1872 * we can't enter User mode on an XScale (unpredictable),
1873 * but User shares registers with SYS
1875 for(i
= 1; i
< 7; i
++)
1879 /* check if there are invalid registers in the current mode
1881 for (j
= 8; j
<= 14; j
++)
1883 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
== 1)
1887 /* if not USR/SYS, check if the SPSR needs to be written */
1888 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1890 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
== 1)
1898 /* send banked registers */
1899 xscale_send_u32(target
, 0x1);
1902 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1903 tmp_cpsr
|= 0xc0; /* I/F bits */
1905 /* send CPSR for desired mode */
1906 xscale_send_u32(target
, tmp_cpsr
);
1908 /* send banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1909 for (j
= 8; j
<= 14; j
++)
1911 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, j
).value
, 0, 32));
1912 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1915 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1917 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32));
1918 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1926 int xscale_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1928 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1929 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1933 DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address
, size
, count
);
1935 if (target
->state
!= TARGET_HALTED
)
1937 WARNING("target not halted");
1938 return ERROR_TARGET_NOT_HALTED
;
1941 /* sanitize arguments */
1942 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1943 return ERROR_INVALID_ARGUMENTS
;
1945 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1946 return ERROR_TARGET_UNALIGNED_ACCESS
;
1948 /* send memory read request (command 0x1n, n: access size) */
1949 xscale_send_u32(target
, 0x10 | size
);
1951 /* send base address for read request */
1952 xscale_send_u32(target
, address
);
1954 /* send number of requested data words */
1955 xscale_send_u32(target
, count
);
1957 /* receive data from target (count times 32-bit words in host endianness) */
1958 buf32
= malloc(4 * count
);
1959 xscale_receive(target
, buf32
, count
);
1961 /* extract data from host-endian buffer into byte stream */
1962 for (i
= 0; i
< count
; i
++)
1967 target_buffer_set_u32(target
, buffer
, buf32
[i
]);
1971 target_buffer_set_u16(target
, buffer
, buf32
[i
] & 0xffff);
1975 *buffer
++ = buf32
[i
] & 0xff;
1978 ERROR("should never get here");
1985 /* examine DCSR, to see if Sticky Abort (SA) got set */
1986 xscale_read_dcsr(target
);
1987 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
1990 xscale_send_u32(target
, 0x60);
1992 return ERROR_TARGET_DATA_ABORT
;
1998 int xscale_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
2000 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2001 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2003 DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address
, size
, count
);
2005 if (target
->state
!= TARGET_HALTED
)
2007 WARNING("target not halted");
2008 return ERROR_TARGET_NOT_HALTED
;
2011 /* sanitize arguments */
2012 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
2013 return ERROR_INVALID_ARGUMENTS
;
2015 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
2016 return ERROR_TARGET_UNALIGNED_ACCESS
;
2018 /* send memory write request (command 0x2n, n: access size) */
2019 xscale_send_u32(target
, 0x20 | size
);
2021 /* send base address for read request */
2022 xscale_send_u32(target
, address
);
2024 /* send number of requested data words to be written*/
2025 xscale_send_u32(target
, count
);
2027 /* extract data from host-endian buffer into byte stream */
2029 for (i
= 0; i
< count
; i
++)
2034 value
= target_buffer_get_u32(target
, buffer
);
2035 xscale_send_u32(target
, value
);
2039 value
= target_buffer_get_u16(target
, buffer
);
2040 xscale_send_u32(target
, value
);
2045 xscale_send_u32(target
, value
);
2049 ERROR("should never get here");
2054 xscale_send(target
, buffer
, count
, size
);
2056 /* examine DCSR, to see if Sticky Abort (SA) got set */
2057 xscale_read_dcsr(target
);
2058 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
2061 xscale_send_u32(target
, 0x60);
2063 return ERROR_TARGET_DATA_ABORT
;
2069 int xscale_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
2071 return xscale_write_memory(target
, address
, 4, count
, buffer
);
2074 int xscale_checksum_memory(struct target_s
*target
, u32 address
, u32 count
, u32
* checksum
)
2076 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2079 u32
xscale_get_ttb(target_t
*target
)
2081 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2082 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2085 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_TTB
]);
2086 ttb
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_TTB
].value
, 0, 32);
2091 void xscale_disable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
2093 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2094 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2097 /* read cp15 control register */
2098 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2099 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2102 cp15_control
&= ~0x1U
;
2107 xscale_send_u32(target
, 0x50);
2108 xscale_send_u32(target
, xscale
->cache_clean_address
);
2110 /* invalidate DCache */
2111 xscale_send_u32(target
, 0x51);
2113 cp15_control
&= ~0x4U
;
2118 /* invalidate ICache */
2119 xscale_send_u32(target
, 0x52);
2120 cp15_control
&= ~0x1000U
;
2123 /* write new cp15 control register */
2124 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2126 /* execute cpwait to ensure outstanding operations complete */
2127 xscale_send_u32(target
, 0x53);
2130 void xscale_enable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
2132 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2133 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2136 /* read cp15 control register */
2137 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2138 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2141 cp15_control
|= 0x1U
;
2144 cp15_control
|= 0x4U
;
2147 cp15_control
|= 0x1000U
;
2149 /* write new cp15 control register */
2150 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2152 /* execute cpwait to ensure outstanding operations complete */
2153 xscale_send_u32(target
, 0x53);
2156 int xscale_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2158 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2159 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2161 if (target
->state
!= TARGET_HALTED
)
2163 WARNING("target not halted");
2164 return ERROR_TARGET_NOT_HALTED
;
2167 if (xscale
->force_hw_bkpts
)
2168 breakpoint
->type
= BKPT_HARD
;
2170 if (breakpoint
->set
)
2172 WARNING("breakpoint already set");
2176 if (breakpoint
->type
== BKPT_HARD
)
2178 u32 value
= breakpoint
->address
| 1;
2179 if (!xscale
->ibcr0_used
)
2181 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], value
);
2182 xscale
->ibcr0_used
= 1;
2183 breakpoint
->set
= 1; /* breakpoint set on first breakpoint register */
2185 else if (!xscale
->ibcr1_used
)
2187 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], value
);
2188 xscale
->ibcr1_used
= 1;
2189 breakpoint
->set
= 2; /* breakpoint set on second breakpoint register */
2193 ERROR("BUG: no hardware comparator available");
2197 else if (breakpoint
->type
== BKPT_SOFT
)
2199 if (breakpoint
->length
== 4)
2201 /* keep the original instruction in target endianness */
2202 target
->type
->read_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
);
2203 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2204 target_write_u32(target
, breakpoint
->address
, xscale
->arm_bkpt
);
2208 /* keep the original instruction in target endianness */
2209 target
->type
->read_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
);
2210 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2211 target_write_u32(target
, breakpoint
->address
, xscale
->thumb_bkpt
);
2213 breakpoint
->set
= 1;
2220 int xscale_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2222 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2223 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2225 if (target
->state
!= TARGET_HALTED
)
2227 WARNING("target not halted");
2228 return ERROR_TARGET_NOT_HALTED
;
2231 if (xscale
->force_hw_bkpts
)
2233 DEBUG("forcing use of hardware breakpoint at address 0x%8.8x", breakpoint
->address
);
2234 breakpoint
->type
= BKPT_HARD
;
2237 if ((breakpoint
->type
== BKPT_HARD
) && (xscale
->ibcr_available
< 1))
2239 INFO("no breakpoint unit available for hardware breakpoint");
2240 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2244 xscale
->ibcr_available
--;
2247 if ((breakpoint
->length
!= 2) && (breakpoint
->length
!= 4))
2249 INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
2250 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2256 int xscale_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2258 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2259 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2261 if (target
->state
!= TARGET_HALTED
)
2263 WARNING("target not halted");
2264 return ERROR_TARGET_NOT_HALTED
;
2267 if (!breakpoint
->set
)
2269 WARNING("breakpoint not set");
2273 if (breakpoint
->type
== BKPT_HARD
)
2275 if (breakpoint
->set
== 1)
2277 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], 0x0);
2278 xscale
->ibcr0_used
= 0;
2280 else if (breakpoint
->set
== 2)
2282 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], 0x0);
2283 xscale
->ibcr1_used
= 0;
2285 breakpoint
->set
= 0;
2289 /* restore original instruction (kept in target endianness) */
2290 if (breakpoint
->length
== 4)
2292 target
->type
->write_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
);
2296 target
->type
->write_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
);
2298 breakpoint
->set
= 0;
2304 int xscale_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2306 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2307 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2309 if (target
->state
!= TARGET_HALTED
)
2311 WARNING("target not halted");
2312 return ERROR_TARGET_NOT_HALTED
;
2315 if (breakpoint
->set
)
2317 xscale_unset_breakpoint(target
, breakpoint
);
2320 if (breakpoint
->type
== BKPT_HARD
)
2321 xscale
->ibcr_available
++;
2326 int xscale_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2328 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2329 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2331 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2332 u32 dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2334 if (target
->state
!= TARGET_HALTED
)
2336 WARNING("target not halted");
2337 return ERROR_TARGET_NOT_HALTED
;
2340 xscale_get_reg(dbcon
);
2342 switch (watchpoint
->rw
)
2354 ERROR("BUG: watchpoint->rw neither read, write nor access");
2357 if (!xscale
->dbr0_used
)
2359 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR0
], watchpoint
->address
);
2360 dbcon_value
|= enable
;
2361 xscale_set_reg_u32(dbcon
, dbcon_value
);
2362 watchpoint
->set
= 1;
2363 xscale
->dbr0_used
= 1;
2365 else if (!xscale
->dbr1_used
)
2367 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR1
], watchpoint
->address
);
2368 dbcon_value
|= enable
<< 2;
2369 xscale_set_reg_u32(dbcon
, dbcon_value
);
2370 watchpoint
->set
= 2;
2371 xscale
->dbr1_used
= 1;
2375 ERROR("BUG: no hardware comparator available");
2382 int xscale_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2384 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2385 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2387 if (target
->state
!= TARGET_HALTED
)
2389 WARNING("target not halted");
2390 return ERROR_TARGET_NOT_HALTED
;
2393 if (xscale
->dbr_available
< 1)
2395 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2398 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
2400 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2403 xscale
->dbr_available
--;
2408 int xscale_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2410 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2411 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2412 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2413 u32 dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2415 if (target
->state
!= TARGET_HALTED
)
2417 WARNING("target not halted");
2418 return ERROR_TARGET_NOT_HALTED
;
2421 if (!watchpoint
->set
)
2423 WARNING("breakpoint not set");
2427 if (watchpoint
->set
== 1)
2429 dbcon_value
&= ~0x3;
2430 xscale_set_reg_u32(dbcon
, dbcon_value
);
2431 xscale
->dbr0_used
= 0;
2433 else if (watchpoint
->set
== 2)
2435 dbcon_value
&= ~0xc;
2436 xscale_set_reg_u32(dbcon
, dbcon_value
);
2437 xscale
->dbr1_used
= 0;
2439 watchpoint
->set
= 0;
2444 int xscale_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2446 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2447 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2449 if (target
->state
!= TARGET_HALTED
)
2451 WARNING("target not halted");
2452 return ERROR_TARGET_NOT_HALTED
;
2455 if (watchpoint
->set
)
2457 xscale_unset_watchpoint(target
, watchpoint
);
2460 xscale
->dbr_available
++;
2465 void xscale_enable_watchpoints(struct target_s
*target
)
2467 watchpoint_t
*watchpoint
= target
->watchpoints
;
2471 if (watchpoint
->set
== 0)
2472 xscale_set_watchpoint(target
, watchpoint
);
2473 watchpoint
= watchpoint
->next
;
2477 void xscale_enable_breakpoints(struct target_s
*target
)
2479 breakpoint_t
*breakpoint
= target
->breakpoints
;
2481 /* set any pending breakpoints */
2484 if (breakpoint
->set
== 0)
2485 xscale_set_breakpoint(target
, breakpoint
);
2486 breakpoint
= breakpoint
->next
;
2490 int xscale_get_reg(reg_t
*reg
)
2492 xscale_reg_t
*arch_info
= reg
->arch_info
;
2493 target_t
*target
= arch_info
->target
;
2494 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2495 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2497 /* DCSR, TX and RX are accessible via JTAG */
2498 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2500 return xscale_read_dcsr(arch_info
->target
);
2502 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2504 /* 1 = consume register content */
2505 return xscale_read_tx(arch_info
->target
, 1);
2507 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2509 /* can't read from RX register (host -> debug handler) */
2512 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2514 /* can't (explicitly) read from TXRXCTRL register */
2517 else /* Other DBG registers have to be transfered by the debug handler */
2519 /* send CP read request (command 0x40) */
2520 xscale_send_u32(target
, 0x40);
2522 /* send CP register number */
2523 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2525 /* read register value */
2526 xscale_read_tx(target
, 1);
2527 buf_cpy(xscale
->reg_cache
->reg_list
[XSCALE_TX
].value
, reg
->value
, 32);
2536 int xscale_set_reg(reg_t
*reg
, u8
* buf
)
2538 xscale_reg_t
*arch_info
= reg
->arch_info
;
2539 target_t
*target
= arch_info
->target
;
2540 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2541 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2542 u32 value
= buf_get_u32(buf
, 0, 32);
2544 /* DCSR, TX and RX are accessible via JTAG */
2545 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2547 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32, value
);
2548 return xscale_write_dcsr(arch_info
->target
, -1, -1);
2550 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2552 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
2553 return xscale_write_rx(arch_info
->target
);
2555 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2557 /* can't write to TX register (debug-handler -> host) */
2560 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2562 /* can't (explicitly) write to TXRXCTRL register */
2565 else /* Other DBG registers have to be transfered by the debug handler */
2567 /* send CP write request (command 0x41) */
2568 xscale_send_u32(target
, 0x41);
2570 /* send CP register number */
2571 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2573 /* send CP register value */
2574 xscale_send_u32(target
, value
);
2575 buf_set_u32(reg
->value
, 0, 32, value
);
2581 /* convenience wrapper to access XScale specific registers */
2582 int xscale_set_reg_u32(reg_t
*reg
, u32 value
)
2586 buf_set_u32(buf
, 0, 32, value
);
2588 return xscale_set_reg(reg
, buf
);
2591 int xscale_write_dcsr_sw(target_t
*target
, u32 value
)
2593 /* get pointers to arch-specific information */
2594 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2595 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2596 reg_t
*dcsr
= &xscale
->reg_cache
->reg_list
[XSCALE_DCSR
];
2597 xscale_reg_t
*dcsr_arch_info
= dcsr
->arch_info
;
2599 /* send CP write request (command 0x41) */
2600 xscale_send_u32(target
, 0x41);
2602 /* send CP register number */
2603 xscale_send_u32(target
, dcsr_arch_info
->dbg_handler_number
);
2605 /* send CP register value */
2606 xscale_send_u32(target
, value
);
2607 buf_set_u32(dcsr
->value
, 0, 32, value
);
2612 int xscale_read_trace(target_t
*target
)
2614 /* get pointers to arch-specific information */
2615 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2616 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2617 xscale_trace_data_t
**trace_data_p
;
2619 /* 258 words from debug handler
2620 * 256 trace buffer entries
2621 * 2 checkpoint addresses
2623 u32 trace_buffer
[258];
2624 int is_address
[256];
2627 if (target
->state
!= TARGET_HALTED
)
2629 WARNING("target must be stopped to read trace data");
2630 return ERROR_TARGET_NOT_HALTED
;
2633 /* send read trace buffer command (command 0x61) */
2634 xscale_send_u32(target
, 0x61);
2636 /* receive trace buffer content */
2637 xscale_receive(target
, trace_buffer
, 258);
2639 /* parse buffer backwards to identify address entries */
2640 for (i
= 255; i
>= 0; i
--)
2643 if (((trace_buffer
[i
] & 0xf0) == 0x90) ||
2644 ((trace_buffer
[i
] & 0xf0) == 0xd0))
2647 is_address
[--i
] = 1;
2649 is_address
[--i
] = 1;
2651 is_address
[--i
] = 1;
2653 is_address
[--i
] = 1;
2658 /* search first non-zero entry */
2659 for (j
= 0; (j
< 256) && (trace_buffer
[j
] == 0) && (!is_address
[j
]); j
++)
2664 DEBUG("no trace data collected");
2665 return ERROR_XSCALE_NO_TRACE_DATA
;
2668 for (trace_data_p
= &xscale
->trace
.data
; *trace_data_p
; trace_data_p
= &(*trace_data_p
)->next
)
2671 *trace_data_p
= malloc(sizeof(xscale_trace_data_t
));
2672 (*trace_data_p
)->next
= NULL
;
2673 (*trace_data_p
)->chkpt0
= trace_buffer
[256];
2674 (*trace_data_p
)->chkpt1
= trace_buffer
[257];
2675 (*trace_data_p
)->last_instruction
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
2676 (*trace_data_p
)->entries
= malloc(sizeof(xscale_trace_entry_t
) * (256 - j
));
2677 (*trace_data_p
)->depth
= 256 - j
;
2679 for (i
= j
; i
< 256; i
++)
2681 (*trace_data_p
)->entries
[i
- j
].data
= trace_buffer
[i
];
2683 (*trace_data_p
)->entries
[i
- j
].type
= XSCALE_TRACE_ADDRESS
;
2685 (*trace_data_p
)->entries
[i
- j
].type
= XSCALE_TRACE_MESSAGE
;
2691 int xscale_read_instruction(target_t
*target
, arm_instruction_t
*instruction
)
2693 /* get pointers to arch-specific information */
2694 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2695 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2702 if (!xscale
->trace
.image
)
2703 return ERROR_TRACE_IMAGE_UNAVAILABLE
;
2705 /* search for the section the current instruction belongs to */
2706 for (i
= 0; i
< xscale
->trace
.image
->num_sections
; i
++)
2708 if ((xscale
->trace
.image
->sections
[i
].base_address
<= xscale
->trace
.current_pc
) &&
2709 (xscale
->trace
.image
->sections
[i
].base_address
+ xscale
->trace
.image
->sections
[i
].size
> xscale
->trace
.current_pc
))
2718 /* current instruction couldn't be found in the image */
2719 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2722 if (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
)
2725 if ((retval
= image_read_section(xscale
->trace
.image
, section
,
2726 xscale
->trace
.current_pc
- xscale
->trace
.image
->sections
[section
].base_address
,
2727 4, buf
, &size_read
)) != ERROR_OK
)
2729 ERROR("error while reading instruction: %i", retval
);
2730 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2732 opcode
= target_buffer_get_u32(target
, buf
);
2733 arm_evaluate_opcode(opcode
, xscale
->trace
.current_pc
, instruction
);
2735 else if (xscale
->trace
.core_state
== ARMV4_5_STATE_THUMB
)
2738 if ((retval
= image_read_section(xscale
->trace
.image
, section
,
2739 xscale
->trace
.current_pc
- xscale
->trace
.image
->sections
[section
].base_address
,
2740 2, buf
, &size_read
)) != ERROR_OK
)
2742 ERROR("error while reading instruction: %i", retval
);
2743 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2745 opcode
= target_buffer_get_u16(target
, buf
);
2746 thumb_evaluate_opcode(opcode
, xscale
->trace
.current_pc
, instruction
);
2750 ERROR("BUG: unknown core state encountered");
2757 int xscale_branch_address(xscale_trace_data_t
*trace_data
, int i
, u32
*target
)
2759 /* if there are less than four entries prior to the indirect branch message
2760 * we can't extract the address */
2766 *target
= (trace_data
->entries
[i
-1].data
) | (trace_data
->entries
[i
-2].data
<< 8) |
2767 (trace_data
->entries
[i
-3].data
<< 16) | (trace_data
->entries
[i
-4].data
<< 24);
2772 int xscale_analyze_trace(target_t
*target
, command_context_t
*cmd_ctx
)
2774 /* get pointers to arch-specific information */
2775 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2776 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2779 xscale_trace_data_t
*trace_data
= xscale
->trace
.data
;
2788 xscale
->trace
.core_state
= ARMV4_5_STATE_ARM
;
2793 for (i
= 0; i
< trace_data
->depth
; i
++)
2799 if (trace_data
->entries
[i
].type
== XSCALE_TRACE_ADDRESS
)
2802 switch ((trace_data
->entries
[i
].data
& 0xf0) >> 4)
2804 case 0: /* Exceptions */
2812 exception
= (trace_data
->entries
[i
].data
& 0x70) >> 4;
2814 next_pc
= (trace_data
->entries
[i
].data
& 0xf0) >> 2;
2815 command_print(cmd_ctx
, "--- exception %i ---", (trace_data
->entries
[i
].data
& 0xf0) >> 4);
2817 case 8: /* Direct Branch */
2820 case 9: /* Indirect Branch */
2822 if (xscale_branch_address(trace_data
, i
, &next_pc
) == 0)
2827 case 13: /* Checkpointed Indirect Branch */
2828 if (xscale_branch_address(trace_data
, i
, &next_pc
) == 0)
2831 if (((chkpt
== 0) && (next_pc
!= trace_data
->chkpt0
))
2832 || ((chkpt
== 1) && (next_pc
!= trace_data
->chkpt1
)))
2833 WARNING("checkpointed indirect branch target address doesn't match checkpoint");
2835 /* explicit fall-through */
2836 case 12: /* Checkpointed Direct Branch */
2841 next_pc
= trace_data
->chkpt0
;
2844 else if (chkpt
== 1)
2847 next_pc
= trace_data
->chkpt0
;
2852 WARNING("more than two checkpointed branches encountered");
2855 case 15: /* Roll-over */
2858 default: /* Reserved */
2859 command_print(cmd_ctx
, "--- reserved trace message ---");
2860 ERROR("BUG: trace message %i is reserved", (trace_data
->entries
[i
].data
& 0xf0) >> 4);
2864 if (xscale
->trace
.pc_ok
)
2866 int executed
= (trace_data
->entries
[i
].data
& 0xf) + rollover
* 16;
2867 arm_instruction_t instruction
;
2869 if ((exception
== 6) || (exception
== 7))
2871 /* IRQ or FIQ exception, no instruction executed */
2875 while (executed
-- >= 0)
2877 if ((retval
= xscale_read_instruction(target
, &instruction
)) != ERROR_OK
)
2879 /* can't continue tracing with no image available */
2880 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
2884 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
2886 /* TODO: handle incomplete images */
2890 /* a precise abort on a load to the PC is included in the incremental
2891 * word count, other instructions causing data aborts are not included
2893 if ((executed
== 0) && (exception
== 4)
2894 && ((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_LDM
)))
2896 if ((instruction
.type
== ARM_LDM
)
2897 && ((instruction
.info
.load_store_multiple
.register_list
& 0x8000) == 0))
2901 else if (((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_LDRSH
))
2902 && (instruction
.info
.load_store
.Rd
!= 15))
2908 /* only the last instruction executed
2909 * (the one that caused the control flow change)
2910 * could be a taken branch
2912 if (((executed
== -1) && (branch
== 1)) &&
2913 (((instruction
.type
== ARM_B
) ||
2914 (instruction
.type
== ARM_BL
) ||
2915 (instruction
.type
== ARM_BLX
)) &&
2916 (instruction
.info
.b_bl_bx_blx
.target_address
!= -1)))
2918 xscale
->trace
.current_pc
= instruction
.info
.b_bl_bx_blx
.target_address
;
2922 xscale
->trace
.current_pc
+= (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2;
2924 command_print(cmd_ctx
, "%s", instruction
.text
);
2932 xscale
->trace
.current_pc
= next_pc
;
2933 xscale
->trace
.pc_ok
= 1;
2937 for (; xscale
->trace
.current_pc
< trace_data
->last_instruction
; xscale
->trace
.current_pc
+= (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2)
2939 arm_instruction_t instruction
;
2940 if ((retval
= xscale_read_instruction(target
, &instruction
)) != ERROR_OK
)
2942 /* can't continue tracing with no image available */
2943 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
2947 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
2949 /* TODO: handle incomplete images */
2952 command_print(cmd_ctx
, "%s", instruction
.text
);
2955 trace_data
= trace_data
->next
;
2961 void xscale_build_reg_cache(target_t
*target
)
2963 /* get pointers to arch-specific information */
2964 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2965 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2967 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
2968 xscale_reg_t
*arch_info
= malloc(sizeof(xscale_reg_arch_info
));
2970 int num_regs
= sizeof(xscale_reg_arch_info
) / sizeof(xscale_reg_t
);
2972 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
2973 armv4_5
->core_cache
= (*cache_p
);
2975 /* register a register arch-type for XScale dbg registers only once */
2976 if (xscale_reg_arch_type
== -1)
2977 xscale_reg_arch_type
= register_reg_arch_type(xscale_get_reg
, xscale_set_reg
);
2979 (*cache_p
)->next
= malloc(sizeof(reg_cache_t
));
2980 cache_p
= &(*cache_p
)->next
;
2982 /* fill in values for the xscale reg cache */
2983 (*cache_p
)->name
= "XScale registers";
2984 (*cache_p
)->next
= NULL
;
2985 (*cache_p
)->reg_list
= malloc(num_regs
* sizeof(reg_t
));
2986 (*cache_p
)->num_regs
= num_regs
;
2988 for (i
= 0; i
< num_regs
; i
++)
2990 (*cache_p
)->reg_list
[i
].name
= xscale_reg_list
[i
];
2991 (*cache_p
)->reg_list
[i
].value
= calloc(4, 1);
2992 (*cache_p
)->reg_list
[i
].dirty
= 0;
2993 (*cache_p
)->reg_list
[i
].valid
= 0;
2994 (*cache_p
)->reg_list
[i
].size
= 32;
2995 (*cache_p
)->reg_list
[i
].bitfield_desc
= NULL
;
2996 (*cache_p
)->reg_list
[i
].num_bitfields
= 0;
2997 (*cache_p
)->reg_list
[i
].arch_info
= &arch_info
[i
];
2998 (*cache_p
)->reg_list
[i
].arch_type
= xscale_reg_arch_type
;
2999 arch_info
[i
] = xscale_reg_arch_info
[i
];
3000 arch_info
[i
].target
= target
;
3003 xscale
->reg_cache
= (*cache_p
);
3006 int xscale_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
3008 if (startup_mode
!= DAEMON_RESET
)
3010 ERROR("XScale target requires a reset");
3011 ERROR("Reset target to enable debug");
3014 /* assert TRST once during startup */
3015 jtag_add_reset(1, 0);
3016 jtag_add_sleep(5000);
3017 jtag_add_reset(0, 0);
3018 jtag_execute_queue();
3029 int xscale_init_arch_info(target_t
*target
, xscale_common_t
*xscale
, int chain_pos
, char *variant
)
3031 armv4_5_common_t
*armv4_5
;
3032 u32 high_reset_branch
, low_reset_branch
;
3035 armv4_5
= &xscale
->armv4_5_common
;
3037 /* store architecture specfic data (none so far) */
3038 xscale
->arch_info
= NULL
;
3039 xscale
->common_magic
= XSCALE_COMMON_MAGIC
;
3041 /* remember the variant (PXA25x, PXA27x, IXP42x, ...) */
3042 xscale
->variant
= strdup(variant
);
3044 /* prepare JTAG information for the new target */
3045 xscale
->jtag_info
.chain_pos
= chain_pos
;
3046 jtag_register_event_callback(xscale_jtag_callback
, target
);
3048 xscale
->jtag_info
.dbgrx
= 0x02;
3049 xscale
->jtag_info
.dbgtx
= 0x10;
3050 xscale
->jtag_info
.dcsr
= 0x09;
3051 xscale
->jtag_info
.ldic
= 0x07;
3053 if ((strcmp(xscale
->variant
, "pxa250") == 0) ||
3054 (strcmp(xscale
->variant
, "pxa255") == 0) ||
3055 (strcmp(xscale
->variant
, "pxa26x") == 0))
3057 xscale
->jtag_info
.ir_length
= 5;
3059 else if ((strcmp(xscale
->variant
, "pxa27x") == 0) ||
3060 (strcmp(xscale
->variant
, "ixp42x") == 0) ||
3061 (strcmp(xscale
->variant
, "ixp45x") == 0) ||
3062 (strcmp(xscale
->variant
, "ixp46x") == 0))
3064 xscale
->jtag_info
.ir_length
= 7;
3067 /* the debug handler isn't installed (and thus not running) at this time */
3068 xscale
->handler_installed
= 0;
3069 xscale
->handler_running
= 0;
3070 xscale
->handler_address
= 0xfe000800;
3072 /* clear the vectors we keep locally for reference */
3073 memset(xscale
->low_vectors
, 0, sizeof(xscale
->low_vectors
));
3074 memset(xscale
->high_vectors
, 0, sizeof(xscale
->high_vectors
));
3076 /* no user-specified vectors have been configured yet */
3077 xscale
->static_low_vectors_set
= 0x0;
3078 xscale
->static_high_vectors_set
= 0x0;
3080 /* calculate branches to debug handler */
3081 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
3082 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
3084 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
3085 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
3087 for (i
= 1; i
<= 7; i
++)
3089 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
3090 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
3093 /* 64kB aligned region used for DCache cleaning */
3094 xscale
->cache_clean_address
= 0xfffe0000;
3096 xscale
->hold_rst
= 0;
3097 xscale
->external_debug_break
= 0;
3099 xscale
->force_hw_bkpts
= 1;
3101 xscale
->ibcr_available
= 2;
3102 xscale
->ibcr0_used
= 0;
3103 xscale
->ibcr1_used
= 0;
3105 xscale
->dbr_available
= 2;
3106 xscale
->dbr0_used
= 0;
3107 xscale
->dbr1_used
= 0;
3109 xscale
->arm_bkpt
= ARMV5_BKPT(0x0);
3110 xscale
->thumb_bkpt
= ARMV5_T_BKPT(0x0) & 0xffff;
3112 xscale
->vector_catch
= 0x1;
3114 xscale
->trace
.capture_status
= TRACE_IDLE
;
3115 xscale
->trace
.data
= NULL
;
3116 xscale
->trace
.image
= NULL
;
3117 xscale
->trace
.buffer_enabled
= 0;
3118 xscale
->trace
.buffer_fill
= 0;
3120 /* prepare ARMv4/5 specific information */
3121 armv4_5
->arch_info
= xscale
;
3122 armv4_5
->read_core_reg
= xscale_read_core_reg
;
3123 armv4_5
->write_core_reg
= xscale_write_core_reg
;
3124 armv4_5
->full_context
= xscale_full_context
;
3126 armv4_5_init_arch_info(target
, armv4_5
);
3128 xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
3129 xscale
->armv4_5_mmu
.get_ttb
= xscale_get_ttb
;
3130 xscale
->armv4_5_mmu
.read_memory
= xscale_read_memory
;
3131 xscale
->armv4_5_mmu
.write_memory
= xscale_write_memory
;
3132 xscale
->armv4_5_mmu
.disable_mmu_caches
= xscale_disable_mmu_caches
;
3133 xscale
->armv4_5_mmu
.enable_mmu_caches
= xscale_enable_mmu_caches
;
3134 xscale
->armv4_5_mmu
.has_tiny_pages
= 1;
3135 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3137 xscale
->fast_memory_access
= 0;
3142 /* target xscale <endianess> <startup_mode> <chain_pos> <variant> */
3143 int xscale_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
)
3146 char *variant
= NULL
;
3147 xscale_common_t
*xscale
= malloc(sizeof(xscale_common_t
));
3148 memset(xscale
, 0, sizeof(*xscale
));
3152 ERROR("'target xscale' requires four arguments: <endianess> <startup_mode> <chain_pos> <variant>");
3156 chain_pos
= strtoul(args
[3], NULL
, 0);
3160 xscale_init_arch_info(target
, xscale
, chain_pos
, variant
);
3161 xscale_build_reg_cache(target
);
3166 int xscale_handle_debug_handler_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3168 target_t
*target
= NULL
;
3169 armv4_5_common_t
*armv4_5
;
3170 xscale_common_t
*xscale
;
3172 u32 handler_address
;
3176 ERROR("'xscale debug_handler <target#> <address>' command takes two required operands");
3180 if ((target
= get_target_by_num(strtoul(args
[0], NULL
, 0))) == NULL
)
3182 ERROR("no target '%s' configured", args
[0]);
3186 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3191 handler_address
= strtoul(args
[1], NULL
, 0);
3193 if (((handler_address
>= 0x800) && (handler_address
<= 0x1fef800)) ||
3194 ((handler_address
>= 0xfe000800) && (handler_address
<= 0xfffff800)))
3196 xscale
->handler_address
= handler_address
;
3200 ERROR("xscale debug_handler <address> must be between 0x800 and 0x1fef800 or between 0xfe000800 and 0xfffff800");
3206 int xscale_handle_cache_clean_address_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3208 target_t
*target
= NULL
;
3209 armv4_5_common_t
*armv4_5
;
3210 xscale_common_t
*xscale
;
3212 u32 cache_clean_address
;
3216 ERROR("'xscale cache_clean_address <target#> <address>' command takes two required operands");
3220 if ((target
= get_target_by_num(strtoul(args
[0], NULL
, 0))) == NULL
)
3222 ERROR("no target '%s' configured", args
[0]);
3226 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3231 cache_clean_address
= strtoul(args
[1], NULL
, 0);
3233 if (cache_clean_address
& 0xffff)
3235 ERROR("xscale cache_clean_address <address> must be 64kb aligned");
3239 xscale
->cache_clean_address
= cache_clean_address
;
3245 int xscale_handle_cache_info_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3247 target_t
*target
= get_current_target(cmd_ctx
);
3248 armv4_5_common_t
*armv4_5
;
3249 xscale_common_t
*xscale
;
3251 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3256 return armv4_5_handle_cache_info_command(cmd_ctx
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
3259 static int xscale_virt2phys(struct target_s
*target
, u32
virtual, u32
*physical
)
3261 armv4_5_common_t
*armv4_5
;
3262 xscale_common_t
*xscale
;
3270 if ((retval
= xscale_get_arch_pointers(target
, &armv4_5
, &xscale
)) != ERROR_OK
)
3274 u32 ret
= armv4_5_mmu_translate_va(target
, &xscale
->armv4_5_mmu
, virtual, &type
, &cb
, &domain
, &ap
);
3283 static int xscale_mmu(struct target_s
*target
, int *enabled
)
3285 armv4_5_common_t
*armv4_5
= target
->arch_info
;
3286 xscale_common_t
*xscale
= armv4_5
->arch_info
;
3288 if (target
->state
!= TARGET_HALTED
)
3290 ERROR("Target not halted");
3291 return ERROR_TARGET_INVALID
;
3293 *enabled
= xscale
->armv4_5_mmu
.mmu_enabled
;
3298 int xscale_handle_mmu_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3300 target_t
*target
= get_current_target(cmd_ctx
);
3301 armv4_5_common_t
*armv4_5
;
3302 xscale_common_t
*xscale
;
3304 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3309 if (target
->state
!= TARGET_HALTED
)
3311 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3317 if (strcmp("enable", args
[0]) == 0)
3319 xscale_enable_mmu_caches(target
, 1, 0, 0);
3320 xscale
->armv4_5_mmu
.mmu_enabled
= 1;
3322 else if (strcmp("disable", args
[0]) == 0)
3324 xscale_disable_mmu_caches(target
, 1, 0, 0);
3325 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3329 command_print(cmd_ctx
, "mmu %s", (xscale
->armv4_5_mmu
.mmu_enabled
) ? "enabled" : "disabled");
3334 int xscale_handle_idcache_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3336 target_t
*target
= get_current_target(cmd_ctx
);
3337 armv4_5_common_t
*armv4_5
;
3338 xscale_common_t
*xscale
;
3339 int icache
= 0, dcache
= 0;
3341 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3346 if (target
->state
!= TARGET_HALTED
)
3348 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3352 if (strcmp(cmd
, "icache") == 0)
3354 else if (strcmp(cmd
, "dcache") == 0)
3359 if (strcmp("enable", args
[0]) == 0)
3361 xscale_enable_mmu_caches(target
, 0, dcache
, icache
);
3364 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 1;
3366 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 1;
3368 else if (strcmp("disable", args
[0]) == 0)
3370 xscale_disable_mmu_caches(target
, 0, dcache
, icache
);
3373 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 0;
3375 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 0;
3380 command_print(cmd_ctx
, "icache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
) ? "enabled" : "disabled");
3383 command_print(cmd_ctx
, "dcache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
) ? "enabled" : "disabled");
3388 int xscale_handle_vector_catch_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3390 target_t
*target
= get_current_target(cmd_ctx
);
3391 armv4_5_common_t
*armv4_5
;
3392 xscale_common_t
*xscale
;
3394 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3401 command_print(cmd_ctx
, "usage: xscale vector_catch [mask]");
3405 xscale
->vector_catch
= strtoul(args
[0], NULL
, 0);
3406 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 8, xscale
->vector_catch
);
3407 xscale_write_dcsr(target
, -1, -1);
3410 command_print(cmd_ctx
, "vector catch mask: 0x%2.2x", xscale
->vector_catch
);
3415 int xscale_handle_force_hw_bkpts_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3417 target_t
*target
= get_current_target(cmd_ctx
);
3418 armv4_5_common_t
*armv4_5
;
3419 xscale_common_t
*xscale
;
3421 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3426 if ((argc
>= 1) && (strcmp("enable", args
[0]) == 0))
3428 xscale
->force_hw_bkpts
= 1;
3430 else if ((argc
>= 1) && (strcmp("disable", args
[0]) == 0))
3432 xscale
->force_hw_bkpts
= 0;
3436 command_print(cmd_ctx
, "usage: xscale force_hw_bkpts <enable|disable>");
3439 command_print(cmd_ctx
, "force hardware breakpoints %s", (xscale
->force_hw_bkpts
) ? "enabled" : "disabled");
3444 int xscale_handle_trace_buffer_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3446 target_t
*target
= get_current_target(cmd_ctx
);
3447 armv4_5_common_t
*armv4_5
;
3448 xscale_common_t
*xscale
;
3451 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3456 if (target
->state
!= TARGET_HALTED
)
3458 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3462 if ((argc
>= 1) && (strcmp("enable", args
[0]) == 0))
3464 xscale_trace_data_t
*td
, *next_td
;
3465 xscale
->trace
.buffer_enabled
= 1;
3467 /* free old trace data */
3468 td
= xscale
->trace
.data
;
3478 xscale
->trace
.data
= NULL
;
3480 else if ((argc
>= 1) && (strcmp("disable", args
[0]) == 0))
3482 xscale
->trace
.buffer_enabled
= 0;
3485 if ((argc
>= 2) && (strcmp("fill", args
[1]) == 0))
3488 xscale
->trace
.buffer_fill
= strtoul(args
[2], NULL
, 0);
3490 xscale
->trace
.buffer_fill
= 1;
3492 else if ((argc
>= 2) && (strcmp("wrap", args
[1]) == 0))
3494 xscale
->trace
.buffer_fill
= -1;
3497 if (xscale
->trace
.buffer_enabled
)
3499 /* if we enable the trace buffer in fill-once
3500 * mode we know the address of the first instruction */
3501 xscale
->trace
.pc_ok
= 1;
3502 xscale
->trace
.current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
3506 /* otherwise the address is unknown, and we have no known good PC */
3507 xscale
->trace
.pc_ok
= 0;
3510 command_print(cmd_ctx
, "trace buffer %s (%s)",
3511 (xscale
->trace
.buffer_enabled
) ? "enabled" : "disabled",
3512 (xscale
->trace
.buffer_fill
> 0) ? "fill" : "wrap");
3514 dcsr_value
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32);
3515 if (xscale
->trace
.buffer_fill
>= 0)
3516 xscale_write_dcsr_sw(target
, (dcsr_value
& 0xfffffffc) | 2);
3518 xscale_write_dcsr_sw(target
, dcsr_value
& 0xfffffffc);
3523 int xscale_handle_trace_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3526 armv4_5_common_t
*armv4_5
;
3527 xscale_common_t
*xscale
;
3531 command_print(cmd_ctx
, "usage: xscale trace_image <file> [base address] [type]");
3535 target
= get_current_target(cmd_ctx
);
3537 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3542 if (xscale
->trace
.image
)
3544 image_close(xscale
->trace
.image
);
3545 free(xscale
->trace
.image
);
3546 command_print(cmd_ctx
, "previously loaded image found and closed");
3549 xscale
->trace
.image
= malloc(sizeof(image_t
));
3550 xscale
->trace
.image
->base_address_set
= 0;
3551 xscale
->trace
.image
->start_address_set
= 0;
3553 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
3556 xscale
->trace
.image
->base_address_set
= 1;
3557 xscale
->trace
.image
->base_address
= strtoul(args
[1], NULL
, 0);
3561 xscale
->trace
.image
->base_address_set
= 0;
3564 if (image_open(xscale
->trace
.image
, args
[0], (argc
>= 3) ? args
[2] : NULL
) != ERROR_OK
)
3566 free(xscale
->trace
.image
);
3567 xscale
->trace
.image
= NULL
;
3574 int xscale_handle_dump_trace_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3576 target_t
*target
= get_current_target(cmd_ctx
);
3577 armv4_5_common_t
*armv4_5
;
3578 xscale_common_t
*xscale
;
3579 xscale_trace_data_t
*trace_data
;
3582 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3587 if (target
->state
!= TARGET_HALTED
)
3589 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3595 command_print(cmd_ctx
, "usage: xscale dump_trace <file>");
3599 trace_data
= xscale
->trace
.data
;
3603 command_print(cmd_ctx
, "no trace data collected");
3607 if (fileio_open(&file
, args
[0], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
)
3616 fileio_write_u32(&file
, trace_data
->chkpt0
);
3617 fileio_write_u32(&file
, trace_data
->chkpt1
);
3618 fileio_write_u32(&file
, trace_data
->last_instruction
);
3619 fileio_write_u32(&file
, trace_data
->depth
);
3621 for (i
= 0; i
< trace_data
->depth
; i
++)
3622 fileio_write_u32(&file
, trace_data
->entries
[i
].data
| ((trace_data
->entries
[i
].type
& 0xffff) << 16));
3624 trace_data
= trace_data
->next
;
3627 fileio_close(&file
);
3632 int xscale_handle_analyze_trace_buffer_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3634 target_t
*target
= get_current_target(cmd_ctx
);
3635 armv4_5_common_t
*armv4_5
;
3636 xscale_common_t
*xscale
;
3638 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3643 xscale_analyze_trace(target
, cmd_ctx
);
3648 int xscale_handle_cp15(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3650 target_t
*target
= get_current_target(cmd_ctx
);
3651 armv4_5_common_t
*armv4_5
;
3652 xscale_common_t
*xscale
;
3654 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3659 if (target
->state
!= TARGET_HALTED
)
3661 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3668 reg_no
= strtoul(args
[0], NULL
, 0);
3669 /*translate from xscale cp15 register no to openocd register*/
3673 reg_no
= XSCALE_MAINID
;
3676 reg_no
= XSCALE_CTRL
;
3679 reg_no
= XSCALE_TTB
;
3682 reg_no
= XSCALE_DAC
;
3685 reg_no
= XSCALE_FSR
;
3688 reg_no
= XSCALE_FAR
;
3691 reg_no
= XSCALE_PID
;
3694 reg_no
= XSCALE_CPACCESS
;
3697 command_print(cmd_ctx
, "invalid register number");
3698 return ERROR_INVALID_ARGUMENTS
;
3700 reg
= &xscale
->reg_cache
->reg_list
[reg_no
];
3707 /* read cp15 control register */
3708 xscale_get_reg(reg
);
3709 value
= buf_get_u32(reg
->value
, 0, 32);
3710 command_print(cmd_ctx
, "%s (/%i): 0x%x", reg
->name
, reg
->size
, value
);
3715 u32 value
= strtoul(args
[1], NULL
, 0);
3717 /* send CP write request (command 0x41) */
3718 xscale_send_u32(target
, 0x41);
3720 /* send CP register number */
3721 xscale_send_u32(target
, reg_no
);
3723 /* send CP register value */
3724 xscale_send_u32(target
, value
);
3726 /* execute cpwait to ensure outstanding operations complete */
3727 xscale_send_u32(target
, 0x53);
3731 command_print(cmd_ctx
, "usage: cp15 [register]<, [value]>");
3737 int handle_xscale_fast_memory_access_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3739 target_t
*target
= get_current_target(cmd_ctx
);
3740 armv4_5_common_t
*armv4_5
;
3741 xscale_common_t
*xscale
;
3743 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3750 if (strcmp("enable", args
[0]) == 0)
3752 xscale
->fast_memory_access
= 1;
3754 else if (strcmp("disable", args
[0]) == 0)
3756 xscale
->fast_memory_access
= 0;
3760 return ERROR_COMMAND_SYNTAX_ERROR
;
3764 return ERROR_COMMAND_SYNTAX_ERROR
;
3767 command_print(cmd_ctx
, "fast memory access is %s", (xscale
->fast_memory_access
) ? "enabled" : "disabled");
3772 int xscale_register_commands(struct command_context_s
*cmd_ctx
)
3774 command_t
*xscale_cmd
;
3776 xscale_cmd
= register_command(cmd_ctx
, NULL
, "xscale", NULL
, COMMAND_ANY
, "xscale specific commands");
3778 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");
3779 register_command(cmd_ctx
, xscale_cmd
, "cache_clean_address", xscale_handle_cache_clean_address_command
, COMMAND_ANY
, NULL
);
3781 register_command(cmd_ctx
, xscale_cmd
, "cache_info", xscale_handle_cache_info_command
, COMMAND_EXEC
, NULL
);
3782 register_command(cmd_ctx
, xscale_cmd
, "mmu", xscale_handle_mmu_command
, COMMAND_EXEC
, "['enable'|'disable'] the MMU");
3783 register_command(cmd_ctx
, xscale_cmd
, "icache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the ICache");
3784 register_command(cmd_ctx
, xscale_cmd
, "dcache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the DCache");
3786 register_command(cmd_ctx
, xscale_cmd
, "vector_catch", xscale_handle_idcache_command
, COMMAND_EXEC
, "<mask> of vectors that should be catched");
3788 register_command(cmd_ctx
, xscale_cmd
, "trace_buffer", xscale_handle_trace_buffer_command
, COMMAND_EXEC
, "<enable|disable> ['fill' [n]|'wrap']");
3790 register_command(cmd_ctx
, xscale_cmd
, "dump_trace", xscale_handle_dump_trace_command
, COMMAND_EXEC
, "dump content of trace buffer to <file>");
3791 register_command(cmd_ctx
, xscale_cmd
, "analyze_trace", xscale_handle_analyze_trace_buffer_command
, COMMAND_EXEC
, "analyze content of trace buffer");
3792 register_command(cmd_ctx
, xscale_cmd
, "trace_image", xscale_handle_trace_image_command
,
3793 COMMAND_EXEC
, "load image from <file> [base address]");
3795 register_command(cmd_ctx
, xscale_cmd
, "cp15", xscale_handle_cp15
, COMMAND_EXEC
, "access coproc 15 <register> [value]");
3796 register_command(cmd_ctx
, xscale_cmd
, "fast_memory_access", handle_xscale_fast_memory_access_command
,
3797 COMMAND_ANY
, "use fast memory accesses instead of slower but potentially unsafe slow accesses <enable|disable>");
3800 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)