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

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)