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

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)