1 /***************************************************************************
2 * Copyright (C) 2006, 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
24 #include "replacements.h"
31 #include "arm_simulator.h"
32 #include "arm_disassembler.h"
35 #include "binarybuffer.h"
36 #include "time_support.h"
37 #include "breakpoints.h"
43 #include <sys/types.h>
49 int xscale_register_commands(struct command_context_s
*cmd_ctx
);
51 /* forward declarations */
52 int xscale_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
);
53 int xscale_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
);
56 int xscale_arch_state(struct target_s
*target
, char *buf
, int buf_size
);
57 enum target_state
xscale_poll(target_t
*target
);
58 int xscale_halt(target_t
*target
);
59 int xscale_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
);
60 int xscale_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
);
61 int xscale_debug_entry(target_t
*target
);
62 int xscale_restore_context(target_t
*target
);
64 int xscale_assert_reset(target_t
*target
);
65 int xscale_deassert_reset(target_t
*target
);
66 int xscale_soft_reset_halt(struct target_s
*target
);
67 int xscale_prepare_reset_halt(struct target_s
*target
);
69 int xscale_set_reg_u32(reg_t
*reg
, u32 value
);
71 int xscale_read_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
);
72 int xscale_write_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
, u32 value
);
74 int xscale_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
);
75 int xscale_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
);
76 int xscale_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
);
77 int xscale_checksum_memory(struct target_s
*target
, u32 address
, u32 count
, u32
* checksum
);
79 int xscale_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
80 int xscale_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
81 int xscale_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
82 int xscale_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
83 int xscale_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
);
84 int xscale_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
);
85 void xscale_enable_watchpoints(struct target_s
*target
);
86 void xscale_enable_breakpoints(struct target_s
*target
);
88 int xscale_read_trace(target_t
*target
);
90 target_type_t xscale_target
=
95 .arch_state
= xscale_arch_state
,
97 .target_request_data
= NULL
,
100 .resume
= xscale_resume
,
103 .assert_reset
= xscale_assert_reset
,
104 .deassert_reset
= xscale_deassert_reset
,
105 .soft_reset_halt
= xscale_soft_reset_halt
,
106 .prepare_reset_halt
= xscale_prepare_reset_halt
,
108 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
110 .read_memory
= xscale_read_memory
,
111 .write_memory
= xscale_write_memory
,
112 .bulk_write_memory
= xscale_bulk_write_memory
,
113 .checksum_memory
= xscale_checksum_memory
,
115 .run_algorithm
= armv4_5_run_algorithm
,
117 .add_breakpoint
= xscale_add_breakpoint
,
118 .remove_breakpoint
= xscale_remove_breakpoint
,
119 .add_watchpoint
= xscale_add_watchpoint
,
120 .remove_watchpoint
= xscale_remove_watchpoint
,
122 .register_commands
= xscale_register_commands
,
123 .target_command
= xscale_target_command
,
124 .init_target
= xscale_init_target
,
128 char* xscale_reg_list
[] =
130 "XSCALE_MAINID", /* 0 */
140 "XSCALE_IBCR0", /* 10 */
150 "XSCALE_RX", /* 20 */
154 xscale_reg_t xscale_reg_arch_info
[] =
156 {XSCALE_MAINID
, NULL
},
157 {XSCALE_CACHETYPE
, NULL
},
159 {XSCALE_AUXCTRL
, NULL
},
165 {XSCALE_CPACCESS
, NULL
},
166 {XSCALE_IBCR0
, NULL
},
167 {XSCALE_IBCR1
, NULL
},
170 {XSCALE_DBCON
, NULL
},
171 {XSCALE_TBREG
, NULL
},
172 {XSCALE_CHKPT0
, NULL
},
173 {XSCALE_CHKPT1
, NULL
},
174 {XSCALE_DCSR
, NULL
}, /* DCSR accessed via JTAG or SW */
175 {-1, NULL
}, /* TX accessed via JTAG */
176 {-1, NULL
}, /* RX accessed via JTAG */
177 {-1, NULL
}, /* TXRXCTRL implicit access via JTAG */
180 int xscale_reg_arch_type
= -1;
182 int xscale_get_reg(reg_t
*reg
);
183 int xscale_set_reg(reg_t
*reg
, u8
*buf
);
185 int xscale_get_arch_pointers(target_t
*target
, armv4_5_common_t
**armv4_5_p
, xscale_common_t
**xscale_p
)
187 armv4_5_common_t
*armv4_5
= target
->arch_info
;
188 xscale_common_t
*xscale
= armv4_5
->arch_info
;
190 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
195 if (xscale
->common_magic
!= XSCALE_COMMON_MAGIC
)
200 *armv4_5_p
= armv4_5
;
206 int xscale_jtag_set_instr(int chain_pos
, u32 new_instr
)
208 jtag_device_t
*device
= jtag_get_device(chain_pos
);
210 if (buf_get_u32(device
->cur_instr
, 0, device
->ir_length
) != new_instr
)
214 field
.device
= chain_pos
;
215 field
.num_bits
= device
->ir_length
;
216 field
.out_value
= calloc(CEIL(field
.num_bits
, 8), 1);
217 buf_set_u32(field
.out_value
, 0, field
.num_bits
, new_instr
);
218 field
.out_mask
= NULL
;
219 field
.in_value
= NULL
;
220 jtag_set_check_value(&field
, device
->expected
, device
->expected_mask
, NULL
);
222 jtag_add_ir_scan(1, &field
, -1, NULL
);
224 free(field
.out_value
);
230 int xscale_jtag_callback(enum jtag_event event
, void *priv
)
234 case JTAG_TRST_ASSERTED
:
236 case JTAG_TRST_RELEASED
:
238 case JTAG_SRST_ASSERTED
:
240 case JTAG_SRST_RELEASED
:
243 WARNING("unhandled JTAG event");
249 int xscale_read_dcsr(target_t
*target
)
251 armv4_5_common_t
*armv4_5
= target
->arch_info
;
252 xscale_common_t
*xscale
= armv4_5
->arch_info
;
256 scan_field_t fields
[3];
258 u8 field0_check_value
= 0x2;
259 u8 field0_check_mask
= 0x7;
261 u8 field2_check_value
= 0x0;
262 u8 field2_check_mask
= 0x1;
264 jtag_add_end_state(TAP_PD
);
265 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dcsr
);
267 buf_set_u32(&field0
, 1, 1, xscale
->hold_rst
);
268 buf_set_u32(&field0
, 2, 1, xscale
->external_debug_break
);
270 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
271 fields
[0].num_bits
= 3;
272 fields
[0].out_value
= &field0
;
273 fields
[0].out_mask
= NULL
;
274 fields
[0].in_value
= NULL
;
275 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
277 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
278 fields
[1].num_bits
= 32;
279 fields
[1].out_value
= NULL
;
280 fields
[1].out_mask
= NULL
;
281 fields
[1].in_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
282 fields
[1].in_handler
= NULL
;
283 fields
[1].in_handler_priv
= NULL
;
284 fields
[1].in_check_value
= NULL
;
285 fields
[1].in_check_mask
= NULL
;
289 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
290 fields
[2].num_bits
= 1;
291 fields
[2].out_value
= &field2
;
292 fields
[2].out_mask
= NULL
;
293 fields
[2].in_value
= NULL
;
294 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
296 jtag_add_dr_scan(3, fields
, -1, NULL
);
298 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
300 ERROR("JTAG error while reading DCSR");
304 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].dirty
= 0;
305 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].valid
= 1;
307 /* write the register with the value we just read
308 * on this second pass, only the first bit of field0 is guaranteed to be 0)
310 field0_check_mask
= 0x1;
311 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
312 fields
[1].in_value
= NULL
;
314 jtag_add_end_state(TAP_RTI
);
316 jtag_add_dr_scan(3, fields
, -1, NULL
);
321 int xscale_receive(target_t
*target
, u32
*buffer
, int num_words
)
323 armv4_5_common_t
*armv4_5
= target
->arch_info
;
324 xscale_common_t
*xscale
= armv4_5
->arch_info
;
326 enum tap_state path
[3];
327 scan_field_t fields
[3];
329 u8
*field0
= malloc(num_words
* 1);
330 u8 field0_check_value
= 0x2;
331 u8 field0_check_mask
= 0x6;
332 u32
*field1
= malloc(num_words
* 4);
333 u8 field2_check_value
= 0x0;
334 u8 field2_check_mask
= 0x1;
336 int words_scheduled
= 0;
345 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
346 fields
[0].num_bits
= 3;
347 fields
[0].out_value
= NULL
;
348 fields
[0].out_mask
= NULL
;
349 /* fields[0].in_value = field0; */
350 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
352 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
353 fields
[1].num_bits
= 32;
354 fields
[1].out_value
= NULL
;
355 fields
[1].out_mask
= NULL
;
356 fields
[1].in_value
= NULL
;
357 fields
[1].in_handler
= NULL
;
358 fields
[1].in_handler_priv
= NULL
;
359 fields
[1].in_check_value
= NULL
;
360 fields
[1].in_check_mask
= NULL
;
364 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
365 fields
[2].num_bits
= 1;
366 fields
[2].out_value
= NULL
;
367 fields
[2].out_mask
= NULL
;
368 fields
[2].in_value
= NULL
;
369 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
371 jtag_add_end_state(TAP_RTI
);
372 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dbgtx
);
373 jtag_add_runtest(1, -1);
375 /* repeat until all words have been collected */
376 while (words_done
< num_words
)
380 for (i
= words_done
; i
< num_words
; i
++)
382 fields
[0].in_value
= &field0
[i
];
383 fields
[1].in_handler
= buf_to_u32_handler
;
384 fields
[1].in_handler_priv
= (u8
*)&field1
[i
];
386 jtag_add_pathmove(3, path
);
387 jtag_add_dr_scan(3, fields
, TAP_RTI
, NULL
);
391 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
393 ERROR("JTAG error while receiving data from debug handler");
397 /* examine results */
398 for (i
= words_done
; i
< num_words
; i
++)
400 if (!(field0
[0] & 1))
402 /* move backwards if necessary */
404 for (j
= i
; j
< num_words
- 1; j
++)
406 field0
[j
] = field0
[j
+1];
407 field1
[j
] = field1
[j
+1];
412 words_done
+= words_scheduled
;
415 for (i
= 0; i
< num_words
; i
++)
416 *(buffer
++) = buf_get_u32((u8
*)&field1
[i
], 0, 32);
423 int xscale_read_tx(target_t
*target
, int consume
)
425 armv4_5_common_t
*armv4_5
= target
->arch_info
;
426 xscale_common_t
*xscale
= armv4_5
->arch_info
;
427 enum tap_state path
[3];
430 struct timeval timeout
, now
;
432 scan_field_t fields
[3];
434 u8 field0_check_value
= 0x2;
435 u8 field0_check_mask
= 0x6;
436 u8 field2_check_value
= 0x0;
437 u8 field2_check_mask
= 0x1;
439 jtag_add_end_state(TAP_RTI
);
441 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dbgtx
);
447 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
448 fields
[0].num_bits
= 3;
449 fields
[0].out_value
= NULL
;
450 fields
[0].out_mask
= NULL
;
451 fields
[0].in_value
= &field0_in
;
452 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
454 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
455 fields
[1].num_bits
= 32;
456 fields
[1].out_value
= NULL
;
457 fields
[1].out_mask
= NULL
;
458 fields
[1].in_value
= xscale
->reg_cache
->reg_list
[XSCALE_TX
].value
;
459 fields
[1].in_handler
= NULL
;
460 fields
[1].in_handler_priv
= NULL
;
461 fields
[1].in_check_value
= NULL
;
462 fields
[1].in_check_mask
= NULL
;
466 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
467 fields
[2].num_bits
= 1;
468 fields
[2].out_value
= NULL
;
469 fields
[2].out_mask
= NULL
;
470 fields
[2].in_value
= NULL
;
471 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
473 gettimeofday(&timeout
, NULL
);
474 timeval_add_time(&timeout
, 5, 0);
478 /* if we want to consume the register content (i.e. clear TX_READY),
479 * we have to go straight from Capture-DR to Shift-DR
480 * otherwise, we go from Capture-DR to Exit1-DR to Pause-DR
483 jtag_add_pathmove(3, path
);
485 jtag_add_statemove(TAP_PD
);
487 jtag_add_dr_scan(3, fields
, TAP_RTI
, NULL
);
489 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
491 ERROR("JTAG error while reading TX");
495 gettimeofday(&now
, NULL
);
496 if ((now
.tv_sec
> timeout
.tv_sec
) && (now
.tv_usec
> timeout
.tv_usec
))
498 ERROR("time out reading TX register");
499 return ERROR_TARGET_TIMEOUT
;
501 } while ((!(field0_in
& 1)) && consume
);
503 if (!(field0_in
& 1))
504 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
509 int xscale_write_rx(target_t
*target
)
511 armv4_5_common_t
*armv4_5
= target
->arch_info
;
512 xscale_common_t
*xscale
= armv4_5
->arch_info
;
515 struct timeval timeout
, now
;
517 scan_field_t fields
[3];
520 u8 field0_check_value
= 0x2;
521 u8 field0_check_mask
= 0x6;
523 u8 field2_check_value
= 0x0;
524 u8 field2_check_mask
= 0x1;
526 jtag_add_end_state(TAP_RTI
);
528 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dbgrx
);
530 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
531 fields
[0].num_bits
= 3;
532 fields
[0].out_value
= &field0_out
;
533 fields
[0].out_mask
= NULL
;
534 fields
[0].in_value
= &field0_in
;
535 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
537 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
538 fields
[1].num_bits
= 32;
539 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
;
540 fields
[1].out_mask
= NULL
;
541 fields
[1].in_value
= NULL
;
542 fields
[1].in_handler
= NULL
;
543 fields
[1].in_handler_priv
= NULL
;
544 fields
[1].in_check_value
= NULL
;
545 fields
[1].in_check_mask
= NULL
;
549 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
550 fields
[2].num_bits
= 1;
551 fields
[2].out_value
= &field2
;
552 fields
[2].out_mask
= NULL
;
553 fields
[2].in_value
= NULL
;
554 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
556 gettimeofday(&timeout
, NULL
);
557 timeval_add_time(&timeout
, 5, 0);
559 /* poll until rx_read is low */
563 jtag_add_dr_scan(3, fields
, TAP_RTI
, NULL
);
565 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
567 ERROR("JTAG error while writing RX");
571 gettimeofday(&now
, NULL
);
572 if ((now
.tv_sec
> timeout
.tv_sec
) && (now
.tv_usec
> timeout
.tv_usec
))
574 ERROR("time out writing RX register");
575 return ERROR_TARGET_TIMEOUT
;
577 } while (field0_in
& 1);
581 jtag_add_dr_scan(3, fields
, TAP_RTI
, NULL
);
583 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
585 ERROR("JTAG error while writing RX");
592 /* send count elements of size byte to the debug handler */
593 int xscale_send(target_t
*target
, u8
*buffer
, int count
, int size
)
595 armv4_5_common_t
*armv4_5
= target
->arch_info
;
596 xscale_common_t
*xscale
= armv4_5
->arch_info
;
601 u8 output
[4] = {0, 0, 0, 0};
603 scan_field_t fields
[3];
606 u8 field0_check_value
= 0x2;
607 u8 field0_check_mask
= 0x6;
609 u8 field2_check_value
= 0x0;
610 u8 field2_check_mask
= 0x1;
612 jtag_add_end_state(TAP_RTI
);
614 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dbgrx
);
616 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
617 fields
[0].num_bits
= 3;
618 fields
[0].out_value
= &field0_out
;
619 fields
[0].out_mask
= NULL
;
620 fields
[0].in_value
= &field0_in
;
621 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
623 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
624 fields
[1].num_bits
= 32;
625 fields
[1].out_value
= output
;
626 fields
[1].out_mask
= NULL
;
627 fields
[1].in_value
= NULL
;
628 fields
[1].in_handler
= NULL
;
629 fields
[1].in_handler_priv
= NULL
;
630 fields
[1].in_check_value
= NULL
;
631 fields
[1].in_check_mask
= NULL
;
635 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
636 fields
[2].num_bits
= 1;
637 fields
[2].out_value
= &field2
;
638 fields
[2].out_mask
= NULL
;
639 fields
[2].in_value
= NULL
;
640 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
642 while (done_count
++ < count
)
644 /* extract sized element from target-endian buffer, and put it
645 * into little-endian output buffer
650 buf_set_u32(output
, 0, 32, target_buffer_get_u32(target
, buffer
));
653 buf_set_u32(output
, 0, 32, target_buffer_get_u16(target
, buffer
));
659 ERROR("BUG: size neither 4, 2 nor 1");
663 jtag_add_dr_scan(3, fields
, TAP_RTI
, NULL
);
667 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
669 ERROR("JTAG error while sending data to debug handler");
676 int xscale_send_u32(target_t
*target
, u32 value
)
678 armv4_5_common_t
*armv4_5
= target
->arch_info
;
679 xscale_common_t
*xscale
= armv4_5
->arch_info
;
681 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
682 return xscale_write_rx(target
);
685 int xscale_write_dcsr(target_t
*target
, int hold_rst
, int ext_dbg_brk
)
687 armv4_5_common_t
*armv4_5
= target
->arch_info
;
688 xscale_common_t
*xscale
= armv4_5
->arch_info
;
692 scan_field_t fields
[3];
694 u8 field0_check_value
= 0x2;
695 u8 field0_check_mask
= 0x7;
697 u8 field2_check_value
= 0x0;
698 u8 field2_check_mask
= 0x1;
701 xscale
->hold_rst
= hold_rst
;
703 if (ext_dbg_brk
!= -1)
704 xscale
->external_debug_break
= ext_dbg_brk
;
706 jtag_add_end_state(TAP_RTI
);
707 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dcsr
);
709 buf_set_u32(&field0
, 1, 1, xscale
->hold_rst
);
710 buf_set_u32(&field0
, 2, 1, xscale
->external_debug_break
);
712 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
713 fields
[0].num_bits
= 3;
714 fields
[0].out_value
= &field0
;
715 fields
[0].out_mask
= NULL
;
716 fields
[0].in_value
= NULL
;
717 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
719 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
720 fields
[1].num_bits
= 32;
721 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
722 fields
[1].out_mask
= NULL
;
723 fields
[1].in_value
= NULL
;
724 fields
[1].in_handler
= NULL
;
725 fields
[1].in_handler_priv
= NULL
;
726 fields
[1].in_check_value
= NULL
;
727 fields
[1].in_check_mask
= NULL
;
731 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
732 fields
[2].num_bits
= 1;
733 fields
[2].out_value
= &field2
;
734 fields
[2].out_mask
= NULL
;
735 fields
[2].in_value
= NULL
;
736 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
738 jtag_add_dr_scan(3, fields
, -1, NULL
);
740 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
742 ERROR("JTAG error while writing DCSR");
746 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].dirty
= 0;
747 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].valid
= 1;
752 /* parity of the number of bits 0 if even; 1 if odd. for 32 bit words */
753 unsigned int parity (unsigned int v
)
760 DEBUG("parity of 0x%x is %i", ov
, (0x6996 >> v
) & 1);
761 return (0x6996 >> v
) & 1;
764 int xscale_load_ic(target_t
*target
, int mini
, u32 va
, u32 buffer
[8])
766 armv4_5_common_t
*armv4_5
= target
->arch_info
;
767 xscale_common_t
*xscale
= armv4_5
->arch_info
;
772 scan_field_t fields
[2];
774 DEBUG("loading miniIC at 0x%8.8x", va
);
776 jtag_add_end_state(TAP_RTI
);
777 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.ldic
); /* LDIC */
779 /* CMD is b010 for Main IC and b011 for Mini IC */
781 buf_set_u32(&cmd
, 0, 3, 0x3);
783 buf_set_u32(&cmd
, 0, 3, 0x2);
785 buf_set_u32(&cmd
, 3, 3, 0x0);
787 /* virtual address of desired cache line */
788 buf_set_u32(packet
, 0, 27, va
>> 5);
790 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
791 fields
[0].num_bits
= 6;
792 fields
[0].out_value
= &cmd
;
793 fields
[0].out_mask
= NULL
;
794 fields
[0].in_value
= NULL
;
795 fields
[0].in_check_value
= NULL
;
796 fields
[0].in_check_mask
= NULL
;
797 fields
[0].in_handler
= NULL
;
798 fields
[0].in_handler_priv
= NULL
;
800 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
801 fields
[1].num_bits
= 27;
802 fields
[1].out_value
= packet
;
803 fields
[1].out_mask
= NULL
;
804 fields
[1].in_value
= NULL
;
805 fields
[1].in_check_value
= NULL
;
806 fields
[1].in_check_mask
= NULL
;
807 fields
[1].in_handler
= NULL
;
808 fields
[1].in_handler_priv
= NULL
;
810 jtag_add_dr_scan(2, fields
, -1, NULL
);
812 fields
[0].num_bits
= 32;
813 fields
[0].out_value
= packet
;
815 fields
[1].num_bits
= 1;
816 fields
[1].out_value
= &cmd
;
818 for (word
= 0; word
< 8; word
++)
820 buf_set_u32(packet
, 0, 32, buffer
[word
]);
821 cmd
= parity(*((u32
*)packet
));
822 jtag_add_dr_scan(2, fields
, -1, NULL
);
825 jtag_execute_queue();
830 int xscale_invalidate_ic_line(target_t
*target
, u32 va
)
832 armv4_5_common_t
*armv4_5
= target
->arch_info
;
833 xscale_common_t
*xscale
= armv4_5
->arch_info
;
837 scan_field_t fields
[2];
839 jtag_add_end_state(TAP_RTI
);
840 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.ldic
); /* LDIC */
842 /* CMD for invalidate IC line b000, bits [6:4] b000 */
843 buf_set_u32(&cmd
, 0, 6, 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, NULL
);
873 int xscale_update_vectors(target_t
*target
)
875 armv4_5_common_t
*armv4_5
= target
->arch_info
;
876 xscale_common_t
*xscale
= armv4_5
->arch_info
;
879 u32 low_reset_branch
, high_reset_branch
;
881 for (i
= 1; i
< 8; i
++)
883 /* if there's a static vector specified for this exception, override */
884 if (xscale
->static_high_vectors_set
& (1 << i
))
886 xscale
->high_vectors
[i
] = xscale
->static_high_vectors
[i
];
890 if (target_read_u32(target
, 0xffff0000 + 4*i
, &xscale
->high_vectors
[i
]) != ERROR_OK
)
892 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
897 for (i
= 1; i
< 8; i
++)
899 if (xscale
->static_low_vectors_set
& (1 << i
))
901 xscale
->low_vectors
[i
] = xscale
->static_low_vectors
[i
];
905 if (target_read_u32(target
, 0x0 + 4*i
, &xscale
->low_vectors
[i
]) != ERROR_OK
)
907 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
912 /* calculate branches to debug handler */
913 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
914 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
916 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
917 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
919 /* invalidate and load exception vectors in mini i-cache */
920 xscale_invalidate_ic_line(target
, 0x0);
921 xscale_invalidate_ic_line(target
, 0xffff0000);
923 xscale_load_ic(target
, 1, 0x0, xscale
->low_vectors
);
924 xscale_load_ic(target
, 1, 0xffff0000, xscale
->high_vectors
);
929 int xscale_arch_state(struct target_s
*target
, char *buf
, int buf_size
)
931 armv4_5_common_t
*armv4_5
= target
->arch_info
;
932 xscale_common_t
*xscale
= armv4_5
->arch_info
;
936 "disabled", "enabled"
939 char *arch_dbg_reason
[] =
941 "", "\n(processor reset)", "\n(trace buffer full)"
944 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
946 ERROR("BUG: called for a non-ARMv4/5 target");
950 snprintf(buf
, buf_size
,
951 "target halted in %s state due to %s, current mode: %s\n"
952 "cpsr: 0x%8.8x pc: 0x%8.8x\n"
953 "MMU: %s, D-Cache: %s, I-Cache: %s"
955 armv4_5_state_strings
[armv4_5
->core_state
],
956 target_debug_reason_strings
[target
->debug_reason
],
957 armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)],
958 buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32),
959 buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32),
960 state
[xscale
->armv4_5_mmu
.mmu_enabled
],
961 state
[xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
],
962 state
[xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
],
963 arch_dbg_reason
[xscale
->arch_debug_reason
]);
968 enum target_state
xscale_poll(target_t
*target
)
971 armv4_5_common_t
*armv4_5
= target
->arch_info
;
972 xscale_common_t
*xscale
= armv4_5
->arch_info
;
974 if ((target
->state
== TARGET_RUNNING
) || (target
->state
== TARGET_DEBUG_RUNNING
))
976 if ((retval
= xscale_read_tx(target
, 0)) == ERROR_OK
)
978 enum target_state previous_state
= target
->state
;
980 /* there's data to read from the tx register, we entered debug state */
981 xscale
->handler_running
= 1;
983 target
->state
= TARGET_HALTED
;
985 /* process debug entry, fetching current mode regs */
986 if ((retval
= xscale_debug_entry(target
)) != ERROR_OK
)
989 /* debug_entry could have overwritten target state (i.e. immediate resume)
990 * don't signal event handlers in that case
992 if (target
->state
!= TARGET_HALTED
)
993 return target
->state
;
995 /* if target was running, signal that we halted
996 * otherwise we reentered from debug execution */
997 if (previous_state
== TARGET_RUNNING
)
998 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1000 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
1002 else if (retval
!= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
1004 ERROR("error while polling TX register");
1009 return target
->state
;
1012 int xscale_debug_entry(target_t
*target
)
1014 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1015 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1017 u32
*buffer
= malloc(4 * 10);
1022 /* clear external dbg break (will be written on next DCSR read) */
1023 xscale
->external_debug_break
= 0;
1024 xscale_read_dcsr(target
);
1026 /* get r0, pc, r1 to r7 and cpsr */
1027 xscale_receive(target
, buffer
, 10);
1029 /* move r0 from buffer to register cache */
1030 buf_set_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32, buffer
[0]);
1031 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
1032 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
1033 DEBUG("r0: 0x%8.8x", buffer
[0]);
1035 /* move pc from buffer to register cache */
1036 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, buffer
[1]);
1037 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
1038 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
1039 DEBUG("pc: 0x%8.8x", buffer
[1]);
1041 /* move data from buffer to register cache */
1042 for (i
= 1; i
<= 7; i
++)
1044 buf_set_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32, buffer
[1 + i
]);
1045 armv4_5
->core_cache
->reg_list
[i
].dirty
= 1;
1046 armv4_5
->core_cache
->reg_list
[i
].valid
= 1;
1047 DEBUG("r%i: 0x%8.8x", i
, buffer
[i
+ 1]);
1050 buf_set_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32, buffer
[9]);
1051 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].dirty
= 1;
1052 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].valid
= 1;
1053 DEBUG("cpsr: 0x%8.8x", buffer
[9]);
1055 armv4_5
->core_mode
= buffer
[9] & 0x1f;
1056 if (armv4_5_mode_to_number(armv4_5
->core_mode
) == -1)
1058 target
->state
= TARGET_UNKNOWN
;
1059 ERROR("cpsr contains invalid mode value - communication failure");
1060 return ERROR_TARGET_FAILURE
;
1062 DEBUG("target entered debug state in %s mode", armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)]);
1064 if (buffer
[9] & 0x20)
1065 armv4_5
->core_state
= ARMV4_5_STATE_THUMB
;
1067 armv4_5
->core_state
= ARMV4_5_STATE_ARM
;
1069 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1070 if ((armv4_5
->core_mode
!= ARMV4_5_MODE_USR
) && (armv4_5
->core_mode
!= ARMV4_5_MODE_SYS
))
1072 xscale_receive(target
, buffer
, 8);
1073 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1074 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
1075 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
1079 /* r8 to r14, but no spsr */
1080 xscale_receive(target
, buffer
, 7);
1083 /* move data from buffer to register cache */
1084 for (i
= 8; i
<= 14; i
++)
1086 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).value
, 0, 32, buffer
[i
- 8]);
1087 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).dirty
= 0;
1088 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).valid
= 1;
1091 /* examine debug reason */
1092 xscale_read_dcsr(target
);
1093 moe
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 2, 3);
1095 /* stored PC (for calculating fixup) */
1096 pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1100 case 0x0: /* Processor reset */
1101 target
->debug_reason
= DBG_REASON_DBGRQ
;
1102 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_RESET
;
1105 case 0x1: /* Instruction breakpoint hit */
1106 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1107 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1110 case 0x2: /* Data breakpoint hit */
1111 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
1112 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1115 case 0x3: /* BKPT instruction executed */
1116 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1117 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1120 case 0x4: /* Ext. debug event */
1121 target
->debug_reason
= DBG_REASON_DBGRQ
;
1122 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1125 case 0x5: /* Vector trap occured */
1126 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1127 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1130 case 0x6: /* Trace buffer full break */
1131 target
->debug_reason
= DBG_REASON_DBGRQ
;
1132 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_TB_FULL
;
1135 case 0x7: /* Reserved */
1137 ERROR("Method of Entry is 'Reserved'");
1142 /* apply PC fixup */
1143 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, pc
);
1145 /* on the first debug entry, identify cache type */
1146 if (xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
1150 /* read cp15 cache type register */
1151 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
]);
1152 cache_type_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
].value
, 0, 32);
1154 armv4_5_identify_cache(cache_type_reg
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
1157 /* examine MMU and Cache settings */
1158 /* read cp15 control register */
1159 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
1160 xscale
->cp15_control_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
1161 xscale
->armv4_5_mmu
.mmu_enabled
= (xscale
->cp15_control_reg
& 0x1U
) ? 1 : 0;
1162 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= (xscale
->cp15_control_reg
& 0x4U
) ? 1 : 0;
1163 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= (xscale
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
1165 /* tracing enabled, read collected trace data */
1166 if (xscale
->trace
.buffer_enabled
)
1168 xscale_read_trace(target
);
1169 xscale
->trace
.buffer_fill
--;
1171 /* resume if we're still collecting trace data */
1172 if ((xscale
->arch_debug_reason
== XSCALE_DBG_REASON_TB_FULL
)
1173 && (xscale
->trace
.buffer_fill
> 0))
1175 xscale_resume(target
, 1, 0x0, 1, 0);
1179 xscale
->trace
.buffer_enabled
= 0;
1186 int xscale_halt(target_t
*target
)
1188 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1189 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1191 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
1193 if (target
->state
== TARGET_HALTED
)
1195 WARNING("target was already halted");
1196 return ERROR_TARGET_ALREADY_HALTED
;
1198 else if (target
->state
== TARGET_UNKNOWN
)
1200 /* this must not happen for a xscale target */
1201 ERROR("target was in unknown state when halt was requested");
1204 else if (target
->state
== TARGET_RESET
)
1206 DEBUG("target->state == TARGET_RESET");
1210 /* assert external dbg break */
1211 xscale
->external_debug_break
= 1;
1212 xscale_read_dcsr(target
);
1214 target
->debug_reason
= DBG_REASON_DBGRQ
;
1220 int xscale_enable_single_step(struct target_s
*target
, u32 next_pc
)
1222 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1223 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1224 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1226 if (xscale
->ibcr0_used
)
1228 breakpoint_t
*ibcr0_bp
= breakpoint_find(target
, buf_get_u32(ibcr0
->value
, 0, 32) & 0xfffffffe);
1232 xscale_unset_breakpoint(target
, ibcr0_bp
);
1236 ERROR("BUG: xscale->ibcr0_used is set, but no breakpoint with that address found");
1241 xscale_set_reg_u32(ibcr0
, next_pc
| 0x1);
1246 int xscale_disable_single_step(struct target_s
*target
)
1248 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1249 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1250 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1252 xscale_set_reg_u32(ibcr0
, 0x0);
1257 int xscale_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
1259 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1260 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1261 breakpoint_t
*breakpoint
= target
->breakpoints
;
1270 if (target
->state
!= TARGET_HALTED
)
1272 WARNING("target not halted");
1273 return ERROR_TARGET_NOT_HALTED
;
1276 if (!debug_execution
)
1278 target_free_all_working_areas(target
);
1281 /* update vector tables */
1282 xscale_update_vectors(target
);
1284 /* current = 1: continue on current pc, otherwise continue at <address> */
1286 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1288 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1290 /* if we're at the reset vector, we have to simulate the branch */
1291 if (current_pc
== 0x0)
1293 arm_simulate_step(target
, NULL
);
1294 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1297 /* the front-end may request us not to handle breakpoints */
1298 if (handle_breakpoints
)
1300 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1304 /* there's a breakpoint at the current PC, we have to step over it */
1305 DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
1306 xscale_unset_breakpoint(target
, breakpoint
);
1308 /* calculate PC of next instruction */
1309 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1312 target_read_u32(target
, current_pc
, ¤t_opcode
);
1313 ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode
);
1316 DEBUG("enable single-step");
1317 xscale_enable_single_step(target
, next_pc
);
1319 /* restore banked registers */
1320 xscale_restore_context(target
);
1322 /* send resume request (command 0x30 or 0x31)
1323 * clean the trace buffer if it is to be enabled (0x62) */
1324 if (xscale
->trace
.buffer_enabled
)
1326 xscale_send_u32(target
, 0x62);
1327 xscale_send_u32(target
, 0x31);
1330 xscale_send_u32(target
, 0x30);
1333 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1334 DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1336 for (i
= 7; i
>= 0; i
--)
1339 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1340 DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1344 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1345 DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1347 /* wait for and process debug entry */
1348 xscale_debug_entry(target
);
1350 DEBUG("disable single-step");
1351 xscale_disable_single_step(target
);
1353 DEBUG("set breakpoint at 0x%8.8x", breakpoint
->address
);
1354 xscale_set_breakpoint(target
, breakpoint
);
1358 /* enable any pending breakpoints and watchpoints */
1359 xscale_enable_breakpoints(target
);
1360 xscale_enable_watchpoints(target
);
1362 /* restore banked registers */
1363 xscale_restore_context(target
);
1365 /* send resume request (command 0x30 or 0x31)
1366 * clean the trace buffer if it is to be enabled (0x62) */
1367 if (xscale
->trace
.buffer_enabled
)
1369 xscale_send_u32(target
, 0x62);
1370 xscale_send_u32(target
, 0x31);
1373 xscale_send_u32(target
, 0x30);
1376 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1377 DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1379 for (i
= 7; i
>= 0; i
--)
1382 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1383 DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1387 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1388 DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1390 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1392 if (!debug_execution
)
1394 /* registers are now invalid */
1395 armv4_5_invalidate_core_regs(target
);
1396 target
->state
= TARGET_RUNNING
;
1397 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1401 target
->state
= TARGET_DEBUG_RUNNING
;
1402 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1405 DEBUG("target resumed");
1407 xscale
->handler_running
= 1;
1412 int xscale_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
1414 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1415 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1416 breakpoint_t
*breakpoint
= target
->breakpoints
;
1418 u32 current_pc
, next_pc
;
1422 if (target
->state
!= TARGET_HALTED
)
1424 WARNING("target not halted");
1425 return ERROR_TARGET_NOT_HALTED
;
1428 /* current = 1: continue on current pc, otherwise continue at <address> */
1430 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1432 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1434 /* if we're at the reset vector, we have to simulate the step */
1435 if (current_pc
== 0x0)
1437 arm_simulate_step(target
, NULL
);
1438 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1440 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1441 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1446 /* the front-end may request us not to handle breakpoints */
1447 if (handle_breakpoints
)
1448 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1450 xscale_unset_breakpoint(target
, breakpoint
);
1453 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1455 /* calculate PC of next instruction */
1456 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1459 target_read_u32(target
, current_pc
, ¤t_opcode
);
1460 ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode
);
1463 DEBUG("enable single-step");
1464 xscale_enable_single_step(target
, next_pc
);
1466 /* restore banked registers */
1467 xscale_restore_context(target
);
1469 /* send resume request (command 0x30 or 0x31)
1470 * clean the trace buffer if it is to be enabled (0x62) */
1471 if (xscale
->trace
.buffer_enabled
)
1473 xscale_send_u32(target
, 0x62);
1474 xscale_send_u32(target
, 0x31);
1477 xscale_send_u32(target
, 0x30);
1480 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1481 DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1483 for (i
= 7; i
>= 0; i
--)
1486 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1487 DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1491 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1492 DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1494 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1496 /* registers are now invalid */
1497 armv4_5_invalidate_core_regs(target
);
1499 /* wait for and process debug entry */
1500 xscale_debug_entry(target
);
1502 DEBUG("disable single-step");
1503 xscale_disable_single_step(target
);
1505 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1509 xscale_set_breakpoint(target
, breakpoint
);
1512 DEBUG("target stepped");
1518 int xscale_assert_reset(target_t
*target
)
1520 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1521 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1523 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
1525 /* select DCSR instruction (set endstate to R-T-I to ensure we don't
1526 * end up in T-L-R, which would reset JTAG
1528 jtag_add_end_state(TAP_RTI
);
1529 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dcsr
);
1531 /* set Hold reset, Halt mode and Trap Reset */
1532 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1533 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1534 xscale_write_dcsr(target
, 1, 0);
1536 /* select BYPASS, because having DCSR selected caused problems on the PXA27x */
1537 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, 0x7f);
1538 jtag_execute_queue();
1541 jtag_add_reset(0, 1);
1543 /* sleep 1ms, to be sure we fulfill any requirements */
1544 jtag_add_sleep(1000);
1545 jtag_execute_queue();
1547 target
->state
= TARGET_RESET
;
1552 int xscale_deassert_reset(target_t
*target
)
1554 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1555 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1557 fileio_t debug_handler
;
1565 breakpoint_t
*breakpoint
= target
->breakpoints
;
1569 xscale
->ibcr_available
= 2;
1570 xscale
->ibcr0_used
= 0;
1571 xscale
->ibcr1_used
= 0;
1573 xscale
->dbr_available
= 2;
1574 xscale
->dbr0_used
= 0;
1575 xscale
->dbr1_used
= 0;
1577 /* mark all hardware breakpoints as unset */
1580 if (breakpoint
->type
== BKPT_HARD
)
1582 breakpoint
->set
= 0;
1584 breakpoint
= breakpoint
->next
;
1587 if (!xscale
->handler_installed
)
1590 jtag_add_reset(0, 0);
1592 /* wait 300ms; 150 and 100ms were not enough */
1593 jtag_add_sleep(3000000);
1595 jtag_add_runtest(2030, TAP_RTI
);
1596 jtag_execute_queue();
1598 /* set Hold reset, Halt mode and Trap Reset */
1599 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1600 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1601 xscale_write_dcsr(target
, 1, 0);
1603 /* Load debug handler */
1604 if (fileio_open(&debug_handler
, PKGLIBDIR
"/xscale/debug_handler.bin", FILEIO_READ
, FILEIO_BINARY
) != ERROR_OK
)
1606 ERROR("file open error: %s", debug_handler
.error_str
);
1610 if ((binary_size
= debug_handler
.size
) % 4)
1612 ERROR("debug_handler.bin: size not a multiple of 4");
1616 if (binary_size
> 0x800)
1618 ERROR("debug_handler.bin: larger than 2kb");
1622 binary_size
= CEIL(binary_size
, 32) * 32;
1624 address
= xscale
->handler_address
;
1625 while (binary_size
> 0)
1630 if ((retval
= fileio_read(&debug_handler
, 32, buffer
, &buf_cnt
)) != ERROR_OK
)
1632 ERROR("reading debug handler failed: %s", debug_handler
.error_str
);
1635 for (i
= 0; i
< buf_cnt
; i
+= 4)
1637 /* convert LE buffer to host-endian u32 */
1638 cache_line
[i
/ 4] = le_to_h_u32(&buffer
[i
]);
1641 for (; buf_cnt
< 32; buf_cnt
+= 4)
1643 cache_line
[buf_cnt
/ 4] = 0xe1a08008;
1646 /* only load addresses other than the reset vectors */
1647 if ((address
% 0x400) != 0x0)
1649 xscale_load_ic(target
, 1, address
, cache_line
);
1653 binary_size
-= buf_cnt
;
1656 xscale_load_ic(target
, 1, 0x0, xscale
->low_vectors
);
1657 xscale_load_ic(target
, 1, 0xffff0000, xscale
->high_vectors
);
1659 jtag_add_runtest(30, TAP_RTI
);
1661 jtag_add_sleep(100000);
1663 /* set Hold reset, Halt mode and Trap Reset */
1664 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1665 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1666 xscale_write_dcsr(target
, 1, 0);
1668 /* clear Hold reset to let the target run (should enter debug handler) */
1669 xscale_write_dcsr(target
, 0, 1);
1670 target
->state
= TARGET_RUNNING
;
1672 if ((target
->reset_mode
!= RESET_HALT
) && (target
->reset_mode
!= RESET_INIT
))
1674 jtag_add_sleep(10000);
1676 /* we should have entered debug now */
1677 xscale_debug_entry(target
);
1678 target
->state
= TARGET_HALTED
;
1680 /* resume the target */
1681 xscale_resume(target
, 1, 0x0, 1, 0);
1684 fileio_close(&debug_handler
);
1688 jtag_add_reset(0, 0);
1695 int xscale_soft_reset_halt(struct target_s
*target
)
1701 int xscale_prepare_reset_halt(struct target_s
*target
)
1703 /* nothing to be done for reset_halt on XScale targets
1704 * we always halt after a reset to upload the debug handler
1709 int xscale_read_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
)
1715 int xscale_write_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
, u32 value
)
1721 int xscale_full_context(target_t
*target
)
1723 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1731 if (target
->state
!= TARGET_HALTED
)
1733 WARNING("target not halted");
1734 return ERROR_TARGET_NOT_HALTED
;
1737 buffer
= malloc(4 * 8);
1739 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1740 * we can't enter User mode on an XScale (unpredictable),
1741 * but User shares registers with SYS
1743 for(i
= 1; i
< 7; i
++)
1747 /* check if there are invalid registers in the current mode
1749 for (j
= 0; j
<= 16; j
++)
1751 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
== 0)
1759 /* request banked registers */
1760 xscale_send_u32(target
, 0x0);
1763 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1764 tmp_cpsr
|= 0xc0; /* I/F bits */
1766 /* send CPSR for desired mode */
1767 xscale_send_u32(target
, tmp_cpsr
);
1769 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1770 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1772 xscale_receive(target
, buffer
, 8);
1773 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1774 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1775 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).valid
= 1;
1779 xscale_receive(target
, buffer
, 7);
1782 /* move data from buffer to register cache */
1783 for (j
= 8; j
<= 14; j
++)
1785 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]);
1786 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1787 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
= 1;
1797 int xscale_restore_context(target_t
*target
)
1799 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1805 if (target
->state
!= TARGET_HALTED
)
1807 WARNING("target not halted");
1808 return ERROR_TARGET_NOT_HALTED
;
1811 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1812 * we can't enter User mode on an XScale (unpredictable),
1813 * but User shares registers with SYS
1815 for(i
= 1; i
< 7; i
++)
1819 /* check if there are invalid registers in the current mode
1821 for (j
= 8; j
<= 14; j
++)
1823 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
== 1)
1827 /* if not USR/SYS, check if the SPSR needs to be written */
1828 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1830 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
== 1)
1838 /* send banked registers */
1839 xscale_send_u32(target
, 0x1);
1842 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1843 tmp_cpsr
|= 0xc0; /* I/F bits */
1845 /* send CPSR for desired mode */
1846 xscale_send_u32(target
, tmp_cpsr
);
1848 /* send banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1849 for (j
= 8; j
<= 14; j
++)
1851 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, j
).value
, 0, 32));
1852 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1855 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1857 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32));
1858 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1866 int xscale_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1868 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1869 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1873 DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address
, size
, count
);
1875 if (target
->state
!= TARGET_HALTED
)
1877 WARNING("target not halted");
1878 return ERROR_TARGET_NOT_HALTED
;
1881 /* sanitize arguments */
1882 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1883 return ERROR_INVALID_ARGUMENTS
;
1885 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1886 return ERROR_TARGET_UNALIGNED_ACCESS
;
1888 /* send memory read request (command 0x1n, n: access size) */
1889 xscale_send_u32(target
, 0x10 | size
);
1891 /* send base address for read request */
1892 xscale_send_u32(target
, address
);
1894 /* send number of requested data words */
1895 xscale_send_u32(target
, count
);
1897 /* receive data from target (count times 32-bit words in host endianness) */
1898 buf32
= malloc(4 * count
);
1899 xscale_receive(target
, buf32
, count
);
1901 /* extract data from host-endian buffer into byte stream */
1902 for (i
= 0; i
< count
; i
++)
1907 target_buffer_set_u32(target
, buffer
, buf32
[i
]);
1911 target_buffer_set_u16(target
, buffer
, buf32
[i
] & 0xffff);
1915 *buffer
++ = buf32
[i
] & 0xff;
1918 ERROR("should never get here");
1925 /* examine DCSR, to see if Sticky Abort (SA) got set */
1926 xscale_read_dcsr(target
);
1927 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
1930 xscale_send_u32(target
, 0x60);
1932 return ERROR_TARGET_DATA_ABORT
;
1938 int xscale_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1940 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1941 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1943 DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address
, size
, count
);
1945 if (target
->state
!= TARGET_HALTED
)
1947 WARNING("target not halted");
1948 return ERROR_TARGET_NOT_HALTED
;
1951 /* sanitize arguments */
1952 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1953 return ERROR_INVALID_ARGUMENTS
;
1955 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1956 return ERROR_TARGET_UNALIGNED_ACCESS
;
1958 /* send memory write request (command 0x2n, n: access size) */
1959 xscale_send_u32(target
, 0x20 | size
);
1961 /* send base address for read request */
1962 xscale_send_u32(target
, address
);
1964 /* send number of requested data words to be written*/
1965 xscale_send_u32(target
, count
);
1967 /* extract data from host-endian buffer into byte stream */
1969 for (i
= 0; i
< count
; i
++)
1974 value
= target_buffer_get_u32(target
, buffer
);
1975 xscale_send_u32(target
, value
);
1979 value
= target_buffer_get_u16(target
, buffer
);
1980 xscale_send_u32(target
, value
);
1985 xscale_send_u32(target
, value
);
1989 ERROR("should never get here");
1994 xscale_send(target
, buffer
, count
, size
);
1996 /* examine DCSR, to see if Sticky Abort (SA) got set */
1997 xscale_read_dcsr(target
);
1998 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
2001 xscale_send_u32(target
, 0x60);
2003 return ERROR_TARGET_DATA_ABORT
;
2009 int xscale_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
2011 xscale_write_memory(target
, address
, 4, count
, buffer
);
2016 int xscale_checksum_memory(struct target_s
*target
, u32 address
, u32 count
, u32
* checksum
)
2018 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2021 u32
xscale_get_ttb(target_t
*target
)
2023 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2024 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2027 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_TTB
]);
2028 ttb
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_TTB
].value
, 0, 32);
2033 void xscale_disable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
2035 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2036 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2039 /* read cp15 control register */
2040 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2041 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2044 cp15_control
&= ~0x1U
;
2049 xscale_send_u32(target
, 0x50);
2050 xscale_send_u32(target
, xscale
->cache_clean_address
);
2052 /* invalidate DCache */
2053 xscale_send_u32(target
, 0x51);
2055 cp15_control
&= ~0x4U
;
2060 /* invalidate ICache */
2061 xscale_send_u32(target
, 0x52);
2062 cp15_control
&= ~0x1000U
;
2065 /* write new cp15 control register */
2066 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2068 /* execute cpwait to ensure outstanding operations complete */
2069 xscale_send_u32(target
, 0x53);
2072 void xscale_enable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
2074 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2075 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2078 /* read cp15 control register */
2079 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2080 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2083 cp15_control
|= 0x1U
;
2086 cp15_control
|= 0x4U
;
2089 cp15_control
|= 0x1000U
;
2091 /* write new cp15 control register */
2092 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2094 /* execute cpwait to ensure outstanding operations complete */
2095 xscale_send_u32(target
, 0x53);
2098 int xscale_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2100 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2101 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2103 if (target
->state
!= TARGET_HALTED
)
2105 WARNING("target not halted");
2106 return ERROR_TARGET_NOT_HALTED
;
2109 if (xscale
->force_hw_bkpts
)
2110 breakpoint
->type
= BKPT_HARD
;
2112 if (breakpoint
->set
)
2114 WARNING("breakpoint already set");
2118 if (breakpoint
->type
== BKPT_HARD
)
2120 u32 value
= breakpoint
->address
| 1;
2121 if (!xscale
->ibcr0_used
)
2123 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], value
);
2124 xscale
->ibcr0_used
= 1;
2125 breakpoint
->set
= 1; /* breakpoint set on first breakpoint register */
2127 else if (!xscale
->ibcr1_used
)
2129 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], value
);
2130 xscale
->ibcr1_used
= 1;
2131 breakpoint
->set
= 2; /* breakpoint set on second breakpoint register */
2135 ERROR("BUG: no hardware comparator available");
2139 else if (breakpoint
->type
== BKPT_SOFT
)
2141 if (breakpoint
->length
== 4)
2143 /* keep the original instruction in target endianness */
2144 target
->type
->read_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
);
2145 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2146 target_write_u32(target
, breakpoint
->address
, xscale
->arm_bkpt
);
2150 /* keep the original instruction in target endianness */
2151 target
->type
->read_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
);
2152 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2153 target_write_u32(target
, breakpoint
->address
, xscale
->thumb_bkpt
);
2155 breakpoint
->set
= 1;
2162 int xscale_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2164 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2165 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2167 if (target
->state
!= TARGET_HALTED
)
2169 WARNING("target not halted");
2170 return ERROR_TARGET_NOT_HALTED
;
2173 if (xscale
->force_hw_bkpts
)
2175 DEBUG("forcing use of hardware breakpoint at address 0x%8.8x", breakpoint
->address
);
2176 breakpoint
->type
= BKPT_HARD
;
2179 if ((breakpoint
->type
== BKPT_HARD
) && (xscale
->ibcr_available
< 1))
2181 INFO("no breakpoint unit available for hardware breakpoint");
2182 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2186 xscale
->ibcr_available
--;
2189 if ((breakpoint
->length
!= 2) && (breakpoint
->length
!= 4))
2191 INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
2192 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2198 int xscale_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2200 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2201 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2203 if (target
->state
!= TARGET_HALTED
)
2205 WARNING("target not halted");
2206 return ERROR_TARGET_NOT_HALTED
;
2209 if (!breakpoint
->set
)
2211 WARNING("breakpoint not set");
2215 if (breakpoint
->type
== BKPT_HARD
)
2217 if (breakpoint
->set
== 1)
2219 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], 0x0);
2220 xscale
->ibcr0_used
= 0;
2222 else if (breakpoint
->set
== 2)
2224 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], 0x0);
2225 xscale
->ibcr1_used
= 0;
2227 breakpoint
->set
= 0;
2231 /* restore original instruction (kept in target endianness) */
2232 if (breakpoint
->length
== 4)
2234 target
->type
->write_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
);
2238 target
->type
->write_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
);
2240 breakpoint
->set
= 0;
2246 int xscale_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2248 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2249 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2251 if (target
->state
!= TARGET_HALTED
)
2253 WARNING("target not halted");
2254 return ERROR_TARGET_NOT_HALTED
;
2257 if (breakpoint
->set
)
2259 xscale_unset_breakpoint(target
, breakpoint
);
2262 if (breakpoint
->type
== BKPT_HARD
)
2263 xscale
->ibcr_available
++;
2268 int xscale_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2270 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2271 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2273 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2274 u32 dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2276 if (target
->state
!= TARGET_HALTED
)
2278 WARNING("target not halted");
2279 return ERROR_TARGET_NOT_HALTED
;
2282 xscale_get_reg(dbcon
);
2284 switch (watchpoint
->rw
)
2296 ERROR("BUG: watchpoint->rw neither read, write nor access");
2299 if (!xscale
->dbr0_used
)
2301 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR0
], watchpoint
->address
);
2302 dbcon_value
|= enable
;
2303 xscale_set_reg_u32(dbcon
, dbcon_value
);
2304 watchpoint
->set
= 1;
2305 xscale
->dbr0_used
= 1;
2307 else if (!xscale
->dbr1_used
)
2309 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR1
], watchpoint
->address
);
2310 dbcon_value
|= enable
<< 2;
2311 xscale_set_reg_u32(dbcon
, dbcon_value
);
2312 watchpoint
->set
= 2;
2313 xscale
->dbr1_used
= 1;
2317 ERROR("BUG: no hardware comparator available");
2324 int xscale_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2326 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2327 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2329 if (target
->state
!= TARGET_HALTED
)
2331 WARNING("target not halted");
2332 return ERROR_TARGET_NOT_HALTED
;
2335 if (xscale
->dbr_available
< 1)
2337 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2340 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
2342 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2345 xscale
->dbr_available
--;
2350 int xscale_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2352 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2353 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2354 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2355 u32 dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2357 if (target
->state
!= TARGET_HALTED
)
2359 WARNING("target not halted");
2360 return ERROR_TARGET_NOT_HALTED
;
2363 if (!watchpoint
->set
)
2365 WARNING("breakpoint not set");
2369 if (watchpoint
->set
== 1)
2371 dbcon_value
&= ~0x3;
2372 xscale_set_reg_u32(dbcon
, dbcon_value
);
2373 xscale
->dbr0_used
= 0;
2375 else if (watchpoint
->set
== 2)
2377 dbcon_value
&= ~0xc;
2378 xscale_set_reg_u32(dbcon
, dbcon_value
);
2379 xscale
->dbr1_used
= 0;
2381 watchpoint
->set
= 0;
2386 int xscale_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2388 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2389 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2391 if (target
->state
!= TARGET_HALTED
)
2393 WARNING("target not halted");
2394 return ERROR_TARGET_NOT_HALTED
;
2397 if (watchpoint
->set
)
2399 xscale_unset_watchpoint(target
, watchpoint
);
2402 xscale
->dbr_available
++;
2407 void xscale_enable_watchpoints(struct target_s
*target
)
2409 watchpoint_t
*watchpoint
= target
->watchpoints
;
2413 if (watchpoint
->set
== 0)
2414 xscale_set_watchpoint(target
, watchpoint
);
2415 watchpoint
= watchpoint
->next
;
2419 void xscale_enable_breakpoints(struct target_s
*target
)
2421 breakpoint_t
*breakpoint
= target
->breakpoints
;
2423 /* set any pending breakpoints */
2426 if (breakpoint
->set
== 0)
2427 xscale_set_breakpoint(target
, breakpoint
);
2428 breakpoint
= breakpoint
->next
;
2432 int xscale_get_reg(reg_t
*reg
)
2434 xscale_reg_t
*arch_info
= reg
->arch_info
;
2435 target_t
*target
= arch_info
->target
;
2436 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2437 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2439 /* DCSR, TX and RX are accessible via JTAG */
2440 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2442 return xscale_read_dcsr(arch_info
->target
);
2444 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2446 /* 1 = consume register content */
2447 return xscale_read_tx(arch_info
->target
, 1);
2449 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2451 /* can't read from RX register (host -> debug handler) */
2454 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2456 /* can't (explicitly) read from TXRXCTRL register */
2459 else /* Other DBG registers have to be transfered by the debug handler */
2461 /* send CP read request (command 0x40) */
2462 xscale_send_u32(target
, 0x40);
2464 /* send CP register number */
2465 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2467 /* read register value */
2468 xscale_read_tx(target
, 1);
2469 buf_cpy(xscale
->reg_cache
->reg_list
[XSCALE_TX
].value
, reg
->value
, 32);
2478 int xscale_set_reg(reg_t
*reg
, u8
* buf
)
2480 xscale_reg_t
*arch_info
= reg
->arch_info
;
2481 target_t
*target
= arch_info
->target
;
2482 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2483 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2484 u32 value
= buf_get_u32(buf
, 0, 32);
2486 /* DCSR, TX and RX are accessible via JTAG */
2487 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2489 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32, value
);
2490 return xscale_write_dcsr(arch_info
->target
, -1, -1);
2492 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2494 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
2495 return xscale_write_rx(arch_info
->target
);
2497 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2499 /* can't write to TX register (debug-handler -> host) */
2502 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2504 /* can't (explicitly) write to TXRXCTRL register */
2507 else /* Other DBG registers have to be transfered by the debug handler */
2509 /* send CP write request (command 0x41) */
2510 xscale_send_u32(target
, 0x41);
2512 /* send CP register number */
2513 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2515 /* send CP register value */
2516 xscale_send_u32(target
, value
);
2517 buf_set_u32(reg
->value
, 0, 32, value
);
2523 /* convenience wrapper to access XScale specific registers */
2524 int xscale_set_reg_u32(reg_t
*reg
, u32 value
)
2528 buf_set_u32(buf
, 0, 32, value
);
2530 return xscale_set_reg(reg
, buf
);
2533 int xscale_write_dcsr_sw(target_t
*target
, u32 value
)
2535 /* get pointers to arch-specific information */
2536 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2537 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2538 reg_t
*dcsr
= &xscale
->reg_cache
->reg_list
[XSCALE_DCSR
];
2539 xscale_reg_t
*dcsr_arch_info
= dcsr
->arch_info
;
2541 /* send CP write request (command 0x41) */
2542 xscale_send_u32(target
, 0x41);
2544 /* send CP register number */
2545 xscale_send_u32(target
, dcsr_arch_info
->dbg_handler_number
);
2547 /* send CP register value */
2548 xscale_send_u32(target
, value
);
2549 buf_set_u32(dcsr
->value
, 0, 32, value
);
2554 int xscale_read_trace(target_t
*target
)
2556 /* get pointers to arch-specific information */
2557 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2558 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2559 xscale_trace_data_t
**trace_data_p
;
2561 /* 258 words from debug handler
2562 * 256 trace buffer entries
2563 * 2 checkpoint addresses
2565 u32 trace_buffer
[258];
2566 int is_address
[256];
2569 if (target
->state
!= TARGET_HALTED
)
2571 WARNING("target must be stopped to read trace data");
2572 return ERROR_TARGET_NOT_HALTED
;
2575 /* send read trace buffer command (command 0x61) */
2576 xscale_send_u32(target
, 0x61);
2578 /* receive trace buffer content */
2579 xscale_receive(target
, trace_buffer
, 258);
2581 /* parse buffer backwards to identify address entries */
2582 for (i
= 255; i
>= 0; i
--)
2585 if (((trace_buffer
[i
] & 0xf0) == 0x90) ||
2586 ((trace_buffer
[i
] & 0xf0) == 0xd0))
2589 is_address
[--i
] = 1;
2591 is_address
[--i
] = 1;
2593 is_address
[--i
] = 1;
2595 is_address
[--i
] = 1;
2600 /* search first non-zero entry */
2601 for (j
= 0; (j
< 256) && (trace_buffer
[j
] == 0) && (!is_address
[j
]); j
++)
2606 DEBUG("no trace data collected");
2607 return ERROR_XSCALE_NO_TRACE_DATA
;
2610 for (trace_data_p
= &xscale
->trace
.data
; *trace_data_p
; trace_data_p
= &(*trace_data_p
)->next
)
2613 *trace_data_p
= malloc(sizeof(xscale_trace_data_t
));
2614 (*trace_data_p
)->next
= NULL
;
2615 (*trace_data_p
)->chkpt0
= trace_buffer
[256];
2616 (*trace_data_p
)->chkpt1
= trace_buffer
[257];
2617 (*trace_data_p
)->last_instruction
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
2618 (*trace_data_p
)->entries
= malloc(sizeof(xscale_trace_entry_t
) * (256 - j
));
2619 (*trace_data_p
)->depth
= 256 - j
;
2621 for (i
= j
; i
< 256; i
++)
2623 (*trace_data_p
)->entries
[i
- j
].data
= trace_buffer
[i
];
2625 (*trace_data_p
)->entries
[i
- j
].type
= XSCALE_TRACE_ADDRESS
;
2627 (*trace_data_p
)->entries
[i
- j
].type
= XSCALE_TRACE_MESSAGE
;
2633 int xscale_read_instruction(target_t
*target
, arm_instruction_t
*instruction
)
2635 /* get pointers to arch-specific information */
2636 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2637 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2644 if (!xscale
->trace
.image
)
2645 return ERROR_TRACE_IMAGE_UNAVAILABLE
;
2647 /* search for the section the current instruction belongs to */
2648 for (i
= 0; i
< xscale
->trace
.image
->num_sections
; i
++)
2650 if ((xscale
->trace
.image
->sections
[i
].base_address
<= xscale
->trace
.current_pc
) &&
2651 (xscale
->trace
.image
->sections
[i
].base_address
+ xscale
->trace
.image
->sections
[i
].size
> xscale
->trace
.current_pc
))
2660 /* current instruction couldn't be found in the image */
2661 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2664 if (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
)
2667 if ((retval
= image_read_section(xscale
->trace
.image
, section
,
2668 xscale
->trace
.current_pc
- xscale
->trace
.image
->sections
[section
].base_address
,
2669 4, buf
, &size_read
)) != ERROR_OK
)
2671 ERROR("error while reading instruction: %i", retval
);
2672 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2674 opcode
= target_buffer_get_u32(target
, buf
);
2675 arm_evaluate_opcode(opcode
, xscale
->trace
.current_pc
, instruction
);
2677 else if (xscale
->trace
.core_state
== ARMV4_5_STATE_THUMB
)
2680 if ((retval
= image_read_section(xscale
->trace
.image
, section
,
2681 xscale
->trace
.current_pc
- xscale
->trace
.image
->sections
[section
].base_address
,
2682 2, buf
, &size_read
)) != ERROR_OK
)
2684 ERROR("error while reading instruction: %i", retval
);
2685 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2687 opcode
= target_buffer_get_u16(target
, buf
);
2688 thumb_evaluate_opcode(opcode
, xscale
->trace
.current_pc
, instruction
);
2692 ERROR("BUG: unknown core state encountered");
2699 int xscale_branch_address(xscale_trace_data_t
*trace_data
, int i
, u32
*target
)
2701 /* if there are less than four entries prior to the indirect branch message
2702 * we can't extract the address */
2708 *target
= (trace_data
->entries
[i
-1].data
) | (trace_data
->entries
[i
-2].data
<< 8) |
2709 (trace_data
->entries
[i
-3].data
<< 16) | (trace_data
->entries
[i
-4].data
<< 24);
2714 int xscale_analyze_trace(target_t
*target
, command_context_t
*cmd_ctx
)
2716 /* get pointers to arch-specific information */
2717 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2718 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2721 xscale_trace_data_t
*trace_data
= xscale
->trace
.data
;
2730 xscale
->trace
.core_state
= ARMV4_5_STATE_ARM
;
2735 for (i
= 0; i
< trace_data
->depth
; i
++)
2741 if (trace_data
->entries
[i
].type
== XSCALE_TRACE_ADDRESS
)
2744 switch ((trace_data
->entries
[i
].data
& 0xf0) >> 4)
2746 case 0: /* Exceptions */
2754 exception
= (trace_data
->entries
[i
].data
& 0x70) >> 4;
2756 next_pc
= (trace_data
->entries
[i
].data
& 0xf0) >> 2;
2757 command_print(cmd_ctx
, "--- exception %i ---", (trace_data
->entries
[i
].data
& 0xf0) >> 4);
2759 case 8: /* Direct Branch */
2762 case 9: /* Indirect Branch */
2764 if (xscale_branch_address(trace_data
, i
, &next_pc
) == 0)
2769 case 13: /* Checkpointed Indirect Branch */
2770 if (xscale_branch_address(trace_data
, i
, &next_pc
) == 0)
2773 if (((chkpt
== 0) && (next_pc
!= trace_data
->chkpt0
))
2774 || ((chkpt
== 1) && (next_pc
!= trace_data
->chkpt1
)))
2775 WARNING("checkpointed indirect branch target address doesn't match checkpoint");
2777 /* explicit fall-through */
2778 case 12: /* Checkpointed Direct Branch */
2783 next_pc
= trace_data
->chkpt0
;
2786 else if (chkpt
== 1)
2789 next_pc
= trace_data
->chkpt0
;
2794 WARNING("more than two checkpointed branches encountered");
2797 case 15: /* Roll-over */
2800 default: /* Reserved */
2801 command_print(cmd_ctx
, "--- reserved trace message ---");
2802 ERROR("BUG: trace message %i is reserved", (trace_data
->entries
[i
].data
& 0xf0) >> 4);
2806 if (xscale
->trace
.pc_ok
)
2808 int executed
= (trace_data
->entries
[i
].data
& 0xf) + rollover
* 16;
2809 arm_instruction_t instruction
;
2811 if ((exception
== 6) || (exception
== 7))
2813 /* IRQ or FIQ exception, no instruction executed */
2817 while (executed
-- >= 0)
2819 if ((retval
= xscale_read_instruction(target
, &instruction
)) != ERROR_OK
)
2821 /* can't continue tracing with no image available */
2822 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
2826 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
2828 /* TODO: handle incomplete images */
2832 /* a precise abort on a load to the PC is included in the incremental
2833 * word count, other instructions causing data aborts are not included
2835 if ((executed
== 0) && (exception
== 4)
2836 && ((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_LDM
)))
2838 if ((instruction
.type
== ARM_LDM
)
2839 && ((instruction
.info
.load_store_multiple
.register_list
& 0x8000) == 0))
2843 else if (((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_LDRSH
))
2844 && (instruction
.info
.load_store
.Rd
!= 15))
2850 /* only the last instruction executed
2851 * (the one that caused the control flow change)
2852 * could be a taken branch
2854 if (((executed
== -1) && (branch
== 1)) &&
2855 (((instruction
.type
== ARM_B
) ||
2856 (instruction
.type
== ARM_BL
) ||
2857 (instruction
.type
== ARM_BLX
)) &&
2858 (instruction
.info
.b_bl_bx_blx
.target_address
!= -1)))
2860 xscale
->trace
.current_pc
= instruction
.info
.b_bl_bx_blx
.target_address
;
2864 xscale
->trace
.current_pc
+= (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2;
2866 command_print(cmd_ctx
, "%s", instruction
.text
);
2874 xscale
->trace
.current_pc
= next_pc
;
2875 xscale
->trace
.pc_ok
= 1;
2879 for (; xscale
->trace
.current_pc
< trace_data
->last_instruction
; xscale
->trace
.current_pc
+= (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2)
2881 arm_instruction_t instruction
;
2882 if ((retval
= xscale_read_instruction(target
, &instruction
)) != ERROR_OK
)
2884 /* can't continue tracing with no image available */
2885 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
2889 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
2891 /* TODO: handle incomplete images */
2894 command_print(cmd_ctx
, "%s", instruction
.text
);
2897 trace_data
= trace_data
->next
;
2903 void xscale_build_reg_cache(target_t
*target
)
2905 /* get pointers to arch-specific information */
2906 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2907 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2909 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
2910 xscale_reg_t
*arch_info
= malloc(sizeof(xscale_reg_arch_info
));
2912 int num_regs
= sizeof(xscale_reg_arch_info
) / sizeof(xscale_reg_t
);
2914 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
2915 armv4_5
->core_cache
= (*cache_p
);
2917 /* register a register arch-type for XScale dbg registers only once */
2918 if (xscale_reg_arch_type
== -1)
2919 xscale_reg_arch_type
= register_reg_arch_type(xscale_get_reg
, xscale_set_reg
);
2921 (*cache_p
)->next
= malloc(sizeof(reg_cache_t
));
2922 cache_p
= &(*cache_p
)->next
;
2924 /* fill in values for the xscale reg cache */
2925 (*cache_p
)->name
= "XScale registers";
2926 (*cache_p
)->next
= NULL
;
2927 (*cache_p
)->reg_list
= malloc(num_regs
* sizeof(reg_t
));
2928 (*cache_p
)->num_regs
= num_regs
;
2930 for (i
= 0; i
< num_regs
; i
++)
2932 (*cache_p
)->reg_list
[i
].name
= xscale_reg_list
[i
];
2933 (*cache_p
)->reg_list
[i
].value
= calloc(4, 1);
2934 (*cache_p
)->reg_list
[i
].dirty
= 0;
2935 (*cache_p
)->reg_list
[i
].valid
= 0;
2936 (*cache_p
)->reg_list
[i
].size
= 32;
2937 (*cache_p
)->reg_list
[i
].bitfield_desc
= NULL
;
2938 (*cache_p
)->reg_list
[i
].num_bitfields
= 0;
2939 (*cache_p
)->reg_list
[i
].arch_info
= &arch_info
[i
];
2940 (*cache_p
)->reg_list
[i
].arch_type
= xscale_reg_arch_type
;
2941 arch_info
[i
] = xscale_reg_arch_info
[i
];
2942 arch_info
[i
].target
= target
;
2945 xscale
->reg_cache
= (*cache_p
);
2948 int xscale_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
2950 if (startup_mode
!= DAEMON_RESET
)
2952 ERROR("XScale target requires a reset");
2953 ERROR("Reset target to enable debug");
2956 /* assert TRST once during startup */
2957 jtag_add_reset(1, 0);
2958 jtag_add_sleep(5000);
2959 jtag_add_reset(0, 0);
2960 jtag_execute_queue();
2971 int xscale_init_arch_info(target_t
*target
, xscale_common_t
*xscale
, int chain_pos
, char *variant
)
2973 armv4_5_common_t
*armv4_5
;
2974 u32 high_reset_branch
, low_reset_branch
;
2977 armv4_5
= &xscale
->armv4_5_common
;
2979 /* store architecture specfic data (none so far) */
2980 xscale
->arch_info
= NULL
;
2981 xscale
->common_magic
= XSCALE_COMMON_MAGIC
;
2983 /* remember the variant (PXA25x, PXA27x, IXP42x, ...) */
2984 xscale
->variant
= strdup(variant
);
2986 /* prepare JTAG information for the new target */
2987 xscale
->jtag_info
.chain_pos
= chain_pos
;
2988 jtag_register_event_callback(xscale_jtag_callback
, target
);
2990 xscale
->jtag_info
.dbgrx
= 0x02;
2991 xscale
->jtag_info
.dbgtx
= 0x10;
2992 xscale
->jtag_info
.dcsr
= 0x09;
2993 xscale
->jtag_info
.ldic
= 0x07;
2995 if ((strcmp(xscale
->variant
, "pxa250") == 0) ||
2996 (strcmp(xscale
->variant
, "pxa255") == 0) ||
2997 (strcmp(xscale
->variant
, "pxa26x") == 0))
2999 xscale
->jtag_info
.ir_length
= 5;
3001 else if ((strcmp(xscale
->variant
, "pxa27x") == 0) ||
3002 (strcmp(xscale
->variant
, "ixp42x") == 0) ||
3003 (strcmp(xscale
->variant
, "ixp45x") == 0) ||
3004 (strcmp(xscale
->variant
, "ixp46x") == 0))
3006 xscale
->jtag_info
.ir_length
= 7;
3009 /* the debug handler isn't installed (and thus not running) at this time */
3010 xscale
->handler_installed
= 0;
3011 xscale
->handler_running
= 0;
3012 xscale
->handler_address
= 0xfe000800;
3014 /* clear the vectors we keep locally for reference */
3015 memset(xscale
->low_vectors
, 0, sizeof(xscale
->low_vectors
));
3016 memset(xscale
->high_vectors
, 0, sizeof(xscale
->high_vectors
));
3018 /* no user-specified vectors have been configured yet */
3019 xscale
->static_low_vectors_set
= 0x0;
3020 xscale
->static_high_vectors_set
= 0x0;
3022 /* calculate branches to debug handler */
3023 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
3024 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
3026 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
3027 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
3029 for (i
= 1; i
<= 7; i
++)
3031 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
3032 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
3035 /* 64kB aligned region used for DCache cleaning */
3036 xscale
->cache_clean_address
= 0xfffe0000;
3038 xscale
->hold_rst
= 0;
3039 xscale
->external_debug_break
= 0;
3041 xscale
->force_hw_bkpts
= 1;
3043 xscale
->ibcr_available
= 2;
3044 xscale
->ibcr0_used
= 0;
3045 xscale
->ibcr1_used
= 0;
3047 xscale
->dbr_available
= 2;
3048 xscale
->dbr0_used
= 0;
3049 xscale
->dbr1_used
= 0;
3051 xscale
->arm_bkpt
= ARMV5_BKPT(0x0);
3052 xscale
->thumb_bkpt
= ARMV5_T_BKPT(0x0) & 0xffff;
3054 xscale
->vector_catch
= 0x1;
3056 xscale
->trace
.capture_status
= TRACE_IDLE
;
3057 xscale
->trace
.data
= NULL
;
3058 xscale
->trace
.image
= NULL
;
3059 xscale
->trace
.buffer_enabled
= 0;
3060 xscale
->trace
.buffer_fill
= 0;
3062 /* prepare ARMv4/5 specific information */
3063 armv4_5
->arch_info
= xscale
;
3064 armv4_5
->read_core_reg
= xscale_read_core_reg
;
3065 armv4_5
->write_core_reg
= xscale_write_core_reg
;
3066 armv4_5
->full_context
= xscale_full_context
;
3068 armv4_5_init_arch_info(target
, armv4_5
);
3070 xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
3071 xscale
->armv4_5_mmu
.get_ttb
= xscale_get_ttb
;
3072 xscale
->armv4_5_mmu
.read_memory
= xscale_read_memory
;
3073 xscale
->armv4_5_mmu
.write_memory
= xscale_write_memory
;
3074 xscale
->armv4_5_mmu
.disable_mmu_caches
= xscale_disable_mmu_caches
;
3075 xscale
->armv4_5_mmu
.enable_mmu_caches
= xscale_enable_mmu_caches
;
3076 xscale
->armv4_5_mmu
.has_tiny_pages
= 1;
3077 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3082 /* target xscale <endianess> <startup_mode> <chain_pos> <variant> */
3083 int xscale_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
)
3086 char *variant
= NULL
;
3087 xscale_common_t
*xscale
= malloc(sizeof(xscale_common_t
));
3091 ERROR("'target xscale' requires four arguments: <endianess> <startup_mode> <chain_pos> <variant>");
3095 chain_pos
= strtoul(args
[3], NULL
, 0);
3099 xscale_init_arch_info(target
, xscale
, chain_pos
, variant
);
3100 xscale_build_reg_cache(target
);
3105 int xscale_handle_debug_handler_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3107 target_t
*target
= NULL
;
3108 armv4_5_common_t
*armv4_5
;
3109 xscale_common_t
*xscale
;
3111 u32 handler_address
;
3115 ERROR("'xscale debug_handler <target#> <address>' command takes two required operands");
3119 if ((target
= get_target_by_num(strtoul(args
[0], NULL
, 0))) == NULL
)
3121 ERROR("no target '%s' configured", args
[0]);
3125 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3127 command_print(cmd_ctx
, "target isn't an ARM920t target");
3131 handler_address
= strtoul(args
[1], NULL
, 0);
3133 if (((handler_address
>= 0x800) && (handler_address
<= 0x1fef800)) ||
3134 ((handler_address
>= 0xfe000800) && (handler_address
<= 0xfffff800)))
3136 xscale
->handler_address
= handler_address
;
3140 ERROR("xscale debug_handler <address> must be between 0x800 and 0x1fef800 or between 0xfe000800 and 0xfffff800");
3146 int xscale_handle_cache_clean_address_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3148 target_t
*target
= NULL
;
3149 armv4_5_common_t
*armv4_5
;
3150 xscale_common_t
*xscale
;
3152 u32 cache_clean_address
;
3156 ERROR("'xscale cache_clean_address <target#> <address>' command takes two required operands");
3160 if ((target
= get_target_by_num(strtoul(args
[0], NULL
, 0))) == NULL
)
3162 ERROR("no target '%s' configured", args
[0]);
3166 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3168 command_print(cmd_ctx
, "target isn't an XScale target");
3172 cache_clean_address
= strtoul(args
[1], NULL
, 0);
3174 if (cache_clean_address
& 0xffff)
3176 ERROR("xscale cache_clean_address <address> must be 64kb aligned");
3180 xscale
->cache_clean_address
= cache_clean_address
;
3186 int xscale_handle_cache_info_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3188 target_t
*target
= get_current_target(cmd_ctx
);
3189 armv4_5_common_t
*armv4_5
;
3190 xscale_common_t
*xscale
;
3192 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3194 command_print(cmd_ctx
, "target isn't an XScale target");
3198 return armv4_5_handle_cache_info_command(cmd_ctx
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
3201 int xscale_handle_virt2phys_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3203 target_t
*target
= get_current_target(cmd_ctx
);
3204 armv4_5_common_t
*armv4_5
;
3205 xscale_common_t
*xscale
;
3207 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3209 command_print(cmd_ctx
, "target isn't an XScale target");
3213 if (target
->state
!= TARGET_HALTED
)
3215 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3219 return armv4_5_mmu_handle_virt2phys_command(cmd_ctx
, cmd
, args
, argc
, target
, &xscale
->armv4_5_mmu
);
3222 int xscale_handle_mmu_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3224 target_t
*target
= get_current_target(cmd_ctx
);
3225 armv4_5_common_t
*armv4_5
;
3226 xscale_common_t
*xscale
;
3228 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3230 command_print(cmd_ctx
, "target isn't an XScale target");
3234 if (target
->state
!= TARGET_HALTED
)
3236 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3242 if (strcmp("enable", args
[0]) == 0)
3244 xscale_enable_mmu_caches(target
, 1, 0, 0);
3245 xscale
->armv4_5_mmu
.mmu_enabled
= 1;
3247 else if (strcmp("disable", args
[0]) == 0)
3249 xscale_disable_mmu_caches(target
, 1, 0, 0);
3250 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3254 command_print(cmd_ctx
, "mmu %s", (xscale
->armv4_5_mmu
.mmu_enabled
) ? "enabled" : "disabled");
3259 int xscale_handle_idcache_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3261 target_t
*target
= get_current_target(cmd_ctx
);
3262 armv4_5_common_t
*armv4_5
;
3263 xscale_common_t
*xscale
;
3264 int icache
= 0, dcache
= 0;
3266 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3268 command_print(cmd_ctx
, "target isn't an XScale target");
3272 if (target
->state
!= TARGET_HALTED
)
3274 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3278 if (strcmp(cmd
, "icache") == 0)
3280 else if (strcmp(cmd
, "dcache") == 0)
3285 if (strcmp("enable", args
[0]) == 0)
3287 xscale_enable_mmu_caches(target
, 0, dcache
, icache
);
3290 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 1;
3292 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 1;
3294 else if (strcmp("disable", args
[0]) == 0)
3296 xscale_disable_mmu_caches(target
, 0, dcache
, icache
);
3299 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 0;
3301 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 0;
3306 command_print(cmd_ctx
, "icache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
) ? "enabled" : "disabled");
3309 command_print(cmd_ctx
, "dcache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
) ? "enabled" : "disabled");
3314 int xscale_handle_vector_catch_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3316 target_t
*target
= get_current_target(cmd_ctx
);
3317 armv4_5_common_t
*armv4_5
;
3318 xscale_common_t
*xscale
;
3320 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3322 command_print(cmd_ctx
, "target isn't an XScale target");
3328 command_print(cmd_ctx
, "usage: xscale vector_catch [mask]");
3332 xscale
->vector_catch
= strtoul(args
[0], NULL
, 0);
3333 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 8, xscale
->vector_catch
);
3334 xscale_write_dcsr(target
, -1, -1);
3337 command_print(cmd_ctx
, "vector catch mask: 0x%2.2x", xscale
->vector_catch
);
3342 int xscale_handle_force_hw_bkpts_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3344 target_t
*target
= get_current_target(cmd_ctx
);
3345 armv4_5_common_t
*armv4_5
;
3346 xscale_common_t
*xscale
;
3348 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3350 command_print(cmd_ctx
, "target isn't an XScale target");
3354 if ((argc
>= 1) && (strcmp("enable", args
[0]) == 0))
3356 xscale
->force_hw_bkpts
= 1;
3358 else if ((argc
>= 1) && (strcmp("disable", args
[0]) == 0))
3360 xscale
->force_hw_bkpts
= 0;
3364 command_print(cmd_ctx
, "usage: xscale force_hw_bkpts <enable|disable>");
3367 command_print(cmd_ctx
, "force hardware breakpoints %s", (xscale
->force_hw_bkpts
) ? "enabled" : "disabled");
3372 int xscale_handle_trace_buffer_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3374 target_t
*target
= get_current_target(cmd_ctx
);
3375 armv4_5_common_t
*armv4_5
;
3376 xscale_common_t
*xscale
;
3379 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3381 command_print(cmd_ctx
, "target isn't an XScale target");
3385 if (target
->state
!= TARGET_HALTED
)
3387 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3391 if ((argc
>= 1) && (strcmp("enable", args
[0]) == 0))
3393 xscale_trace_data_t
*td
, *next_td
;
3394 xscale
->trace
.buffer_enabled
= 1;
3396 /* free old trace data */
3397 td
= xscale
->trace
.data
;
3407 xscale
->trace
.data
= NULL
;
3409 else if ((argc
>= 1) && (strcmp("disable", args
[0]) == 0))
3411 xscale
->trace
.buffer_enabled
= 0;
3414 if ((argc
>= 2) && (strcmp("fill", args
[1]) == 0))
3417 xscale
->trace
.buffer_fill
= strtoul(args
[2], NULL
, 0);
3419 xscale
->trace
.buffer_fill
= 1;
3421 else if ((argc
>= 2) && (strcmp("wrap", args
[1]) == 0))
3423 xscale
->trace
.buffer_fill
= -1;
3426 if (xscale
->trace
.buffer_enabled
)
3428 /* if we enable the trace buffer in fill-once
3429 * mode we know the address of the first instruction */
3430 xscale
->trace
.pc_ok
= 1;
3431 xscale
->trace
.current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
3435 /* otherwise the address is unknown, and we have no known good PC */
3436 xscale
->trace
.pc_ok
= 0;
3439 command_print(cmd_ctx
, "trace buffer %s (%s)",
3440 (xscale
->trace
.buffer_enabled
) ? "enabled" : "disabled",
3441 (xscale
->trace
.buffer_fill
> 0) ? "fill" : "wrap");
3443 dcsr_value
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32);
3444 if (xscale
->trace
.buffer_fill
>= 0)
3445 xscale_write_dcsr_sw(target
, (dcsr_value
& 0xfffffffc) | 2);
3447 xscale_write_dcsr_sw(target
, dcsr_value
& 0xfffffffc);
3452 int xscale_handle_trace_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3455 armv4_5_common_t
*armv4_5
;
3456 xscale_common_t
*xscale
;
3460 command_print(cmd_ctx
, "usage: xscale trace_image <file> [base address] [type]");
3464 target
= get_current_target(cmd_ctx
);
3466 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3468 command_print(cmd_ctx
, "target isn't an XScale target");
3472 if (xscale
->trace
.image
)
3474 image_close(xscale
->trace
.image
);
3475 free(xscale
->trace
.image
);
3476 command_print(cmd_ctx
, "previously loaded image found and closed");
3479 xscale
->trace
.image
= malloc(sizeof(image_t
));
3480 xscale
->trace
.image
->base_address_set
= 0;
3481 xscale
->trace
.image
->start_address_set
= 0;
3483 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
3486 xscale
->trace
.image
->base_address_set
= 1;
3487 xscale
->trace
.image
->base_address
= strtoul(args
[1], NULL
, 0);
3491 xscale
->trace
.image
->base_address_set
= 0;
3494 if (image_open(xscale
->trace
.image
, args
[0], (argc
>= 3) ? args
[2] : NULL
) != ERROR_OK
)
3496 command_print(cmd_ctx
, "image opening error: %s", xscale
->trace
.image
->error_str
);
3497 free(xscale
->trace
.image
);
3498 xscale
->trace
.image
= NULL
;
3505 int xscale_handle_dump_trace_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3507 target_t
*target
= get_current_target(cmd_ctx
);
3508 armv4_5_common_t
*armv4_5
;
3509 xscale_common_t
*xscale
;
3510 xscale_trace_data_t
*trace_data
;
3513 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3515 command_print(cmd_ctx
, "target isn't an XScale target");
3519 if (target
->state
!= TARGET_HALTED
)
3521 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3527 command_print(cmd_ctx
, "usage: xscale dump_trace <file>");
3531 trace_data
= xscale
->trace
.data
;
3535 command_print(cmd_ctx
, "no trace data collected");
3539 if (fileio_open(&file
, args
[0], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
)
3541 command_print(cmd_ctx
, "file open error: %s", file
.error_str
);
3549 fileio_write_u32(&file
, trace_data
->chkpt0
);
3550 fileio_write_u32(&file
, trace_data
->chkpt1
);
3551 fileio_write_u32(&file
, trace_data
->last_instruction
);
3552 fileio_write_u32(&file
, trace_data
->depth
);
3554 for (i
= 0; i
< trace_data
->depth
; i
++)
3555 fileio_write_u32(&file
, trace_data
->entries
[i
].data
| ((trace_data
->entries
[i
].type
& 0xffff) << 16));
3557 trace_data
= trace_data
->next
;
3560 fileio_close(&file
);
3565 int xscale_handle_analyze_trace_buffer_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3567 target_t
*target
= get_current_target(cmd_ctx
);
3568 armv4_5_common_t
*armv4_5
;
3569 xscale_common_t
*xscale
;
3571 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3573 command_print(cmd_ctx
, "target isn't an XScale target");
3577 xscale_analyze_trace(target
, cmd_ctx
);
3582 int xscale_handle_cp15(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3584 target_t
*target
= get_current_target(cmd_ctx
);
3585 armv4_5_common_t
*armv4_5
;
3586 xscale_common_t
*xscale
;
3588 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3590 command_print(cmd_ctx
, "target isn't an XScale target");
3594 if (target
->state
!= TARGET_HALTED
)
3596 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3603 reg_no
= strtoul(args
[0], NULL
, 0);
3604 /*translate from xscale cp15 register no to openocd register*/
3608 reg_no
= XSCALE_MAINID
;
3611 reg_no
= XSCALE_CTRL
;
3614 reg_no
= XSCALE_TTB
;
3617 reg_no
= XSCALE_DAC
;
3620 reg_no
= XSCALE_FSR
;
3623 reg_no
= XSCALE_FAR
;
3626 reg_no
= XSCALE_PID
;
3629 reg_no
= XSCALE_CPACCESS
;
3632 command_print(cmd_ctx
, "invalid register number");
3633 return ERROR_INVALID_ARGUMENTS
;
3635 reg
= &xscale
->reg_cache
->reg_list
[reg_no
];
3642 /* read cp15 control register */
3643 xscale_get_reg(reg
);
3644 value
= buf_get_u32(reg
->value
, 0, 32);
3645 command_print(cmd_ctx
, "%s (/%i): 0x%x", reg
->name
, reg
->size
, value
);
3650 u32 value
= strtoul(args
[1], NULL
, 0);
3652 /* send CP write request (command 0x41) */
3653 xscale_send_u32(target
, 0x41);
3655 /* send CP register number */
3656 xscale_send_u32(target
, reg_no
);
3658 /* send CP register value */
3659 xscale_send_u32(target
, value
);
3661 /* execute cpwait to ensure outstanding operations complete */
3662 xscale_send_u32(target
, 0x53);
3666 command_print(cmd_ctx
, "usage: cp15 [register]<, [value]>");
3672 int xscale_register_commands(struct command_context_s
*cmd_ctx
)
3674 command_t
*xscale_cmd
;
3676 xscale_cmd
= register_command(cmd_ctx
, NULL
, "xscale", NULL
, COMMAND_ANY
, "xscale specific commands");
3678 register_command(cmd_ctx
, xscale_cmd
, "debug_handler", xscale_handle_debug_handler_command
, COMMAND_CONFIG
, NULL
);
3679 register_command(cmd_ctx
, xscale_cmd
, "cache_clean_address", xscale_handle_cache_clean_address_command
, COMMAND_ANY
, NULL
);
3681 register_command(cmd_ctx
, xscale_cmd
, "cache_info", xscale_handle_cache_info_command
, COMMAND_EXEC
, NULL
);
3682 register_command(cmd_ctx
, xscale_cmd
, "virt2phys", xscale_handle_virt2phys_command
, COMMAND_EXEC
, NULL
);
3683 register_command(cmd_ctx
, xscale_cmd
, "mmu", xscale_handle_mmu_command
, COMMAND_EXEC
, "['enable'|'disable'] the MMU");
3684 register_command(cmd_ctx
, xscale_cmd
, "icache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the ICache");
3685 register_command(cmd_ctx
, xscale_cmd
, "dcache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the DCache");
3687 register_command(cmd_ctx
, xscale_cmd
, "vector_catch", xscale_handle_idcache_command
, COMMAND_EXEC
, "<mask> of vectors that should be catched");
3689 register_command(cmd_ctx
, xscale_cmd
, "trace_buffer", xscale_handle_trace_buffer_command
, COMMAND_EXEC
, "<enable|disable> ['fill' [n]|'wrap']");
3691 register_command(cmd_ctx
, xscale_cmd
, "dump_trace", xscale_handle_dump_trace_command
, COMMAND_EXEC
, "dump content of trace buffer to <file>");
3692 register_command(cmd_ctx
, xscale_cmd
, "analyze_trace", xscale_handle_analyze_trace_buffer_command
, COMMAND_EXEC
, "analyze content of trace buffer");
3693 register_command(cmd_ctx
, xscale_cmd
, "trace_image", xscale_handle_trace_image_command
,
3694 COMMAND_EXEC
, "load image from <file> [base address]");
3696 register_command(cmd_ctx
, xscale_cmd
, "cp15", xscale_handle_cp15
, COMMAND_EXEC
, "access coproc 15 <register> [value]");
3698 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)