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

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)