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

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)