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
;
296 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
297 fields
[2].num_bits
= 1;
298 fields
[2].out_value
= &field2
;
299 fields
[2].out_mask
= NULL
;
300 fields
[2].in_value
= NULL
;
301 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
303 jtag_add_dr_scan(3, fields
, -1);
305 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
307 ERROR("JTAG error while reading DCSR");
311 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].dirty
= 0;
312 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].valid
= 1;
314 /* write the register with the value we just read
315 * on this second pass, only the first bit of field0 is guaranteed to be 0)
317 field0_check_mask
= 0x1;
318 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
319 fields
[1].in_value
= NULL
;
321 jtag_add_end_state(TAP_RTI
);
323 jtag_add_dr_scan(3, fields
, -1);
328 int xscale_receive(target_t
*target
, u32
*buffer
, int num_words
)
331 armv4_5_common_t
*armv4_5
= target
->arch_info
;
332 xscale_common_t
*xscale
= armv4_5
->arch_info
;
334 enum tap_state path
[3];
335 scan_field_t fields
[3];
337 u8
*field0
= malloc(num_words
* 1);
338 u8 field0_check_value
= 0x2;
339 u8 field0_check_mask
= 0x6;
340 u32
*field1
= malloc(num_words
* 4);
341 u8 field2_check_value
= 0x0;
342 u8 field2_check_mask
= 0x1;
344 int words_scheduled
= 0;
352 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
353 fields
[0].num_bits
= 3;
354 fields
[0].out_value
= NULL
;
355 fields
[0].out_mask
= NULL
;
356 /* fields[0].in_value = field0; */
357 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
359 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
360 fields
[1].num_bits
= 32;
361 fields
[1].out_value
= NULL
;
362 fields
[1].out_mask
= NULL
;
363 fields
[1].in_value
= NULL
;
364 fields
[1].in_handler
= NULL
;
365 fields
[1].in_handler_priv
= NULL
;
366 fields
[1].in_check_value
= NULL
;
367 fields
[1].in_check_mask
= NULL
;
371 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
372 fields
[2].num_bits
= 1;
373 fields
[2].out_value
= NULL
;
374 fields
[2].out_mask
= NULL
;
375 fields
[2].in_value
= NULL
;
376 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
378 jtag_add_end_state(TAP_RTI
);
379 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dbgtx
);
380 jtag_add_runtest(1, -1);
382 /* repeat until all words have been collected */
384 while (words_done
< num_words
)
388 for (i
= words_done
; i
< num_words
; i
++)
390 fields
[0].in_value
= &field0
[i
];
391 fields
[1].in_handler
= buf_to_u32_handler
;
392 fields
[1].in_handler_priv
= (u8
*)&field1
[i
];
394 jtag_add_pathmove(3, path
);
395 jtag_add_dr_scan(3, fields
, TAP_RTI
);
399 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
401 ERROR("JTAG error while receiving data from debug handler");
405 /* examine results */
406 for (i
= words_done
; i
< num_words
; i
++)
408 if (!(field0
[0] & 1))
410 /* move backwards if necessary */
412 for (j
= i
; j
< num_words
- 1; j
++)
414 field0
[j
] = field0
[j
+1];
415 field1
[j
] = field1
[j
+1];
420 if (words_scheduled
==0)
422 if (attempts
++==1000)
424 ERROR("Failed to receiving data from debug handler after 1000 attempts");
425 retval
=ERROR_JTAG_QUEUE_FAILED
;
430 words_done
+= words_scheduled
;
433 for (i
= 0; i
< num_words
; i
++)
434 *(buffer
++) = buf_get_u32((u8
*)&field1
[i
], 0, 32);
441 int xscale_read_tx(target_t
*target
, int consume
)
443 armv4_5_common_t
*armv4_5
= target
->arch_info
;
444 xscale_common_t
*xscale
= armv4_5
->arch_info
;
445 enum tap_state path
[3];
446 enum tap_state noconsume_path
[9];
449 struct timeval timeout
, now
;
451 scan_field_t fields
[3];
453 u8 field0_check_value
= 0x2;
454 u8 field0_check_mask
= 0x6;
455 u8 field2_check_value
= 0x0;
456 u8 field2_check_mask
= 0x1;
458 jtag_add_end_state(TAP_RTI
);
460 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dbgtx
);
466 noconsume_path
[0] = TAP_SDS
;
467 noconsume_path
[1] = TAP_CD
;
468 noconsume_path
[2] = TAP_E1D
;
469 noconsume_path
[3] = TAP_PD
;
470 noconsume_path
[4] = TAP_E2D
;
471 noconsume_path
[5] = TAP_UD
;
472 noconsume_path
[6] = TAP_SDS
;
473 noconsume_path
[7] = TAP_CD
;
474 noconsume_path
[8] = TAP_SD
;
476 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
477 fields
[0].num_bits
= 3;
478 fields
[0].out_value
= NULL
;
479 fields
[0].out_mask
= NULL
;
480 fields
[0].in_value
= &field0_in
;
481 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
483 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
484 fields
[1].num_bits
= 32;
485 fields
[1].out_value
= NULL
;
486 fields
[1].out_mask
= NULL
;
487 fields
[1].in_value
= xscale
->reg_cache
->reg_list
[XSCALE_TX
].value
;
488 fields
[1].in_handler
= NULL
;
489 fields
[1].in_handler_priv
= NULL
;
490 fields
[1].in_check_value
= NULL
;
491 fields
[1].in_check_mask
= NULL
;
495 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
496 fields
[2].num_bits
= 1;
497 fields
[2].out_value
= NULL
;
498 fields
[2].out_mask
= NULL
;
499 fields
[2].in_value
= NULL
;
500 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
502 gettimeofday(&timeout
, NULL
);
503 timeval_add_time(&timeout
, 5, 0);
507 /* if we want to consume the register content (i.e. clear TX_READY),
508 * we have to go straight from Capture-DR to Shift-DR
509 * otherwise, we go from Capture-DR to Exit1-DR to Pause-DR
512 jtag_add_pathmove(3, path
);
514 jtag_add_pathmove(sizeof(noconsume_path
)/sizeof(*noconsume_path
), noconsume_path
);
516 jtag_add_dr_scan(3, fields
, TAP_RTI
);
518 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
520 ERROR("JTAG error while reading TX");
521 return ERROR_TARGET_TIMEOUT
;
524 gettimeofday(&now
, NULL
);
525 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
)&& (now
.tv_usec
> timeout
.tv_usec
)))
527 ERROR("time out reading TX register");
528 return ERROR_TARGET_TIMEOUT
;
530 } while ((!(field0_in
& 1)) && consume
);
532 if (!(field0_in
& 1))
533 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
538 int xscale_write_rx(target_t
*target
)
540 armv4_5_common_t
*armv4_5
= target
->arch_info
;
541 xscale_common_t
*xscale
= armv4_5
->arch_info
;
544 struct timeval timeout
, now
;
546 scan_field_t fields
[3];
549 u8 field0_check_value
= 0x2;
550 u8 field0_check_mask
= 0x6;
552 u8 field2_check_value
= 0x0;
553 u8 field2_check_mask
= 0x1;
555 jtag_add_end_state(TAP_RTI
);
557 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dbgrx
);
559 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
560 fields
[0].num_bits
= 3;
561 fields
[0].out_value
= &field0_out
;
562 fields
[0].out_mask
= NULL
;
563 fields
[0].in_value
= &field0_in
;
564 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
566 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
567 fields
[1].num_bits
= 32;
568 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
;
569 fields
[1].out_mask
= NULL
;
570 fields
[1].in_value
= NULL
;
571 fields
[1].in_handler
= NULL
;
572 fields
[1].in_handler_priv
= NULL
;
573 fields
[1].in_check_value
= NULL
;
574 fields
[1].in_check_mask
= NULL
;
578 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
579 fields
[2].num_bits
= 1;
580 fields
[2].out_value
= &field2
;
581 fields
[2].out_mask
= NULL
;
582 fields
[2].in_value
= NULL
;
583 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
585 gettimeofday(&timeout
, NULL
);
586 timeval_add_time(&timeout
, 5, 0);
588 /* poll until rx_read is low */
592 jtag_add_dr_scan(3, fields
, TAP_RTI
);
594 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
596 ERROR("JTAG error while writing RX");
600 gettimeofday(&now
, NULL
);
601 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
)&& (now
.tv_usec
> timeout
.tv_usec
)))
603 ERROR("time out writing RX register");
604 return ERROR_TARGET_TIMEOUT
;
606 } while (field0_in
& 1);
610 jtag_add_dr_scan(3, fields
, TAP_RTI
);
612 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
614 ERROR("JTAG error while writing RX");
621 /* send count elements of size byte to the debug handler */
622 int xscale_send(target_t
*target
, u8
*buffer
, int count
, int size
)
624 armv4_5_common_t
*armv4_5
= target
->arch_info
;
625 xscale_common_t
*xscale
= armv4_5
->arch_info
;
630 u8 output
[4] = {0, 0, 0, 0};
632 scan_field_t fields
[3];
634 u8 field0_check_value
= 0x2;
635 u8 field0_check_mask
= 0x6;
637 u8 field2_check_value
= 0x0;
638 u8 field2_check_mask
= 0x1;
640 jtag_add_end_state(TAP_RTI
);
642 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dbgrx
);
644 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
645 fields
[0].num_bits
= 3;
646 fields
[0].out_value
= &field0_out
;
647 fields
[0].out_mask
= NULL
;
648 fields
[0].in_handler
= NULL
;
649 if (!xscale
->fast_memory_access
)
651 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
654 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
655 fields
[1].num_bits
= 32;
656 fields
[1].out_value
= output
;
657 fields
[1].out_mask
= NULL
;
658 fields
[1].in_value
= NULL
;
659 fields
[1].in_handler
= NULL
;
660 fields
[1].in_handler_priv
= NULL
;
661 fields
[1].in_check_value
= NULL
;
662 fields
[1].in_check_mask
= NULL
;
666 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
667 fields
[2].num_bits
= 1;
668 fields
[2].out_value
= &field2
;
669 fields
[2].out_mask
= NULL
;
670 fields
[2].in_value
= NULL
;
671 fields
[2].in_handler
= NULL
;
672 if (!xscale
->fast_memory_access
)
674 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
679 int endianness
= target
->endianness
;
680 while (done_count
++ < count
)
682 if (endianness
== TARGET_LITTLE_ENDIAN
)
695 jtag_add_dr_scan(3, fields
, TAP_RTI
);
701 while (done_count
++ < count
)
703 /* extract sized element from target-endian buffer, and put it
704 * into little-endian output buffer
709 buf_set_u32(output
, 0, 32, target_buffer_get_u16(target
, buffer
));
715 ERROR("BUG: size neither 4, 2 nor 1");
719 jtag_add_dr_scan(3, fields
, TAP_RTI
);
725 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
727 ERROR("JTAG error while sending data to debug handler");
734 int xscale_send_u32(target_t
*target
, u32 value
)
736 armv4_5_common_t
*armv4_5
= target
->arch_info
;
737 xscale_common_t
*xscale
= armv4_5
->arch_info
;
739 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
740 return xscale_write_rx(target
);
743 int xscale_write_dcsr(target_t
*target
, int hold_rst
, int ext_dbg_brk
)
745 armv4_5_common_t
*armv4_5
= target
->arch_info
;
746 xscale_common_t
*xscale
= armv4_5
->arch_info
;
750 scan_field_t fields
[3];
752 u8 field0_check_value
= 0x2;
753 u8 field0_check_mask
= 0x7;
755 u8 field2_check_value
= 0x0;
756 u8 field2_check_mask
= 0x1;
759 xscale
->hold_rst
= hold_rst
;
761 if (ext_dbg_brk
!= -1)
762 xscale
->external_debug_break
= ext_dbg_brk
;
764 jtag_add_end_state(TAP_RTI
);
765 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dcsr
);
767 buf_set_u32(&field0
, 1, 1, xscale
->hold_rst
);
768 buf_set_u32(&field0
, 2, 1, xscale
->external_debug_break
);
770 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
771 fields
[0].num_bits
= 3;
772 fields
[0].out_value
= &field0
;
773 fields
[0].out_mask
= NULL
;
774 fields
[0].in_value
= NULL
;
775 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
777 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
778 fields
[1].num_bits
= 32;
779 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
780 fields
[1].out_mask
= NULL
;
781 fields
[1].in_value
= NULL
;
782 fields
[1].in_handler
= NULL
;
783 fields
[1].in_handler_priv
= NULL
;
784 fields
[1].in_check_value
= NULL
;
785 fields
[1].in_check_mask
= NULL
;
789 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
790 fields
[2].num_bits
= 1;
791 fields
[2].out_value
= &field2
;
792 fields
[2].out_mask
= NULL
;
793 fields
[2].in_value
= NULL
;
794 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
796 jtag_add_dr_scan(3, fields
, -1);
798 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
800 ERROR("JTAG error while writing DCSR");
804 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].dirty
= 0;
805 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].valid
= 1;
810 /* parity of the number of bits 0 if even; 1 if odd. for 32 bit words */
811 unsigned int parity (unsigned int v
)
818 DEBUG("parity of 0x%x is %i", ov
, (0x6996 >> v
) & 1);
819 return (0x6996 >> v
) & 1;
822 int xscale_load_ic(target_t
*target
, int mini
, u32 va
, u32 buffer
[8])
824 armv4_5_common_t
*armv4_5
= target
->arch_info
;
825 xscale_common_t
*xscale
= armv4_5
->arch_info
;
830 scan_field_t fields
[2];
832 DEBUG("loading miniIC at 0x%8.8x", va
);
834 jtag_add_end_state(TAP_RTI
);
835 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.ldic
); /* LDIC */
837 /* CMD is b010 for Main IC and b011 for Mini IC */
839 buf_set_u32(&cmd
, 0, 3, 0x3);
841 buf_set_u32(&cmd
, 0, 3, 0x2);
843 buf_set_u32(&cmd
, 3, 3, 0x0);
845 /* virtual address of desired cache line */
846 buf_set_u32(packet
, 0, 27, va
>> 5);
848 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
849 fields
[0].num_bits
= 6;
850 fields
[0].out_value
= &cmd
;
851 fields
[0].out_mask
= NULL
;
852 fields
[0].in_value
= NULL
;
853 fields
[0].in_check_value
= NULL
;
854 fields
[0].in_check_mask
= NULL
;
855 fields
[0].in_handler
= NULL
;
856 fields
[0].in_handler_priv
= NULL
;
858 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
859 fields
[1].num_bits
= 27;
860 fields
[1].out_value
= packet
;
861 fields
[1].out_mask
= NULL
;
862 fields
[1].in_value
= NULL
;
863 fields
[1].in_check_value
= NULL
;
864 fields
[1].in_check_mask
= NULL
;
865 fields
[1].in_handler
= NULL
;
866 fields
[1].in_handler_priv
= NULL
;
868 jtag_add_dr_scan(2, fields
, -1);
870 fields
[0].num_bits
= 32;
871 fields
[0].out_value
= packet
;
873 fields
[1].num_bits
= 1;
874 fields
[1].out_value
= &cmd
;
876 for (word
= 0; word
< 8; word
++)
878 buf_set_u32(packet
, 0, 32, buffer
[word
]);
879 cmd
= parity(*((u32
*)packet
));
880 jtag_add_dr_scan(2, fields
, -1);
883 jtag_execute_queue();
888 int xscale_invalidate_ic_line(target_t
*target
, u32 va
)
890 armv4_5_common_t
*armv4_5
= target
->arch_info
;
891 xscale_common_t
*xscale
= armv4_5
->arch_info
;
895 scan_field_t fields
[2];
897 jtag_add_end_state(TAP_RTI
);
898 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.ldic
); /* LDIC */
900 /* CMD for invalidate IC line b000, bits [6:4] b000 */
901 buf_set_u32(&cmd
, 0, 6, 0x0);
903 /* virtual address of desired cache line */
904 buf_set_u32(packet
, 0, 27, va
>> 5);
906 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
907 fields
[0].num_bits
= 6;
908 fields
[0].out_value
= &cmd
;
909 fields
[0].out_mask
= NULL
;
910 fields
[0].in_value
= NULL
;
911 fields
[0].in_check_value
= NULL
;
912 fields
[0].in_check_mask
= NULL
;
913 fields
[0].in_handler
= NULL
;
914 fields
[0].in_handler_priv
= NULL
;
916 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
917 fields
[1].num_bits
= 27;
918 fields
[1].out_value
= packet
;
919 fields
[1].out_mask
= NULL
;
920 fields
[1].in_value
= NULL
;
921 fields
[1].in_check_value
= NULL
;
922 fields
[1].in_check_mask
= NULL
;
923 fields
[1].in_handler
= NULL
;
924 fields
[1].in_handler_priv
= NULL
;
926 jtag_add_dr_scan(2, fields
, -1);
931 int xscale_update_vectors(target_t
*target
)
933 armv4_5_common_t
*armv4_5
= target
->arch_info
;
934 xscale_common_t
*xscale
= armv4_5
->arch_info
;
937 u32 low_reset_branch
, high_reset_branch
;
939 for (i
= 1; i
< 8; i
++)
941 /* if there's a static vector specified for this exception, override */
942 if (xscale
->static_high_vectors_set
& (1 << i
))
944 xscale
->high_vectors
[i
] = xscale
->static_high_vectors
[i
];
948 if (target_read_u32(target
, 0xffff0000 + 4*i
, &xscale
->high_vectors
[i
]) != ERROR_OK
)
950 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
955 for (i
= 1; i
< 8; i
++)
957 if (xscale
->static_low_vectors_set
& (1 << i
))
959 xscale
->low_vectors
[i
] = xscale
->static_low_vectors
[i
];
963 if (target_read_u32(target
, 0x0 + 4*i
, &xscale
->low_vectors
[i
]) != ERROR_OK
)
965 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
970 /* calculate branches to debug handler */
971 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
972 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
974 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
975 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
977 /* invalidate and load exception vectors in mini i-cache */
978 xscale_invalidate_ic_line(target
, 0x0);
979 xscale_invalidate_ic_line(target
, 0xffff0000);
981 xscale_load_ic(target
, 1, 0x0, xscale
->low_vectors
);
982 xscale_load_ic(target
, 1, 0xffff0000, xscale
->high_vectors
);
987 int xscale_arch_state(struct target_s
*target
)
989 armv4_5_common_t
*armv4_5
= target
->arch_info
;
990 xscale_common_t
*xscale
= armv4_5
->arch_info
;
994 "disabled", "enabled"
997 char *arch_dbg_reason
[] =
999 "", "\n(processor reset)", "\n(trace buffer full)"
1002 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
1004 ERROR("BUG: called for a non-ARMv4/5 target");
1008 USER("target halted in %s state due to %s, current mode: %s\n"
1009 "cpsr: 0x%8.8x pc: 0x%8.8x\n"
1010 "MMU: %s, D-Cache: %s, I-Cache: %s"
1012 armv4_5_state_strings
[armv4_5
->core_state
],
1013 target_debug_reason_strings
[target
->debug_reason
],
1014 armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)],
1015 buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32),
1016 buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32),
1017 state
[xscale
->armv4_5_mmu
.mmu_enabled
],
1018 state
[xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
],
1019 state
[xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
],
1020 arch_dbg_reason
[xscale
->arch_debug_reason
]);
1025 int xscale_poll(target_t
*target
)
1027 int retval
=ERROR_OK
;
1028 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1029 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1031 if ((target
->state
== TARGET_RUNNING
) || (target
->state
== TARGET_DEBUG_RUNNING
))
1033 enum target_state previous_state
= target
->state
;
1034 if ((retval
= xscale_read_tx(target
, 0)) == ERROR_OK
)
1037 /* there's data to read from the tx register, we entered debug state */
1038 xscale
->handler_running
= 1;
1040 target
->state
= TARGET_HALTED
;
1042 /* process debug entry, fetching current mode regs */
1043 retval
= xscale_debug_entry(target
);
1045 else if (retval
!= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
1047 USER("error while polling TX register, reset CPU");
1048 /* here we "lie" so GDB won't get stuck and a reset can be perfomed */
1049 target
->state
= TARGET_HALTED
;
1052 /* debug_entry could have overwritten target state (i.e. immediate resume)
1053 * don't signal event handlers in that case
1055 if (target
->state
!= TARGET_HALTED
)
1058 /* if target was running, signal that we halted
1059 * otherwise we reentered from debug execution */
1060 if (previous_state
== TARGET_RUNNING
)
1061 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1063 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
1069 int xscale_debug_entry(target_t
*target
)
1071 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1072 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1079 /* clear external dbg break (will be written on next DCSR read) */
1080 xscale
->external_debug_break
= 0;
1081 xscale_read_dcsr(target
);
1083 /* get r0, pc, r1 to r7 and cpsr */
1084 xscale_receive(target
, buffer
, 10);
1086 /* move r0 from buffer to register cache */
1087 buf_set_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32, buffer
[0]);
1088 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
1089 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
1090 DEBUG("r0: 0x%8.8x", buffer
[0]);
1092 /* move pc from buffer to register cache */
1093 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, buffer
[1]);
1094 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
1095 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
1096 DEBUG("pc: 0x%8.8x", buffer
[1]);
1098 /* move data from buffer to register cache */
1099 for (i
= 1; i
<= 7; i
++)
1101 buf_set_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32, buffer
[1 + i
]);
1102 armv4_5
->core_cache
->reg_list
[i
].dirty
= 1;
1103 armv4_5
->core_cache
->reg_list
[i
].valid
= 1;
1104 DEBUG("r%i: 0x%8.8x", i
, buffer
[i
+ 1]);
1107 buf_set_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32, buffer
[9]);
1108 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].dirty
= 1;
1109 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].valid
= 1;
1110 DEBUG("cpsr: 0x%8.8x", buffer
[9]);
1112 armv4_5
->core_mode
= buffer
[9] & 0x1f;
1113 if (armv4_5_mode_to_number(armv4_5
->core_mode
) == -1)
1115 target
->state
= TARGET_UNKNOWN
;
1116 ERROR("cpsr contains invalid mode value - communication failure");
1117 return ERROR_TARGET_FAILURE
;
1119 DEBUG("target entered debug state in %s mode", armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)]);
1121 if (buffer
[9] & 0x20)
1122 armv4_5
->core_state
= ARMV4_5_STATE_THUMB
;
1124 armv4_5
->core_state
= ARMV4_5_STATE_ARM
;
1126 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1127 if ((armv4_5
->core_mode
!= ARMV4_5_MODE_USR
) && (armv4_5
->core_mode
!= ARMV4_5_MODE_SYS
))
1129 xscale_receive(target
, buffer
, 8);
1130 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1131 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
1132 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
1136 /* r8 to r14, but no spsr */
1137 xscale_receive(target
, buffer
, 7);
1140 /* move data from buffer to register cache */
1141 for (i
= 8; i
<= 14; i
++)
1143 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).value
, 0, 32, buffer
[i
- 8]);
1144 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).dirty
= 0;
1145 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).valid
= 1;
1148 /* examine debug reason */
1149 xscale_read_dcsr(target
);
1150 moe
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 2, 3);
1152 /* stored PC (for calculating fixup) */
1153 pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1157 case 0x0: /* Processor reset */
1158 target
->debug_reason
= DBG_REASON_DBGRQ
;
1159 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_RESET
;
1162 case 0x1: /* Instruction breakpoint hit */
1163 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1164 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1167 case 0x2: /* Data breakpoint hit */
1168 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
1169 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1172 case 0x3: /* BKPT instruction executed */
1173 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1174 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1177 case 0x4: /* Ext. debug event */
1178 target
->debug_reason
= DBG_REASON_DBGRQ
;
1179 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1182 case 0x5: /* Vector trap occured */
1183 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1184 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1187 case 0x6: /* Trace buffer full break */
1188 target
->debug_reason
= DBG_REASON_DBGRQ
;
1189 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_TB_FULL
;
1192 case 0x7: /* Reserved */
1194 ERROR("Method of Entry is 'Reserved'");
1199 /* apply PC fixup */
1200 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, pc
);
1202 /* on the first debug entry, identify cache type */
1203 if (xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
1207 /* read cp15 cache type register */
1208 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
]);
1209 cache_type_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
].value
, 0, 32);
1211 armv4_5_identify_cache(cache_type_reg
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
1214 /* examine MMU and Cache settings */
1215 /* read cp15 control register */
1216 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
1217 xscale
->cp15_control_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
1218 xscale
->armv4_5_mmu
.mmu_enabled
= (xscale
->cp15_control_reg
& 0x1U
) ? 1 : 0;
1219 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= (xscale
->cp15_control_reg
& 0x4U
) ? 1 : 0;
1220 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= (xscale
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
1222 /* tracing enabled, read collected trace data */
1223 if (xscale
->trace
.buffer_enabled
)
1225 xscale_read_trace(target
);
1226 xscale
->trace
.buffer_fill
--;
1228 /* resume if we're still collecting trace data */
1229 if ((xscale
->arch_debug_reason
== XSCALE_DBG_REASON_TB_FULL
)
1230 && (xscale
->trace
.buffer_fill
> 0))
1232 xscale_resume(target
, 1, 0x0, 1, 0);
1236 xscale
->trace
.buffer_enabled
= 0;
1243 int xscale_halt(target_t
*target
)
1245 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1246 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1248 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
1250 if (target
->state
== TARGET_HALTED
)
1252 WARNING("target was already halted");
1253 return ERROR_TARGET_ALREADY_HALTED
;
1255 else if (target
->state
== TARGET_UNKNOWN
)
1257 /* this must not happen for a xscale target */
1258 ERROR("target was in unknown state when halt was requested");
1259 return ERROR_TARGET_INVALID
;
1261 else if (target
->state
== TARGET_RESET
)
1263 DEBUG("target->state == TARGET_RESET");
1267 /* assert external dbg break */
1268 xscale
->external_debug_break
= 1;
1269 xscale_read_dcsr(target
);
1271 target
->debug_reason
= DBG_REASON_DBGRQ
;
1277 int xscale_enable_single_step(struct target_s
*target
, u32 next_pc
)
1279 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1280 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1281 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1283 if (xscale
->ibcr0_used
)
1285 breakpoint_t
*ibcr0_bp
= breakpoint_find(target
, buf_get_u32(ibcr0
->value
, 0, 32) & 0xfffffffe);
1289 xscale_unset_breakpoint(target
, ibcr0_bp
);
1293 ERROR("BUG: xscale->ibcr0_used is set, but no breakpoint with that address found");
1298 xscale_set_reg_u32(ibcr0
, next_pc
| 0x1);
1303 int xscale_disable_single_step(struct target_s
*target
)
1305 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1306 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1307 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1309 xscale_set_reg_u32(ibcr0
, 0x0);
1314 int xscale_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
1316 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1317 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1318 breakpoint_t
*breakpoint
= target
->breakpoints
;
1327 if (target
->state
!= TARGET_HALTED
)
1329 WARNING("target not halted");
1330 return ERROR_TARGET_NOT_HALTED
;
1333 if (!debug_execution
)
1335 target_free_all_working_areas(target
);
1338 /* update vector tables */
1339 xscale_update_vectors(target
);
1341 /* current = 1: continue on current pc, otherwise continue at <address> */
1343 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1345 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1347 /* if we're at the reset vector, we have to simulate the branch */
1348 if (current_pc
== 0x0)
1350 arm_simulate_step(target
, NULL
);
1351 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1354 /* the front-end may request us not to handle breakpoints */
1355 if (handle_breakpoints
)
1357 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1361 /* there's a breakpoint at the current PC, we have to step over it */
1362 DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
1363 xscale_unset_breakpoint(target
, breakpoint
);
1365 /* calculate PC of next instruction */
1366 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1369 target_read_u32(target
, current_pc
, ¤t_opcode
);
1370 ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode
);
1373 DEBUG("enable single-step");
1374 xscale_enable_single_step(target
, next_pc
);
1376 /* restore banked registers */
1377 xscale_restore_context(target
);
1379 /* send resume request (command 0x30 or 0x31)
1380 * clean the trace buffer if it is to be enabled (0x62) */
1381 if (xscale
->trace
.buffer_enabled
)
1383 xscale_send_u32(target
, 0x62);
1384 xscale_send_u32(target
, 0x31);
1387 xscale_send_u32(target
, 0x30);
1390 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1391 DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1393 for (i
= 7; i
>= 0; i
--)
1396 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1397 DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1401 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1402 DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1404 /* wait for and process debug entry */
1405 xscale_debug_entry(target
);
1407 DEBUG("disable single-step");
1408 xscale_disable_single_step(target
);
1410 DEBUG("set breakpoint at 0x%8.8x", breakpoint
->address
);
1411 xscale_set_breakpoint(target
, breakpoint
);
1415 /* enable any pending breakpoints and watchpoints */
1416 xscale_enable_breakpoints(target
);
1417 xscale_enable_watchpoints(target
);
1419 /* restore banked registers */
1420 xscale_restore_context(target
);
1422 /* send resume request (command 0x30 or 0x31)
1423 * clean the trace buffer if it is to be enabled (0x62) */
1424 if (xscale
->trace
.buffer_enabled
)
1426 xscale_send_u32(target
, 0x62);
1427 xscale_send_u32(target
, 0x31);
1430 xscale_send_u32(target
, 0x30);
1433 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1434 DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1436 for (i
= 7; i
>= 0; i
--)
1439 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1440 DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1444 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1445 DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1447 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1449 if (!debug_execution
)
1451 /* registers are now invalid */
1452 armv4_5_invalidate_core_regs(target
);
1453 target
->state
= TARGET_RUNNING
;
1454 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1458 target
->state
= TARGET_DEBUG_RUNNING
;
1459 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1462 DEBUG("target resumed");
1464 xscale
->handler_running
= 1;
1469 int xscale_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
1471 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1472 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1473 breakpoint_t
*breakpoint
= target
->breakpoints
;
1475 u32 current_pc
, next_pc
;
1479 if (target
->state
!= TARGET_HALTED
)
1481 WARNING("target not halted");
1482 return ERROR_TARGET_NOT_HALTED
;
1485 /* current = 1: continue on current pc, otherwise continue at <address> */
1487 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1489 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1491 /* if we're at the reset vector, we have to simulate the step */
1492 if (current_pc
== 0x0)
1494 arm_simulate_step(target
, NULL
);
1495 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1497 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1498 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1503 /* the front-end may request us not to handle breakpoints */
1504 if (handle_breakpoints
)
1505 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1507 xscale_unset_breakpoint(target
, breakpoint
);
1510 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1512 /* calculate PC of next instruction */
1513 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1516 target_read_u32(target
, current_pc
, ¤t_opcode
);
1517 ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode
);
1520 DEBUG("enable single-step");
1521 xscale_enable_single_step(target
, next_pc
);
1523 /* restore banked registers */
1524 xscale_restore_context(target
);
1526 /* send resume request (command 0x30 or 0x31)
1527 * clean the trace buffer if it is to be enabled (0x62) */
1528 if (xscale
->trace
.buffer_enabled
)
1530 xscale_send_u32(target
, 0x62);
1531 xscale_send_u32(target
, 0x31);
1534 xscale_send_u32(target
, 0x30);
1537 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1538 DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1540 for (i
= 7; i
>= 0; i
--)
1543 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1544 DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1548 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1549 DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1551 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1553 /* registers are now invalid */
1554 armv4_5_invalidate_core_regs(target
);
1556 /* wait for and process debug entry */
1557 xscale_debug_entry(target
);
1559 DEBUG("disable single-step");
1560 xscale_disable_single_step(target
);
1562 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1566 xscale_set_breakpoint(target
, breakpoint
);
1569 DEBUG("target stepped");
1575 int xscale_assert_reset(target_t
*target
)
1577 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1578 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1580 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
1582 /* select DCSR instruction (set endstate to R-T-I to ensure we don't
1583 * end up in T-L-R, which would reset JTAG
1585 jtag_add_end_state(TAP_RTI
);
1586 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dcsr
);
1588 /* set Hold reset, Halt mode and Trap Reset */
1589 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1590 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1591 xscale_write_dcsr(target
, 1, 0);
1593 /* select BYPASS, because having DCSR selected caused problems on the PXA27x */
1594 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, 0x7f);
1595 jtag_execute_queue();
1598 jtag_add_reset(0, 1);
1600 /* sleep 1ms, to be sure we fulfill any requirements */
1601 jtag_add_sleep(1000);
1602 jtag_execute_queue();
1604 target
->state
= TARGET_RESET
;
1609 int xscale_deassert_reset(target_t
*target
)
1611 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1612 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1614 fileio_t debug_handler
;
1622 breakpoint_t
*breakpoint
= target
->breakpoints
;
1626 xscale
->ibcr_available
= 2;
1627 xscale
->ibcr0_used
= 0;
1628 xscale
->ibcr1_used
= 0;
1630 xscale
->dbr_available
= 2;
1631 xscale
->dbr0_used
= 0;
1632 xscale
->dbr1_used
= 0;
1634 /* mark all hardware breakpoints as unset */
1637 if (breakpoint
->type
== BKPT_HARD
)
1639 breakpoint
->set
= 0;
1641 breakpoint
= breakpoint
->next
;
1644 if (!xscale
->handler_installed
)
1647 jtag_add_reset(0, 0);
1649 /* wait 300ms; 150 and 100ms were not enough */
1650 jtag_add_sleep(300*1000);
1652 jtag_add_runtest(2030, TAP_RTI
);
1653 jtag_execute_queue();
1655 /* set Hold reset, Halt mode and Trap Reset */
1656 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1657 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1658 xscale_write_dcsr(target
, 1, 0);
1660 /* Load debug handler */
1661 if (fileio_open(&debug_handler
, "xscale/debug_handler.bin", FILEIO_READ
, FILEIO_BINARY
) != ERROR_OK
)
1666 if ((binary_size
= debug_handler
.size
) % 4)
1668 ERROR("debug_handler.bin: size not a multiple of 4");
1672 if (binary_size
> 0x800)
1674 ERROR("debug_handler.bin: larger than 2kb");
1678 binary_size
= CEIL(binary_size
, 32) * 32;
1680 address
= xscale
->handler_address
;
1681 while (binary_size
> 0)
1686 if ((retval
= fileio_read(&debug_handler
, 32, buffer
, &buf_cnt
)) != ERROR_OK
)
1691 for (i
= 0; i
< buf_cnt
; i
+= 4)
1693 /* convert LE buffer to host-endian u32 */
1694 cache_line
[i
/ 4] = le_to_h_u32(&buffer
[i
]);
1697 for (; buf_cnt
< 32; buf_cnt
+= 4)
1699 cache_line
[buf_cnt
/ 4] = 0xe1a08008;
1702 /* only load addresses other than the reset vectors */
1703 if ((address
% 0x400) != 0x0)
1705 xscale_load_ic(target
, 1, address
, cache_line
);
1709 binary_size
-= buf_cnt
;
1712 xscale_load_ic(target
, 1, 0x0, xscale
->low_vectors
);
1713 xscale_load_ic(target
, 1, 0xffff0000, xscale
->high_vectors
);
1715 jtag_add_runtest(30, TAP_RTI
);
1717 jtag_add_sleep(100000);
1719 /* set Hold reset, Halt mode and Trap Reset */
1720 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1721 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1722 xscale_write_dcsr(target
, 1, 0);
1724 /* clear Hold reset to let the target run (should enter debug handler) */
1725 xscale_write_dcsr(target
, 0, 1);
1726 target
->state
= TARGET_RUNNING
;
1728 if ((target
->reset_mode
!= RESET_HALT
) && (target
->reset_mode
!= RESET_INIT
))
1730 jtag_add_sleep(10000);
1732 /* we should have entered debug now */
1733 xscale_debug_entry(target
);
1734 target
->state
= TARGET_HALTED
;
1736 /* resume the target */
1737 xscale_resume(target
, 1, 0x0, 1, 0);
1740 fileio_close(&debug_handler
);
1744 jtag_add_reset(0, 0);
1751 int xscale_soft_reset_halt(struct target_s
*target
)
1757 int xscale_prepare_reset_halt(struct target_s
*target
)
1759 /* nothing to be done for reset_halt on XScale targets
1760 * we always halt after a reset to upload the debug handler
1765 int xscale_read_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
)
1771 int xscale_write_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
, u32 value
)
1777 int xscale_full_context(target_t
*target
)
1779 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1787 if (target
->state
!= TARGET_HALTED
)
1789 WARNING("target not halted");
1790 return ERROR_TARGET_NOT_HALTED
;
1793 buffer
= malloc(4 * 8);
1795 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1796 * we can't enter User mode on an XScale (unpredictable),
1797 * but User shares registers with SYS
1799 for(i
= 1; i
< 7; i
++)
1803 /* check if there are invalid registers in the current mode
1805 for (j
= 0; j
<= 16; j
++)
1807 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
== 0)
1815 /* request banked registers */
1816 xscale_send_u32(target
, 0x0);
1819 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1820 tmp_cpsr
|= 0xc0; /* I/F bits */
1822 /* send CPSR for desired mode */
1823 xscale_send_u32(target
, tmp_cpsr
);
1825 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1826 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1828 xscale_receive(target
, buffer
, 8);
1829 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1830 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1831 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).valid
= 1;
1835 xscale_receive(target
, buffer
, 7);
1838 /* move data from buffer to register cache */
1839 for (j
= 8; j
<= 14; j
++)
1841 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]);
1842 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1843 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
= 1;
1853 int xscale_restore_context(target_t
*target
)
1855 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1861 if (target
->state
!= TARGET_HALTED
)
1863 WARNING("target not halted");
1864 return ERROR_TARGET_NOT_HALTED
;
1867 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1868 * we can't enter User mode on an XScale (unpredictable),
1869 * but User shares registers with SYS
1871 for(i
= 1; i
< 7; i
++)
1875 /* check if there are invalid registers in the current mode
1877 for (j
= 8; j
<= 14; j
++)
1879 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
== 1)
1883 /* if not USR/SYS, check if the SPSR needs to be written */
1884 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1886 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
== 1)
1894 /* send banked registers */
1895 xscale_send_u32(target
, 0x1);
1898 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1899 tmp_cpsr
|= 0xc0; /* I/F bits */
1901 /* send CPSR for desired mode */
1902 xscale_send_u32(target
, tmp_cpsr
);
1904 /* send banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1905 for (j
= 8; j
<= 14; j
++)
1907 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, j
).value
, 0, 32));
1908 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1911 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1913 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32));
1914 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1922 int xscale_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1924 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1925 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1929 DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address
, size
, count
);
1931 if (target
->state
!= TARGET_HALTED
)
1933 WARNING("target not halted");
1934 return ERROR_TARGET_NOT_HALTED
;
1937 /* sanitize arguments */
1938 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1939 return ERROR_INVALID_ARGUMENTS
;
1941 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1942 return ERROR_TARGET_UNALIGNED_ACCESS
;
1944 /* send memory read request (command 0x1n, n: access size) */
1945 xscale_send_u32(target
, 0x10 | size
);
1947 /* send base address for read request */
1948 xscale_send_u32(target
, address
);
1950 /* send number of requested data words */
1951 xscale_send_u32(target
, count
);
1953 /* receive data from target (count times 32-bit words in host endianness) */
1954 buf32
= malloc(4 * count
);
1955 xscale_receive(target
, buf32
, count
);
1957 /* extract data from host-endian buffer into byte stream */
1958 for (i
= 0; i
< count
; i
++)
1963 target_buffer_set_u32(target
, buffer
, buf32
[i
]);
1967 target_buffer_set_u16(target
, buffer
, buf32
[i
] & 0xffff);
1971 *buffer
++ = buf32
[i
] & 0xff;
1974 ERROR("should never get here");
1981 /* examine DCSR, to see if Sticky Abort (SA) got set */
1982 xscale_read_dcsr(target
);
1983 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
1986 xscale_send_u32(target
, 0x60);
1988 return ERROR_TARGET_DATA_ABORT
;
1994 int xscale_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1996 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1997 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1999 DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address
, size
, count
);
2001 if (target
->state
!= TARGET_HALTED
)
2003 WARNING("target not halted");
2004 return ERROR_TARGET_NOT_HALTED
;
2007 /* sanitize arguments */
2008 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
2009 return ERROR_INVALID_ARGUMENTS
;
2011 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
2012 return ERROR_TARGET_UNALIGNED_ACCESS
;
2014 /* send memory write request (command 0x2n, n: access size) */
2015 xscale_send_u32(target
, 0x20 | size
);
2017 /* send base address for read request */
2018 xscale_send_u32(target
, address
);
2020 /* send number of requested data words to be written*/
2021 xscale_send_u32(target
, count
);
2023 /* extract data from host-endian buffer into byte stream */
2025 for (i
= 0; i
< count
; i
++)
2030 value
= target_buffer_get_u32(target
, buffer
);
2031 xscale_send_u32(target
, value
);
2035 value
= target_buffer_get_u16(target
, buffer
);
2036 xscale_send_u32(target
, value
);
2041 xscale_send_u32(target
, value
);
2045 ERROR("should never get here");
2050 xscale_send(target
, buffer
, count
, size
);
2052 /* examine DCSR, to see if Sticky Abort (SA) got set */
2053 xscale_read_dcsr(target
);
2054 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
2057 xscale_send_u32(target
, 0x60);
2059 return ERROR_TARGET_DATA_ABORT
;
2065 int xscale_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
2067 return xscale_write_memory(target
, address
, 4, count
, buffer
);
2070 int xscale_checksum_memory(struct target_s
*target
, u32 address
, u32 count
, u32
* checksum
)
2072 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2075 u32
xscale_get_ttb(target_t
*target
)
2077 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2078 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2081 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_TTB
]);
2082 ttb
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_TTB
].value
, 0, 32);
2087 void xscale_disable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
2089 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2090 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2093 /* read cp15 control register */
2094 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2095 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2098 cp15_control
&= ~0x1U
;
2103 xscale_send_u32(target
, 0x50);
2104 xscale_send_u32(target
, xscale
->cache_clean_address
);
2106 /* invalidate DCache */
2107 xscale_send_u32(target
, 0x51);
2109 cp15_control
&= ~0x4U
;
2114 /* invalidate ICache */
2115 xscale_send_u32(target
, 0x52);
2116 cp15_control
&= ~0x1000U
;
2119 /* write new cp15 control register */
2120 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2122 /* execute cpwait to ensure outstanding operations complete */
2123 xscale_send_u32(target
, 0x53);
2126 void xscale_enable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
2128 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2129 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2132 /* read cp15 control register */
2133 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2134 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2137 cp15_control
|= 0x1U
;
2140 cp15_control
|= 0x4U
;
2143 cp15_control
|= 0x1000U
;
2145 /* write new cp15 control register */
2146 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2148 /* execute cpwait to ensure outstanding operations complete */
2149 xscale_send_u32(target
, 0x53);
2152 int xscale_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2154 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2155 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2157 if (target
->state
!= TARGET_HALTED
)
2159 WARNING("target not halted");
2160 return ERROR_TARGET_NOT_HALTED
;
2163 if (xscale
->force_hw_bkpts
)
2164 breakpoint
->type
= BKPT_HARD
;
2166 if (breakpoint
->set
)
2168 WARNING("breakpoint already set");
2172 if (breakpoint
->type
== BKPT_HARD
)
2174 u32 value
= breakpoint
->address
| 1;
2175 if (!xscale
->ibcr0_used
)
2177 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], value
);
2178 xscale
->ibcr0_used
= 1;
2179 breakpoint
->set
= 1; /* breakpoint set on first breakpoint register */
2181 else if (!xscale
->ibcr1_used
)
2183 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], value
);
2184 xscale
->ibcr1_used
= 1;
2185 breakpoint
->set
= 2; /* breakpoint set on second breakpoint register */
2189 ERROR("BUG: no hardware comparator available");
2193 else if (breakpoint
->type
== BKPT_SOFT
)
2195 if (breakpoint
->length
== 4)
2197 /* keep the original instruction in target endianness */
2198 target
->type
->read_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
);
2199 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2200 target_write_u32(target
, breakpoint
->address
, xscale
->arm_bkpt
);
2204 /* keep the original instruction in target endianness */
2205 target
->type
->read_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
);
2206 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2207 target_write_u32(target
, breakpoint
->address
, xscale
->thumb_bkpt
);
2209 breakpoint
->set
= 1;
2216 int xscale_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2218 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2219 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2221 if (target
->state
!= TARGET_HALTED
)
2223 WARNING("target not halted");
2224 return ERROR_TARGET_NOT_HALTED
;
2227 if (xscale
->force_hw_bkpts
)
2229 DEBUG("forcing use of hardware breakpoint at address 0x%8.8x", breakpoint
->address
);
2230 breakpoint
->type
= BKPT_HARD
;
2233 if ((breakpoint
->type
== BKPT_HARD
) && (xscale
->ibcr_available
< 1))
2235 INFO("no breakpoint unit available for hardware breakpoint");
2236 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2240 xscale
->ibcr_available
--;
2243 if ((breakpoint
->length
!= 2) && (breakpoint
->length
!= 4))
2245 INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
2246 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2252 int xscale_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2254 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2255 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2257 if (target
->state
!= TARGET_HALTED
)
2259 WARNING("target not halted");
2260 return ERROR_TARGET_NOT_HALTED
;
2263 if (!breakpoint
->set
)
2265 WARNING("breakpoint not set");
2269 if (breakpoint
->type
== BKPT_HARD
)
2271 if (breakpoint
->set
== 1)
2273 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], 0x0);
2274 xscale
->ibcr0_used
= 0;
2276 else if (breakpoint
->set
== 2)
2278 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], 0x0);
2279 xscale
->ibcr1_used
= 0;
2281 breakpoint
->set
= 0;
2285 /* restore original instruction (kept in target endianness) */
2286 if (breakpoint
->length
== 4)
2288 target
->type
->write_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
);
2292 target
->type
->write_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
);
2294 breakpoint
->set
= 0;
2300 int xscale_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2302 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2303 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2305 if (target
->state
!= TARGET_HALTED
)
2307 WARNING("target not halted");
2308 return ERROR_TARGET_NOT_HALTED
;
2311 if (breakpoint
->set
)
2313 xscale_unset_breakpoint(target
, breakpoint
);
2316 if (breakpoint
->type
== BKPT_HARD
)
2317 xscale
->ibcr_available
++;
2322 int xscale_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2324 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2325 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2327 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2328 u32 dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2330 if (target
->state
!= TARGET_HALTED
)
2332 WARNING("target not halted");
2333 return ERROR_TARGET_NOT_HALTED
;
2336 xscale_get_reg(dbcon
);
2338 switch (watchpoint
->rw
)
2350 ERROR("BUG: watchpoint->rw neither read, write nor access");
2353 if (!xscale
->dbr0_used
)
2355 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR0
], watchpoint
->address
);
2356 dbcon_value
|= enable
;
2357 xscale_set_reg_u32(dbcon
, dbcon_value
);
2358 watchpoint
->set
= 1;
2359 xscale
->dbr0_used
= 1;
2361 else if (!xscale
->dbr1_used
)
2363 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR1
], watchpoint
->address
);
2364 dbcon_value
|= enable
<< 2;
2365 xscale_set_reg_u32(dbcon
, dbcon_value
);
2366 watchpoint
->set
= 2;
2367 xscale
->dbr1_used
= 1;
2371 ERROR("BUG: no hardware comparator available");
2378 int xscale_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2380 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2381 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2383 if (target
->state
!= TARGET_HALTED
)
2385 WARNING("target not halted");
2386 return ERROR_TARGET_NOT_HALTED
;
2389 if (xscale
->dbr_available
< 1)
2391 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2394 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
2396 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2399 xscale
->dbr_available
--;
2404 int xscale_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2406 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2407 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2408 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2409 u32 dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2411 if (target
->state
!= TARGET_HALTED
)
2413 WARNING("target not halted");
2414 return ERROR_TARGET_NOT_HALTED
;
2417 if (!watchpoint
->set
)
2419 WARNING("breakpoint not set");
2423 if (watchpoint
->set
== 1)
2425 dbcon_value
&= ~0x3;
2426 xscale_set_reg_u32(dbcon
, dbcon_value
);
2427 xscale
->dbr0_used
= 0;
2429 else if (watchpoint
->set
== 2)
2431 dbcon_value
&= ~0xc;
2432 xscale_set_reg_u32(dbcon
, dbcon_value
);
2433 xscale
->dbr1_used
= 0;
2435 watchpoint
->set
= 0;
2440 int xscale_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2442 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2443 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2445 if (target
->state
!= TARGET_HALTED
)
2447 WARNING("target not halted");
2448 return ERROR_TARGET_NOT_HALTED
;
2451 if (watchpoint
->set
)
2453 xscale_unset_watchpoint(target
, watchpoint
);
2456 xscale
->dbr_available
++;
2461 void xscale_enable_watchpoints(struct target_s
*target
)
2463 watchpoint_t
*watchpoint
= target
->watchpoints
;
2467 if (watchpoint
->set
== 0)
2468 xscale_set_watchpoint(target
, watchpoint
);
2469 watchpoint
= watchpoint
->next
;
2473 void xscale_enable_breakpoints(struct target_s
*target
)
2475 breakpoint_t
*breakpoint
= target
->breakpoints
;
2477 /* set any pending breakpoints */
2480 if (breakpoint
->set
== 0)
2481 xscale_set_breakpoint(target
, breakpoint
);
2482 breakpoint
= breakpoint
->next
;
2486 int xscale_get_reg(reg_t
*reg
)
2488 xscale_reg_t
*arch_info
= reg
->arch_info
;
2489 target_t
*target
= arch_info
->target
;
2490 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2491 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2493 /* DCSR, TX and RX are accessible via JTAG */
2494 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2496 return xscale_read_dcsr(arch_info
->target
);
2498 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2500 /* 1 = consume register content */
2501 return xscale_read_tx(arch_info
->target
, 1);
2503 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2505 /* can't read from RX register (host -> debug handler) */
2508 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2510 /* can't (explicitly) read from TXRXCTRL register */
2513 else /* Other DBG registers have to be transfered by the debug handler */
2515 /* send CP read request (command 0x40) */
2516 xscale_send_u32(target
, 0x40);
2518 /* send CP register number */
2519 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2521 /* read register value */
2522 xscale_read_tx(target
, 1);
2523 buf_cpy(xscale
->reg_cache
->reg_list
[XSCALE_TX
].value
, reg
->value
, 32);
2532 int xscale_set_reg(reg_t
*reg
, u8
* buf
)
2534 xscale_reg_t
*arch_info
= reg
->arch_info
;
2535 target_t
*target
= arch_info
->target
;
2536 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2537 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2538 u32 value
= buf_get_u32(buf
, 0, 32);
2540 /* DCSR, TX and RX are accessible via JTAG */
2541 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2543 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32, value
);
2544 return xscale_write_dcsr(arch_info
->target
, -1, -1);
2546 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2548 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
2549 return xscale_write_rx(arch_info
->target
);
2551 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2553 /* can't write to TX register (debug-handler -> host) */
2556 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2558 /* can't (explicitly) write to TXRXCTRL register */
2561 else /* Other DBG registers have to be transfered by the debug handler */
2563 /* send CP write request (command 0x41) */
2564 xscale_send_u32(target
, 0x41);
2566 /* send CP register number */
2567 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2569 /* send CP register value */
2570 xscale_send_u32(target
, value
);
2571 buf_set_u32(reg
->value
, 0, 32, value
);
2577 /* convenience wrapper to access XScale specific registers */
2578 int xscale_set_reg_u32(reg_t
*reg
, u32 value
)
2582 buf_set_u32(buf
, 0, 32, value
);
2584 return xscale_set_reg(reg
, buf
);
2587 int xscale_write_dcsr_sw(target_t
*target
, u32 value
)
2589 /* get pointers to arch-specific information */
2590 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2591 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2592 reg_t
*dcsr
= &xscale
->reg_cache
->reg_list
[XSCALE_DCSR
];
2593 xscale_reg_t
*dcsr_arch_info
= dcsr
->arch_info
;
2595 /* send CP write request (command 0x41) */
2596 xscale_send_u32(target
, 0x41);
2598 /* send CP register number */
2599 xscale_send_u32(target
, dcsr_arch_info
->dbg_handler_number
);
2601 /* send CP register value */
2602 xscale_send_u32(target
, value
);
2603 buf_set_u32(dcsr
->value
, 0, 32, value
);
2608 int xscale_read_trace(target_t
*target
)
2610 /* get pointers to arch-specific information */
2611 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2612 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2613 xscale_trace_data_t
**trace_data_p
;
2615 /* 258 words from debug handler
2616 * 256 trace buffer entries
2617 * 2 checkpoint addresses
2619 u32 trace_buffer
[258];
2620 int is_address
[256];
2623 if (target
->state
!= TARGET_HALTED
)
2625 WARNING("target must be stopped to read trace data");
2626 return ERROR_TARGET_NOT_HALTED
;
2629 /* send read trace buffer command (command 0x61) */
2630 xscale_send_u32(target
, 0x61);
2632 /* receive trace buffer content */
2633 xscale_receive(target
, trace_buffer
, 258);
2635 /* parse buffer backwards to identify address entries */
2636 for (i
= 255; i
>= 0; i
--)
2639 if (((trace_buffer
[i
] & 0xf0) == 0x90) ||
2640 ((trace_buffer
[i
] & 0xf0) == 0xd0))
2643 is_address
[--i
] = 1;
2645 is_address
[--i
] = 1;
2647 is_address
[--i
] = 1;
2649 is_address
[--i
] = 1;
2654 /* search first non-zero entry */
2655 for (j
= 0; (j
< 256) && (trace_buffer
[j
] == 0) && (!is_address
[j
]); j
++)
2660 DEBUG("no trace data collected");
2661 return ERROR_XSCALE_NO_TRACE_DATA
;
2664 for (trace_data_p
= &xscale
->trace
.data
; *trace_data_p
; trace_data_p
= &(*trace_data_p
)->next
)
2667 *trace_data_p
= malloc(sizeof(xscale_trace_data_t
));
2668 (*trace_data_p
)->next
= NULL
;
2669 (*trace_data_p
)->chkpt0
= trace_buffer
[256];
2670 (*trace_data_p
)->chkpt1
= trace_buffer
[257];
2671 (*trace_data_p
)->last_instruction
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
2672 (*trace_data_p
)->entries
= malloc(sizeof(xscale_trace_entry_t
) * (256 - j
));
2673 (*trace_data_p
)->depth
= 256 - j
;
2675 for (i
= j
; i
< 256; i
++)
2677 (*trace_data_p
)->entries
[i
- j
].data
= trace_buffer
[i
];
2679 (*trace_data_p
)->entries
[i
- j
].type
= XSCALE_TRACE_ADDRESS
;
2681 (*trace_data_p
)->entries
[i
- j
].type
= XSCALE_TRACE_MESSAGE
;
2687 int xscale_read_instruction(target_t
*target
, arm_instruction_t
*instruction
)
2689 /* get pointers to arch-specific information */
2690 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2691 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2698 if (!xscale
->trace
.image
)
2699 return ERROR_TRACE_IMAGE_UNAVAILABLE
;
2701 /* search for the section the current instruction belongs to */
2702 for (i
= 0; i
< xscale
->trace
.image
->num_sections
; i
++)
2704 if ((xscale
->trace
.image
->sections
[i
].base_address
<= xscale
->trace
.current_pc
) &&
2705 (xscale
->trace
.image
->sections
[i
].base_address
+ xscale
->trace
.image
->sections
[i
].size
> xscale
->trace
.current_pc
))
2714 /* current instruction couldn't be found in the image */
2715 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2718 if (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
)
2721 if ((retval
= image_read_section(xscale
->trace
.image
, section
,
2722 xscale
->trace
.current_pc
- xscale
->trace
.image
->sections
[section
].base_address
,
2723 4, buf
, &size_read
)) != ERROR_OK
)
2725 ERROR("error while reading instruction: %i", retval
);
2726 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2728 opcode
= target_buffer_get_u32(target
, buf
);
2729 arm_evaluate_opcode(opcode
, xscale
->trace
.current_pc
, instruction
);
2731 else if (xscale
->trace
.core_state
== ARMV4_5_STATE_THUMB
)
2734 if ((retval
= image_read_section(xscale
->trace
.image
, section
,
2735 xscale
->trace
.current_pc
- xscale
->trace
.image
->sections
[section
].base_address
,
2736 2, buf
, &size_read
)) != ERROR_OK
)
2738 ERROR("error while reading instruction: %i", retval
);
2739 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2741 opcode
= target_buffer_get_u16(target
, buf
);
2742 thumb_evaluate_opcode(opcode
, xscale
->trace
.current_pc
, instruction
);
2746 ERROR("BUG: unknown core state encountered");
2753 int xscale_branch_address(xscale_trace_data_t
*trace_data
, int i
, u32
*target
)
2755 /* if there are less than four entries prior to the indirect branch message
2756 * we can't extract the address */
2762 *target
= (trace_data
->entries
[i
-1].data
) | (trace_data
->entries
[i
-2].data
<< 8) |
2763 (trace_data
->entries
[i
-3].data
<< 16) | (trace_data
->entries
[i
-4].data
<< 24);
2768 int xscale_analyze_trace(target_t
*target
, command_context_t
*cmd_ctx
)
2770 /* get pointers to arch-specific information */
2771 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2772 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2775 xscale_trace_data_t
*trace_data
= xscale
->trace
.data
;
2784 xscale
->trace
.core_state
= ARMV4_5_STATE_ARM
;
2789 for (i
= 0; i
< trace_data
->depth
; i
++)
2795 if (trace_data
->entries
[i
].type
== XSCALE_TRACE_ADDRESS
)
2798 switch ((trace_data
->entries
[i
].data
& 0xf0) >> 4)
2800 case 0: /* Exceptions */
2808 exception
= (trace_data
->entries
[i
].data
& 0x70) >> 4;
2810 next_pc
= (trace_data
->entries
[i
].data
& 0xf0) >> 2;
2811 command_print(cmd_ctx
, "--- exception %i ---", (trace_data
->entries
[i
].data
& 0xf0) >> 4);
2813 case 8: /* Direct Branch */
2816 case 9: /* Indirect Branch */
2818 if (xscale_branch_address(trace_data
, i
, &next_pc
) == 0)
2823 case 13: /* Checkpointed Indirect Branch */
2824 if (xscale_branch_address(trace_data
, i
, &next_pc
) == 0)
2827 if (((chkpt
== 0) && (next_pc
!= trace_data
->chkpt0
))
2828 || ((chkpt
== 1) && (next_pc
!= trace_data
->chkpt1
)))
2829 WARNING("checkpointed indirect branch target address doesn't match checkpoint");
2831 /* explicit fall-through */
2832 case 12: /* Checkpointed Direct Branch */
2837 next_pc
= trace_data
->chkpt0
;
2840 else if (chkpt
== 1)
2843 next_pc
= trace_data
->chkpt0
;
2848 WARNING("more than two checkpointed branches encountered");
2851 case 15: /* Roll-over */
2854 default: /* Reserved */
2855 command_print(cmd_ctx
, "--- reserved trace message ---");
2856 ERROR("BUG: trace message %i is reserved", (trace_data
->entries
[i
].data
& 0xf0) >> 4);
2860 if (xscale
->trace
.pc_ok
)
2862 int executed
= (trace_data
->entries
[i
].data
& 0xf) + rollover
* 16;
2863 arm_instruction_t instruction
;
2865 if ((exception
== 6) || (exception
== 7))
2867 /* IRQ or FIQ exception, no instruction executed */
2871 while (executed
-- >= 0)
2873 if ((retval
= xscale_read_instruction(target
, &instruction
)) != ERROR_OK
)
2875 /* can't continue tracing with no image available */
2876 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
2880 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
2882 /* TODO: handle incomplete images */
2886 /* a precise abort on a load to the PC is included in the incremental
2887 * word count, other instructions causing data aborts are not included
2889 if ((executed
== 0) && (exception
== 4)
2890 && ((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_LDM
)))
2892 if ((instruction
.type
== ARM_LDM
)
2893 && ((instruction
.info
.load_store_multiple
.register_list
& 0x8000) == 0))
2897 else if (((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_LDRSH
))
2898 && (instruction
.info
.load_store
.Rd
!= 15))
2904 /* only the last instruction executed
2905 * (the one that caused the control flow change)
2906 * could be a taken branch
2908 if (((executed
== -1) && (branch
== 1)) &&
2909 (((instruction
.type
== ARM_B
) ||
2910 (instruction
.type
== ARM_BL
) ||
2911 (instruction
.type
== ARM_BLX
)) &&
2912 (instruction
.info
.b_bl_bx_blx
.target_address
!= -1)))
2914 xscale
->trace
.current_pc
= instruction
.info
.b_bl_bx_blx
.target_address
;
2918 xscale
->trace
.current_pc
+= (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2;
2920 command_print(cmd_ctx
, "%s", instruction
.text
);
2928 xscale
->trace
.current_pc
= next_pc
;
2929 xscale
->trace
.pc_ok
= 1;
2933 for (; xscale
->trace
.current_pc
< trace_data
->last_instruction
; xscale
->trace
.current_pc
+= (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2)
2935 arm_instruction_t instruction
;
2936 if ((retval
= xscale_read_instruction(target
, &instruction
)) != ERROR_OK
)
2938 /* can't continue tracing with no image available */
2939 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
2943 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
2945 /* TODO: handle incomplete images */
2948 command_print(cmd_ctx
, "%s", instruction
.text
);
2951 trace_data
= trace_data
->next
;
2957 void xscale_build_reg_cache(target_t
*target
)
2959 /* get pointers to arch-specific information */
2960 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2961 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2963 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
2964 xscale_reg_t
*arch_info
= malloc(sizeof(xscale_reg_arch_info
));
2966 int num_regs
= sizeof(xscale_reg_arch_info
) / sizeof(xscale_reg_t
);
2968 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
2969 armv4_5
->core_cache
= (*cache_p
);
2971 /* register a register arch-type for XScale dbg registers only once */
2972 if (xscale_reg_arch_type
== -1)
2973 xscale_reg_arch_type
= register_reg_arch_type(xscale_get_reg
, xscale_set_reg
);
2975 (*cache_p
)->next
= malloc(sizeof(reg_cache_t
));
2976 cache_p
= &(*cache_p
)->next
;
2978 /* fill in values for the xscale reg cache */
2979 (*cache_p
)->name
= "XScale registers";
2980 (*cache_p
)->next
= NULL
;
2981 (*cache_p
)->reg_list
= malloc(num_regs
* sizeof(reg_t
));
2982 (*cache_p
)->num_regs
= num_regs
;
2984 for (i
= 0; i
< num_regs
; i
++)
2986 (*cache_p
)->reg_list
[i
].name
= xscale_reg_list
[i
];
2987 (*cache_p
)->reg_list
[i
].value
= calloc(4, 1);
2988 (*cache_p
)->reg_list
[i
].dirty
= 0;
2989 (*cache_p
)->reg_list
[i
].valid
= 0;
2990 (*cache_p
)->reg_list
[i
].size
= 32;
2991 (*cache_p
)->reg_list
[i
].bitfield_desc
= NULL
;
2992 (*cache_p
)->reg_list
[i
].num_bitfields
= 0;
2993 (*cache_p
)->reg_list
[i
].arch_info
= &arch_info
[i
];
2994 (*cache_p
)->reg_list
[i
].arch_type
= xscale_reg_arch_type
;
2995 arch_info
[i
] = xscale_reg_arch_info
[i
];
2996 arch_info
[i
].target
= target
;
2999 xscale
->reg_cache
= (*cache_p
);
3002 int xscale_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
3004 if (startup_mode
!= DAEMON_RESET
)
3006 ERROR("XScale target requires a reset");
3007 ERROR("Reset target to enable debug");
3010 /* assert TRST once during startup */
3011 jtag_add_reset(1, 0);
3012 jtag_add_sleep(5000);
3013 jtag_add_reset(0, 0);
3014 jtag_execute_queue();
3025 int xscale_init_arch_info(target_t
*target
, xscale_common_t
*xscale
, int chain_pos
, char *variant
)
3027 armv4_5_common_t
*armv4_5
;
3028 u32 high_reset_branch
, low_reset_branch
;
3031 armv4_5
= &xscale
->armv4_5_common
;
3033 /* store architecture specfic data (none so far) */
3034 xscale
->arch_info
= NULL
;
3035 xscale
->common_magic
= XSCALE_COMMON_MAGIC
;
3037 /* remember the variant (PXA25x, PXA27x, IXP42x, ...) */
3038 xscale
->variant
= strdup(variant
);
3040 /* prepare JTAG information for the new target */
3041 xscale
->jtag_info
.chain_pos
= chain_pos
;
3042 jtag_register_event_callback(xscale_jtag_callback
, target
);
3044 xscale
->jtag_info
.dbgrx
= 0x02;
3045 xscale
->jtag_info
.dbgtx
= 0x10;
3046 xscale
->jtag_info
.dcsr
= 0x09;
3047 xscale
->jtag_info
.ldic
= 0x07;
3049 if ((strcmp(xscale
->variant
, "pxa250") == 0) ||
3050 (strcmp(xscale
->variant
, "pxa255") == 0) ||
3051 (strcmp(xscale
->variant
, "pxa26x") == 0))
3053 xscale
->jtag_info
.ir_length
= 5;
3055 else if ((strcmp(xscale
->variant
, "pxa27x") == 0) ||
3056 (strcmp(xscale
->variant
, "ixp42x") == 0) ||
3057 (strcmp(xscale
->variant
, "ixp45x") == 0) ||
3058 (strcmp(xscale
->variant
, "ixp46x") == 0))
3060 xscale
->jtag_info
.ir_length
= 7;
3063 /* the debug handler isn't installed (and thus not running) at this time */
3064 xscale
->handler_installed
= 0;
3065 xscale
->handler_running
= 0;
3066 xscale
->handler_address
= 0xfe000800;
3068 /* clear the vectors we keep locally for reference */
3069 memset(xscale
->low_vectors
, 0, sizeof(xscale
->low_vectors
));
3070 memset(xscale
->high_vectors
, 0, sizeof(xscale
->high_vectors
));
3072 /* no user-specified vectors have been configured yet */
3073 xscale
->static_low_vectors_set
= 0x0;
3074 xscale
->static_high_vectors_set
= 0x0;
3076 /* calculate branches to debug handler */
3077 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
3078 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
3080 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
3081 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
3083 for (i
= 1; i
<= 7; i
++)
3085 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
3086 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
3089 /* 64kB aligned region used for DCache cleaning */
3090 xscale
->cache_clean_address
= 0xfffe0000;
3092 xscale
->hold_rst
= 0;
3093 xscale
->external_debug_break
= 0;
3095 xscale
->force_hw_bkpts
= 1;
3097 xscale
->ibcr_available
= 2;
3098 xscale
->ibcr0_used
= 0;
3099 xscale
->ibcr1_used
= 0;
3101 xscale
->dbr_available
= 2;
3102 xscale
->dbr0_used
= 0;
3103 xscale
->dbr1_used
= 0;
3105 xscale
->arm_bkpt
= ARMV5_BKPT(0x0);
3106 xscale
->thumb_bkpt
= ARMV5_T_BKPT(0x0) & 0xffff;
3108 xscale
->vector_catch
= 0x1;
3110 xscale
->trace
.capture_status
= TRACE_IDLE
;
3111 xscale
->trace
.data
= NULL
;
3112 xscale
->trace
.image
= NULL
;
3113 xscale
->trace
.buffer_enabled
= 0;
3114 xscale
->trace
.buffer_fill
= 0;
3116 /* prepare ARMv4/5 specific information */
3117 armv4_5
->arch_info
= xscale
;
3118 armv4_5
->read_core_reg
= xscale_read_core_reg
;
3119 armv4_5
->write_core_reg
= xscale_write_core_reg
;
3120 armv4_5
->full_context
= xscale_full_context
;
3122 armv4_5_init_arch_info(target
, armv4_5
);
3124 xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
3125 xscale
->armv4_5_mmu
.get_ttb
= xscale_get_ttb
;
3126 xscale
->armv4_5_mmu
.read_memory
= xscale_read_memory
;
3127 xscale
->armv4_5_mmu
.write_memory
= xscale_write_memory
;
3128 xscale
->armv4_5_mmu
.disable_mmu_caches
= xscale_disable_mmu_caches
;
3129 xscale
->armv4_5_mmu
.enable_mmu_caches
= xscale_enable_mmu_caches
;
3130 xscale
->armv4_5_mmu
.has_tiny_pages
= 1;
3131 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3133 xscale
->fast_memory_access
= 0;
3138 /* target xscale <endianess> <startup_mode> <chain_pos> <variant> */
3139 int xscale_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
)
3142 char *variant
= NULL
;
3143 xscale_common_t
*xscale
= malloc(sizeof(xscale_common_t
));
3147 ERROR("'target xscale' requires four arguments: <endianess> <startup_mode> <chain_pos> <variant>");
3151 chain_pos
= strtoul(args
[3], NULL
, 0);
3155 xscale_init_arch_info(target
, xscale
, chain_pos
, variant
);
3156 xscale_build_reg_cache(target
);
3161 int xscale_handle_debug_handler_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3163 target_t
*target
= NULL
;
3164 armv4_5_common_t
*armv4_5
;
3165 xscale_common_t
*xscale
;
3167 u32 handler_address
;
3171 ERROR("'xscale debug_handler <target#> <address>' command takes two required operands");
3175 if ((target
= get_target_by_num(strtoul(args
[0], NULL
, 0))) == NULL
)
3177 ERROR("no target '%s' configured", args
[0]);
3181 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3186 handler_address
= strtoul(args
[1], NULL
, 0);
3188 if (((handler_address
>= 0x800) && (handler_address
<= 0x1fef800)) ||
3189 ((handler_address
>= 0xfe000800) && (handler_address
<= 0xfffff800)))
3191 xscale
->handler_address
= handler_address
;
3195 ERROR("xscale debug_handler <address> must be between 0x800 and 0x1fef800 or between 0xfe000800 and 0xfffff800");
3201 int xscale_handle_cache_clean_address_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3203 target_t
*target
= NULL
;
3204 armv4_5_common_t
*armv4_5
;
3205 xscale_common_t
*xscale
;
3207 u32 cache_clean_address
;
3211 ERROR("'xscale cache_clean_address <target#> <address>' command takes two required operands");
3215 if ((target
= get_target_by_num(strtoul(args
[0], NULL
, 0))) == NULL
)
3217 ERROR("no target '%s' configured", args
[0]);
3221 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3226 cache_clean_address
= strtoul(args
[1], NULL
, 0);
3228 if (cache_clean_address
& 0xffff)
3230 ERROR("xscale cache_clean_address <address> must be 64kb aligned");
3234 xscale
->cache_clean_address
= cache_clean_address
;
3240 int xscale_handle_cache_info_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3242 target_t
*target
= get_current_target(cmd_ctx
);
3243 armv4_5_common_t
*armv4_5
;
3244 xscale_common_t
*xscale
;
3246 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3251 return armv4_5_handle_cache_info_command(cmd_ctx
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
3254 static int xscale_virt2phys(struct target_s
*target
, u32
virtual, u32
*physical
)
3256 armv4_5_common_t
*armv4_5
;
3257 xscale_common_t
*xscale
;
3265 if ((retval
= xscale_get_arch_pointers(target
, &armv4_5
, &xscale
)) != ERROR_OK
)
3269 u32 ret
= armv4_5_mmu_translate_va(target
, &xscale
->armv4_5_mmu
, virtual, &type
, &cb
, &domain
, &ap
);
3278 static int xscale_mmu(struct target_s
*target
, int *enabled
)
3280 armv4_5_common_t
*armv4_5
= target
->arch_info
;
3281 xscale_common_t
*xscale
= armv4_5
->arch_info
;
3283 if (target
->state
!= TARGET_HALTED
)
3285 ERROR("Target not halted");
3286 return ERROR_TARGET_INVALID
;
3288 *enabled
= xscale
->armv4_5_mmu
.mmu_enabled
;
3293 int xscale_handle_mmu_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3295 target_t
*target
= get_current_target(cmd_ctx
);
3296 armv4_5_common_t
*armv4_5
;
3297 xscale_common_t
*xscale
;
3299 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3304 if (target
->state
!= TARGET_HALTED
)
3306 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3312 if (strcmp("enable", args
[0]) == 0)
3314 xscale_enable_mmu_caches(target
, 1, 0, 0);
3315 xscale
->armv4_5_mmu
.mmu_enabled
= 1;
3317 else if (strcmp("disable", args
[0]) == 0)
3319 xscale_disable_mmu_caches(target
, 1, 0, 0);
3320 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3324 command_print(cmd_ctx
, "mmu %s", (xscale
->armv4_5_mmu
.mmu_enabled
) ? "enabled" : "disabled");
3329 int xscale_handle_idcache_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3331 target_t
*target
= get_current_target(cmd_ctx
);
3332 armv4_5_common_t
*armv4_5
;
3333 xscale_common_t
*xscale
;
3334 int icache
= 0, dcache
= 0;
3336 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3341 if (target
->state
!= TARGET_HALTED
)
3343 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3347 if (strcmp(cmd
, "icache") == 0)
3349 else if (strcmp(cmd
, "dcache") == 0)
3354 if (strcmp("enable", args
[0]) == 0)
3356 xscale_enable_mmu_caches(target
, 0, dcache
, icache
);
3359 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 1;
3361 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 1;
3363 else if (strcmp("disable", args
[0]) == 0)
3365 xscale_disable_mmu_caches(target
, 0, dcache
, icache
);
3368 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 0;
3370 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 0;
3375 command_print(cmd_ctx
, "icache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
) ? "enabled" : "disabled");
3378 command_print(cmd_ctx
, "dcache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
) ? "enabled" : "disabled");
3383 int xscale_handle_vector_catch_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3385 target_t
*target
= get_current_target(cmd_ctx
);
3386 armv4_5_common_t
*armv4_5
;
3387 xscale_common_t
*xscale
;
3389 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3396 command_print(cmd_ctx
, "usage: xscale vector_catch [mask]");
3400 xscale
->vector_catch
= strtoul(args
[0], NULL
, 0);
3401 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 8, xscale
->vector_catch
);
3402 xscale_write_dcsr(target
, -1, -1);
3405 command_print(cmd_ctx
, "vector catch mask: 0x%2.2x", xscale
->vector_catch
);
3410 int xscale_handle_force_hw_bkpts_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3412 target_t
*target
= get_current_target(cmd_ctx
);
3413 armv4_5_common_t
*armv4_5
;
3414 xscale_common_t
*xscale
;
3416 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3421 if ((argc
>= 1) && (strcmp("enable", args
[0]) == 0))
3423 xscale
->force_hw_bkpts
= 1;
3425 else if ((argc
>= 1) && (strcmp("disable", args
[0]) == 0))
3427 xscale
->force_hw_bkpts
= 0;
3431 command_print(cmd_ctx
, "usage: xscale force_hw_bkpts <enable|disable>");
3434 command_print(cmd_ctx
, "force hardware breakpoints %s", (xscale
->force_hw_bkpts
) ? "enabled" : "disabled");
3439 int xscale_handle_trace_buffer_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3441 target_t
*target
= get_current_target(cmd_ctx
);
3442 armv4_5_common_t
*armv4_5
;
3443 xscale_common_t
*xscale
;
3446 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3451 if (target
->state
!= TARGET_HALTED
)
3453 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3457 if ((argc
>= 1) && (strcmp("enable", args
[0]) == 0))
3459 xscale_trace_data_t
*td
, *next_td
;
3460 xscale
->trace
.buffer_enabled
= 1;
3462 /* free old trace data */
3463 td
= xscale
->trace
.data
;
3473 xscale
->trace
.data
= NULL
;
3475 else if ((argc
>= 1) && (strcmp("disable", args
[0]) == 0))
3477 xscale
->trace
.buffer_enabled
= 0;
3480 if ((argc
>= 2) && (strcmp("fill", args
[1]) == 0))
3483 xscale
->trace
.buffer_fill
= strtoul(args
[2], NULL
, 0);
3485 xscale
->trace
.buffer_fill
= 1;
3487 else if ((argc
>= 2) && (strcmp("wrap", args
[1]) == 0))
3489 xscale
->trace
.buffer_fill
= -1;
3492 if (xscale
->trace
.buffer_enabled
)
3494 /* if we enable the trace buffer in fill-once
3495 * mode we know the address of the first instruction */
3496 xscale
->trace
.pc_ok
= 1;
3497 xscale
->trace
.current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
3501 /* otherwise the address is unknown, and we have no known good PC */
3502 xscale
->trace
.pc_ok
= 0;
3505 command_print(cmd_ctx
, "trace buffer %s (%s)",
3506 (xscale
->trace
.buffer_enabled
) ? "enabled" : "disabled",
3507 (xscale
->trace
.buffer_fill
> 0) ? "fill" : "wrap");
3509 dcsr_value
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32);
3510 if (xscale
->trace
.buffer_fill
>= 0)
3511 xscale_write_dcsr_sw(target
, (dcsr_value
& 0xfffffffc) | 2);
3513 xscale_write_dcsr_sw(target
, dcsr_value
& 0xfffffffc);
3518 int xscale_handle_trace_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3521 armv4_5_common_t
*armv4_5
;
3522 xscale_common_t
*xscale
;
3526 command_print(cmd_ctx
, "usage: xscale trace_image <file> [base address] [type]");
3530 target
= get_current_target(cmd_ctx
);
3532 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3537 if (xscale
->trace
.image
)
3539 image_close(xscale
->trace
.image
);
3540 free(xscale
->trace
.image
);
3541 command_print(cmd_ctx
, "previously loaded image found and closed");
3544 xscale
->trace
.image
= malloc(sizeof(image_t
));
3545 xscale
->trace
.image
->base_address_set
= 0;
3546 xscale
->trace
.image
->start_address_set
= 0;
3548 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
3551 xscale
->trace
.image
->base_address_set
= 1;
3552 xscale
->trace
.image
->base_address
= strtoul(args
[1], NULL
, 0);
3556 xscale
->trace
.image
->base_address_set
= 0;
3559 if (image_open(xscale
->trace
.image
, args
[0], (argc
>= 3) ? args
[2] : NULL
) != ERROR_OK
)
3561 free(xscale
->trace
.image
);
3562 xscale
->trace
.image
= NULL
;
3569 int xscale_handle_dump_trace_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3571 target_t
*target
= get_current_target(cmd_ctx
);
3572 armv4_5_common_t
*armv4_5
;
3573 xscale_common_t
*xscale
;
3574 xscale_trace_data_t
*trace_data
;
3577 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3582 if (target
->state
!= TARGET_HALTED
)
3584 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3590 command_print(cmd_ctx
, "usage: xscale dump_trace <file>");
3594 trace_data
= xscale
->trace
.data
;
3598 command_print(cmd_ctx
, "no trace data collected");
3602 if (fileio_open(&file
, args
[0], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
)
3611 fileio_write_u32(&file
, trace_data
->chkpt0
);
3612 fileio_write_u32(&file
, trace_data
->chkpt1
);
3613 fileio_write_u32(&file
, trace_data
->last_instruction
);
3614 fileio_write_u32(&file
, trace_data
->depth
);
3616 for (i
= 0; i
< trace_data
->depth
; i
++)
3617 fileio_write_u32(&file
, trace_data
->entries
[i
].data
| ((trace_data
->entries
[i
].type
& 0xffff) << 16));
3619 trace_data
= trace_data
->next
;
3622 fileio_close(&file
);
3627 int xscale_handle_analyze_trace_buffer_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3629 target_t
*target
= get_current_target(cmd_ctx
);
3630 armv4_5_common_t
*armv4_5
;
3631 xscale_common_t
*xscale
;
3633 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3638 xscale_analyze_trace(target
, cmd_ctx
);
3643 int xscale_handle_cp15(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3645 target_t
*target
= get_current_target(cmd_ctx
);
3646 armv4_5_common_t
*armv4_5
;
3647 xscale_common_t
*xscale
;
3649 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3654 if (target
->state
!= TARGET_HALTED
)
3656 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3663 reg_no
= strtoul(args
[0], NULL
, 0);
3664 /*translate from xscale cp15 register no to openocd register*/
3668 reg_no
= XSCALE_MAINID
;
3671 reg_no
= XSCALE_CTRL
;
3674 reg_no
= XSCALE_TTB
;
3677 reg_no
= XSCALE_DAC
;
3680 reg_no
= XSCALE_FSR
;
3683 reg_no
= XSCALE_FAR
;
3686 reg_no
= XSCALE_PID
;
3689 reg_no
= XSCALE_CPACCESS
;
3692 command_print(cmd_ctx
, "invalid register number");
3693 return ERROR_INVALID_ARGUMENTS
;
3695 reg
= &xscale
->reg_cache
->reg_list
[reg_no
];
3702 /* read cp15 control register */
3703 xscale_get_reg(reg
);
3704 value
= buf_get_u32(reg
->value
, 0, 32);
3705 command_print(cmd_ctx
, "%s (/%i): 0x%x", reg
->name
, reg
->size
, value
);
3710 u32 value
= strtoul(args
[1], NULL
, 0);
3712 /* send CP write request (command 0x41) */
3713 xscale_send_u32(target
, 0x41);
3715 /* send CP register number */
3716 xscale_send_u32(target
, reg_no
);
3718 /* send CP register value */
3719 xscale_send_u32(target
, value
);
3721 /* execute cpwait to ensure outstanding operations complete */
3722 xscale_send_u32(target
, 0x53);
3726 command_print(cmd_ctx
, "usage: cp15 [register]<, [value]>");
3732 int handle_xscale_fast_memory_access_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3734 target_t
*target
= get_current_target(cmd_ctx
);
3735 armv4_5_common_t
*armv4_5
;
3736 xscale_common_t
*xscale
;
3738 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3745 if (strcmp("enable", args
[0]) == 0)
3747 xscale
->fast_memory_access
= 1;
3749 else if (strcmp("disable", args
[0]) == 0)
3751 xscale
->fast_memory_access
= 0;
3755 return ERROR_COMMAND_SYNTAX_ERROR
;
3759 return ERROR_COMMAND_SYNTAX_ERROR
;
3762 command_print(cmd_ctx
, "fast memory access is %s", (xscale
->fast_memory_access
) ? "enabled" : "disabled");
3767 int xscale_register_commands(struct command_context_s
*cmd_ctx
)
3769 command_t
*xscale_cmd
;
3771 xscale_cmd
= register_command(cmd_ctx
, NULL
, "xscale", NULL
, COMMAND_ANY
, "xscale specific commands");
3773 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");
3774 register_command(cmd_ctx
, xscale_cmd
, "cache_clean_address", xscale_handle_cache_clean_address_command
, COMMAND_ANY
, NULL
);
3776 register_command(cmd_ctx
, xscale_cmd
, "cache_info", xscale_handle_cache_info_command
, COMMAND_EXEC
, NULL
);
3777 register_command(cmd_ctx
, xscale_cmd
, "mmu", xscale_handle_mmu_command
, COMMAND_EXEC
, "['enable'|'disable'] the MMU");
3778 register_command(cmd_ctx
, xscale_cmd
, "icache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the ICache");
3779 register_command(cmd_ctx
, xscale_cmd
, "dcache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the DCache");
3781 register_command(cmd_ctx
, xscale_cmd
, "vector_catch", xscale_handle_idcache_command
, COMMAND_EXEC
, "<mask> of vectors that should be catched");
3783 register_command(cmd_ctx
, xscale_cmd
, "trace_buffer", xscale_handle_trace_buffer_command
, COMMAND_EXEC
, "<enable|disable> ['fill' [n]|'wrap']");
3785 register_command(cmd_ctx
, xscale_cmd
, "dump_trace", xscale_handle_dump_trace_command
, COMMAND_EXEC
, "dump content of trace buffer to <file>");
3786 register_command(cmd_ctx
, xscale_cmd
, "analyze_trace", xscale_handle_analyze_trace_buffer_command
, COMMAND_EXEC
, "analyze content of trace buffer");
3787 register_command(cmd_ctx
, xscale_cmd
, "trace_image", xscale_handle_trace_image_command
,
3788 COMMAND_EXEC
, "load image from <file> [base address]");
3790 register_command(cmd_ctx
, xscale_cmd
, "cp15", xscale_handle_cp15
, COMMAND_EXEC
, "access coproc 15 <register> [value]");
3791 register_command(cmd_ctx
, xscale_cmd
, "fast_memory_access", handle_xscale_fast_memory_access_command
,
3792 COMMAND_ANY
, "use fast memory accesses instead of slower but potentially unsafe slow accesses <enable|disable>");
3795 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)