1 /***************************************************************************
2 * Copyright (C) 2006 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"
34 #include "binarybuffer.h"
35 #include "time_support.h"
36 #include "breakpoints.h"
41 #include <sys/types.h>
47 int xscale_register_commands(struct command_context_s
*cmd_ctx
);
49 /* forward declarations */
50 int xscale_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
);
51 int xscale_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
);
54 int xscale_arch_state(struct target_s
*target
, char *buf
, int buf_size
);
55 enum target_state
xscale_poll(target_t
*target
);
56 int xscale_halt(target_t
*target
);
57 int xscale_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
);
58 int xscale_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
);
59 int xscale_debug_entry(target_t
*target
);
60 int xscale_restore_context(target_t
*target
);
62 int xscale_assert_reset(target_t
*target
);
63 int xscale_deassert_reset(target_t
*target
);
64 int xscale_soft_reset_halt(struct target_s
*target
);
65 int xscale_prepare_reset_halt(struct target_s
*target
);
67 int xscale_set_reg_u32(reg_t
*reg
, u32 value
);
69 int xscale_read_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
);
70 int xscale_write_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
, u32 value
);
72 int xscale_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
);
73 int xscale_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
);
74 int xscale_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
);
76 int xscale_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
77 int xscale_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
78 int xscale_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
79 int xscale_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
80 int xscale_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
);
81 int xscale_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
);
82 void xscale_enable_watchpoints(struct target_s
*target
);
83 void xscale_enable_breakpoints(struct target_s
*target
);
85 target_type_t xscale_target
=
90 .arch_state
= xscale_arch_state
,
93 .resume
= xscale_resume
,
96 .assert_reset
= xscale_assert_reset
,
97 .deassert_reset
= xscale_deassert_reset
,
98 .soft_reset_halt
= xscale_soft_reset_halt
,
99 .prepare_reset_halt
= xscale_prepare_reset_halt
,
101 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
103 .read_memory
= xscale_read_memory
,
104 .write_memory
= xscale_write_memory
,
105 .bulk_write_memory
= xscale_bulk_write_memory
,
107 .run_algorithm
= armv4_5_run_algorithm
,
109 .add_breakpoint
= xscale_add_breakpoint
,
110 .remove_breakpoint
= xscale_remove_breakpoint
,
111 .add_watchpoint
= xscale_add_watchpoint
,
112 .remove_watchpoint
= xscale_remove_watchpoint
,
114 .register_commands
= xscale_register_commands
,
115 .target_command
= xscale_target_command
,
116 .init_target
= xscale_init_target
,
120 char* xscale_reg_list
[] =
122 "XSCALE_MAINID", /* 0 */
132 "XSCALE_IBCR0", /* 10 */
142 "XSCALE_RX", /* 20 */
146 xscale_reg_t xscale_reg_arch_info
[] =
148 {XSCALE_MAINID
, NULL
},
149 {XSCALE_CACHETYPE
, NULL
},
151 {XSCALE_AUXCTRL
, NULL
},
157 {XSCALE_CPACCESS
, NULL
},
158 {XSCALE_IBCR0
, NULL
},
159 {XSCALE_IBCR1
, NULL
},
162 {XSCALE_DBCON
, NULL
},
163 {XSCALE_TBREG
, NULL
},
164 {XSCALE_CHKPT0
, NULL
},
165 {XSCALE_CHKPT1
, NULL
},
166 {XSCALE_DCSR
, NULL
}, /* DCSR accessed via JTAG or SW */
167 {-1, NULL
}, /* TX accessed via JTAG */
168 {-1, NULL
}, /* RX accessed via JTAG */
169 {-1, NULL
}, /* TXRXCTRL implicit access via JTAG */
172 int xscale_reg_arch_type
= -1;
174 int xscale_get_reg(reg_t
*reg
);
175 int xscale_set_reg(reg_t
*reg
, u8
*buf
);
177 int xscale_get_arch_pointers(target_t
*target
, armv4_5_common_t
**armv4_5_p
, xscale_common_t
**xscale_p
)
179 armv4_5_common_t
*armv4_5
= target
->arch_info
;
180 xscale_common_t
*xscale
= armv4_5
->arch_info
;
182 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
187 if (xscale
->common_magic
!= XSCALE_COMMON_MAGIC
)
192 *armv4_5_p
= armv4_5
;
198 int xscale_jtag_set_instr(int chain_pos
, u32 new_instr
)
200 jtag_device_t
*device
= jtag_get_device(chain_pos
);
202 if (buf_get_u32(device
->cur_instr
, 0, device
->ir_length
) != new_instr
)
206 field
.device
= chain_pos
;
207 field
.num_bits
= device
->ir_length
;
208 field
.out_value
= calloc(CEIL(field
.num_bits
, 8), 1);
209 buf_set_u32(field
.out_value
, 0, field
.num_bits
, new_instr
);
210 field
.out_mask
= NULL
;
211 field
.in_value
= NULL
;
212 field
.in_check_value
= device
->expected
;
213 field
.in_check_mask
= device
->expected_mask
;
214 field
.in_handler
= NULL
;
215 field
.in_handler_priv
= NULL
;
217 jtag_add_ir_scan(1, &field
, -1, NULL
);
219 free(field
.out_value
);
225 int xscale_jtag_callback(enum jtag_event event
, void *priv
)
229 case JTAG_TRST_ASSERTED
:
231 case JTAG_TRST_RELEASED
:
233 case JTAG_SRST_ASSERTED
:
235 case JTAG_SRST_RELEASED
:
238 WARNING("unhandled JTAG event");
244 int xscale_read_dcsr(target_t
*target
)
246 armv4_5_common_t
*armv4_5
= target
->arch_info
;
247 xscale_common_t
*xscale
= armv4_5
->arch_info
;
251 scan_field_t fields
[3];
253 u8 field0_check_value
= 0x2;
254 u8 field0_check_mask
= 0x7;
256 u8 field2_check_value
= 0x0;
257 u8 field2_check_mask
= 0x1;
259 jtag_add_end_state(TAP_PD
);
260 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dcsr
);
262 buf_set_u32(&field0
, 1, 1, xscale
->hold_rst
);
263 buf_set_u32(&field0
, 2, 1, xscale
->external_debug_break
);
265 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
266 fields
[0].num_bits
= 3;
267 fields
[0].out_value
= &field0
;
268 fields
[0].out_mask
= NULL
;
269 fields
[0].in_value
= NULL
;
270 fields
[0].in_check_value
= &field0_check_value
;
271 fields
[0].in_check_mask
= &field0_check_mask
;
272 fields
[0].in_handler
= NULL
;
273 fields
[0].in_handler_priv
= NULL
;
275 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
276 fields
[1].num_bits
= 32;
277 fields
[1].out_value
= NULL
;
278 fields
[1].out_mask
= NULL
;
279 fields
[1].in_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
280 fields
[1].in_handler
= NULL
;
281 fields
[1].in_handler_priv
= NULL
;
282 fields
[1].in_check_value
= NULL
;
283 fields
[1].in_check_mask
= NULL
;
285 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
286 fields
[2].num_bits
= 1;
287 fields
[2].out_value
= &field2
;
288 fields
[2].out_mask
= NULL
;
289 fields
[2].in_value
= NULL
;
290 fields
[2].in_check_value
= &field2_check_value
;
291 fields
[2].in_check_mask
= &field2_check_mask
;
292 fields
[2].in_handler
= NULL
;
293 fields
[2].in_handler_priv
= NULL
;
295 jtag_add_dr_scan(3, fields
, -1, NULL
);
297 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
299 ERROR("JTAG error while reading DCSR");
303 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].dirty
= 0;
304 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].valid
= 1;
306 /* write the register with the value we just read
307 * on this second pass, only the first bit of field0 is guaranteed to be 0)
309 field0_check_mask
= 0x1;
310 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
311 fields
[1].in_value
= NULL
;
313 jtag_add_end_state(TAP_RTI
);
315 jtag_add_dr_scan(3, fields
, -1, NULL
);
320 int xscale_receive(target_t
*target
, u32
*buffer
, int num_words
)
322 armv4_5_common_t
*armv4_5
= target
->arch_info
;
323 xscale_common_t
*xscale
= armv4_5
->arch_info
;
325 enum tap_state path
[3];
326 scan_field_t fields
[3];
328 u8
*field0
= malloc(num_words
* 1);
329 u8 field0_check_value
= 0x2;
330 u8 field0_check_mask
= 0x6;
331 u32
*field1
= malloc(num_words
* 4);
332 u8 field2_check_value
= 0x0;
333 u8 field2_check_mask
= 0x1;
335 int words_scheduled
= 0;
344 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
345 fields
[0].num_bits
= 3;
346 fields
[0].out_value
= NULL
;
347 fields
[0].out_mask
= NULL
;
348 /* fields[0].in_value = field0; */
349 fields
[0].in_check_value
= &field0_check_value
;
350 fields
[0].in_check_mask
= &field0_check_mask
;
351 fields
[0].in_handler
= NULL
;
352 fields
[0].in_handler_priv
= NULL
;
354 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
355 fields
[1].num_bits
= 32;
356 fields
[1].out_value
= NULL
;
357 fields
[1].out_mask
= NULL
;
358 fields
[1].in_value
= NULL
;
359 fields
[1].in_handler
= NULL
;
360 fields
[1].in_handler_priv
= NULL
;
361 fields
[1].in_check_value
= NULL
;
362 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 fields
[2].in_check_value
= &field2_check_value
;
370 fields
[2].in_check_mask
= &field2_check_mask
;
371 fields
[2].in_handler
= NULL
;
372 fields
[2].in_handler_priv
= NULL
;
374 jtag_add_end_state(TAP_RTI
);
375 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dbgtx
);
376 jtag_add_runtest(1, -1);
378 /* repeat until all words have been collected */
379 while (words_done
< num_words
)
383 for (i
= words_done
; i
< num_words
; i
++)
385 fields
[0].in_value
= &field0
[i
];
386 fields
[1].in_handler
= buf_to_u32_handler
;
387 fields
[1].in_handler_priv
= (u8
*)&field1
[i
];
389 jtag_add_pathmove(3, path
);
390 jtag_add_dr_scan(3, fields
, TAP_RTI
, NULL
);
394 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
396 ERROR("JTAG error while receiving data from debug handler");
400 /* examine results */
401 for (i
= words_done
; i
< num_words
; i
++)
403 if (!(field0
[0] & 1))
405 /* move backwards if necessary */
407 for (j
= i
; j
< num_words
- 1; j
++)
409 field0
[j
] = field0
[j
+1];
410 field1
[j
] = field1
[j
+1];
415 words_done
+= words_scheduled
;
418 for (i
= 0; i
< num_words
; i
++)
419 *(buffer
++) = buf_get_u32((u8
*)&field1
[i
], 0, 32);
426 int xscale_read_tx(target_t
*target
, int consume
)
428 armv4_5_common_t
*armv4_5
= target
->arch_info
;
429 xscale_common_t
*xscale
= armv4_5
->arch_info
;
430 enum tap_state path
[3];
433 struct timeval timeout
, now
;
435 scan_field_t fields
[3];
437 u8 field0_check_value
= 0x2;
438 u8 field0_check_mask
= 0x6;
439 u8 field2_check_value
= 0x0;
440 u8 field2_check_mask
= 0x1;
442 jtag_add_end_state(TAP_RTI
);
444 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dbgtx
);
450 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
451 fields
[0].num_bits
= 3;
452 fields
[0].out_value
= NULL
;
453 fields
[0].out_mask
= NULL
;
454 fields
[0].in_value
= &field0_in
;
455 fields
[0].in_check_value
= &field0_check_value
;
456 fields
[0].in_check_mask
= &field0_check_mask
;
457 fields
[0].in_handler
= NULL
;
458 fields
[0].in_handler_priv
= NULL
;
460 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
461 fields
[1].num_bits
= 32;
462 fields
[1].out_value
= NULL
;
463 fields
[1].out_mask
= NULL
;
464 fields
[1].in_value
= xscale
->reg_cache
->reg_list
[XSCALE_TX
].value
;
465 fields
[1].in_handler
= NULL
;
466 fields
[1].in_handler_priv
= NULL
;
467 fields
[1].in_check_value
= NULL
;
468 fields
[1].in_check_mask
= NULL
;
470 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
471 fields
[2].num_bits
= 1;
472 fields
[2].out_value
= NULL
;
473 fields
[2].out_mask
= NULL
;
474 fields
[2].in_value
= NULL
;
475 fields
[2].in_check_value
= &field2_check_value
;
476 fields
[2].in_check_mask
= &field2_check_mask
;
477 fields
[2].in_handler
= NULL
;
478 fields
[2].in_handler_priv
= NULL
;
480 gettimeofday(&timeout
, NULL
);
481 timeval_add_time(&timeout
, 5, 0);
485 /* if we want to consume the register content (i.e. clear TX_READY),
486 * we have to go straight from Capture-DR to Shift-DR
487 * otherwise, we go from Capture-DR to Exit1-DR to Pause-DR
490 jtag_add_pathmove(3, path
);
492 jtag_add_statemove(TAP_PD
);
494 jtag_add_dr_scan(3, fields
, TAP_RTI
, NULL
);
496 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
498 ERROR("JTAG error while reading TX");
502 gettimeofday(&now
, NULL
);
503 if ((now
.tv_sec
> timeout
.tv_sec
) && (now
.tv_usec
> timeout
.tv_usec
))
505 ERROR("time out reading TX register");
506 return ERROR_TARGET_TIMEOUT
;
508 } while ((!(field0_in
& 1)) && consume
);
510 if (!(field0_in
& 1))
511 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
516 int xscale_write_rx(target_t
*target
)
518 armv4_5_common_t
*armv4_5
= target
->arch_info
;
519 xscale_common_t
*xscale
= armv4_5
->arch_info
;
522 struct timeval timeout
, now
;
524 scan_field_t fields
[3];
527 u8 field0_check_value
= 0x2;
528 u8 field0_check_mask
= 0x6;
530 u8 field2_check_value
= 0x0;
531 u8 field2_check_mask
= 0x1;
533 jtag_add_end_state(TAP_RTI
);
535 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dbgrx
);
537 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
538 fields
[0].num_bits
= 3;
539 fields
[0].out_value
= &field0_out
;
540 fields
[0].out_mask
= NULL
;
541 fields
[0].in_value
= &field0_in
;
542 fields
[0].in_check_value
= &field0_check_value
;
543 fields
[0].in_check_mask
= &field0_check_mask
;
544 fields
[0].in_handler
= NULL
;
545 fields
[0].in_handler_priv
= NULL
;
547 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
548 fields
[1].num_bits
= 32;
549 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
;
550 fields
[1].out_mask
= NULL
;
551 fields
[1].in_value
= NULL
;
552 fields
[1].in_handler
= NULL
;
553 fields
[1].in_handler_priv
= NULL
;
554 fields
[1].in_check_value
= NULL
;
555 fields
[1].in_check_mask
= NULL
;
557 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
558 fields
[2].num_bits
= 1;
559 fields
[2].out_value
= &field2
;
560 fields
[2].out_mask
= NULL
;
561 fields
[2].in_value
= NULL
;
562 fields
[2].in_check_value
= &field2_check_value
;
563 fields
[2].in_check_mask
= &field2_check_mask
;
564 fields
[2].in_handler
= NULL
;
565 fields
[2].in_handler_priv
= NULL
;
567 gettimeofday(&timeout
, NULL
);
568 timeval_add_time(&timeout
, 5, 0);
570 /* poll until rx_read is low */
574 jtag_add_dr_scan(3, fields
, TAP_RTI
, NULL
);
576 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
578 ERROR("JTAG error while writing RX");
582 gettimeofday(&now
, NULL
);
583 if ((now
.tv_sec
> timeout
.tv_sec
) && (now
.tv_usec
> timeout
.tv_usec
))
585 ERROR("time out writing RX register");
586 return ERROR_TARGET_TIMEOUT
;
588 } while (field0_in
& 1);
592 jtag_add_dr_scan(3, fields
, TAP_RTI
, NULL
);
594 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
596 ERROR("JTAG error while writing RX");
603 /* send count elements of size byte to the debug handler */
604 int xscale_send(target_t
*target
, u8
*buffer
, int count
, int size
)
606 armv4_5_common_t
*armv4_5
= target
->arch_info
;
607 xscale_common_t
*xscale
= armv4_5
->arch_info
;
612 u8 output
[4] = {0, 0, 0, 0};
614 scan_field_t fields
[3];
617 u8 field0_check_value
= 0x2;
618 u8 field0_check_mask
= 0x6;
620 u8 field2_check_value
= 0x0;
621 u8 field2_check_mask
= 0x1;
623 jtag_add_end_state(TAP_RTI
);
625 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dbgrx
);
627 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
628 fields
[0].num_bits
= 3;
629 fields
[0].out_value
= &field0_out
;
630 fields
[0].out_mask
= NULL
;
631 fields
[0].in_value
= &field0_in
;
632 fields
[0].in_check_value
= &field0_check_value
;
633 fields
[0].in_check_mask
= &field0_check_mask
;
634 fields
[0].in_handler
= NULL
;
635 fields
[0].in_handler_priv
= NULL
;
637 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
638 fields
[1].num_bits
= 32;
639 fields
[1].out_value
= output
;
640 fields
[1].out_mask
= NULL
;
641 fields
[1].in_value
= NULL
;
642 fields
[1].in_handler
= NULL
;
643 fields
[1].in_handler_priv
= NULL
;
644 fields
[1].in_check_value
= NULL
;
645 fields
[1].in_check_mask
= NULL
;
647 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
648 fields
[2].num_bits
= 1;
649 fields
[2].out_value
= &field2
;
650 fields
[2].out_mask
= NULL
;
651 fields
[2].in_value
= NULL
;
652 fields
[2].in_check_value
= &field2_check_value
;
653 fields
[2].in_check_mask
= &field2_check_mask
;
654 fields
[2].in_handler
= NULL
;
655 fields
[2].in_handler_priv
= NULL
;
657 while (done_count
++ < count
)
659 /* extract sized element from target-endian buffer, and put it
660 * into little-endian output buffer
665 buf_set_u32(output
, 0, 32, target_buffer_get_u32(target
, buffer
));
668 buf_set_u32(output
, 0, 32, target_buffer_get_u16(target
, buffer
));
674 ERROR("BUG: size neither 4, 2 nor 1");
678 jtag_add_dr_scan(3, fields
, TAP_RTI
, NULL
);
682 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
684 ERROR("JTAG error while sending data to debug handler");
691 int xscale_send_u32(target_t
*target
, u32 value
)
693 armv4_5_common_t
*armv4_5
= target
->arch_info
;
694 xscale_common_t
*xscale
= armv4_5
->arch_info
;
696 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
697 return xscale_write_rx(target
);
700 int xscale_write_dcsr(target_t
*target
, int hold_rst
, int ext_dbg_brk
)
702 armv4_5_common_t
*armv4_5
= target
->arch_info
;
703 xscale_common_t
*xscale
= armv4_5
->arch_info
;
707 scan_field_t fields
[3];
709 u8 field0_check_value
= 0x2;
710 u8 field0_check_mask
= 0x7;
712 u8 field2_check_value
= 0x0;
713 u8 field2_check_mask
= 0x1;
716 xscale
->hold_rst
= hold_rst
;
718 if (ext_dbg_brk
!= -1)
719 xscale
->external_debug_break
= ext_dbg_brk
;
721 jtag_add_end_state(TAP_RTI
);
722 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dcsr
);
724 buf_set_u32(&field0
, 1, 1, xscale
->hold_rst
);
725 buf_set_u32(&field0
, 2, 1, xscale
->external_debug_break
);
727 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
728 fields
[0].num_bits
= 3;
729 fields
[0].out_value
= &field0
;
730 fields
[0].out_mask
= NULL
;
731 fields
[0].in_value
= NULL
;
732 fields
[0].in_check_value
= &field0_check_value
;
733 fields
[0].in_check_mask
= &field0_check_mask
;
734 fields
[0].in_handler
= NULL
;
735 fields
[0].in_handler_priv
= NULL
;
737 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
738 fields
[1].num_bits
= 32;
739 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
740 fields
[1].out_mask
= NULL
;
741 fields
[1].in_value
= NULL
;
742 fields
[1].in_handler
= NULL
;
743 fields
[1].in_handler_priv
= NULL
;
744 fields
[1].in_check_value
= NULL
;
745 fields
[1].in_check_mask
= NULL
;
747 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
748 fields
[2].num_bits
= 1;
749 fields
[2].out_value
= &field2
;
750 fields
[2].out_mask
= NULL
;
751 fields
[2].in_value
= NULL
;
752 fields
[2].in_check_value
= &field2_check_value
;
753 fields
[2].in_check_mask
= &field2_check_mask
;
754 fields
[2].in_handler
= NULL
;
755 fields
[2].in_handler_priv
= NULL
;
757 jtag_add_dr_scan(3, fields
, -1, NULL
);
759 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
761 ERROR("JTAG error while writing DCSR");
765 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].dirty
= 0;
766 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].valid
= 1;
771 /* parity of the number of bits 0 if even; 1 if odd. for 32 bit words */
772 unsigned int parity (unsigned int v
)
779 DEBUG("parity of 0x%x is %i", ov
, (0x6996 >> v
) & 1);
780 return (0x6996 >> v
) & 1;
783 int xscale_load_ic(target_t
*target
, int mini
, u32 va
, u32 buffer
[8])
785 armv4_5_common_t
*armv4_5
= target
->arch_info
;
786 xscale_common_t
*xscale
= armv4_5
->arch_info
;
791 scan_field_t fields
[2];
793 DEBUG("loading miniIC at 0x%8.8x", va
);
795 jtag_add_end_state(TAP_RTI
);
796 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.ldic
); /* LDIC */
798 /* CMD is b010 for Main IC and b011 for Mini IC */
800 buf_set_u32(&cmd
, 0, 3, 0x3);
802 buf_set_u32(&cmd
, 0, 3, 0x2);
804 buf_set_u32(&cmd
, 3, 3, 0x0);
806 /* virtual address of desired cache line */
807 buf_set_u32(packet
, 0, 27, va
>> 5);
809 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
810 fields
[0].num_bits
= 6;
811 fields
[0].out_value
= &cmd
;
812 fields
[0].out_mask
= NULL
;
813 fields
[0].in_value
= NULL
;
814 fields
[0].in_check_value
= NULL
;
815 fields
[0].in_check_mask
= NULL
;
816 fields
[0].in_handler
= NULL
;
817 fields
[0].in_handler_priv
= NULL
;
819 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
820 fields
[1].num_bits
= 27;
821 fields
[1].out_value
= packet
;
822 fields
[1].out_mask
= NULL
;
823 fields
[1].in_value
= NULL
;
824 fields
[1].in_check_value
= NULL
;
825 fields
[1].in_check_mask
= NULL
;
826 fields
[1].in_handler
= NULL
;
827 fields
[1].in_handler_priv
= NULL
;
829 jtag_add_dr_scan(2, fields
, -1, NULL
);
831 fields
[0].num_bits
= 32;
832 fields
[0].out_value
= packet
;
834 fields
[1].num_bits
= 1;
835 fields
[1].out_value
= &cmd
;
837 for (word
= 0; word
< 8; word
++)
839 buf_set_u32(packet
, 0, 32, buffer
[word
]);
840 cmd
= parity(*((u32
*)packet
));
841 jtag_add_dr_scan(2, fields
, -1, NULL
);
844 jtag_execute_queue();
849 int xscale_invalidate_ic_line(target_t
*target
, u32 va
)
851 armv4_5_common_t
*armv4_5
= target
->arch_info
;
852 xscale_common_t
*xscale
= armv4_5
->arch_info
;
856 scan_field_t fields
[2];
858 jtag_add_end_state(TAP_RTI
);
859 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.ldic
); /* LDIC */
861 /* CMD for invalidate IC line b000, bits [6:4] b000 */
862 buf_set_u32(&cmd
, 0, 6, 0x0);
864 /* virtual address of desired cache line */
865 buf_set_u32(packet
, 0, 27, va
>> 5);
867 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
868 fields
[0].num_bits
= 6;
869 fields
[0].out_value
= &cmd
;
870 fields
[0].out_mask
= NULL
;
871 fields
[0].in_value
= NULL
;
872 fields
[0].in_check_value
= NULL
;
873 fields
[0].in_check_mask
= NULL
;
874 fields
[0].in_handler
= NULL
;
875 fields
[0].in_handler_priv
= NULL
;
877 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
878 fields
[1].num_bits
= 27;
879 fields
[1].out_value
= packet
;
880 fields
[1].out_mask
= NULL
;
881 fields
[1].in_value
= NULL
;
882 fields
[1].in_check_value
= NULL
;
883 fields
[1].in_check_mask
= NULL
;
884 fields
[1].in_handler
= NULL
;
885 fields
[1].in_handler_priv
= NULL
;
887 jtag_add_dr_scan(2, fields
, -1, NULL
);
892 int xscale_update_vectors(target_t
*target
)
894 armv4_5_common_t
*armv4_5
= target
->arch_info
;
895 xscale_common_t
*xscale
= armv4_5
->arch_info
;
898 u32 low_reset_branch
, high_reset_branch
;
900 for (i
= 1; i
< 8; i
++)
902 /* if there's a static vector specified for this exception, override */
903 if (xscale
->static_high_vectors_set
& (1 << i
))
905 xscale
->high_vectors
[i
] = xscale
->static_high_vectors
[i
];
909 if (target_read_u32(target
, 0xffff0000 + 4*i
, &xscale
->high_vectors
[i
]) != ERROR_OK
)
911 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
916 for (i
= 1; i
< 8; i
++)
918 if (xscale
->static_low_vectors_set
& (1 << i
))
920 xscale
->low_vectors
[i
] = xscale
->static_low_vectors
[i
];
924 if (target_read_u32(target
, 0x0 + 4*i
, &xscale
->low_vectors
[i
]) != ERROR_OK
)
926 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
931 /* calculate branches to debug handler */
932 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
933 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
935 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
936 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
938 /* invalidate and load exception vectors in mini i-cache */
939 xscale_invalidate_ic_line(target
, 0x0);
940 xscale_invalidate_ic_line(target
, 0xffff0000);
942 xscale_load_ic(target
, 1, 0x0, xscale
->low_vectors
);
943 xscale_load_ic(target
, 1, 0xffff0000, xscale
->high_vectors
);
948 int xscale_arch_state(struct target_s
*target
, char *buf
, int buf_size
)
950 armv4_5_common_t
*armv4_5
= target
->arch_info
;
951 xscale_common_t
*xscale
= armv4_5
->arch_info
;
955 "disabled", "enabled"
958 char *arch_dbg_reason
[] =
960 "", "\n(processor reset)", "\n(trace buffer full)"
963 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
965 ERROR("BUG: called for a non-ARMv4/5 target");
969 snprintf(buf
, buf_size
,
970 "target halted in %s state due to %s, current mode: %s\n"
971 "cpsr: 0x%8.8x pc: 0x%8.8x\n"
972 "MMU: %s, D-Cache: %s, I-Cache: %s"
974 armv4_5_state_strings
[armv4_5
->core_state
],
975 target_debug_reason_strings
[target
->debug_reason
],
976 armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)],
977 buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32),
978 buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32),
979 state
[xscale
->armv4_5_mmu
.mmu_enabled
],
980 state
[xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
],
981 state
[xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
],
982 arch_dbg_reason
[xscale
->arch_debug_reason
]);
987 enum target_state
xscale_poll(target_t
*target
)
990 armv4_5_common_t
*armv4_5
= target
->arch_info
;
991 xscale_common_t
*xscale
= armv4_5
->arch_info
;
993 if ((target
->state
== TARGET_RUNNING
) || (target
->state
== TARGET_DEBUG_RUNNING
))
995 if ((retval
= xscale_read_tx(target
, 0)) == ERROR_OK
)
997 /* there's data to read from the tx register, we entered debug state */
998 xscale
->handler_running
= 1;
1000 /* process debug entry, fetching current mode regs */
1001 if ((retval
= xscale_debug_entry(target
)) != ERROR_OK
)
1004 /* if target was running, signal that we halted
1005 * otherwise we reentered from debug execution */
1006 if (target
->state
== TARGET_RUNNING
)
1007 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1009 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
1011 target
->state
= TARGET_HALTED
;
1013 else if (retval
!= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
1015 ERROR("error while polling TX register");
1020 return target
->state
;
1023 int xscale_debug_entry(target_t
*target
)
1025 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1026 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1028 u32
*buffer
= malloc(4 * 10);
1033 /* clear external dbg break (will be written on next DCSR read) */
1034 xscale
->external_debug_break
= 0;
1035 xscale_read_dcsr(target
);
1037 /* get r0, pc, r1 to r7 and cpsr */
1038 xscale_receive(target
, buffer
, 10);
1040 /* move r0 from buffer to register cache */
1041 buf_set_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32, buffer
[0]);
1042 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
1043 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
1044 DEBUG("r0: 0x%8.8x", buffer
[0]);
1046 /* move pc from buffer to register cache */
1047 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, buffer
[1]);
1048 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
1049 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
1050 DEBUG("pc: 0x%8.8x", buffer
[1]);
1052 /* move data from buffer to register cache */
1053 for (i
= 1; i
<= 7; i
++)
1055 buf_set_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32, buffer
[1 + i
]);
1056 armv4_5
->core_cache
->reg_list
[i
].dirty
= 1;
1057 armv4_5
->core_cache
->reg_list
[i
].valid
= 1;
1058 DEBUG("r%i: 0x%8.8x", i
, buffer
[i
+ 1]);
1061 buf_set_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32, buffer
[9]);
1062 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].dirty
= 1;
1063 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].valid
= 1;
1064 DEBUG("cpsr: 0x%8.8x", buffer
[9]);
1066 armv4_5
->core_mode
= buffer
[9] & 0x1f;
1067 if (armv4_5_mode_to_number(armv4_5
->core_mode
) == -1)
1069 target
->state
= TARGET_UNKNOWN
;
1070 ERROR("cpsr contains invalid mode value - communication failure");
1071 return ERROR_TARGET_FAILURE
;
1073 DEBUG("target entered debug state in %s mode", armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)]);
1075 if (buffer
[9] & 0x20)
1076 armv4_5
->core_state
= ARMV4_5_STATE_THUMB
;
1078 armv4_5
->core_state
= ARMV4_5_STATE_ARM
;
1080 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1081 if ((armv4_5
->core_mode
!= ARMV4_5_MODE_USR
) && (armv4_5
->core_mode
!= ARMV4_5_MODE_SYS
))
1083 xscale_receive(target
, buffer
, 8);
1084 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1085 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
1086 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
1090 /* r8 to r14, but no spsr */
1091 xscale_receive(target
, buffer
, 7);
1094 /* move data from buffer to register cache */
1095 for (i
= 8; i
<= 14; i
++)
1097 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).value
, 0, 32, buffer
[i
- 8]);
1098 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).dirty
= 0;
1099 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).valid
= 1;
1102 /* examine debug reason */
1103 xscale_read_dcsr(target
);
1104 moe
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 2, 3);
1106 /* stored PC (for calculating fixup) */
1107 pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1111 case 0x0: /* Processor reset */
1112 target
->debug_reason
= DBG_REASON_DBGRQ
;
1113 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_RESET
;
1116 case 0x1: /* Instruction breakpoint hit */
1117 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1118 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1121 case 0x2: /* Data breakpoint hit */
1122 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
1123 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1126 case 0x3: /* BKPT instruction executed */
1127 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1128 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1131 case 0x4: /* Ext. debug event */
1132 target
->debug_reason
= DBG_REASON_DBGRQ
;
1133 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1136 case 0x5: /* Vector trap occured */
1137 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1138 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1141 case 0x6: /* Trace buffer full break */
1142 target
->debug_reason
= DBG_REASON_DBGRQ
;
1143 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_TB_FULL
;
1146 case 0x7: /* Reserved */
1148 ERROR("Method of Entry is 'Reserved'");
1153 /* apply PC fixup */
1154 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, pc
);
1156 /* on the first debug entry, identify cache type */
1157 if (xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
1161 /* read cp15 cache type register */
1162 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
]);
1163 cache_type_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
].value
, 0, 32);
1165 armv4_5_identify_cache(cache_type_reg
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
1168 /* examine MMU and Cache settings */
1169 /* read cp15 control register */
1170 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
1171 xscale
->cp15_control_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
1172 xscale
->armv4_5_mmu
.mmu_enabled
= (xscale
->cp15_control_reg
& 0x1U
) ? 1 : 0;
1173 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= (xscale
->cp15_control_reg
& 0x4U
) ? 1 : 0;
1174 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= (xscale
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
1179 int xscale_halt(target_t
*target
)
1181 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1182 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1184 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
1186 if (target
->state
== TARGET_HALTED
)
1188 WARNING("target was already halted");
1189 return ERROR_TARGET_ALREADY_HALTED
;
1191 else if (target
->state
== TARGET_UNKNOWN
)
1193 /* this must not happen for a xscale target */
1194 ERROR("target was in unknown state when halt was requested");
1197 else if (target
->state
== TARGET_RESET
)
1199 DEBUG("target->state == TARGET_RESET");
1202 jtag_add_reset(0, -1);
1206 /* assert external dbg break */
1207 xscale
->external_debug_break
= 1;
1208 xscale_read_dcsr(target
);
1210 target
->debug_reason
= DBG_REASON_DBGRQ
;
1216 int xscale_enable_single_step(struct target_s
*target
, u32 next_pc
)
1218 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1219 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1220 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1222 if (xscale
->ibcr0_used
)
1224 breakpoint_t
*ibcr0_bp
= breakpoint_find(target
, buf_get_u32(ibcr0
->value
, 0, 32) & 0xfffffffe);
1228 xscale_unset_breakpoint(target
, ibcr0_bp
);
1232 ERROR("BUG: xscale->ibcr0_used is set, but no breakpoint with that address found");
1237 xscale_set_reg_u32(ibcr0
, next_pc
| 0x1);
1242 int xscale_disable_single_step(struct target_s
*target
)
1244 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1245 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1246 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1248 xscale_set_reg_u32(ibcr0
, 0x0);
1253 int xscale_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
1255 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1256 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1257 breakpoint_t
*breakpoint
= target
->breakpoints
;
1266 if (target
->state
!= TARGET_HALTED
)
1268 WARNING("target not halted");
1269 return ERROR_TARGET_NOT_HALTED
;
1272 if (!debug_execution
)
1274 target_free_all_working_areas(target
);
1277 /* update vector tables */
1278 xscale_update_vectors(target
);
1280 /* current = 1: continue on current pc, otherwise continue at <address> */
1282 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1284 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1286 /* if we're at the reset vector, we have to simulate the branch */
1287 if (current_pc
== 0x0)
1289 arm_simulate_step(target
, NULL
);
1290 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1293 /* the front-end may request us not to handle breakpoints */
1294 if (handle_breakpoints
)
1296 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1300 /* there's a breakpoint at the current PC, we have to step over it */
1301 DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
1302 xscale_unset_breakpoint(target
, breakpoint
);
1304 /* calculate PC of next instruction */
1305 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1308 target_read_u32(target
, current_pc
, ¤t_opcode
);
1309 ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode
);
1312 DEBUG("enable single-step");
1313 xscale_enable_single_step(target
, next_pc
);
1315 /* restore banked registers */
1316 xscale_restore_context(target
);
1318 /* send resume request (command 0x30 or 0x31)
1319 * clean the trace buffer if it is to be enabled (0x62) */
1320 if (xscale
->trace_buffer_enabled
)
1322 xscale_send_u32(target
, 0x62);
1323 xscale_send_u32(target
, 0x31);
1326 xscale_send_u32(target
, 0x30);
1329 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1330 DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1332 for (i
= 7; i
>= 0; i
--)
1335 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1336 DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1340 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1341 DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1343 /* wait for and process debug entry */
1344 xscale_debug_entry(target
);
1346 DEBUG("disable single-step");
1347 xscale_disable_single_step(target
);
1349 DEBUG("set breakpoint at 0x%8.8x", breakpoint
->address
);
1350 xscale_set_breakpoint(target
, breakpoint
);
1354 /* enable any pending breakpoints and watchpoints */
1355 xscale_enable_breakpoints(target
);
1356 xscale_enable_watchpoints(target
);
1358 /* restore banked registers */
1359 xscale_restore_context(target
);
1361 /* send resume request (command 0x30 or 0x31)
1362 * clean the trace buffer if it is to be enabled (0x62) */
1363 if (xscale
->trace_buffer_enabled
)
1365 xscale_send_u32(target
, 0x62);
1366 xscale_send_u32(target
, 0x31);
1369 xscale_send_u32(target
, 0x30);
1372 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1373 DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1375 for (i
= 7; i
>= 0; i
--)
1378 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1379 DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1383 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1384 DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1386 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1388 if (!debug_execution
)
1390 /* registers are now invalid */
1391 armv4_5_invalidate_core_regs(target
);
1392 target
->state
= TARGET_RUNNING
;
1393 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1397 target
->state
= TARGET_DEBUG_RUNNING
;
1398 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1401 DEBUG("target resumed");
1403 xscale
->handler_running
= 1;
1408 int xscale_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
1410 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1411 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1412 breakpoint_t
*breakpoint
= target
->breakpoints
;
1414 u32 current_pc
, next_pc
;
1418 if (target
->state
!= TARGET_HALTED
)
1420 WARNING("target not halted");
1421 return ERROR_TARGET_NOT_HALTED
;
1424 /* current = 1: continue on current pc, otherwise continue at <address> */
1426 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1428 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1430 /* if we're at the reset vector, we have to simulate the step */
1431 if (current_pc
== 0x0)
1433 arm_simulate_step(target
, NULL
);
1434 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1436 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1437 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1442 /* the front-end may request us not to handle breakpoints */
1443 if (handle_breakpoints
)
1444 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1446 xscale_unset_breakpoint(target
, breakpoint
);
1449 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1451 /* calculate PC of next instruction */
1452 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1455 target_read_u32(target
, current_pc
, ¤t_opcode
);
1456 ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode
);
1459 DEBUG("enable single-step");
1460 xscale_enable_single_step(target
, next_pc
);
1462 /* restore banked registers */
1463 xscale_restore_context(target
);
1465 /* send resume request (command 0x30 or 0x31)
1466 * clean the trace buffer if it is to be enabled (0x62) */
1467 if (xscale
->trace_buffer_enabled
)
1469 xscale_send_u32(target
, 0x62);
1470 xscale_send_u32(target
, 0x31);
1473 xscale_send_u32(target
, 0x30);
1476 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1477 DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1479 for (i
= 7; i
>= 0; i
--)
1482 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1483 DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1487 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1488 DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1490 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1492 /* registers are now invalid */
1493 armv4_5_invalidate_core_regs(target
);
1495 /* wait for and process debug entry */
1496 xscale_debug_entry(target
);
1498 DEBUG("disable single-step");
1499 xscale_disable_single_step(target
);
1501 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1505 xscale_set_breakpoint(target
, breakpoint
);
1508 DEBUG("target stepped");
1514 int xscale_assert_reset(target_t
*target
)
1516 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1517 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1519 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
1521 /* if the handler isn't installed yet, we have to assert TRST, too */
1522 if (!xscale
->handler_installed
)
1524 jtag_add_reset(1, 1);
1527 jtag_add_reset(-1, 1);
1529 /* sleep 1ms, to be sure we fulfill any requirements */
1530 jtag_add_sleep(1000);
1532 target
->state
= TARGET_RESET
;
1538 int xscale_deassert_reset(target_t
*target
)
1540 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1541 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1545 struct stat binary_stat
;
1552 breakpoint_t
*breakpoint
= target
->breakpoints
;
1554 xscale
->ibcr_available
= 2;
1555 xscale
->ibcr0_used
= 0;
1556 xscale
->ibcr1_used
= 0;
1558 xscale
->dbr_available
= 2;
1559 xscale
->dbr0_used
= 0;
1560 xscale
->dbr1_used
= 0;
1562 /* mark all hardware breakpoints as unset */
1565 if (breakpoint
->type
== BKPT_HARD
)
1567 breakpoint
->set
= 0;
1569 breakpoint
= breakpoint
->next
;
1572 if (!xscale
->handler_installed
)
1575 jtag_add_reset(0, -1);
1576 jtag_add_sleep(100000);
1578 /* set Hold reset, Halt mode and Trap Reset */
1579 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1580 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1581 xscale_write_dcsr(target
, 1, 0);
1582 jtag_add_runtest(100, TAP_RTI
);
1583 jtag_execute_queue();
1586 jtag_add_reset(0, 0);
1587 /* wait 150ms; 100ms were not enough */
1588 jtag_add_sleep(150000);
1590 jtag_add_runtest(2030, TAP_RTI
);
1591 jtag_execute_queue();
1593 xscale_write_dcsr(target
, 1, 0);
1594 jtag_execute_queue();
1596 /* TODO: load debug handler */
1597 if (stat("target/xscale/debug_handler.bin", &binary_stat
) == -1)
1599 ERROR("couldn't stat() target/xscale/debug_handler.bin: %s", strerror(errno
));
1603 if (!(binary
= fopen("target/xscale/debug_handler.bin", "r")))
1605 ERROR("couldn't open target/xscale/debug_handler.bin: %s", strerror(errno
));
1609 if ((binary_size
= binary_stat
.st_size
) % 4)
1611 ERROR("debug_handler.bin: size not a multiple of 4");
1615 if (binary_size
> 0x800)
1617 ERROR("debug_handler.bin: larger than 2kb");
1621 binary_size
= CEIL(binary_size
, 32) * 32;
1623 address
= xscale
->handler_address
;
1624 while (binary_size
> 0)
1626 buf_cnt
= fread(buffer
, 4, 8, binary
);
1628 for (i
= 0; i
< buf_cnt
; i
++)
1630 /* convert LE buffer to host-endian u32 */
1631 buffer
[i
] = buf_get_u32((u8
*)(&buffer
[i
]), 0, 32);
1636 for (; buf_cnt
< 8; buf_cnt
++)
1638 buffer
[buf_cnt
] = 0xe1a08008;
1642 /* only load addresses other than the reset vectors */
1643 if ((address
% 0x400) != 0x0)
1645 xscale_load_ic(target
, 1, address
, buffer
);
1648 address
+= buf_cnt
* 4;
1649 binary_size
-= buf_cnt
* 4;
1652 xscale_load_ic(target
, 1, 0x0, xscale
->low_vectors
);
1653 xscale_load_ic(target
, 1, 0xffff0000, xscale
->high_vectors
);
1655 jtag_add_runtest(30, TAP_RTI
);
1657 /* let the target run (should enter debug handler) */
1658 xscale_write_dcsr(target
, 0, 0);
1659 target
->state
= TARGET_RUNNING
;
1661 if ((target
->reset_mode
!= RESET_HALT
) && (target
->reset_mode
!= RESET_INIT
))
1663 jtag_add_sleep(10000);
1665 /* we should have entered debug now */
1666 xscale_debug_entry(target
);
1667 target
->state
= TARGET_HALTED
;
1669 /* the PC is now at 0x0 */
1670 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, 0x0);
1675 jtag_add_reset(0, 0);
1682 int xscale_soft_reset_halt(struct target_s
*target
)
1688 int xscale_prepare_reset_halt(struct target_s
*target
)
1690 /* nothing to be done for reset_halt on XScale targets */
1694 int xscale_read_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
)
1700 int xscale_write_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
, u32 value
)
1706 int xscale_full_context(target_t
*target
)
1708 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1716 if (target
->state
!= TARGET_HALTED
)
1718 WARNING("target not halted");
1719 return ERROR_TARGET_NOT_HALTED
;
1722 buffer
= malloc(4 * 8);
1724 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1725 * we can't enter User mode on an XScale (unpredictable),
1726 * but User shares registers with SYS
1728 for(i
= 1; i
< 7; i
++)
1732 /* check if there are invalid registers in the current mode
1734 for (j
= 0; j
<= 16; j
++)
1736 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
== 0)
1744 /* request banked registers */
1745 xscale_send_u32(target
, 0x0);
1748 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1749 tmp_cpsr
|= 0xc0; /* I/F bits */
1751 /* send CPSR for desired mode */
1752 xscale_send_u32(target
, tmp_cpsr
);
1754 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1755 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1757 xscale_receive(target
, buffer
, 8);
1758 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1759 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1760 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).valid
= 1;
1764 xscale_receive(target
, buffer
, 7);
1767 /* move data from buffer to register cache */
1768 for (j
= 8; j
<= 14; j
++)
1770 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]);
1771 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1772 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
= 1;
1782 int xscale_restore_context(target_t
*target
)
1784 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1790 if (target
->state
!= TARGET_HALTED
)
1792 WARNING("target not halted");
1793 return ERROR_TARGET_NOT_HALTED
;
1796 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1797 * we can't enter User mode on an XScale (unpredictable),
1798 * but User shares registers with SYS
1800 for(i
= 1; i
< 7; i
++)
1804 /* check if there are invalid registers in the current mode
1806 for (j
= 8; j
<= 14; j
++)
1808 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
== 1)
1812 /* if not USR/SYS, check if the SPSR needs to be written */
1813 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1815 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
== 1)
1823 /* send banked registers */
1824 xscale_send_u32(target
, 0x1);
1827 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1828 tmp_cpsr
|= 0xc0; /* I/F bits */
1830 /* send CPSR for desired mode */
1831 xscale_send_u32(target
, tmp_cpsr
);
1833 /* send banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1834 for (j
= 8; j
<= 14; j
++)
1836 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, j
).value
, 0, 32));
1837 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1840 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1842 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32));
1843 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1851 int xscale_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1853 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1854 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1858 DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address
, size
, count
);
1860 if (target
->state
!= TARGET_HALTED
)
1862 WARNING("target not halted");
1863 return ERROR_TARGET_NOT_HALTED
;
1866 /* sanitize arguments */
1867 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1868 return ERROR_INVALID_ARGUMENTS
;
1870 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1871 return ERROR_TARGET_UNALIGNED_ACCESS
;
1873 /* send memory read request (command 0x1n, n: access size) */
1874 xscale_send_u32(target
, 0x10 | size
);
1876 /* send base address for read request */
1877 xscale_send_u32(target
, address
);
1879 /* send number of requested data words */
1880 xscale_send_u32(target
, count
);
1882 /* receive data from target (count times 32-bit words in host endianness) */
1883 buf32
= malloc(4 * count
);
1884 xscale_receive(target
, buf32
, count
);
1886 /* extract data from host-endian buffer into byte stream */
1887 for (i
= 0; i
< count
; i
++)
1892 target_buffer_set_u32(target
, buffer
, buf32
[i
]);
1896 target_buffer_set_u16(target
, buffer
, buf32
[i
] & 0xffff);
1900 *buffer
++ = buf32
[i
] & 0xff;
1903 ERROR("should never get here");
1910 /* examine DCSR, to see if Sticky Abort (SA) got set */
1911 xscale_read_dcsr(target
);
1912 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
1915 xscale_send_u32(target
, 0x60);
1917 return ERROR_TARGET_DATA_ABORT
;
1923 int xscale_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1925 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1926 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1928 DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address
, size
, count
);
1930 if (target
->state
!= TARGET_HALTED
)
1932 WARNING("target not halted");
1933 return ERROR_TARGET_NOT_HALTED
;
1936 /* sanitize arguments */
1937 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1938 return ERROR_INVALID_ARGUMENTS
;
1940 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1941 return ERROR_TARGET_UNALIGNED_ACCESS
;
1943 /* send memory write request (command 0x2n, n: access size) */
1944 xscale_send_u32(target
, 0x20 | size
);
1946 /* send base address for read request */
1947 xscale_send_u32(target
, address
);
1949 /* send number of requested data words to be written*/
1950 xscale_send_u32(target
, count
);
1952 /* extract data from host-endian buffer into byte stream */
1954 for (i
= 0; i
< count
; i
++)
1959 value
= target_buffer_get_u32(target
, buffer
);
1960 xscale_send_u32(target
, value
);
1964 value
= target_buffer_get_u16(target
, buffer
);
1965 xscale_send_u32(target
, value
);
1970 xscale_send_u32(target
, value
);
1974 ERROR("should never get here");
1979 xscale_send(target
, buffer
, count
, size
);
1981 /* examine DCSR, to see if Sticky Abort (SA) got set */
1982 xscale_read_dcsr(target
);
1983 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
1986 xscale_send_u32(target
, 0x60);
1988 return ERROR_TARGET_DATA_ABORT
;
1994 int xscale_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
1996 xscale_write_memory(target
, address
, 4, count
, buffer
);
2001 u32
xscale_get_ttb(target_t
*target
)
2003 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2004 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2007 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_TTB
]);
2008 ttb
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_TTB
].value
, 0, 32);
2013 void xscale_disable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
2015 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2016 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2019 /* read cp15 control register */
2020 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2021 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2024 cp15_control
&= ~0x1U
;
2029 xscale_send_u32(target
, 0x50);
2030 xscale_send_u32(target
, xscale
->cache_clean_address
);
2032 /* invalidate DCache */
2033 xscale_send_u32(target
, 0x51);
2035 cp15_control
&= ~0x4U
;
2040 /* invalidate ICache */
2041 xscale_send_u32(target
, 0x52);
2042 cp15_control
&= ~0x1000U
;
2045 /* write new cp15 control register */
2046 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2048 /* execute cpwait to ensure outstanding operations complete */
2049 xscale_send_u32(target
, 0x53);
2052 void xscale_enable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
2054 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2055 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2058 /* read cp15 control register */
2059 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2060 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2063 cp15_control
|= 0x1U
;
2066 cp15_control
|= 0x4U
;
2069 cp15_control
|= 0x1000U
;
2071 /* write new cp15 control register */
2072 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2074 /* execute cpwait to ensure outstanding operations complete */
2075 xscale_send_u32(target
, 0x53);
2078 int xscale_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2080 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2081 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2083 if (target
->state
!= TARGET_HALTED
)
2085 WARNING("target not halted");
2086 return ERROR_TARGET_NOT_HALTED
;
2089 if (xscale
->force_hw_bkpts
)
2090 breakpoint
->type
= BKPT_HARD
;
2092 if (breakpoint
->set
)
2094 WARNING("breakpoint already set");
2098 if (breakpoint
->type
== BKPT_HARD
)
2100 u32 value
= breakpoint
->address
| 1;
2101 if (!xscale
->ibcr0_used
)
2103 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], value
);
2104 xscale
->ibcr0_used
= 1;
2105 breakpoint
->set
= 1; /* breakpoint set on first breakpoint register */
2107 else if (!xscale
->ibcr1_used
)
2109 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], value
);
2110 xscale
->ibcr1_used
= 1;
2111 breakpoint
->set
= 2; /* breakpoint set on second breakpoint register */
2115 ERROR("BUG: no hardware comparator available");
2119 else if (breakpoint
->type
== BKPT_SOFT
)
2121 if (breakpoint
->length
== 4)
2123 /* keep the original instruction in target endianness */
2124 target
->type
->read_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
);
2125 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2126 target_write_u32(target
, breakpoint
->address
, xscale
->arm_bkpt
);
2130 /* keep the original instruction in target endianness */
2131 target
->type
->read_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
);
2132 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2133 target_write_u32(target
, breakpoint
->address
, xscale
->thumb_bkpt
);
2135 breakpoint
->set
= 1;
2142 int xscale_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2144 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2145 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2147 if (target
->state
!= TARGET_HALTED
)
2149 WARNING("target not halted");
2150 return ERROR_TARGET_NOT_HALTED
;
2153 if (xscale
->force_hw_bkpts
)
2155 DEBUG("forcing use of hardware breakpoint at address 0x%8.8x", breakpoint
->address
);
2156 breakpoint
->type
= BKPT_HARD
;
2159 if ((breakpoint
->type
== BKPT_HARD
) && (xscale
->ibcr_available
< 1))
2161 INFO("no breakpoint unit available for hardware breakpoint");
2162 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2166 xscale
->ibcr_available
--;
2169 if ((breakpoint
->length
!= 2) && (breakpoint
->length
!= 4))
2171 INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
2172 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2178 int xscale_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2180 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2181 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2183 if (target
->state
!= TARGET_HALTED
)
2185 WARNING("target not halted");
2186 return ERROR_TARGET_NOT_HALTED
;
2189 if (!breakpoint
->set
)
2191 WARNING("breakpoint not set");
2195 if (breakpoint
->type
== BKPT_HARD
)
2197 if (breakpoint
->set
== 1)
2199 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], 0x0);
2200 xscale
->ibcr0_used
= 0;
2202 else if (breakpoint
->set
== 2)
2204 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], 0x0);
2205 xscale
->ibcr1_used
= 0;
2207 breakpoint
->set
= 0;
2211 /* restore original instruction (kept in target endianness) */
2212 if (breakpoint
->length
== 4)
2214 target
->type
->write_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
);
2218 target
->type
->write_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
);
2220 breakpoint
->set
= 0;
2226 int xscale_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2228 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2229 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2231 if (target
->state
!= TARGET_HALTED
)
2233 WARNING("target not halted");
2234 return ERROR_TARGET_NOT_HALTED
;
2237 if (breakpoint
->set
)
2239 xscale_unset_breakpoint(target
, breakpoint
);
2242 if (breakpoint
->type
== BKPT_HARD
)
2243 xscale
->ibcr_available
++;
2248 int xscale_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2250 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2251 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2253 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2254 u32 dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2256 if (target
->state
!= TARGET_HALTED
)
2258 WARNING("target not halted");
2259 return ERROR_TARGET_NOT_HALTED
;
2262 xscale_get_reg(dbcon
);
2264 switch (watchpoint
->rw
)
2276 ERROR("BUG: watchpoint->rw neither read, write nor access");
2279 if (!xscale
->dbr0_used
)
2281 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR0
], watchpoint
->address
);
2282 dbcon_value
|= enable
;
2283 xscale_set_reg_u32(dbcon
, dbcon_value
);
2284 watchpoint
->set
= 1;
2285 xscale
->dbr0_used
= 1;
2287 else if (!xscale
->dbr1_used
)
2289 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR1
], watchpoint
->address
);
2290 dbcon_value
|= enable
<< 2;
2291 xscale_set_reg_u32(dbcon
, dbcon_value
);
2292 watchpoint
->set
= 2;
2293 xscale
->dbr1_used
= 1;
2297 ERROR("BUG: no hardware comparator available");
2304 int xscale_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2306 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2307 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2309 if (target
->state
!= TARGET_HALTED
)
2311 WARNING("target not halted");
2312 return ERROR_TARGET_NOT_HALTED
;
2315 if (xscale
->dbr_available
< 1)
2317 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2320 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
2322 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2325 xscale
->dbr_available
--;
2330 int xscale_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2332 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2333 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2334 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2335 u32 dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2337 if (target
->state
!= TARGET_HALTED
)
2339 WARNING("target not halted");
2340 return ERROR_TARGET_NOT_HALTED
;
2343 if (!watchpoint
->set
)
2345 WARNING("breakpoint not set");
2349 if (watchpoint
->set
== 1)
2351 dbcon_value
&= ~0x3;
2352 xscale_set_reg_u32(dbcon
, dbcon_value
);
2353 xscale
->dbr0_used
= 0;
2355 else if (watchpoint
->set
== 2)
2357 dbcon_value
&= ~0xc;
2358 xscale_set_reg_u32(dbcon
, dbcon_value
);
2359 xscale
->dbr1_used
= 0;
2361 watchpoint
->set
= 0;
2366 int xscale_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2368 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2369 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2371 if (target
->state
!= TARGET_HALTED
)
2373 WARNING("target not halted");
2374 return ERROR_TARGET_NOT_HALTED
;
2377 if (watchpoint
->set
)
2379 xscale_unset_watchpoint(target
, watchpoint
);
2382 xscale
->dbr_available
++;
2387 void xscale_enable_watchpoints(struct target_s
*target
)
2389 watchpoint_t
*watchpoint
= target
->watchpoints
;
2393 if (watchpoint
->set
== 0)
2394 xscale_set_watchpoint(target
, watchpoint
);
2395 watchpoint
= watchpoint
->next
;
2399 void xscale_enable_breakpoints(struct target_s
*target
)
2401 breakpoint_t
*breakpoint
= target
->breakpoints
;
2403 /* set any pending breakpoints */
2406 if (breakpoint
->set
== 0)
2407 xscale_set_breakpoint(target
, breakpoint
);
2408 breakpoint
= breakpoint
->next
;
2412 int xscale_get_reg(reg_t
*reg
)
2414 xscale_reg_t
*arch_info
= reg
->arch_info
;
2415 target_t
*target
= arch_info
->target
;
2416 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2417 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2419 /* DCSR, TX and RX are accessible via JTAG */
2420 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2422 return xscale_read_dcsr(arch_info
->target
);
2424 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2426 /* 1 = consume register content */
2427 return xscale_read_tx(arch_info
->target
, 1);
2429 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2431 /* can't read from RX register (host -> debug handler) */
2434 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2436 /* can't (explicitly) read from TXRXCTRL register */
2439 else /* Other DBG registers have to be transfered by the debug handler */
2441 /* send CP read request (command 0x40) */
2442 xscale_send_u32(target
, 0x40);
2444 /* send CP register number */
2445 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2447 /* read register value */
2448 xscale_read_tx(target
, 1);
2449 buf_cpy(xscale
->reg_cache
->reg_list
[XSCALE_TX
].value
, reg
->value
, 32);
2458 int xscale_set_reg(reg_t
*reg
, u8
* buf
)
2460 xscale_reg_t
*arch_info
= reg
->arch_info
;
2461 target_t
*target
= arch_info
->target
;
2462 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2463 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2464 u32 value
= buf_get_u32(buf
, 0, 32);
2466 /* DCSR, TX and RX are accessible via JTAG */
2467 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2469 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32, value
);
2470 return xscale_write_dcsr(arch_info
->target
, -1, -1);
2472 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2474 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
2475 return xscale_write_rx(arch_info
->target
);
2477 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2479 /* can't write to TX register (debug-handler -> host) */
2482 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2484 /* can't (explicitly) write to TXRXCTRL register */
2487 else /* Other DBG registers have to be transfered by the debug handler */
2489 /* send CP write request (command 0x41) */
2490 xscale_send_u32(target
, 0x41);
2492 /* send CP register number */
2493 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2495 /* send CP register value */
2496 xscale_send_u32(target
, value
);
2497 buf_set_u32(reg
->value
, 0, 32, value
);
2503 /* convenience wrapper to access XScale specific registers */
2504 int xscale_set_reg_u32(reg_t
*reg
, u32 value
)
2508 buf_set_u32(buf
, 0, 32, value
);
2510 return xscale_set_reg(reg
, buf
);
2513 int xscale_write_dcsr_sw(target_t
*target
, u32 value
)
2515 /* get pointers to arch-specific information */
2516 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2517 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2518 reg_t
*dcsr
= &xscale
->reg_cache
->reg_list
[XSCALE_DCSR
];
2519 xscale_reg_t
*dcsr_arch_info
= dcsr
->arch_info
;
2521 /* send CP write request (command 0x41) */
2522 xscale_send_u32(target
, 0x41);
2524 /* send CP register number */
2525 xscale_send_u32(target
, dcsr_arch_info
->dbg_handler_number
);
2527 /* send CP register value */
2528 xscale_send_u32(target
, value
);
2529 buf_set_u32(dcsr
->value
, 0, 32, value
);
2534 void xscale_build_reg_cache(target_t
*target
)
2536 /* get pointers to arch-specific information */
2537 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2538 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2540 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
2541 xscale_reg_t
*arch_info
= malloc(sizeof(xscale_reg_arch_info
));
2543 int num_regs
= sizeof(xscale_reg_arch_info
) / sizeof(xscale_reg_t
);
2545 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
2546 armv4_5
->core_cache
= (*cache_p
);
2548 /* register a register arch-type for XScale dbg registers only once */
2549 if (xscale_reg_arch_type
== -1)
2550 xscale_reg_arch_type
= register_reg_arch_type(xscale_get_reg
, xscale_set_reg
);
2552 (*cache_p
)->next
= malloc(sizeof(reg_cache_t
));
2553 cache_p
= &(*cache_p
)->next
;
2555 /* fill in values for the xscale reg cache */
2556 (*cache_p
)->name
= "XScale registers";
2557 (*cache_p
)->next
= NULL
;
2558 (*cache_p
)->reg_list
= malloc(num_regs
* sizeof(reg_t
));
2559 (*cache_p
)->num_regs
= num_regs
;
2561 for (i
= 0; i
< num_regs
; i
++)
2563 (*cache_p
)->reg_list
[i
].name
= xscale_reg_list
[i
];
2564 (*cache_p
)->reg_list
[i
].value
= calloc(4, 1);
2565 (*cache_p
)->reg_list
[i
].dirty
= 0;
2566 (*cache_p
)->reg_list
[i
].valid
= 0;
2567 (*cache_p
)->reg_list
[i
].size
= 32;
2568 (*cache_p
)->reg_list
[i
].bitfield_desc
= NULL
;
2569 (*cache_p
)->reg_list
[i
].num_bitfields
= 0;
2570 (*cache_p
)->reg_list
[i
].arch_info
= &arch_info
[i
];
2571 (*cache_p
)->reg_list
[i
].arch_type
= xscale_reg_arch_type
;
2572 arch_info
[i
] = xscale_reg_arch_info
[i
];
2573 arch_info
[i
].target
= target
;
2576 xscale
->reg_cache
= (*cache_p
);
2579 int xscale_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
2581 if (startup_mode
!= DAEMON_RESET
)
2583 ERROR("XScale target requires a reset");
2584 ERROR("Reset target to enable debug");
2596 int xscale_init_arch_info(target_t
*target
, xscale_common_t
*xscale
, int chain_pos
, char *variant
)
2598 armv4_5_common_t
*armv4_5
;
2599 u32 high_reset_branch
, low_reset_branch
;
2602 armv4_5
= &xscale
->armv4_5_common
;
2604 /* store architecture specfic data (none so far) */
2605 xscale
->arch_info
= NULL
;
2606 xscale
->common_magic
= XSCALE_COMMON_MAGIC
;
2608 /* remember the variant (PXA25x, PXA27x, IXP42x, ...) */
2609 xscale
->variant
= strdup(variant
);
2611 /* prepare JTAG information for the new target */
2612 xscale
->jtag_info
.chain_pos
= chain_pos
;
2613 jtag_register_event_callback(xscale_jtag_callback
, target
);
2615 xscale
->jtag_info
.dbgrx
= 0x02;
2616 xscale
->jtag_info
.dbgtx
= 0x10;
2617 xscale
->jtag_info
.dcsr
= 0x09;
2618 xscale
->jtag_info
.ldic
= 0x07;
2620 if ((strcmp(xscale
->variant
, "pxa250") == 0) ||
2621 (strcmp(xscale
->variant
, "pxa255") == 0) ||
2622 (strcmp(xscale
->variant
, "pxa26x") == 0))
2624 xscale
->jtag_info
.ir_length
= 5;
2626 else if ((strcmp(xscale
->variant
, "pxa27x") == 0) ||
2627 (strcmp(xscale
->variant
, "ixp42x") == 0) ||
2628 (strcmp(xscale
->variant
, "ixp45x") == 0) ||
2629 (strcmp(xscale
->variant
, "ixp46x") == 0))
2631 xscale
->jtag_info
.ir_length
= 7;
2634 /* the debug handler isn't installed (and thus not running) at this time */
2635 xscale
->handler_installed
= 0;
2636 xscale
->handler_running
= 0;
2637 xscale
->handler_address
= 0xfe000800;
2639 /* clear the vectors we keep locally for reference */
2640 memset(xscale
->low_vectors
, 0, sizeof(xscale
->low_vectors
));
2641 memset(xscale
->high_vectors
, 0, sizeof(xscale
->high_vectors
));
2643 /* no user-specified vectors have been configured yet */
2644 xscale
->static_low_vectors_set
= 0x0;
2645 xscale
->static_high_vectors_set
= 0x0;
2647 /* calculate branches to debug handler */
2648 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
2649 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
2651 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
2652 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
2654 for (i
= 1; i
<= 7; i
++)
2656 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
2657 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
2660 /* 64kB aligned region used for DCache cleaning */
2661 xscale
->cache_clean_address
= 0xfffe0000;
2663 xscale
->hold_rst
= 0;
2664 xscale
->external_debug_break
= 0;
2666 xscale
->force_hw_bkpts
= 1;
2668 xscale
->ibcr_available
= 2;
2669 xscale
->ibcr0_used
= 0;
2670 xscale
->ibcr1_used
= 0;
2672 xscale
->dbr_available
= 2;
2673 xscale
->dbr0_used
= 0;
2674 xscale
->dbr1_used
= 0;
2676 xscale
->arm_bkpt
= ARMV5_BKPT(0x0);
2677 xscale
->thumb_bkpt
= ARMV5_T_BKPT(0x0) & 0xffff;
2679 xscale
->vector_catch
= 0x1;
2681 xscale
->trace_buffer_enabled
= 0;
2682 xscale
->trace_buffer_fill
= 0;
2684 /* prepare ARMv4/5 specific information */
2685 armv4_5
->arch_info
= xscale
;
2686 armv4_5
->read_core_reg
= xscale_read_core_reg
;
2687 armv4_5
->write_core_reg
= xscale_write_core_reg
;
2688 armv4_5
->full_context
= xscale_full_context
;
2690 armv4_5_init_arch_info(target
, armv4_5
);
2692 xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
2693 xscale
->armv4_5_mmu
.get_ttb
= xscale_get_ttb
;
2694 xscale
->armv4_5_mmu
.read_memory
= xscale_read_memory
;
2695 xscale
->armv4_5_mmu
.write_memory
= xscale_write_memory
;
2696 xscale
->armv4_5_mmu
.disable_mmu_caches
= xscale_disable_mmu_caches
;
2697 xscale
->armv4_5_mmu
.enable_mmu_caches
= xscale_enable_mmu_caches
;
2698 xscale
->armv4_5_mmu
.has_tiny_pages
= 1;
2699 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
2704 /* target xscale <endianess> <startup_mode> <chain_pos> <variant> */
2705 int xscale_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
)
2708 char *variant
= NULL
;
2709 xscale_common_t
*xscale
= malloc(sizeof(xscale_common_t
));
2713 ERROR("'target xscale' requires four arguments: <endianess> <startup_mode> <chain_pos> <variant>");
2717 chain_pos
= strtoul(args
[3], NULL
, 0);
2721 xscale_init_arch_info(target
, xscale
, chain_pos
, variant
);
2722 xscale_build_reg_cache(target
);
2727 int xscale_handle_debug_handler_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2729 target_t
*target
= NULL
;
2730 armv4_5_common_t
*armv4_5
;
2731 xscale_common_t
*xscale
;
2733 u32 handler_address
;
2737 ERROR("'xscale debug_handler <target#> <address>' command takes two required operands");
2741 if ((target
= get_target_by_num(strtoul(args
[0], NULL
, 0))) == NULL
)
2743 ERROR("no target '%s' configured", args
[0]);
2747 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
2749 command_print(cmd_ctx
, "target isn't an ARM920t target");
2753 handler_address
= strtoul(args
[1], NULL
, 0);
2755 if (((handler_address
>= 0x800) && (handler_address
<= 0x1fef800)) ||
2756 ((handler_address
>= 0xfe000800) && (handler_address
<= 0xfffff800)))
2758 xscale
->handler_address
= handler_address
;
2762 ERROR("xscale debug_handler <address> must be between 0x800 and 0x1fef800 or between 0xfe000800 and 0xfffff800");
2768 int xscale_handle_cache_clean_address_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2770 target_t
*target
= NULL
;
2771 armv4_5_common_t
*armv4_5
;
2772 xscale_common_t
*xscale
;
2774 u32 cache_clean_address
;
2778 ERROR("'xscale cache_clean_address <target#> <address>' command takes two required operands");
2782 if ((target
= get_target_by_num(strtoul(args
[0], NULL
, 0))) == NULL
)
2784 ERROR("no target '%s' configured", args
[0]);
2788 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
2790 command_print(cmd_ctx
, "target isn't an XScale target");
2794 cache_clean_address
= strtoul(args
[1], NULL
, 0);
2796 if (cache_clean_address
& 0xffff)
2798 ERROR("xscale cache_clean_address <address> must be 64kb aligned");
2802 xscale
->cache_clean_address
= cache_clean_address
;
2808 int xscale_handle_cache_info_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2810 target_t
*target
= get_current_target(cmd_ctx
);
2811 armv4_5_common_t
*armv4_5
;
2812 xscale_common_t
*xscale
;
2814 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
2816 command_print(cmd_ctx
, "target isn't an XScale target");
2820 return armv4_5_handle_cache_info_command(cmd_ctx
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
2823 int xscale_handle_virt2phys_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2825 target_t
*target
= get_current_target(cmd_ctx
);
2826 armv4_5_common_t
*armv4_5
;
2827 xscale_common_t
*xscale
;
2829 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
2831 command_print(cmd_ctx
, "target isn't an XScale target");
2835 if (target
->state
!= TARGET_HALTED
)
2837 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
2841 return armv4_5_mmu_handle_virt2phys_command(cmd_ctx
, cmd
, args
, argc
, target
, &xscale
->armv4_5_mmu
);
2844 int xscale_handle_mmu_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2846 target_t
*target
= get_current_target(cmd_ctx
);
2847 armv4_5_common_t
*armv4_5
;
2848 xscale_common_t
*xscale
;
2850 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
2852 command_print(cmd_ctx
, "target isn't an XScale target");
2856 if (target
->state
!= TARGET_HALTED
)
2858 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
2864 if (strcmp("enable", args
[0]) == 0)
2866 xscale_enable_mmu_caches(target
, 1, 0, 0);
2867 xscale
->armv4_5_mmu
.mmu_enabled
= 1;
2869 else if (strcmp("disable", args
[0]) == 0)
2871 xscale_disable_mmu_caches(target
, 1, 0, 0);
2872 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
2876 command_print(cmd_ctx
, "mmu %s", (xscale
->armv4_5_mmu
.mmu_enabled
) ? "enabled" : "disabled");
2881 int xscale_handle_idcache_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2883 target_t
*target
= get_current_target(cmd_ctx
);
2884 armv4_5_common_t
*armv4_5
;
2885 xscale_common_t
*xscale
;
2886 int icache
= 0, dcache
= 0;
2888 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
2890 command_print(cmd_ctx
, "target isn't an XScale target");
2894 if (target
->state
!= TARGET_HALTED
)
2896 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
2900 if (strcmp(cmd
, "icache") == 0)
2902 else if (strcmp(cmd
, "dcache") == 0)
2907 if (strcmp("enable", args
[0]) == 0)
2909 xscale_enable_mmu_caches(target
, 0, dcache
, icache
);
2912 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 1;
2914 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 1;
2916 else if (strcmp("disable", args
[0]) == 0)
2918 xscale_disable_mmu_caches(target
, 0, dcache
, icache
);
2921 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 0;
2923 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 0;
2928 command_print(cmd_ctx
, "icache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
) ? "enabled" : "disabled");
2931 command_print(cmd_ctx
, "dcache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
) ? "enabled" : "disabled");
2936 int xscale_handle_vector_catch_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2938 target_t
*target
= get_current_target(cmd_ctx
);
2939 armv4_5_common_t
*armv4_5
;
2940 xscale_common_t
*xscale
;
2942 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
2944 command_print(cmd_ctx
, "target isn't an XScale target");
2950 command_print(cmd_ctx
, "usage: xscale vector_catch [mask]");
2954 xscale
->vector_catch
= strtoul(args
[0], NULL
, 0);
2955 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 8, xscale
->vector_catch
);
2956 xscale_write_dcsr(target
, -1, -1);
2959 command_print(cmd_ctx
, "vector catch mask: 0x%2.2x", xscale
->vector_catch
);
2964 int xscale_handle_force_hw_bkpts_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2966 target_t
*target
= get_current_target(cmd_ctx
);
2967 armv4_5_common_t
*armv4_5
;
2968 xscale_common_t
*xscale
;
2970 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
2972 command_print(cmd_ctx
, "target isn't an XScale target");
2976 if ((argc
>= 1) && (strcmp("enable", args
[0]) == 0))
2978 xscale
->force_hw_bkpts
= 1;
2980 else if ((argc
>= 1) && (strcmp("disable", args
[0]) == 0))
2982 xscale
->force_hw_bkpts
= 0;
2986 command_print(cmd_ctx
, "usage: xscale force_hw_bkpts <enable|disable>");
2989 command_print(cmd_ctx
, "force hardware breakpoints %s", (xscale
->force_hw_bkpts
) ? "enabled" : "disabled");
2994 int xscale_handle_trace_buffer_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2996 target_t
*target
= get_current_target(cmd_ctx
);
2997 armv4_5_common_t
*armv4_5
;
2998 xscale_common_t
*xscale
;
3001 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3003 command_print(cmd_ctx
, "target isn't an XScale target");
3007 if (target
->state
!= TARGET_HALTED
)
3009 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3013 if ((argc
>= 1) && (strcmp("enable", args
[0]) == 0))
3015 xscale
->trace_buffer_enabled
= 1;
3017 else if ((argc
>= 1) && (strcmp("disable", args
[0]) == 0))
3019 xscale
->trace_buffer_enabled
= 0;
3022 if ((argc
>= 2) && (strcmp("fill", args
[1]) == 0))
3024 xscale
->trace_buffer_fill
= 1;
3026 else if ((argc
>= 2) && (strcmp("wrap", args
[1]) == 0))
3028 xscale
->trace_buffer_fill
= 0;
3031 command_print(cmd_ctx
, "trace buffer %s (%s)",
3032 (xscale
->trace_buffer_enabled
) ? "enabled" : "disabled",
3033 (xscale
->trace_buffer_fill
) ? "fill" : "wrap");
3035 dcsr_value
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32);
3036 if (xscale
->trace_buffer_fill
)
3037 xscale_write_dcsr_sw(target
, (dcsr_value
& 0xfffffffc) | 2);
3039 xscale_write_dcsr_sw(target
, dcsr_value
& 0xfffffffc);
3044 int xscale_handle_dump_trace_buffer_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3046 target_t
*target
= get_current_target(cmd_ctx
);
3047 armv4_5_common_t
*armv4_5
;
3048 xscale_common_t
*xscale
;
3049 u32 trace_buffer
[258];
3050 int is_address
[256];
3053 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3055 command_print(cmd_ctx
, "target isn't an XScale target");
3059 if (target
->state
!= TARGET_HALTED
)
3061 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3065 /* send read trace buffer command (command 0x61) */
3066 xscale_send_u32(target
, 0x61);
3068 /* receive trace buffer content */
3069 xscale_receive(target
, trace_buffer
, 258);
3071 for (i
= 255; i
>= 0; i
--)
3074 if (((trace_buffer
[i
] & 0xf0) == 0x90) ||
3075 ((trace_buffer
[i
] & 0xf0) == 0xd0))
3078 is_address
[--i
] = 1;
3080 is_address
[--i
] = 1;
3082 is_address
[--i
] = 1;
3084 is_address
[--i
] = 1;
3088 for (i
= 0; i
< 256; i
++)
3091 command_print(cmd_ctx
, "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x",
3092 trace_buffer
[i
+ 0], trace_buffer
[i
+ 1], trace_buffer
[i
+ 2], trace_buffer
[i
+ 3],
3093 trace_buffer
[i
+ 4], trace_buffer
[i
+ 5], trace_buffer
[i
+ 6], trace_buffer
[i
+ 6]
3099 command_print(cmd_ctx
, "address: 0x%2.2x%2.2x%2.2x%2.2x", trace_buffer
[i
], trace_buffer
[i
+1], trace_buffer
[i
+2], trace_buffer
[i
+3]);
3104 switch ((trace_buffer
[i
] & 0xf0) >> 4)
3107 command_print(cmd_ctx
, "0x%2.2x: reset exception", trace_buffer
[i
]);
3110 command_print(cmd_ctx
, "0x%2.2x: undef exception", trace_buffer
[i
]);
3113 command_print(cmd_ctx
, "0x%2.2x: swi exception", trace_buffer
[i
]);
3116 command_print(cmd_ctx
, "0x%2.2x: pabort exception", trace_buffer
[i
]);
3119 command_print(cmd_ctx
, "0x%2.2x: dabort exception", trace_buffer
[i
]);
3122 command_print(cmd_ctx
, "0x%2.2x: invalid", trace_buffer
[i
]);
3125 command_print(cmd_ctx
, "0x%2.2x: irq exception", trace_buffer
[i
]);
3128 command_print(cmd_ctx
, "0x%2.2x: fiq exception", trace_buffer
[i
]);
3131 command_print(cmd_ctx
, "0x%2.2x: direct branch", trace_buffer
[i
]);
3134 command_print(cmd_ctx
, "0x%2.2x: indirect branch", trace_buffer
[i
]);
3137 command_print(cmd_ctx
, "0x%2.2x: invalid", trace_buffer
[i
]);
3140 command_print(cmd_ctx
, "0x%2.2x: invalid", trace_buffer
[i
]);
3143 command_print(cmd_ctx
, "0x%2.2x: checkpointed direct branch", trace_buffer
[i
]);
3146 command_print(cmd_ctx
, "0x%2.2x: checkpointed indirect branch", trace_buffer
[i
]);
3149 command_print(cmd_ctx
, "0x%2.2x: invalid", trace_buffer
[i
]);
3152 command_print(cmd_ctx
, "0x%2.2x: rollover", trace_buffer
[i
]);
3158 command_print(cmd_ctx
, "chkpt0: 0x%8.8x, chkpt1: 0x%8.8x", trace_buffer
[256], trace_buffer
[257]);
3163 int xscale_register_commands(struct command_context_s
*cmd_ctx
)
3165 command_t
*xscale_cmd
;
3167 xscale_cmd
= register_command(cmd_ctx
, NULL
, "xscale", NULL
, COMMAND_ANY
, "xscale specific commands");
3169 register_command(cmd_ctx
, xscale_cmd
, "debug_handler", xscale_handle_debug_handler_command
, COMMAND_CONFIG
, NULL
);
3170 register_command(cmd_ctx
, xscale_cmd
, "cache_clean_address", xscale_handle_cache_clean_address_command
, COMMAND_ANY
, NULL
);
3172 register_command(cmd_ctx
, xscale_cmd
, "cache_info", xscale_handle_cache_info_command
, COMMAND_EXEC
, NULL
);
3173 register_command(cmd_ctx
, xscale_cmd
, "virt2phys", xscale_handle_virt2phys_command
, COMMAND_EXEC
, NULL
);
3174 register_command(cmd_ctx
, xscale_cmd
, "mmu", xscale_handle_mmu_command
, COMMAND_EXEC
, "['enable'|'disable'] the MMU");
3175 register_command(cmd_ctx
, xscale_cmd
, "icache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the ICache");
3176 register_command(cmd_ctx
, xscale_cmd
, "dcache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the DCache");
3178 register_command(cmd_ctx
, xscale_cmd
, "vector_catch", xscale_handle_idcache_command
, COMMAND_EXEC
, "<mask> of vectors that should be catched");
3180 register_command(cmd_ctx
, xscale_cmd
, "trace_buffer", xscale_handle_trace_buffer_command
, COMMAND_EXEC
, "<enable|disable> ['fill'|'wrap']");
3182 register_command(cmd_ctx
, xscale_cmd
, "dump_trace_buffer", xscale_handle_dump_trace_buffer_command
, COMMAND_EXEC
, "dump content of trace buffer");
3184 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)