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_create(struct target_s
*target
, Jim_Interp
*interp
);
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_create
= xscale_target_create
,
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(jtag_tap_t
*tap
, u32 new_instr
)
220 if (buf_get_u32(tap
->cur_instr
, 0, tap
->ir_length
) != new_instr
)
225 field
.num_bits
= tap
->ir_length
;
226 field
.out_value
= calloc(CEIL(field
.num_bits
, 8), 1);
227 buf_set_u32(field
.out_value
, 0, field
.num_bits
, new_instr
);
228 field
.out_mask
= NULL
;
229 field
.in_value
= NULL
;
230 jtag_set_check_value(&field
, tap
->expected
, tap
->expected_mask
, NULL
);
232 jtag_add_ir_scan(1, &field
, TAP_INVALID
);
234 free(field
.out_value
);
240 int xscale_read_dcsr(target_t
*target
)
242 armv4_5_common_t
*armv4_5
= target
->arch_info
;
243 xscale_common_t
*xscale
= armv4_5
->arch_info
;
247 scan_field_t fields
[3];
249 u8 field0_check_value
= 0x2;
250 u8 field0_check_mask
= 0x7;
252 u8 field2_check_value
= 0x0;
253 u8 field2_check_mask
= 0x1;
255 jtag_add_end_state(TAP_DRPAUSE
);
256 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dcsr
);
258 buf_set_u32(&field0
, 1, 1, xscale
->hold_rst
);
259 buf_set_u32(&field0
, 2, 1, xscale
->external_debug_break
);
261 fields
[0].tap
= xscale
->jtag_info
.tap
;
262 fields
[0].num_bits
= 3;
263 fields
[0].out_value
= &field0
;
264 fields
[0].out_mask
= NULL
;
265 fields
[0].in_value
= NULL
;
266 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
268 fields
[1].tap
= xscale
->jtag_info
.tap
;
269 fields
[1].num_bits
= 32;
270 fields
[1].out_value
= NULL
;
271 fields
[1].out_mask
= NULL
;
272 fields
[1].in_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
273 fields
[1].in_handler
= NULL
;
274 fields
[1].in_handler_priv
= NULL
;
275 fields
[1].in_check_value
= NULL
;
276 fields
[1].in_check_mask
= NULL
;
278 fields
[2].tap
= xscale
->jtag_info
.tap
;
279 fields
[2].num_bits
= 1;
280 fields
[2].out_value
= &field2
;
281 fields
[2].out_mask
= NULL
;
282 fields
[2].in_value
= NULL
;
283 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
285 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
287 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
289 LOG_ERROR("JTAG error while reading DCSR");
293 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].dirty
= 0;
294 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].valid
= 1;
296 /* write the register with the value we just read
297 * on this second pass, only the first bit of field0 is guaranteed to be 0)
299 field0_check_mask
= 0x1;
300 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
301 fields
[1].in_value
= NULL
;
303 jtag_add_end_state(TAP_IDLE
);
305 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
307 /* DANGER!!! this must be here. It will make sure that the arguments
308 * to jtag_set_check_value() does not go out of scope! */
309 return jtag_execute_queue();
312 int xscale_receive(target_t
*target
, u32
*buffer
, int num_words
)
315 return ERROR_INVALID_ARGUMENTS
;
318 armv4_5_common_t
*armv4_5
= target
->arch_info
;
319 xscale_common_t
*xscale
= armv4_5
->arch_info
;
322 scan_field_t fields
[3];
324 u8
*field0
= malloc(num_words
* 1);
325 u8 field0_check_value
= 0x2;
326 u8 field0_check_mask
= 0x6;
327 u32
*field1
= malloc(num_words
* 4);
328 u8 field2_check_value
= 0x0;
329 u8 field2_check_mask
= 0x1;
331 int words_scheduled
= 0;
335 path
[0] = TAP_DRSELECT
;
336 path
[1] = TAP_DRCAPTURE
;
337 path
[2] = TAP_DRSHIFT
;
339 fields
[0].tap
= xscale
->jtag_info
.tap
;
340 fields
[0].num_bits
= 3;
341 fields
[0].out_value
= NULL
;
342 fields
[0].out_mask
= NULL
;
343 fields
[0].in_value
= NULL
;
344 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
346 fields
[1].tap
= xscale
->jtag_info
.tap
;
347 fields
[1].num_bits
= 32;
348 fields
[1].out_value
= NULL
;
349 fields
[1].out_mask
= NULL
;
350 fields
[1].in_value
= NULL
;
351 fields
[1].in_handler
= NULL
;
352 fields
[1].in_handler_priv
= NULL
;
353 fields
[1].in_check_value
= NULL
;
354 fields
[1].in_check_mask
= NULL
;
356 fields
[2].tap
= xscale
->jtag_info
.tap
;
357 fields
[2].num_bits
= 1;
358 fields
[2].out_value
= NULL
;
359 fields
[2].out_mask
= NULL
;
360 fields
[2].in_value
= NULL
;
361 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
363 jtag_add_end_state(TAP_IDLE
);
364 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dbgtx
);
365 jtag_add_runtest(1, TAP_INVALID
); /* ensures that we're in the TAP_IDLE state as the above could be a no-op */
367 /* repeat until all words have been collected */
369 while (words_done
< num_words
)
373 for (i
= words_done
; i
< num_words
; i
++)
375 fields
[0].in_value
= &field0
[i
];
376 fields
[1].in_handler
= buf_to_u32_handler
;
377 fields
[1].in_handler_priv
= (u8
*)&field1
[i
];
379 jtag_add_pathmove(3, path
);
380 jtag_add_dr_scan(3, fields
, TAP_IDLE
);
384 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
386 LOG_ERROR("JTAG error while receiving data from debug handler");
390 /* examine results */
391 for (i
= words_done
; i
< num_words
; i
++)
393 if (!(field0
[0] & 1))
395 /* move backwards if necessary */
397 for (j
= i
; j
< num_words
- 1; j
++)
399 field0
[j
] = field0
[j
+1];
400 field1
[j
] = field1
[j
+1];
405 if (words_scheduled
==0)
407 if (attempts
++==1000)
409 LOG_ERROR("Failed to receiving data from debug handler after 1000 attempts");
410 retval
=ERROR_TARGET_TIMEOUT
;
415 words_done
+= words_scheduled
;
418 for (i
= 0; i
< num_words
; i
++)
419 *(buffer
++) = buf_get_u32((u8
*)&field1
[i
], 0, 32);
426 int xscale_read_tx(target_t
*target
, int consume
)
428 armv4_5_common_t
*armv4_5
= target
->arch_info
;
429 xscale_common_t
*xscale
= armv4_5
->arch_info
;
431 tap_state_t noconsume_path
[6];
434 struct timeval timeout
, now
;
436 scan_field_t fields
[3];
438 u8 field0_check_value
= 0x2;
439 u8 field0_check_mask
= 0x6;
440 u8 field2_check_value
= 0x0;
441 u8 field2_check_mask
= 0x1;
443 jtag_add_end_state(TAP_IDLE
);
445 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dbgtx
);
447 path
[0] = TAP_DRSELECT
;
448 path
[1] = TAP_DRCAPTURE
;
449 path
[2] = TAP_DRSHIFT
;
451 noconsume_path
[0] = TAP_DRSELECT
;
452 noconsume_path
[1] = TAP_DRCAPTURE
;
453 noconsume_path
[2] = TAP_DREXIT1
;
454 noconsume_path
[3] = TAP_DRPAUSE
;
455 noconsume_path
[4] = TAP_DREXIT2
;
456 noconsume_path
[5] = TAP_DRSHIFT
;
458 fields
[0].tap
= xscale
->jtag_info
.tap
;
459 fields
[0].num_bits
= 3;
460 fields
[0].out_value
= NULL
;
461 fields
[0].out_mask
= NULL
;
462 fields
[0].in_value
= &field0_in
;
463 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
465 fields
[1].tap
= xscale
->jtag_info
.tap
;
466 fields
[1].num_bits
= 32;
467 fields
[1].out_value
= NULL
;
468 fields
[1].out_mask
= NULL
;
469 fields
[1].in_value
= xscale
->reg_cache
->reg_list
[XSCALE_TX
].value
;
470 fields
[1].in_handler
= NULL
;
471 fields
[1].in_handler_priv
= NULL
;
472 fields
[1].in_check_value
= NULL
;
473 fields
[1].in_check_mask
= NULL
;
475 fields
[2].tap
= xscale
->jtag_info
.tap
;
476 fields
[2].num_bits
= 1;
477 fields
[2].out_value
= NULL
;
478 fields
[2].out_mask
= NULL
;
479 fields
[2].in_value
= NULL
;
480 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
482 gettimeofday(&timeout
, NULL
);
483 timeval_add_time(&timeout
, 1, 0);
487 /* if we want to consume the register content (i.e. clear TX_READY),
488 * we have to go straight from Capture-DR to Shift-DR
489 * otherwise, we go from Capture-DR to Exit1-DR to Pause-DR
492 jtag_add_pathmove(3, path
);
495 jtag_add_pathmove(sizeof(noconsume_path
)/sizeof(*noconsume_path
), noconsume_path
);
498 jtag_add_dr_scan(3, fields
, TAP_IDLE
);
500 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
502 LOG_ERROR("JTAG error while reading TX");
503 return ERROR_TARGET_TIMEOUT
;
506 gettimeofday(&now
, NULL
);
507 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
)&& (now
.tv_usec
> timeout
.tv_usec
)))
509 LOG_ERROR("time out reading TX register");
510 return ERROR_TARGET_TIMEOUT
;
512 if (!((!(field0_in
& 1)) && consume
))
518 LOG_DEBUG("waiting 100ms");
519 alive_sleep(100); /* 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_IDLE
);
552 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dbgrx
);
554 fields
[0].tap
= xscale
->jtag_info
.tap
;
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].tap
= xscale
->jtag_info
.tap
;
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
;
571 fields
[2].tap
= xscale
->jtag_info
.tap
;
572 fields
[2].num_bits
= 1;
573 fields
[2].out_value
= &field2
;
574 fields
[2].out_mask
= NULL
;
575 fields
[2].in_value
= NULL
;
576 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
578 gettimeofday(&timeout
, NULL
);
579 timeval_add_time(&timeout
, 1, 0);
581 /* poll until rx_read is low */
582 LOG_DEBUG("polling RX");
585 jtag_add_dr_scan(3, fields
, TAP_IDLE
);
587 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
589 LOG_ERROR("JTAG error while writing RX");
593 gettimeofday(&now
, NULL
);
594 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
)&& (now
.tv_usec
> timeout
.tv_usec
)))
596 LOG_ERROR("time out writing RX register");
597 return ERROR_TARGET_TIMEOUT
;
599 if (!(field0_in
& 1))
603 LOG_DEBUG("waiting 100ms");
604 alive_sleep(100); /* avoid flooding the logs */
614 jtag_add_dr_scan(3, fields
, TAP_IDLE
);
616 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
618 LOG_ERROR("JTAG error while writing RX");
625 /* send count elements of size byte to the debug handler */
626 int xscale_send(target_t
*target
, u8
*buffer
, int count
, int size
)
628 armv4_5_common_t
*armv4_5
= target
->arch_info
;
629 xscale_common_t
*xscale
= armv4_5
->arch_info
;
637 jtag_add_end_state(TAP_IDLE
);
639 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dbgrx
);
646 int endianness
= target
->endianness
;
647 while (done_count
++ < count
)
652 if (endianness
== TARGET_LITTLE_ENDIAN
)
654 t
[1]=le_to_h_u32(buffer
);
657 t
[1]=be_to_h_u32(buffer
);
661 if (endianness
== TARGET_LITTLE_ENDIAN
)
663 t
[1]=le_to_h_u16(buffer
);
666 t
[1]=be_to_h_u16(buffer
);
673 LOG_ERROR("BUG: size neither 4, 2 nor 1");
676 jtag_add_dr_out(xscale
->jtag_info
.tap
,
684 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
686 LOG_ERROR("JTAG error while sending data to debug handler");
693 int xscale_send_u32(target_t
*target
, u32 value
)
695 armv4_5_common_t
*armv4_5
= target
->arch_info
;
696 xscale_common_t
*xscale
= armv4_5
->arch_info
;
698 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
699 return xscale_write_rx(target
);
702 int xscale_write_dcsr(target_t
*target
, int hold_rst
, int ext_dbg_brk
)
704 armv4_5_common_t
*armv4_5
= target
->arch_info
;
705 xscale_common_t
*xscale
= armv4_5
->arch_info
;
709 scan_field_t fields
[3];
711 u8 field0_check_value
= 0x2;
712 u8 field0_check_mask
= 0x7;
714 u8 field2_check_value
= 0x0;
715 u8 field2_check_mask
= 0x1;
718 xscale
->hold_rst
= hold_rst
;
720 if (ext_dbg_brk
!= -1)
721 xscale
->external_debug_break
= ext_dbg_brk
;
723 jtag_add_end_state(TAP_IDLE
);
724 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dcsr
);
726 buf_set_u32(&field0
, 1, 1, xscale
->hold_rst
);
727 buf_set_u32(&field0
, 2, 1, xscale
->external_debug_break
);
729 fields
[0].tap
= xscale
->jtag_info
.tap
;
730 fields
[0].num_bits
= 3;
731 fields
[0].out_value
= &field0
;
732 fields
[0].out_mask
= NULL
;
733 fields
[0].in_value
= NULL
;
734 jtag_set_check_value(fields
+0, &field0_check_value
, &field0_check_mask
, NULL
);
736 fields
[1].tap
= xscale
->jtag_info
.tap
;
737 fields
[1].num_bits
= 32;
738 fields
[1].out_value
= xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
;
739 fields
[1].out_mask
= NULL
;
740 fields
[1].in_value
= NULL
;
741 fields
[1].in_handler
= NULL
;
742 fields
[1].in_handler_priv
= NULL
;
743 fields
[1].in_check_value
= NULL
;
744 fields
[1].in_check_mask
= NULL
;
746 fields
[2].tap
= xscale
->jtag_info
.tap
;
747 fields
[2].num_bits
= 1;
748 fields
[2].out_value
= &field2
;
749 fields
[2].out_mask
= NULL
;
750 fields
[2].in_value
= NULL
;
751 jtag_set_check_value(fields
+2, &field2_check_value
, &field2_check_mask
, NULL
);
753 jtag_add_dr_scan(3, fields
, TAP_INVALID
);
755 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
757 LOG_ERROR("JTAG error while writing DCSR");
761 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].dirty
= 0;
762 xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].valid
= 1;
767 /* parity of the number of bits 0 if even; 1 if odd. for 32 bit words */
768 unsigned int parity (unsigned int v
)
775 LOG_DEBUG("parity of 0x%x is %i", ov
, (0x6996 >> v
) & 1);
776 return (0x6996 >> v
) & 1;
779 int xscale_load_ic(target_t
*target
, int mini
, u32 va
, u32 buffer
[8])
781 armv4_5_common_t
*armv4_5
= target
->arch_info
;
782 xscale_common_t
*xscale
= armv4_5
->arch_info
;
787 scan_field_t fields
[2];
789 LOG_DEBUG("loading miniIC at 0x%8.8x", va
);
791 jtag_add_end_state(TAP_IDLE
);
792 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.ldic
); /* LDIC */
794 /* CMD is b010 for Main IC and b011 for Mini IC */
796 buf_set_u32(&cmd
, 0, 3, 0x3);
798 buf_set_u32(&cmd
, 0, 3, 0x2);
800 buf_set_u32(&cmd
, 3, 3, 0x0);
802 /* virtual address of desired cache line */
803 buf_set_u32(packet
, 0, 27, va
>> 5);
805 fields
[0].tap
= xscale
->jtag_info
.tap
;
806 fields
[0].num_bits
= 6;
807 fields
[0].out_value
= &cmd
;
808 fields
[0].out_mask
= NULL
;
809 fields
[0].in_value
= NULL
;
810 fields
[0].in_check_value
= NULL
;
811 fields
[0].in_check_mask
= NULL
;
812 fields
[0].in_handler
= NULL
;
813 fields
[0].in_handler_priv
= NULL
;
815 fields
[1].tap
= xscale
->jtag_info
.tap
;
816 fields
[1].num_bits
= 27;
817 fields
[1].out_value
= packet
;
818 fields
[1].out_mask
= NULL
;
819 fields
[1].in_value
= NULL
;
820 fields
[1].in_check_value
= NULL
;
821 fields
[1].in_check_mask
= NULL
;
822 fields
[1].in_handler
= NULL
;
823 fields
[1].in_handler_priv
= NULL
;
825 jtag_add_dr_scan(2, fields
, TAP_INVALID
);
827 fields
[0].num_bits
= 32;
828 fields
[0].out_value
= packet
;
830 fields
[1].num_bits
= 1;
831 fields
[1].out_value
= &cmd
;
833 for (word
= 0; word
< 8; word
++)
835 buf_set_u32(packet
, 0, 32, buffer
[word
]);
836 cmd
= parity(*((u32
*)packet
));
837 jtag_add_dr_scan(2, fields
, TAP_INVALID
);
840 jtag_execute_queue();
845 int xscale_invalidate_ic_line(target_t
*target
, u32 va
)
847 armv4_5_common_t
*armv4_5
= target
->arch_info
;
848 xscale_common_t
*xscale
= armv4_5
->arch_info
;
852 scan_field_t fields
[2];
854 jtag_add_end_state(TAP_IDLE
);
855 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.ldic
); /* LDIC */
857 /* CMD for invalidate IC line b000, bits [6:4] b000 */
858 buf_set_u32(&cmd
, 0, 6, 0x0);
860 /* virtual address of desired cache line */
861 buf_set_u32(packet
, 0, 27, va
>> 5);
863 fields
[0].tap
= xscale
->jtag_info
.tap
;
864 fields
[0].num_bits
= 6;
865 fields
[0].out_value
= &cmd
;
866 fields
[0].out_mask
= NULL
;
867 fields
[0].in_value
= NULL
;
868 fields
[0].in_check_value
= NULL
;
869 fields
[0].in_check_mask
= NULL
;
870 fields
[0].in_handler
= NULL
;
871 fields
[0].in_handler_priv
= NULL
;
873 fields
[1].tap
= xscale
->jtag_info
.tap
;
874 fields
[1].num_bits
= 27;
875 fields
[1].out_value
= packet
;
876 fields
[1].out_mask
= NULL
;
877 fields
[1].in_value
= NULL
;
878 fields
[1].in_check_value
= NULL
;
879 fields
[1].in_check_mask
= NULL
;
880 fields
[1].in_handler
= NULL
;
881 fields
[1].in_handler_priv
= NULL
;
883 jtag_add_dr_scan(2, fields
, TAP_INVALID
);
888 int xscale_update_vectors(target_t
*target
)
890 armv4_5_common_t
*armv4_5
= target
->arch_info
;
891 xscale_common_t
*xscale
= armv4_5
->arch_info
;
895 u32 low_reset_branch
, high_reset_branch
;
897 for (i
= 1; i
< 8; i
++)
899 /* if there's a static vector specified for this exception, override */
900 if (xscale
->static_high_vectors_set
& (1 << i
))
902 xscale
->high_vectors
[i
] = xscale
->static_high_vectors
[i
];
906 retval
=target_read_u32(target
, 0xffff0000 + 4*i
, &xscale
->high_vectors
[i
]);
907 if (retval
== ERROR_TARGET_TIMEOUT
)
909 if (retval
!=ERROR_OK
)
911 /* Some of these reads will fail as part of normal execution */
912 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
917 for (i
= 1; i
< 8; i
++)
919 if (xscale
->static_low_vectors_set
& (1 << i
))
921 xscale
->low_vectors
[i
] = xscale
->static_low_vectors
[i
];
925 retval
=target_read_u32(target
, 0x0 + 4*i
, &xscale
->low_vectors
[i
]);
926 if (retval
== ERROR_TARGET_TIMEOUT
)
928 if (retval
!=ERROR_OK
)
930 /* Some of these reads will fail as part of normal execution */
931 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
936 /* calculate branches to debug handler */
937 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
938 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
940 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
941 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
943 /* invalidate and load exception vectors in mini i-cache */
944 xscale_invalidate_ic_line(target
, 0x0);
945 xscale_invalidate_ic_line(target
, 0xffff0000);
947 xscale_load_ic(target
, 1, 0x0, xscale
->low_vectors
);
948 xscale_load_ic(target
, 1, 0xffff0000, xscale
->high_vectors
);
953 int xscale_arch_state(struct target_s
*target
)
955 armv4_5_common_t
*armv4_5
= target
->arch_info
;
956 xscale_common_t
*xscale
= armv4_5
->arch_info
;
960 "disabled", "enabled"
963 char *arch_dbg_reason
[] =
965 "", "\n(processor reset)", "\n(trace buffer full)"
968 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
970 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
974 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
975 "cpsr: 0x%8.8x pc: 0x%8.8x\n"
976 "MMU: %s, D-Cache: %s, I-Cache: %s"
978 armv4_5_state_strings
[armv4_5
->core_state
],
979 Jim_Nvp_value2name_simple( nvp_target_debug_reason
, target
->debug_reason
)->name
,
980 armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)],
981 buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32),
982 buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32),
983 state
[xscale
->armv4_5_mmu
.mmu_enabled
],
984 state
[xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
],
985 state
[xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
],
986 arch_dbg_reason
[xscale
->arch_debug_reason
]);
991 int xscale_poll(target_t
*target
)
994 armv4_5_common_t
*armv4_5
= target
->arch_info
;
995 xscale_common_t
*xscale
= armv4_5
->arch_info
;
997 if ((target
->state
== TARGET_RUNNING
) || (target
->state
== TARGET_DEBUG_RUNNING
))
999 enum target_state previous_state
= target
->state
;
1000 if ((retval
= xscale_read_tx(target
, 0)) == ERROR_OK
)
1003 /* there's data to read from the tx register, we entered debug state */
1004 xscale
->handler_running
= 1;
1006 target
->state
= TARGET_HALTED
;
1008 /* process debug entry, fetching current mode regs */
1009 retval
= xscale_debug_entry(target
);
1011 else if (retval
!= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
1013 LOG_USER("error while polling TX register, reset CPU");
1014 /* here we "lie" so GDB won't get stuck and a reset can be perfomed */
1015 target
->state
= TARGET_HALTED
;
1018 /* debug_entry could have overwritten target state (i.e. immediate resume)
1019 * don't signal event handlers in that case
1021 if (target
->state
!= TARGET_HALTED
)
1024 /* if target was running, signal that we halted
1025 * otherwise we reentered from debug execution */
1026 if (previous_state
== TARGET_RUNNING
)
1027 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1029 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
1035 int xscale_debug_entry(target_t
*target
)
1037 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1038 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1046 /* clear external dbg break (will be written on next DCSR read) */
1047 xscale
->external_debug_break
= 0;
1048 if ((retval
=xscale_read_dcsr(target
))!=ERROR_OK
)
1051 /* get r0, pc, r1 to r7 and cpsr */
1052 if ((retval
=xscale_receive(target
, buffer
, 10))!=ERROR_OK
)
1055 /* move r0 from buffer to register cache */
1056 buf_set_u32(armv4_5
->core_cache
->reg_list
[0].value
, 0, 32, buffer
[0]);
1057 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
1058 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
1059 LOG_DEBUG("r0: 0x%8.8x", buffer
[0]);
1061 /* move pc from buffer to register cache */
1062 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, buffer
[1]);
1063 armv4_5
->core_cache
->reg_list
[15].dirty
= 1;
1064 armv4_5
->core_cache
->reg_list
[15].valid
= 1;
1065 LOG_DEBUG("pc: 0x%8.8x", buffer
[1]);
1067 /* move data from buffer to register cache */
1068 for (i
= 1; i
<= 7; i
++)
1070 buf_set_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32, buffer
[1 + i
]);
1071 armv4_5
->core_cache
->reg_list
[i
].dirty
= 1;
1072 armv4_5
->core_cache
->reg_list
[i
].valid
= 1;
1073 LOG_DEBUG("r%i: 0x%8.8x", i
, buffer
[i
+ 1]);
1076 buf_set_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32, buffer
[9]);
1077 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].dirty
= 1;
1078 armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].valid
= 1;
1079 LOG_DEBUG("cpsr: 0x%8.8x", buffer
[9]);
1081 armv4_5
->core_mode
= buffer
[9] & 0x1f;
1082 if (armv4_5_mode_to_number(armv4_5
->core_mode
) == -1)
1084 target
->state
= TARGET_UNKNOWN
;
1085 LOG_ERROR("cpsr contains invalid mode value - communication failure");
1086 return ERROR_TARGET_FAILURE
;
1088 LOG_DEBUG("target entered debug state in %s mode", armv4_5_mode_strings
[armv4_5_mode_to_number(armv4_5
->core_mode
)]);
1090 if (buffer
[9] & 0x20)
1091 armv4_5
->core_state
= ARMV4_5_STATE_THUMB
;
1093 armv4_5
->core_state
= ARMV4_5_STATE_ARM
;
1096 if (armv4_5_mode_to_number(armv4_5
->core_mode
)==-1)
1099 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1100 if ((armv4_5
->core_mode
!= ARMV4_5_MODE_USR
) && (armv4_5
->core_mode
!= ARMV4_5_MODE_SYS
))
1102 xscale_receive(target
, buffer
, 8);
1103 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1104 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).dirty
= 0;
1105 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).valid
= 1;
1109 /* r8 to r14, but no spsr */
1110 xscale_receive(target
, buffer
, 7);
1113 /* move data from buffer to register cache */
1114 for (i
= 8; i
<= 14; i
++)
1116 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).value
, 0, 32, buffer
[i
- 8]);
1117 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).dirty
= 0;
1118 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, i
).valid
= 1;
1121 /* examine debug reason */
1122 xscale_read_dcsr(target
);
1123 moe
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 2, 3);
1125 /* stored PC (for calculating fixup) */
1126 pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1130 case 0x0: /* Processor reset */
1131 target
->debug_reason
= DBG_REASON_DBGRQ
;
1132 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_RESET
;
1135 case 0x1: /* Instruction breakpoint hit */
1136 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1137 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1140 case 0x2: /* Data breakpoint hit */
1141 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
1142 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1145 case 0x3: /* BKPT instruction executed */
1146 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1147 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1150 case 0x4: /* Ext. debug event */
1151 target
->debug_reason
= DBG_REASON_DBGRQ
;
1152 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1155 case 0x5: /* Vector trap occured */
1156 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1157 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_GENERIC
;
1160 case 0x6: /* Trace buffer full break */
1161 target
->debug_reason
= DBG_REASON_DBGRQ
;
1162 xscale
->arch_debug_reason
= XSCALE_DBG_REASON_TB_FULL
;
1165 case 0x7: /* Reserved */
1167 LOG_ERROR("Method of Entry is 'Reserved'");
1172 /* apply PC fixup */
1173 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, pc
);
1175 /* on the first debug entry, identify cache type */
1176 if (xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
== -1)
1180 /* read cp15 cache type register */
1181 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
]);
1182 cache_type_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CACHETYPE
].value
, 0, 32);
1184 armv4_5_identify_cache(cache_type_reg
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
1187 /* examine MMU and Cache settings */
1188 /* read cp15 control register */
1189 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
1190 xscale
->cp15_control_reg
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
1191 xscale
->armv4_5_mmu
.mmu_enabled
= (xscale
->cp15_control_reg
& 0x1U
) ? 1 : 0;
1192 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= (xscale
->cp15_control_reg
& 0x4U
) ? 1 : 0;
1193 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= (xscale
->cp15_control_reg
& 0x1000U
) ? 1 : 0;
1195 /* tracing enabled, read collected trace data */
1196 if (xscale
->trace
.buffer_enabled
)
1198 xscale_read_trace(target
);
1199 xscale
->trace
.buffer_fill
--;
1201 /* resume if we're still collecting trace data */
1202 if ((xscale
->arch_debug_reason
== XSCALE_DBG_REASON_TB_FULL
)
1203 && (xscale
->trace
.buffer_fill
> 0))
1205 xscale_resume(target
, 1, 0x0, 1, 0);
1209 xscale
->trace
.buffer_enabled
= 0;
1216 int xscale_halt(target_t
*target
)
1218 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1219 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1221 LOG_DEBUG("target->state: %s",
1222 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
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
];
1258 if (xscale
->ibcr0_used
)
1260 breakpoint_t
*ibcr0_bp
= breakpoint_find(target
, buf_get_u32(ibcr0
->value
, 0, 32) & 0xfffffffe);
1264 xscale_unset_breakpoint(target
, ibcr0_bp
);
1268 LOG_ERROR("BUG: xscale->ibcr0_used is set, but no breakpoint with that address found");
1273 if ((retval
=xscale_set_reg_u32(ibcr0
, next_pc
| 0x1))!=ERROR_OK
)
1279 int xscale_disable_single_step(struct target_s
*target
)
1281 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1282 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1283 reg_t
*ibcr0
= &xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
];
1286 if ((retval
=xscale_set_reg_u32(ibcr0
, 0x0))!=ERROR_OK
)
1292 int xscale_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
1294 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1295 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1296 breakpoint_t
*breakpoint
= target
->breakpoints
;
1305 if (target
->state
!= TARGET_HALTED
)
1307 LOG_WARNING("target not halted");
1308 return ERROR_TARGET_NOT_HALTED
;
1311 if (!debug_execution
)
1313 target_free_all_working_areas(target
);
1316 /* update vector tables */
1317 if ((retval
=xscale_update_vectors(target
))!=ERROR_OK
)
1320 /* current = 1: continue on current pc, otherwise continue at <address> */
1322 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1324 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1326 /* if we're at the reset vector, we have to simulate the branch */
1327 if (current_pc
== 0x0)
1329 arm_simulate_step(target
, NULL
);
1330 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1333 /* the front-end may request us not to handle breakpoints */
1334 if (handle_breakpoints
)
1336 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1340 /* there's a breakpoint at the current PC, we have to step over it */
1341 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
1342 xscale_unset_breakpoint(target
, breakpoint
);
1344 /* calculate PC of next instruction */
1345 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1348 target_read_u32(target
, current_pc
, ¤t_opcode
);
1349 LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode
);
1352 LOG_DEBUG("enable single-step");
1353 xscale_enable_single_step(target
, next_pc
);
1355 /* restore banked registers */
1356 xscale_restore_context(target
);
1358 /* send resume request (command 0x30 or 0x31)
1359 * clean the trace buffer if it is to be enabled (0x62) */
1360 if (xscale
->trace
.buffer_enabled
)
1362 xscale_send_u32(target
, 0x62);
1363 xscale_send_u32(target
, 0x31);
1366 xscale_send_u32(target
, 0x30);
1369 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1370 LOG_DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1372 for (i
= 7; i
>= 0; i
--)
1375 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1376 LOG_DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1380 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1381 LOG_DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1383 /* wait for and process debug entry */
1384 xscale_debug_entry(target
);
1386 LOG_DEBUG("disable single-step");
1387 xscale_disable_single_step(target
);
1389 LOG_DEBUG("set breakpoint at 0x%8.8x", breakpoint
->address
);
1390 xscale_set_breakpoint(target
, breakpoint
);
1394 /* enable any pending breakpoints and watchpoints */
1395 xscale_enable_breakpoints(target
);
1396 xscale_enable_watchpoints(target
);
1398 /* restore banked registers */
1399 xscale_restore_context(target
);
1401 /* send resume request (command 0x30 or 0x31)
1402 * clean the trace buffer if it is to be enabled (0x62) */
1403 if (xscale
->trace
.buffer_enabled
)
1405 xscale_send_u32(target
, 0x62);
1406 xscale_send_u32(target
, 0x31);
1409 xscale_send_u32(target
, 0x30);
1412 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1413 LOG_DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1415 for (i
= 7; i
>= 0; i
--)
1418 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1419 LOG_DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1423 xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1424 LOG_DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1426 target
->debug_reason
= DBG_REASON_NOTHALTED
;
1428 if (!debug_execution
)
1430 /* registers are now invalid */
1431 armv4_5_invalidate_core_regs(target
);
1432 target
->state
= TARGET_RUNNING
;
1433 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1437 target
->state
= TARGET_DEBUG_RUNNING
;
1438 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
1441 LOG_DEBUG("target resumed");
1443 xscale
->handler_running
= 1;
1448 static int xscale_step_inner(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
1450 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1451 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1457 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1459 /* calculate PC of next instruction */
1460 if ((retval
= arm_simulate_step(target
, &next_pc
)) != ERROR_OK
)
1462 u32 current_opcode
, current_pc
;
1463 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1465 target_read_u32(target
, current_pc
, ¤t_opcode
);
1466 LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode
);
1470 LOG_DEBUG("enable single-step");
1471 if ((retval
=xscale_enable_single_step(target
, next_pc
))!=ERROR_OK
)
1474 /* restore banked registers */
1475 if ((retval
=xscale_restore_context(target
))!=ERROR_OK
)
1478 /* send resume request (command 0x30 or 0x31)
1479 * clean the trace buffer if it is to be enabled (0x62) */
1480 if (xscale
->trace
.buffer_enabled
)
1482 if ((retval
=xscale_send_u32(target
, 0x62))!=ERROR_OK
)
1484 if ((retval
=xscale_send_u32(target
, 0x31))!=ERROR_OK
)
1488 if ((retval
=xscale_send_u32(target
, 0x30))!=ERROR_OK
)
1492 if ((retval
=xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32)))!=ERROR_OK
)
1494 LOG_DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[ARMV4_5_CPSR
].value
, 0, 32));
1496 for (i
= 7; i
>= 0; i
--)
1499 if ((retval
=xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32)))!=ERROR_OK
)
1501 LOG_DEBUG("writing r%i with value 0x%8.8x", i
, buf_get_u32(armv4_5
->core_cache
->reg_list
[i
].value
, 0, 32));
1505 if ((retval
=xscale_send_u32(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32)))!=ERROR_OK
)
1507 LOG_DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32));
1509 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
1511 /* registers are now invalid */
1512 if ((retval
=armv4_5_invalidate_core_regs(target
))!=ERROR_OK
)
1515 /* wait for and process debug entry */
1516 if ((retval
=xscale_debug_entry(target
))!=ERROR_OK
)
1519 LOG_DEBUG("disable single-step");
1520 if ((retval
=xscale_disable_single_step(target
))!=ERROR_OK
)
1523 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1528 int xscale_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
1530 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1531 breakpoint_t
*breakpoint
= target
->breakpoints
;
1536 if (target
->state
!= TARGET_HALTED
)
1538 LOG_WARNING("target not halted");
1539 return ERROR_TARGET_NOT_HALTED
;
1542 /* current = 1: continue on current pc, otherwise continue at <address> */
1544 buf_set_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32, address
);
1546 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1548 /* if we're at the reset vector, we have to simulate the step */
1549 if (current_pc
== 0x0)
1551 if ((retval
=arm_simulate_step(target
, NULL
))!=ERROR_OK
)
1553 current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
1555 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
1556 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
1561 /* the front-end may request us not to handle breakpoints */
1562 if (handle_breakpoints
)
1563 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32))))
1565 if ((retval
=xscale_unset_breakpoint(target
, breakpoint
))!=ERROR_OK
)
1569 retval
= xscale_step_inner(target
, current
, address
, handle_breakpoints
);
1573 xscale_set_breakpoint(target
, breakpoint
);
1576 LOG_DEBUG("target stepped");
1582 int xscale_assert_reset(target_t
*target
)
1584 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1585 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1587 LOG_DEBUG("target->state: %s",
1588 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
1590 /* select DCSR instruction (set endstate to R-T-I to ensure we don't
1591 * end up in T-L-R, which would reset JTAG
1593 jtag_add_end_state(TAP_IDLE
);
1594 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, xscale
->jtag_info
.dcsr
);
1596 /* set Hold reset, Halt mode and Trap Reset */
1597 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1598 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1599 xscale_write_dcsr(target
, 1, 0);
1601 /* select BYPASS, because having DCSR selected caused problems on the PXA27x */
1602 xscale_jtag_set_instr(xscale
->jtag_info
.tap
, 0x7f);
1603 jtag_execute_queue();
1606 jtag_add_reset(0, 1);
1608 /* sleep 1ms, to be sure we fulfill any requirements */
1609 jtag_add_sleep(1000);
1610 jtag_execute_queue();
1612 target
->state
= TARGET_RESET
;
1614 if (target
->reset_halt
)
1617 if ((retval
= target_halt(target
))!=ERROR_OK
)
1624 int xscale_deassert_reset(target_t
*target
)
1626 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1627 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1629 fileio_t debug_handler
;
1637 breakpoint_t
*breakpoint
= target
->breakpoints
;
1641 xscale
->ibcr_available
= 2;
1642 xscale
->ibcr0_used
= 0;
1643 xscale
->ibcr1_used
= 0;
1645 xscale
->dbr_available
= 2;
1646 xscale
->dbr0_used
= 0;
1647 xscale
->dbr1_used
= 0;
1649 /* mark all hardware breakpoints as unset */
1652 if (breakpoint
->type
== BKPT_HARD
)
1654 breakpoint
->set
= 0;
1656 breakpoint
= breakpoint
->next
;
1659 if (!xscale
->handler_installed
)
1662 jtag_add_reset(0, 0);
1664 /* wait 300ms; 150 and 100ms were not enough */
1665 jtag_add_sleep(300*1000);
1667 jtag_add_runtest(2030, TAP_IDLE
);
1668 jtag_execute_queue();
1670 /* set Hold reset, Halt mode and Trap Reset */
1671 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1672 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1673 xscale_write_dcsr(target
, 1, 0);
1675 /* Load debug handler */
1676 if (fileio_open(&debug_handler
, "xscale/debug_handler.bin", FILEIO_READ
, FILEIO_BINARY
) != ERROR_OK
)
1681 if ((binary_size
= debug_handler
.size
) % 4)
1683 LOG_ERROR("debug_handler.bin: size not a multiple of 4");
1687 if (binary_size
> 0x800)
1689 LOG_ERROR("debug_handler.bin: larger than 2kb");
1693 binary_size
= CEIL(binary_size
, 32) * 32;
1695 address
= xscale
->handler_address
;
1696 while (binary_size
> 0)
1701 if ((retval
= fileio_read(&debug_handler
, 32, buffer
, &buf_cnt
)) != ERROR_OK
)
1706 for (i
= 0; i
< buf_cnt
; i
+= 4)
1708 /* convert LE buffer to host-endian u32 */
1709 cache_line
[i
/ 4] = le_to_h_u32(&buffer
[i
]);
1712 for (; buf_cnt
< 32; buf_cnt
+= 4)
1714 cache_line
[buf_cnt
/ 4] = 0xe1a08008;
1717 /* only load addresses other than the reset vectors */
1718 if ((address
% 0x400) != 0x0)
1720 xscale_load_ic(target
, 1, address
, cache_line
);
1724 binary_size
-= buf_cnt
;
1727 xscale_load_ic(target
, 1, 0x0, xscale
->low_vectors
);
1728 xscale_load_ic(target
, 1, 0xffff0000, xscale
->high_vectors
);
1730 jtag_add_runtest(30, TAP_IDLE
);
1732 jtag_add_sleep(100000);
1734 /* set Hold reset, Halt mode and Trap Reset */
1735 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 30, 1, 0x1);
1736 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 1, 0x1);
1737 xscale_write_dcsr(target
, 1, 0);
1739 /* clear Hold reset to let the target run (should enter debug handler) */
1740 xscale_write_dcsr(target
, 0, 1);
1741 target
->state
= TARGET_RUNNING
;
1743 if (!target
->reset_halt
)
1745 jtag_add_sleep(10000);
1747 /* we should have entered debug now */
1748 xscale_debug_entry(target
);
1749 target
->state
= TARGET_HALTED
;
1751 /* resume the target */
1752 xscale_resume(target
, 1, 0x0, 1, 0);
1755 fileio_close(&debug_handler
);
1759 jtag_add_reset(0, 0);
1765 int xscale_soft_reset_halt(struct target_s
*target
)
1770 int xscale_read_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
)
1775 int xscale_write_core_reg(struct target_s
*target
, int num
, enum armv4_5_mode mode
, u32 value
)
1781 int xscale_full_context(target_t
*target
)
1783 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1791 if (target
->state
!= TARGET_HALTED
)
1793 LOG_WARNING("target not halted");
1794 return ERROR_TARGET_NOT_HALTED
;
1797 buffer
= malloc(4 * 8);
1799 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1800 * we can't enter User mode on an XScale (unpredictable),
1801 * but User shares registers with SYS
1803 for(i
= 1; i
< 7; i
++)
1807 /* check if there are invalid registers in the current mode
1809 for (j
= 0; j
<= 16; j
++)
1811 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
== 0)
1819 /* request banked registers */
1820 xscale_send_u32(target
, 0x0);
1823 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1824 tmp_cpsr
|= 0xc0; /* I/F bits */
1826 /* send CPSR for desired mode */
1827 xscale_send_u32(target
, tmp_cpsr
);
1829 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1830 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1832 xscale_receive(target
, buffer
, 8);
1833 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32, buffer
[7]);
1834 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1835 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).valid
= 1;
1839 xscale_receive(target
, buffer
, 7);
1842 /* move data from buffer to register cache */
1843 for (j
= 8; j
<= 14; j
++)
1845 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).value
, 0, 32, buffer
[j
- 8]);
1846 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1847 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).valid
= 1;
1857 int xscale_restore_context(target_t
*target
)
1859 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1865 if (target
->state
!= TARGET_HALTED
)
1867 LOG_WARNING("target not halted");
1868 return ERROR_TARGET_NOT_HALTED
;
1871 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1872 * we can't enter User mode on an XScale (unpredictable),
1873 * but User shares registers with SYS
1875 for(i
= 1; i
< 7; i
++)
1879 /* check if there are invalid registers in the current mode
1881 for (j
= 8; j
<= 14; j
++)
1883 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
== 1)
1887 /* if not USR/SYS, check if the SPSR needs to be written */
1888 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1890 if (ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
== 1)
1898 /* send banked registers */
1899 xscale_send_u32(target
, 0x1);
1902 tmp_cpsr
|= armv4_5_number_to_mode(i
);
1903 tmp_cpsr
|= 0xc0; /* I/F bits */
1905 /* send CPSR for desired mode */
1906 xscale_send_u32(target
, tmp_cpsr
);
1908 /* send banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1909 for (j
= 8; j
<= 14; j
++)
1911 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, j
).value
, 0, 32));
1912 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), j
).dirty
= 0;
1915 if ((armv4_5_number_to_mode(i
) != ARMV4_5_MODE_USR
) && (armv4_5_number_to_mode(i
) != ARMV4_5_MODE_SYS
))
1917 xscale_send_u32(target
, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5
->core_mode
, 16).value
, 0, 32));
1918 ARMV4_5_CORE_REG_MODE(armv4_5
->core_cache
, armv4_5_number_to_mode(i
), 16).dirty
= 0;
1926 int xscale_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1928 armv4_5_common_t
*armv4_5
= target
->arch_info
;
1929 xscale_common_t
*xscale
= armv4_5
->arch_info
;
1934 LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address
, size
, count
);
1936 if (target
->state
!= TARGET_HALTED
)
1938 LOG_WARNING("target not halted");
1939 return ERROR_TARGET_NOT_HALTED
;
1942 /* sanitize arguments */
1943 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1944 return ERROR_INVALID_ARGUMENTS
;
1946 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1947 return ERROR_TARGET_UNALIGNED_ACCESS
;
1949 /* send memory read request (command 0x1n, n: access size) */
1950 if ((retval
=xscale_send_u32(target
, 0x10 | size
))!=ERROR_OK
)
1953 /* send base address for read request */
1954 if ((retval
=xscale_send_u32(target
, address
))!=ERROR_OK
)
1957 /* send number of requested data words */
1958 if ((retval
=xscale_send_u32(target
, count
))!=ERROR_OK
)
1961 /* receive data from target (count times 32-bit words in host endianness) */
1962 buf32
= malloc(4 * count
);
1963 if ((retval
=xscale_receive(target
, buf32
, count
))!=ERROR_OK
)
1966 /* extract data from host-endian buffer into byte stream */
1967 for (i
= 0; i
< count
; i
++)
1972 target_buffer_set_u32(target
, buffer
, buf32
[i
]);
1976 target_buffer_set_u16(target
, buffer
, buf32
[i
] & 0xffff);
1980 *buffer
++ = buf32
[i
] & 0xff;
1983 LOG_ERROR("should never get here");
1990 /* examine DCSR, to see if Sticky Abort (SA) got set */
1991 if ((retval
=xscale_read_dcsr(target
))!=ERROR_OK
)
1993 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
1996 if ((retval
=xscale_send_u32(target
, 0x60))!=ERROR_OK
)
1999 return ERROR_TARGET_DATA_ABORT
;
2005 int xscale_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
2007 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2008 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2011 LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address
, size
, count
);
2013 if (target
->state
!= TARGET_HALTED
)
2015 LOG_WARNING("target not halted");
2016 return ERROR_TARGET_NOT_HALTED
;
2019 /* sanitize arguments */
2020 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
2021 return ERROR_INVALID_ARGUMENTS
;
2023 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
2024 return ERROR_TARGET_UNALIGNED_ACCESS
;
2026 /* send memory write request (command 0x2n, n: access size) */
2027 if ((retval
=xscale_send_u32(target
, 0x20 | size
))!=ERROR_OK
)
2030 /* send base address for read request */
2031 if ((retval
=xscale_send_u32(target
, address
))!=ERROR_OK
)
2034 /* send number of requested data words to be written*/
2035 if ((retval
=xscale_send_u32(target
, count
))!=ERROR_OK
)
2038 /* extract data from host-endian buffer into byte stream */
2040 for (i
= 0; i
< count
; i
++)
2045 value
= target_buffer_get_u32(target
, buffer
);
2046 xscale_send_u32(target
, value
);
2050 value
= target_buffer_get_u16(target
, buffer
);
2051 xscale_send_u32(target
, value
);
2056 xscale_send_u32(target
, value
);
2060 LOG_ERROR("should never get here");
2065 if ((retval
=xscale_send(target
, buffer
, count
, size
))!=ERROR_OK
)
2068 /* examine DCSR, to see if Sticky Abort (SA) got set */
2069 if ((retval
=xscale_read_dcsr(target
))!=ERROR_OK
)
2071 if (buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 5, 1) == 1)
2074 if ((retval
=xscale_send_u32(target
, 0x60))!=ERROR_OK
)
2077 return ERROR_TARGET_DATA_ABORT
;
2083 int xscale_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
2085 return xscale_write_memory(target
, address
, 4, count
, buffer
);
2088 u32
xscale_get_ttb(target_t
*target
)
2090 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2091 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2094 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_TTB
]);
2095 ttb
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_TTB
].value
, 0, 32);
2100 void xscale_disable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
2102 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2103 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2106 /* read cp15 control register */
2107 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2108 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2111 cp15_control
&= ~0x1U
;
2116 xscale_send_u32(target
, 0x50);
2117 xscale_send_u32(target
, xscale
->cache_clean_address
);
2119 /* invalidate DCache */
2120 xscale_send_u32(target
, 0x51);
2122 cp15_control
&= ~0x4U
;
2127 /* invalidate ICache */
2128 xscale_send_u32(target
, 0x52);
2129 cp15_control
&= ~0x1000U
;
2132 /* write new cp15 control register */
2133 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2135 /* execute cpwait to ensure outstanding operations complete */
2136 xscale_send_u32(target
, 0x53);
2139 void xscale_enable_mmu_caches(target_t
*target
, int mmu
, int d_u_cache
, int i_cache
)
2141 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2142 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2145 /* read cp15 control register */
2146 xscale_get_reg(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
]);
2147 cp15_control
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_CTRL
].value
, 0, 32);
2150 cp15_control
|= 0x1U
;
2153 cp15_control
|= 0x4U
;
2156 cp15_control
|= 0x1000U
;
2158 /* write new cp15 control register */
2159 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_CTRL
], cp15_control
);
2161 /* execute cpwait to ensure outstanding operations complete */
2162 xscale_send_u32(target
, 0x53);
2165 int xscale_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2168 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2169 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2171 if (target
->state
!= TARGET_HALTED
)
2173 LOG_WARNING("target not halted");
2174 return ERROR_TARGET_NOT_HALTED
;
2177 if (breakpoint
->set
)
2179 LOG_WARNING("breakpoint already set");
2183 if (breakpoint
->type
== BKPT_HARD
)
2185 u32 value
= breakpoint
->address
| 1;
2186 if (!xscale
->ibcr0_used
)
2188 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], value
);
2189 xscale
->ibcr0_used
= 1;
2190 breakpoint
->set
= 1; /* breakpoint set on first breakpoint register */
2192 else if (!xscale
->ibcr1_used
)
2194 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], value
);
2195 xscale
->ibcr1_used
= 1;
2196 breakpoint
->set
= 2; /* breakpoint set on second breakpoint register */
2200 LOG_ERROR("BUG: no hardware comparator available");
2204 else if (breakpoint
->type
== BKPT_SOFT
)
2206 if (breakpoint
->length
== 4)
2208 /* keep the original instruction in target endianness */
2209 if((retval
= target
->type
->read_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
2213 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2214 if((retval
= target_write_u32(target
, breakpoint
->address
, xscale
->arm_bkpt
)) != ERROR_OK
)
2221 /* keep the original instruction in target endianness */
2222 if((retval
= target
->type
->read_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
2226 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2227 if((retval
= target_write_u32(target
, breakpoint
->address
, xscale
->thumb_bkpt
)) != ERROR_OK
)
2232 breakpoint
->set
= 1;
2238 int xscale_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2240 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2241 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2243 if (target
->state
!= TARGET_HALTED
)
2245 LOG_WARNING("target not halted");
2246 return ERROR_TARGET_NOT_HALTED
;
2249 if ((breakpoint
->type
== BKPT_HARD
) && (xscale
->ibcr_available
< 1))
2251 LOG_INFO("no breakpoint unit available for hardware breakpoint");
2252 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2255 if ((breakpoint
->length
!= 2) && (breakpoint
->length
!= 4))
2257 LOG_INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
2258 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2261 if (breakpoint
->type
== BKPT_HARD
)
2263 xscale
->ibcr_available
--;
2269 int xscale_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2272 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2273 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2275 if (target
->state
!= TARGET_HALTED
)
2277 LOG_WARNING("target not halted");
2278 return ERROR_TARGET_NOT_HALTED
;
2281 if (!breakpoint
->set
)
2283 LOG_WARNING("breakpoint not set");
2287 if (breakpoint
->type
== BKPT_HARD
)
2289 if (breakpoint
->set
== 1)
2291 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR0
], 0x0);
2292 xscale
->ibcr0_used
= 0;
2294 else if (breakpoint
->set
== 2)
2296 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_IBCR1
], 0x0);
2297 xscale
->ibcr1_used
= 0;
2299 breakpoint
->set
= 0;
2303 /* restore original instruction (kept in target endianness) */
2304 if (breakpoint
->length
== 4)
2306 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
2313 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
2318 breakpoint
->set
= 0;
2324 int xscale_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
2326 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2327 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2329 if (target
->state
!= TARGET_HALTED
)
2331 LOG_WARNING("target not halted");
2332 return ERROR_TARGET_NOT_HALTED
;
2335 if (breakpoint
->set
)
2337 xscale_unset_breakpoint(target
, breakpoint
);
2340 if (breakpoint
->type
== BKPT_HARD
)
2341 xscale
->ibcr_available
++;
2346 int xscale_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2348 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2349 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2351 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2352 u32 dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2354 if (target
->state
!= TARGET_HALTED
)
2356 LOG_WARNING("target not halted");
2357 return ERROR_TARGET_NOT_HALTED
;
2360 xscale_get_reg(dbcon
);
2362 switch (watchpoint
->rw
)
2374 LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
2377 if (!xscale
->dbr0_used
)
2379 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR0
], watchpoint
->address
);
2380 dbcon_value
|= enable
;
2381 xscale_set_reg_u32(dbcon
, dbcon_value
);
2382 watchpoint
->set
= 1;
2383 xscale
->dbr0_used
= 1;
2385 else if (!xscale
->dbr1_used
)
2387 xscale_set_reg_u32(&xscale
->reg_cache
->reg_list
[XSCALE_DBR1
], watchpoint
->address
);
2388 dbcon_value
|= enable
<< 2;
2389 xscale_set_reg_u32(dbcon
, dbcon_value
);
2390 watchpoint
->set
= 2;
2391 xscale
->dbr1_used
= 1;
2395 LOG_ERROR("BUG: no hardware comparator available");
2402 int xscale_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2404 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2405 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2407 if (target
->state
!= TARGET_HALTED
)
2409 LOG_WARNING("target not halted");
2410 return ERROR_TARGET_NOT_HALTED
;
2413 if (xscale
->dbr_available
< 1)
2415 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2418 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
2420 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
2423 xscale
->dbr_available
--;
2428 int xscale_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2430 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2431 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2432 reg_t
*dbcon
= &xscale
->reg_cache
->reg_list
[XSCALE_DBCON
];
2433 u32 dbcon_value
= buf_get_u32(dbcon
->value
, 0, 32);
2435 if (target
->state
!= TARGET_HALTED
)
2437 LOG_WARNING("target not halted");
2438 return ERROR_TARGET_NOT_HALTED
;
2441 if (!watchpoint
->set
)
2443 LOG_WARNING("breakpoint not set");
2447 if (watchpoint
->set
== 1)
2449 dbcon_value
&= ~0x3;
2450 xscale_set_reg_u32(dbcon
, dbcon_value
);
2451 xscale
->dbr0_used
= 0;
2453 else if (watchpoint
->set
== 2)
2455 dbcon_value
&= ~0xc;
2456 xscale_set_reg_u32(dbcon
, dbcon_value
);
2457 xscale
->dbr1_used
= 0;
2459 watchpoint
->set
= 0;
2464 int xscale_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
2466 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2467 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2469 if (target
->state
!= TARGET_HALTED
)
2471 LOG_WARNING("target not halted");
2472 return ERROR_TARGET_NOT_HALTED
;
2475 if (watchpoint
->set
)
2477 xscale_unset_watchpoint(target
, watchpoint
);
2480 xscale
->dbr_available
++;
2485 void xscale_enable_watchpoints(struct target_s
*target
)
2487 watchpoint_t
*watchpoint
= target
->watchpoints
;
2491 if (watchpoint
->set
== 0)
2492 xscale_set_watchpoint(target
, watchpoint
);
2493 watchpoint
= watchpoint
->next
;
2497 void xscale_enable_breakpoints(struct target_s
*target
)
2499 breakpoint_t
*breakpoint
= target
->breakpoints
;
2501 /* set any pending breakpoints */
2504 if (breakpoint
->set
== 0)
2505 xscale_set_breakpoint(target
, breakpoint
);
2506 breakpoint
= breakpoint
->next
;
2510 int xscale_get_reg(reg_t
*reg
)
2512 xscale_reg_t
*arch_info
= reg
->arch_info
;
2513 target_t
*target
= arch_info
->target
;
2514 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2515 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2517 /* DCSR, TX and RX are accessible via JTAG */
2518 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2520 return xscale_read_dcsr(arch_info
->target
);
2522 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2524 /* 1 = consume register content */
2525 return xscale_read_tx(arch_info
->target
, 1);
2527 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2529 /* can't read from RX register (host -> debug handler) */
2532 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2534 /* can't (explicitly) read from TXRXCTRL register */
2537 else /* Other DBG registers have to be transfered by the debug handler */
2539 /* send CP read request (command 0x40) */
2540 xscale_send_u32(target
, 0x40);
2542 /* send CP register number */
2543 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2545 /* read register value */
2546 xscale_read_tx(target
, 1);
2547 buf_cpy(xscale
->reg_cache
->reg_list
[XSCALE_TX
].value
, reg
->value
, 32);
2556 int xscale_set_reg(reg_t
*reg
, u8
* buf
)
2558 xscale_reg_t
*arch_info
= reg
->arch_info
;
2559 target_t
*target
= arch_info
->target
;
2560 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2561 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2562 u32 value
= buf_get_u32(buf
, 0, 32);
2564 /* DCSR, TX and RX are accessible via JTAG */
2565 if (strcmp(reg
->name
, "XSCALE_DCSR") == 0)
2567 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32, value
);
2568 return xscale_write_dcsr(arch_info
->target
, -1, -1);
2570 else if (strcmp(reg
->name
, "XSCALE_RX") == 0)
2572 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_RX
].value
, 0, 32, value
);
2573 return xscale_write_rx(arch_info
->target
);
2575 else if (strcmp(reg
->name
, "XSCALE_TX") == 0)
2577 /* can't write to TX register (debug-handler -> host) */
2580 else if (strcmp(reg
->name
, "XSCALE_TXRXCTRL") == 0)
2582 /* can't (explicitly) write to TXRXCTRL register */
2585 else /* Other DBG registers have to be transfered by the debug handler */
2587 /* send CP write request (command 0x41) */
2588 xscale_send_u32(target
, 0x41);
2590 /* send CP register number */
2591 xscale_send_u32(target
, arch_info
->dbg_handler_number
);
2593 /* send CP register value */
2594 xscale_send_u32(target
, value
);
2595 buf_set_u32(reg
->value
, 0, 32, value
);
2601 /* convenience wrapper to access XScale specific registers */
2602 int xscale_set_reg_u32(reg_t
*reg
, u32 value
)
2606 buf_set_u32(buf
, 0, 32, value
);
2608 return xscale_set_reg(reg
, buf
);
2611 int xscale_write_dcsr_sw(target_t
*target
, u32 value
)
2613 /* get pointers to arch-specific information */
2614 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2615 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2616 reg_t
*dcsr
= &xscale
->reg_cache
->reg_list
[XSCALE_DCSR
];
2617 xscale_reg_t
*dcsr_arch_info
= dcsr
->arch_info
;
2619 /* send CP write request (command 0x41) */
2620 xscale_send_u32(target
, 0x41);
2622 /* send CP register number */
2623 xscale_send_u32(target
, dcsr_arch_info
->dbg_handler_number
);
2625 /* send CP register value */
2626 xscale_send_u32(target
, value
);
2627 buf_set_u32(dcsr
->value
, 0, 32, value
);
2632 int xscale_read_trace(target_t
*target
)
2634 /* get pointers to arch-specific information */
2635 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2636 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2637 xscale_trace_data_t
**trace_data_p
;
2639 /* 258 words from debug handler
2640 * 256 trace buffer entries
2641 * 2 checkpoint addresses
2643 u32 trace_buffer
[258];
2644 int is_address
[256];
2647 if (target
->state
!= TARGET_HALTED
)
2649 LOG_WARNING("target must be stopped to read trace data");
2650 return ERROR_TARGET_NOT_HALTED
;
2653 /* send read trace buffer command (command 0x61) */
2654 xscale_send_u32(target
, 0x61);
2656 /* receive trace buffer content */
2657 xscale_receive(target
, trace_buffer
, 258);
2659 /* parse buffer backwards to identify address entries */
2660 for (i
= 255; i
>= 0; i
--)
2663 if (((trace_buffer
[i
] & 0xf0) == 0x90) ||
2664 ((trace_buffer
[i
] & 0xf0) == 0xd0))
2667 is_address
[--i
] = 1;
2669 is_address
[--i
] = 1;
2671 is_address
[--i
] = 1;
2673 is_address
[--i
] = 1;
2678 /* search first non-zero entry */
2679 for (j
= 0; (j
< 256) && (trace_buffer
[j
] == 0) && (!is_address
[j
]); j
++)
2684 LOG_DEBUG("no trace data collected");
2685 return ERROR_XSCALE_NO_TRACE_DATA
;
2688 for (trace_data_p
= &xscale
->trace
.data
; *trace_data_p
; trace_data_p
= &(*trace_data_p
)->next
)
2691 *trace_data_p
= malloc(sizeof(xscale_trace_data_t
));
2692 (*trace_data_p
)->next
= NULL
;
2693 (*trace_data_p
)->chkpt0
= trace_buffer
[256];
2694 (*trace_data_p
)->chkpt1
= trace_buffer
[257];
2695 (*trace_data_p
)->last_instruction
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
2696 (*trace_data_p
)->entries
= malloc(sizeof(xscale_trace_entry_t
) * (256 - j
));
2697 (*trace_data_p
)->depth
= 256 - j
;
2699 for (i
= j
; i
< 256; i
++)
2701 (*trace_data_p
)->entries
[i
- j
].data
= trace_buffer
[i
];
2703 (*trace_data_p
)->entries
[i
- j
].type
= XSCALE_TRACE_ADDRESS
;
2705 (*trace_data_p
)->entries
[i
- j
].type
= XSCALE_TRACE_MESSAGE
;
2711 int xscale_read_instruction(target_t
*target
, arm_instruction_t
*instruction
)
2713 /* get pointers to arch-specific information */
2714 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2715 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2722 if (!xscale
->trace
.image
)
2723 return ERROR_TRACE_IMAGE_UNAVAILABLE
;
2725 /* search for the section the current instruction belongs to */
2726 for (i
= 0; i
< xscale
->trace
.image
->num_sections
; i
++)
2728 if ((xscale
->trace
.image
->sections
[i
].base_address
<= xscale
->trace
.current_pc
) &&
2729 (xscale
->trace
.image
->sections
[i
].base_address
+ xscale
->trace
.image
->sections
[i
].size
> xscale
->trace
.current_pc
))
2738 /* current instruction couldn't be found in the image */
2739 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2742 if (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
)
2745 if ((retval
= image_read_section(xscale
->trace
.image
, section
,
2746 xscale
->trace
.current_pc
- xscale
->trace
.image
->sections
[section
].base_address
,
2747 4, buf
, &size_read
)) != ERROR_OK
)
2749 LOG_ERROR("error while reading instruction: %i", retval
);
2750 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2752 opcode
= target_buffer_get_u32(target
, buf
);
2753 arm_evaluate_opcode(opcode
, xscale
->trace
.current_pc
, instruction
);
2755 else if (xscale
->trace
.core_state
== ARMV4_5_STATE_THUMB
)
2758 if ((retval
= image_read_section(xscale
->trace
.image
, section
,
2759 xscale
->trace
.current_pc
- xscale
->trace
.image
->sections
[section
].base_address
,
2760 2, buf
, &size_read
)) != ERROR_OK
)
2762 LOG_ERROR("error while reading instruction: %i", retval
);
2763 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE
;
2765 opcode
= target_buffer_get_u16(target
, buf
);
2766 thumb_evaluate_opcode(opcode
, xscale
->trace
.current_pc
, instruction
);
2770 LOG_ERROR("BUG: unknown core state encountered");
2777 int xscale_branch_address(xscale_trace_data_t
*trace_data
, int i
, u32
*target
)
2779 /* if there are less than four entries prior to the indirect branch message
2780 * we can't extract the address */
2786 *target
= (trace_data
->entries
[i
-1].data
) | (trace_data
->entries
[i
-2].data
<< 8) |
2787 (trace_data
->entries
[i
-3].data
<< 16) | (trace_data
->entries
[i
-4].data
<< 24);
2792 int xscale_analyze_trace(target_t
*target
, command_context_t
*cmd_ctx
)
2794 /* get pointers to arch-specific information */
2795 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2796 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2799 xscale_trace_data_t
*trace_data
= xscale
->trace
.data
;
2808 xscale
->trace
.core_state
= ARMV4_5_STATE_ARM
;
2813 for (i
= 0; i
< trace_data
->depth
; i
++)
2819 if (trace_data
->entries
[i
].type
== XSCALE_TRACE_ADDRESS
)
2822 switch ((trace_data
->entries
[i
].data
& 0xf0) >> 4)
2824 case 0: /* Exceptions */
2832 exception
= (trace_data
->entries
[i
].data
& 0x70) >> 4;
2834 next_pc
= (trace_data
->entries
[i
].data
& 0xf0) >> 2;
2835 command_print(cmd_ctx
, "--- exception %i ---", (trace_data
->entries
[i
].data
& 0xf0) >> 4);
2837 case 8: /* Direct Branch */
2840 case 9: /* Indirect Branch */
2842 if (xscale_branch_address(trace_data
, i
, &next_pc
) == 0)
2847 case 13: /* Checkpointed Indirect Branch */
2848 if (xscale_branch_address(trace_data
, i
, &next_pc
) == 0)
2851 if (((chkpt
== 0) && (next_pc
!= trace_data
->chkpt0
))
2852 || ((chkpt
== 1) && (next_pc
!= trace_data
->chkpt1
)))
2853 LOG_WARNING("checkpointed indirect branch target address doesn't match checkpoint");
2855 /* explicit fall-through */
2856 case 12: /* Checkpointed Direct Branch */
2861 next_pc
= trace_data
->chkpt0
;
2864 else if (chkpt
== 1)
2867 next_pc
= trace_data
->chkpt0
;
2872 LOG_WARNING("more than two checkpointed branches encountered");
2875 case 15: /* Roll-over */
2878 default: /* Reserved */
2879 command_print(cmd_ctx
, "--- reserved trace message ---");
2880 LOG_ERROR("BUG: trace message %i is reserved", (trace_data
->entries
[i
].data
& 0xf0) >> 4);
2884 if (xscale
->trace
.pc_ok
)
2886 int executed
= (trace_data
->entries
[i
].data
& 0xf) + rollover
* 16;
2887 arm_instruction_t instruction
;
2889 if ((exception
== 6) || (exception
== 7))
2891 /* IRQ or FIQ exception, no instruction executed */
2895 while (executed
-- >= 0)
2897 if ((retval
= xscale_read_instruction(target
, &instruction
)) != ERROR_OK
)
2899 /* can't continue tracing with no image available */
2900 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
2904 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
2906 /* TODO: handle incomplete images */
2910 /* a precise abort on a load to the PC is included in the incremental
2911 * word count, other instructions causing data aborts are not included
2913 if ((executed
== 0) && (exception
== 4)
2914 && ((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_LDM
)))
2916 if ((instruction
.type
== ARM_LDM
)
2917 && ((instruction
.info
.load_store_multiple
.register_list
& 0x8000) == 0))
2921 else if (((instruction
.type
>= ARM_LDR
) && (instruction
.type
<= ARM_LDRSH
))
2922 && (instruction
.info
.load_store
.Rd
!= 15))
2928 /* only the last instruction executed
2929 * (the one that caused the control flow change)
2930 * could be a taken branch
2932 if (((executed
== -1) && (branch
== 1)) &&
2933 (((instruction
.type
== ARM_B
) ||
2934 (instruction
.type
== ARM_BL
) ||
2935 (instruction
.type
== ARM_BLX
)) &&
2936 (instruction
.info
.b_bl_bx_blx
.target_address
!= ~0UL)))
2938 xscale
->trace
.current_pc
= instruction
.info
.b_bl_bx_blx
.target_address
;
2942 xscale
->trace
.current_pc
+= (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2;
2944 command_print(cmd_ctx
, "%s", instruction
.text
);
2952 xscale
->trace
.current_pc
= next_pc
;
2953 xscale
->trace
.pc_ok
= 1;
2957 for (; xscale
->trace
.current_pc
< trace_data
->last_instruction
; xscale
->trace
.current_pc
+= (xscale
->trace
.core_state
== ARMV4_5_STATE_ARM
) ? 4 : 2)
2959 arm_instruction_t instruction
;
2960 if ((retval
= xscale_read_instruction(target
, &instruction
)) != ERROR_OK
)
2962 /* can't continue tracing with no image available */
2963 if (retval
== ERROR_TRACE_IMAGE_UNAVAILABLE
)
2967 else if (retval
== ERROR_TRACE_INSTRUCTION_UNAVAILABLE
)
2969 /* TODO: handle incomplete images */
2972 command_print(cmd_ctx
, "%s", instruction
.text
);
2975 trace_data
= trace_data
->next
;
2981 void xscale_build_reg_cache(target_t
*target
)
2983 /* get pointers to arch-specific information */
2984 armv4_5_common_t
*armv4_5
= target
->arch_info
;
2985 xscale_common_t
*xscale
= armv4_5
->arch_info
;
2987 reg_cache_t
**cache_p
= register_get_last_cache_p(&target
->reg_cache
);
2988 xscale_reg_t
*arch_info
= malloc(sizeof(xscale_reg_arch_info
));
2990 int num_regs
= sizeof(xscale_reg_arch_info
) / sizeof(xscale_reg_t
);
2992 (*cache_p
) = armv4_5_build_reg_cache(target
, armv4_5
);
2993 armv4_5
->core_cache
= (*cache_p
);
2995 /* register a register arch-type for XScale dbg registers only once */
2996 if (xscale_reg_arch_type
== -1)
2997 xscale_reg_arch_type
= register_reg_arch_type(xscale_get_reg
, xscale_set_reg
);
2999 (*cache_p
)->next
= malloc(sizeof(reg_cache_t
));
3000 cache_p
= &(*cache_p
)->next
;
3002 /* fill in values for the xscale reg cache */
3003 (*cache_p
)->name
= "XScale registers";
3004 (*cache_p
)->next
= NULL
;
3005 (*cache_p
)->reg_list
= malloc(num_regs
* sizeof(reg_t
));
3006 (*cache_p
)->num_regs
= num_regs
;
3008 for (i
= 0; i
< num_regs
; i
++)
3010 (*cache_p
)->reg_list
[i
].name
= xscale_reg_list
[i
];
3011 (*cache_p
)->reg_list
[i
].value
= calloc(4, 1);
3012 (*cache_p
)->reg_list
[i
].dirty
= 0;
3013 (*cache_p
)->reg_list
[i
].valid
= 0;
3014 (*cache_p
)->reg_list
[i
].size
= 32;
3015 (*cache_p
)->reg_list
[i
].bitfield_desc
= NULL
;
3016 (*cache_p
)->reg_list
[i
].num_bitfields
= 0;
3017 (*cache_p
)->reg_list
[i
].arch_info
= &arch_info
[i
];
3018 (*cache_p
)->reg_list
[i
].arch_type
= xscale_reg_arch_type
;
3019 arch_info
[i
] = xscale_reg_arch_info
[i
];
3020 arch_info
[i
].target
= target
;
3023 xscale
->reg_cache
= (*cache_p
);
3026 int xscale_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
3031 int xscale_quit(void)
3036 int xscale_init_arch_info(target_t
*target
, xscale_common_t
*xscale
, jtag_tap_t
*tap
, const char *variant
)
3038 armv4_5_common_t
*armv4_5
;
3039 u32 high_reset_branch
, low_reset_branch
;
3042 armv4_5
= &xscale
->armv4_5_common
;
3044 /* store architecture specfic data (none so far) */
3045 xscale
->arch_info
= NULL
;
3046 xscale
->common_magic
= XSCALE_COMMON_MAGIC
;
3048 /* remember the variant (PXA25x, PXA27x, IXP42x, ...) */
3049 xscale
->variant
= strdup(variant
);
3051 /* prepare JTAG information for the new target */
3052 xscale
->jtag_info
.tap
= tap
;
3054 xscale
->jtag_info
.dbgrx
= 0x02;
3055 xscale
->jtag_info
.dbgtx
= 0x10;
3056 xscale
->jtag_info
.dcsr
= 0x09;
3057 xscale
->jtag_info
.ldic
= 0x07;
3059 if ((strcmp(xscale
->variant
, "pxa250") == 0) ||
3060 (strcmp(xscale
->variant
, "pxa255") == 0) ||
3061 (strcmp(xscale
->variant
, "pxa26x") == 0))
3063 xscale
->jtag_info
.ir_length
= 5;
3065 else if ((strcmp(xscale
->variant
, "pxa27x") == 0) ||
3066 (strcmp(xscale
->variant
, "ixp42x") == 0) ||
3067 (strcmp(xscale
->variant
, "ixp45x") == 0) ||
3068 (strcmp(xscale
->variant
, "ixp46x") == 0))
3070 xscale
->jtag_info
.ir_length
= 7;
3073 /* the debug handler isn't installed (and thus not running) at this time */
3074 xscale
->handler_installed
= 0;
3075 xscale
->handler_running
= 0;
3076 xscale
->handler_address
= 0xfe000800;
3078 /* clear the vectors we keep locally for reference */
3079 memset(xscale
->low_vectors
, 0, sizeof(xscale
->low_vectors
));
3080 memset(xscale
->high_vectors
, 0, sizeof(xscale
->high_vectors
));
3082 /* no user-specified vectors have been configured yet */
3083 xscale
->static_low_vectors_set
= 0x0;
3084 xscale
->static_high_vectors_set
= 0x0;
3086 /* calculate branches to debug handler */
3087 low_reset_branch
= (xscale
->handler_address
+ 0x20 - 0x0 - 0x8) >> 2;
3088 high_reset_branch
= (xscale
->handler_address
+ 0x20 - 0xffff0000 - 0x8) >> 2;
3090 xscale
->low_vectors
[0] = ARMV4_5_B((low_reset_branch
& 0xffffff), 0);
3091 xscale
->high_vectors
[0] = ARMV4_5_B((high_reset_branch
& 0xffffff), 0);
3093 for (i
= 1; i
<= 7; i
++)
3095 xscale
->low_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
3096 xscale
->high_vectors
[i
] = ARMV4_5_B(0xfffffe, 0);
3099 /* 64kB aligned region used for DCache cleaning */
3100 xscale
->cache_clean_address
= 0xfffe0000;
3102 xscale
->hold_rst
= 0;
3103 xscale
->external_debug_break
= 0;
3105 xscale
->ibcr_available
= 2;
3106 xscale
->ibcr0_used
= 0;
3107 xscale
->ibcr1_used
= 0;
3109 xscale
->dbr_available
= 2;
3110 xscale
->dbr0_used
= 0;
3111 xscale
->dbr1_used
= 0;
3113 xscale
->arm_bkpt
= ARMV5_BKPT(0x0);
3114 xscale
->thumb_bkpt
= ARMV5_T_BKPT(0x0) & 0xffff;
3116 xscale
->vector_catch
= 0x1;
3118 xscale
->trace
.capture_status
= TRACE_IDLE
;
3119 xscale
->trace
.data
= NULL
;
3120 xscale
->trace
.image
= NULL
;
3121 xscale
->trace
.buffer_enabled
= 0;
3122 xscale
->trace
.buffer_fill
= 0;
3124 /* prepare ARMv4/5 specific information */
3125 armv4_5
->arch_info
= xscale
;
3126 armv4_5
->read_core_reg
= xscale_read_core_reg
;
3127 armv4_5
->write_core_reg
= xscale_write_core_reg
;
3128 armv4_5
->full_context
= xscale_full_context
;
3130 armv4_5_init_arch_info(target
, armv4_5
);
3132 xscale
->armv4_5_mmu
.armv4_5_cache
.ctype
= -1;
3133 xscale
->armv4_5_mmu
.get_ttb
= xscale_get_ttb
;
3134 xscale
->armv4_5_mmu
.read_memory
= xscale_read_memory
;
3135 xscale
->armv4_5_mmu
.write_memory
= xscale_write_memory
;
3136 xscale
->armv4_5_mmu
.disable_mmu_caches
= xscale_disable_mmu_caches
;
3137 xscale
->armv4_5_mmu
.enable_mmu_caches
= xscale_enable_mmu_caches
;
3138 xscale
->armv4_5_mmu
.has_tiny_pages
= 1;
3139 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3144 /* target xscale <endianess> <startup_mode> <chain_pos> <variant> */
3145 int xscale_target_create(struct target_s
*target
, Jim_Interp
*interp
)
3147 xscale_common_t
*xscale
= calloc(1,sizeof(xscale_common_t
));
3149 xscale_init_arch_info(target
, xscale
, target
->tap
, target
->variant
);
3150 xscale_build_reg_cache(target
);
3155 int xscale_handle_debug_handler_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3157 target_t
*target
= NULL
;
3158 armv4_5_common_t
*armv4_5
;
3159 xscale_common_t
*xscale
;
3161 u32 handler_address
;
3165 LOG_ERROR("'xscale debug_handler <target#> <address>' command takes two required operands");
3169 if ((target
= get_target_by_num(strtoul(args
[0], NULL
, 0))) == NULL
)
3171 LOG_ERROR("no target '%s' configured", args
[0]);
3175 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3180 handler_address
= strtoul(args
[1], NULL
, 0);
3182 if (((handler_address
>= 0x800) && (handler_address
<= 0x1fef800)) ||
3183 ((handler_address
>= 0xfe000800) && (handler_address
<= 0xfffff800)))
3185 xscale
->handler_address
= handler_address
;
3189 LOG_ERROR("xscale debug_handler <address> must be between 0x800 and 0x1fef800 or between 0xfe000800 and 0xfffff800");
3196 int xscale_handle_cache_clean_address_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3198 target_t
*target
= NULL
;
3199 armv4_5_common_t
*armv4_5
;
3200 xscale_common_t
*xscale
;
3202 u32 cache_clean_address
;
3206 return ERROR_COMMAND_SYNTAX_ERROR
;
3209 if ((target
= get_target_by_num(strtoul(args
[0], NULL
, 0))) == NULL
)
3211 LOG_ERROR("no target '%s' configured", args
[0]);
3215 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3220 cache_clean_address
= strtoul(args
[1], NULL
, 0);
3222 if (cache_clean_address
& 0xffff)
3224 LOG_ERROR("xscale cache_clean_address <address> must be 64kb aligned");
3228 xscale
->cache_clean_address
= cache_clean_address
;
3234 int xscale_handle_cache_info_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3236 target_t
*target
= get_current_target(cmd_ctx
);
3237 armv4_5_common_t
*armv4_5
;
3238 xscale_common_t
*xscale
;
3240 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3245 return armv4_5_handle_cache_info_command(cmd_ctx
, &xscale
->armv4_5_mmu
.armv4_5_cache
);
3248 static int xscale_virt2phys(struct target_s
*target
, u32
virtual, u32
*physical
)
3250 armv4_5_common_t
*armv4_5
;
3251 xscale_common_t
*xscale
;
3258 if ((retval
= xscale_get_arch_pointers(target
, &armv4_5
, &xscale
)) != ERROR_OK
)
3262 u32 ret
= armv4_5_mmu_translate_va(target
, &xscale
->armv4_5_mmu
, virtual, &type
, &cb
, &domain
, &ap
);
3271 static int xscale_mmu(struct target_s
*target
, int *enabled
)
3273 armv4_5_common_t
*armv4_5
= target
->arch_info
;
3274 xscale_common_t
*xscale
= armv4_5
->arch_info
;
3276 if (target
->state
!= TARGET_HALTED
)
3278 LOG_ERROR("Target not halted");
3279 return ERROR_TARGET_INVALID
;
3281 *enabled
= xscale
->armv4_5_mmu
.mmu_enabled
;
3285 int xscale_handle_mmu_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3287 target_t
*target
= get_current_target(cmd_ctx
);
3288 armv4_5_common_t
*armv4_5
;
3289 xscale_common_t
*xscale
;
3291 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3296 if (target
->state
!= TARGET_HALTED
)
3298 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3304 if (strcmp("enable", args
[0]) == 0)
3306 xscale_enable_mmu_caches(target
, 1, 0, 0);
3307 xscale
->armv4_5_mmu
.mmu_enabled
= 1;
3309 else if (strcmp("disable", args
[0]) == 0)
3311 xscale_disable_mmu_caches(target
, 1, 0, 0);
3312 xscale
->armv4_5_mmu
.mmu_enabled
= 0;
3316 command_print(cmd_ctx
, "mmu %s", (xscale
->armv4_5_mmu
.mmu_enabled
) ? "enabled" : "disabled");
3321 int xscale_handle_idcache_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3323 target_t
*target
= get_current_target(cmd_ctx
);
3324 armv4_5_common_t
*armv4_5
;
3325 xscale_common_t
*xscale
;
3326 int icache
= 0, dcache
= 0;
3328 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3333 if (target
->state
!= TARGET_HALTED
)
3335 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3339 if (strcmp(cmd
, "icache") == 0)
3341 else if (strcmp(cmd
, "dcache") == 0)
3346 if (strcmp("enable", args
[0]) == 0)
3348 xscale_enable_mmu_caches(target
, 0, dcache
, icache
);
3351 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 1;
3353 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 1;
3355 else if (strcmp("disable", args
[0]) == 0)
3357 xscale_disable_mmu_caches(target
, 0, dcache
, icache
);
3360 xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
= 0;
3362 xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
= 0;
3367 command_print(cmd_ctx
, "icache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
) ? "enabled" : "disabled");
3370 command_print(cmd_ctx
, "dcache %s", (xscale
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
) ? "enabled" : "disabled");
3375 int xscale_handle_vector_catch_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3377 target_t
*target
= get_current_target(cmd_ctx
);
3378 armv4_5_common_t
*armv4_5
;
3379 xscale_common_t
*xscale
;
3381 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3388 command_print(cmd_ctx
, "usage: xscale vector_catch [mask]");
3392 xscale
->vector_catch
= strtoul(args
[0], NULL
, 0);
3393 buf_set_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 16, 8, xscale
->vector_catch
);
3394 xscale_write_dcsr(target
, -1, -1);
3397 command_print(cmd_ctx
, "vector catch mask: 0x%2.2x", xscale
->vector_catch
);
3403 int xscale_handle_trace_buffer_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3405 target_t
*target
= get_current_target(cmd_ctx
);
3406 armv4_5_common_t
*armv4_5
;
3407 xscale_common_t
*xscale
;
3410 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3415 if (target
->state
!= TARGET_HALTED
)
3417 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3421 if ((argc
>= 1) && (strcmp("enable", args
[0]) == 0))
3423 xscale_trace_data_t
*td
, *next_td
;
3424 xscale
->trace
.buffer_enabled
= 1;
3426 /* free old trace data */
3427 td
= xscale
->trace
.data
;
3437 xscale
->trace
.data
= NULL
;
3439 else if ((argc
>= 1) && (strcmp("disable", args
[0]) == 0))
3441 xscale
->trace
.buffer_enabled
= 0;
3444 if ((argc
>= 2) && (strcmp("fill", args
[1]) == 0))
3447 xscale
->trace
.buffer_fill
= strtoul(args
[2], NULL
, 0);
3449 xscale
->trace
.buffer_fill
= 1;
3451 else if ((argc
>= 2) && (strcmp("wrap", args
[1]) == 0))
3453 xscale
->trace
.buffer_fill
= -1;
3456 if (xscale
->trace
.buffer_enabled
)
3458 /* if we enable the trace buffer in fill-once
3459 * mode we know the address of the first instruction */
3460 xscale
->trace
.pc_ok
= 1;
3461 xscale
->trace
.current_pc
= buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32);
3465 /* otherwise the address is unknown, and we have no known good PC */
3466 xscale
->trace
.pc_ok
= 0;
3469 command_print(cmd_ctx
, "trace buffer %s (%s)",
3470 (xscale
->trace
.buffer_enabled
) ? "enabled" : "disabled",
3471 (xscale
->trace
.buffer_fill
> 0) ? "fill" : "wrap");
3473 dcsr_value
= buf_get_u32(xscale
->reg_cache
->reg_list
[XSCALE_DCSR
].value
, 0, 32);
3474 if (xscale
->trace
.buffer_fill
>= 0)
3475 xscale_write_dcsr_sw(target
, (dcsr_value
& 0xfffffffc) | 2);
3477 xscale_write_dcsr_sw(target
, dcsr_value
& 0xfffffffc);
3482 int xscale_handle_trace_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3485 armv4_5_common_t
*armv4_5
;
3486 xscale_common_t
*xscale
;
3490 command_print(cmd_ctx
, "usage: xscale trace_image <file> [base address] [type]");
3494 target
= get_current_target(cmd_ctx
);
3496 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3501 if (xscale
->trace
.image
)
3503 image_close(xscale
->trace
.image
);
3504 free(xscale
->trace
.image
);
3505 command_print(cmd_ctx
, "previously loaded image found and closed");
3508 xscale
->trace
.image
= malloc(sizeof(image_t
));
3509 xscale
->trace
.image
->base_address_set
= 0;
3510 xscale
->trace
.image
->start_address_set
= 0;
3512 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
3515 xscale
->trace
.image
->base_address_set
= 1;
3516 xscale
->trace
.image
->base_address
= strtoul(args
[1], NULL
, 0);
3520 xscale
->trace
.image
->base_address_set
= 0;
3523 if (image_open(xscale
->trace
.image
, args
[0], (argc
>= 3) ? args
[2] : NULL
) != ERROR_OK
)
3525 free(xscale
->trace
.image
);
3526 xscale
->trace
.image
= NULL
;
3533 int xscale_handle_dump_trace_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3535 target_t
*target
= get_current_target(cmd_ctx
);
3536 armv4_5_common_t
*armv4_5
;
3537 xscale_common_t
*xscale
;
3538 xscale_trace_data_t
*trace_data
;
3541 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3546 if (target
->state
!= TARGET_HALTED
)
3548 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3554 command_print(cmd_ctx
, "usage: xscale dump_trace <file>");
3558 trace_data
= xscale
->trace
.data
;
3562 command_print(cmd_ctx
, "no trace data collected");
3566 if (fileio_open(&file
, args
[0], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
)
3575 fileio_write_u32(&file
, trace_data
->chkpt0
);
3576 fileio_write_u32(&file
, trace_data
->chkpt1
);
3577 fileio_write_u32(&file
, trace_data
->last_instruction
);
3578 fileio_write_u32(&file
, trace_data
->depth
);
3580 for (i
= 0; i
< trace_data
->depth
; i
++)
3581 fileio_write_u32(&file
, trace_data
->entries
[i
].data
| ((trace_data
->entries
[i
].type
& 0xffff) << 16));
3583 trace_data
= trace_data
->next
;
3586 fileio_close(&file
);
3591 int xscale_handle_analyze_trace_buffer_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3593 target_t
*target
= get_current_target(cmd_ctx
);
3594 armv4_5_common_t
*armv4_5
;
3595 xscale_common_t
*xscale
;
3597 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3602 xscale_analyze_trace(target
, cmd_ctx
);
3607 int xscale_handle_cp15(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
3609 target_t
*target
= get_current_target(cmd_ctx
);
3610 armv4_5_common_t
*armv4_5
;
3611 xscale_common_t
*xscale
;
3613 if (xscale_get_arch_pointers(target
, &armv4_5
, &xscale
) != ERROR_OK
)
3618 if (target
->state
!= TARGET_HALTED
)
3620 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
3627 reg_no
= strtoul(args
[0], NULL
, 0);
3628 /*translate from xscale cp15 register no to openocd register*/
3632 reg_no
= XSCALE_MAINID
;
3635 reg_no
= XSCALE_CTRL
;
3638 reg_no
= XSCALE_TTB
;
3641 reg_no
= XSCALE_DAC
;
3644 reg_no
= XSCALE_FSR
;
3647 reg_no
= XSCALE_FAR
;
3650 reg_no
= XSCALE_PID
;
3653 reg_no
= XSCALE_CPACCESS
;
3656 command_print(cmd_ctx
, "invalid register number");
3657 return ERROR_INVALID_ARGUMENTS
;
3659 reg
= &xscale
->reg_cache
->reg_list
[reg_no
];
3666 /* read cp15 control register */
3667 xscale_get_reg(reg
);
3668 value
= buf_get_u32(reg
->value
, 0, 32);
3669 command_print(cmd_ctx
, "%s (/%i): 0x%x", reg
->name
, reg
->size
, value
);
3674 u32 value
= strtoul(args
[1], NULL
, 0);
3676 /* send CP write request (command 0x41) */
3677 xscale_send_u32(target
, 0x41);
3679 /* send CP register number */
3680 xscale_send_u32(target
, reg_no
);
3682 /* send CP register value */
3683 xscale_send_u32(target
, value
);
3685 /* execute cpwait to ensure outstanding operations complete */
3686 xscale_send_u32(target
, 0x53);
3690 command_print(cmd_ctx
, "usage: cp15 [register]<, [value]>");
3696 int xscale_register_commands(struct command_context_s
*cmd_ctx
)
3698 command_t
*xscale_cmd
;
3700 xscale_cmd
= register_command(cmd_ctx
, NULL
, "xscale", NULL
, COMMAND_ANY
, "xscale specific commands");
3702 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");
3703 register_command(cmd_ctx
, xscale_cmd
, "cache_clean_address", xscale_handle_cache_clean_address_command
, COMMAND_ANY
, NULL
);
3705 register_command(cmd_ctx
, xscale_cmd
, "cache_info", xscale_handle_cache_info_command
, COMMAND_EXEC
, NULL
);
3706 register_command(cmd_ctx
, xscale_cmd
, "mmu", xscale_handle_mmu_command
, COMMAND_EXEC
, "['enable'|'disable'] the MMU");
3707 register_command(cmd_ctx
, xscale_cmd
, "icache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the ICache");
3708 register_command(cmd_ctx
, xscale_cmd
, "dcache", xscale_handle_idcache_command
, COMMAND_EXEC
, "['enable'|'disable'] the DCache");
3710 register_command(cmd_ctx
, xscale_cmd
, "vector_catch", xscale_handle_vector_catch_command
, COMMAND_EXEC
, "<mask> of vectors that should be catched");
3712 register_command(cmd_ctx
, xscale_cmd
, "trace_buffer", xscale_handle_trace_buffer_command
, COMMAND_EXEC
, "<enable|disable> ['fill' [n]|'wrap']");
3714 register_command(cmd_ctx
, xscale_cmd
, "dump_trace", xscale_handle_dump_trace_command
, COMMAND_EXEC
, "dump content of trace buffer to <file>");
3715 register_command(cmd_ctx
, xscale_cmd
, "analyze_trace", xscale_handle_analyze_trace_buffer_command
, COMMAND_EXEC
, "analyze content of trace buffer");
3716 register_command(cmd_ctx
, xscale_cmd
, "trace_image", xscale_handle_trace_image_command
,
3717 COMMAND_EXEC
, "load image from <file> [base address]");
3719 register_command(cmd_ctx
, xscale_cmd
, "cp15", xscale_handle_cp15
, COMMAND_EXEC
, "access coproc 15 <register> [value]");
3721 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)