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

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)