retire unused code.
[openocd.git] / src / target / xscale.c
1 /***************************************************************************
2 * Copyright (C) 2006, 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "replacements.h"
25
26 #include "xscale.h"
27
28 #include "register.h"
29 #include "target.h"
30 #include "armv4_5.h"
31 #include "arm_simulator.h"
32 #include "arm_disassembler.h"
33 #include "log.h"
34 #include "jtag.h"
35 #include "binarybuffer.h"
36 #include "time_support.h"
37 #include "breakpoints.h"
38 #include "fileio.h"
39
40 #include <stdlib.h>
41 #include <string.h>
42
43 #include <sys/types.h>
44 #include <unistd.h>
45 #include <errno.h>
46
47
48 /* cli handling */
49 int xscale_register_commands(struct command_context_s *cmd_ctx);
50
51 /* forward declarations */
52 int xscale_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
53 int xscale_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
54 int xscale_quit();
55
56 int xscale_arch_state(struct target_s *target);
57 int xscale_poll(target_t *target);
58 int xscale_halt(target_t *target);
59 int xscale_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution);
60 int xscale_step(struct target_s *target, int current, u32 address, int handle_breakpoints);
61 int xscale_debug_entry(target_t *target);
62 int xscale_restore_context(target_t *target);
63
64 int xscale_assert_reset(target_t *target);
65 int xscale_deassert_reset(target_t *target);
66 int xscale_soft_reset_halt(struct target_s *target);
67 int xscale_prepare_reset_halt(struct target_s *target);
68
69 int xscale_set_reg_u32(reg_t *reg, u32 value);
70
71 int xscale_read_core_reg(struct target_s *target, int num, enum armv4_5_mode mode);
72 int xscale_write_core_reg(struct target_s *target, int num, enum armv4_5_mode mode, u32 value);
73
74 int xscale_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
75 int xscale_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
76 int xscale_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer);
77 int xscale_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum);
78
79 int xscale_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
80 int xscale_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
81 int xscale_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
82 int xscale_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
83 int xscale_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint);
84 int xscale_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint);
85 void xscale_enable_watchpoints(struct target_s *target);
86 void xscale_enable_breakpoints(struct target_s *target);
87 static int xscale_virt2phys(struct target_s *target, u32 virtual, u32 *physical);
88 static int xscale_mmu(struct target_s *target, int *enabled);
89
90 int xscale_read_trace(target_t *target);
91
92 target_type_t xscale_target =
93 {
94 .name = "xscale",
95
96 .poll = xscale_poll,
97 .arch_state = xscale_arch_state,
98
99 .target_request_data = NULL,
100
101 .halt = xscale_halt,
102 .resume = xscale_resume,
103 .step = xscale_step,
104
105 .assert_reset = xscale_assert_reset,
106 .deassert_reset = xscale_deassert_reset,
107 .soft_reset_halt = xscale_soft_reset_halt,
108 .prepare_reset_halt = xscale_prepare_reset_halt,
109
110 .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
111
112 .read_memory = xscale_read_memory,
113 .write_memory = xscale_write_memory,
114 .bulk_write_memory = xscale_bulk_write_memory,
115 .checksum_memory = xscale_checksum_memory,
116
117 .run_algorithm = armv4_5_run_algorithm,
118
119 .add_breakpoint = xscale_add_breakpoint,
120 .remove_breakpoint = xscale_remove_breakpoint,
121 .add_watchpoint = xscale_add_watchpoint,
122 .remove_watchpoint = xscale_remove_watchpoint,
123
124 .register_commands = xscale_register_commands,
125 .target_command = xscale_target_command,
126 .init_target = xscale_init_target,
127 .quit = xscale_quit,
128
129 .virt2phys = xscale_virt2phys,
130 .mmu = xscale_mmu
131 };
132
133 char* xscale_reg_list[] =
134 {
135 "XSCALE_MAINID", /* 0 */
136 "XSCALE_CACHETYPE",
137 "XSCALE_CTRL",
138 "XSCALE_AUXCTRL",
139 "XSCALE_TTB",
140 "XSCALE_DAC",
141 "XSCALE_FSR",
142 "XSCALE_FAR",
143 "XSCALE_PID",
144 "XSCALE_CPACCESS",
145 "XSCALE_IBCR0", /* 10 */
146 "XSCALE_IBCR1",
147 "XSCALE_DBR0",
148 "XSCALE_DBR1",
149 "XSCALE_DBCON",
150 "XSCALE_TBREG",
151 "XSCALE_CHKPT0",
152 "XSCALE_CHKPT1",
153 "XSCALE_DCSR",
154 "XSCALE_TX",
155 "XSCALE_RX", /* 20 */
156 "XSCALE_TXRXCTRL",
157 };
158
159 xscale_reg_t xscale_reg_arch_info[] =
160 {
161 {XSCALE_MAINID, NULL},
162 {XSCALE_CACHETYPE, NULL},
163 {XSCALE_CTRL, NULL},
164 {XSCALE_AUXCTRL, NULL},
165 {XSCALE_TTB, NULL},
166 {XSCALE_DAC, NULL},
167 {XSCALE_FSR, NULL},
168 {XSCALE_FAR, NULL},
169 {XSCALE_PID, NULL},
170 {XSCALE_CPACCESS, NULL},
171 {XSCALE_IBCR0, NULL},
172 {XSCALE_IBCR1, NULL},
173 {XSCALE_DBR0, NULL},
174 {XSCALE_DBR1, NULL},
175 {XSCALE_DBCON, NULL},
176 {XSCALE_TBREG, NULL},
177 {XSCALE_CHKPT0, NULL},
178 {XSCALE_CHKPT1, NULL},
179 {XSCALE_DCSR, NULL}, /* DCSR accessed via JTAG or SW */
180 {-1, NULL}, /* TX accessed via JTAG */
181 {-1, NULL}, /* RX accessed via JTAG */
182 {-1, NULL}, /* TXRXCTRL implicit access via JTAG */
183 };
184
185 int xscale_reg_arch_type = -1;
186
187 int xscale_get_reg(reg_t *reg);
188 int xscale_set_reg(reg_t *reg, u8 *buf);
189
190 int xscale_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, xscale_common_t **xscale_p)
191 {
192 armv4_5_common_t *armv4_5 = target->arch_info;
193 xscale_common_t *xscale = armv4_5->arch_info;
194
195 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
196 {
197 ERROR("target isn't an XScale target");
198 return -1;
199 }
200
201 if (xscale->common_magic != XSCALE_COMMON_MAGIC)
202 {
203 ERROR("target isn't an XScale target");
204 return -1;
205 }
206
207 *armv4_5_p = armv4_5;
208 *xscale_p = xscale;
209
210 return ERROR_OK;
211 }
212
213 int xscale_jtag_set_instr(int chain_pos, u32 new_instr)
214 {
215 jtag_device_t *device = jtag_get_device(chain_pos);
216
217 if (buf_get_u32(device->cur_instr, 0, device->ir_length) != new_instr)
218 {
219 scan_field_t field;
220
221 field.device = chain_pos;
222 field.num_bits = device->ir_length;
223 field.out_value = calloc(CEIL(field.num_bits, 8), 1);
224 buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
225 field.out_mask = NULL;
226 field.in_value = NULL;
227 jtag_set_check_value(&field, device->expected, device->expected_mask, NULL);
228
229 jtag_add_ir_scan(1, &field, -1);
230
231 free(field.out_value);
232 }
233
234 return ERROR_OK;
235 }
236
237 int xscale_read_dcsr(target_t *target)
238 {
239 armv4_5_common_t *armv4_5 = target->arch_info;
240 xscale_common_t *xscale = armv4_5->arch_info;
241
242 int retval;
243
244 scan_field_t fields[3];
245 u8 field0 = 0x0;
246 u8 field0_check_value = 0x2;
247 u8 field0_check_mask = 0x7;
248 u8 field2 = 0x0;
249 u8 field2_check_value = 0x0;
250 u8 field2_check_mask = 0x1;
251
252 jtag_add_end_state(TAP_PD);
253 xscale_jtag_set_instr(xscale->jtag_info.chain_pos, xscale->jtag_info.dcsr);
254
255 buf_set_u32(&field0, 1, 1, xscale->hold_rst);
256 buf_set_u32(&field0, 2, 1, xscale->external_debug_break);
257
258 fields[0].device = xscale->jtag_info.chain_pos;
259 fields[0].num_bits = 3;
260 fields[0].out_value = &field0;
261 fields[0].out_mask = NULL;
262 fields[0].in_value = NULL;
263 jtag_set_check_value(fields+0, &field0_check_value, &field0_check_mask, NULL);
264
265 fields[1].device = xscale->jtag_info.chain_pos;
266 fields[1].num_bits = 32;
267 fields[1].out_value = NULL;
268 fields[1].out_mask = NULL;
269 fields[1].in_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value;
270 fields[1].in_handler = NULL;
271 fields[1].in_handler_priv = NULL;
272 fields[1].in_check_value = NULL;
273 fields[1].in_check_mask = NULL;
274
275 fields[2].device = xscale->jtag_info.chain_pos;
276 fields[2].num_bits = 1;
277 fields[2].out_value = &field2;
278 fields[2].out_mask = NULL;
279 fields[2].in_value = NULL;
280 jtag_set_check_value(fields+2, &field2_check_value, &field2_check_mask, NULL);
281
282 jtag_add_dr_scan(3, fields, -1);
283
284 if ((retval = jtag_execute_queue()) != ERROR_OK)
285 {
286 ERROR("JTAG error while reading DCSR");
287 return retval;
288 }
289
290 xscale->reg_cache->reg_list[XSCALE_DCSR].dirty = 0;
291 xscale->reg_cache->reg_list[XSCALE_DCSR].valid = 1;
292
293 /* write the register with the value we just read
294 * on this second pass, only the first bit of field0 is guaranteed to be 0)
295 */
296 field0_check_mask = 0x1;
297 fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value;
298 fields[1].in_value = NULL;
299
300 jtag_add_end_state(TAP_RTI);
301
302 jtag_add_dr_scan(3, fields, -1);
303
304 /* DANGER!!! this must be here. It will make sure that the arguments
305 * to jtag_set_check_value() does not go out of scope! */
306 return jtag_execute_queue();
307 }
308
309 int xscale_receive(target_t *target, u32 *buffer, int num_words)
310 {
311 if (num_words==0)
312 return ERROR_INVALID_ARGUMENTS;
313
314 int retval=ERROR_OK;
315 armv4_5_common_t *armv4_5 = target->arch_info;
316 xscale_common_t *xscale = armv4_5->arch_info;
317
318 enum tap_state path[3];
319 scan_field_t fields[3];
320
321 u8 *field0 = malloc(num_words * 1);
322 u8 field0_check_value = 0x2;
323 u8 field0_check_mask = 0x6;
324 u32 *field1 = malloc(num_words * 4);
325 u8 field2_check_value = 0x0;
326 u8 field2_check_mask = 0x1;
327 int words_done = 0;
328 int words_scheduled = 0;
329
330 int i;
331
332 path[0] = TAP_SDS;
333 path[1] = TAP_CD;
334 path[2] = TAP_SD;
335
336 fields[0].device = xscale->jtag_info.chain_pos;
337 fields[0].num_bits = 3;
338 fields[0].out_value = NULL;
339 fields[0].out_mask = NULL;
340 fields[0].in_value = NULL;
341 jtag_set_check_value(fields+0, &field0_check_value, &field0_check_mask, NULL);
342
343 fields[1].device = xscale->jtag_info.chain_pos;
344 fields[1].num_bits = 32;
345 fields[1].out_value = NULL;
346 fields[1].out_mask = NULL;
347 fields[1].in_value = NULL;
348 fields[1].in_handler = NULL;
349 fields[1].in_handler_priv = NULL;
350 fields[1].in_check_value = NULL;
351 fields[1].in_check_mask = NULL;
352
353
354
355 fields[2].device = xscale->jtag_info.chain_pos;
356 fields[2].num_bits = 1;
357 fields[2].out_value = NULL;
358 fields[2].out_mask = NULL;
359 fields[2].in_value = NULL;
360 jtag_set_check_value(fields+2, &field2_check_value, &field2_check_mask, NULL);
361
362 jtag_add_end_state(TAP_RTI);
363 xscale_jtag_set_instr(xscale->jtag_info.chain_pos, xscale->jtag_info.dbgtx);
364 jtag_add_runtest(1, -1); /* ensures that we're in the TAP_RTI state as the above could be a no-op */
365
366 /* repeat until all words have been collected */
367 int attempts=0;
368 while (words_done < num_words)
369 {
370 /* schedule reads */
371 words_scheduled = 0;
372 for (i = words_done; i < num_words; i++)
373 {
374 fields[0].in_value = &field0[i];
375 fields[1].in_handler = buf_to_u32_handler;
376 fields[1].in_handler_priv = (u8*)&field1[i];
377
378 jtag_add_pathmove(3, path);
379 jtag_add_dr_scan(3, fields, TAP_RTI);
380 words_scheduled++;
381 }
382
383 if ((retval = jtag_execute_queue()) != ERROR_OK)
384 {
385 ERROR("JTAG error while receiving data from debug handler");
386 break;
387 }
388
389 /* examine results */
390 for (i = words_done; i < num_words; i++)
391 {
392 if (!(field0[0] & 1))
393 {
394 /* move backwards if necessary */
395 int j;
396 for (j = i; j < num_words - 1; j++)
397 {
398 field0[j] = field0[j+1];
399 field1[j] = field1[j+1];
400 }
401 words_scheduled--;
402 }
403 }
404 if (words_scheduled==0)
405 {
406 if (attempts++==1000)
407 {
408 ERROR("Failed to receiving data from debug handler after 1000 attempts");
409 retval=ERROR_TARGET_TIMEOUT;
410 break;
411 }
412 }
413
414 words_done += words_scheduled;
415 }
416
417 for (i = 0; i < num_words; i++)
418 *(buffer++) = buf_get_u32((u8*)&field1[i], 0, 32);
419
420 free(field1);
421
422 return retval;
423 }
424
425 int xscale_read_tx(target_t *target, int consume)
426 {
427 armv4_5_common_t *armv4_5 = target->arch_info;
428 xscale_common_t *xscale = armv4_5->arch_info;
429 enum tap_state path[3];
430 enum tap_state noconsume_path[9];
431
432 int retval;
433 struct timeval timeout, now;
434
435 scan_field_t fields[3];
436 u8 field0_in = 0x0;
437 u8 field0_check_value = 0x2;
438 u8 field0_check_mask = 0x6;
439 u8 field2_check_value = 0x0;
440 u8 field2_check_mask = 0x1;
441
442 jtag_add_end_state(TAP_RTI);
443
444 xscale_jtag_set_instr(xscale->jtag_info.chain_pos, xscale->jtag_info.dbgtx);
445
446 path[0] = TAP_SDS;
447 path[1] = TAP_CD;
448 path[2] = TAP_SD;
449
450 noconsume_path[0] = TAP_SDS;
451 noconsume_path[1] = TAP_CD;
452 noconsume_path[2] = TAP_E1D;
453 noconsume_path[3] = TAP_PD;
454 noconsume_path[4] = TAP_E2D;
455 noconsume_path[5] = TAP_UD;
456 noconsume_path[6] = TAP_SDS;
457 noconsume_path[7] = TAP_CD;
458 noconsume_path[8] = TAP_SD;
459
460 fields[0].device = xscale->jtag_info.chain_pos;
461 fields[0].num_bits = 3;
462 fields[0].out_value = NULL;
463 fields[0].out_mask = NULL;
464 fields[0].in_value = &field0_in;
465 jtag_set_check_value(fields+0, &field0_check_value, &field0_check_mask, NULL);
466
467 fields[1].device = xscale->jtag_info.chain_pos;
468 fields[1].num_bits = 32;
469 fields[1].out_value = NULL;
470 fields[1].out_mask = NULL;
471 fields[1].in_value = xscale->reg_cache->reg_list[XSCALE_TX].value;
472 fields[1].in_handler = NULL;
473 fields[1].in_handler_priv = NULL;
474 fields[1].in_check_value = NULL;
475 fields[1].in_check_mask = NULL;
476
477
478
479 fields[2].device = xscale->jtag_info.chain_pos;
480 fields[2].num_bits = 1;
481 fields[2].out_value = NULL;
482 fields[2].out_mask = NULL;
483 fields[2].in_value = NULL;
484 jtag_set_check_value(fields+2, &field2_check_value, &field2_check_mask, NULL);
485
486 gettimeofday(&timeout, NULL);
487 timeval_add_time(&timeout, 5, 0);
488
489 for (;;)
490 {
491 /* if we want to consume the register content (i.e. clear TX_READY),
492 * we have to go straight from Capture-DR to Shift-DR
493 * otherwise, we go from Capture-DR to Exit1-DR to Pause-DR
494 */
495 if (consume)
496 jtag_add_pathmove(3, path);
497 else
498 jtag_add_pathmove(sizeof(noconsume_path)/sizeof(*noconsume_path), noconsume_path);
499
500 jtag_add_dr_scan(3, fields, TAP_RTI);
501
502 if ((retval = jtag_execute_queue()) != ERROR_OK)
503 {
504 ERROR("JTAG error while reading TX");
505 return ERROR_TARGET_TIMEOUT;
506 }
507
508 gettimeofday(&now, NULL);
509 if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec)&& (now.tv_usec > timeout.tv_usec)))
510 {
511 ERROR("time out reading TX register");
512 return ERROR_TARGET_TIMEOUT;
513 }
514 if (!((!(field0_in & 1)) && consume))
515 {
516 break;
517 }
518 usleep(500*1000); /* avoid flooding the logs */
519 }
520
521 if (!(field0_in & 1))
522 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
523
524 return ERROR_OK;
525 }
526
527 int xscale_write_rx(target_t *target)
528 {
529 armv4_5_common_t *armv4_5 = target->arch_info;
530 xscale_common_t *xscale = armv4_5->arch_info;
531
532 int retval;
533 struct timeval timeout, now;
534
535 scan_field_t fields[3];
536 u8 field0_out = 0x0;
537 u8 field0_in = 0x0;
538 u8 field0_check_value = 0x2;
539 u8 field0_check_mask = 0x6;
540 u8 field2 = 0x0;
541 u8 field2_check_value = 0x0;
542 u8 field2_check_mask = 0x1;
543
544 jtag_add_end_state(TAP_RTI);
545
546 xscale_jtag_set_instr(xscale->jtag_info.chain_pos, xscale->jtag_info.dbgrx);
547
548 fields[0].device = xscale->jtag_info.chain_pos;
549 fields[0].num_bits = 3;
550 fields[0].out_value = &field0_out;
551 fields[0].out_mask = NULL;
552 fields[0].in_value = &field0_in;
553 jtag_set_check_value(fields+0, &field0_check_value, &field0_check_mask, NULL);
554
555 fields[1].device = xscale->jtag_info.chain_pos;
556 fields[1].num_bits = 32;
557 fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_RX].value;
558 fields[1].out_mask = NULL;
559 fields[1].in_value = NULL;
560 fields[1].in_handler = NULL;
561 fields[1].in_handler_priv = NULL;
562 fields[1].in_check_value = NULL;
563 fields[1].in_check_mask = NULL;
564
565
566
567 fields[2].device = xscale->jtag_info.chain_pos;
568 fields[2].num_bits = 1;
569 fields[2].out_value = &field2;
570 fields[2].out_mask = NULL;
571 fields[2].in_value = NULL;
572 jtag_set_check_value(fields+2, &field2_check_value, &field2_check_mask, NULL);
573
574 gettimeofday(&timeout, NULL);
575 timeval_add_time(&timeout, 5, 0);
576
577 /* poll until rx_read is low */
578 DEBUG("polling RX");
579 for (;;)
580 {
581 jtag_add_dr_scan(3, fields, TAP_RTI);
582
583 if ((retval = jtag_execute_queue()) != ERROR_OK)
584 {
585 ERROR("JTAG error while writing RX");
586 return retval;
587 }
588
589 gettimeofday(&now, NULL);
590 if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec)&& (now.tv_usec > timeout.tv_usec)))
591 {
592 ERROR("time out writing RX register");
593 return ERROR_TARGET_TIMEOUT;
594 }
595 if (!(field0_in & 1))
596 break;
597 usleep(500*1000); /* wait 500ms to avoid flooding the logs */
598 }
599
600 /* set rx_valid */
601 field2 = 0x1;
602 jtag_add_dr_scan(3, fields, TAP_RTI);
603
604 if ((retval = jtag_execute_queue()) != ERROR_OK)
605 {
606 ERROR("JTAG error while writing RX");
607 return retval;
608 }
609
610 return ERROR_OK;
611 }
612
613 /* send count elements of size byte to the debug handler */
614 int xscale_send(target_t *target, u8 *buffer, int count, int size)
615 {
616 armv4_5_common_t *armv4_5 = target->arch_info;
617 xscale_common_t *xscale = armv4_5->arch_info;
618
619 int retval;
620
621 int done_count = 0;
622 u8 output[4] = {0, 0, 0, 0};
623
624 scan_field_t fields[3];
625 u8 field0_out = 0x0;
626 u8 field0_check_value = 0x2;
627 u8 field0_check_mask = 0x6;
628 u8 field2 = 0x1;
629 u8 field2_check_value = 0x0;
630 u8 field2_check_mask = 0x1;
631
632 jtag_add_end_state(TAP_RTI);
633
634 xscale_jtag_set_instr(xscale->jtag_info.chain_pos, xscale->jtag_info.dbgrx);
635
636 fields[0].device = xscale->jtag_info.chain_pos;
637 fields[0].num_bits = 3;
638 fields[0].out_value = &field0_out;
639 fields[0].out_mask = NULL;
640 fields[0].in_handler = NULL;
641 fields[0].in_value = NULL;
642 if (!xscale->fast_memory_access)
643 {
644 jtag_set_check_value(fields+0, &field0_check_value, &field0_check_mask, NULL);
645 }
646
647 fields[1].device = xscale->jtag_info.chain_pos;
648 fields[1].num_bits = 32;
649 fields[1].out_value = output;
650 fields[1].out_mask = NULL;
651 fields[1].in_value = NULL;
652 fields[1].in_handler = NULL;
653 fields[1].in_handler_priv = NULL;
654 fields[1].in_check_value = NULL;
655 fields[1].in_check_mask = NULL;
656
657
658
659 fields[2].device = xscale->jtag_info.chain_pos;
660 fields[2].num_bits = 1;
661 fields[2].out_value = &field2;
662 fields[2].out_mask = NULL;
663 fields[2].in_value = NULL;
664 fields[2].in_handler = NULL;
665 if (!xscale->fast_memory_access)
666 {
667 jtag_set_check_value(fields+2, &field2_check_value, &field2_check_mask, NULL);
668 }
669
670 if (size==4)
671 {
672 int endianness = target->endianness;
673 while (done_count++ < count)
674 {
675 if (endianness == TARGET_LITTLE_ENDIAN)
676 {
677 output[0]=buffer[0];
678 output[1]=buffer[1];
679 output[2]=buffer[2];
680 output[3]=buffer[3];
681 } else
682 {
683 output[0]=buffer[3];
684 output[1]=buffer[2];
685 output[2]=buffer[1];
686 output[3]=buffer[0];
687 }
688 jtag_add_dr_scan(3, fields, TAP_RTI);
689 buffer += size;
690 }
691
692 } else
693 {
694 while (done_count++ < count)
695 {
696 /* extract sized element from target-endian buffer, and put it
697 * into little-endian output buffer
698 */
699 switch (size)
700 {
701 case 2:
702 buf_set_u32(output, 0, 32, target_buffer_get_u16(target, buffer));
703 break;
704 case 1:
705 output[0] = *buffer;
706 break;
707 default:
708 ERROR("BUG: size neither 4, 2 nor 1");
709 exit(-1);
710 }
711
712 jtag_add_dr_scan(3, fields, TAP_RTI);
713 buffer += size;
714 }
715
716 }
717
718 if ((retval = jtag_execute_queue()) != ERROR_OK)
719 {
720 ERROR("JTAG error while sending data to debug handler");
721 return retval;
722 }
723
724 return ERROR_OK;
725 }
726
727 int xscale_send_u32(target_t *target, u32 value)
728 {
729 armv4_5_common_t *armv4_5 = target->arch_info;
730 xscale_common_t *xscale = armv4_5->arch_info;
731
732 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_RX].value, 0, 32, value);
733 return xscale_write_rx(target);
734 }
735
736 int xscale_write_dcsr(target_t *target, int hold_rst, int ext_dbg_brk)
737 {
738 armv4_5_common_t *armv4_5 = target->arch_info;
739 xscale_common_t *xscale = armv4_5->arch_info;
740
741 int retval;
742
743 scan_field_t fields[3];
744 u8 field0 = 0x0;
745 u8 field0_check_value = 0x2;
746 u8 field0_check_mask = 0x7;
747 u8 field2 = 0x0;
748 u8 field2_check_value = 0x0;
749 u8 field2_check_mask = 0x1;
750
751 if (hold_rst != -1)
752 xscale->hold_rst = hold_rst;
753
754 if (ext_dbg_brk != -1)
755 xscale->external_debug_break = ext_dbg_brk;
756
757 jtag_add_end_state(TAP_RTI);
758 xscale_jtag_set_instr(xscale->jtag_info.chain_pos, xscale->jtag_info.dcsr);
759
760 buf_set_u32(&field0, 1, 1, xscale->hold_rst);
761 buf_set_u32(&field0, 2, 1, xscale->external_debug_break);
762
763 fields[0].device = xscale->jtag_info.chain_pos;
764 fields[0].num_bits = 3;
765 fields[0].out_value = &field0;
766 fields[0].out_mask = NULL;
767 fields[0].in_value = NULL;
768 jtag_set_check_value(fields+0, &field0_check_value, &field0_check_mask, NULL);
769
770 fields[1].device = xscale->jtag_info.chain_pos;
771 fields[1].num_bits = 32;
772 fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value;
773 fields[1].out_mask = NULL;
774 fields[1].in_value = NULL;
775 fields[1].in_handler = NULL;
776 fields[1].in_handler_priv = NULL;
777 fields[1].in_check_value = NULL;
778 fields[1].in_check_mask = NULL;
779
780
781
782 fields[2].device = xscale->jtag_info.chain_pos;
783 fields[2].num_bits = 1;
784 fields[2].out_value = &field2;
785 fields[2].out_mask = NULL;
786 fields[2].in_value = NULL;
787 jtag_set_check_value(fields+2, &field2_check_value, &field2_check_mask, NULL);
788
789 jtag_add_dr_scan(3, fields, -1);
790
791 if ((retval = jtag_execute_queue()) != ERROR_OK)
792 {
793 ERROR("JTAG error while writing DCSR");
794 return retval;
795 }
796
797 xscale->reg_cache->reg_list[XSCALE_DCSR].dirty = 0;
798 xscale->reg_cache->reg_list[XSCALE_DCSR].valid = 1;
799
800 return ERROR_OK;
801 }
802
803 /* parity of the number of bits 0 if even; 1 if odd. for 32 bit words */
804 unsigned int parity (unsigned int v)
805 {
806 unsigned int ov = v;
807 v ^= v >> 16;
808 v ^= v >> 8;
809 v ^= v >> 4;
810 v &= 0xf;
811 DEBUG("parity of 0x%x is %i", ov, (0x6996 >> v) & 1);
812 return (0x6996 >> v) & 1;
813 }
814
815 int xscale_load_ic(target_t *target, int mini, u32 va, u32 buffer[8])
816 {
817 armv4_5_common_t *armv4_5 = target->arch_info;
818 xscale_common_t *xscale = armv4_5->arch_info;
819 u8 packet[4];
820 u8 cmd;
821 int word;
822
823 scan_field_t fields[2];
824
825 DEBUG("loading miniIC at 0x%8.8x", va);
826
827 jtag_add_end_state(TAP_RTI);
828 xscale_jtag_set_instr(xscale->jtag_info.chain_pos, xscale->jtag_info.ldic); /* LDIC */
829
830 /* CMD is b010 for Main IC and b011 for Mini IC */
831 if (mini)
832 buf_set_u32(&cmd, 0, 3, 0x3);
833 else
834 buf_set_u32(&cmd, 0, 3, 0x2);
835
836 buf_set_u32(&cmd, 3, 3, 0x0);
837
838 /* virtual address of desired cache line */
839 buf_set_u32(packet, 0, 27, va >> 5);
840
841 fields[0].device = xscale->jtag_info.chain_pos;
842 fields[0].num_bits = 6;
843 fields[0].out_value = &cmd;
844 fields[0].out_mask = NULL;
845 fields[0].in_value = NULL;
846 fields[0].in_check_value = NULL;
847 fields[0].in_check_mask = NULL;
848 fields[0].in_handler = NULL;
849 fields[0].in_handler_priv = NULL;
850
851 fields[1].device = xscale->jtag_info.chain_pos;
852 fields[1].num_bits = 27;
853 fields[1].out_value = packet;
854 fields[1].out_mask = NULL;
855 fields[1].in_value = NULL;
856 fields[1].in_check_value = NULL;
857 fields[1].in_check_mask = NULL;
858 fields[1].in_handler = NULL;
859 fields[1].in_handler_priv = NULL;
860
861 jtag_add_dr_scan(2, fields, -1);
862
863 fields[0].num_bits = 32;
864 fields[0].out_value = packet;
865
866 fields[1].num_bits = 1;
867 fields[1].out_value = &cmd;
868
869 for (word = 0; word < 8; word++)
870 {
871 buf_set_u32(packet, 0, 32, buffer[word]);
872 cmd = parity(*((u32*)packet));
873 jtag_add_dr_scan(2, fields, -1);
874 }
875
876 jtag_execute_queue();
877
878 return ERROR_OK;
879 }
880
881 int xscale_invalidate_ic_line(target_t *target, u32 va)
882 {
883 armv4_5_common_t *armv4_5 = target->arch_info;
884 xscale_common_t *xscale = armv4_5->arch_info;
885 u8 packet[4];
886 u8 cmd;
887
888 scan_field_t fields[2];
889
890 jtag_add_end_state(TAP_RTI);
891 xscale_jtag_set_instr(xscale->jtag_info.chain_pos, xscale->jtag_info.ldic); /* LDIC */
892
893 /* CMD for invalidate IC line b000, bits [6:4] b000 */
894 buf_set_u32(&cmd, 0, 6, 0x0);
895
896 /* virtual address of desired cache line */
897 buf_set_u32(packet, 0, 27, va >> 5);
898
899 fields[0].device = xscale->jtag_info.chain_pos;
900 fields[0].num_bits = 6;
901 fields[0].out_value = &cmd;
902 fields[0].out_mask = NULL;
903 fields[0].in_value = NULL;
904 fields[0].in_check_value = NULL;
905 fields[0].in_check_mask = NULL;
906 fields[0].in_handler = NULL;
907 fields[0].in_handler_priv = NULL;
908
909 fields[1].device = xscale->jtag_info.chain_pos;
910 fields[1].num_bits = 27;
911 fields[1].out_value = packet;
912 fields[1].out_mask = NULL;
913 fields[1].in_value = NULL;
914 fields[1].in_check_value = NULL;
915 fields[1].in_check_mask = NULL;
916 fields[1].in_handler = NULL;
917 fields[1].in_handler_priv = NULL;
918
919 jtag_add_dr_scan(2, fields, -1);
920
921 return ERROR_OK;
922 }
923
924 int xscale_update_vectors(target_t *target)
925 {
926 armv4_5_common_t *armv4_5 = target->arch_info;
927 xscale_common_t *xscale = armv4_5->arch_info;
928 int i;
929 int retval;
930
931 u32 low_reset_branch, high_reset_branch;
932
933 for (i = 1; i < 8; i++)
934 {
935 /* if there's a static vector specified for this exception, override */
936 if (xscale->static_high_vectors_set & (1 << i))
937 {
938 xscale->high_vectors[i] = xscale->static_high_vectors[i];
939 }
940 else
941 {
942 retval=target_read_u32(target, 0xffff0000 + 4*i, &xscale->high_vectors[i]);
943 if (retval == ERROR_TARGET_TIMEOUT)
944 return retval;
945 if (retval!=ERROR_OK)
946 {
947 /* Some of these reads will fail as part of normal execution */
948 xscale->high_vectors[i] = ARMV4_5_B(0xfffffe, 0);
949 }
950 }
951 }
952
953 for (i = 1; i < 8; i++)
954 {
955 if (xscale->static_low_vectors_set & (1 << i))
956 {
957 xscale->low_vectors[i] = xscale->static_low_vectors[i];
958 }
959 else
960 {
961 retval=target_read_u32(target, 0x0 + 4*i, &xscale->low_vectors[i]);
962 if (retval == ERROR_TARGET_TIMEOUT)
963 return retval;
964 if (retval!=ERROR_OK)
965 {
966 /* Some of these reads will fail as part of normal execution */
967 xscale->low_vectors[i] = ARMV4_5_B(0xfffffe, 0);
968 }
969 }
970 }
971
972 /* calculate branches to debug handler */
973 low_reset_branch = (xscale->handler_address + 0x20 - 0x0 - 0x8) >> 2;
974 high_reset_branch = (xscale->handler_address + 0x20 - 0xffff0000 - 0x8) >> 2;
975
976 xscale->low_vectors[0] = ARMV4_5_B((low_reset_branch & 0xffffff), 0);
977 xscale->high_vectors[0] = ARMV4_5_B((high_reset_branch & 0xffffff), 0);
978
979 /* invalidate and load exception vectors in mini i-cache */
980 xscale_invalidate_ic_line(target, 0x0);
981 xscale_invalidate_ic_line(target, 0xffff0000);
982
983 xscale_load_ic(target, 1, 0x0, xscale->low_vectors);
984 xscale_load_ic(target, 1, 0xffff0000, xscale->high_vectors);
985
986 return ERROR_OK;
987 }
988
989 int xscale_arch_state(struct target_s *target)
990 {
991 armv4_5_common_t *armv4_5 = target->arch_info;
992 xscale_common_t *xscale = armv4_5->arch_info;
993
994 char *state[] =
995 {
996 "disabled", "enabled"
997 };
998
999 char *arch_dbg_reason[] =
1000 {
1001 "", "\n(processor reset)", "\n(trace buffer full)"
1002 };
1003
1004 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
1005 {
1006 ERROR("BUG: called for a non-ARMv4/5 target");
1007 exit(-1);
1008 }
1009
1010 USER("target halted in %s state due to %s, current mode: %s\n"
1011 "cpsr: 0x%8.8x pc: 0x%8.8x\n"
1012 "MMU: %s, D-Cache: %s, I-Cache: %s"
1013 "%s",
1014 armv4_5_state_strings[armv4_5->core_state],
1015 target_debug_reason_strings[target->debug_reason],
1016 armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
1017 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
1018 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
1019 state[xscale->armv4_5_mmu.mmu_enabled],
1020 state[xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
1021 state[xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled],
1022 arch_dbg_reason[xscale->arch_debug_reason]);
1023
1024 return ERROR_OK;
1025 }
1026
1027 int xscale_poll(target_t *target)
1028 {
1029 int retval=ERROR_OK;
1030 armv4_5_common_t *armv4_5 = target->arch_info;
1031 xscale_common_t *xscale = armv4_5->arch_info;
1032
1033 if ((target->state == TARGET_RUNNING) || (target->state == TARGET_DEBUG_RUNNING))
1034 {
1035 enum target_state previous_state = target->state;
1036 if ((retval = xscale_read_tx(target, 0)) == ERROR_OK)
1037 {
1038
1039 /* there's data to read from the tx register, we entered debug state */
1040 xscale->handler_running = 1;
1041
1042 target->state = TARGET_HALTED;
1043
1044 /* process debug entry, fetching current mode regs */
1045 retval = xscale_debug_entry(target);
1046 }
1047 else if (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
1048 {
1049 USER("error while polling TX register, reset CPU");
1050 /* here we "lie" so GDB won't get stuck and a reset can be perfomed */
1051 target->state = TARGET_HALTED;
1052 }
1053
1054 /* debug_entry could have overwritten target state (i.e. immediate resume)
1055 * don't signal event handlers in that case
1056 */
1057 if (target->state != TARGET_HALTED)
1058 return ERROR_OK;
1059
1060 /* if target was running, signal that we halted
1061 * otherwise we reentered from debug execution */
1062 if (previous_state == TARGET_RUNNING)
1063 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1064 else
1065 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
1066 }
1067
1068 return retval;
1069 }
1070
1071 int xscale_debug_entry(target_t *target)
1072 {
1073 armv4_5_common_t *armv4_5 = target->arch_info;
1074 xscale_common_t *xscale = armv4_5->arch_info;
1075 u32 pc;
1076 u32 buffer[10];
1077 int i;
1078 int retval;
1079
1080 u32 moe;
1081
1082 /* clear external dbg break (will be written on next DCSR read) */
1083 xscale->external_debug_break = 0;
1084 if ((retval=xscale_read_dcsr(target))!=ERROR_OK)
1085 return retval;
1086
1087 /* get r0, pc, r1 to r7 and cpsr */
1088 if ((retval=xscale_receive(target, buffer, 10))!=ERROR_OK)
1089 return retval;
1090
1091 /* move r0 from buffer to register cache */
1092 buf_set_u32(armv4_5->core_cache->reg_list[0].value, 0, 32, buffer[0]);
1093 armv4_5->core_cache->reg_list[15].dirty = 1;
1094 armv4_5->core_cache->reg_list[15].valid = 1;
1095 DEBUG("r0: 0x%8.8x", buffer[0]);
1096
1097 /* move pc from buffer to register cache */
1098 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, buffer[1]);
1099 armv4_5->core_cache->reg_list[15].dirty = 1;
1100 armv4_5->core_cache->reg_list[15].valid = 1;
1101 DEBUG("pc: 0x%8.8x", buffer[1]);
1102
1103 /* move data from buffer to register cache */
1104 for (i = 1; i <= 7; i++)
1105 {
1106 buf_set_u32(armv4_5->core_cache->reg_list[i].value, 0, 32, buffer[1 + i]);
1107 armv4_5->core_cache->reg_list[i].dirty = 1;
1108 armv4_5->core_cache->reg_list[i].valid = 1;
1109 DEBUG("r%i: 0x%8.8x", i, buffer[i + 1]);
1110 }
1111
1112 buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32, buffer[9]);
1113 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
1114 armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
1115 DEBUG("cpsr: 0x%8.8x", buffer[9]);
1116
1117 armv4_5->core_mode = buffer[9] & 0x1f;
1118 if (armv4_5_mode_to_number(armv4_5->core_mode) == -1)
1119 {
1120 target->state = TARGET_UNKNOWN;
1121 ERROR("cpsr contains invalid mode value - communication failure");
1122 return ERROR_TARGET_FAILURE;
1123 }
1124 DEBUG("target entered debug state in %s mode", armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)]);
1125
1126 if (buffer[9] & 0x20)
1127 armv4_5->core_state = ARMV4_5_STATE_THUMB;
1128 else
1129 armv4_5->core_state = ARMV4_5_STATE_ARM;
1130
1131 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1132 if ((armv4_5->core_mode != ARMV4_5_MODE_USR) && (armv4_5->core_mode != ARMV4_5_MODE_SYS))
1133 {
1134 xscale_receive(target, buffer, 8);
1135 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32, buffer[7]);
1136 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).dirty = 0;
1137 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).valid = 1;
1138 }
1139 else
1140 {
1141 /* r8 to r14, but no spsr */
1142 xscale_receive(target, buffer, 7);
1143 }
1144
1145 /* move data from buffer to register cache */
1146 for (i = 8; i <= 14; i++)
1147 {
1148 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).value, 0, 32, buffer[i - 8]);
1149 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = 0;
1150 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid = 1;
1151 }
1152
1153 /* examine debug reason */
1154 xscale_read_dcsr(target);
1155 moe = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 2, 3);
1156
1157 /* stored PC (for calculating fixup) */
1158 pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
1159
1160 switch (moe)
1161 {
1162 case 0x0: /* Processor reset */
1163 target->debug_reason = DBG_REASON_DBGRQ;
1164 xscale->arch_debug_reason = XSCALE_DBG_REASON_RESET;
1165 pc -= 4;
1166 break;
1167 case 0x1: /* Instruction breakpoint hit */
1168 target->debug_reason = DBG_REASON_BREAKPOINT;
1169 xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;
1170 pc -= 4;
1171 break;
1172 case 0x2: /* Data breakpoint hit */
1173 target->debug_reason = DBG_REASON_WATCHPOINT;
1174 xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;
1175 pc -= 4;
1176 break;
1177 case 0x3: /* BKPT instruction executed */
1178 target->debug_reason = DBG_REASON_BREAKPOINT;
1179 xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;
1180 pc -= 4;
1181 break;
1182 case 0x4: /* Ext. debug event */
1183 target->debug_reason = DBG_REASON_DBGRQ;
1184 xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;
1185 pc -= 4;
1186 break;
1187 case 0x5: /* Vector trap occured */
1188 target->debug_reason = DBG_REASON_BREAKPOINT;
1189 xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;
1190 pc -= 4;
1191 break;
1192 case 0x6: /* Trace buffer full break */
1193 target->debug_reason = DBG_REASON_DBGRQ;
1194 xscale->arch_debug_reason = XSCALE_DBG_REASON_TB_FULL;
1195 pc -= 4;
1196 break;
1197 case 0x7: /* Reserved */
1198 default:
1199 ERROR("Method of Entry is 'Reserved'");
1200 exit(-1);
1201 break;
1202 }
1203
1204 /* apply PC fixup */
1205 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, pc);
1206
1207 /* on the first debug entry, identify cache type */
1208 if (xscale->armv4_5_mmu.armv4_5_cache.ctype == -1)
1209 {
1210 u32 cache_type_reg;
1211
1212 /* read cp15 cache type register */
1213 xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CACHETYPE]);
1214 cache_type_reg = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CACHETYPE].value, 0, 32);
1215
1216 armv4_5_identify_cache(cache_type_reg, &xscale->armv4_5_mmu.armv4_5_cache);
1217 }
1218
1219 /* examine MMU and Cache settings */
1220 /* read cp15 control register */
1221 xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);
1222 xscale->cp15_control_reg = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32);
1223 xscale->armv4_5_mmu.mmu_enabled = (xscale->cp15_control_reg & 0x1U) ? 1 : 0;
1224 xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = (xscale->cp15_control_reg & 0x4U) ? 1 : 0;
1225 xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = (xscale->cp15_control_reg & 0x1000U) ? 1 : 0;
1226
1227 /* tracing enabled, read collected trace data */
1228 if (xscale->trace.buffer_enabled)
1229 {
1230 xscale_read_trace(target);
1231 xscale->trace.buffer_fill--;
1232
1233 /* resume if we're still collecting trace data */
1234 if ((xscale->arch_debug_reason == XSCALE_DBG_REASON_TB_FULL)
1235 && (xscale->trace.buffer_fill > 0))
1236 {
1237 xscale_resume(target, 1, 0x0, 1, 0);
1238 }
1239 else
1240 {
1241 xscale->trace.buffer_enabled = 0;
1242 }
1243 }
1244
1245 return ERROR_OK;
1246 }
1247
1248 int xscale_halt(target_t *target)
1249 {
1250 armv4_5_common_t *armv4_5 = target->arch_info;
1251 xscale_common_t *xscale = armv4_5->arch_info;
1252
1253 DEBUG("target->state: %s", target_state_strings[target->state]);
1254
1255 if (target->state == TARGET_HALTED)
1256 {
1257 WARNING("target was already halted");
1258 return ERROR_OK;
1259 }
1260 else if (target->state == TARGET_UNKNOWN)
1261 {
1262 /* this must not happen for a xscale target */
1263 ERROR("target was in unknown state when halt was requested");
1264 return ERROR_TARGET_INVALID;
1265 }
1266 else if (target->state == TARGET_RESET)
1267 {
1268 DEBUG("target->state == TARGET_RESET");
1269 }
1270 else
1271 {
1272 /* assert external dbg break */
1273 xscale->external_debug_break = 1;
1274 xscale_read_dcsr(target);
1275
1276 target->debug_reason = DBG_REASON_DBGRQ;
1277 }
1278
1279 return ERROR_OK;
1280 }
1281
1282 int xscale_enable_single_step(struct target_s *target, u32 next_pc)
1283 {
1284 armv4_5_common_t *armv4_5 = target->arch_info;
1285 xscale_common_t *xscale= armv4_5->arch_info;
1286 reg_t *ibcr0 = &xscale->reg_cache->reg_list[XSCALE_IBCR0];
1287
1288 if (xscale->ibcr0_used)
1289 {
1290 breakpoint_t *ibcr0_bp = breakpoint_find(target, buf_get_u32(ibcr0->value, 0, 32) & 0xfffffffe);
1291
1292 if (ibcr0_bp)
1293 {
1294 xscale_unset_breakpoint(target, ibcr0_bp);
1295 }
1296 else
1297 {
1298 ERROR("BUG: xscale->ibcr0_used is set, but no breakpoint with that address found");
1299 exit(-1);
1300 }
1301 }
1302
1303 xscale_set_reg_u32(ibcr0, next_pc | 0x1);
1304
1305 return ERROR_OK;
1306 }
1307
1308 int xscale_disable_single_step(struct target_s *target)
1309 {
1310 armv4_5_common_t *armv4_5 = target->arch_info;
1311 xscale_common_t *xscale= armv4_5->arch_info;
1312 reg_t *ibcr0 = &xscale->reg_cache->reg_list[XSCALE_IBCR0];
1313
1314 xscale_set_reg_u32(ibcr0, 0x0);
1315
1316 return ERROR_OK;
1317 }
1318
1319 int xscale_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution)
1320 {
1321 armv4_5_common_t *armv4_5 = target->arch_info;
1322 xscale_common_t *xscale= armv4_5->arch_info;
1323 breakpoint_t *breakpoint = target->breakpoints;
1324
1325 u32 current_pc;
1326
1327 int retval;
1328 int i;
1329
1330 DEBUG("-");
1331
1332 if (target->state != TARGET_HALTED)
1333 {
1334 WARNING("target not halted");
1335 return ERROR_TARGET_NOT_HALTED;
1336 }
1337
1338 if (!debug_execution)
1339 {
1340 target_free_all_working_areas(target);
1341 }
1342
1343 /* update vector tables */
1344 if ((retval=xscale_update_vectors(target))!=ERROR_OK)
1345 return retval;
1346
1347 /* current = 1: continue on current pc, otherwise continue at <address> */
1348 if (!current)
1349 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, address);
1350
1351 current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
1352
1353 /* if we're at the reset vector, we have to simulate the branch */
1354 if (current_pc == 0x0)
1355 {
1356 arm_simulate_step(target, NULL);
1357 current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
1358 }
1359
1360 /* the front-end may request us not to handle breakpoints */
1361 if (handle_breakpoints)
1362 {
1363 if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))))
1364 {
1365 u32 next_pc;
1366
1367 /* there's a breakpoint at the current PC, we have to step over it */
1368 DEBUG("unset breakpoint at 0x%8.8x", breakpoint->address);
1369 xscale_unset_breakpoint(target, breakpoint);
1370
1371 /* calculate PC of next instruction */
1372 if ((retval = arm_simulate_step(target, &next_pc)) != ERROR_OK)
1373 {
1374 u32 current_opcode;
1375 target_read_u32(target, current_pc, &current_opcode);
1376 ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode);
1377 }
1378
1379 DEBUG("enable single-step");
1380 xscale_enable_single_step(target, next_pc);
1381
1382 /* restore banked registers */
1383 xscale_restore_context(target);
1384
1385 /* send resume request (command 0x30 or 0x31)
1386 * clean the trace buffer if it is to be enabled (0x62) */
1387 if (xscale->trace.buffer_enabled)
1388 {
1389 xscale_send_u32(target, 0x62);
1390 xscale_send_u32(target, 0x31);
1391 }
1392 else
1393 xscale_send_u32(target, 0x30);
1394
1395 /* send CPSR */
1396 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1397 DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1398
1399 for (i = 7; i >= 0; i--)
1400 {
1401 /* send register */
1402 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
1403 DEBUG("writing r%i with value 0x%8.8x", i, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
1404 }
1405
1406 /* send PC */
1407 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1408 DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1409
1410 /* wait for and process debug entry */
1411 xscale_debug_entry(target);
1412
1413 DEBUG("disable single-step");
1414 xscale_disable_single_step(target);
1415
1416 DEBUG("set breakpoint at 0x%8.8x", breakpoint->address);
1417 xscale_set_breakpoint(target, breakpoint);
1418 }
1419 }
1420
1421 /* enable any pending breakpoints and watchpoints */
1422 xscale_enable_breakpoints(target);
1423 xscale_enable_watchpoints(target);
1424
1425 /* restore banked registers */
1426 xscale_restore_context(target);
1427
1428 /* send resume request (command 0x30 or 0x31)
1429 * clean the trace buffer if it is to be enabled (0x62) */
1430 if (xscale->trace.buffer_enabled)
1431 {
1432 xscale_send_u32(target, 0x62);
1433 xscale_send_u32(target, 0x31);
1434 }
1435 else
1436 xscale_send_u32(target, 0x30);
1437
1438 /* send CPSR */
1439 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1440 DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1441
1442 for (i = 7; i >= 0; i--)
1443 {
1444 /* send register */
1445 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
1446 DEBUG("writing r%i with value 0x%8.8x", i, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
1447 }
1448
1449 /* send PC */
1450 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1451 DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1452
1453 target->debug_reason = DBG_REASON_NOTHALTED;
1454
1455 if (!debug_execution)
1456 {
1457 /* registers are now invalid */
1458 armv4_5_invalidate_core_regs(target);
1459 target->state = TARGET_RUNNING;
1460 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1461 }
1462 else
1463 {
1464 target->state = TARGET_DEBUG_RUNNING;
1465 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
1466 }
1467
1468 DEBUG("target resumed");
1469
1470 xscale->handler_running = 1;
1471
1472 return ERROR_OK;
1473 }
1474
1475 int xscale_step(struct target_s *target, int current, u32 address, int handle_breakpoints)
1476 {
1477 armv4_5_common_t *armv4_5 = target->arch_info;
1478 xscale_common_t *xscale = armv4_5->arch_info;
1479 breakpoint_t *breakpoint = target->breakpoints;
1480
1481 u32 current_pc, next_pc;
1482 int i;
1483 int retval;
1484
1485 if (target->state != TARGET_HALTED)
1486 {
1487 WARNING("target not halted");
1488 return ERROR_TARGET_NOT_HALTED;
1489 }
1490
1491 /* current = 1: continue on current pc, otherwise continue at <address> */
1492 if (!current)
1493 buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, address);
1494
1495 current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
1496
1497 /* if we're at the reset vector, we have to simulate the step */
1498 if (current_pc == 0x0)
1499 {
1500 arm_simulate_step(target, NULL);
1501 current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
1502
1503 target->debug_reason = DBG_REASON_SINGLESTEP;
1504 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1505
1506 return ERROR_OK;
1507 }
1508
1509 /* the front-end may request us not to handle breakpoints */
1510 if (handle_breakpoints)
1511 if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))))
1512 {
1513 xscale_unset_breakpoint(target, breakpoint);
1514 }
1515
1516 target->debug_reason = DBG_REASON_SINGLESTEP;
1517
1518 /* calculate PC of next instruction */
1519 if ((retval = arm_simulate_step(target, &next_pc)) != ERROR_OK)
1520 {
1521 u32 current_opcode;
1522 target_read_u32(target, current_pc, &current_opcode);
1523 ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode);
1524 }
1525
1526 DEBUG("enable single-step");
1527 xscale_enable_single_step(target, next_pc);
1528
1529 /* restore banked registers */
1530 xscale_restore_context(target);
1531
1532 /* send resume request (command 0x30 or 0x31)
1533 * clean the trace buffer if it is to be enabled (0x62) */
1534 if (xscale->trace.buffer_enabled)
1535 {
1536 xscale_send_u32(target, 0x62);
1537 xscale_send_u32(target, 0x31);
1538 }
1539 else
1540 xscale_send_u32(target, 0x30);
1541
1542 /* send CPSR */
1543 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1544 DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
1545
1546 for (i = 7; i >= 0; i--)
1547 {
1548 /* send register */
1549 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
1550 DEBUG("writing r%i with value 0x%8.8x", i, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
1551 }
1552
1553 /* send PC */
1554 xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1555 DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
1556
1557 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1558
1559 /* registers are now invalid */
1560 armv4_5_invalidate_core_regs(target);
1561
1562 /* wait for and process debug entry */
1563 xscale_debug_entry(target);
1564
1565 DEBUG("disable single-step");
1566 xscale_disable_single_step(target);
1567
1568 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1569
1570 if (breakpoint)
1571 {
1572 xscale_set_breakpoint(target, breakpoint);
1573 }
1574
1575 DEBUG("target stepped");
1576
1577 return ERROR_OK;
1578
1579 }
1580
1581 int xscale_assert_reset(target_t *target)
1582 {
1583 armv4_5_common_t *armv4_5 = target->arch_info;
1584 xscale_common_t *xscale = armv4_5->arch_info;
1585
1586 DEBUG("target->state: %s", target_state_strings[target->state]);
1587
1588 /* select DCSR instruction (set endstate to R-T-I to ensure we don't
1589 * end up in T-L-R, which would reset JTAG
1590 */
1591 jtag_add_end_state(TAP_RTI);
1592 xscale_jtag_set_instr(xscale->jtag_info.chain_pos, xscale->jtag_info.dcsr);
1593
1594 /* set Hold reset, Halt mode and Trap Reset */
1595 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
1596 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);
1597 xscale_write_dcsr(target, 1, 0);
1598
1599 /* select BYPASS, because having DCSR selected caused problems on the PXA27x */
1600 xscale_jtag_set_instr(xscale->jtag_info.chain_pos, 0x7f);
1601 jtag_execute_queue();
1602
1603 /* assert reset */
1604 jtag_add_reset(0, 1);
1605
1606 /* sleep 1ms, to be sure we fulfill any requirements */
1607 jtag_add_sleep(1000);
1608 jtag_execute_queue();
1609
1610 target->state = TARGET_RESET;
1611
1612 return ERROR_OK;
1613 }
1614
1615 int xscale_deassert_reset(target_t *target)
1616 {
1617 armv4_5_common_t *armv4_5 = target->arch_info;
1618 xscale_common_t *xscale = armv4_5->arch_info;
1619
1620 fileio_t debug_handler;
1621 u32 address;
1622 u32 binary_size;
1623
1624 u32 buf_cnt;
1625 int i;
1626 int retval;
1627
1628 breakpoint_t *breakpoint = target->breakpoints;
1629
1630 DEBUG("-");
1631
1632 xscale->ibcr_available = 2;
1633 xscale->ibcr0_used = 0;
1634 xscale->ibcr1_used = 0;
1635
1636 xscale->dbr_available = 2;
1637 xscale->dbr0_used = 0;
1638 xscale->dbr1_used = 0;
1639
1640 /* mark all hardware breakpoints as unset */
1641 while (breakpoint)
1642 {
1643 if (breakpoint->type == BKPT_HARD)
1644 {
1645 breakpoint->set = 0;
1646 }
1647 breakpoint = breakpoint->next;
1648 }
1649
1650 if (!xscale->handler_installed)
1651 {
1652 /* release SRST */
1653 jtag_add_reset(0, 0);
1654
1655 /* wait 300ms; 150 and 100ms were not enough */
1656 jtag_add_sleep(300*1000);
1657
1658 jtag_add_runtest(2030, TAP_RTI);
1659 jtag_execute_queue();
1660
1661 /* set Hold reset, Halt mode and Trap Reset */
1662 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
1663 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);
1664 xscale_write_dcsr(target, 1, 0);
1665
1666 /* Load debug handler */
1667 if (fileio_open(&debug_handler, "xscale/debug_handler.bin", FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
1668 {
1669 return ERROR_OK;
1670 }
1671
1672 if ((binary_size = debug_handler.size) % 4)
1673 {
1674 ERROR("debug_handler.bin: size not a multiple of 4");
1675 exit(-1);
1676 }
1677
1678 if (binary_size > 0x800)
1679 {
1680 ERROR("debug_handler.bin: larger than 2kb");
1681 exit(-1);
1682 }
1683
1684 binary_size = CEIL(binary_size, 32) * 32;
1685
1686 address = xscale->handler_address;
1687 while (binary_size > 0)
1688 {
1689 u32 cache_line[8];
1690 u8 buffer[32];
1691
1692 if ((retval = fileio_read(&debug_handler, 32, buffer, &buf_cnt)) != ERROR_OK)
1693 {
1694
1695 }
1696
1697 for (i = 0; i < buf_cnt; i += 4)
1698 {
1699 /* convert LE buffer to host-endian u32 */
1700 cache_line[i / 4] = le_to_h_u32(&buffer[i]);
1701 }
1702
1703 for (; buf_cnt < 32; buf_cnt += 4)
1704 {
1705 cache_line[buf_cnt / 4] = 0xe1a08008;
1706 }
1707
1708 /* only load addresses other than the reset vectors */
1709 if ((address % 0x400) != 0x0)
1710 {
1711 xscale_load_ic(target, 1, address, cache_line);
1712 }
1713
1714 address += buf_cnt;
1715 binary_size -= buf_cnt;
1716 };
1717
1718 xscale_load_ic(target, 1, 0x0, xscale->low_vectors);
1719 xscale_load_ic(target, 1, 0xffff0000, xscale->high_vectors);
1720
1721 jtag_add_runtest(30, TAP_RTI);
1722
1723 jtag_add_sleep(100000);
1724
1725 /* set Hold reset, Halt mode and Trap Reset */
1726 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
1727 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);
1728 xscale_write_dcsr(target, 1, 0);
1729
1730 /* clear Hold reset to let the target run (should enter debug handler) */
1731 xscale_write_dcsr(target, 0, 1);
1732 target->state = TARGET_RUNNING;
1733
1734 if ((target->reset_mode != RESET_HALT) && (target->reset_mode != RESET_INIT))
1735 {
1736 jtag_add_sleep(10000);
1737
1738 /* we should have entered debug now */
1739 xscale_debug_entry(target);
1740 target->state = TARGET_HALTED;
1741
1742 /* resume the target */
1743 xscale_resume(target, 1, 0x0, 1, 0);
1744 }
1745
1746 fileio_close(&debug_handler);
1747 }
1748 else
1749 {
1750 jtag_add_reset(0, 0);
1751 }
1752
1753
1754 return ERROR_OK;
1755 }
1756
1757 int xscale_soft_reset_halt(struct target_s *target)
1758 {
1759
1760 return ERROR_OK;
1761 }
1762
1763 int xscale_prepare_reset_halt(struct target_s *target)
1764 {
1765 /* nothing to be done for reset_halt on XScale targets
1766 * we always halt after a reset to upload the debug handler
1767 */
1768 return ERROR_OK;
1769 }
1770
1771 int xscale_read_core_reg(struct target_s *target, int num, enum armv4_5_mode mode)
1772 {
1773
1774 return ERROR_OK;
1775 }
1776
1777 int xscale_write_core_reg(struct target_s *target, int num, enum armv4_5_mode mode, u32 value)
1778 {
1779
1780 return ERROR_OK;
1781 }
1782
1783 int xscale_full_context(target_t *target)
1784 {
1785 armv4_5_common_t *armv4_5 = target->arch_info;
1786
1787 u32 *buffer;
1788
1789 int i, j;
1790
1791 DEBUG("-");
1792
1793 if (target->state != TARGET_HALTED)
1794 {
1795 WARNING("target not halted");
1796 return ERROR_TARGET_NOT_HALTED;
1797 }
1798
1799 buffer = malloc(4 * 8);
1800
1801 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1802 * we can't enter User mode on an XScale (unpredictable),
1803 * but User shares registers with SYS
1804 */
1805 for(i = 1; i < 7; i++)
1806 {
1807 int valid = 1;
1808
1809 /* check if there are invalid registers in the current mode
1810 */
1811 for (j = 0; j <= 16; j++)
1812 {
1813 if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).valid == 0)
1814 valid = 0;
1815 }
1816
1817 if (!valid)
1818 {
1819 u32 tmp_cpsr;
1820
1821 /* request banked registers */
1822 xscale_send_u32(target, 0x0);
1823
1824 tmp_cpsr = 0x0;
1825 tmp_cpsr |= armv4_5_number_to_mode(i);
1826 tmp_cpsr |= 0xc0; /* I/F bits */
1827
1828 /* send CPSR for desired mode */
1829 xscale_send_u32(target, tmp_cpsr);
1830
1831 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1832 if ((armv4_5_number_to_mode(i) != ARMV4_5_MODE_USR) && (armv4_5_number_to_mode(i) != ARMV4_5_MODE_SYS))
1833 {
1834 xscale_receive(target, buffer, 8);
1835 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32, buffer[7]);
1836 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty = 0;
1837 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).valid = 1;
1838 }
1839 else
1840 {
1841 xscale_receive(target, buffer, 7);
1842 }
1843
1844 /* move data from buffer to register cache */
1845 for (j = 8; j <= 14; j++)
1846 {
1847 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]);
1848 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty = 0;
1849 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).valid = 1;
1850 }
1851 }
1852 }
1853
1854 free(buffer);
1855
1856 return ERROR_OK;
1857 }
1858
1859 int xscale_restore_context(target_t *target)
1860 {
1861 armv4_5_common_t *armv4_5 = target->arch_info;
1862
1863 int i, j;
1864
1865 DEBUG("-");
1866
1867 if (target->state != TARGET_HALTED)
1868 {
1869 WARNING("target not halted");
1870 return ERROR_TARGET_NOT_HALTED;
1871 }
1872
1873 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1874 * we can't enter User mode on an XScale (unpredictable),
1875 * but User shares registers with SYS
1876 */
1877 for(i = 1; i < 7; i++)
1878 {
1879 int dirty = 0;
1880
1881 /* check if there are invalid registers in the current mode
1882 */
1883 for (j = 8; j <= 14; j++)
1884 {
1885 if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty == 1)
1886 dirty = 1;
1887 }
1888
1889 /* if not USR/SYS, check if the SPSR needs to be written */
1890 if ((armv4_5_number_to_mode(i) != ARMV4_5_MODE_USR) && (armv4_5_number_to_mode(i) != ARMV4_5_MODE_SYS))
1891 {
1892 if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty == 1)
1893 dirty = 1;
1894 }
1895
1896 if (dirty)
1897 {
1898 u32 tmp_cpsr;
1899
1900 /* send banked registers */
1901 xscale_send_u32(target, 0x1);
1902
1903 tmp_cpsr = 0x0;
1904 tmp_cpsr |= armv4_5_number_to_mode(i);
1905 tmp_cpsr |= 0xc0; /* I/F bits */
1906
1907 /* send CPSR for desired mode */
1908 xscale_send_u32(target, tmp_cpsr);
1909
1910 /* send banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1911 for (j = 8; j <= 14; j++)
1912 {
1913 xscale_send_u32(target, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, j).value, 0, 32));
1914 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty = 0;
1915 }
1916
1917 if ((armv4_5_number_to_mode(i) != ARMV4_5_MODE_USR) && (armv4_5_number_to_mode(i) != ARMV4_5_MODE_SYS))
1918 {
1919 xscale_send_u32(target, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32));
1920 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty = 0;
1921 }
1922 }
1923 }
1924
1925 return ERROR_OK;
1926 }
1927
1928 int xscale_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1929 {
1930 armv4_5_common_t *armv4_5 = target->arch_info;
1931 xscale_common_t *xscale = armv4_5->arch_info;
1932 u32 *buf32;
1933 int i;
1934 int retval;
1935
1936 DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
1937
1938 if (target->state != TARGET_HALTED)
1939 {
1940 WARNING("target not halted");
1941 return ERROR_TARGET_NOT_HALTED;
1942 }
1943
1944 /* sanitize arguments */
1945 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1946 return ERROR_INVALID_ARGUMENTS;
1947
1948 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
1949 return ERROR_TARGET_UNALIGNED_ACCESS;
1950
1951 /* send memory read request (command 0x1n, n: access size) */
1952 if ((retval=xscale_send_u32(target, 0x10 | size))!=ERROR_OK)
1953 return retval;
1954
1955 /* send base address for read request */
1956 if ((retval=xscale_send_u32(target, address))!=ERROR_OK)
1957 return retval;
1958
1959 /* send number of requested data words */
1960 if ((retval=xscale_send_u32(target, count))!=ERROR_OK)
1961 return retval;
1962
1963 /* receive data from target (count times 32-bit words in host endianness) */
1964 buf32 = malloc(4 * count);
1965 if ((retval=xscale_receive(target, buf32, count))!=ERROR_OK)
1966 return retval;
1967
1968 /* extract data from host-endian buffer into byte stream */
1969 for (i = 0; i < count; i++)
1970 {
1971 switch (size)
1972 {
1973 case 4:
1974 target_buffer_set_u32(target, buffer, buf32[i]);
1975 buffer += 4;
1976 break;
1977 case 2:
1978 target_buffer_set_u16(target, buffer, buf32[i] & 0xffff);
1979 buffer += 2;
1980 break;
1981 case 1:
1982 *buffer++ = buf32[i] & 0xff;
1983 break;
1984 default:
1985 ERROR("should never get here");
1986 exit(-1);
1987 }
1988 }
1989
1990 free(buf32);
1991
1992 /* examine DCSR, to see if Sticky Abort (SA) got set */
1993 if ((retval=xscale_read_dcsr(target))!=ERROR_OK)
1994 return retval;
1995 if (buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 5, 1) == 1)
1996 {
1997 /* clear SA bit */
1998 if ((retval=xscale_send_u32(target, 0x60))!=ERROR_OK)
1999 return retval;
2000
2001 return ERROR_TARGET_DATA_ABORT;
2002 }
2003
2004 return ERROR_OK;
2005 }
2006
2007 int xscale_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
2008 {
2009 armv4_5_common_t *armv4_5 = target->arch_info;
2010 xscale_common_t *xscale = armv4_5->arch_info;
2011 int retval;
2012
2013 DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
2014
2015 if (target->state != TARGET_HALTED)
2016 {
2017 WARNING("target not halted");
2018 return ERROR_TARGET_NOT_HALTED;
2019 }
2020
2021 /* sanitize arguments */
2022 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
2023 return ERROR_INVALID_ARGUMENTS;
2024
2025 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
2026 return ERROR_TARGET_UNALIGNED_ACCESS;
2027
2028 /* send memory write request (command 0x2n, n: access size) */
2029 if ((retval=xscale_send_u32(target, 0x20 | size))!=ERROR_OK)
2030 return retval;
2031
2032 /* send base address for read request */
2033 if ((retval=xscale_send_u32(target, address))!=ERROR_OK)
2034 return retval;
2035
2036 /* send number of requested data words to be written*/
2037 if ((retval=xscale_send_u32(target, count))!=ERROR_OK)
2038 return retval;
2039
2040 /* extract data from host-endian buffer into byte stream */
2041 #if 0
2042 for (i = 0; i < count; i++)
2043 {
2044 switch (size)
2045 {
2046 case 4:
2047 value = target_buffer_get_u32(target, buffer);
2048 xscale_send_u32(target, value);
2049 buffer += 4;
2050 break;
2051 case 2:
2052 value = target_buffer_get_u16(target, buffer);
2053 xscale_send_u32(target, value);
2054 buffer += 2;
2055 break;
2056 case 1:
2057 value = *buffer;
2058 xscale_send_u32(target, value);
2059 buffer += 1;
2060 break;
2061 default:
2062 ERROR("should never get here");
2063 exit(-1);
2064 }
2065 }
2066 #endif
2067 if ((retval=xscale_send(target, buffer, count, size))!=ERROR_OK)
2068 return retval;
2069
2070 /* examine DCSR, to see if Sticky Abort (SA) got set */
2071 if ((retval=xscale_read_dcsr(target))!=ERROR_OK)
2072 return retval;
2073 if (buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 5, 1) == 1)
2074 {
2075 /* clear SA bit */
2076 if ((retval=xscale_send_u32(target, 0x60))!=ERROR_OK)
2077 return retval;
2078
2079 return ERROR_TARGET_DATA_ABORT;
2080 }
2081
2082 return ERROR_OK;
2083 }
2084
2085 int xscale_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
2086 {
2087 return xscale_write_memory(target, address, 4, count, buffer);
2088 }
2089
2090 int xscale_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum)
2091 {
2092 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2093 }
2094
2095 u32 xscale_get_ttb(target_t *target)
2096 {
2097 armv4_5_common_t *armv4_5 = target->arch_info;
2098 xscale_common_t *xscale = armv4_5->arch_info;
2099 u32 ttb;
2100
2101 xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_TTB]);
2102 ttb = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_TTB].value, 0, 32);
2103
2104 return ttb;
2105 }
2106
2107 void xscale_disable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
2108 {
2109 armv4_5_common_t *armv4_5 = target->arch_info;
2110 xscale_common_t *xscale = armv4_5->arch_info;
2111 u32 cp15_control;
2112
2113 /* read cp15 control register */
2114 xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);
2115 cp15_control = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32);
2116
2117 if (mmu)
2118 cp15_control &= ~0x1U;
2119
2120 if (d_u_cache)
2121 {
2122 /* clean DCache */
2123 xscale_send_u32(target, 0x50);
2124 xscale_send_u32(target, xscale->cache_clean_address);
2125
2126 /* invalidate DCache */
2127 xscale_send_u32(target, 0x51);
2128
2129 cp15_control &= ~0x4U;
2130 }
2131
2132 if (i_cache)
2133 {
2134 /* invalidate ICache */
2135 xscale_send_u32(target, 0x52);
2136 cp15_control &= ~0x1000U;
2137 }
2138
2139 /* write new cp15 control register */
2140 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_CTRL], cp15_control);
2141
2142 /* execute cpwait to ensure outstanding operations complete */
2143 xscale_send_u32(target, 0x53);
2144 }
2145
2146 void xscale_enable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
2147 {
2148 armv4_5_common_t *armv4_5 = target->arch_info;
2149 xscale_common_t *xscale = armv4_5->arch_info;
2150 u32 cp15_control;
2151
2152 /* read cp15 control register */
2153 xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);
2154 cp15_control = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32);
2155
2156 if (mmu)
2157 cp15_control |= 0x1U;
2158
2159 if (d_u_cache)
2160 cp15_control |= 0x4U;
2161
2162 if (i_cache)
2163 cp15_control |= 0x1000U;
2164
2165 /* write new cp15 control register */
2166 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_CTRL], cp15_control);
2167
2168 /* execute cpwait to ensure outstanding operations complete */
2169 xscale_send_u32(target, 0x53);
2170 }
2171
2172 int xscale_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
2173 {
2174 armv4_5_common_t *armv4_5 = target->arch_info;
2175 xscale_common_t *xscale = armv4_5->arch_info;
2176
2177 if (target->state != TARGET_HALTED)
2178 {
2179 WARNING("target not halted");
2180 return ERROR_TARGET_NOT_HALTED;
2181 }
2182
2183 if (xscale->force_hw_bkpts)
2184 breakpoint->type = BKPT_HARD;
2185
2186 if (breakpoint->set)
2187 {
2188 WARNING("breakpoint already set");
2189 return ERROR_OK;
2190 }
2191
2192 if (breakpoint->type == BKPT_HARD)
2193 {
2194 u32 value = breakpoint->address | 1;
2195 if (!xscale->ibcr0_used)
2196 {
2197 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR0], value);
2198 xscale->ibcr0_used = 1;
2199 breakpoint->set = 1; /* breakpoint set on first breakpoint register */
2200 }
2201 else if (!xscale->ibcr1_used)
2202 {
2203 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR1], value);
2204 xscale->ibcr1_used = 1;
2205 breakpoint->set = 2; /* breakpoint set on second breakpoint register */
2206 }
2207 else
2208 {
2209 ERROR("BUG: no hardware comparator available");
2210 return ERROR_OK;
2211 }
2212 }
2213 else if (breakpoint->type == BKPT_SOFT)
2214 {
2215 if (breakpoint->length == 4)
2216 {
2217 /* keep the original instruction in target endianness */
2218 target->type->read_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr);
2219 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2220 target_write_u32(target, breakpoint->address, xscale->arm_bkpt);
2221 }
2222 else
2223 {
2224 /* keep the original instruction in target endianness */
2225 target->type->read_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr);
2226 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2227 target_write_u32(target, breakpoint->address, xscale->thumb_bkpt);
2228 }
2229 breakpoint->set = 1;
2230 }
2231
2232 return ERROR_OK;
2233
2234 }
2235
2236 int xscale_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
2237 {
2238 armv4_5_common_t *armv4_5 = target->arch_info;
2239 xscale_common_t *xscale = armv4_5->arch_info;
2240
2241 if (target->state != TARGET_HALTED)
2242 {
2243 WARNING("target not halted");
2244 return ERROR_TARGET_NOT_HALTED;
2245 }
2246
2247 if (xscale->force_hw_bkpts)
2248 {
2249 DEBUG("forcing use of hardware breakpoint at address 0x%8.8x", breakpoint->address);
2250 breakpoint->type = BKPT_HARD;
2251 }
2252
2253 if ((breakpoint->type == BKPT_HARD) && (xscale->ibcr_available < 1))
2254 {
2255 INFO("no breakpoint unit available for hardware breakpoint");
2256 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2257 }
2258 else
2259 {
2260 xscale->ibcr_available--;
2261 }
2262
2263 if ((breakpoint->length != 2) && (breakpoint->length != 4))
2264 {
2265 INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
2266 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2267 }
2268
2269 return ERROR_OK;
2270 }
2271
2272 int xscale_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
2273 {
2274 armv4_5_common_t *armv4_5 = target->arch_info;
2275 xscale_common_t *xscale = armv4_5->arch_info;
2276
2277 if (target->state != TARGET_HALTED)
2278 {
2279 WARNING("target not halted");
2280 return ERROR_TARGET_NOT_HALTED;
2281 }
2282
2283 if (!breakpoint->set)
2284 {
2285 WARNING("breakpoint not set");
2286 return ERROR_OK;
2287 }
2288
2289 if (breakpoint->type == BKPT_HARD)
2290 {
2291 if (breakpoint->set == 1)
2292 {
2293 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR0], 0x0);
2294 xscale->ibcr0_used = 0;
2295 }
2296 else if (breakpoint->set == 2)
2297 {
2298 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR1], 0x0);
2299 xscale->ibcr1_used = 0;
2300 }
2301 breakpoint->set = 0;
2302 }
2303 else
2304 {
2305 /* restore original instruction (kept in target endianness) */
2306 if (breakpoint->length == 4)
2307 {
2308 target->type->write_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr);
2309 }
2310 else
2311 {
2312 target->type->write_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr);
2313 }
2314 breakpoint->set = 0;
2315 }
2316
2317 return ERROR_OK;
2318 }
2319
2320 int xscale_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
2321 {
2322 armv4_5_common_t *armv4_5 = target->arch_info;
2323 xscale_common_t *xscale = armv4_5->arch_info;
2324
2325 if (target->state != TARGET_HALTED)
2326 {
2327 WARNING("target not halted");
2328 return ERROR_TARGET_NOT_HALTED;
2329 }
2330
2331 if (breakpoint->set)
2332 {
2333 xscale_unset_breakpoint(target, breakpoint);
2334 }
2335
2336 if (breakpoint->type == BKPT_HARD)
2337 xscale->ibcr_available++;
2338
2339 return ERROR_OK;
2340 }
2341
2342 int xscale_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
2343 {
2344 armv4_5_common_t *armv4_5 = target->arch_info;
2345 xscale_common_t *xscale = armv4_5->arch_info;
2346 u8 enable=0;
2347 reg_t *dbcon = &xscale->reg_cache->reg_list[XSCALE_DBCON];
2348 u32 dbcon_value = buf_get_u32(dbcon->value, 0, 32);
2349
2350 if (target->state != TARGET_HALTED)
2351 {
2352 WARNING("target not halted");
2353 return ERROR_TARGET_NOT_HALTED;
2354 }
2355
2356 xscale_get_reg(dbcon);
2357
2358 switch (watchpoint->rw)
2359 {
2360 case WPT_READ:
2361 enable = 0x3;
2362 break;
2363 case WPT_ACCESS:
2364 enable = 0x2;
2365 break;
2366 case WPT_WRITE:
2367 enable = 0x1;
2368 break;
2369 default:
2370 ERROR("BUG: watchpoint->rw neither read, write nor access");
2371 }
2372
2373 if (!xscale->dbr0_used)
2374 {
2375 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR0], watchpoint->address);
2376 dbcon_value |= enable;
2377 xscale_set_reg_u32(dbcon, dbcon_value);
2378 watchpoint->set = 1;
2379 xscale->dbr0_used = 1;
2380 }
2381 else if (!xscale->dbr1_used)
2382 {
2383 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR1], watchpoint->address);
2384 dbcon_value |= enable << 2;
2385 xscale_set_reg_u32(dbcon, dbcon_value);
2386 watchpoint->set = 2;
2387 xscale->dbr1_used = 1;
2388 }
2389 else
2390 {
2391 ERROR("BUG: no hardware comparator available");
2392 return ERROR_OK;
2393 }
2394
2395 return ERROR_OK;
2396 }
2397
2398 int xscale_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
2399 {
2400 armv4_5_common_t *armv4_5 = target->arch_info;
2401 xscale_common_t *xscale = armv4_5->arch_info;
2402
2403 if (target->state != TARGET_HALTED)
2404 {
2405 WARNING("target not halted");
2406 return ERROR_TARGET_NOT_HALTED;
2407 }
2408
2409 if (xscale->dbr_available < 1)
2410 {
2411 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2412 }
2413
2414 if ((watchpoint->length != 1) && (watchpoint->length != 2) && (watchpoint->length != 4))
2415 {
2416 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2417 }
2418
2419 xscale->dbr_available--;
2420
2421 return ERROR_OK;
2422 }
2423
2424 int xscale_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
2425 {
2426 armv4_5_common_t *armv4_5 = target->arch_info;
2427 xscale_common_t *xscale = armv4_5->arch_info;
2428 reg_t *dbcon = &xscale->reg_cache->reg_list[XSCALE_DBCON];
2429 u32 dbcon_value = buf_get_u32(dbcon->value, 0, 32);
2430
2431 if (target->state != TARGET_HALTED)
2432 {
2433 WARNING("target not halted");
2434 return ERROR_TARGET_NOT_HALTED;
2435 }
2436
2437 if (!watchpoint->set)
2438 {
2439 WARNING("breakpoint not set");
2440 return ERROR_OK;
2441 }
2442
2443 if (watchpoint->set == 1)
2444 {
2445 dbcon_value &= ~0x3;
2446 xscale_set_reg_u32(dbcon, dbcon_value);
2447 xscale->dbr0_used = 0;
2448 }
2449 else if (watchpoint->set == 2)
2450 {
2451 dbcon_value &= ~0xc;
2452 xscale_set_reg_u32(dbcon, dbcon_value);
2453 xscale->dbr1_used = 0;
2454 }
2455 watchpoint->set = 0;
2456
2457 return ERROR_OK;
2458 }
2459
2460 int xscale_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
2461 {
2462 armv4_5_common_t *armv4_5 = target->arch_info;
2463 xscale_common_t *xscale = armv4_5->arch_info;
2464
2465 if (target->state != TARGET_HALTED)
2466 {
2467 WARNING("target not halted");
2468 return ERROR_TARGET_NOT_HALTED;
2469 }
2470
2471 if (watchpoint->set)
2472 {
2473 xscale_unset_watchpoint(target, watchpoint);
2474 }
2475
2476 xscale->dbr_available++;
2477
2478 return ERROR_OK;
2479 }
2480
2481 void xscale_enable_watchpoints(struct target_s *target)
2482 {
2483 watchpoint_t *watchpoint = target->watchpoints;
2484
2485 while (watchpoint)
2486 {
2487 if (watchpoint->set == 0)
2488 xscale_set_watchpoint(target, watchpoint);
2489 watchpoint = watchpoint->next;
2490 }
2491 }
2492
2493 void xscale_enable_breakpoints(struct target_s *target)
2494 {
2495 breakpoint_t *breakpoint = target->breakpoints;
2496
2497 /* set any pending breakpoints */
2498 while (breakpoint)
2499 {
2500 if (breakpoint->set == 0)
2501 xscale_set_breakpoint(target, breakpoint);
2502 breakpoint = breakpoint->next;
2503 }
2504 }
2505
2506 int xscale_get_reg(reg_t *reg)
2507 {
2508 xscale_reg_t *arch_info = reg->arch_info;
2509 target_t *target = arch_info->target;
2510 armv4_5_common_t *armv4_5 = target->arch_info;
2511 xscale_common_t *xscale = armv4_5->arch_info;
2512
2513 /* DCSR, TX and RX are accessible via JTAG */
2514 if (strcmp(reg->name, "XSCALE_DCSR") == 0)
2515 {
2516 return xscale_read_dcsr(arch_info->target);
2517 }
2518 else if (strcmp(reg->name, "XSCALE_TX") == 0)
2519 {
2520 /* 1 = consume register content */
2521 return xscale_read_tx(arch_info->target, 1);
2522 }
2523 else if (strcmp(reg->name, "XSCALE_RX") == 0)
2524 {
2525 /* can't read from RX register (host -> debug handler) */
2526 return ERROR_OK;
2527 }
2528 else if (strcmp(reg->name, "XSCALE_TXRXCTRL") == 0)
2529 {
2530 /* can't (explicitly) read from TXRXCTRL register */
2531 return ERROR_OK;
2532 }
2533 else /* Other DBG registers have to be transfered by the debug handler */
2534 {
2535 /* send CP read request (command 0x40) */
2536 xscale_send_u32(target, 0x40);
2537
2538 /* send CP register number */
2539 xscale_send_u32(target, arch_info->dbg_handler_number);
2540
2541 /* read register value */
2542 xscale_read_tx(target, 1);
2543 buf_cpy(xscale->reg_cache->reg_list[XSCALE_TX].value, reg->value, 32);
2544
2545 reg->dirty = 0;
2546 reg->valid = 1;
2547 }
2548
2549 return ERROR_OK;
2550 }
2551
2552 int xscale_set_reg(reg_t *reg, u8* buf)
2553 {
2554 xscale_reg_t *arch_info = reg->arch_info;
2555 target_t *target = arch_info->target;
2556 armv4_5_common_t *armv4_5 = target->arch_info;
2557 xscale_common_t *xscale = armv4_5->arch_info;
2558 u32 value = buf_get_u32(buf, 0, 32);
2559
2560 /* DCSR, TX and RX are accessible via JTAG */
2561 if (strcmp(reg->name, "XSCALE_DCSR") == 0)
2562 {
2563 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 0, 32, value);
2564 return xscale_write_dcsr(arch_info->target, -1, -1);
2565 }
2566 else if (strcmp(reg->name, "XSCALE_RX") == 0)
2567 {
2568 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_RX].value, 0, 32, value);
2569 return xscale_write_rx(arch_info->target);
2570 }
2571 else if (strcmp(reg->name, "XSCALE_TX") == 0)
2572 {
2573 /* can't write to TX register (debug-handler -> host) */
2574 return ERROR_OK;
2575 }
2576 else if (strcmp(reg->name, "XSCALE_TXRXCTRL") == 0)
2577 {
2578 /* can't (explicitly) write to TXRXCTRL register */
2579 return ERROR_OK;
2580 }
2581 else /* Other DBG registers have to be transfered by the debug handler */
2582 {
2583 /* send CP write request (command 0x41) */
2584 xscale_send_u32(target, 0x41);
2585
2586 /* send CP register number */
2587 xscale_send_u32(target, arch_info->dbg_handler_number);
2588
2589 /* send CP register value */
2590 xscale_send_u32(target, value);
2591 buf_set_u32(reg->value, 0, 32, value);
2592 }
2593
2594 return ERROR_OK;
2595 }
2596
2597 /* convenience wrapper to access XScale specific registers */
2598 int xscale_set_reg_u32(reg_t *reg, u32 value)
2599 {
2600 u8 buf[4];
2601
2602 buf_set_u32(buf, 0, 32, value);
2603
2604 return xscale_set_reg(reg, buf);
2605 }
2606
2607 int xscale_write_dcsr_sw(target_t *target, u32 value)
2608 {
2609 /* get pointers to arch-specific information */
2610 armv4_5_common_t *armv4_5 = target->arch_info;
2611 xscale_common_t *xscale = armv4_5->arch_info;
2612 reg_t *dcsr = &xscale->reg_cache->reg_list[XSCALE_DCSR];
2613 xscale_reg_t *dcsr_arch_info = dcsr->arch_info;
2614
2615 /* send CP write request (command 0x41) */
2616 xscale_send_u32(target, 0x41);
2617
2618 /* send CP register number */
2619 xscale_send_u32(target, dcsr_arch_info->dbg_handler_number);
2620
2621 /* send CP register value */
2622 xscale_send_u32(target, value);
2623 buf_set_u32(dcsr->value, 0, 32, value);
2624
2625 return ERROR_OK;
2626 }
2627
2628 int xscale_read_trace(target_t *target)
2629 {
2630 /* get pointers to arch-specific information */
2631 armv4_5_common_t *armv4_5 = target->arch_info;
2632 xscale_common_t *xscale = armv4_5->arch_info;
2633 xscale_trace_data_t **trace_data_p;
2634
2635 /* 258 words from debug handler
2636 * 256 trace buffer entries
2637 * 2 checkpoint addresses
2638 */
2639 u32 trace_buffer[258];
2640 int is_address[256];
2641 int i, j;
2642
2643 if (target->state != TARGET_HALTED)
2644 {
2645 WARNING("target must be stopped to read trace data");
2646 return ERROR_TARGET_NOT_HALTED;
2647 }
2648
2649 /* send read trace buffer command (command 0x61) */
2650 xscale_send_u32(target, 0x61);
2651
2652 /* receive trace buffer content */
2653 xscale_receive(target, trace_buffer, 258);
2654
2655 /* parse buffer backwards to identify address entries */
2656 for (i = 255; i >= 0; i--)
2657 {
2658 is_address[i] = 0;
2659 if (((trace_buffer[i] & 0xf0) == 0x90) ||
2660 ((trace_buffer[i] & 0xf0) == 0xd0))
2661 {
2662 if (i >= 3)
2663 is_address[--i] = 1;
2664 if (i >= 2)
2665 is_address[--i] = 1;
2666 if (i >= 1)
2667 is_address[--i] = 1;
2668 if (i >= 0)
2669 is_address[--i] = 1;
2670 }
2671 }
2672
2673
2674 /* search first non-zero entry */
2675 for (j = 0; (j < 256) && (trace_buffer[j] == 0) && (!is_address[j]); j++)
2676 ;
2677
2678 if (j == 256)
2679 {
2680 DEBUG("no trace data collected");
2681 return ERROR_XSCALE_NO_TRACE_DATA;
2682 }
2683
2684 for (trace_data_p = &xscale->trace.data; *trace_data_p; trace_data_p = &(*trace_data_p)->next)
2685 ;
2686
2687 *trace_data_p = malloc(sizeof(xscale_trace_data_t));
2688 (*trace_data_p)->next = NULL;
2689 (*trace_data_p)->chkpt0 = trace_buffer[256];
2690 (*trace_data_p)->chkpt1 = trace_buffer[257];
2691 (*trace_data_p)->last_instruction = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
2692 (*trace_data_p)->entries = malloc(sizeof(xscale_trace_entry_t) * (256 - j));
2693 (*trace_data_p)->depth = 256 - j;
2694
2695 for (i = j; i < 256; i++)
2696 {
2697 (*trace_data_p)->entries[i - j].data = trace_buffer[i];
2698 if (is_address[i])
2699 (*trace_data_p)->entries[i - j].type = XSCALE_TRACE_ADDRESS;
2700 else
2701 (*trace_data_p)->entries[i - j].type = XSCALE_TRACE_MESSAGE;
2702 }
2703
2704 return ERROR_OK;
2705 }
2706
2707 int xscale_read_instruction(target_t *target, arm_instruction_t *instruction)
2708 {
2709 /* get pointers to arch-specific information */
2710 armv4_5_common_t *armv4_5 = target->arch_info;
2711 xscale_common_t *xscale = armv4_5->arch_info;
2712 int i;
2713 int section = -1;
2714 u32 size_read;
2715 u32 opcode;
2716 int retval;
2717
2718 if (!xscale->trace.image)
2719 return ERROR_TRACE_IMAGE_UNAVAILABLE;
2720
2721 /* search for the section the current instruction belongs to */
2722 for (i = 0; i < xscale->trace.image->num_sections; i++)
2723 {
2724 if ((xscale->trace.image->sections[i].base_address <= xscale->trace.current_pc) &&
2725 (xscale->trace.image->sections[i].base_address + xscale->trace.image->sections[i].size > xscale->trace.current_pc))
2726 {
2727 section = i;
2728 break;
2729 }
2730 }
2731
2732 if (section == -1)
2733 {
2734 /* current instruction couldn't be found in the image */
2735 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
2736 }
2737
2738 if (xscale->trace.core_state == ARMV4_5_STATE_ARM)
2739 {
2740 u8 buf[4];
2741 if ((retval = image_read_section(xscale->trace.image, section,
2742 xscale->trace.current_pc - xscale->trace.image->sections[section].base_address,
2743 4, buf, &size_read)) != ERROR_OK)
2744 {
2745 ERROR("error while reading instruction: %i", retval);
2746 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
2747 }
2748 opcode = target_buffer_get_u32(target, buf);
2749 arm_evaluate_opcode(opcode, xscale->trace.current_pc, instruction);
2750 }
2751 else if (xscale->trace.core_state == ARMV4_5_STATE_THUMB)
2752 {
2753 u8 buf[2];
2754 if ((retval = image_read_section(xscale->trace.image, section,
2755 xscale->trace.current_pc - xscale->trace.image->sections[section].base_address,
2756 2, buf, &size_read)) != ERROR_OK)
2757 {
2758 ERROR("error while reading instruction: %i", retval);
2759 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
2760 }
2761 opcode = target_buffer_get_u16(target, buf);
2762 thumb_evaluate_opcode(opcode, xscale->trace.current_pc, instruction);
2763 }
2764 else
2765 {
2766 ERROR("BUG: unknown core state encountered");
2767 exit(-1);
2768 }
2769
2770 return ERROR_OK;
2771 }
2772
2773 int xscale_branch_address(xscale_trace_data_t *trace_data, int i, u32 *target)
2774 {
2775 /* if there are less than four entries prior to the indirect branch message
2776 * we can't extract the address */
2777 if (i < 4)
2778 {
2779 return -1;
2780 }
2781
2782 *target = (trace_data->entries[i-1].data) | (trace_data->entries[i-2].data << 8) |
2783 (trace_data->entries[i-3].data << 16) | (trace_data->entries[i-4].data << 24);
2784
2785 return 0;
2786 }
2787
2788 int xscale_analyze_trace(target_t *target, command_context_t *cmd_ctx)
2789 {
2790 /* get pointers to arch-specific information */
2791 armv4_5_common_t *armv4_5 = target->arch_info;
2792 xscale_common_t *xscale = armv4_5->arch_info;
2793 int next_pc_ok = 0;
2794 u32 next_pc = 0x0;
2795 xscale_trace_data_t *trace_data = xscale->trace.data;
2796 int retval;
2797
2798 while (trace_data)
2799 {
2800 int i, chkpt;
2801 int rollover;
2802 int branch;
2803 int exception;
2804 xscale->trace.core_state = ARMV4_5_STATE_ARM;
2805
2806 chkpt = 0;
2807 rollover = 0;
2808
2809 for (i = 0; i < trace_data->depth; i++)
2810 {
2811 next_pc_ok = 0;
2812 branch = 0;
2813 exception = 0;
2814
2815 if (trace_data->entries[i].type == XSCALE_TRACE_ADDRESS)
2816 continue;
2817
2818 switch ((trace_data->entries[i].data & 0xf0) >> 4)
2819 {
2820 case 0: /* Exceptions */
2821 case 1:
2822 case 2:
2823 case 3:
2824 case 4:
2825 case 5:
2826 case 6:
2827 case 7:
2828 exception = (trace_data->entries[i].data & 0x70) >> 4;
2829 next_pc_ok = 1;
2830 next_pc = (trace_data->entries[i].data & 0xf0) >> 2;
2831 command_print(cmd_ctx, "--- exception %i ---", (trace_data->entries[i].data & 0xf0) >> 4);
2832 break;
2833 case 8: /* Direct Branch */
2834 branch = 1;
2835 break;
2836 case 9: /* Indirect Branch */
2837 branch = 1;
2838 if (xscale_branch_address(trace_data, i, &next_pc) == 0)
2839 {
2840 next_pc_ok = 1;
2841 }
2842 break;
2843 case 13: /* Checkpointed Indirect Branch */
2844 if (xscale_branch_address(trace_data, i, &next_pc) == 0)
2845 {
2846 next_pc_ok = 1;
2847 if (((chkpt == 0) && (next_pc != trace_data->chkpt0))
2848 || ((chkpt == 1) && (next_pc != trace_data->chkpt1)))
2849 WARNING("checkpointed indirect branch target address doesn't match checkpoint");
2850 }
2851 /* explicit fall-through */
2852 case 12: /* Checkpointed Direct Branch */
2853 branch = 1;
2854 if (chkpt == 0)
2855 {
2856 next_pc_ok = 1;
2857 next_pc = trace_data->chkpt0;
2858 chkpt++;
2859 }
2860 else if (chkpt == 1)
2861 {
2862 next_pc_ok = 1;
2863 next_pc = trace_data->chkpt0;
2864 chkpt++;
2865 }
2866 else
2867 {
2868 WARNING("more than two checkpointed branches encountered");
2869 }
2870 break;
2871 case 15: /* Roll-over */
2872 rollover++;
2873 continue;
2874 default: /* Reserved */
2875 command_print(cmd_ctx, "--- reserved trace message ---");
2876 ERROR("BUG: trace message %i is reserved", (trace_data->entries[i].data & 0xf0) >> 4);
2877 return ERROR_OK;
2878 }
2879
2880 if (xscale->trace.pc_ok)
2881 {
2882 int executed = (trace_data->entries[i].data & 0xf) + rollover * 16;
2883 arm_instruction_t instruction;
2884
2885 if ((exception == 6) || (exception == 7))
2886 {
2887 /* IRQ or FIQ exception, no instruction executed */
2888 executed -= 1;
2889 }
2890
2891 while (executed-- >= 0)
2892 {
2893 if ((retval = xscale_read_instruction(target, &instruction)) != ERROR_OK)
2894 {
2895 /* can't continue tracing with no image available */
2896 if (retval == ERROR_TRACE_IMAGE_UNAVAILABLE)
2897 {
2898 return retval;
2899 }
2900 else if (retval == ERROR_TRACE_INSTRUCTION_UNAVAILABLE)
2901 {
2902 /* TODO: handle incomplete images */
2903 }
2904 }
2905
2906 /* a precise abort on a load to the PC is included in the incremental
2907 * word count, other instructions causing data aborts are not included
2908 */
2909 if ((executed == 0) && (exception == 4)
2910 && ((instruction.type >= ARM_LDR) && (instruction.type <= ARM_LDM)))
2911 {
2912 if ((instruction.type == ARM_LDM)
2913 && ((instruction.info.load_store_multiple.register_list & 0x8000) == 0))
2914 {
2915 executed--;
2916 }
2917 else if (((instruction.type >= ARM_LDR) && (instruction.type <= ARM_LDRSH))
2918 && (instruction.info.load_store.Rd != 15))
2919 {
2920 executed--;
2921 }
2922 }
2923
2924 /* only the last instruction executed
2925 * (the one that caused the control flow change)
2926 * could be a taken branch
2927 */
2928 if (((executed == -1) && (branch == 1)) &&
2929 (((instruction.type == ARM_B) ||
2930 (instruction.type == ARM_BL) ||
2931 (instruction.type == ARM_BLX)) &&
2932 (instruction.info.b_bl_bx_blx.target_address != -1)))
2933 {
2934 xscale->trace.current_pc = instruction.info.b_bl_bx_blx.target_address;
2935 }
2936 else
2937 {
2938 xscale->trace.current_pc += (xscale->trace.core_state == ARMV4_5_STATE_ARM) ? 4 : 2;
2939 }
2940 command_print(cmd_ctx, "%s", instruction.text);
2941 }
2942
2943 rollover = 0;
2944 }
2945
2946 if (next_pc_ok)
2947 {
2948 xscale->trace.current_pc = next_pc;
2949 xscale->trace.pc_ok = 1;
2950 }
2951 }
2952
2953 for (; xscale->trace.current_pc < trace_data->last_instruction; xscale->trace.current_pc += (xscale->trace.core_state == ARMV4_5_STATE_ARM) ? 4 : 2)
2954 {
2955 arm_instruction_t instruction;
2956 if ((retval = xscale_read_instruction(target, &instruction)) != ERROR_OK)
2957 {
2958 /* can't continue tracing with no image available */
2959 if (retval == ERROR_TRACE_IMAGE_UNAVAILABLE)
2960 {
2961 return retval;
2962 }
2963 else if (retval == ERROR_TRACE_INSTRUCTION_UNAVAILABLE)
2964 {
2965 /* TODO: handle incomplete images */
2966 }
2967 }
2968 command_print(cmd_ctx, "%s", instruction.text);
2969 }
2970
2971 trace_data = trace_data->next;
2972 }
2973
2974 return ERROR_OK;
2975 }
2976
2977 void xscale_build_reg_cache(target_t *target)
2978 {
2979 /* get pointers to arch-specific information */
2980 armv4_5_common_t *armv4_5 = target->arch_info;
2981 xscale_common_t *xscale = armv4_5->arch_info;
2982
2983 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
2984 xscale_reg_t *arch_info = malloc(sizeof(xscale_reg_arch_info));
2985 int i;
2986 int num_regs = sizeof(xscale_reg_arch_info) / sizeof(xscale_reg_t);
2987
2988 (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
2989 armv4_5->core_cache = (*cache_p);
2990
2991 /* register a register arch-type for XScale dbg registers only once */
2992 if (xscale_reg_arch_type == -1)
2993 xscale_reg_arch_type = register_reg_arch_type(xscale_get_reg, xscale_set_reg);
2994
2995 (*cache_p)->next = malloc(sizeof(reg_cache_t));
2996 cache_p = &(*cache_p)->next;
2997
2998 /* fill in values for the xscale reg cache */
2999 (*cache_p)->name = "XScale registers";
3000 (*cache_p)->next = NULL;
3001 (*cache_p)->reg_list = malloc(num_regs * sizeof(reg_t));
3002 (*cache_p)->num_regs = num_regs;
3003
3004 for (i = 0; i < num_regs; i++)
3005 {
3006 (*cache_p)->reg_list[i].name = xscale_reg_list[i];
3007 (*cache_p)->reg_list[i].value = calloc(4, 1);
3008 (*cache_p)->reg_list[i].dirty = 0;
3009 (*cache_p)->reg_list[i].valid = 0;
3010 (*cache_p)->reg_list[i].size = 32;
3011 (*cache_p)->reg_list[i].bitfield_desc = NULL;
3012 (*cache_p)->reg_list[i].num_bitfields = 0;
3013 (*cache_p)->reg_list[i].arch_info = &arch_info[i];
3014 (*cache_p)->reg_list[i].arch_type = xscale_reg_arch_type;
3015 arch_info[i] = xscale_reg_arch_info[i];
3016 arch_info[i].target = target;
3017 }
3018
3019 xscale->reg_cache = (*cache_p);
3020 }
3021
3022 int xscale_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
3023 {
3024 if (startup_mode != DAEMON_RESET)
3025 {
3026 ERROR("XScale target requires a reset");
3027 ERROR("Reset target to enable debug");
3028 }
3029
3030 /* assert TRST once during startup */
3031 jtag_add_reset(1, 0);
3032 jtag_add_sleep(5000);
3033 jtag_add_reset(0, 0);
3034 jtag_execute_queue();
3035
3036 return ERROR_OK;
3037 }
3038
3039 int xscale_quit()
3040 {
3041
3042 return ERROR_OK;
3043 }
3044
3045 int xscale_init_arch_info(target_t *target, xscale_common_t *xscale, int chain_pos, char *variant)
3046 {
3047 armv4_5_common_t *armv4_5;
3048 u32 high_reset_branch, low_reset_branch;
3049 int i;
3050
3051 armv4_5 = &xscale->armv4_5_common;
3052
3053 /* store architecture specfic data (none so far) */
3054 xscale->arch_info = NULL;
3055 xscale->common_magic = XSCALE_COMMON_MAGIC;
3056
3057 /* remember the variant (PXA25x, PXA27x, IXP42x, ...) */
3058 xscale->variant = strdup(variant);
3059
3060 /* prepare JTAG information for the new target */
3061 xscale->jtag_info.chain_pos = chain_pos;
3062
3063 xscale->jtag_info.dbgrx = 0x02;
3064 xscale->jtag_info.dbgtx = 0x10;
3065 xscale->jtag_info.dcsr = 0x09;
3066 xscale->jtag_info.ldic = 0x07;
3067
3068 if ((strcmp(xscale->variant, "pxa250") == 0) ||
3069 (strcmp(xscale->variant, "pxa255") == 0) ||
3070 (strcmp(xscale->variant, "pxa26x") == 0))
3071 {
3072 xscale->jtag_info.ir_length = 5;
3073 }
3074 else if ((strcmp(xscale->variant, "pxa27x") == 0) ||
3075 (strcmp(xscale->variant, "ixp42x") == 0) ||
3076 (strcmp(xscale->variant, "ixp45x") == 0) ||
3077 (strcmp(xscale->variant, "ixp46x") == 0))
3078 {
3079 xscale->jtag_info.ir_length = 7;
3080 }
3081
3082 /* the debug handler isn't installed (and thus not running) at this time */
3083 xscale->handler_installed = 0;
3084 xscale->handler_running = 0;
3085 xscale->handler_address = 0xfe000800;
3086
3087 /* clear the vectors we keep locally for reference */
3088 memset(xscale->low_vectors, 0, sizeof(xscale->low_vectors));
3089 memset(xscale->high_vectors, 0, sizeof(xscale->high_vectors));
3090
3091 /* no user-specified vectors have been configured yet */
3092 xscale->static_low_vectors_set = 0x0;
3093 xscale->static_high_vectors_set = 0x0;
3094
3095 /* calculate branches to debug handler */
3096 low_reset_branch = (xscale->handler_address + 0x20 - 0x0 - 0x8) >> 2;
3097 high_reset_branch = (xscale->handler_address + 0x20 - 0xffff0000 - 0x8) >> 2;
3098
3099 xscale->low_vectors[0] = ARMV4_5_B((low_reset_branch & 0xffffff), 0);
3100 xscale->high_vectors[0] = ARMV4_5_B((high_reset_branch & 0xffffff), 0);
3101
3102 for (i = 1; i <= 7; i++)
3103 {
3104 xscale->low_vectors[i] = ARMV4_5_B(0xfffffe, 0);
3105 xscale->high_vectors[i] = ARMV4_5_B(0xfffffe, 0);
3106 }
3107
3108 /* 64kB aligned region used for DCache cleaning */
3109 xscale->cache_clean_address = 0xfffe0000;
3110
3111 xscale->hold_rst = 0;
3112 xscale->external_debug_break = 0;
3113
3114 xscale->force_hw_bkpts = 1;
3115
3116 xscale->ibcr_available = 2;
3117 xscale->ibcr0_used = 0;
3118 xscale->ibcr1_used = 0;
3119
3120 xscale->dbr_available = 2;
3121 xscale->dbr0_used = 0;
3122 xscale->dbr1_used = 0;
3123
3124 xscale->arm_bkpt = ARMV5_BKPT(0x0);
3125 xscale->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
3126
3127 xscale->vector_catch = 0x1;
3128
3129 xscale->trace.capture_status = TRACE_IDLE;
3130 xscale->trace.data = NULL;
3131 xscale->trace.image = NULL;
3132 xscale->trace.buffer_enabled = 0;
3133 xscale->trace.buffer_fill = 0;
3134
3135 /* prepare ARMv4/5 specific information */
3136 armv4_5->arch_info = xscale;
3137 armv4_5->read_core_reg = xscale_read_core_reg;
3138 armv4_5->write_core_reg = xscale_write_core_reg;
3139 armv4_5->full_context = xscale_full_context;
3140
3141 armv4_5_init_arch_info(target, armv4_5);
3142
3143 xscale->armv4_5_mmu.armv4_5_cache.ctype = -1;
3144 xscale->armv4_5_mmu.get_ttb = xscale_get_ttb;
3145 xscale->armv4_5_mmu.read_memory = xscale_read_memory;
3146 xscale->armv4_5_mmu.write_memory = xscale_write_memory;
3147 xscale->armv4_5_mmu.disable_mmu_caches = xscale_disable_mmu_caches;
3148 xscale->armv4_5_mmu.enable_mmu_caches = xscale_enable_mmu_caches;
3149 xscale->armv4_5_mmu.has_tiny_pages = 1;
3150 xscale->armv4_5_mmu.mmu_enabled = 0;
3151
3152 xscale->fast_memory_access = 0;
3153
3154 return ERROR_OK;
3155 }
3156
3157 /* target xscale <endianess> <startup_mode> <chain_pos> <variant> */
3158 int xscale_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
3159 {
3160 int chain_pos;
3161 char *variant = NULL;
3162 xscale_common_t *xscale = malloc(sizeof(xscale_common_t));
3163 memset(xscale, 0, sizeof(*xscale));
3164
3165 if (argc < 5)
3166 {
3167 ERROR("'target xscale' requires four arguments: <endianess> <startup_mode> <chain_pos> <variant>");
3168 return ERROR_OK;
3169 }
3170
3171 chain_pos = strtoul(args[3], NULL, 0);
3172
3173 variant = args[4];
3174
3175 xscale_init_arch_info(target, xscale, chain_pos, variant);
3176 xscale_build_reg_cache(target);
3177
3178 return ERROR_OK;
3179 }
3180
3181 int xscale_handle_debug_handler_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3182 {
3183 target_t *target = NULL;
3184 armv4_5_common_t *armv4_5;
3185 xscale_common_t *xscale;
3186
3187 u32 handler_address;
3188
3189 if (argc < 2)
3190 {
3191 ERROR("'xscale debug_handler <target#> <address>' command takes two required operands");
3192 return ERROR_OK;
3193 }
3194
3195 if ((target = get_target_by_num(strtoul(args[0], NULL, 0))) == NULL)
3196 {
3197 ERROR("no target '%s' configured", args[0]);
3198 return ERROR_OK;
3199 }
3200
3201 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3202 {
3203 return ERROR_OK;
3204 }
3205
3206 handler_address = strtoul(args[1], NULL, 0);
3207
3208 if (((handler_address >= 0x800) && (handler_address <= 0x1fef800)) ||
3209 ((handler_address >= 0xfe000800) && (handler_address <= 0xfffff800)))
3210 {
3211 xscale->handler_address = handler_address;
3212 }
3213 else
3214 {
3215 ERROR("xscale debug_handler <address> must be between 0x800 and 0x1fef800 or between 0xfe000800 and 0xfffff800");
3216 }
3217
3218 return ERROR_OK;
3219 }
3220
3221 int xscale_handle_cache_clean_address_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3222 {
3223 target_t *target = NULL;
3224 armv4_5_common_t *armv4_5;
3225 xscale_common_t *xscale;
3226
3227 u32 cache_clean_address;
3228
3229 if (argc < 2)
3230 {
3231 ERROR("'xscale cache_clean_address <target#> <address>' command takes two required operands");
3232 return ERROR_OK;
3233 }
3234
3235 if ((target = get_target_by_num(strtoul(args[0], NULL, 0))) == NULL)
3236 {
3237 ERROR("no target '%s' configured", args[0]);
3238 return ERROR_OK;
3239 }
3240
3241 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3242 {
3243 return ERROR_OK;
3244 }
3245
3246 cache_clean_address = strtoul(args[1], NULL, 0);
3247
3248 if (cache_clean_address & 0xffff)
3249 {
3250 ERROR("xscale cache_clean_address <address> must be 64kb aligned");
3251 }
3252 else
3253 {
3254 xscale->cache_clean_address = cache_clean_address;
3255 }
3256
3257 return ERROR_OK;
3258 }
3259
3260 int xscale_handle_cache_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3261 {
3262 target_t *target = get_current_target(cmd_ctx);
3263 armv4_5_common_t *armv4_5;
3264 xscale_common_t *xscale;
3265
3266 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3267 {
3268 return ERROR_OK;
3269 }
3270
3271 return armv4_5_handle_cache_info_command(cmd_ctx, &xscale->armv4_5_mmu.armv4_5_cache);
3272 }
3273
3274 static int xscale_virt2phys(struct target_s *target, u32 virtual, u32 *physical)
3275 {
3276 armv4_5_common_t *armv4_5;
3277 xscale_common_t *xscale;
3278 int retval;
3279 int type;
3280 u32 cb;
3281 int domain;
3282 u32 ap;
3283
3284
3285 if ((retval = xscale_get_arch_pointers(target, &armv4_5, &xscale)) != ERROR_OK)
3286 {
3287 return retval;
3288 }
3289 u32 ret = armv4_5_mmu_translate_va(target, &xscale->armv4_5_mmu, virtual, &type, &cb, &domain, &ap);
3290 if (type == -1)
3291 {
3292 return ret;
3293 }
3294 *physical = ret;
3295 return ERROR_OK;
3296 }
3297
3298 static int xscale_mmu(struct target_s *target, int *enabled)
3299 {
3300 armv4_5_common_t *armv4_5 = target->arch_info;
3301 xscale_common_t *xscale = armv4_5->arch_info;
3302
3303 if (target->state != TARGET_HALTED)
3304 {
3305 ERROR("Target not halted");
3306 return ERROR_TARGET_INVALID;
3307 }
3308 *enabled = xscale->armv4_5_mmu.mmu_enabled;
3309 return ERROR_OK;
3310 }
3311
3312
3313 int xscale_handle_mmu_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
3314 {
3315 target_t *target = get_current_target(cmd_ctx);
3316 armv4_5_common_t *armv4_5;
3317 xscale_common_t *xscale;
3318
3319 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3320 {
3321 return ERROR_OK;
3322 }
3323
3324 if (target->state != TARGET_HALTED)
3325 {
3326 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3327 return ERROR_OK;
3328 }
3329
3330 if (argc >= 1)
3331 {
3332 if (strcmp("enable", args[0]) == 0)
3333 {
3334 xscale_enable_mmu_caches(target, 1, 0, 0);
3335 xscale->armv4_5_mmu.mmu_enabled = 1;
3336 }
3337 else if (strcmp("disable", args[0]) == 0)
3338 {
3339 xscale_disable_mmu_caches(target, 1, 0, 0);
3340 xscale->armv4_5_mmu.mmu_enabled = 0;
3341 }
3342 }
3343
3344 command_print(cmd_ctx, "mmu %s", (xscale->armv4_5_mmu.mmu_enabled) ? "enabled" : "disabled");
3345
3346 return ERROR_OK;
3347 }
3348
3349 int xscale_handle_idcache_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
3350 {
3351 target_t *target = get_current_target(cmd_ctx);
3352 armv4_5_common_t *armv4_5;
3353 xscale_common_t *xscale;
3354 int icache = 0, dcache = 0;
3355
3356 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3357 {
3358 return ERROR_OK;
3359 }
3360
3361 if (target->state != TARGET_HALTED)
3362 {
3363 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3364 return ERROR_OK;
3365 }
3366
3367 if (strcmp(cmd, "icache") == 0)
3368 icache = 1;
3369 else if (strcmp(cmd, "dcache") == 0)
3370 dcache = 1;
3371
3372 if (argc >= 1)
3373 {
3374 if (strcmp("enable", args[0]) == 0)
3375 {
3376 xscale_enable_mmu_caches(target, 0, dcache, icache);
3377
3378 if (icache)
3379 xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 1;
3380 else if (dcache)
3381 xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 1;
3382 }
3383 else if (strcmp("disable", args[0]) == 0)
3384 {
3385 xscale_disable_mmu_caches(target, 0, dcache, icache);
3386
3387 if (icache)
3388 xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
3389 else if (dcache)
3390 xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
3391 }
3392 }
3393
3394 if (icache)
3395 command_print(cmd_ctx, "icache %s", (xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled) ? "enabled" : "disabled");
3396
3397 if (dcache)
3398 command_print(cmd_ctx, "dcache %s", (xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) ? "enabled" : "disabled");
3399
3400 return ERROR_OK;
3401 }
3402
3403 int xscale_handle_vector_catch_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
3404 {
3405 target_t *target = get_current_target(cmd_ctx);
3406 armv4_5_common_t *armv4_5;
3407 xscale_common_t *xscale;
3408
3409 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3410 {
3411 return ERROR_OK;
3412 }
3413
3414 if (argc < 1)
3415 {
3416 command_print(cmd_ctx, "usage: xscale vector_catch [mask]");
3417 }
3418 else
3419 {
3420 xscale->vector_catch = strtoul(args[0], NULL, 0);
3421 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 8, xscale->vector_catch);
3422 xscale_write_dcsr(target, -1, -1);
3423 }
3424
3425 command_print(cmd_ctx, "vector catch mask: 0x%2.2x", xscale->vector_catch);
3426
3427 return ERROR_OK;
3428 }
3429
3430 int xscale_handle_force_hw_bkpts_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3431 {
3432 target_t *target = get_current_target(cmd_ctx);
3433 armv4_5_common_t *armv4_5;
3434 xscale_common_t *xscale;
3435
3436 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3437 {
3438 return ERROR_OK;
3439 }
3440
3441 if ((argc >= 1) && (strcmp("enable", args[0]) == 0))
3442 {
3443 xscale->force_hw_bkpts = 1;
3444 }
3445 else if ((argc >= 1) && (strcmp("disable", args[0]) == 0))
3446 {
3447 xscale->force_hw_bkpts = 0;
3448 }
3449 else
3450 {
3451 command_print(cmd_ctx, "usage: xscale force_hw_bkpts <enable|disable>");
3452 }
3453
3454 command_print(cmd_ctx, "force hardware breakpoints %s", (xscale->force_hw_bkpts) ? "enabled" : "disabled");
3455
3456 return ERROR_OK;
3457 }
3458
3459 int xscale_handle_trace_buffer_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3460 {
3461 target_t *target = get_current_target(cmd_ctx);
3462 armv4_5_common_t *armv4_5;
3463 xscale_common_t *xscale;
3464 u32 dcsr_value;
3465
3466 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3467 {
3468 return ERROR_OK;
3469 }
3470
3471 if (target->state != TARGET_HALTED)
3472 {
3473 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3474 return ERROR_OK;
3475 }
3476
3477 if ((argc >= 1) && (strcmp("enable", args[0]) == 0))
3478 {
3479 xscale_trace_data_t *td, *next_td;
3480 xscale->trace.buffer_enabled = 1;
3481
3482 /* free old trace data */
3483 td = xscale->trace.data;
3484 while (td)
3485 {
3486 next_td = td->next;
3487
3488 if (td->entries)
3489 free(td->entries);
3490 free(td);
3491 td = next_td;
3492 }
3493 xscale->trace.data = NULL;
3494 }
3495 else if ((argc >= 1) && (strcmp("disable", args[0]) == 0))
3496 {
3497 xscale->trace.buffer_enabled = 0;
3498 }
3499
3500 if ((argc >= 2) && (strcmp("fill", args[1]) == 0))
3501 {
3502 if (argc >= 3)
3503 xscale->trace.buffer_fill = strtoul(args[2], NULL, 0);
3504 else
3505 xscale->trace.buffer_fill = 1;
3506 }
3507 else if ((argc >= 2) && (strcmp("wrap", args[1]) == 0))
3508 {
3509 xscale->trace.buffer_fill = -1;
3510 }
3511
3512 if (xscale->trace.buffer_enabled)
3513 {
3514 /* if we enable the trace buffer in fill-once
3515 * mode we know the address of the first instruction */
3516 xscale->trace.pc_ok = 1;
3517 xscale->trace.current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
3518 }
3519 else
3520 {
3521 /* otherwise the address is unknown, and we have no known good PC */
3522 xscale->trace.pc_ok = 0;
3523 }
3524
3525 command_print(cmd_ctx, "trace buffer %s (%s)",
3526 (xscale->trace.buffer_enabled) ? "enabled" : "disabled",
3527 (xscale->trace.buffer_fill > 0) ? "fill" : "wrap");
3528
3529 dcsr_value = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 0, 32);
3530 if (xscale->trace.buffer_fill >= 0)
3531 xscale_write_dcsr_sw(target, (dcsr_value & 0xfffffffc) | 2);
3532 else
3533 xscale_write_dcsr_sw(target, dcsr_value & 0xfffffffc);
3534
3535 return ERROR_OK;
3536 }
3537
3538 int xscale_handle_trace_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3539 {
3540 target_t *target;
3541 armv4_5_common_t *armv4_5;
3542 xscale_common_t *xscale;
3543
3544 if (argc < 1)
3545 {
3546 command_print(cmd_ctx, "usage: xscale trace_image <file> [base address] [type]");
3547 return ERROR_OK;
3548 }
3549
3550 target = get_current_target(cmd_ctx);
3551
3552 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3553 {
3554 return ERROR_OK;
3555 }
3556
3557 if (xscale->trace.image)
3558 {
3559 image_close(xscale->trace.image);
3560 free(xscale->trace.image);
3561 command_print(cmd_ctx, "previously loaded image found and closed");
3562 }
3563
3564 xscale->trace.image = malloc(sizeof(image_t));
3565 xscale->trace.image->base_address_set = 0;
3566 xscale->trace.image->start_address_set = 0;
3567
3568 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
3569 if (argc >= 2)
3570 {
3571 xscale->trace.image->base_address_set = 1;
3572 xscale->trace.image->base_address = strtoul(args[1], NULL, 0);
3573 }
3574 else
3575 {
3576 xscale->trace.image->base_address_set = 0;
3577 }
3578
3579 if (image_open(xscale->trace.image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
3580 {
3581 free(xscale->trace.image);
3582 xscale->trace.image = NULL;
3583 return ERROR_OK;
3584 }
3585
3586 return ERROR_OK;
3587 }
3588
3589 int xscale_handle_dump_trace_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3590 {
3591 target_t *target = get_current_target(cmd_ctx);
3592 armv4_5_common_t *armv4_5;
3593 xscale_common_t *xscale;
3594 xscale_trace_data_t *trace_data;
3595 fileio_t file;
3596
3597 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3598 {
3599 return ERROR_OK;
3600 }
3601
3602 if (target->state != TARGET_HALTED)
3603 {
3604 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3605 return ERROR_OK;
3606 }
3607
3608 if (argc < 1)
3609 {
3610 command_print(cmd_ctx, "usage: xscale dump_trace <file>");
3611 return ERROR_OK;
3612 }
3613
3614 trace_data = xscale->trace.data;
3615
3616 if (!trace_data)
3617 {
3618 command_print(cmd_ctx, "no trace data collected");
3619 return ERROR_OK;
3620 }
3621
3622 if (fileio_open(&file, args[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)
3623 {
3624 return ERROR_OK;
3625 }
3626
3627 while (trace_data)
3628 {
3629 int i;
3630
3631 fileio_write_u32(&file, trace_data->chkpt0);
3632 fileio_write_u32(&file, trace_data->chkpt1);
3633 fileio_write_u32(&file, trace_data->last_instruction);
3634 fileio_write_u32(&file, trace_data->depth);
3635
3636 for (i = 0; i < trace_data->depth; i++)
3637 fileio_write_u32(&file, trace_data->entries[i].data | ((trace_data->entries[i].type & 0xffff) << 16));
3638
3639 trace_data = trace_data->next;
3640 }
3641
3642 fileio_close(&file);
3643
3644 return ERROR_OK;
3645 }
3646
3647 int xscale_handle_analyze_trace_buffer_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3648 {
3649 target_t *target = get_current_target(cmd_ctx);
3650 armv4_5_common_t *armv4_5;
3651 xscale_common_t *xscale;
3652
3653 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3654 {
3655 return ERROR_OK;
3656 }
3657
3658 xscale_analyze_trace(target, cmd_ctx);
3659
3660 return ERROR_OK;
3661 }
3662
3663 int xscale_handle_cp15(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
3664 {
3665 target_t *target = get_current_target(cmd_ctx);
3666 armv4_5_common_t *armv4_5;
3667 xscale_common_t *xscale;
3668
3669 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3670 {
3671 return ERROR_OK;
3672 }
3673
3674 if (target->state != TARGET_HALTED)
3675 {
3676 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3677 return ERROR_OK;
3678 }
3679 u32 reg_no = 0;
3680 reg_t *reg = NULL;
3681 if(argc > 0)
3682 {
3683 reg_no = strtoul(args[0], NULL, 0);
3684 /*translate from xscale cp15 register no to openocd register*/
3685 switch(reg_no)
3686 {
3687 case 0:
3688 reg_no = XSCALE_MAINID;
3689 break;
3690 case 1:
3691 reg_no = XSCALE_CTRL;
3692 break;
3693 case 2:
3694 reg_no = XSCALE_TTB;
3695 break;
3696 case 3:
3697 reg_no = XSCALE_DAC;
3698 break;
3699 case 5:
3700 reg_no = XSCALE_FSR;
3701 break;
3702 case 6:
3703 reg_no = XSCALE_FAR;
3704 break;
3705 case 13:
3706 reg_no = XSCALE_PID;
3707 break;
3708 case 15:
3709 reg_no = XSCALE_CPACCESS;
3710 break;
3711 default:
3712 command_print(cmd_ctx, "invalid register number");
3713 return ERROR_INVALID_ARGUMENTS;
3714 }
3715 reg = &xscale->reg_cache->reg_list[reg_no];
3716
3717 }
3718 if(argc == 1)
3719 {
3720 u32 value;
3721
3722 /* read cp15 control register */
3723 xscale_get_reg(reg);
3724 value = buf_get_u32(reg->value, 0, 32);
3725 command_print(cmd_ctx, "%s (/%i): 0x%x", reg->name, reg->size, value);
3726 }
3727 else if(argc == 2)
3728 {
3729
3730 u32 value = strtoul(args[1], NULL, 0);
3731
3732 /* send CP write request (command 0x41) */
3733 xscale_send_u32(target, 0x41);
3734
3735 /* send CP register number */
3736 xscale_send_u32(target, reg_no);
3737
3738 /* send CP register value */
3739 xscale_send_u32(target, value);
3740
3741 /* execute cpwait to ensure outstanding operations complete */
3742 xscale_send_u32(target, 0x53);
3743 }
3744 else
3745 {
3746 command_print(cmd_ctx, "usage: cp15 [register]<, [value]>");
3747 }
3748
3749 return ERROR_OK;
3750 }
3751
3752 int handle_xscale_fast_memory_access_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3753 {
3754 target_t *target = get_current_target(cmd_ctx);
3755 armv4_5_common_t *armv4_5;
3756 xscale_common_t *xscale;
3757
3758 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3759 {
3760 return ERROR_OK;
3761 }
3762
3763 if (argc == 1)
3764 {
3765 if (strcmp("enable", args[0]) == 0)
3766 {
3767 xscale->fast_memory_access = 1;
3768 }
3769 else if (strcmp("disable", args[0]) == 0)
3770 {
3771 xscale->fast_memory_access = 0;
3772 }
3773 else
3774 {
3775 return ERROR_COMMAND_SYNTAX_ERROR;
3776 }
3777 } else if (argc!=0)
3778 {
3779 return ERROR_COMMAND_SYNTAX_ERROR;
3780 }
3781
3782 command_print(cmd_ctx, "fast memory access is %s", (xscale->fast_memory_access) ? "enabled" : "disabled");
3783
3784 return ERROR_OK;
3785 }
3786
3787 int xscale_register_commands(struct command_context_s *cmd_ctx)
3788 {
3789 command_t *xscale_cmd;
3790
3791 xscale_cmd = register_command(cmd_ctx, NULL, "xscale", NULL, COMMAND_ANY, "xscale specific commands");
3792
3793 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");
3794 register_command(cmd_ctx, xscale_cmd, "cache_clean_address", xscale_handle_cache_clean_address_command, COMMAND_ANY, NULL);
3795
3796 register_command(cmd_ctx, xscale_cmd, "cache_info", xscale_handle_cache_info_command, COMMAND_EXEC, NULL);
3797 register_command(cmd_ctx, xscale_cmd, "mmu", xscale_handle_mmu_command, COMMAND_EXEC, "['enable'|'disable'] the MMU");
3798 register_command(cmd_ctx, xscale_cmd, "icache", xscale_handle_idcache_command, COMMAND_EXEC, "['enable'|'disable'] the ICache");
3799 register_command(cmd_ctx, xscale_cmd, "dcache", xscale_handle_idcache_command, COMMAND_EXEC, "['enable'|'disable'] the DCache");
3800
3801 register_command(cmd_ctx, xscale_cmd, "vector_catch", xscale_handle_idcache_command, COMMAND_EXEC, "<mask> of vectors that should be catched");
3802
3803 register_command(cmd_ctx, xscale_cmd, "trace_buffer", xscale_handle_trace_buffer_command, COMMAND_EXEC, "<enable|disable> ['fill' [n]|'wrap']");
3804
3805 register_command(cmd_ctx, xscale_cmd, "dump_trace", xscale_handle_dump_trace_command, COMMAND_EXEC, "dump content of trace buffer to <file>");
3806 register_command(cmd_ctx, xscale_cmd, "analyze_trace", xscale_handle_analyze_trace_buffer_command, COMMAND_EXEC, "analyze content of trace buffer");
3807 register_command(cmd_ctx, xscale_cmd, "trace_image", xscale_handle_trace_image_command,
3808 COMMAND_EXEC, "load image from <file> [base address]");
3809
3810 register_command(cmd_ctx, xscale_cmd, "cp15", xscale_handle_cp15, COMMAND_EXEC, "access coproc 15 <register> [value]");
3811 register_command(cmd_ctx, xscale_cmd, "fast_memory_access", handle_xscale_fast_memory_access_command,
3812 COMMAND_ANY, "use fast memory accesses instead of slower but potentially unsafe slow accesses <enable|disable>");
3813
3814
3815 armv4_5_register_commands(cmd_ctx);
3816
3817 return ERROR_OK;
3818 }

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)