1 /***************************************************************************
2 * Copyright (C) 2006, 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2007,2008 Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
27 #include "replacements.h"
31 #include "arm7_9_common.h"
35 #include "arm_simulator.h"
36 #include "arm_disassembler.h"
39 #include "binarybuffer.h"
40 #include "time_support.h"
41 #include "breakpoints.h"
47 #include <sys/types.h>
53 int xscale_register_commands(struct command_context_s
*cmd_ctx
);
55 /* forward declarations */
56 int xscale_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
);
57 int xscale_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
);
58 int xscale_quit(void);
60 int xscale_arch_state(struct target_s
*target
);
61 int xscale_poll(target_t
*target
);
62 int xscale_halt(target_t
*target
);
63 int xscale_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
);
64 int xscale_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
);
65 int xscale_debug_entry(target_t
*target
);
66 int xscale_restore_context(target_t
*target
);
68 int xscale_assert_reset(target_t
*target
);
69 int xscale_deassert_reset(target_t
*target
);
70 int xscale_soft_reset_halt(struct target_s
*target
);
72 int xscale_set_reg_u32(reg_t
*reg
, u32 value
);
74 int xscale_read_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
);
75 int xscale_write_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
, u32 value
);
77 int xscale_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
);
78 int xscale_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
);
79 int xscale_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
);
81 int xscale_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
82 int xscale_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
83 int xscale_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
84 int xscale_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
85 int xscale_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
);
86 int xscale_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
);
87 void xscale_enable_watchpoints(struct target_s
*target
);
88 void xscale_enable_breakpoints(struct target_s
*target
);
89 static int xscale_virt2phys(struct target_s
*target
, u32
virtual, u32
*physical
);
90 static int xscale_mmu(struct target_s
*target
, int *enabled
);
92 int xscale_read_trace(target_t
*target
);
94 target_type_t xscale_target
=
99 .arch_state
= xscale_arch_state
,
101 .target_request_data
= NULL
,
104 .resume
= xscale_resume
,
107 .assert_reset
= xscale_assert_reset
,
108 .deassert_reset
= xscale_deassert_reset
,
109 .soft_reset_halt
= xscale_soft_reset_halt
,
111 .get_gdb_reg_list
= armv4_5_get_gdb_reg_list
,
113 .read_memory
= xscale_read_memory
,
114 .write_memory
= xscale_write_memory
,
115 .bulk_write_memory
= xscale_bulk_write_memory
,
116 .checksum_memory
= arm7_9_checksum_memory
,
117 .blank_check_memory
= arm7_9_blank_check_memory
,
119 .run_algorithm
= armv4_5_run_algorithm
,
121 .add_breakpoint
= xscale_add_breakpoint
,
122 .remove_breakpoint
= xscale_remove_breakpoint
,
123 .add_watchpoint
= xscale_add_watchpoint
,
124 .remove_watchpoint
= xscale_remove_watchpoint
,
126 .register_commands
= xscale_register_commands
,
127 .target_command
= xscale_target_command
,
128 .init_target
= xscale_init_target
,
131 .virt2phys
= xscale_virt2phys
,
135 char* xscale_reg_list
[] =
137 "XSCALE_MAINID", /* 0 */
147 "XSCALE_IBCR0", /* 10 */
157 "XSCALE_RX", /* 20 */
161 xscale_reg_t xscale_reg_arch_info
[] =
163 {XSCALE_MAINID
, NULL
},
164 {XSCALE_CACHETYPE
, NULL
},
166 {XSCALE_AUXCTRL
, NULL
},
172 {XSCALE_CPACCESS
, NULL
},
173 {XSCALE_IBCR0
, NULL
},
174 {XSCALE_IBCR1
, NULL
},
177 {XSCALE_DBCON
, NULL
},
178 {XSCALE_TBREG
, NULL
},
179 {XSCALE_CHKPT0
, NULL
},
180 {XSCALE_CHKPT1
, NULL
},
181 {XSCALE_DCSR
, NULL
}, /* DCSR accessed via JTAG or SW */
182 {-1, NULL
}, /* TX accessed via JTAG */
183 {-1, NULL
}, /* RX accessed via JTAG */
184 {-1, NULL
}, /* TXRXCTRL implicit access via JTAG */
187 int xscale_reg_arch_type
= -1;
189 int xscale_get_reg(reg_t
*reg
);
190 int xscale_set_reg(reg_t
*reg
, u8
*buf
);
192 int xscale_get_arch_pointers(target_t
*target
, armv4_5_common_t
**armv4_5_p
, xscale_common_t
**xscale_p
)
194 armv4_5_common_t
*armv4_5
= target
->arch_info
;
195 xscale_common_t
*xscale
= armv4_5
->arch_info
;
197 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
199 LOG_ERROR("target isn't an XScale target");
203 if (xscale
->common_magic
!= XSCALE_COMMON_MAGIC
)
205 LOG_ERROR("target isn't an XScale target");
209 *armv4_5_p
= armv4_5
;
215 int xscale_jtag_set_instr(int chain_pos
, u32 new_instr
)
217 jtag_device_t
*device
= jtag_get_device(chain_pos
);
219 if (buf_get_u32(device
->cur_instr
, 0, device
->ir_length
) != new_instr
)
223 field
.device
= chain_pos
;
224 field
.num_bits
= device
->ir_length
;
225 field
.out_value
= calloc(CEIL(field
.num_bits
, 8), 1);
226 buf_set_u32(field
.out_value
, 0, field
.num_bits
, new_instr
);
227 field
.out_mask
= NULL
;
228 field
.in_value
= NULL
;
229 jtag_set_check_value(&field
, device
->expected
, device
->expected_mask
, NULL
);
231 jtag_add_ir_scan(1, &field
, -1);
233 free(field
.out_value
);
239 int xscale_read_dcsr(target_t
*target
)
241 armv4_5_common_t
*armv4_5
= target
->arch_info
;
242 xscale_common_t
*xscale
= armv4_5
->arch_info
;
246 scan_field_t fields
[3];
248 u8 field0_check_value
= 0x2;
249 u8 field0_check_mask
= 0x7;
251 u8 field2_check_value
= 0x0;
252 u8 field2_check_mask
= 0x1;
254 jtag_add_end_state(TAP_PD
);
255 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dcsr
);
257 buf_set_u32(&field0
, 1, 1, xscale
->hold_rst
);
258 buf_set_u32(&field0
, 2, 1, xscale
->external_debug_break
);
260 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
261 fields
[0].num_bits
= 3;
262 fields
[0].out_value
= &field0
;
263 fields
[0].out_mask
= NULL
;
264 fields
[0].in_value
= NULL
;
265 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
267 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
268 fields
[1].num_bits
= 32;
269 fields
[1].out_value
= NULL
;
270 fields
[1].out_mask
= NULL
;
271 fields
[1].in_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
272 fields
[1].in_handler
= NULL
;
273 fields
[1].in_handler_priv
= NULL
;
274 fields
[1].in_check_value
= NULL
;
275 fields
[1].in_check_mask
= NULL
;
277 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
278 fields
[2].num_bits
= 1;
279 fields
[2].out_value
= &field2
;
280 fields
[2].out_mask
= NULL
;
281 fields
[2].in_value
= NULL
;
282 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
284 jtag_add_dr_scan(3, fields
, -1);
286 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
288 LOG_ERROR("JTAG error while reading DCSR");
292 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].dirty
= 0;
293 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].valid
= 1;
295 /* write the register with the value we just read
296 * on this second pass, only the first bit of field0 is guaranteed to be 0)
298 field0_check_mask
= 0x1;
299 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
300 fields
[1].in_value
= NULL
;
302 jtag_add_end_state(TAP_RTI
);
304 jtag_add_dr_scan(3, fields
, -1);
306 /* DANGER!!! this must be here. It will make sure that the arguments
307 * to jtag_set_check_value() does not go out of scope! */
308 return jtag_execute_queue();
311 int xscale_receive(target_t
*target
, u32
*buffer
, int num_words
)
314 return ERROR_INVALID_ARGUMENTS
;
317 armv4_5_common_t
*armv4_5
= target
->arch_info
;
318 xscale_common_t
*xscale
= armv4_5
->arch_info
;
320 enum tap_state path
[3];
321 scan_field_t fields
[3];
323 u8
*field0
= malloc(num_words
* 1);
324 u8 field0_check_value
= 0x2;
325 u8 field0_check_mask
= 0x6;
326 u32
*field1
= malloc(num_words
* 4);
327 u8 field2_check_value
= 0x0;
328 u8 field2_check_mask
= 0x1;
330 int words_scheduled
= 0;
338 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
339 fields
[0].num_bits
= 3;
340 fields
[0].out_value
= NULL
;
341 fields
[0].out_mask
= NULL
;
342 fields
[0].in_value
= NULL
;
343 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
345 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
346 fields
[1].num_bits
= 32;
347 fields
[1].out_value
= NULL
;
348 fields
[1].out_mask
= NULL
;
349 fields
[1].in_value
= NULL
;
350 fields
[1].in_handler
= NULL
;
351 fields
[1].in_handler_priv
= NULL
;
352 fields
[1].in_check_value
= NULL
;
353 fields
[1].in_check_mask
= NULL
;
357 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
358 fields
[2].num_bits
= 1;
359 fields
[2].out_value
= NULL
;
360 fields
[2].out_mask
= NULL
;
361 fields
[2].in_value
= NULL
;
362 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
364 jtag_add_end_state(TAP_RTI
);
365 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dbgtx
);
366 jtag_add_runtest(1, -1); /* ensures that we're in the TAP_RTI state as the above could be a no-op */
368 /* repeat until all words have been collected */
370 while (words_done
< num_words
)
374 for (i
= words_done
; i
< num_words
; i
++)
376 fields
[0].in_value
= &field0
[i
];
377 fields
[1].in_handler
= buf_to_u32_handler
;
378 fields
[1].in_handler_priv
= (u8
*)&field1
[i
];
380 jtag_add_pathmove(3, path
);
381 jtag_add_dr_scan(3, fields
, TAP_RTI
);
385 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
387 LOG_ERROR("JTAG error while receiving data from debug handler");
391 /* examine results */
392 for (i
= words_done
; i
< num_words
; i
++)
394 if (!(field0
[0] & 1))
396 /* move backwards if necessary */
398 for (j
= i
; j
< num_words
- 1; j
++)
400 field0
[j
] = field0
[j
+1];
401 field1
[j
] = field1
[j
+1];
406 if (words_scheduled
==0)
408 if (attempts
++==1000)
410 LOG_ERROR("Failed to receiving data from debug handler after 1000 attempts");
411 retval
=ERROR_TARGET_TIMEOUT
;
416 words_done
+= words_scheduled
;
419 for (i
= 0; i
< num_words
; i
++)
420 *(buffer
++) = buf_get_u32((u8
*)&field1
[i
], 0, 32);
427 int xscale_read_tx(target_t
*target
, int consume
)
429 armv4_5_common_t
*armv4_5
= target
->arch_info
;
430 xscale_common_t
*xscale
= armv4_5
->arch_info
;
431 enum tap_state path
[3];
432 enum tap_state noconsume_path
[6];
435 struct timeval timeout
, now
;
437 scan_field_t fields
[3];
439 u8 field0_check_value
= 0x2;
440 u8 field0_check_mask
= 0x6;
441 u8 field2_check_value
= 0x0;
442 u8 field2_check_mask
= 0x1;
444 jtag_add_end_state(TAP_RTI
);
446 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dbgtx
);
452 noconsume_path
[0] = TAP_SDS
;
453 noconsume_path
[1] = TAP_CD
;
454 noconsume_path
[2] = TAP_E1D
;
455 noconsume_path
[3] = TAP_PD
;
456 noconsume_path
[4] = TAP_E2D
;
457 noconsume_path
[5] = TAP_SD
;
459 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
460 fields
[0].num_bits
= 3;
461 fields
[0].out_value
= NULL
;
462 fields
[0].out_mask
= NULL
;
463 fields
[0].in_value
= &field0_in
;
464 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
466 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
467 fields
[1].num_bits
= 32;
468 fields
[1].out_value
= NULL
;
469 fields
[1].out_mask
= NULL
;
470 fields
[1].in_value
= xscale
->reg_cache
->reg_list
[XSCALE_TX
].value
;
471 fields
[1].in_handler
= NULL
;
472 fields
[1].in_handler_priv
= NULL
;
473 fields
[1].in_check_value
= NULL
;
474 fields
[1].in_check_mask
= NULL
;
478 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
479 fields
[2].num_bits
= 1;
480 fields
[2].out_value
= NULL
;
481 fields
[2].out_mask
= NULL
;
482 fields
[2].in_value
= NULL
;
483 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
485 gettimeofday(&timeout
, NULL
);
486 timeval_add_time(&timeout
, 1, 0);
490 /* if we want to consume the register content (i.e. clear TX_READY),
491 * we have to go straight from Capture-DR to Shift-DR
492 * otherwise, we go from Capture-DR to Exit1-DR to Pause-DR
495 jtag_add_pathmove(3, path
);
498 jtag_add_pathmove(sizeof(noconsume_path
)/sizeof(*noconsume_path
), noconsume_path
);
501 jtag_add_dr_scan(3, fields
, TAP_RTI
);
503 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
505 LOG_ERROR("JTAG error while reading TX");
506 return ERROR_TARGET_TIMEOUT
;
509 gettimeofday(&now
, NULL
);
510 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
)&& (now
.tv_usec
> timeout
.tv_usec
)))
512 LOG_ERROR("time out reading TX register");
513 return ERROR_TARGET_TIMEOUT
;
515 if (!((!(field0_in
& 1)) && consume
))
521 LOG_DEBUG("waiting 10ms");
522 usleep(10*1000); /* avoid flooding the logs */
527 if (!(field0_in
& 1))
528 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
533 int xscale_write_rx(target_t
*target
)
535 armv4_5_common_t
*armv4_5
= target
->arch_info
;
536 xscale_common_t
*xscale
= armv4_5
->arch_info
;
539 struct timeval timeout
, now
;
541 scan_field_t fields
[3];
544 u8 field0_check_value
= 0x2;
545 u8 field0_check_mask
= 0x6;
547 u8 field2_check_value
= 0x0;
548 u8 field2_check_mask
= 0x1;
550 jtag_add_end_state(TAP_RTI
);
552 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dbgrx
);
554 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
555 fields
[0].num_bits
= 3;
556 fields
[0].out_value
= &field0_out
;
557 fields
[0].out_mask
= NULL
;
558 fields
[0].in_value
= &field0_in
;
559 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
561 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
562 fields
[1].num_bits
= 32;
563 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
;
564 fields
[1].out_mask
= NULL
;
565 fields
[1].in_value
= NULL
;
566 fields
[1].in_handler
= NULL
;
567 fields
[1].in_handler_priv
= NULL
;
568 fields
[1].in_check_value
= NULL
;
569 fields
[1].in_check_mask
= NULL
;
573 fields
[2].device
= xscale
->jtag_info
.chain_pos
;
574 fields
[2].num_bits
= 1;
575 fields
[2].out_value
= &field2
;
576 fields
[2].out_mask
= NULL
;
577 fields
[2].in_value
= NULL
;
578 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
580 gettimeofday(&timeout
, NULL
);
581 timeval_add_time(&timeout
, 1, 0);
583 /* poll until rx_read is low */
584 LOG_DEBUG("polling RX");
587 jtag_add_dr_scan(3, fields
, TAP_RTI
);
589 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
591 LOG_ERROR("JTAG error while writing RX");
595 gettimeofday(&now
, NULL
);
596 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
)&& (now
.tv_usec
> timeout
.tv_usec
)))
598 LOG_ERROR("time out writing RX register");
599 return ERROR_TARGET_TIMEOUT
;
601 if (!(field0_in
& 1))
605 LOG_DEBUG("waiting 10ms");
606 usleep(10*1000); /* avoid flooding the logs */
613 jtag_add_dr_scan(3, fields
, TAP_RTI
);
615 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
617 LOG_ERROR("JTAG error while writing RX");
624 /* send count elements of size byte to the debug handler */
625 int xscale_send(target_t
*target
, u8
*buffer
, int count
, int size
)
627 armv4_5_common_t
*armv4_5
= target
->arch_info
;
628 xscale_common_t
*xscale
= armv4_5
->arch_info
;
636 jtag_add_end_state(TAP_RTI
);
638 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dbgrx
);
645 int endianness
= target
->endianness
;
646 while (done_count
++ < count
)
651 if (endianness
== TARGET_LITTLE_ENDIAN
)
653 t
[1]=le_to_h_u32(buffer
);
656 t
[1]=be_to_h_u32(buffer
);
660 if (endianness
== TARGET_LITTLE_ENDIAN
)
662 t
[1]=le_to_h_u16(buffer
);
665 t
[1]=be_to_h_u16(buffer
);
672 LOG_ERROR("BUG: size neither 4, 2 nor 1");
675 jtag_add_dr_out(xscale
->jtag_info
.chain_pos
,
683 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
685 LOG_ERROR("JTAG error while sending data to debug handler");
692 int xscale_send_u32(target_t
*target
, u32 value
)
694 armv4_5_common_t
*armv4_5
= target
->arch_info
;
695 xscale_common_t
*xscale
= armv4_5
->arch_info
;
697 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
698 return xscale_write_rx(target
);
701 int xscale_write_dcsr(target_t
*target
, int hold_rst
, int ext_dbg_brk
)
703 armv4_5_common_t
*armv4_5
= target
->arch_info
;
704 xscale_common_t
*xscale
= armv4_5
->arch_info
;
708 scan_field_t fields
[3];
710 u8 field0_check_value
= 0x2;
711 u8 field0_check_mask
= 0x7;
713 u8 field2_check_value
= 0x0;
714 u8 field2_check_mask
= 0x1;
717 xscale
->hold_rst
= hold_rst
;
719 if (ext_dbg_brk
!= -1)
720 xscale
->external_debug_break
= ext_dbg_brk
;
722 jtag_add_end_state(TAP_RTI
);
723 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dcsr
);
725 buf_set_u32(&field0
, 1, 1, xscale
->hold_rst
);
726 buf_set_u32(&field0
, 2, 1, xscale
->external_debug_break
);
728 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
729 fields
[0].num_bits
= 3;
730 fields
[0].out_value
= &field0
;
731 fields
[0].out_mask
= NULL
;
732 fields
[0].in_value
= NULL
;
733 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
735 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
736 fields
[1].num_bits
= 32;
737 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
738 fields
[1].out_mask
= NULL
;
739 fields
[1].in_value
= NULL
;
740 fields
[1].in_handler
= NULL
;
741 fields
[1].in_handler_priv
= NULL
;
742 fields
[1].in_check_value
= NULL
;
743 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 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
754 jtag_add_dr_scan(3, fields
, -1);
756 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
758 LOG_ERROR("JTAG error while writing DCSR");
762 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].dirty
= 0;
763 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].valid
= 1;
768 /* parity of the number of bits 0 if even; 1 if odd. for 32 bit words */
769 unsigned int parity (unsigned int v
)
776 LOG_DEBUG("parity of 0x%x is %i", ov
, (0x6996 >> v
) & 1);
777 return (0x6996 >> v
) & 1;
780 int xscale_load_ic(target_t
*target
, int mini
, u32 va
, u32 buffer
[8])
782 armv4_5_common_t
*armv4_5
= target
->arch_info
;
783 xscale_common_t
*xscale
= armv4_5
->arch_info
;
788 scan_field_t fields
[2];
790 LOG_DEBUG("loading miniIC at 0x%8.8x", va
);
792 jtag_add_end_state(TAP_RTI
);
793 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.ldic
); /* LDIC */
795 /* CMD is b010 for Main IC and b011 for Mini IC */
797 buf_set_u32(&cmd
, 0, 3, 0x3);
799 buf_set_u32(&cmd
, 0, 3, 0x2);
801 buf_set_u32(&cmd
, 3, 3, 0x0);
803 /* virtual address of desired cache line */
804 buf_set_u32(packet
, 0, 27, va
>> 5);
806 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
807 fields
[0].num_bits
= 6;
808 fields
[0].out_value
= &cmd
;
809 fields
[0].out_mask
= NULL
;
810 fields
[0].in_value
= NULL
;
811 fields
[0].in_check_value
= NULL
;
812 fields
[0].in_check_mask
= NULL
;
813 fields
[0].in_handler
= NULL
;
814 fields
[0].in_handler_priv
= NULL
;
816 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
817 fields
[1].num_bits
= 27;
818 fields
[1].out_value
= packet
;
819 fields
[1].out_mask
= NULL
;
820 fields
[1].in_value
= NULL
;
821 fields
[1].in_check_value
= NULL
;
822 fields
[1].in_check_mask
= NULL
;
823 fields
[1].in_handler
= NULL
;
824 fields
[1].in_handler_priv
= NULL
;
826 jtag_add_dr_scan(2, fields
, -1);
828 fields
[0].num_bits
= 32;
829 fields
[0].out_value
= packet
;
831 fields
[1].num_bits
= 1;
832 fields
[1].out_value
= &cmd
;
834 for (word
= 0; word
< 8; word
++)
836 buf_set_u32(packet
, 0, 32, buffer
[word
]);
837 cmd
= parity(*((u32
*)packet
));
838 jtag_add_dr_scan(2, fields
, -1);
841 jtag_execute_queue();
846 int xscale_invalidate_ic_line(target_t
*target
, u32 va
)
848 armv4_5_common_t
*armv4_5
= target
->arch_info
;
849 xscale_common_t
*xscale
= armv4_5
->arch_info
;
853 scan_field_t fields
[2];
855 jtag_add_end_state(TAP_RTI
);
856 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.ldic
); /* LDIC */
858 /* CMD for invalidate IC line b000, bits [6:4] b000 */
859 buf_set_u32(&cmd
, 0, 6, 0x0);
861 /* virtual address of desired cache line */
862 buf_set_u32(packet
, 0, 27, va
>> 5);
864 fields
[0].device
= xscale
->jtag_info
.chain_pos
;
865 fields
[0].num_bits
= 6;
866 fields
[0].out_value
= &cmd
;
867 fields
[0].out_mask
= NULL
;
868 fields
[0].in_value
= NULL
;
869 fields
[0].in_check_value
= NULL
;
870 fields
[0].in_check_mask
= NULL
;
871 fields
[0].in_handler
= NULL
;
872 fields
[0].in_handler_priv
= NULL
;
874 fields
[1].device
= xscale
->jtag_info
.chain_pos
;
875 fields
[1].num_bits
= 27;
876 fields
[1].out_value
= packet
;
877 fields
[1].out_mask
= NULL
;
878 fields
[1].in_value
= NULL
;
879 fields
[1].in_check_value
= NULL
;
880 fields
[1].in_check_mask
= NULL
;
881 fields
[1].in_handler
= NULL
;
882 fields
[1].in_handler_priv
= NULL
;
884 jtag_add_dr_scan(2, fields
, -1);
889 int xscale_update_vectors(target_t
*target
)
891 armv4_5_common_t
*armv4_5
= target
->arch_info
;
892 xscale_common_t
*xscale
= armv4_5
->arch_info
;
896 u32 low_reset_branch
, high_reset_branch
;
898 for (i
= 1; i
< 8; i
++)
900 /* if there's a static vector specified for this exception, override */
901 if (xscale
->static_high_vectors_set
& (1 << i
))
903 xscale
->high_vectors
[i
] = xscale
->static_high_vectors
[i
];
907 retval
=target_read_u32(target
, 0xffff0000 + 4*i
, &xscale
->high_vectors
[i
]);
908 if (retval
== ERROR_TARGET_TIMEOUT
)
910 if (retval
!=ERROR_OK
)
912 /* Some of these reads will fail as part of normal execution */
913 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
918 for (i
= 1; i
< 8; i
++)
920 if (xscale
->static_low_vectors_set
& (1 << i
))
922 xscale
->low_vectors
[i
] = xscale
->static_low_vectors
[i
];
926 retval
=target_read_u32(target
, 0x0 + 4*i
, &xscale
->low_vectors
[i
]);
927 if (retval
== ERROR_TARGET_TIMEOUT
)
929 if (retval
!=ERROR_OK
)
931 /* Some of these reads will fail as part of normal execution */
932 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
937 /* calculate branches to debug handler */
938 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
939 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
941 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
942 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
944 /* invalidate and load exception vectors in mini i-cache */
945 xscale_invalidate_ic_line(target
, 0x0);
946 xscale_invalidate_ic_line(target
, 0xffff0000);
948 xscale_load_ic(target
, 1, 0x0, xscale
->low_vectors
);
949 xscale_load_ic(target
, 1, 0xffff0000, xscale
->high_vectors
);
954 int xscale_arch_state(struct target_s
*target
)
956 armv4_5_common_t
*armv4_5
= target
->arch_info
;
957 xscale_common_t
*xscale
= armv4_5
->arch_info
;
961 "disabled", "enabled"
964 char *arch_dbg_reason
[] =
966 "", "\n(processor reset)", "\n(trace buffer full)"
969 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
971 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
975 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
976 "cpsr: 0x%8.8x pc: 0x%8.8x\n"
977 "MMU: %s, D-Cache: %s, I-Cache: %s"
979 armv4_5_state_strings
[armv4_5
->core_state
],
980 target_debug_reason_strings
[target
->debug_reason
],
981 armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)],
982 buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32),
983 buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32),
984 state
[xscale
->armv4_5_mmu
.mmu_enabled
],
985 state
[xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
],
986 state
[xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
],
987 arch_dbg_reason
[xscale
->arch_debug_reason
]);
992 int xscale_poll(target_t
*target
)
995 armv4_5_common_t
*armv4_5
= target
->arch_info
;
996 xscale_common_t
*xscale
= armv4_5
->arch_info
;
998 if ((target
->state
== TARGET_RUNNING
) || (target
->state
== TARGET_DEBUG_RUNNING
))
1000 enum target_state previous_state
= target
->state
;
1001 if ((retval
= xscale_read_tx(target
, 0)) == ERROR_OK
)
1004 /* there's data to read from the tx register, we entered debug state */
1005 xscale
->handler_running
= 1;
1007 target
->state
= TARGET_HALTED
;
1009 /* process debug entry, fetching current mode regs */
1010 retval
= xscale_debug_entry(target
);
1012 else if (retval
!= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
1014 LOG_USER("error while polling TX register, reset CPU");
1015 /* here we "lie" so GDB won't get stuck and a reset can be perfomed */
1016 target
->state
= TARGET_HALTED
;
1019 /* debug_entry could have overwritten target state (i.e. immediate resume)
1020 * don't signal event handlers in that case
1022 if (target
->state
!= TARGET_HALTED
)
1025 /* if target was running, signal that we halted
1026 * otherwise we reentered from debug execution */
1027 if (previous_state
== TARGET_RUNNING
)
1028 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1030 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
1036 int xscale_debug_entry(target_t
*target
)
1038 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1039 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1047 /* clear external dbg break (will be written on next DCSR read) */
1048 xscale
->external_debug_break
= 0;
1049 if ((retval
=xscale_read_dcsr(target
))!=ERROR_OK
)
1052 /* get r0, pc, r1 to r7 and cpsr */
1053 if ((retval
=xscale_receive(target
, buffer
, 10))!=ERROR_OK
)
1056 /* move r0 from buffer to register cache */
1057 buf_set_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32, buffer
[0]);
1058 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
1059 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
1060 LOG_DEBUG("r0: 0x%8.8x", buffer
[0]);
1062 /* move pc from buffer to register cache */
1063 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, buffer
[1]);
1064 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
1065 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
1066 LOG_DEBUG("pc: 0x%8.8x", buffer
[1]);
1068 /* move data from buffer to register cache */
1069 for (i
= 1; i
<= 7; i
++)
1071 buf_set_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32, buffer
[1 + i
]);
1072 armv4_5
->core_cache
->reg_list
[i
].dirty
= 1;
1073 armv4_5
->core_cache
->reg_list
[i
].valid
= 1;
1074 LOG_DEBUG("r%i: 0x%8.8x", i
, buffer
[i
+ 1]);
1077 buf_set_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32, buffer
[9]);
1078 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].dirty
= 1;
1079 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].valid
= 1;
1080 LOG_DEBUG("cpsr: 0x%8.8x", buffer
[9]);
1082 armv4_5
->core_mode
= buffer
[9] & 0x1f;
1083 if (armv4_5_mode_to_number(armv4_5
->core_mode
) == -1)
1085 target
->state
= TARGET_UNKNOWN
;
1086 LOG_ERROR("cpsr contains invalid mode value - communication failure");
1087 return ERROR_TARGET_FAILURE
;
1089 LOG_DEBUG("target entered debug state in %s mode", armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)]);
1091 if (buffer
[9] & 0x20)
1092 armv4_5
->core_state
= ARMV4_5_STATE_THUMB
;
1094 armv4_5
->core_state
= ARMV4_5_STATE_ARM
;
1097 if (armv4_5_mode_to_number(armv4_5
->core_mode
)==-1)
1100 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1101 if ((armv4_5
->core_mode
!= ARMV4_5_MODE_USR
) && (armv4_5
->core_mode
!= ARMV4_5_MODE_SYS
))
1103 xscale_receive(target
, buffer
, 8);
1104 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1105 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
1106 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
1110 /* r8 to r14, but no spsr */
1111 xscale_receive(target
, buffer
, 7);
1114 /* move data from buffer to register cache */
1115 for (i
= 8; i
<= 14; i
++)
1117 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).value
, 0, 32, buffer
[i
- 8]);
1118 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).dirty
= 0;
1119 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).valid
= 1;
1122 /* examine debug reason */
1123 xscale_read_dcsr(target
);
1124 moe
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 2, 3);
1126 /* stored PC (for calculating fixup) */
1127 pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1131 case 0x0: /* Processor reset */
1132 target
->debug_reason
= DBG_REASON_DBGRQ
;
1133 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_RESET
;
1136 case 0x1: /* Instruction breakpoint hit */
1137 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1138 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1141 case 0x2: /* Data breakpoint hit */
1142 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
1143 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1146 case 0x3: /* BKPT instruction executed */
1147 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1148 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1151 case 0x4: /* Ext. debug event */
1152 target
->debug_reason
= DBG_REASON_DBGRQ
;
1153 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1156 case 0x5: /* Vector trap occured */
1157 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1158 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1161 case 0x6: /* Trace buffer full break */
1162 target
->debug_reason
= DBG_REASON_DBGRQ
;
1163 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_TB_FULL
;
1166 case 0x7: /* Reserved */
1168 LOG_ERROR("Method of Entry is 'Reserved'");
1173 /* apply PC fixup */
1174 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, pc
);
1176 /* on the first debug entry, identify cache type */
1177 if (xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
1181 /* read cp15 cache type register */
1182 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
]);
1183 cache_type_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
].value
, 0, 32);
1185 armv4_5_identify_cache(cache_type_reg
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
1188 /* examine MMU and Cache settings */
1189 /* read cp15 control register */
1190 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
1191 xscale
->cp15_control_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
1192 xscale
->armv4_5_mmu
.mmu_enabled
= (xscale
->cp15_control_reg
& 0x1U
) ? 1 : 0;
1193 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= (xscale
->cp15_control_reg
& 0x4U
) ? 1 : 0;
1194 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= (xscale
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
1196 /* tracing enabled, read collected trace data */
1197 if (xscale
->trace
.buffer_enabled
)
1199 xscale_read_trace(target
);
1200 xscale
->trace
.buffer_fill
--;
1202 /* resume if we're still collecting trace data */
1203 if ((xscale
->arch_debug_reason
== XSCALE_DBG_REASON_TB_FULL
)
1204 && (xscale
->trace
.buffer_fill
> 0))
1206 xscale_resume(target
, 1, 0x0, 1, 0);
1210 xscale
->trace
.buffer_enabled
= 0;
1217 int xscale_halt(target_t
*target
)
1219 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1220 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1222 LOG_DEBUG("target->state: %s", target_state_strings
[target
->state
]);
1224 if (target
->state
== TARGET_HALTED
)
1226 LOG_DEBUG("target was already halted");
1229 else if (target
->state
== TARGET_UNKNOWN
)
1231 /* this must not happen for a xscale target */
1232 LOG_ERROR("target was in unknown state when halt was requested");
1233 return ERROR_TARGET_INVALID
;
1235 else if (target
->state
== TARGET_RESET
)
1237 LOG_DEBUG("target->state == TARGET_RESET");
1241 /* assert external dbg break */
1242 xscale
->external_debug_break
= 1;
1243 xscale_read_dcsr(target
);
1245 target
->debug_reason
= DBG_REASON_DBGRQ
;
1251 int xscale_enable_single_step(struct target_s
*target
, u32 next_pc
)
1253 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1254 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1255 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1257 if (xscale
->ibcr0_used
)
1259 breakpoint_t
*ibcr0_bp
= breakpoint_find(target
, buf_get_u32(ibcr0
->value
, 0, 32) & 0xfffffffe);
1263 xscale_unset_breakpoint(target
, ibcr0_bp
);
1267 LOG_ERROR("BUG: xscale->ibcr0_used is set, but no breakpoint with that address found");
1272 xscale_set_reg_u32(ibcr0
, next_pc
| 0x1);
1277 int xscale_disable_single_step(struct target_s
*target
)
1279 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1280 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1281 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1283 xscale_set_reg_u32(ibcr0
, 0x0);
1288 int xscale_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
1290 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1291 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1292 breakpoint_t
*breakpoint
= target
->breakpoints
;
1301 if (target
->state
!= TARGET_HALTED
)
1303 LOG_WARNING("target not halted");
1304 return ERROR_TARGET_NOT_HALTED
;
1307 if (!debug_execution
)
1309 target_free_all_working_areas(target
);
1312 /* update vector tables */
1313 if ((retval
=xscale_update_vectors(target
))!=ERROR_OK
)
1316 /* current = 1: continue on current pc, otherwise continue at <address> */
1318 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1320 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1322 /* if we're at the reset vector, we have to simulate the branch */
1323 if (current_pc
== 0x0)
1325 arm_simulate_step(target
, NULL
);
1326 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1329 /* the front-end may request us not to handle breakpoints */
1330 if (handle_breakpoints
)
1332 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1336 /* there's a breakpoint at the current PC, we have to step over it */
1337 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
1338 xscale_unset_breakpoint(target
, breakpoint
);
1340 /* calculate PC of next instruction */
1341 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1344 target_read_u32(target
, current_pc
, ¤t_opcode
);
1345 LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode
);
1348 LOG_DEBUG("enable single-step");
1349 xscale_enable_single_step(target
, next_pc
);
1351 /* restore banked registers */
1352 xscale_restore_context(target
);
1354 /* send resume request (command 0x30 or 0x31)
1355 * clean the trace buffer if it is to be enabled (0x62) */
1356 if (xscale
->trace
.buffer_enabled
)
1358 xscale_send_u32(target
, 0x62);
1359 xscale_send_u32(target
, 0x31);
1362 xscale_send_u32(target
, 0x30);
1365 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1366 LOG_DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1368 for (i
= 7; i
>= 0; i
--)
1371 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1372 LOG_DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1376 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1377 LOG_DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1379 /* wait for and process debug entry */
1380 xscale_debug_entry(target
);
1382 LOG_DEBUG("disable single-step");
1383 xscale_disable_single_step(target
);
1385 LOG_DEBUG("set breakpoint at 0x%8.8x", breakpoint
->address
);
1386 xscale_set_breakpoint(target
, breakpoint
);
1390 /* enable any pending breakpoints and watchpoints */
1391 xscale_enable_breakpoints(target
);
1392 xscale_enable_watchpoints(target
);
1394 /* restore banked registers */
1395 xscale_restore_context(target
);
1397 /* send resume request (command 0x30 or 0x31)
1398 * clean the trace buffer if it is to be enabled (0x62) */
1399 if (xscale
->trace
.buffer_enabled
)
1401 xscale_send_u32(target
, 0x62);
1402 xscale_send_u32(target
, 0x31);
1405 xscale_send_u32(target
, 0x30);
1408 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1409 LOG_DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1411 for (i
= 7; i
>= 0; i
--)
1414 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1415 LOG_DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1419 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1420 LOG_DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1422 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1424 if (!debug_execution
)
1426 /* registers are now invalid */
1427 armv4_5_invalidate_core_regs(target
);
1428 target
->state
= TARGET_RUNNING
;
1429 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1433 target
->state
= TARGET_DEBUG_RUNNING
;
1434 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1437 LOG_DEBUG("target resumed");
1439 xscale
->handler_running
= 1;
1444 int xscale_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
1446 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1447 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1448 breakpoint_t
*breakpoint
= target
->breakpoints
;
1450 u32 current_pc
, next_pc
;
1454 if (target
->state
!= TARGET_HALTED
)
1456 LOG_WARNING("target not halted");
1457 return ERROR_TARGET_NOT_HALTED
;
1460 /* current = 1: continue on current pc, otherwise continue at <address> */
1462 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1464 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1466 /* if we're at the reset vector, we have to simulate the step */
1467 if (current_pc
== 0x0)
1469 arm_simulate_step(target
, NULL
);
1470 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1472 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1473 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1478 /* the front-end may request us not to handle breakpoints */
1479 if (handle_breakpoints
)
1480 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1482 xscale_unset_breakpoint(target
, breakpoint
);
1485 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1487 /* calculate PC of next instruction */
1488 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1491 target_read_u32(target
, current_pc
, ¤t_opcode
);
1492 LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode
);
1495 LOG_DEBUG("enable single-step");
1496 xscale_enable_single_step(target
, next_pc
);
1498 /* restore banked registers */
1499 xscale_restore_context(target
);
1501 /* send resume request (command 0x30 or 0x31)
1502 * clean the trace buffer if it is to be enabled (0x62) */
1503 if (xscale
->trace
.buffer_enabled
)
1505 xscale_send_u32(target
, 0x62);
1506 xscale_send_u32(target
, 0x31);
1509 xscale_send_u32(target
, 0x30);
1512 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1513 LOG_DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1515 for (i
= 7; i
>= 0; i
--)
1518 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1519 LOG_DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1523 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1524 LOG_DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1526 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1528 /* registers are now invalid */
1529 armv4_5_invalidate_core_regs(target
);
1531 /* wait for and process debug entry */
1532 xscale_debug_entry(target
);
1534 LOG_DEBUG("disable single-step");
1535 xscale_disable_single_step(target
);
1537 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1541 xscale_set_breakpoint(target
, breakpoint
);
1544 LOG_DEBUG("target stepped");
1550 int xscale_assert_reset(target_t
*target
)
1552 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1553 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1555 LOG_DEBUG("target->state: %s", target_state_strings
[target
->state
]);
1557 /* select DCSR instruction (set endstate to R-T-I to ensure we don't
1558 * end up in T-L-R, which would reset JTAG
1560 jtag_add_end_state(TAP_RTI
);
1561 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, xscale
->jtag_info
.dcsr
);
1563 /* set Hold reset, Halt mode and Trap Reset */
1564 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1565 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1566 xscale_write_dcsr(target
, 1, 0);
1568 /* select BYPASS, because having DCSR selected caused problems on the PXA27x */
1569 xscale_jtag_set_instr(xscale
->jtag_info
.chain_pos
, 0x7f);
1570 jtag_execute_queue();
1573 jtag_add_reset(0, 1);
1575 /* sleep 1ms, to be sure we fulfill any requirements */
1576 jtag_add_sleep(1000);
1577 jtag_execute_queue();
1579 target
->state
= TARGET_RESET
;
1581 if (target
->reset_halt
)
1584 if ((retval
= target_halt(target
))!=ERROR_OK
)
1591 int xscale_deassert_reset(target_t
*target
)
1593 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1594 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1596 fileio_t debug_handler
;
1604 breakpoint_t
*breakpoint
= target
->breakpoints
;
1608 xscale
->ibcr_available
= 2;
1609 xscale
->ibcr0_used
= 0;
1610 xscale
->ibcr1_used
= 0;
1612 xscale
->dbr_available
= 2;
1613 xscale
->dbr0_used
= 0;
1614 xscale
->dbr1_used
= 0;
1616 /* mark all hardware breakpoints as unset */
1619 if (breakpoint
->type
== BKPT_HARD
)
1621 breakpoint
->set
= 0;
1623 breakpoint
= breakpoint
->next
;
1626 if (!xscale
->handler_installed
)
1629 jtag_add_reset(0, 0);
1631 /* wait 300ms; 150 and 100ms were not enough */
1632 jtag_add_sleep(300*1000);
1634 jtag_add_runtest(2030, TAP_RTI
);
1635 jtag_execute_queue();
1637 /* set Hold reset, Halt mode and Trap Reset */
1638 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1639 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1640 xscale_write_dcsr(target
, 1, 0);
1642 /* Load debug handler */
1643 if (fileio_open(&debug_handler
, "xscale/debug_handler.bin", FILEIO_READ
, FILEIO_BINARY
) != ERROR_OK
)
1648 if ((binary_size
= debug_handler
.size
) % 4)
1650 LOG_ERROR("debug_handler.bin: size not a multiple of 4");
1654 if (binary_size
> 0x800)
1656 LOG_ERROR("debug_handler.bin: larger than 2kb");
1660 binary_size
= CEIL(binary_size
, 32) * 32;
1662 address
= xscale
->handler_address
;
1663 while (binary_size
> 0)
1668 if ((retval
= fileio_read(&debug_handler
, 32, buffer
, &buf_cnt
)) != ERROR_OK
)
1673 for (i
= 0; i
< buf_cnt
; i
+= 4)
1675 /* convert LE buffer to host-endian u32 */
1676 cache_line
[i
/ 4] = le_to_h_u32(&buffer
[i
]);
1679 for (; buf_cnt
< 32; buf_cnt
+= 4)
1681 cache_line
[buf_cnt
/ 4] = 0xe1a08008;
1684 /* only load addresses other than the reset vectors */
1685 if ((address
% 0x400) != 0x0)
1687 xscale_load_ic(target
, 1, address
, cache_line
);
1691 binary_size
-= buf_cnt
;
1694 xscale_load_ic(target
, 1, 0x0, xscale
->low_vectors
);
1695 xscale_load_ic(target
, 1, 0xffff0000, xscale
->high_vectors
);
1697 jtag_add_runtest(30, TAP_RTI
);
1699 jtag_add_sleep(100000);
1701 /* set Hold reset, Halt mode and Trap Reset */
1702 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1703 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1704 xscale_write_dcsr(target
, 1, 0);
1706 /* clear Hold reset to let the target run (should enter debug handler) */
1707 xscale_write_dcsr(target
, 0, 1);
1708 target
->state
= TARGET_RUNNING
;
1710 if (!target
->reset_halt
)
1712 jtag_add_sleep(10000);
1714 /* we should have entered debug now */
1715 xscale_debug_entry(target
);
1716 target
->state
= TARGET_HALTED
;
1718 /* resume the target */
1719 xscale_resume(target
, 1, 0x0, 1, 0);
1722 fileio_close(&debug_handler
);
1726 jtag_add_reset(0, 0);
1733 int xscale_soft_reset_halt(struct target_s
*target
)
1739 int xscale_read_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
)
1745 int xscale_write_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
, u32 value
)
1751 int xscale_full_context(target_t
*target
)
1753 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1761 if (target
->state
!= TARGET_HALTED
)
1763 LOG_WARNING("target not halted");
1764 return ERROR_TARGET_NOT_HALTED
;
1767 buffer
= malloc(4 * 8);
1769 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1770 * we can't enter User mode on an XScale (unpredictable),
1771 * but User shares registers with SYS
1773 for(i
= 1; i
< 7; i
++)
1777 /* check if there are invalid registers in the current mode
1779 for (j
= 0; j
<= 16; j
++)
1781 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
== 0)
1789 /* request banked registers */
1790 xscale_send_u32(target
, 0x0);
1793 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1794 tmp_cpsr
|= 0xc0; /* I/F bits */
1796 /* send CPSR for desired mode */
1797 xscale_send_u32(target
, tmp_cpsr
);
1799 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1800 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1802 xscale_receive(target
, buffer
, 8);
1803 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1804 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1805 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).valid
= 1;
1809 xscale_receive(target
, buffer
, 7);
1812 /* move data from buffer to register cache */
1813 for (j
= 8; j
<= 14; j
++)
1815 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]);
1816 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1817 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
= 1;
1827 int xscale_restore_context(target_t
*target
)
1829 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1835 if (target
->state
!= TARGET_HALTED
)
1837 LOG_WARNING("target not halted");
1838 return ERROR_TARGET_NOT_HALTED
;
1841 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1842 * we can't enter User mode on an XScale (unpredictable),
1843 * but User shares registers with SYS
1845 for(i
= 1; i
< 7; i
++)
1849 /* check if there are invalid registers in the current mode
1851 for (j
= 8; j
<= 14; j
++)
1853 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
== 1)
1857 /* if not USR/SYS, check if the SPSR needs to be written */
1858 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1860 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
== 1)
1868 /* send banked registers */
1869 xscale_send_u32(target
, 0x1);
1872 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1873 tmp_cpsr
|= 0xc0; /* I/F bits */
1875 /* send CPSR for desired mode */
1876 xscale_send_u32(target
, tmp_cpsr
);
1878 /* send banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1879 for (j
= 8; j
<= 14; j
++)
1881 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, j
).value
, 0, 32));
1882 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1885 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1887 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32));
1888 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1896 int xscale_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1898 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1899 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1904 LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address
, size
, count
);
1906 if (target
->state
!= TARGET_HALTED
)
1908 LOG_WARNING("target not halted");
1909 return ERROR_TARGET_NOT_HALTED
;
1912 /* sanitize arguments */
1913 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1914 return ERROR_INVALID_ARGUMENTS
;
1916 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1917 return ERROR_TARGET_UNALIGNED_ACCESS
;
1919 /* send memory read request (command 0x1n, n: access size) */
1920 if ((retval
=xscale_send_u32(target
, 0x10 | size
))!=ERROR_OK
)
1923 /* send base address for read request */
1924 if ((retval
=xscale_send_u32(target
, address
))!=ERROR_OK
)
1927 /* send number of requested data words */
1928 if ((retval
=xscale_send_u32(target
, count
))!=ERROR_OK
)
1931 /* receive data from target (count times 32-bit words in host endianness) */
1932 buf32
= malloc(4 * count
);
1933 if ((retval
=xscale_receive(target
, buf32
, count
))!=ERROR_OK
)
1936 /* extract data from host-endian buffer into byte stream */
1937 for (i
= 0; i
< count
; i
++)
1942 target_buffer_set_u32(target
, buffer
, buf32
[i
]);
1946 target_buffer_set_u16(target
, buffer
, buf32
[i
] & 0xffff);
1950 *buffer
++ = buf32
[i
] & 0xff;
1953 LOG_ERROR("should never get here");
1960 /* examine DCSR, to see if Sticky Abort (SA) got set */
1961 if ((retval
=xscale_read_dcsr(target
))!=ERROR_OK
)
1963 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
1966 if ((retval
=xscale_send_u32(target
, 0x60))!=ERROR_OK
)
1969 return ERROR_TARGET_DATA_ABORT
;
1975 int xscale_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1977 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1978 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1981 LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address
, size
, count
);
1983 if (target
->state
!= TARGET_HALTED
)
1985 LOG_WARNING("target not halted");
1986 return ERROR_TARGET_NOT_HALTED
;
1989 /* sanitize arguments */
1990 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1991 return ERROR_INVALID_ARGUMENTS
;
1993 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1994 return ERROR_TARGET_UNALIGNED_ACCESS
;
1996 /* send memory write request (command 0x2n, n: access size) */
1997 if ((retval
=xscale_send_u32(target
, 0x20 | size
))!=ERROR_OK
)
2000 /* send base address for read request */
2001 if ((retval
=xscale_send_u32(target
, address
))!=ERROR_OK
)
2004 /* send number of requested data words to be written*/
2005 if ((retval
=xscale_send_u32(target
, count
))!=ERROR_OK
)
2008 /* extract data from host-endian buffer into byte stream */
2010 for (i
= 0; i
< count
; i
++)
2015 value
= target_buffer_get_u32(target
, buffer
);
2016 xscale_send_u32(target
, value
);
2020 value
= target_buffer_get_u16(target
, buffer
);
2021 xscale_send_u32(target
, value
);
2026 xscale_send_u32(target
, value
);
2030 LOG_ERROR("should never get here");
2035 if ((retval
=xscale_send(target
, buffer
, count
, size
))!=ERROR_OK
)
2038 /* examine DCSR, to see if Sticky Abort (SA) got set */
2039 if ((retval
=xscale_read_dcsr(target
))!=ERROR_OK
)
2041 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
2044 if ((retval
=xscale_send_u32(target
, 0x60))!=ERROR_OK
)
2047 return ERROR_TARGET_DATA_ABORT
;
2053 int xscale_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
2055 return xscale_write_memory(target
, address
, 4, count
, buffer
);
2058 u32
xscale_get_ttb(target_t
*target
)
2060 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2061 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2064 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_TTB
]);
2065 ttb
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_TTB
].value
, 0, 32);
2070 void xscale_disable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
2072 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2073 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2076 /* read cp15 control register */
2077 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2078 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2081 cp15_control
&= ~0x1U
;
2086 xscale_send_u32(target
, 0x50);
2087 xscale_send_u32(target
, xscale
->cache_clean_address
);
2089 /* invalidate DCache */
2090 xscale_send_u32(target
, 0x51);
2092 cp15_control
&= ~0x4U
;
2097 /* invalidate ICache */
2098 xscale_send_u32(target
, 0x52);
2099 cp15_control
&= ~0x1000U
;
2102 /* write new cp15 control register */
2103 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2105 /* execute cpwait to ensure outstanding operations complete */
2106 xscale_send_u32(target
, 0x53);
2109 void xscale_enable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
2111 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2112 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2115 /* read cp15 control register */
2116 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2117 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2120 cp15_control
|= 0x1U
;
2123 cp15_control
|= 0x4U
;
2126 cp15_control
|= 0x1000U
;
2128 /* write new cp15 control register */
2129 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2131 /* execute cpwait to ensure outstanding operations complete */
2132 xscale_send_u32(target
, 0x53);
2135 int xscale_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2137 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2138 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2140 if (target
->state
!= TARGET_HALTED
)
2142 LOG_WARNING("target not halted");
2143 return ERROR_TARGET_NOT_HALTED
;
2146 if (xscale
->force_hw_bkpts
)
2147 breakpoint
->type
= BKPT_HARD
;
2149 if (breakpoint
->set
)
2151 LOG_WARNING("breakpoint already set");
2155 if (breakpoint
->type
== BKPT_HARD
)
2157 u32 value
= breakpoint
->address
| 1;
2158 if (!xscale
->ibcr0_used
)
2160 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], value
);
2161 xscale
->ibcr0_used
= 1;
2162 breakpoint
->set
= 1; /* breakpoint set on first breakpoint register */
2164 else if (!xscale
->ibcr1_used
)
2166 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], value
);
2167 xscale
->ibcr1_used
= 1;
2168 breakpoint
->set
= 2; /* breakpoint set on second breakpoint register */
2172 LOG_ERROR("BUG: no hardware comparator available");
2176 else if (breakpoint
->type
== BKPT_SOFT
)
2178 if (breakpoint
->length
== 4)
2180 /* keep the original instruction in target endianness */
2181 target
->type
->read_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
);
2182 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2183 target_write_u32(target
, breakpoint
->address
, xscale
->arm_bkpt
);
2187 /* keep the original instruction in target endianness */
2188 target
->type
->read_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
);
2189 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2190 target_write_u32(target
, breakpoint
->address
, xscale
->thumb_bkpt
);
2192 breakpoint
->set
= 1;
2199 int xscale_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2201 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2202 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2204 if (target
->state
!= TARGET_HALTED
)
2206 LOG_WARNING("target not halted");
2207 return ERROR_TARGET_NOT_HALTED
;
2210 if (xscale
->force_hw_bkpts
)
2212 LOG_DEBUG("forcing use of hardware breakpoint at address 0x%8.8x", breakpoint
->address
);
2213 breakpoint
->type
= BKPT_HARD
;
2216 if ((breakpoint
->type
== BKPT_HARD
) && (xscale
->ibcr_available
< 1))
2218 LOG_INFO("no breakpoint unit available for hardware breakpoint");
2219 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2223 xscale
->ibcr_available
--;
2226 if ((breakpoint
->length
!= 2) && (breakpoint
->length
!= 4))
2228 LOG_INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
2229 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2235 int xscale_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2237 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2238 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2240 if (target
->state
!= TARGET_HALTED
)
2242 LOG_WARNING("target not halted");
2243 return ERROR_TARGET_NOT_HALTED
;
2246 if (!breakpoint
->set
)
2248 LOG_WARNING("breakpoint not set");
2252 if (breakpoint
->type
== BKPT_HARD
)
2254 if (breakpoint
->set
== 1)
2256 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], 0x0);
2257 xscale
->ibcr0_used
= 0;
2259 else if (breakpoint
->set
== 2)
2261 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], 0x0);
2262 xscale
->ibcr1_used
= 0;
2264 breakpoint
->set
= 0;
2268 /* restore original instruction (kept in target endianness) */
2269 if (breakpoint
->length
== 4)
2271 target
->type
->write_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
);
2275 target
->type
->write_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
);
2277 breakpoint
->set
= 0;
2283 int xscale_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2285 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2286 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2288 if (target
->state
!= TARGET_HALTED
)
2290 LOG_WARNING("target not halted");
2291 return ERROR_TARGET_NOT_HALTED
;
2294 if (breakpoint
->set
)
2296 xscale_unset_breakpoint(target
, breakpoint
);
2299 if (breakpoint
->type
== BKPT_HARD
)
2300 xscale
->ibcr_available
++;
2305 int xscale_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2307 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2308 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2310 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2311 u32 dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2313 if (target
->state
!= TARGET_HALTED
)
2315 LOG_WARNING("target not halted");
2316 return ERROR_TARGET_NOT_HALTED
;
2319 xscale_get_reg(dbcon
);
2321 switch (watchpoint
->rw
)
2333 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
2336 if (!xscale
->dbr0_used
)
2338 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR0
], watchpoint
->address
);
2339 dbcon_value
|= enable
;
2340 xscale_set_reg_u32(dbcon
, dbcon_value
);
2341 watchpoint
->set
= 1;
2342 xscale
->dbr0_used
= 1;
2344 else if (!xscale
->dbr1_used
)
2346 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR1
], watchpoint
->address
);
2347 dbcon_value
|= enable
<< 2;
2348 xscale_set_reg_u32(dbcon
, dbcon_value
);
2349 watchpoint
->set
= 2;
2350 xscale
->dbr1_used
= 1;
2354 LOG_ERROR("BUG: no hardware comparator available");
2361 int xscale_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2363 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2364 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2366 if (target
->state
!= TARGET_HALTED
)
2368 LOG_WARNING("target not halted");
2369 return ERROR_TARGET_NOT_HALTED
;
2372 if (xscale
->dbr_available
< 1)
2374 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2377 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
2379 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2382 xscale
->dbr_available
--;
2387 int xscale_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2389 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2390 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2391 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2392 u32 dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2394 if (target
->state
!= TARGET_HALTED
)
2396 LOG_WARNING("target not halted");
2397 return ERROR_TARGET_NOT_HALTED
;
2400 if (!watchpoint
->set
)
2402 LOG_WARNING("breakpoint not set");
2406 if (watchpoint
->set
== 1)
2408 dbcon_value
&= ~0x3;
2409 xscale_set_reg_u32(dbcon
, dbcon_value
);
2410 xscale
->dbr0_used
= 0;
2412 else if (watchpoint
->set
== 2)
2414 dbcon_value
&= ~0xc;
2415 xscale_set_reg_u32(dbcon
, dbcon_value
);
2416 xscale
->dbr1_used
= 0;
2418 watchpoint
->set
= 0;
2423 int xscale_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2425 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2426 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2428 if (target
->state
!= TARGET_HALTED
)
2430 LOG_WARNING("target not halted");
2431 return ERROR_TARGET_NOT_HALTED
;
2434 if (watchpoint
->set
)
2436 xscale_unset_watchpoint(target
, watchpoint
);
2439 xscale
->dbr_available
++;
2444 void xscale_enable_watchpoints(struct target_s
*target
)
2446 watchpoint_t
*watchpoint
= target
->watchpoints
;
2450 if (watchpoint
->set
== 0)
2451 xscale_set_watchpoint(target
, watchpoint
);
2452 watchpoint
= watchpoint
->next
;
2456 void xscale_enable_breakpoints(struct target_s
*target
)
2458 breakpoint_t
*breakpoint
= target
->breakpoints
;
2460 /* set any pending breakpoints */
2463 if (breakpoint
->set
== 0)
2464 xscale_set_breakpoint(target
, breakpoint
);
2465 breakpoint
= breakpoint
->next
;
2469 int xscale_get_reg(reg_t
*reg
)
2471 xscale_reg_t
*arch_info
= reg
->arch_info
;
2472 target_t
*target
= arch_info
->target
;
2473 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2474 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2476 /* DCSR, TX and RX are accessible via JTAG */
2477 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2479 return xscale_read_dcsr(arch_info
->target
);
2481 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2483 /* 1 = consume register content */
2484 return xscale_read_tx(arch_info
->target
, 1);
2486 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2488 /* can't read from RX register (host -> debug handler) */
2491 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2493 /* can't (explicitly) read from TXRXCTRL register */
2496 else /* Other DBG registers have to be transfered by the debug handler */
2498 /* send CP read request (command 0x40) */
2499 xscale_send_u32(target
, 0x40);
2501 /* send CP register number */
2502 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2504 /* read register value */
2505 xscale_read_tx(target
, 1);
2506 buf_cpy(xscale
->reg_cache
->reg_list
[XSCALE_TX
].value
, reg
->value
, 32);
2515 int xscale_set_reg(reg_t
*reg
, u8
* buf
)
2517 xscale_reg_t
*arch_info
= reg
->arch_info
;
2518 target_t
*target
= arch_info
->target
;
2519 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2520 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2521 u32 value
= buf_get_u32(buf
, 0, 32);
2523 /* DCSR, TX and RX are accessible via JTAG */
2524 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2526 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32, value
);
2527 return xscale_write_dcsr(arch_info
->target
, -1, -1);
2529 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2531 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
2532 return xscale_write_rx(arch_info
->target
);
2534 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2536 /* can't write to TX register (debug-handler -> host) */
2539 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2541 /* can't (explicitly) write to TXRXCTRL register */
2544 else /* Other DBG registers have to be transfered by the debug handler */
2546 /* send CP write request (command 0x41) */
2547 xscale_send_u32(target
, 0x41);
2549 /* send CP register number */
2550 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2552 /* send CP register value */
2553 xscale_send_u32(target
, value
);
2554 buf_set_u32(reg
->value
, 0, 32, value
);
2560 /* convenience wrapper to access XScale specific registers */
2561 int xscale_set_reg_u32(reg_t
*reg
, u32 value
)
2565 buf_set_u32(buf
, 0, 32, value
);
2567 return xscale_set_reg(reg
, buf
);
2570 int xscale_write_dcsr_sw(target_t
*target
, u32 value
)
2572 /* get pointers to arch-specific information */
2573 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2574 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2575 reg_t
*dcsr
= &xscale
->reg_cache
->reg_list
[XSCALE_DCSR
];
2576 xscale_reg_t
*dcsr_arch_info
= dcsr
->arch_info
;
2578 /* send CP write request (command 0x41) */
2579 xscale_send_u32(target
, 0x41);
2581 /* send CP register number */
2582 xscale_send_u32(target
, dcsr_arch_info
->dbg_handler_number
);
2584 /* send CP register value */
2585 xscale_send_u32(target
, value
);
2586 buf_set_u32(dcsr
->value
, 0, 32, value
);
2591 int xscale_read_trace(target_t
*target
)
2593 /* get pointers to arch-specific information */
2594 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2595 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2596 xscale_trace_data_t
**trace_data_p
;
2598 /* 258 words from debug handler
2599 * 256 trace buffer entries
2600 * 2 checkpoint addresses
2602 u32 trace_buffer
[258];
2603 int is_address
[256];
2606 if (target
->state
!= TARGET_HALTED
)
2608 LOG_WARNING("target must be stopped to read trace data");
2609 return ERROR_TARGET_NOT_HALTED
;
2612 /* send read trace buffer command (command 0x61) */
2613 xscale_send_u32(target
, 0x61);
2615 /* receive trace buffer content */
2616 xscale_receive(target
, trace_buffer
, 258);
2618 /* parse buffer backwards to identify address entries */
2619 for (i
= 255; i
>= 0; i
--)
2622 if (((trace_buffer
[i
] & 0xf0) == 0x90) ||
2623 ((trace_buffer
[i
] & 0xf0) == 0xd0))
2626 is_address
[--i
] = 1;
2628 is_address
[--i
] = 1;
2630 is_address
[--i
] = 1;
2632 is_address
[--i
] = 1;
2637 /* search first non-zero entry */
2638 for (j
= 0; (j
< 256) && (trace_buffer
[j
] == 0) && (!is_address
[j
]); j
++)
2643 LOG_DEBUG("no trace data collected");
2644 return ERROR_XSCALE_NO_TRACE_DATA
;
2647 for (trace_data_p
= &xscale
->trace
.data
; *trace_data_p
; trace_data_p
= &(*trace_data_p
)->next
)
2650 *trace_data_p
= malloc(sizeof(xscale_trace_data_t
));
2651 (*trace_data_p
)->next
= NULL
;
2652 (*trace_data_p
)->chkpt0
= trace_buffer
[256];
2653 (*trace_data_p
)->chkpt1
= trace_buffer
[257];
2654 (*trace_data_p
)->last_instruction
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
2655 (*trace_data_p
)->entries
= malloc(sizeof(xscale_trace_entry_t
) * (256 - j
));
2656 (*trace_data_p
)->depth
= 256 - j
;
2658 for (i
= j
; i
< 256; i
++)
2660 (*trace_data_p
)->entries
[i
- j
].data
= trace_buffer
[i
];
2662 (*trace_data_p
)->entries
[i
- j
].type
= XSCALE_TRACE_ADDRESS
;
2664 (*trace_data_p
)->entries
[i
- j
].type
= XSCALE_TRACE_MESSAGE
;
2670 int xscale_read_instruction(target_t
*target
, arm_instruction_t
*instruction
)
2672 /* get pointers to arch-specific information */
2673 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2674 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2681 if (!xscale
->trace
.image
)
2682 return ERROR_TRACE_IMAGE_UNAVAILABLE
;
2684 /* search for the section the current instruction belongs to */
2685 for (i
= 0; i
< xscale
->trace
.image
->num_sections
; i
++)
2687 if ((xscale
->trace
.image
->sections
[i
].base_address
<= xscale
->trace
.current_pc
) &&
2688 (xscale
->trace
.image
->sections
[i
].base_address
+ xscale
->trace
.image
->sections
[i
].size
> xscale
->trace
.current_pc
))
2697 /* current instruction couldn't be found in the image */
2698 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2701 if (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
)
2704 if ((retval
= image_read_section(xscale
->trace
.image
, section
,
2705 xscale
->trace
.current_pc
- xscale
->trace
.image
->sections
[section
].base_address
,
2706 4, buf
, &size_read
)) != ERROR_OK
)
2708 LOG_ERROR("error while reading instruction: %i", retval
);
2709 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2711 opcode
= target_buffer_get_u32(target
, buf
);
2712 arm_evaluate_opcode(opcode
, xscale
->trace
.current_pc
, instruction
);
2714 else if (xscale
->trace
.core_state
== ARMV4_5_STATE_THUMB
)
2717 if ((retval
= image_read_section(xscale
->trace
.image
, section
,
2718 xscale
->trace
.current_pc
- xscale
->trace
.image
->sections
[section
].base_address
,
2719 2, buf
, &size_read
)) != ERROR_OK
)
2721 LOG_ERROR("error while reading instruction: %i", retval
);
2722 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2724 opcode
= target_buffer_get_u16(target
, buf
);
2725 thumb_evaluate_opcode(opcode
, xscale
->trace
.current_pc
, instruction
);
2729 LOG_ERROR("BUG: unknown core state encountered");
2736 int xscale_branch_address(xscale_trace_data_t
*trace_data
, int i
, u32
*target
)
2738 /* if there are less than four entries prior to the indirect branch message
2739 * we can't extract the address */
2745 *target
= (trace_data
->entries
[i
-1].data
) | (trace_data
->entries
[i
-2].data
<< 8) |
2746 (trace_data
->entries
[i
-3].data
<< 16) | (trace_data
->entries
[i
-4].data
<< 24);
2751 int xscale_analyze_trace(target_t
*target
, command_context_t
*cmd_ctx
)
2753 /* get pointers to arch-specific information */
2754 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2755 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2758 xscale_trace_data_t
*trace_data
= xscale
->trace
.data
;
2767 xscale
->trace
.core_state
= ARMV4_5_STATE_ARM
;
2772 for (i
= 0; i
< trace_data
->depth
; i
++)
2778 if (trace_data
->entries
[i
].type
== XSCALE_TRACE_ADDRESS
)
2781 switch ((trace_data
->entries
[i
].data
& 0xf0) >> 4)
2783 case 0: /* Exceptions */
2791 exception
= (trace_data
->entries
[i
].data
& 0x70) >> 4;
2793 next_pc
= (trace_data
->entries
[i
].data
& 0xf0) >> 2;
2794 command_print(cmd_ctx
, "--- exception %i ---", (trace_data
->entries
[i
].data
& 0xf0) >> 4);
2796 case 8: /* Direct Branch */
2799 case 9: /* Indirect Branch */
2801 if (xscale_branch_address(trace_data
, i
, &next_pc
) == 0)
2806 case 13: /* Checkpointed Indirect Branch */
2807 if (xscale_branch_address(trace_data
, i
, &next_pc
) == 0)
2810 if (((chkpt
== 0) && (next_pc
!= trace_data
->chkpt0
))
2811 || ((chkpt
== 1) && (next_pc
!= trace_data
->chkpt1
)))
2812 LOG_WARNING("checkpointed indirect branch target address doesn't match checkpoint");
2814 /* explicit fall-through */
2815 case 12: /* Checkpointed Direct Branch */
2820 next_pc
= trace_data
->chkpt0
;
2823 else if (chkpt
== 1)
2826 next_pc
= trace_data
->chkpt0
;
2831 LOG_WARNING("more than two checkpointed branches encountered");
2834 case 15: /* Roll-over */
2837 default: /* Reserved */
2838 command_print(cmd_ctx
, "--- reserved trace message ---");
2839 LOG_ERROR("BUG: trace message %i is reserved", (trace_data
->entries
[i
].data
& 0xf0) >> 4);
2843 if (xscale
->trace
.pc_ok
)
2845 int executed
= (trace_data
->entries
[i
].data
& 0xf) + rollover
* 16;
2846 arm_instruction_t instruction
;
2848 if ((exception
== 6) || (exception
== 7))
2850 /* IRQ or FIQ exception, no instruction executed */
2854 while (executed
-- >= 0)
2856 if ((retval
= xscale_read_instruction(target
, &instruction
)) != ERROR_OK
)
2858 /* can't continue tracing with no image available */
2859 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
2863 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
2865 /* TODO: handle incomplete images */
2869 /* a precise abort on a load to the PC is included in the incremental
2870 * word count, other instructions causing data aborts are not included
2872 if ((executed
== 0) && (exception
== 4)
2873 && ((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_LDM
)))
2875 if ((instruction
.type
== ARM_LDM
)
2876 && ((instruction
.info
.load_store_multiple
.register_list
& 0x8000) == 0))
2880 else if (((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_LDRSH
))
2881 && (instruction
.info
.load_store
.Rd
!= 15))
2887 /* only the last instruction executed
2888 * (the one that caused the control flow change)
2889 * could be a taken branch
2891 if (((executed
== -1) && (branch
== 1)) &&
2892 (((instruction
.type
== ARM_B
) ||
2893 (instruction
.type
== ARM_BL
) ||
2894 (instruction
.type
== ARM_BLX
)) &&
2895 (instruction
.info
.b_bl_bx_blx
.target_address
!= -1)))
2897 xscale
->trace
.current_pc
= instruction
.info
.b_bl_bx_blx
.target_address
;
2901 xscale
->trace
.current_pc
+= (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2;
2903 command_print(cmd_ctx
, "%s", instruction
.text
);
2911 xscale
->trace
.current_pc
= next_pc
;
2912 xscale
->trace
.pc_ok
= 1;
2916 for (; xscale
->trace
.current_pc
< trace_data
->last_instruction
; xscale
->trace
.current_pc
+= (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2)
2918 arm_instruction_t instruction
;
2919 if ((retval
= xscale_read_instruction(target
, &instruction
)) != ERROR_OK
)
2921 /* can't continue tracing with no image available */
2922 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
2926 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
2928 /* TODO: handle incomplete images */
2931 command_print(cmd_ctx
, "%s", instruction
.text
);
2934 trace_data
= trace_data
->next
;
2940 void xscale_build_reg_cache(target_t
*target
)
2942 /* get pointers to arch-specific information */
2943 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2944 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2946 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
2947 xscale_reg_t
*arch_info
= malloc(sizeof(xscale_reg_arch_info
));
2949 int num_regs
= sizeof(xscale_reg_arch_info
) / sizeof(xscale_reg_t
);
2951 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
2952 armv4_5
->core_cache
= (*cache_p
);
2954 /* register a register arch-type for XScale dbg registers only once */
2955 if (xscale_reg_arch_type
== -1)
2956 xscale_reg_arch_type
= register_reg_arch_type(xscale_get_reg
, xscale_set_reg
);
2958 (*cache_p
)->next
= malloc(sizeof(reg_cache_t
));
2959 cache_p
= &(*cache_p
)->next
;
2961 /* fill in values for the xscale reg cache */
2962 (*cache_p
)->name
= "XScale registers";
2963 (*cache_p
)->next
= NULL
;
2964 (*cache_p
)->reg_list
= malloc(num_regs
* sizeof(reg_t
));
2965 (*cache_p
)->num_regs
= num_regs
;
2967 for (i
= 0; i
< num_regs
; i
++)
2969 (*cache_p
)->reg_list
[i
].name
= xscale_reg_list
[i
];
2970 (*cache_p
)->reg_list
[i
].value
= calloc(4, 1);
2971 (*cache_p
)->reg_list
[i
].dirty
= 0;
2972 (*cache_p
)->reg_list
[i
].valid
= 0;
2973 (*cache_p
)->reg_list
[i
].size
= 32;
2974 (*cache_p
)->reg_list
[i
].bitfield_desc
= NULL
;
2975 (*cache_p
)->reg_list
[i
].num_bitfields
= 0;
2976 (*cache_p
)->reg_list
[i
].arch_info
= &arch_info
[i
];
2977 (*cache_p
)->reg_list
[i
].arch_type
= xscale_reg_arch_type
;
2978 arch_info
[i
] = xscale_reg_arch_info
[i
];
2979 arch_info
[i
].target
= target
;
2982 xscale
->reg_cache
= (*cache_p
);
2985 int xscale_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
2990 int xscale_quit(void)
2996 int xscale_init_arch_info(target_t
*target
, xscale_common_t
*xscale
, int chain_pos
, char *variant
)
2998 armv4_5_common_t
*armv4_5
;
2999 u32 high_reset_branch
, low_reset_branch
;
3002 armv4_5
= &xscale
->armv4_5_common
;
3004 /* store architecture specfic data (none so far) */
3005 xscale
->arch_info
= NULL
;
3006 xscale
->common_magic
= XSCALE_COMMON_MAGIC
;
3008 /* remember the variant (PXA25x, PXA27x, IXP42x, ...) */
3009 xscale
->variant
= strdup(variant
);
3011 /* prepare JTAG information for the new target */
3012 xscale
->jtag_info
.chain_pos
= chain_pos
;
3014 xscale
->jtag_info
.dbgrx
= 0x02;
3015 xscale
->jtag_info
.dbgtx
= 0x10;
3016 xscale
->jtag_info
.dcsr
= 0x09;
3017 xscale
->jtag_info
.ldic
= 0x07;
3019 if ((strcmp(xscale
->variant
, "pxa250") == 0) ||
3020 (strcmp(xscale
->variant
, "pxa255") == 0) ||
3021 (strcmp(xscale
->variant
, "pxa26x") == 0))
3023 xscale
->jtag_info
.ir_length
= 5;
3025 else if ((strcmp(xscale
->variant
, "pxa27x") == 0) ||
3026 (strcmp(xscale
->variant
, "ixp42x") == 0) ||
3027 (strcmp(xscale
->variant
, "ixp45x") == 0) ||
3028 (strcmp(xscale
->variant
, "ixp46x") == 0))
3030 xscale
->jtag_info
.ir_length
= 7;
3033 /* the debug handler isn't installed (and thus not running) at this time */
3034 xscale
->handler_installed
= 0;
3035 xscale
->handler_running
= 0;
3036 xscale
->handler_address
= 0xfe000800;
3038 /* clear the vectors we keep locally for reference */
3039 memset(xscale
->low_vectors
, 0, sizeof(xscale
->low_vectors
));
3040 memset(xscale
->high_vectors
, 0, sizeof(xscale
->high_vectors
));
3042 /* no user-specified vectors have been configured yet */
3043 xscale
->static_low_vectors_set
= 0x0;
3044 xscale
->static_high_vectors_set
= 0x0;
3046 /* calculate branches to debug handler */
3047 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
3048 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
3050 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
3051 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
3053 for (i
= 1; i
<= 7; i
++)
3055 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
3056 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
3059 /* 64kB aligned region used for DCache cleaning */
3060 xscale
->cache_clean_address
= 0xfffe0000;
3062 xscale
->hold_rst
= 0;
3063 xscale
->external_debug_break
= 0;
3065 xscale
->force_hw_bkpts
= 1;
3067 xscale
->ibcr_available
= 2;
3068 xscale
->ibcr0_used
= 0;
3069 xscale
->ibcr1_used
= 0;
3071 xscale
->dbr_available
= 2;
3072 xscale
->dbr0_used
= 0;
3073 xscale
->dbr1_used
= 0;
3075 xscale
->arm_bkpt
= ARMV5_BKPT(0x0);
3076 xscale
->thumb_bkpt
= ARMV5_T_BKPT(0x0) & 0xffff;
3078 xscale
->vector_catch
= 0x1;
3080 xscale
->trace
.capture_status
= TRACE_IDLE
;
3081 xscale
->trace
.data
= NULL
;
3082 xscale
->trace
.image
= NULL
;
3083 xscale
->trace
.buffer_enabled
= 0;
3084 xscale
->trace
.buffer_fill
= 0;
3086 /* prepare ARMv4/5 specific information */
3087 armv4_5
->arch_info
= xscale
;
3088 armv4_5
->read_core_reg
= xscale_read_core_reg
;
3089 armv4_5
->write_core_reg
= xscale_write_core_reg
;
3090 armv4_5
->full_context
= xscale_full_context
;
3092 armv4_5_init_arch_info(target
, armv4_5
);
3094 xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
3095 xscale
->armv4_5_mmu
.get_ttb
= xscale_get_ttb
;
3096 xscale
->armv4_5_mmu
.read_memory
= xscale_read_memory
;
3097 xscale
->armv4_5_mmu
.write_memory
= xscale_write_memory
;
3098 xscale
->armv4_5_mmu
.disable_mmu_caches
= xscale_disable_mmu_caches
;
3099 xscale
->armv4_5_mmu
.enable_mmu_caches
= xscale_enable_mmu_caches
;
3100 xscale
->armv4_5_mmu
.has_tiny_pages
= 1;
3101 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3106 /* target xscale <endianess> <startup_mode> <chain_pos> <variant> */
3107 int xscale_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
)
3110 char *variant
= NULL
;
3111 xscale_common_t
*xscale
= malloc(sizeof(xscale_common_t
));
3112 memset(xscale
, 0, sizeof(*xscale
));
3116 LOG_ERROR("'target xscale' requires four arguments: <endianess> <startup_mode> <chain_pos> <variant>");
3120 chain_pos
= strtoul(args
[3], NULL
, 0);
3124 xscale_init_arch_info(target
, xscale
, chain_pos
, variant
);
3125 xscale_build_reg_cache(target
);
3130 int xscale_handle_debug_handler_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3132 target_t
*target
= NULL
;
3133 armv4_5_common_t
*armv4_5
;
3134 xscale_common_t
*xscale
;
3136 u32 handler_address
;
3140 LOG_ERROR("'xscale debug_handler <target#> <address>' command takes two required operands");
3144 if ((target
= get_target_by_num(strtoul(args
[0], NULL
, 0))) == NULL
)
3146 LOG_ERROR("no target '%s' configured", args
[0]);
3150 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3155 handler_address
= strtoul(args
[1], NULL
, 0);
3157 if (((handler_address
>= 0x800) && (handler_address
<= 0x1fef800)) ||
3158 ((handler_address
>= 0xfe000800) && (handler_address
<= 0xfffff800)))
3160 xscale
->handler_address
= handler_address
;
3164 LOG_ERROR("xscale debug_handler <address> must be between 0x800 and 0x1fef800 or between 0xfe000800 and 0xfffff800");
3170 int xscale_handle_cache_clean_address_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3172 target_t
*target
= NULL
;
3173 armv4_5_common_t
*armv4_5
;
3174 xscale_common_t
*xscale
;
3176 u32 cache_clean_address
;
3180 LOG_ERROR("'xscale cache_clean_address <target#> <address>' command takes two required operands");
3184 if ((target
= get_target_by_num(strtoul(args
[0], NULL
, 0))) == NULL
)
3186 LOG_ERROR("no target '%s' configured", args
[0]);
3190 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3195 cache_clean_address
= strtoul(args
[1], NULL
, 0);
3197 if (cache_clean_address
& 0xffff)
3199 LOG_ERROR("xscale cache_clean_address <address> must be 64kb aligned");
3203 xscale
->cache_clean_address
= cache_clean_address
;
3209 int xscale_handle_cache_info_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3211 target_t
*target
= get_current_target(cmd_ctx
);
3212 armv4_5_common_t
*armv4_5
;
3213 xscale_common_t
*xscale
;
3215 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3220 return armv4_5_handle_cache_info_command(cmd_ctx
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
3223 static int xscale_virt2phys(struct target_s
*target
, u32
virtual, u32
*physical
)
3225 armv4_5_common_t
*armv4_5
;
3226 xscale_common_t
*xscale
;
3234 if ((retval
= xscale_get_arch_pointers(target
, &armv4_5
, &xscale
)) != ERROR_OK
)
3238 u32 ret
= armv4_5_mmu_translate_va(target
, &xscale
->armv4_5_mmu
, virtual, &type
, &cb
, &domain
, &ap
);
3247 static int xscale_mmu(struct target_s
*target
, int *enabled
)
3249 armv4_5_common_t
*armv4_5
= target
->arch_info
;
3250 xscale_common_t
*xscale
= armv4_5
->arch_info
;
3252 if (target
->state
!= TARGET_HALTED
)
3254 LOG_ERROR("Target not halted");
3255 return ERROR_TARGET_INVALID
;
3257 *enabled
= xscale
->armv4_5_mmu
.mmu_enabled
;
3262 int xscale_handle_mmu_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3264 target_t
*target
= get_current_target(cmd_ctx
);
3265 armv4_5_common_t
*armv4_5
;
3266 xscale_common_t
*xscale
;
3268 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3273 if (target
->state
!= TARGET_HALTED
)
3275 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3281 if (strcmp("enable", args
[0]) == 0)
3283 xscale_enable_mmu_caches(target
, 1, 0, 0);
3284 xscale
->armv4_5_mmu
.mmu_enabled
= 1;
3286 else if (strcmp("disable", args
[0]) == 0)
3288 xscale_disable_mmu_caches(target
, 1, 0, 0);
3289 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3293 command_print(cmd_ctx
, "mmu %s", (xscale
->armv4_5_mmu
.mmu_enabled
) ? "enabled" : "disabled");
3298 int xscale_handle_idcache_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3300 target_t
*target
= get_current_target(cmd_ctx
);
3301 armv4_5_common_t
*armv4_5
;
3302 xscale_common_t
*xscale
;
3303 int icache
= 0, dcache
= 0;
3305 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3310 if (target
->state
!= TARGET_HALTED
)
3312 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3316 if (strcmp(cmd
, "icache") == 0)
3318 else if (strcmp(cmd
, "dcache") == 0)
3323 if (strcmp("enable", args
[0]) == 0)
3325 xscale_enable_mmu_caches(target
, 0, dcache
, icache
);
3328 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 1;
3330 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 1;
3332 else if (strcmp("disable", args
[0]) == 0)
3334 xscale_disable_mmu_caches(target
, 0, dcache
, icache
);
3337 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 0;
3339 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 0;
3344 command_print(cmd_ctx
, "icache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
) ? "enabled" : "disabled");
3347 command_print(cmd_ctx
, "dcache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
) ? "enabled" : "disabled");
3352 int xscale_handle_vector_catch_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3354 target_t
*target
= get_current_target(cmd_ctx
);
3355 armv4_5_common_t
*armv4_5
;
3356 xscale_common_t
*xscale
;
3358 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3365 command_print(cmd_ctx
, "usage: xscale vector_catch [mask]");
3369 xscale
->vector_catch
= strtoul(args
[0], NULL
, 0);
3370 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 8, xscale
->vector_catch
);
3371 xscale_write_dcsr(target
, -1, -1);
3374 command_print(cmd_ctx
, "vector catch mask: 0x%2.2x", xscale
->vector_catch
);
3379 int xscale_handle_force_hw_bkpts_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3381 target_t
*target
= get_current_target(cmd_ctx
);
3382 armv4_5_common_t
*armv4_5
;
3383 xscale_common_t
*xscale
;
3385 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3390 if ((argc
>= 1) && (strcmp("enable", args
[0]) == 0))
3392 xscale
->force_hw_bkpts
= 1;
3394 else if ((argc
>= 1) && (strcmp("disable", args
[0]) == 0))
3396 xscale
->force_hw_bkpts
= 0;
3400 command_print(cmd_ctx
, "usage: xscale force_hw_bkpts <enable|disable>");
3403 command_print(cmd_ctx
, "force hardware breakpoints %s", (xscale
->force_hw_bkpts
) ? "enabled" : "disabled");
3408 int xscale_handle_trace_buffer_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3410 target_t
*target
= get_current_target(cmd_ctx
);
3411 armv4_5_common_t
*armv4_5
;
3412 xscale_common_t
*xscale
;
3415 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3420 if (target
->state
!= TARGET_HALTED
)
3422 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3426 if ((argc
>= 1) && (strcmp("enable", args
[0]) == 0))
3428 xscale_trace_data_t
*td
, *next_td
;
3429 xscale
->trace
.buffer_enabled
= 1;
3431 /* free old trace data */
3432 td
= xscale
->trace
.data
;
3442 xscale
->trace
.data
= NULL
;
3444 else if ((argc
>= 1) && (strcmp("disable", args
[0]) == 0))
3446 xscale
->trace
.buffer_enabled
= 0;
3449 if ((argc
>= 2) && (strcmp("fill", args
[1]) == 0))
3452 xscale
->trace
.buffer_fill
= strtoul(args
[2], NULL
, 0);
3454 xscale
->trace
.buffer_fill
= 1;
3456 else if ((argc
>= 2) && (strcmp("wrap", args
[1]) == 0))
3458 xscale
->trace
.buffer_fill
= -1;
3461 if (xscale
->trace
.buffer_enabled
)
3463 /* if we enable the trace buffer in fill-once
3464 * mode we know the address of the first instruction */
3465 xscale
->trace
.pc_ok
= 1;
3466 xscale
->trace
.current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
3470 /* otherwise the address is unknown, and we have no known good PC */
3471 xscale
->trace
.pc_ok
= 0;
3474 command_print(cmd_ctx
, "trace buffer %s (%s)",
3475 (xscale
->trace
.buffer_enabled
) ? "enabled" : "disabled",
3476 (xscale
->trace
.buffer_fill
> 0) ? "fill" : "wrap");
3478 dcsr_value
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32);
3479 if (xscale
->trace
.buffer_fill
>= 0)
3480 xscale_write_dcsr_sw(target
, (dcsr_value
& 0xfffffffc) | 2);
3482 xscale_write_dcsr_sw(target
, dcsr_value
& 0xfffffffc);
3487 int xscale_handle_trace_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3490 armv4_5_common_t
*armv4_5
;
3491 xscale_common_t
*xscale
;
3495 command_print(cmd_ctx
, "usage: xscale trace_image <file> [base address] [type]");
3499 target
= get_current_target(cmd_ctx
);
3501 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3506 if (xscale
->trace
.image
)
3508 image_close(xscale
->trace
.image
);
3509 free(xscale
->trace
.image
);
3510 command_print(cmd_ctx
, "previously loaded image found and closed");
3513 xscale
->trace
.image
= malloc(sizeof(image_t
));
3514 xscale
->trace
.image
->base_address_set
= 0;
3515 xscale
->trace
.image
->start_address_set
= 0;
3517 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
3520 xscale
->trace
.image
->base_address_set
= 1;
3521 xscale
->trace
.image
->base_address
= strtoul(args
[1], NULL
, 0);
3525 xscale
->trace
.image
->base_address_set
= 0;
3528 if (image_open(xscale
->trace
.image
, args
[0], (argc
>= 3) ? args
[2] : NULL
) != ERROR_OK
)
3530 free(xscale
->trace
.image
);
3531 xscale
->trace
.image
= NULL
;
3538 int xscale_handle_dump_trace_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3540 target_t
*target
= get_current_target(cmd_ctx
);
3541 armv4_5_common_t
*armv4_5
;
3542 xscale_common_t
*xscale
;
3543 xscale_trace_data_t
*trace_data
;
3546 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3551 if (target
->state
!= TARGET_HALTED
)
3553 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3559 command_print(cmd_ctx
, "usage: xscale dump_trace <file>");
3563 trace_data
= xscale
->trace
.data
;
3567 command_print(cmd_ctx
, "no trace data collected");
3571 if (fileio_open(&file
, args
[0], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
)
3580 fileio_write_u32(&file
, trace_data
->chkpt0
);
3581 fileio_write_u32(&file
, trace_data
->chkpt1
);
3582 fileio_write_u32(&file
, trace_data
->last_instruction
);
3583 fileio_write_u32(&file
, trace_data
->depth
);
3585 for (i
= 0; i
< trace_data
->depth
; i
++)
3586 fileio_write_u32(&file
, trace_data
->entries
[i
].data
| ((trace_data
->entries
[i
].type
& 0xffff) << 16));
3588 trace_data
= trace_data
->next
;
3591 fileio_close(&file
);
3596 int xscale_handle_analyze_trace_buffer_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3598 target_t
*target
= get_current_target(cmd_ctx
);
3599 armv4_5_common_t
*armv4_5
;
3600 xscale_common_t
*xscale
;
3602 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3607 xscale_analyze_trace(target
, cmd_ctx
);
3612 int xscale_handle_cp15(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3614 target_t
*target
= get_current_target(cmd_ctx
);
3615 armv4_5_common_t
*armv4_5
;
3616 xscale_common_t
*xscale
;
3618 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3623 if (target
->state
!= TARGET_HALTED
)
3625 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3632 reg_no
= strtoul(args
[0], NULL
, 0);
3633 /*translate from xscale cp15 register no to openocd register*/
3637 reg_no
= XSCALE_MAINID
;
3640 reg_no
= XSCALE_CTRL
;
3643 reg_no
= XSCALE_TTB
;
3646 reg_no
= XSCALE_DAC
;
3649 reg_no
= XSCALE_FSR
;
3652 reg_no
= XSCALE_FAR
;
3655 reg_no
= XSCALE_PID
;
3658 reg_no
= XSCALE_CPACCESS
;
3661 command_print(cmd_ctx
, "invalid register number");
3662 return ERROR_INVALID_ARGUMENTS
;
3664 reg
= &xscale
->reg_cache
->reg_list
[reg_no
];
3671 /* read cp15 control register */
3672 xscale_get_reg(reg
);
3673 value
= buf_get_u32(reg
->value
, 0, 32);
3674 command_print(cmd_ctx
, "%s (/%i): 0x%x", reg
->name
, reg
->size
, value
);
3679 u32 value
= strtoul(args
[1], NULL
, 0);
3681 /* send CP write request (command 0x41) */
3682 xscale_send_u32(target
, 0x41);
3684 /* send CP register number */
3685 xscale_send_u32(target
, reg_no
);
3687 /* send CP register value */
3688 xscale_send_u32(target
, value
);
3690 /* execute cpwait to ensure outstanding operations complete */
3691 xscale_send_u32(target
, 0x53);
3695 command_print(cmd_ctx
, "usage: cp15 [register]<, [value]>");
3701 int xscale_register_commands(struct command_context_s
*cmd_ctx
)
3703 command_t
*xscale_cmd
;
3705 xscale_cmd
= register_command(cmd_ctx
, NULL
, "xscale", NULL
, COMMAND_ANY
, "xscale specific commands");
3707 register_command(cmd_ctx
, xscale_cmd
, "debug_handler", xscale_handle_debug_handler_command
, COMMAND_ANY
, "'xscale debug_handler <target#> <address>' command takes two required operands");
3708 register_command(cmd_ctx
, xscale_cmd
, "cache_clean_address", xscale_handle_cache_clean_address_command
, COMMAND_ANY
, NULL
);
3710 register_command(cmd_ctx
, xscale_cmd
, "cache_info", xscale_handle_cache_info_command
, COMMAND_EXEC
, NULL
);
3711 register_command(cmd_ctx
, xscale_cmd
, "mmu", xscale_handle_mmu_command
, COMMAND_EXEC
, "['enable'|'disable'] the MMU");
3712 register_command(cmd_ctx
, xscale_cmd
, "icache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the ICache");
3713 register_command(cmd_ctx
, xscale_cmd
, "dcache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the DCache");
3715 register_command(cmd_ctx
, xscale_cmd
, "vector_catch", xscale_handle_idcache_command
, COMMAND_EXEC
, "<mask> of vectors that should be catched");
3717 register_command(cmd_ctx
, xscale_cmd
, "trace_buffer", xscale_handle_trace_buffer_command
, COMMAND_EXEC
, "<enable|disable> ['fill' [n]|'wrap']");
3719 register_command(cmd_ctx
, xscale_cmd
, "dump_trace", xscale_handle_dump_trace_command
, COMMAND_EXEC
, "dump content of trace buffer to <file>");
3720 register_command(cmd_ctx
, xscale_cmd
, "analyze_trace", xscale_handle_analyze_trace_buffer_command
, COMMAND_EXEC
, "analyze content of trace buffer");
3721 register_command(cmd_ctx
, xscale_cmd
, "trace_image", xscale_handle_trace_image_command
,
3722 COMMAND_EXEC
, "load image from <file> [base address]");
3724 register_command(cmd_ctx
, xscale_cmd
, "cp15", xscale_handle_cp15
, COMMAND_EXEC
, "access coproc 15 <register> [value]");
3726 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)