reduce compare noise. If someone should be crazy enough to try to run OpenOCD under...
[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 /* TRST every time. We want to be able to support daemon_startup attach */
1589 jtag_add_reset(1, 0);
1590 jtag_add_sleep(5000);
1591 jtag_add_reset(0, 0);
1592 jtag_add_sleep(5000);
1593 jtag_execute_queue();
1594
1595
1596
1597 /* select DCSR instruction (set endstate to R-T-I to ensure we don't
1598 * end up in T-L-R, which would reset JTAG
1599 */
1600 jtag_add_end_state(TAP_RTI);
1601 xscale_jtag_set_instr(xscale->jtag_info.chain_pos, xscale->jtag_info.dcsr);
1602
1603 /* set Hold reset, Halt mode and Trap Reset */
1604 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
1605 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);
1606 xscale_write_dcsr(target, 1, 0);
1607
1608 /* select BYPASS, because having DCSR selected caused problems on the PXA27x */
1609 xscale_jtag_set_instr(xscale->jtag_info.chain_pos, 0x7f);
1610 jtag_execute_queue();
1611
1612 /* assert reset */
1613 jtag_add_reset(0, 1);
1614
1615 /* sleep 1ms, to be sure we fulfill any requirements */
1616 jtag_add_sleep(1000);
1617 jtag_execute_queue();
1618
1619 target->state = TARGET_RESET;
1620
1621 return ERROR_OK;
1622 }
1623
1624 int xscale_deassert_reset(target_t *target)
1625 {
1626 armv4_5_common_t *armv4_5 = target->arch_info;
1627 xscale_common_t *xscale = armv4_5->arch_info;
1628
1629 fileio_t debug_handler;
1630 u32 address;
1631 u32 binary_size;
1632
1633 u32 buf_cnt;
1634 int i;
1635 int retval;
1636
1637 breakpoint_t *breakpoint = target->breakpoints;
1638
1639 DEBUG("-");
1640
1641 xscale->ibcr_available = 2;
1642 xscale->ibcr0_used = 0;
1643 xscale->ibcr1_used = 0;
1644
1645 xscale->dbr_available = 2;
1646 xscale->dbr0_used = 0;
1647 xscale->dbr1_used = 0;
1648
1649 /* mark all hardware breakpoints as unset */
1650 while (breakpoint)
1651 {
1652 if (breakpoint->type == BKPT_HARD)
1653 {
1654 breakpoint->set = 0;
1655 }
1656 breakpoint = breakpoint->next;
1657 }
1658
1659 if (!xscale->handler_installed)
1660 {
1661 /* release SRST */
1662 jtag_add_reset(0, 0);
1663
1664 /* wait 300ms; 150 and 100ms were not enough */
1665 jtag_add_sleep(300*1000);
1666
1667 jtag_add_runtest(2030, TAP_RTI);
1668 jtag_execute_queue();
1669
1670 /* set Hold reset, Halt mode and Trap Reset */
1671 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
1672 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);
1673 xscale_write_dcsr(target, 1, 0);
1674
1675 /* Load debug handler */
1676 if (fileio_open(&debug_handler, "xscale/debug_handler.bin", FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
1677 {
1678 return ERROR_OK;
1679 }
1680
1681 if ((binary_size = debug_handler.size) % 4)
1682 {
1683 ERROR("debug_handler.bin: size not a multiple of 4");
1684 exit(-1);
1685 }
1686
1687 if (binary_size > 0x800)
1688 {
1689 ERROR("debug_handler.bin: larger than 2kb");
1690 exit(-1);
1691 }
1692
1693 binary_size = CEIL(binary_size, 32) * 32;
1694
1695 address = xscale->handler_address;
1696 while (binary_size > 0)
1697 {
1698 u32 cache_line[8];
1699 u8 buffer[32];
1700
1701 if ((retval = fileio_read(&debug_handler, 32, buffer, &buf_cnt)) != ERROR_OK)
1702 {
1703
1704 }
1705
1706 for (i = 0; i < buf_cnt; i += 4)
1707 {
1708 /* convert LE buffer to host-endian u32 */
1709 cache_line[i / 4] = le_to_h_u32(&buffer[i]);
1710 }
1711
1712 for (; buf_cnt < 32; buf_cnt += 4)
1713 {
1714 cache_line[buf_cnt / 4] = 0xe1a08008;
1715 }
1716
1717 /* only load addresses other than the reset vectors */
1718 if ((address % 0x400) != 0x0)
1719 {
1720 xscale_load_ic(target, 1, address, cache_line);
1721 }
1722
1723 address += buf_cnt;
1724 binary_size -= buf_cnt;
1725 };
1726
1727 xscale_load_ic(target, 1, 0x0, xscale->low_vectors);
1728 xscale_load_ic(target, 1, 0xffff0000, xscale->high_vectors);
1729
1730 jtag_add_runtest(30, TAP_RTI);
1731
1732 jtag_add_sleep(100000);
1733
1734 /* set Hold reset, Halt mode and Trap Reset */
1735 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);
1736 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);
1737 xscale_write_dcsr(target, 1, 0);
1738
1739 /* clear Hold reset to let the target run (should enter debug handler) */
1740 xscale_write_dcsr(target, 0, 1);
1741 target->state = TARGET_RUNNING;
1742
1743 if ((target->reset_mode != RESET_HALT) && (target->reset_mode != RESET_INIT))
1744 {
1745 jtag_add_sleep(10000);
1746
1747 /* we should have entered debug now */
1748 xscale_debug_entry(target);
1749 target->state = TARGET_HALTED;
1750
1751 /* resume the target */
1752 xscale_resume(target, 1, 0x0, 1, 0);
1753 }
1754
1755 fileio_close(&debug_handler);
1756 }
1757 else
1758 {
1759 jtag_add_reset(0, 0);
1760 }
1761
1762
1763 return ERROR_OK;
1764 }
1765
1766 int xscale_soft_reset_halt(struct target_s *target)
1767 {
1768
1769 return ERROR_OK;
1770 }
1771
1772 int xscale_prepare_reset_halt(struct target_s *target)
1773 {
1774 /* nothing to be done for reset_halt on XScale targets
1775 * we always halt after a reset to upload the debug handler
1776 */
1777 return ERROR_OK;
1778 }
1779
1780 int xscale_read_core_reg(struct target_s *target, int num, enum armv4_5_mode mode)
1781 {
1782
1783 return ERROR_OK;
1784 }
1785
1786 int xscale_write_core_reg(struct target_s *target, int num, enum armv4_5_mode mode, u32 value)
1787 {
1788
1789 return ERROR_OK;
1790 }
1791
1792 int xscale_full_context(target_t *target)
1793 {
1794 armv4_5_common_t *armv4_5 = target->arch_info;
1795
1796 u32 *buffer;
1797
1798 int i, j;
1799
1800 DEBUG("-");
1801
1802 if (target->state != TARGET_HALTED)
1803 {
1804 WARNING("target not halted");
1805 return ERROR_TARGET_NOT_HALTED;
1806 }
1807
1808 buffer = malloc(4 * 8);
1809
1810 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1811 * we can't enter User mode on an XScale (unpredictable),
1812 * but User shares registers with SYS
1813 */
1814 for(i = 1; i < 7; i++)
1815 {
1816 int valid = 1;
1817
1818 /* check if there are invalid registers in the current mode
1819 */
1820 for (j = 0; j <= 16; j++)
1821 {
1822 if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).valid == 0)
1823 valid = 0;
1824 }
1825
1826 if (!valid)
1827 {
1828 u32 tmp_cpsr;
1829
1830 /* request banked registers */
1831 xscale_send_u32(target, 0x0);
1832
1833 tmp_cpsr = 0x0;
1834 tmp_cpsr |= armv4_5_number_to_mode(i);
1835 tmp_cpsr |= 0xc0; /* I/F bits */
1836
1837 /* send CPSR for desired mode */
1838 xscale_send_u32(target, tmp_cpsr);
1839
1840 /* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1841 if ((armv4_5_number_to_mode(i) != ARMV4_5_MODE_USR) && (armv4_5_number_to_mode(i) != ARMV4_5_MODE_SYS))
1842 {
1843 xscale_receive(target, buffer, 8);
1844 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32, buffer[7]);
1845 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty = 0;
1846 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).valid = 1;
1847 }
1848 else
1849 {
1850 xscale_receive(target, buffer, 7);
1851 }
1852
1853 /* move data from buffer to register cache */
1854 for (j = 8; j <= 14; j++)
1855 {
1856 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]);
1857 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty = 0;
1858 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).valid = 1;
1859 }
1860 }
1861 }
1862
1863 free(buffer);
1864
1865 return ERROR_OK;
1866 }
1867
1868 int xscale_restore_context(target_t *target)
1869 {
1870 armv4_5_common_t *armv4_5 = target->arch_info;
1871
1872 int i, j;
1873
1874 DEBUG("-");
1875
1876 if (target->state != TARGET_HALTED)
1877 {
1878 WARNING("target not halted");
1879 return ERROR_TARGET_NOT_HALTED;
1880 }
1881
1882 /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)
1883 * we can't enter User mode on an XScale (unpredictable),
1884 * but User shares registers with SYS
1885 */
1886 for(i = 1; i < 7; i++)
1887 {
1888 int dirty = 0;
1889
1890 /* check if there are invalid registers in the current mode
1891 */
1892 for (j = 8; j <= 14; j++)
1893 {
1894 if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty == 1)
1895 dirty = 1;
1896 }
1897
1898 /* if not USR/SYS, check if the SPSR needs to be written */
1899 if ((armv4_5_number_to_mode(i) != ARMV4_5_MODE_USR) && (armv4_5_number_to_mode(i) != ARMV4_5_MODE_SYS))
1900 {
1901 if (ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty == 1)
1902 dirty = 1;
1903 }
1904
1905 if (dirty)
1906 {
1907 u32 tmp_cpsr;
1908
1909 /* send banked registers */
1910 xscale_send_u32(target, 0x1);
1911
1912 tmp_cpsr = 0x0;
1913 tmp_cpsr |= armv4_5_number_to_mode(i);
1914 tmp_cpsr |= 0xc0; /* I/F bits */
1915
1916 /* send CPSR for desired mode */
1917 xscale_send_u32(target, tmp_cpsr);
1918
1919 /* send banked registers, r8 to r14, and spsr if not in USR/SYS mode */
1920 for (j = 8; j <= 14; j++)
1921 {
1922 xscale_send_u32(target, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, j).value, 0, 32));
1923 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), j).dirty = 0;
1924 }
1925
1926 if ((armv4_5_number_to_mode(i) != ARMV4_5_MODE_USR) && (armv4_5_number_to_mode(i) != ARMV4_5_MODE_SYS))
1927 {
1928 xscale_send_u32(target, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32));
1929 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_number_to_mode(i), 16).dirty = 0;
1930 }
1931 }
1932 }
1933
1934 return ERROR_OK;
1935 }
1936
1937 int xscale_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1938 {
1939 armv4_5_common_t *armv4_5 = target->arch_info;
1940 xscale_common_t *xscale = armv4_5->arch_info;
1941 u32 *buf32;
1942 int i;
1943 int retval;
1944
1945 DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
1946
1947 if (target->state != TARGET_HALTED)
1948 {
1949 WARNING("target not halted");
1950 return ERROR_TARGET_NOT_HALTED;
1951 }
1952
1953 /* sanitize arguments */
1954 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1955 return ERROR_INVALID_ARGUMENTS;
1956
1957 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
1958 return ERROR_TARGET_UNALIGNED_ACCESS;
1959
1960 /* send memory read request (command 0x1n, n: access size) */
1961 if ((retval=xscale_send_u32(target, 0x10 | size))!=ERROR_OK)
1962 return retval;
1963
1964 /* send base address for read request */
1965 if ((retval=xscale_send_u32(target, address))!=ERROR_OK)
1966 return retval;
1967
1968 /* send number of requested data words */
1969 if ((retval=xscale_send_u32(target, count))!=ERROR_OK)
1970 return retval;
1971
1972 /* receive data from target (count times 32-bit words in host endianness) */
1973 buf32 = malloc(4 * count);
1974 if ((retval=xscale_receive(target, buf32, count))!=ERROR_OK)
1975 return retval;
1976
1977 /* extract data from host-endian buffer into byte stream */
1978 for (i = 0; i < count; i++)
1979 {
1980 switch (size)
1981 {
1982 case 4:
1983 target_buffer_set_u32(target, buffer, buf32[i]);
1984 buffer += 4;
1985 break;
1986 case 2:
1987 target_buffer_set_u16(target, buffer, buf32[i] & 0xffff);
1988 buffer += 2;
1989 break;
1990 case 1:
1991 *buffer++ = buf32[i] & 0xff;
1992 break;
1993 default:
1994 ERROR("should never get here");
1995 exit(-1);
1996 }
1997 }
1998
1999 free(buf32);
2000
2001 /* examine DCSR, to see if Sticky Abort (SA) got set */
2002 if ((retval=xscale_read_dcsr(target))!=ERROR_OK)
2003 return retval;
2004 if (buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 5, 1) == 1)
2005 {
2006 /* clear SA bit */
2007 if ((retval=xscale_send_u32(target, 0x60))!=ERROR_OK)
2008 return retval;
2009
2010 return ERROR_TARGET_DATA_ABORT;
2011 }
2012
2013 return ERROR_OK;
2014 }
2015
2016 int xscale_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
2017 {
2018 armv4_5_common_t *armv4_5 = target->arch_info;
2019 xscale_common_t *xscale = armv4_5->arch_info;
2020 int retval;
2021
2022 DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count);
2023
2024 if (target->state != TARGET_HALTED)
2025 {
2026 WARNING("target not halted");
2027 return ERROR_TARGET_NOT_HALTED;
2028 }
2029
2030 /* sanitize arguments */
2031 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
2032 return ERROR_INVALID_ARGUMENTS;
2033
2034 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
2035 return ERROR_TARGET_UNALIGNED_ACCESS;
2036
2037 /* send memory write request (command 0x2n, n: access size) */
2038 if ((retval=xscale_send_u32(target, 0x20 | size))!=ERROR_OK)
2039 return retval;
2040
2041 /* send base address for read request */
2042 if ((retval=xscale_send_u32(target, address))!=ERROR_OK)
2043 return retval;
2044
2045 /* send number of requested data words to be written*/
2046 if ((retval=xscale_send_u32(target, count))!=ERROR_OK)
2047 return retval;
2048
2049 /* extract data from host-endian buffer into byte stream */
2050 #if 0
2051 for (i = 0; i < count; i++)
2052 {
2053 switch (size)
2054 {
2055 case 4:
2056 value = target_buffer_get_u32(target, buffer);
2057 xscale_send_u32(target, value);
2058 buffer += 4;
2059 break;
2060 case 2:
2061 value = target_buffer_get_u16(target, buffer);
2062 xscale_send_u32(target, value);
2063 buffer += 2;
2064 break;
2065 case 1:
2066 value = *buffer;
2067 xscale_send_u32(target, value);
2068 buffer += 1;
2069 break;
2070 default:
2071 ERROR("should never get here");
2072 exit(-1);
2073 }
2074 }
2075 #endif
2076 if ((retval=xscale_send(target, buffer, count, size))!=ERROR_OK)
2077 return retval;
2078
2079 /* examine DCSR, to see if Sticky Abort (SA) got set */
2080 if ((retval=xscale_read_dcsr(target))!=ERROR_OK)
2081 return retval;
2082 if (buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 5, 1) == 1)
2083 {
2084 /* clear SA bit */
2085 if ((retval=xscale_send_u32(target, 0x60))!=ERROR_OK)
2086 return retval;
2087
2088 return ERROR_TARGET_DATA_ABORT;
2089 }
2090
2091 return ERROR_OK;
2092 }
2093
2094 int xscale_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
2095 {
2096 return xscale_write_memory(target, address, 4, count, buffer);
2097 }
2098
2099 int xscale_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum)
2100 {
2101 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2102 }
2103
2104 u32 xscale_get_ttb(target_t *target)
2105 {
2106 armv4_5_common_t *armv4_5 = target->arch_info;
2107 xscale_common_t *xscale = armv4_5->arch_info;
2108 u32 ttb;
2109
2110 xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_TTB]);
2111 ttb = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_TTB].value, 0, 32);
2112
2113 return ttb;
2114 }
2115
2116 void xscale_disable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
2117 {
2118 armv4_5_common_t *armv4_5 = target->arch_info;
2119 xscale_common_t *xscale = armv4_5->arch_info;
2120 u32 cp15_control;
2121
2122 /* read cp15 control register */
2123 xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);
2124 cp15_control = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32);
2125
2126 if (mmu)
2127 cp15_control &= ~0x1U;
2128
2129 if (d_u_cache)
2130 {
2131 /* clean DCache */
2132 xscale_send_u32(target, 0x50);
2133 xscale_send_u32(target, xscale->cache_clean_address);
2134
2135 /* invalidate DCache */
2136 xscale_send_u32(target, 0x51);
2137
2138 cp15_control &= ~0x4U;
2139 }
2140
2141 if (i_cache)
2142 {
2143 /* invalidate ICache */
2144 xscale_send_u32(target, 0x52);
2145 cp15_control &= ~0x1000U;
2146 }
2147
2148 /* write new cp15 control register */
2149 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_CTRL], cp15_control);
2150
2151 /* execute cpwait to ensure outstanding operations complete */
2152 xscale_send_u32(target, 0x53);
2153 }
2154
2155 void xscale_enable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
2156 {
2157 armv4_5_common_t *armv4_5 = target->arch_info;
2158 xscale_common_t *xscale = armv4_5->arch_info;
2159 u32 cp15_control;
2160
2161 /* read cp15 control register */
2162 xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);
2163 cp15_control = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32);
2164
2165 if (mmu)
2166 cp15_control |= 0x1U;
2167
2168 if (d_u_cache)
2169 cp15_control |= 0x4U;
2170
2171 if (i_cache)
2172 cp15_control |= 0x1000U;
2173
2174 /* write new cp15 control register */
2175 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_CTRL], cp15_control);
2176
2177 /* execute cpwait to ensure outstanding operations complete */
2178 xscale_send_u32(target, 0x53);
2179 }
2180
2181 int xscale_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
2182 {
2183 armv4_5_common_t *armv4_5 = target->arch_info;
2184 xscale_common_t *xscale = armv4_5->arch_info;
2185
2186 if (target->state != TARGET_HALTED)
2187 {
2188 WARNING("target not halted");
2189 return ERROR_TARGET_NOT_HALTED;
2190 }
2191
2192 if (xscale->force_hw_bkpts)
2193 breakpoint->type = BKPT_HARD;
2194
2195 if (breakpoint->set)
2196 {
2197 WARNING("breakpoint already set");
2198 return ERROR_OK;
2199 }
2200
2201 if (breakpoint->type == BKPT_HARD)
2202 {
2203 u32 value = breakpoint->address | 1;
2204 if (!xscale->ibcr0_used)
2205 {
2206 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR0], value);
2207 xscale->ibcr0_used = 1;
2208 breakpoint->set = 1; /* breakpoint set on first breakpoint register */
2209 }
2210 else if (!xscale->ibcr1_used)
2211 {
2212 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR1], value);
2213 xscale->ibcr1_used = 1;
2214 breakpoint->set = 2; /* breakpoint set on second breakpoint register */
2215 }
2216 else
2217 {
2218 ERROR("BUG: no hardware comparator available");
2219 return ERROR_OK;
2220 }
2221 }
2222 else if (breakpoint->type == BKPT_SOFT)
2223 {
2224 if (breakpoint->length == 4)
2225 {
2226 /* keep the original instruction in target endianness */
2227 target->type->read_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr);
2228 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2229 target_write_u32(target, breakpoint->address, xscale->arm_bkpt);
2230 }
2231 else
2232 {
2233 /* keep the original instruction in target endianness */
2234 target->type->read_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr);
2235 /* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
2236 target_write_u32(target, breakpoint->address, xscale->thumb_bkpt);
2237 }
2238 breakpoint->set = 1;
2239 }
2240
2241 return ERROR_OK;
2242
2243 }
2244
2245 int xscale_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
2246 {
2247 armv4_5_common_t *armv4_5 = target->arch_info;
2248 xscale_common_t *xscale = armv4_5->arch_info;
2249
2250 if (target->state != TARGET_HALTED)
2251 {
2252 WARNING("target not halted");
2253 return ERROR_TARGET_NOT_HALTED;
2254 }
2255
2256 if (xscale->force_hw_bkpts)
2257 {
2258 DEBUG("forcing use of hardware breakpoint at address 0x%8.8x", breakpoint->address);
2259 breakpoint->type = BKPT_HARD;
2260 }
2261
2262 if ((breakpoint->type == BKPT_HARD) && (xscale->ibcr_available < 1))
2263 {
2264 INFO("no breakpoint unit available for hardware breakpoint");
2265 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2266 }
2267 else
2268 {
2269 xscale->ibcr_available--;
2270 }
2271
2272 if ((breakpoint->length != 2) && (breakpoint->length != 4))
2273 {
2274 INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
2275 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2276 }
2277
2278 return ERROR_OK;
2279 }
2280
2281 int xscale_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
2282 {
2283 armv4_5_common_t *armv4_5 = target->arch_info;
2284 xscale_common_t *xscale = armv4_5->arch_info;
2285
2286 if (target->state != TARGET_HALTED)
2287 {
2288 WARNING("target not halted");
2289 return ERROR_TARGET_NOT_HALTED;
2290 }
2291
2292 if (!breakpoint->set)
2293 {
2294 WARNING("breakpoint not set");
2295 return ERROR_OK;
2296 }
2297
2298 if (breakpoint->type == BKPT_HARD)
2299 {
2300 if (breakpoint->set == 1)
2301 {
2302 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR0], 0x0);
2303 xscale->ibcr0_used = 0;
2304 }
2305 else if (breakpoint->set == 2)
2306 {
2307 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR1], 0x0);
2308 xscale->ibcr1_used = 0;
2309 }
2310 breakpoint->set = 0;
2311 }
2312 else
2313 {
2314 /* restore original instruction (kept in target endianness) */
2315 if (breakpoint->length == 4)
2316 {
2317 target->type->write_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr);
2318 }
2319 else
2320 {
2321 target->type->write_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr);
2322 }
2323 breakpoint->set = 0;
2324 }
2325
2326 return ERROR_OK;
2327 }
2328
2329 int xscale_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
2330 {
2331 armv4_5_common_t *armv4_5 = target->arch_info;
2332 xscale_common_t *xscale = armv4_5->arch_info;
2333
2334 if (target->state != TARGET_HALTED)
2335 {
2336 WARNING("target not halted");
2337 return ERROR_TARGET_NOT_HALTED;
2338 }
2339
2340 if (breakpoint->set)
2341 {
2342 xscale_unset_breakpoint(target, breakpoint);
2343 }
2344
2345 if (breakpoint->type == BKPT_HARD)
2346 xscale->ibcr_available++;
2347
2348 return ERROR_OK;
2349 }
2350
2351 int xscale_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
2352 {
2353 armv4_5_common_t *armv4_5 = target->arch_info;
2354 xscale_common_t *xscale = armv4_5->arch_info;
2355 u8 enable=0;
2356 reg_t *dbcon = &xscale->reg_cache->reg_list[XSCALE_DBCON];
2357 u32 dbcon_value = buf_get_u32(dbcon->value, 0, 32);
2358
2359 if (target->state != TARGET_HALTED)
2360 {
2361 WARNING("target not halted");
2362 return ERROR_TARGET_NOT_HALTED;
2363 }
2364
2365 xscale_get_reg(dbcon);
2366
2367 switch (watchpoint->rw)
2368 {
2369 case WPT_READ:
2370 enable = 0x3;
2371 break;
2372 case WPT_ACCESS:
2373 enable = 0x2;
2374 break;
2375 case WPT_WRITE:
2376 enable = 0x1;
2377 break;
2378 default:
2379 ERROR("BUG: watchpoint->rw neither read, write nor access");
2380 }
2381
2382 if (!xscale->dbr0_used)
2383 {
2384 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR0], watchpoint->address);
2385 dbcon_value |= enable;
2386 xscale_set_reg_u32(dbcon, dbcon_value);
2387 watchpoint->set = 1;
2388 xscale->dbr0_used = 1;
2389 }
2390 else if (!xscale->dbr1_used)
2391 {
2392 xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR1], watchpoint->address);
2393 dbcon_value |= enable << 2;
2394 xscale_set_reg_u32(dbcon, dbcon_value);
2395 watchpoint->set = 2;
2396 xscale->dbr1_used = 1;
2397 }
2398 else
2399 {
2400 ERROR("BUG: no hardware comparator available");
2401 return ERROR_OK;
2402 }
2403
2404 return ERROR_OK;
2405 }
2406
2407 int xscale_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
2408 {
2409 armv4_5_common_t *armv4_5 = target->arch_info;
2410 xscale_common_t *xscale = armv4_5->arch_info;
2411
2412 if (target->state != TARGET_HALTED)
2413 {
2414 WARNING("target not halted");
2415 return ERROR_TARGET_NOT_HALTED;
2416 }
2417
2418 if (xscale->dbr_available < 1)
2419 {
2420 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2421 }
2422
2423 if ((watchpoint->length != 1) && (watchpoint->length != 2) && (watchpoint->length != 4))
2424 {
2425 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
2426 }
2427
2428 xscale->dbr_available--;
2429
2430 return ERROR_OK;
2431 }
2432
2433 int xscale_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
2434 {
2435 armv4_5_common_t *armv4_5 = target->arch_info;
2436 xscale_common_t *xscale = armv4_5->arch_info;
2437 reg_t *dbcon = &xscale->reg_cache->reg_list[XSCALE_DBCON];
2438 u32 dbcon_value = buf_get_u32(dbcon->value, 0, 32);
2439
2440 if (target->state != TARGET_HALTED)
2441 {
2442 WARNING("target not halted");
2443 return ERROR_TARGET_NOT_HALTED;
2444 }
2445
2446 if (!watchpoint->set)
2447 {
2448 WARNING("breakpoint not set");
2449 return ERROR_OK;
2450 }
2451
2452 if (watchpoint->set == 1)
2453 {
2454 dbcon_value &= ~0x3;
2455 xscale_set_reg_u32(dbcon, dbcon_value);
2456 xscale->dbr0_used = 0;
2457 }
2458 else if (watchpoint->set == 2)
2459 {
2460 dbcon_value &= ~0xc;
2461 xscale_set_reg_u32(dbcon, dbcon_value);
2462 xscale->dbr1_used = 0;
2463 }
2464 watchpoint->set = 0;
2465
2466 return ERROR_OK;
2467 }
2468
2469 int xscale_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
2470 {
2471 armv4_5_common_t *armv4_5 = target->arch_info;
2472 xscale_common_t *xscale = armv4_5->arch_info;
2473
2474 if (target->state != TARGET_HALTED)
2475 {
2476 WARNING("target not halted");
2477 return ERROR_TARGET_NOT_HALTED;
2478 }
2479
2480 if (watchpoint->set)
2481 {
2482 xscale_unset_watchpoint(target, watchpoint);
2483 }
2484
2485 xscale->dbr_available++;
2486
2487 return ERROR_OK;
2488 }
2489
2490 void xscale_enable_watchpoints(struct target_s *target)
2491 {
2492 watchpoint_t *watchpoint = target->watchpoints;
2493
2494 while (watchpoint)
2495 {
2496 if (watchpoint->set == 0)
2497 xscale_set_watchpoint(target, watchpoint);
2498 watchpoint = watchpoint->next;
2499 }
2500 }
2501
2502 void xscale_enable_breakpoints(struct target_s *target)
2503 {
2504 breakpoint_t *breakpoint = target->breakpoints;
2505
2506 /* set any pending breakpoints */
2507 while (breakpoint)
2508 {
2509 if (breakpoint->set == 0)
2510 xscale_set_breakpoint(target, breakpoint);
2511 breakpoint = breakpoint->next;
2512 }
2513 }
2514
2515 int xscale_get_reg(reg_t *reg)
2516 {
2517 xscale_reg_t *arch_info = reg->arch_info;
2518 target_t *target = arch_info->target;
2519 armv4_5_common_t *armv4_5 = target->arch_info;
2520 xscale_common_t *xscale = armv4_5->arch_info;
2521
2522 /* DCSR, TX and RX are accessible via JTAG */
2523 if (strcmp(reg->name, "XSCALE_DCSR") == 0)
2524 {
2525 return xscale_read_dcsr(arch_info->target);
2526 }
2527 else if (strcmp(reg->name, "XSCALE_TX") == 0)
2528 {
2529 /* 1 = consume register content */
2530 return xscale_read_tx(arch_info->target, 1);
2531 }
2532 else if (strcmp(reg->name, "XSCALE_RX") == 0)
2533 {
2534 /* can't read from RX register (host -> debug handler) */
2535 return ERROR_OK;
2536 }
2537 else if (strcmp(reg->name, "XSCALE_TXRXCTRL") == 0)
2538 {
2539 /* can't (explicitly) read from TXRXCTRL register */
2540 return ERROR_OK;
2541 }
2542 else /* Other DBG registers have to be transfered by the debug handler */
2543 {
2544 /* send CP read request (command 0x40) */
2545 xscale_send_u32(target, 0x40);
2546
2547 /* send CP register number */
2548 xscale_send_u32(target, arch_info->dbg_handler_number);
2549
2550 /* read register value */
2551 xscale_read_tx(target, 1);
2552 buf_cpy(xscale->reg_cache->reg_list[XSCALE_TX].value, reg->value, 32);
2553
2554 reg->dirty = 0;
2555 reg->valid = 1;
2556 }
2557
2558 return ERROR_OK;
2559 }
2560
2561 int xscale_set_reg(reg_t *reg, u8* buf)
2562 {
2563 xscale_reg_t *arch_info = reg->arch_info;
2564 target_t *target = arch_info->target;
2565 armv4_5_common_t *armv4_5 = target->arch_info;
2566 xscale_common_t *xscale = armv4_5->arch_info;
2567 u32 value = buf_get_u32(buf, 0, 32);
2568
2569 /* DCSR, TX and RX are accessible via JTAG */
2570 if (strcmp(reg->name, "XSCALE_DCSR") == 0)
2571 {
2572 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 0, 32, value);
2573 return xscale_write_dcsr(arch_info->target, -1, -1);
2574 }
2575 else if (strcmp(reg->name, "XSCALE_RX") == 0)
2576 {
2577 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_RX].value, 0, 32, value);
2578 return xscale_write_rx(arch_info->target);
2579 }
2580 else if (strcmp(reg->name, "XSCALE_TX") == 0)
2581 {
2582 /* can't write to TX register (debug-handler -> host) */
2583 return ERROR_OK;
2584 }
2585 else if (strcmp(reg->name, "XSCALE_TXRXCTRL") == 0)
2586 {
2587 /* can't (explicitly) write to TXRXCTRL register */
2588 return ERROR_OK;
2589 }
2590 else /* Other DBG registers have to be transfered by the debug handler */
2591 {
2592 /* send CP write request (command 0x41) */
2593 xscale_send_u32(target, 0x41);
2594
2595 /* send CP register number */
2596 xscale_send_u32(target, arch_info->dbg_handler_number);
2597
2598 /* send CP register value */
2599 xscale_send_u32(target, value);
2600 buf_set_u32(reg->value, 0, 32, value);
2601 }
2602
2603 return ERROR_OK;
2604 }
2605
2606 /* convenience wrapper to access XScale specific registers */
2607 int xscale_set_reg_u32(reg_t *reg, u32 value)
2608 {
2609 u8 buf[4];
2610
2611 buf_set_u32(buf, 0, 32, value);
2612
2613 return xscale_set_reg(reg, buf);
2614 }
2615
2616 int xscale_write_dcsr_sw(target_t *target, u32 value)
2617 {
2618 /* get pointers to arch-specific information */
2619 armv4_5_common_t *armv4_5 = target->arch_info;
2620 xscale_common_t *xscale = armv4_5->arch_info;
2621 reg_t *dcsr = &xscale->reg_cache->reg_list[XSCALE_DCSR];
2622 xscale_reg_t *dcsr_arch_info = dcsr->arch_info;
2623
2624 /* send CP write request (command 0x41) */
2625 xscale_send_u32(target, 0x41);
2626
2627 /* send CP register number */
2628 xscale_send_u32(target, dcsr_arch_info->dbg_handler_number);
2629
2630 /* send CP register value */
2631 xscale_send_u32(target, value);
2632 buf_set_u32(dcsr->value, 0, 32, value);
2633
2634 return ERROR_OK;
2635 }
2636
2637 int xscale_read_trace(target_t *target)
2638 {
2639 /* get pointers to arch-specific information */
2640 armv4_5_common_t *armv4_5 = target->arch_info;
2641 xscale_common_t *xscale = armv4_5->arch_info;
2642 xscale_trace_data_t **trace_data_p;
2643
2644 /* 258 words from debug handler
2645 * 256 trace buffer entries
2646 * 2 checkpoint addresses
2647 */
2648 u32 trace_buffer[258];
2649 int is_address[256];
2650 int i, j;
2651
2652 if (target->state != TARGET_HALTED)
2653 {
2654 WARNING("target must be stopped to read trace data");
2655 return ERROR_TARGET_NOT_HALTED;
2656 }
2657
2658 /* send read trace buffer command (command 0x61) */
2659 xscale_send_u32(target, 0x61);
2660
2661 /* receive trace buffer content */
2662 xscale_receive(target, trace_buffer, 258);
2663
2664 /* parse buffer backwards to identify address entries */
2665 for (i = 255; i >= 0; i--)
2666 {
2667 is_address[i] = 0;
2668 if (((trace_buffer[i] & 0xf0) == 0x90) ||
2669 ((trace_buffer[i] & 0xf0) == 0xd0))
2670 {
2671 if (i >= 3)
2672 is_address[--i] = 1;
2673 if (i >= 2)
2674 is_address[--i] = 1;
2675 if (i >= 1)
2676 is_address[--i] = 1;
2677 if (i >= 0)
2678 is_address[--i] = 1;
2679 }
2680 }
2681
2682
2683 /* search first non-zero entry */
2684 for (j = 0; (j < 256) && (trace_buffer[j] == 0) && (!is_address[j]); j++)
2685 ;
2686
2687 if (j == 256)
2688 {
2689 DEBUG("no trace data collected");
2690 return ERROR_XSCALE_NO_TRACE_DATA;
2691 }
2692
2693 for (trace_data_p = &xscale->trace.data; *trace_data_p; trace_data_p = &(*trace_data_p)->next)
2694 ;
2695
2696 *trace_data_p = malloc(sizeof(xscale_trace_data_t));
2697 (*trace_data_p)->next = NULL;
2698 (*trace_data_p)->chkpt0 = trace_buffer[256];
2699 (*trace_data_p)->chkpt1 = trace_buffer[257];
2700 (*trace_data_p)->last_instruction = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
2701 (*trace_data_p)->entries = malloc(sizeof(xscale_trace_entry_t) * (256 - j));
2702 (*trace_data_p)->depth = 256 - j;
2703
2704 for (i = j; i < 256; i++)
2705 {
2706 (*trace_data_p)->entries[i - j].data = trace_buffer[i];
2707 if (is_address[i])
2708 (*trace_data_p)->entries[i - j].type = XSCALE_TRACE_ADDRESS;
2709 else
2710 (*trace_data_p)->entries[i - j].type = XSCALE_TRACE_MESSAGE;
2711 }
2712
2713 return ERROR_OK;
2714 }
2715
2716 int xscale_read_instruction(target_t *target, arm_instruction_t *instruction)
2717 {
2718 /* get pointers to arch-specific information */
2719 armv4_5_common_t *armv4_5 = target->arch_info;
2720 xscale_common_t *xscale = armv4_5->arch_info;
2721 int i;
2722 int section = -1;
2723 u32 size_read;
2724 u32 opcode;
2725 int retval;
2726
2727 if (!xscale->trace.image)
2728 return ERROR_TRACE_IMAGE_UNAVAILABLE;
2729
2730 /* search for the section the current instruction belongs to */
2731 for (i = 0; i < xscale->trace.image->num_sections; i++)
2732 {
2733 if ((xscale->trace.image->sections[i].base_address <= xscale->trace.current_pc) &&
2734 (xscale->trace.image->sections[i].base_address + xscale->trace.image->sections[i].size > xscale->trace.current_pc))
2735 {
2736 section = i;
2737 break;
2738 }
2739 }
2740
2741 if (section == -1)
2742 {
2743 /* current instruction couldn't be found in the image */
2744 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
2745 }
2746
2747 if (xscale->trace.core_state == ARMV4_5_STATE_ARM)
2748 {
2749 u8 buf[4];
2750 if ((retval = image_read_section(xscale->trace.image, section,
2751 xscale->trace.current_pc - xscale->trace.image->sections[section].base_address,
2752 4, buf, &size_read)) != ERROR_OK)
2753 {
2754 ERROR("error while reading instruction: %i", retval);
2755 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
2756 }
2757 opcode = target_buffer_get_u32(target, buf);
2758 arm_evaluate_opcode(opcode, xscale->trace.current_pc, instruction);
2759 }
2760 else if (xscale->trace.core_state == ARMV4_5_STATE_THUMB)
2761 {
2762 u8 buf[2];
2763 if ((retval = image_read_section(xscale->trace.image, section,
2764 xscale->trace.current_pc - xscale->trace.image->sections[section].base_address,
2765 2, buf, &size_read)) != ERROR_OK)
2766 {
2767 ERROR("error while reading instruction: %i", retval);
2768 return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
2769 }
2770 opcode = target_buffer_get_u16(target, buf);
2771 thumb_evaluate_opcode(opcode, xscale->trace.current_pc, instruction);
2772 }
2773 else
2774 {
2775 ERROR("BUG: unknown core state encountered");
2776 exit(-1);
2777 }
2778
2779 return ERROR_OK;
2780 }
2781
2782 int xscale_branch_address(xscale_trace_data_t *trace_data, int i, u32 *target)
2783 {
2784 /* if there are less than four entries prior to the indirect branch message
2785 * we can't extract the address */
2786 if (i < 4)
2787 {
2788 return -1;
2789 }
2790
2791 *target = (trace_data->entries[i-1].data) | (trace_data->entries[i-2].data << 8) |
2792 (trace_data->entries[i-3].data << 16) | (trace_data->entries[i-4].data << 24);
2793
2794 return 0;
2795 }
2796
2797 int xscale_analyze_trace(target_t *target, command_context_t *cmd_ctx)
2798 {
2799 /* get pointers to arch-specific information */
2800 armv4_5_common_t *armv4_5 = target->arch_info;
2801 xscale_common_t *xscale = armv4_5->arch_info;
2802 int next_pc_ok = 0;
2803 u32 next_pc = 0x0;
2804 xscale_trace_data_t *trace_data = xscale->trace.data;
2805 int retval;
2806
2807 while (trace_data)
2808 {
2809 int i, chkpt;
2810 int rollover;
2811 int branch;
2812 int exception;
2813 xscale->trace.core_state = ARMV4_5_STATE_ARM;
2814
2815 chkpt = 0;
2816 rollover = 0;
2817
2818 for (i = 0; i < trace_data->depth; i++)
2819 {
2820 next_pc_ok = 0;
2821 branch = 0;
2822 exception = 0;
2823
2824 if (trace_data->entries[i].type == XSCALE_TRACE_ADDRESS)
2825 continue;
2826
2827 switch ((trace_data->entries[i].data & 0xf0) >> 4)
2828 {
2829 case 0: /* Exceptions */
2830 case 1:
2831 case 2:
2832 case 3:
2833 case 4:
2834 case 5:
2835 case 6:
2836 case 7:
2837 exception = (trace_data->entries[i].data & 0x70) >> 4;
2838 next_pc_ok = 1;
2839 next_pc = (trace_data->entries[i].data & 0xf0) >> 2;
2840 command_print(cmd_ctx, "--- exception %i ---", (trace_data->entries[i].data & 0xf0) >> 4);
2841 break;
2842 case 8: /* Direct Branch */
2843 branch = 1;
2844 break;
2845 case 9: /* Indirect Branch */
2846 branch = 1;
2847 if (xscale_branch_address(trace_data, i, &next_pc) == 0)
2848 {
2849 next_pc_ok = 1;
2850 }
2851 break;
2852 case 13: /* Checkpointed Indirect Branch */
2853 if (xscale_branch_address(trace_data, i, &next_pc) == 0)
2854 {
2855 next_pc_ok = 1;
2856 if (((chkpt == 0) && (next_pc != trace_data->chkpt0))
2857 || ((chkpt == 1) && (next_pc != trace_data->chkpt1)))
2858 WARNING("checkpointed indirect branch target address doesn't match checkpoint");
2859 }
2860 /* explicit fall-through */
2861 case 12: /* Checkpointed Direct Branch */
2862 branch = 1;
2863 if (chkpt == 0)
2864 {
2865 next_pc_ok = 1;
2866 next_pc = trace_data->chkpt0;
2867 chkpt++;
2868 }
2869 else if (chkpt == 1)
2870 {
2871 next_pc_ok = 1;
2872 next_pc = trace_data->chkpt0;
2873 chkpt++;
2874 }
2875 else
2876 {
2877 WARNING("more than two checkpointed branches encountered");
2878 }
2879 break;
2880 case 15: /* Roll-over */
2881 rollover++;
2882 continue;
2883 default: /* Reserved */
2884 command_print(cmd_ctx, "--- reserved trace message ---");
2885 ERROR("BUG: trace message %i is reserved", (trace_data->entries[i].data & 0xf0) >> 4);
2886 return ERROR_OK;
2887 }
2888
2889 if (xscale->trace.pc_ok)
2890 {
2891 int executed = (trace_data->entries[i].data & 0xf) + rollover * 16;
2892 arm_instruction_t instruction;
2893
2894 if ((exception == 6) || (exception == 7))
2895 {
2896 /* IRQ or FIQ exception, no instruction executed */
2897 executed -= 1;
2898 }
2899
2900 while (executed-- >= 0)
2901 {
2902 if ((retval = xscale_read_instruction(target, &instruction)) != ERROR_OK)
2903 {
2904 /* can't continue tracing with no image available */
2905 if (retval == ERROR_TRACE_IMAGE_UNAVAILABLE)
2906 {
2907 return retval;
2908 }
2909 else if (retval == ERROR_TRACE_INSTRUCTION_UNAVAILABLE)
2910 {
2911 /* TODO: handle incomplete images */
2912 }
2913 }
2914
2915 /* a precise abort on a load to the PC is included in the incremental
2916 * word count, other instructions causing data aborts are not included
2917 */
2918 if ((executed == 0) && (exception == 4)
2919 && ((instruction.type >= ARM_LDR) && (instruction.type <= ARM_LDM)))
2920 {
2921 if ((instruction.type == ARM_LDM)
2922 && ((instruction.info.load_store_multiple.register_list & 0x8000) == 0))
2923 {
2924 executed--;
2925 }
2926 else if (((instruction.type >= ARM_LDR) && (instruction.type <= ARM_LDRSH))
2927 && (instruction.info.load_store.Rd != 15))
2928 {
2929 executed--;
2930 }
2931 }
2932
2933 /* only the last instruction executed
2934 * (the one that caused the control flow change)
2935 * could be a taken branch
2936 */
2937 if (((executed == -1) && (branch == 1)) &&
2938 (((instruction.type == ARM_B) ||
2939 (instruction.type == ARM_BL) ||
2940 (instruction.type == ARM_BLX)) &&
2941 (instruction.info.b_bl_bx_blx.target_address != -1)))
2942 {
2943 xscale->trace.current_pc = instruction.info.b_bl_bx_blx.target_address;
2944 }
2945 else
2946 {
2947 xscale->trace.current_pc += (xscale->trace.core_state == ARMV4_5_STATE_ARM) ? 4 : 2;
2948 }
2949 command_print(cmd_ctx, "%s", instruction.text);
2950 }
2951
2952 rollover = 0;
2953 }
2954
2955 if (next_pc_ok)
2956 {
2957 xscale->trace.current_pc = next_pc;
2958 xscale->trace.pc_ok = 1;
2959 }
2960 }
2961
2962 for (; xscale->trace.current_pc < trace_data->last_instruction; xscale->trace.current_pc += (xscale->trace.core_state == ARMV4_5_STATE_ARM) ? 4 : 2)
2963 {
2964 arm_instruction_t instruction;
2965 if ((retval = xscale_read_instruction(target, &instruction)) != ERROR_OK)
2966 {
2967 /* can't continue tracing with no image available */
2968 if (retval == ERROR_TRACE_IMAGE_UNAVAILABLE)
2969 {
2970 return retval;
2971 }
2972 else if (retval == ERROR_TRACE_INSTRUCTION_UNAVAILABLE)
2973 {
2974 /* TODO: handle incomplete images */
2975 }
2976 }
2977 command_print(cmd_ctx, "%s", instruction.text);
2978 }
2979
2980 trace_data = trace_data->next;
2981 }
2982
2983 return ERROR_OK;
2984 }
2985
2986 void xscale_build_reg_cache(target_t *target)
2987 {
2988 /* get pointers to arch-specific information */
2989 armv4_5_common_t *armv4_5 = target->arch_info;
2990 xscale_common_t *xscale = armv4_5->arch_info;
2991
2992 reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
2993 xscale_reg_t *arch_info = malloc(sizeof(xscale_reg_arch_info));
2994 int i;
2995 int num_regs = sizeof(xscale_reg_arch_info) / sizeof(xscale_reg_t);
2996
2997 (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
2998 armv4_5->core_cache = (*cache_p);
2999
3000 /* register a register arch-type for XScale dbg registers only once */
3001 if (xscale_reg_arch_type == -1)
3002 xscale_reg_arch_type = register_reg_arch_type(xscale_get_reg, xscale_set_reg);
3003
3004 (*cache_p)->next = malloc(sizeof(reg_cache_t));
3005 cache_p = &(*cache_p)->next;
3006
3007 /* fill in values for the xscale reg cache */
3008 (*cache_p)->name = "XScale registers";
3009 (*cache_p)->next = NULL;
3010 (*cache_p)->reg_list = malloc(num_regs * sizeof(reg_t));
3011 (*cache_p)->num_regs = num_regs;
3012
3013 for (i = 0; i < num_regs; i++)
3014 {
3015 (*cache_p)->reg_list[i].name = xscale_reg_list[i];
3016 (*cache_p)->reg_list[i].value = calloc(4, 1);
3017 (*cache_p)->reg_list[i].dirty = 0;
3018 (*cache_p)->reg_list[i].valid = 0;
3019 (*cache_p)->reg_list[i].size = 32;
3020 (*cache_p)->reg_list[i].bitfield_desc = NULL;
3021 (*cache_p)->reg_list[i].num_bitfields = 0;
3022 (*cache_p)->reg_list[i].arch_info = &arch_info[i];
3023 (*cache_p)->reg_list[i].arch_type = xscale_reg_arch_type;
3024 arch_info[i] = xscale_reg_arch_info[i];
3025 arch_info[i].target = target;
3026 }
3027
3028 xscale->reg_cache = (*cache_p);
3029 }
3030
3031 int xscale_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
3032 {
3033 return ERROR_OK;
3034 }
3035
3036 int xscale_quit()
3037 {
3038
3039 return ERROR_OK;
3040 }
3041
3042 int xscale_init_arch_info(target_t *target, xscale_common_t *xscale, int chain_pos, char *variant)
3043 {
3044 armv4_5_common_t *armv4_5;
3045 u32 high_reset_branch, low_reset_branch;
3046 int i;
3047
3048 armv4_5 = &xscale->armv4_5_common;
3049
3050 /* store architecture specfic data (none so far) */
3051 xscale->arch_info = NULL;
3052 xscale->common_magic = XSCALE_COMMON_MAGIC;
3053
3054 /* remember the variant (PXA25x, PXA27x, IXP42x, ...) */
3055 xscale->variant = strdup(variant);
3056
3057 /* prepare JTAG information for the new target */
3058 xscale->jtag_info.chain_pos = chain_pos;
3059
3060 xscale->jtag_info.dbgrx = 0x02;
3061 xscale->jtag_info.dbgtx = 0x10;
3062 xscale->jtag_info.dcsr = 0x09;
3063 xscale->jtag_info.ldic = 0x07;
3064
3065 if ((strcmp(xscale->variant, "pxa250") == 0) ||
3066 (strcmp(xscale->variant, "pxa255") == 0) ||
3067 (strcmp(xscale->variant, "pxa26x") == 0))
3068 {
3069 xscale->jtag_info.ir_length = 5;
3070 }
3071 else if ((strcmp(xscale->variant, "pxa27x") == 0) ||
3072 (strcmp(xscale->variant, "ixp42x") == 0) ||
3073 (strcmp(xscale->variant, "ixp45x") == 0) ||
3074 (strcmp(xscale->variant, "ixp46x") == 0))
3075 {
3076 xscale->jtag_info.ir_length = 7;
3077 }
3078
3079 /* the debug handler isn't installed (and thus not running) at this time */
3080 xscale->handler_installed = 0;
3081 xscale->handler_running = 0;
3082 xscale->handler_address = 0xfe000800;
3083
3084 /* clear the vectors we keep locally for reference */
3085 memset(xscale->low_vectors, 0, sizeof(xscale->low_vectors));
3086 memset(xscale->high_vectors, 0, sizeof(xscale->high_vectors));
3087
3088 /* no user-specified vectors have been configured yet */
3089 xscale->static_low_vectors_set = 0x0;
3090 xscale->static_high_vectors_set = 0x0;
3091
3092 /* calculate branches to debug handler */
3093 low_reset_branch = (xscale->handler_address + 0x20 - 0x0 - 0x8) >> 2;
3094 high_reset_branch = (xscale->handler_address + 0x20 - 0xffff0000 - 0x8) >> 2;
3095
3096 xscale->low_vectors[0] = ARMV4_5_B((low_reset_branch & 0xffffff), 0);
3097 xscale->high_vectors[0] = ARMV4_5_B((high_reset_branch & 0xffffff), 0);
3098
3099 for (i = 1; i <= 7; i++)
3100 {
3101 xscale->low_vectors[i] = ARMV4_5_B(0xfffffe, 0);
3102 xscale->high_vectors[i] = ARMV4_5_B(0xfffffe, 0);
3103 }
3104
3105 /* 64kB aligned region used for DCache cleaning */
3106 xscale->cache_clean_address = 0xfffe0000;
3107
3108 xscale->hold_rst = 0;
3109 xscale->external_debug_break = 0;
3110
3111 xscale->force_hw_bkpts = 1;
3112
3113 xscale->ibcr_available = 2;
3114 xscale->ibcr0_used = 0;
3115 xscale->ibcr1_used = 0;
3116
3117 xscale->dbr_available = 2;
3118 xscale->dbr0_used = 0;
3119 xscale->dbr1_used = 0;
3120
3121 xscale->arm_bkpt = ARMV5_BKPT(0x0);
3122 xscale->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
3123
3124 xscale->vector_catch = 0x1;
3125
3126 xscale->trace.capture_status = TRACE_IDLE;
3127 xscale->trace.data = NULL;
3128 xscale->trace.image = NULL;
3129 xscale->trace.buffer_enabled = 0;
3130 xscale->trace.buffer_fill = 0;
3131
3132 /* prepare ARMv4/5 specific information */
3133 armv4_5->arch_info = xscale;
3134 armv4_5->read_core_reg = xscale_read_core_reg;
3135 armv4_5->write_core_reg = xscale_write_core_reg;
3136 armv4_5->full_context = xscale_full_context;
3137
3138 armv4_5_init_arch_info(target, armv4_5);
3139
3140 xscale->armv4_5_mmu.armv4_5_cache.ctype = -1;
3141 xscale->armv4_5_mmu.get_ttb = xscale_get_ttb;
3142 xscale->armv4_5_mmu.read_memory = xscale_read_memory;
3143 xscale->armv4_5_mmu.write_memory = xscale_write_memory;
3144 xscale->armv4_5_mmu.disable_mmu_caches = xscale_disable_mmu_caches;
3145 xscale->armv4_5_mmu.enable_mmu_caches = xscale_enable_mmu_caches;
3146 xscale->armv4_5_mmu.has_tiny_pages = 1;
3147 xscale->armv4_5_mmu.mmu_enabled = 0;
3148
3149 xscale->fast_memory_access = 0;
3150
3151 return ERROR_OK;
3152 }
3153
3154 /* target xscale <endianess> <startup_mode> <chain_pos> <variant> */
3155 int xscale_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
3156 {
3157 int chain_pos;
3158 char *variant = NULL;
3159 xscale_common_t *xscale = malloc(sizeof(xscale_common_t));
3160 memset(xscale, 0, sizeof(*xscale));
3161
3162 if (argc < 5)
3163 {
3164 ERROR("'target xscale' requires four arguments: <endianess> <startup_mode> <chain_pos> <variant>");
3165 return ERROR_OK;
3166 }
3167
3168 chain_pos = strtoul(args[3], NULL, 0);
3169
3170 variant = args[4];
3171
3172 xscale_init_arch_info(target, xscale, chain_pos, variant);
3173 xscale_build_reg_cache(target);
3174
3175 return ERROR_OK;
3176 }
3177
3178 int xscale_handle_debug_handler_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3179 {
3180 target_t *target = NULL;
3181 armv4_5_common_t *armv4_5;
3182 xscale_common_t *xscale;
3183
3184 u32 handler_address;
3185
3186 if (argc < 2)
3187 {
3188 ERROR("'xscale debug_handler <target#> <address>' command takes two required operands");
3189 return ERROR_OK;
3190 }
3191
3192 if ((target = get_target_by_num(strtoul(args[0], NULL, 0))) == NULL)
3193 {
3194 ERROR("no target '%s' configured", args[0]);
3195 return ERROR_OK;
3196 }
3197
3198 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3199 {
3200 return ERROR_OK;
3201 }
3202
3203 handler_address = strtoul(args[1], NULL, 0);
3204
3205 if (((handler_address >= 0x800) && (handler_address <= 0x1fef800)) ||
3206 ((handler_address >= 0xfe000800) && (handler_address <= 0xfffff800)))
3207 {
3208 xscale->handler_address = handler_address;
3209 }
3210 else
3211 {
3212 ERROR("xscale debug_handler <address> must be between 0x800 and 0x1fef800 or between 0xfe000800 and 0xfffff800");
3213 }
3214
3215 return ERROR_OK;
3216 }
3217
3218 int xscale_handle_cache_clean_address_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3219 {
3220 target_t *target = NULL;
3221 armv4_5_common_t *armv4_5;
3222 xscale_common_t *xscale;
3223
3224 u32 cache_clean_address;
3225
3226 if (argc < 2)
3227 {
3228 ERROR("'xscale cache_clean_address <target#> <address>' command takes two required operands");
3229 return ERROR_OK;
3230 }
3231
3232 if ((target = get_target_by_num(strtoul(args[0], NULL, 0))) == NULL)
3233 {
3234 ERROR("no target '%s' configured", args[0]);
3235 return ERROR_OK;
3236 }
3237
3238 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3239 {
3240 return ERROR_OK;
3241 }
3242
3243 cache_clean_address = strtoul(args[1], NULL, 0);
3244
3245 if (cache_clean_address & 0xffff)
3246 {
3247 ERROR("xscale cache_clean_address <address> must be 64kb aligned");
3248 }
3249 else
3250 {
3251 xscale->cache_clean_address = cache_clean_address;
3252 }
3253
3254 return ERROR_OK;
3255 }
3256
3257 int xscale_handle_cache_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3258 {
3259 target_t *target = get_current_target(cmd_ctx);
3260 armv4_5_common_t *armv4_5;
3261 xscale_common_t *xscale;
3262
3263 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3264 {
3265 return ERROR_OK;
3266 }
3267
3268 return armv4_5_handle_cache_info_command(cmd_ctx, &xscale->armv4_5_mmu.armv4_5_cache);
3269 }
3270
3271 static int xscale_virt2phys(struct target_s *target, u32 virtual, u32 *physical)
3272 {
3273 armv4_5_common_t *armv4_5;
3274 xscale_common_t *xscale;
3275 int retval;
3276 int type;
3277 u32 cb;
3278 int domain;
3279 u32 ap;
3280
3281
3282 if ((retval = xscale_get_arch_pointers(target, &armv4_5, &xscale)) != ERROR_OK)
3283 {
3284 return retval;
3285 }
3286 u32 ret = armv4_5_mmu_translate_va(target, &xscale->armv4_5_mmu, virtual, &type, &cb, &domain, &ap);
3287 if (type == -1)
3288 {
3289 return ret;
3290 }
3291 *physical = ret;
3292 return ERROR_OK;
3293 }
3294
3295 static int xscale_mmu(struct target_s *target, int *enabled)
3296 {
3297 armv4_5_common_t *armv4_5 = target->arch_info;
3298 xscale_common_t *xscale = armv4_5->arch_info;
3299
3300 if (target->state != TARGET_HALTED)
3301 {
3302 ERROR("Target not halted");
3303 return ERROR_TARGET_INVALID;
3304 }
3305 *enabled = xscale->armv4_5_mmu.mmu_enabled;
3306 return ERROR_OK;
3307 }
3308
3309
3310 int xscale_handle_mmu_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
3311 {
3312 target_t *target = get_current_target(cmd_ctx);
3313 armv4_5_common_t *armv4_5;
3314 xscale_common_t *xscale;
3315
3316 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3317 {
3318 return ERROR_OK;
3319 }
3320
3321 if (target->state != TARGET_HALTED)
3322 {
3323 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3324 return ERROR_OK;
3325 }
3326
3327 if (argc >= 1)
3328 {
3329 if (strcmp("enable", args[0]) == 0)
3330 {
3331 xscale_enable_mmu_caches(target, 1, 0, 0);
3332 xscale->armv4_5_mmu.mmu_enabled = 1;
3333 }
3334 else if (strcmp("disable", args[0]) == 0)
3335 {
3336 xscale_disable_mmu_caches(target, 1, 0, 0);
3337 xscale->armv4_5_mmu.mmu_enabled = 0;
3338 }
3339 }
3340
3341 command_print(cmd_ctx, "mmu %s", (xscale->armv4_5_mmu.mmu_enabled) ? "enabled" : "disabled");
3342
3343 return ERROR_OK;
3344 }
3345
3346 int xscale_handle_idcache_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
3347 {
3348 target_t *target = get_current_target(cmd_ctx);
3349 armv4_5_common_t *armv4_5;
3350 xscale_common_t *xscale;
3351 int icache = 0, dcache = 0;
3352
3353 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3354 {
3355 return ERROR_OK;
3356 }
3357
3358 if (target->state != TARGET_HALTED)
3359 {
3360 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3361 return ERROR_OK;
3362 }
3363
3364 if (strcmp(cmd, "icache") == 0)
3365 icache = 1;
3366 else if (strcmp(cmd, "dcache") == 0)
3367 dcache = 1;
3368
3369 if (argc >= 1)
3370 {
3371 if (strcmp("enable", args[0]) == 0)
3372 {
3373 xscale_enable_mmu_caches(target, 0, dcache, icache);
3374
3375 if (icache)
3376 xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 1;
3377 else if (dcache)
3378 xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 1;
3379 }
3380 else if (strcmp("disable", args[0]) == 0)
3381 {
3382 xscale_disable_mmu_caches(target, 0, dcache, icache);
3383
3384 if (icache)
3385 xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
3386 else if (dcache)
3387 xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
3388 }
3389 }
3390
3391 if (icache)
3392 command_print(cmd_ctx, "icache %s", (xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled) ? "enabled" : "disabled");
3393
3394 if (dcache)
3395 command_print(cmd_ctx, "dcache %s", (xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) ? "enabled" : "disabled");
3396
3397 return ERROR_OK;
3398 }
3399
3400 int xscale_handle_vector_catch_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
3401 {
3402 target_t *target = get_current_target(cmd_ctx);
3403 armv4_5_common_t *armv4_5;
3404 xscale_common_t *xscale;
3405
3406 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3407 {
3408 return ERROR_OK;
3409 }
3410
3411 if (argc < 1)
3412 {
3413 command_print(cmd_ctx, "usage: xscale vector_catch [mask]");
3414 }
3415 else
3416 {
3417 xscale->vector_catch = strtoul(args[0], NULL, 0);
3418 buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 8, xscale->vector_catch);
3419 xscale_write_dcsr(target, -1, -1);
3420 }
3421
3422 command_print(cmd_ctx, "vector catch mask: 0x%2.2x", xscale->vector_catch);
3423
3424 return ERROR_OK;
3425 }
3426
3427 int xscale_handle_force_hw_bkpts_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3428 {
3429 target_t *target = get_current_target(cmd_ctx);
3430 armv4_5_common_t *armv4_5;
3431 xscale_common_t *xscale;
3432
3433 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3434 {
3435 return ERROR_OK;
3436 }
3437
3438 if ((argc >= 1) && (strcmp("enable", args[0]) == 0))
3439 {
3440 xscale->force_hw_bkpts = 1;
3441 }
3442 else if ((argc >= 1) && (strcmp("disable", args[0]) == 0))
3443 {
3444 xscale->force_hw_bkpts = 0;
3445 }
3446 else
3447 {
3448 command_print(cmd_ctx, "usage: xscale force_hw_bkpts <enable|disable>");
3449 }
3450
3451 command_print(cmd_ctx, "force hardware breakpoints %s", (xscale->force_hw_bkpts) ? "enabled" : "disabled");
3452
3453 return ERROR_OK;
3454 }
3455
3456 int xscale_handle_trace_buffer_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3457 {
3458 target_t *target = get_current_target(cmd_ctx);
3459 armv4_5_common_t *armv4_5;
3460 xscale_common_t *xscale;
3461 u32 dcsr_value;
3462
3463 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3464 {
3465 return ERROR_OK;
3466 }
3467
3468 if (target->state != TARGET_HALTED)
3469 {
3470 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3471 return ERROR_OK;
3472 }
3473
3474 if ((argc >= 1) && (strcmp("enable", args[0]) == 0))
3475 {
3476 xscale_trace_data_t *td, *next_td;
3477 xscale->trace.buffer_enabled = 1;
3478
3479 /* free old trace data */
3480 td = xscale->trace.data;
3481 while (td)
3482 {
3483 next_td = td->next;
3484
3485 if (td->entries)
3486 free(td->entries);
3487 free(td);
3488 td = next_td;
3489 }
3490 xscale->trace.data = NULL;
3491 }
3492 else if ((argc >= 1) && (strcmp("disable", args[0]) == 0))
3493 {
3494 xscale->trace.buffer_enabled = 0;
3495 }
3496
3497 if ((argc >= 2) && (strcmp("fill", args[1]) == 0))
3498 {
3499 if (argc >= 3)
3500 xscale->trace.buffer_fill = strtoul(args[2], NULL, 0);
3501 else
3502 xscale->trace.buffer_fill = 1;
3503 }
3504 else if ((argc >= 2) && (strcmp("wrap", args[1]) == 0))
3505 {
3506 xscale->trace.buffer_fill = -1;
3507 }
3508
3509 if (xscale->trace.buffer_enabled)
3510 {
3511 /* if we enable the trace buffer in fill-once
3512 * mode we know the address of the first instruction */
3513 xscale->trace.pc_ok = 1;
3514 xscale->trace.current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
3515 }
3516 else
3517 {
3518 /* otherwise the address is unknown, and we have no known good PC */
3519 xscale->trace.pc_ok = 0;
3520 }
3521
3522 command_print(cmd_ctx, "trace buffer %s (%s)",
3523 (xscale->trace.buffer_enabled) ? "enabled" : "disabled",
3524 (xscale->trace.buffer_fill > 0) ? "fill" : "wrap");
3525
3526 dcsr_value = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 0, 32);
3527 if (xscale->trace.buffer_fill >= 0)
3528 xscale_write_dcsr_sw(target, (dcsr_value & 0xfffffffc) | 2);
3529 else
3530 xscale_write_dcsr_sw(target, dcsr_value & 0xfffffffc);
3531
3532 return ERROR_OK;
3533 }
3534
3535 int xscale_handle_trace_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3536 {
3537 target_t *target;
3538 armv4_5_common_t *armv4_5;
3539 xscale_common_t *xscale;
3540
3541 if (argc < 1)
3542 {
3543 command_print(cmd_ctx, "usage: xscale trace_image <file> [base address] [type]");
3544 return ERROR_OK;
3545 }
3546
3547 target = get_current_target(cmd_ctx);
3548
3549 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3550 {
3551 return ERROR_OK;
3552 }
3553
3554 if (xscale->trace.image)
3555 {
3556 image_close(xscale->trace.image);
3557 free(xscale->trace.image);
3558 command_print(cmd_ctx, "previously loaded image found and closed");
3559 }
3560
3561 xscale->trace.image = malloc(sizeof(image_t));
3562 xscale->trace.image->base_address_set = 0;
3563 xscale->trace.image->start_address_set = 0;
3564
3565 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
3566 if (argc >= 2)
3567 {
3568 xscale->trace.image->base_address_set = 1;
3569 xscale->trace.image->base_address = strtoul(args[1], NULL, 0);
3570 }
3571 else
3572 {
3573 xscale->trace.image->base_address_set = 0;
3574 }
3575
3576 if (image_open(xscale->trace.image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
3577 {
3578 free(xscale->trace.image);
3579 xscale->trace.image = NULL;
3580 return ERROR_OK;
3581 }
3582
3583 return ERROR_OK;
3584 }
3585
3586 int xscale_handle_dump_trace_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3587 {
3588 target_t *target = get_current_target(cmd_ctx);
3589 armv4_5_common_t *armv4_5;
3590 xscale_common_t *xscale;
3591 xscale_trace_data_t *trace_data;
3592 fileio_t file;
3593
3594 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3595 {
3596 return ERROR_OK;
3597 }
3598
3599 if (target->state != TARGET_HALTED)
3600 {
3601 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3602 return ERROR_OK;
3603 }
3604
3605 if (argc < 1)
3606 {
3607 command_print(cmd_ctx, "usage: xscale dump_trace <file>");
3608 return ERROR_OK;
3609 }
3610
3611 trace_data = xscale->trace.data;
3612
3613 if (!trace_data)
3614 {
3615 command_print(cmd_ctx, "no trace data collected");
3616 return ERROR_OK;
3617 }
3618
3619 if (fileio_open(&file, args[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)
3620 {
3621 return ERROR_OK;
3622 }
3623
3624 while (trace_data)
3625 {
3626 int i;
3627
3628 fileio_write_u32(&file, trace_data->chkpt0);
3629 fileio_write_u32(&file, trace_data->chkpt1);
3630 fileio_write_u32(&file, trace_data->last_instruction);
3631 fileio_write_u32(&file, trace_data->depth);
3632
3633 for (i = 0; i < trace_data->depth; i++)
3634 fileio_write_u32(&file, trace_data->entries[i].data | ((trace_data->entries[i].type & 0xffff) << 16));
3635
3636 trace_data = trace_data->next;
3637 }
3638
3639 fileio_close(&file);
3640
3641 return ERROR_OK;
3642 }
3643
3644 int xscale_handle_analyze_trace_buffer_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3645 {
3646 target_t *target = get_current_target(cmd_ctx);
3647 armv4_5_common_t *armv4_5;
3648 xscale_common_t *xscale;
3649
3650 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3651 {
3652 return ERROR_OK;
3653 }
3654
3655 xscale_analyze_trace(target, cmd_ctx);
3656
3657 return ERROR_OK;
3658 }
3659
3660 int xscale_handle_cp15(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
3661 {
3662 target_t *target = get_current_target(cmd_ctx);
3663 armv4_5_common_t *armv4_5;
3664 xscale_common_t *xscale;
3665
3666 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3667 {
3668 return ERROR_OK;
3669 }
3670
3671 if (target->state != TARGET_HALTED)
3672 {
3673 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
3674 return ERROR_OK;
3675 }
3676 u32 reg_no = 0;
3677 reg_t *reg = NULL;
3678 if(argc > 0)
3679 {
3680 reg_no = strtoul(args[0], NULL, 0);
3681 /*translate from xscale cp15 register no to openocd register*/
3682 switch(reg_no)
3683 {
3684 case 0:
3685 reg_no = XSCALE_MAINID;
3686 break;
3687 case 1:
3688 reg_no = XSCALE_CTRL;
3689 break;
3690 case 2:
3691 reg_no = XSCALE_TTB;
3692 break;
3693 case 3:
3694 reg_no = XSCALE_DAC;
3695 break;
3696 case 5:
3697 reg_no = XSCALE_FSR;
3698 break;
3699 case 6:
3700 reg_no = XSCALE_FAR;
3701 break;
3702 case 13:
3703 reg_no = XSCALE_PID;
3704 break;
3705 case 15:
3706 reg_no = XSCALE_CPACCESS;
3707 break;
3708 default:
3709 command_print(cmd_ctx, "invalid register number");
3710 return ERROR_INVALID_ARGUMENTS;
3711 }
3712 reg = &xscale->reg_cache->reg_list[reg_no];
3713
3714 }
3715 if(argc == 1)
3716 {
3717 u32 value;
3718
3719 /* read cp15 control register */
3720 xscale_get_reg(reg);
3721 value = buf_get_u32(reg->value, 0, 32);
3722 command_print(cmd_ctx, "%s (/%i): 0x%x", reg->name, reg->size, value);
3723 }
3724 else if(argc == 2)
3725 {
3726
3727 u32 value = strtoul(args[1], NULL, 0);
3728
3729 /* send CP write request (command 0x41) */
3730 xscale_send_u32(target, 0x41);
3731
3732 /* send CP register number */
3733 xscale_send_u32(target, reg_no);
3734
3735 /* send CP register value */
3736 xscale_send_u32(target, value);
3737
3738 /* execute cpwait to ensure outstanding operations complete */
3739 xscale_send_u32(target, 0x53);
3740 }
3741 else
3742 {
3743 command_print(cmd_ctx, "usage: cp15 [register]<, [value]>");
3744 }
3745
3746 return ERROR_OK;
3747 }
3748
3749 int handle_xscale_fast_memory_access_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
3750 {
3751 target_t *target = get_current_target(cmd_ctx);
3752 armv4_5_common_t *armv4_5;
3753 xscale_common_t *xscale;
3754
3755 if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
3756 {
3757 return ERROR_OK;
3758 }
3759
3760 if (argc == 1)
3761 {
3762 if (strcmp("enable", args[0]) == 0)
3763 {
3764 xscale->fast_memory_access = 1;
3765 }
3766 else if (strcmp("disable", args[0]) == 0)
3767 {
3768 xscale->fast_memory_access = 0;
3769 }
3770 else
3771 {
3772 return ERROR_COMMAND_SYNTAX_ERROR;
3773 }
3774 } else if (argc!=0)
3775 {
3776 return ERROR_COMMAND_SYNTAX_ERROR;
3777 }
3778
3779 command_print(cmd_ctx, "fast memory access is %s", (xscale->fast_memory_access) ? "enabled" : "disabled");
3780
3781 return ERROR_OK;
3782 }
3783
3784 int xscale_register_commands(struct command_context_s *cmd_ctx)
3785 {
3786 command_t *xscale_cmd;
3787
3788 xscale_cmd = register_command(cmd_ctx, NULL, "xscale", NULL, COMMAND_ANY, "xscale specific commands");
3789
3790 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");
3791 register_command(cmd_ctx, xscale_cmd, "cache_clean_address", xscale_handle_cache_clean_address_command, COMMAND_ANY, NULL);
3792
3793 register_command(cmd_ctx, xscale_cmd, "cache_info", xscale_handle_cache_info_command, COMMAND_EXEC, NULL);
3794 register_command(cmd_ctx, xscale_cmd, "mmu", xscale_handle_mmu_command, COMMAND_EXEC, "['enable'|'disable'] the MMU");
3795 register_command(cmd_ctx, xscale_cmd, "icache", xscale_handle_idcache_command, COMMAND_EXEC, "['enable'|'disable'] the ICache");
3796 register_command(cmd_ctx, xscale_cmd, "dcache", xscale_handle_idcache_command, COMMAND_EXEC, "['enable'|'disable'] the DCache");
3797
3798 register_command(cmd_ctx, xscale_cmd, "vector_catch", xscale_handle_idcache_command, COMMAND_EXEC, "<mask> of vectors that should be catched");
3799
3800 register_command(cmd_ctx, xscale_cmd, "trace_buffer", xscale_handle_trace_buffer_command, COMMAND_EXEC, "<enable|disable> ['fill' [n]|'wrap']");
3801
3802 register_command(cmd_ctx, xscale_cmd, "dump_trace", xscale_handle_dump_trace_command, COMMAND_EXEC, "dump content of trace buffer to <file>");
3803 register_command(cmd_ctx, xscale_cmd, "analyze_trace", xscale_handle_analyze_trace_buffer_command, COMMAND_EXEC, "analyze content of trace buffer");
3804 register_command(cmd_ctx, xscale_cmd, "trace_image", xscale_handle_trace_image_command,
3805 COMMAND_EXEC, "load image from <file> [base address]");
3806
3807 register_command(cmd_ctx, xscale_cmd, "cp15", xscale_handle_cp15, COMMAND_EXEC, "access coproc 15 <register> [value]");
3808 register_command(cmd_ctx, xscale_cmd, "fast_memory_access", handle_xscale_fast_memory_access_command,
3809 COMMAND_ANY, "use fast memory accesses instead of slower but potentially unsafe slow accesses <enable|disable>");
3810
3811
3812 armv4_5_register_commands(cmd_ctx);
3813
3814 return ERROR_OK;
3815 }

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)