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

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)