reset cleanup
[openocd.git] / src / target / target.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2007,2008 Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
7 * *
8 * Copyright (C) 2008, Duane Ellis *
9 * openocd@duaneeellis.com *
10 * *
11 * Copyright (C) 2008 by Spencer Oliver *
12 * spen@spen-soft.co.uk *
13 * *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
18 * *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program; if not, write to the *
26 * Free Software Foundation, Inc., *
27 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
28 ***************************************************************************/
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include "replacements.h"
34 #include "target.h"
35 #include "target_request.h"
36
37 #include "log.h"
38 #include "configuration.h"
39 #include "binarybuffer.h"
40 #include "jtag.h"
41
42 #include <string.h>
43 #include <stdlib.h>
44 #include <inttypes.h>
45
46 #include <sys/types.h>
47 #include <sys/stat.h>
48 #include <unistd.h>
49 #include <errno.h>
50
51 #include <sys/time.h>
52 #include <time.h>
53
54 #include <time_support.h>
55
56 #include <fileio.h>
57 #include <image.h>
58
59 int cli_target_callback_event_handler(struct target_s *target, enum target_event event, void *priv);
60
61
62 int handle_targets_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
63
64 int handle_working_area_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
65
66 int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
67 int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
68 int handle_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
69 int handle_wait_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
70 int handle_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
71 int handle_soft_reset_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
72 int handle_resume_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
73 int handle_step_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
74 int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
75 int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
76 int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
77 int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
78 int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
79 int handle_bp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
80 int handle_rbp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
81 int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
82 int handle_rwp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
83 int handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc);
84 int handle_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
85 static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
86 static int jim_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
87 static int jim_target( Jim_Interp *interp, int argc, Jim_Obj *const *argv);
88
89 static int target_array2mem(Jim_Interp *interp, target_t *target, int argc, Jim_Obj *const *argv);
90 static int target_mem2array(Jim_Interp *interp, target_t *target, int argc, Jim_Obj *const *argv);
91
92
93
94 /* targets */
95 extern target_type_t arm7tdmi_target;
96 extern target_type_t arm720t_target;
97 extern target_type_t arm9tdmi_target;
98 extern target_type_t arm920t_target;
99 extern target_type_t arm966e_target;
100 extern target_type_t arm926ejs_target;
101 extern target_type_t feroceon_target;
102 extern target_type_t xscale_target;
103 extern target_type_t cortexm3_target;
104 extern target_type_t arm11_target;
105 extern target_type_t mips_m4k_target;
106
107 target_type_t *target_types[] =
108 {
109 &arm7tdmi_target,
110 &arm9tdmi_target,
111 &arm920t_target,
112 &arm720t_target,
113 &arm966e_target,
114 &arm926ejs_target,
115 &feroceon_target,
116 &xscale_target,
117 &cortexm3_target,
118 &arm11_target,
119 &mips_m4k_target,
120 NULL,
121 };
122
123 target_t *all_targets = NULL;
124 target_event_callback_t *target_event_callbacks = NULL;
125 target_timer_callback_t *target_timer_callbacks = NULL;
126
127 const Jim_Nvp nvp_assert[] = {
128 { .name = "assert", NVP_ASSERT },
129 { .name = "deassert", NVP_DEASSERT },
130 { .name = "T", NVP_ASSERT },
131 { .name = "F", NVP_DEASSERT },
132 { .name = "t", NVP_ASSERT },
133 { .name = "f", NVP_DEASSERT },
134 { .name = NULL, .value = -1 }
135 };
136
137 const Jim_Nvp nvp_error_target[] = {
138 { .value = ERROR_TARGET_INVALID, .name = "err-invalid" },
139 { .value = ERROR_TARGET_INIT_FAILED, .name = "err-init-failed" },
140 { .value = ERROR_TARGET_TIMEOUT, .name = "err-timeout" },
141 { .value = ERROR_TARGET_NOT_HALTED, .name = "err-not-halted" },
142 { .value = ERROR_TARGET_FAILURE, .name = "err-failure" },
143 { .value = ERROR_TARGET_UNALIGNED_ACCESS , .name = "err-unaligned-access" },
144 { .value = ERROR_TARGET_DATA_ABORT , .name = "err-data-abort" },
145 { .value = ERROR_TARGET_RESOURCE_NOT_AVAILABLE , .name = "err-resource-not-available" },
146 { .value = ERROR_TARGET_TRANSLATION_FAULT , .name = "err-translation-fault" },
147 { .value = ERROR_TARGET_NOT_RUNNING, .name = "err-not-running" },
148 { .value = ERROR_TARGET_NOT_EXAMINED, .name = "err-not-examined" },
149 { .value = -1, .name = NULL }
150 };
151
152 const char *target_strerror_safe( int err )
153 {
154 const Jim_Nvp *n;
155
156 n = Jim_Nvp_value2name_simple( nvp_error_target, err );
157 if( n->name == NULL ){
158 return "unknown";
159 } else {
160 return n->name;
161 }
162 }
163
164 const Jim_Nvp nvp_target_event[] = {
165 { .value = TARGET_EVENT_OLD_pre_reset , .name = "old-pre_reset" },
166 { .value = TARGET_EVENT_OLD_gdb_program_config , .name = "old-gdb_program_config" },
167 { .value = TARGET_EVENT_OLD_post_reset , .name = "old-post_reset" },
168 { .value = TARGET_EVENT_OLD_pre_resume , .name = "old-pre_resume" },
169
170
171 { .value = TARGET_EVENT_EARLY_HALTED, .name = "early-halted" },
172 { .value = TARGET_EVENT_HALTED, .name = "halted" },
173 { .value = TARGET_EVENT_RESUMED, .name = "resumed" },
174 { .value = TARGET_EVENT_RESUME_START, .name = "resume-start" },
175 { .value = TARGET_EVENT_RESUME_END, .name = "resume-end" },
176
177 /* historical name */
178
179 { .value = TARGET_EVENT_RESET_START, .name = "reset-start" },
180
181 { .value = TARGET_EVENT_RESET_ASSERT_PRE, .name = "reset-assert-pre" },
182 { .value = TARGET_EVENT_RESET_ASSERT_POST, .name = "reset-assert-post" },
183 { .value = TARGET_EVENT_RESET_DEASSERT_PRE, .name = "reset-deassert-pre" },
184 { .value = TARGET_EVENT_RESET_DEASSERT_POST, .name = "reset-deassert-post" },
185 { .value = TARGET_EVENT_RESET_HALT_PRE, .name = "reset-halt-pre" },
186 { .value = TARGET_EVENT_RESET_HALT_POST, .name = "reset-halt-post" },
187 { .value = TARGET_EVENT_RESET_WAIT_PRE, .name = "reset-wait-pre" },
188 { .value = TARGET_EVENT_RESET_WAIT_POST, .name = "reset-wait-post" },
189 { .value = TARGET_EVENT_RESET_INIT , .name = "reset-init" },
190 { .value = TARGET_EVENT_RESET_END, .name = "reset-end" },
191
192
193
194
195
196 { .value = TARGET_EVENT_EXAMINE_START, .name = "examine-start" },
197 { .value = TARGET_EVENT_EXAMINE_START, .name = "examine-end" },
198
199
200 { .value = TARGET_EVENT_DEBUG_HALTED, .name = "debug-halted" },
201 { .value = TARGET_EVENT_DEBUG_RESUMED, .name = "debug-resumed" },
202
203 { .value = TARGET_EVENT_GDB_ATTACH, .name = "gdb-attach" },
204 { .value = TARGET_EVENT_GDB_DETACH, .name = "gdb-detach" },
205
206
207 { .value = TARGET_EVENT_GDB_FLASH_WRITE_START, .name = "gdb-flash-write-start" },
208 { .value = TARGET_EVENT_GDB_FLASH_WRITE_END , .name = "gdb-flash-write-end" },
209
210 { .value = TARGET_EVENT_GDB_FLASH_ERASE_START, .name = "gdb-flash-erase-start" },
211 { .value = TARGET_EVENT_GDB_FLASH_ERASE_END , .name = "gdb-flash-erase-end" },
212
213 { .value = TARGET_EVENT_RESUME_START, .name = "resume-start" },
214 { .value = TARGET_EVENT_RESUMED , .name = "resume-ok" },
215 { .value = TARGET_EVENT_RESUME_END , .name = "resume-end" },
216
217 { .name = NULL, .value = -1 }
218 };
219
220 const Jim_Nvp nvp_target_state[] = {
221 { .name = "unknown", .value = TARGET_UNKNOWN },
222 { .name = "running", .value = TARGET_RUNNING },
223 { .name = "halted", .value = TARGET_HALTED },
224 { .name = "reset", .value = TARGET_RESET },
225 { .name = "debug-running", .value = TARGET_DEBUG_RUNNING },
226 { .name = NULL, .value = -1 },
227 };
228
229
230 const Jim_Nvp nvp_target_debug_reason [] = {
231 { .name = "debug-request" , .value = DBG_REASON_DBGRQ },
232 { .name = "breakpoint" , .value = DBG_REASON_BREAKPOINT },
233 { .name = "watchpoint" , .value = DBG_REASON_WATCHPOINT },
234 { .name = "watchpoint-and-breakpoint", .value = DBG_REASON_WPTANDBKPT },
235 { .name = "single-step" , .value = DBG_REASON_SINGLESTEP },
236 { .name = "target-not-halted" , .value = DBG_REASON_NOTHALTED },
237 { .name = "undefined" , .value = DBG_REASON_UNDEFINED },
238 { .name = NULL, .value = -1 },
239 };
240
241
242 const Jim_Nvp nvp_target_endian[] = {
243 { .name = "big", .value = TARGET_BIG_ENDIAN },
244 { .name = "little", .value = TARGET_LITTLE_ENDIAN },
245 { .name = "be", .value = TARGET_BIG_ENDIAN },
246 { .name = "le", .value = TARGET_LITTLE_ENDIAN },
247 { .name = NULL, .value = -1 },
248 };
249
250 const Jim_Nvp nvp_reset_modes[] = {
251 { .name = "unknown", .value = RESET_UNKNOWN },
252 { .name = "run" , .value = RESET_RUN },
253 { .name = "halt" , .value = RESET_HALT },
254 { .name = "init" , .value = RESET_INIT },
255 { .name = NULL , .value = -1 },
256 };
257
258 static int
259 max_target_number( void )
260 {
261 target_t *t;
262 int x;
263
264 x = -1;
265 t = all_targets;
266 while( t ){
267 if( x < t->target_number ){
268 x = (t->target_number)+1;
269 }
270 t = t->next;
271 }
272 return x;
273 }
274
275 /* determine the number of the new target */
276 static int
277 new_target_number( void )
278 {
279 target_t *t;
280 int x;
281
282 /* number is 0 based */
283 x = -1;
284 t = all_targets;
285 while(t){
286 if( x < t->target_number ){
287 x = t->target_number;
288 }
289 t = t->next;
290 }
291 return x+1;
292 }
293
294 static int target_continous_poll = 1;
295
296 /* read a u32 from a buffer in target memory endianness */
297 u32 target_buffer_get_u32(target_t *target, u8 *buffer)
298 {
299 if (target->endianness == TARGET_LITTLE_ENDIAN)
300 return le_to_h_u32(buffer);
301 else
302 return be_to_h_u32(buffer);
303 }
304
305 /* read a u16 from a buffer in target memory endianness */
306 u16 target_buffer_get_u16(target_t *target, u8 *buffer)
307 {
308 if (target->endianness == TARGET_LITTLE_ENDIAN)
309 return le_to_h_u16(buffer);
310 else
311 return be_to_h_u16(buffer);
312 }
313
314 /* read a u8 from a buffer in target memory endianness */
315 u8 target_buffer_get_u8(target_t *target, u8 *buffer)
316 {
317 return *buffer & 0x0ff;
318 }
319
320 /* write a u32 to a buffer in target memory endianness */
321 void target_buffer_set_u32(target_t *target, u8 *buffer, u32 value)
322 {
323 if (target->endianness == TARGET_LITTLE_ENDIAN)
324 h_u32_to_le(buffer, value);
325 else
326 h_u32_to_be(buffer, value);
327 }
328
329 /* write a u16 to a buffer in target memory endianness */
330 void target_buffer_set_u16(target_t *target, u8 *buffer, u16 value)
331 {
332 if (target->endianness == TARGET_LITTLE_ENDIAN)
333 h_u16_to_le(buffer, value);
334 else
335 h_u16_to_be(buffer, value);
336 }
337
338 /* write a u8 to a buffer in target memory endianness */
339 void target_buffer_set_u8(target_t *target, u8 *buffer, u8 value)
340 {
341 *buffer = value;
342 }
343
344 /* returns a pointer to the n-th configured target */
345 target_t* get_target_by_num(int num)
346 {
347 target_t *target = all_targets;
348
349 while (target){
350 if( target->target_number == num ){
351 return target;
352 }
353 target = target->next;
354 }
355
356 return NULL;
357 }
358
359 int get_num_by_target(target_t *query_target)
360 {
361 return query_target->target_number;
362 }
363
364 target_t* get_current_target(command_context_t *cmd_ctx)
365 {
366 target_t *target = get_target_by_num(cmd_ctx->current_target);
367
368 if (target == NULL)
369 {
370 LOG_ERROR("BUG: current_target out of bounds");
371 exit(-1);
372 }
373
374 return target;
375 }
376
377
378 int target_poll(struct target_s *target)
379 {
380 /* We can't poll until after examine */
381 if (!target->type->examined)
382 {
383 /* Fail silently lest we pollute the log */
384 return ERROR_FAIL;
385 }
386 return target->type->poll(target);
387 }
388
389 int target_halt(struct target_s *target)
390 {
391 /* We can't poll until after examine */
392 if (!target->type->examined)
393 {
394 LOG_ERROR("Target not examined yet");
395 return ERROR_FAIL;
396 }
397 return target->type->halt(target);
398 }
399
400 int target_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution)
401 {
402 int retval;
403
404 /* We can't poll until after examine */
405 if (!target->type->examined)
406 {
407 LOG_ERROR("Target not examined yet");
408 return ERROR_FAIL;
409 }
410
411 /* note that resume *must* be asynchronous. The CPU can halt before we poll. The CPU can
412 * even halt at the current PC as a result of a software breakpoint being inserted by (a bug?)
413 * the application.
414 */
415 if ((retval = target->type->resume(target, current, address, handle_breakpoints, debug_execution)) != ERROR_OK)
416 return retval;
417
418 return retval;
419 }
420
421
422 int target_process_reset(struct command_context_s *cmd_ctx, enum target_reset_mode reset_mode)
423 {
424 char buf[100];
425 int retval;
426 Jim_Nvp *n;
427 n = Jim_Nvp_value2name_simple( nvp_reset_modes, reset_mode );
428 if( n->name == NULL ){
429 LOG_ERROR("invalid reset mode");
430 return ERROR_FAIL;
431 }
432
433 sprintf( buf, "ocd_process_reset %s", n->name );
434 retval = Jim_Eval( interp, buf );
435
436 if(retval != JIM_OK) {
437 Jim_PrintErrorMessage(interp);
438 return ERROR_FAIL;
439 }
440
441 /* We want any events to be processed before the prompt */
442 retval = target_call_timer_callbacks_now();
443
444 return retval;
445 }
446
447
448 static int default_virt2phys(struct target_s *target, u32 virtual, u32 *physical)
449 {
450 *physical = virtual;
451 return ERROR_OK;
452 }
453
454 static int default_mmu(struct target_s *target, int *enabled)
455 {
456 *enabled = 0;
457 return ERROR_OK;
458 }
459
460 static int default_examine(struct target_s *target)
461 {
462 target->type->examined = 1;
463 return ERROR_OK;
464 }
465
466
467 /* Targets that correctly implement init+examine, i.e.
468 * no communication with target during init:
469 *
470 * XScale
471 */
472 int target_examine(void)
473 {
474 int retval = ERROR_OK;
475 target_t *target = all_targets;
476 while (target)
477 {
478 if ((retval = target->type->examine(target))!=ERROR_OK)
479 return retval;
480 target = target->next;
481 }
482 return retval;
483 }
484
485 static int target_write_memory_imp(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
486 {
487 if (!target->type->examined)
488 {
489 LOG_ERROR("Target not examined yet");
490 return ERROR_FAIL;
491 }
492 return target->type->write_memory_imp(target, address, size, count, buffer);
493 }
494
495 static int target_read_memory_imp(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
496 {
497 if (!target->type->examined)
498 {
499 LOG_ERROR("Target not examined yet");
500 return ERROR_FAIL;
501 }
502 return target->type->read_memory_imp(target, address, size, count, buffer);
503 }
504
505 static int target_soft_reset_halt_imp(struct target_s *target)
506 {
507 if (!target->type->examined)
508 {
509 LOG_ERROR("Target not examined yet");
510 return ERROR_FAIL;
511 }
512 return target->type->soft_reset_halt_imp(target);
513 }
514
515 static int target_run_algorithm_imp(struct target_s *target, int num_mem_params, mem_param_t *mem_params, int num_reg_params, reg_param_t *reg_param, u32 entry_point, u32 exit_point, int timeout_ms, void *arch_info)
516 {
517 if (!target->type->examined)
518 {
519 LOG_ERROR("Target not examined yet");
520 return ERROR_FAIL;
521 }
522 return target->type->run_algorithm_imp(target, num_mem_params, mem_params, num_reg_params, reg_param, entry_point, exit_point, timeout_ms, arch_info);
523 }
524
525 int target_init(struct command_context_s *cmd_ctx)
526 {
527 target_t *target = all_targets;
528 int retval;
529
530 while (target)
531 {
532 target->type->examined = 0;
533 if (target->type->examine == NULL)
534 {
535 target->type->examine = default_examine;
536 }
537
538 if (target->type->init_target(cmd_ctx, target) != ERROR_OK)
539 {
540 LOG_ERROR("target '%s' init failed", target->type->name);
541 exit(-1);
542 }
543
544 /* Set up default functions if none are provided by target */
545 if (target->type->virt2phys == NULL)
546 {
547 target->type->virt2phys = default_virt2phys;
548 }
549 target->type->virt2phys = default_virt2phys;
550 /* a non-invasive way(in terms of patches) to add some code that
551 * runs before the type->write/read_memory implementation
552 */
553 target->type->write_memory_imp = target->type->write_memory;
554 target->type->write_memory = target_write_memory_imp;
555 target->type->read_memory_imp = target->type->read_memory;
556 target->type->read_memory = target_read_memory_imp;
557 target->type->soft_reset_halt_imp = target->type->soft_reset_halt;
558 target->type->soft_reset_halt = target_soft_reset_halt_imp;
559 target->type->run_algorithm_imp = target->type->run_algorithm;
560 target->type->run_algorithm = target_run_algorithm_imp;
561
562
563 if (target->type->mmu == NULL)
564 {
565 target->type->mmu = default_mmu;
566 }
567 target = target->next;
568 }
569
570 if (all_targets)
571 {
572 if((retval = target_register_user_commands(cmd_ctx)) != ERROR_OK)
573 return retval;
574 if((retval = target_register_timer_callback(handle_target, 100, 1, NULL)) != ERROR_OK)
575 return retval;
576 }
577
578 return ERROR_OK;
579 }
580
581 int target_register_event_callback(int (*callback)(struct target_s *target, enum target_event event, void *priv), void *priv)
582 {
583 target_event_callback_t **callbacks_p = &target_event_callbacks;
584
585 if (callback == NULL)
586 {
587 return ERROR_INVALID_ARGUMENTS;
588 }
589
590 if (*callbacks_p)
591 {
592 while ((*callbacks_p)->next)
593 callbacks_p = &((*callbacks_p)->next);
594 callbacks_p = &((*callbacks_p)->next);
595 }
596
597 (*callbacks_p) = malloc(sizeof(target_event_callback_t));
598 (*callbacks_p)->callback = callback;
599 (*callbacks_p)->priv = priv;
600 (*callbacks_p)->next = NULL;
601
602 return ERROR_OK;
603 }
604
605 int target_register_timer_callback(int (*callback)(void *priv), int time_ms, int periodic, void *priv)
606 {
607 target_timer_callback_t **callbacks_p = &target_timer_callbacks;
608 struct timeval now;
609
610 if (callback == NULL)
611 {
612 return ERROR_INVALID_ARGUMENTS;
613 }
614
615 if (*callbacks_p)
616 {
617 while ((*callbacks_p)->next)
618 callbacks_p = &((*callbacks_p)->next);
619 callbacks_p = &((*callbacks_p)->next);
620 }
621
622 (*callbacks_p) = malloc(sizeof(target_timer_callback_t));
623 (*callbacks_p)->callback = callback;
624 (*callbacks_p)->periodic = periodic;
625 (*callbacks_p)->time_ms = time_ms;
626
627 gettimeofday(&now, NULL);
628 (*callbacks_p)->when.tv_usec = now.tv_usec + (time_ms % 1000) * 1000;
629 time_ms -= (time_ms % 1000);
630 (*callbacks_p)->when.tv_sec = now.tv_sec + (time_ms / 1000);
631 if ((*callbacks_p)->when.tv_usec > 1000000)
632 {
633 (*callbacks_p)->when.tv_usec = (*callbacks_p)->when.tv_usec - 1000000;
634 (*callbacks_p)->when.tv_sec += 1;
635 }
636
637 (*callbacks_p)->priv = priv;
638 (*callbacks_p)->next = NULL;
639
640 return ERROR_OK;
641 }
642
643 int target_unregister_event_callback(int (*callback)(struct target_s *target, enum target_event event, void *priv), void *priv)
644 {
645 target_event_callback_t **p = &target_event_callbacks;
646 target_event_callback_t *c = target_event_callbacks;
647
648 if (callback == NULL)
649 {
650 return ERROR_INVALID_ARGUMENTS;
651 }
652
653 while (c)
654 {
655 target_event_callback_t *next = c->next;
656 if ((c->callback == callback) && (c->priv == priv))
657 {
658 *p = next;
659 free(c);
660 return ERROR_OK;
661 }
662 else
663 p = &(c->next);
664 c = next;
665 }
666
667 return ERROR_OK;
668 }
669
670 int target_unregister_timer_callback(int (*callback)(void *priv), void *priv)
671 {
672 target_timer_callback_t **p = &target_timer_callbacks;
673 target_timer_callback_t *c = target_timer_callbacks;
674
675 if (callback == NULL)
676 {
677 return ERROR_INVALID_ARGUMENTS;
678 }
679
680 while (c)
681 {
682 target_timer_callback_t *next = c->next;
683 if ((c->callback == callback) && (c->priv == priv))
684 {
685 *p = next;
686 free(c);
687 return ERROR_OK;
688 }
689 else
690 p = &(c->next);
691 c = next;
692 }
693
694 return ERROR_OK;
695 }
696
697 int target_call_event_callbacks(target_t *target, enum target_event event)
698 {
699 target_event_callback_t *callback = target_event_callbacks;
700 target_event_callback_t *next_callback;
701
702 if (event == TARGET_EVENT_HALTED)
703 {
704 /* execute early halted first */
705 target_call_event_callbacks(target, TARGET_EVENT_EARLY_HALTED);
706 }
707
708
709 LOG_DEBUG("target event %i (%s)",
710 event,
711 Jim_Nvp_value2name_simple( nvp_target_event, event )->name );
712
713 target_handle_event( target, event );
714
715 while (callback)
716 {
717 next_callback = callback->next;
718 callback->callback(target, event, callback->priv);
719 callback = next_callback;
720 }
721
722 return ERROR_OK;
723 }
724
725 static int target_call_timer_callbacks_check_time(int checktime)
726 {
727 target_timer_callback_t *callback = target_timer_callbacks;
728 target_timer_callback_t *next_callback;
729 struct timeval now;
730
731 keep_alive();
732
733 gettimeofday(&now, NULL);
734
735 while (callback)
736 {
737 next_callback = callback->next;
738
739 if ((!checktime&&callback->periodic)||
740 (((now.tv_sec >= callback->when.tv_sec) && (now.tv_usec >= callback->when.tv_usec))
741 || (now.tv_sec > callback->when.tv_sec)))
742 {
743 if(callback->callback != NULL)
744 {
745 callback->callback(callback->priv);
746 if (callback->periodic)
747 {
748 int time_ms = callback->time_ms;
749 callback->when.tv_usec = now.tv_usec + (time_ms % 1000) * 1000;
750 time_ms -= (time_ms % 1000);
751 callback->when.tv_sec = now.tv_sec + time_ms / 1000;
752 if (callback->when.tv_usec > 1000000)
753 {
754 callback->when.tv_usec = callback->when.tv_usec - 1000000;
755 callback->when.tv_sec += 1;
756 }
757 }
758 else
759 {
760 int retval;
761 if((retval = target_unregister_timer_callback(callback->callback, callback->priv)) != ERROR_OK)
762 return retval;
763 }
764 }
765 }
766
767 callback = next_callback;
768 }
769
770 return ERROR_OK;
771 }
772
773 int target_call_timer_callbacks(void)
774 {
775 return target_call_timer_callbacks_check_time(1);
776 }
777
778 /* invoke periodic callbacks immediately */
779 int target_call_timer_callbacks_now(void)
780 {
781 return target_call_timer_callbacks_check_time(0);
782 }
783
784 int target_alloc_working_area(struct target_s *target, u32 size, working_area_t **area)
785 {
786 working_area_t *c = target->working_areas;
787 working_area_t *new_wa = NULL;
788
789 /* Reevaluate working area address based on MMU state*/
790 if (target->working_areas == NULL)
791 {
792 int retval;
793 int enabled;
794 retval = target->type->mmu(target, &enabled);
795 if (retval != ERROR_OK)
796 {
797 return retval;
798 }
799 if (enabled)
800 {
801 target->working_area = target->working_area_virt;
802 }
803 else
804 {
805 target->working_area = target->working_area_phys;
806 }
807 }
808
809 /* only allocate multiples of 4 byte */
810 if (size % 4)
811 {
812 LOG_ERROR("BUG: code tried to allocate unaligned number of bytes, padding");
813 size = CEIL(size, 4);
814 }
815
816 /* see if there's already a matching working area */
817 while (c)
818 {
819 if ((c->free) && (c->size == size))
820 {
821 new_wa = c;
822 break;
823 }
824 c = c->next;
825 }
826
827 /* if not, allocate a new one */
828 if (!new_wa)
829 {
830 working_area_t **p = &target->working_areas;
831 u32 first_free = target->working_area;
832 u32 free_size = target->working_area_size;
833
834 LOG_DEBUG("allocating new working area");
835
836 c = target->working_areas;
837 while (c)
838 {
839 first_free += c->size;
840 free_size -= c->size;
841 p = &c->next;
842 c = c->next;
843 }
844
845 if (free_size < size)
846 {
847 LOG_WARNING("not enough working area available(requested %d, free %d)", size, free_size);
848 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
849 }
850
851 new_wa = malloc(sizeof(working_area_t));
852 new_wa->next = NULL;
853 new_wa->size = size;
854 new_wa->address = first_free;
855
856 if (target->backup_working_area)
857 {
858 int retval;
859 new_wa->backup = malloc(new_wa->size);
860 if((retval = target->type->read_memory(target, new_wa->address, 4, new_wa->size / 4, new_wa->backup)) != ERROR_OK)
861 {
862 free(new_wa->backup);
863 free(new_wa);
864 return retval;
865 }
866 }
867 else
868 {
869 new_wa->backup = NULL;
870 }
871
872 /* put new entry in list */
873 *p = new_wa;
874 }
875
876 /* mark as used, and return the new (reused) area */
877 new_wa->free = 0;
878 *area = new_wa;
879
880 /* user pointer */
881 new_wa->user = area;
882
883 return ERROR_OK;
884 }
885
886 int target_free_working_area_restore(struct target_s *target, working_area_t *area, int restore)
887 {
888 if (area->free)
889 return ERROR_OK;
890
891 if (restore&&target->backup_working_area)
892 {
893 int retval;
894 if((retval = target->type->write_memory(target, area->address, 4, area->size / 4, area->backup)) != ERROR_OK)
895 return retval;
896 }
897
898 area->free = 1;
899
900 /* mark user pointer invalid */
901 *area->user = NULL;
902 area->user = NULL;
903
904 return ERROR_OK;
905 }
906
907 int target_free_working_area(struct target_s *target, working_area_t *area)
908 {
909 return target_free_working_area_restore(target, area, 1);
910 }
911
912 /* free resources and restore memory, if restoring memory fails,
913 * free up resources anyway
914 */
915 void target_free_all_working_areas_restore(struct target_s *target, int restore)
916 {
917 working_area_t *c = target->working_areas;
918
919 while (c)
920 {
921 working_area_t *next = c->next;
922 target_free_working_area_restore(target, c, restore);
923
924 if (c->backup)
925 free(c->backup);
926
927 free(c);
928
929 c = next;
930 }
931
932 target->working_areas = NULL;
933 }
934
935 void target_free_all_working_areas(struct target_s *target)
936 {
937 target_free_all_working_areas_restore(target, 1);
938 }
939
940 int target_register_commands(struct command_context_s *cmd_ctx)
941 {
942
943 register_command(cmd_ctx, NULL, "targets", handle_targets_command, COMMAND_EXEC, NULL);
944 register_command(cmd_ctx, NULL, "working_area", handle_working_area_command, COMMAND_ANY, "working_area <target#> <address> <size> <'backup'|'nobackup'> [virtual address]");
945 register_command(cmd_ctx, NULL, "virt2phys", handle_virt2phys_command, COMMAND_ANY, "virt2phys <virtual address>");
946 register_command(cmd_ctx, NULL, "profile", handle_profile_command, COMMAND_EXEC, "PRELIMINARY! - profile <seconds> <gmon.out>");
947
948 register_jim(cmd_ctx, "target", jim_target, "configure target" );
949
950
951 /* script procedures */
952 register_jim(cmd_ctx, "ocd_mem2array", jim_mem2array, "read memory and return as a TCL array for script processing");
953 register_jim(cmd_ctx, "ocd_array2mem", jim_array2mem, "convert a TCL array to memory locations and write the values");
954 return ERROR_OK;
955 }
956
957 int target_arch_state(struct target_s *target)
958 {
959 int retval;
960 if (target==NULL)
961 {
962 LOG_USER("No target has been configured");
963 return ERROR_OK;
964 }
965
966 LOG_USER("target state: %s",
967 Jim_Nvp_value2name_simple(nvp_target_state,target->state)->name);
968
969 if (target->state!=TARGET_HALTED)
970 return ERROR_OK;
971
972 retval=target->type->arch_state(target);
973 return retval;
974 }
975
976 /* Single aligned words are guaranteed to use 16 or 32 bit access
977 * mode respectively, otherwise data is handled as quickly as
978 * possible
979 */
980 int target_write_buffer(struct target_s *target, u32 address, u32 size, u8 *buffer)
981 {
982 int retval;
983 LOG_DEBUG("writing buffer of %i byte at 0x%8.8x", size, address);
984
985 if (!target->type->examined)
986 {
987 LOG_ERROR("Target not examined yet");
988 return ERROR_FAIL;
989 }
990
991 if ((address + size - 1) < address)
992 {
993 /* GDB can request this when e.g. PC is 0xfffffffc*/
994 LOG_ERROR("address+size wrapped(0x%08x, 0x%08x)", address, size);
995 return ERROR_FAIL;
996 }
997
998 if (((address % 2) == 0) && (size == 2))
999 {
1000 return target->type->write_memory(target, address, 2, 1, buffer);
1001 }
1002
1003 /* handle unaligned head bytes */
1004 if (address % 4)
1005 {
1006 int unaligned = 4 - (address % 4);
1007
1008 if (unaligned > size)
1009 unaligned = size;
1010
1011 if ((retval = target->type->write_memory(target, address, 1, unaligned, buffer)) != ERROR_OK)
1012 return retval;
1013
1014 buffer += unaligned;
1015 address += unaligned;
1016 size -= unaligned;
1017 }
1018
1019 /* handle aligned words */
1020 if (size >= 4)
1021 {
1022 int aligned = size - (size % 4);
1023
1024 /* use bulk writes above a certain limit. This may have to be changed */
1025 if (aligned > 128)
1026 {
1027 if ((retval = target->type->bulk_write_memory(target, address, aligned / 4, buffer)) != ERROR_OK)
1028 return retval;
1029 }
1030 else
1031 {
1032 if ((retval = target->type->write_memory(target, address, 4, aligned / 4, buffer)) != ERROR_OK)
1033 return retval;
1034 }
1035
1036 buffer += aligned;
1037 address += aligned;
1038 size -= aligned;
1039 }
1040
1041 /* handle tail writes of less than 4 bytes */
1042 if (size > 0)
1043 {
1044 if ((retval = target->type->write_memory(target, address, 1, size, buffer)) != ERROR_OK)
1045 return retval;
1046 }
1047
1048 return ERROR_OK;
1049 }
1050
1051
1052 /* Single aligned words are guaranteed to use 16 or 32 bit access
1053 * mode respectively, otherwise data is handled as quickly as
1054 * possible
1055 */
1056 int target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffer)
1057 {
1058 int retval;
1059 LOG_DEBUG("reading buffer of %i byte at 0x%8.8x", size, address);
1060
1061 if (!target->type->examined)
1062 {
1063 LOG_ERROR("Target not examined yet");
1064 return ERROR_FAIL;
1065 }
1066
1067 if ((address + size - 1) < address)
1068 {
1069 /* GDB can request this when e.g. PC is 0xfffffffc*/
1070 LOG_ERROR("address+size wrapped(0x%08x, 0x%08x)", address, size);
1071 return ERROR_FAIL;
1072 }
1073
1074 if (((address % 2) == 0) && (size == 2))
1075 {
1076 return target->type->read_memory(target, address, 2, 1, buffer);
1077 }
1078
1079 /* handle unaligned head bytes */
1080 if (address % 4)
1081 {
1082 int unaligned = 4 - (address % 4);
1083
1084 if (unaligned > size)
1085 unaligned = size;
1086
1087 if ((retval = target->type->read_memory(target, address, 1, unaligned, buffer)) != ERROR_OK)
1088 return retval;
1089
1090 buffer += unaligned;
1091 address += unaligned;
1092 size -= unaligned;
1093 }
1094
1095 /* handle aligned words */
1096 if (size >= 4)
1097 {
1098 int aligned = size - (size % 4);
1099
1100 if ((retval = target->type->read_memory(target, address, 4, aligned / 4, buffer)) != ERROR_OK)
1101 return retval;
1102
1103 buffer += aligned;
1104 address += aligned;
1105 size -= aligned;
1106 }
1107
1108 /* handle tail writes of less than 4 bytes */
1109 if (size > 0)
1110 {
1111 if ((retval = target->type->read_memory(target, address, 1, size, buffer)) != ERROR_OK)
1112 return retval;
1113 }
1114
1115 return ERROR_OK;
1116 }
1117
1118 int target_checksum_memory(struct target_s *target, u32 address, u32 size, u32* crc)
1119 {
1120 u8 *buffer;
1121 int retval;
1122 int i;
1123 u32 checksum = 0;
1124 if (!target->type->examined)
1125 {
1126 LOG_ERROR("Target not examined yet");
1127 return ERROR_FAIL;
1128 }
1129
1130 if ((retval = target->type->checksum_memory(target, address,
1131 size, &checksum)) != ERROR_OK)
1132 {
1133 buffer = malloc(size);
1134 if (buffer == NULL)
1135 {
1136 LOG_ERROR("error allocating buffer for section (%d bytes)", size);
1137 return ERROR_INVALID_ARGUMENTS;
1138 }
1139 retval = target_read_buffer(target, address, size, buffer);
1140 if (retval != ERROR_OK)
1141 {
1142 free(buffer);
1143 return retval;
1144 }
1145
1146 /* convert to target endianess */
1147 for (i = 0; i < (size/sizeof(u32)); i++)
1148 {
1149 u32 target_data;
1150 target_data = target_buffer_get_u32(target, &buffer[i*sizeof(u32)]);
1151 target_buffer_set_u32(target, &buffer[i*sizeof(u32)], target_data);
1152 }
1153
1154 retval = image_calculate_checksum( buffer, size, &checksum );
1155 free(buffer);
1156 }
1157
1158 *crc = checksum;
1159
1160 return retval;
1161 }
1162
1163 int target_blank_check_memory(struct target_s *target, u32 address, u32 size, u32* blank)
1164 {
1165 int retval;
1166 if (!target->type->examined)
1167 {
1168 LOG_ERROR("Target not examined yet");
1169 return ERROR_FAIL;
1170 }
1171
1172 if (target->type->blank_check_memory == 0)
1173 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1174
1175 retval = target->type->blank_check_memory(target, address, size, blank);
1176
1177 return retval;
1178 }
1179
1180 int target_read_u32(struct target_s *target, u32 address, u32 *value)
1181 {
1182 u8 value_buf[4];
1183 if (!target->type->examined)
1184 {
1185 LOG_ERROR("Target not examined yet");
1186 return ERROR_FAIL;
1187 }
1188
1189 int retval = target->type->read_memory(target, address, 4, 1, value_buf);
1190
1191 if (retval == ERROR_OK)
1192 {
1193 *value = target_buffer_get_u32(target, value_buf);
1194 LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address, *value);
1195 }
1196 else
1197 {
1198 *value = 0x0;
1199 LOG_DEBUG("address: 0x%8.8x failed", address);
1200 }
1201
1202 return retval;
1203 }
1204
1205 int target_read_u16(struct target_s *target, u32 address, u16 *value)
1206 {
1207 u8 value_buf[2];
1208 if (!target->type->examined)
1209 {
1210 LOG_ERROR("Target not examined yet");
1211 return ERROR_FAIL;
1212 }
1213
1214 int retval = target->type->read_memory(target, address, 2, 1, value_buf);
1215
1216 if (retval == ERROR_OK)
1217 {
1218 *value = target_buffer_get_u16(target, value_buf);
1219 LOG_DEBUG("address: 0x%8.8x, value: 0x%4.4x", address, *value);
1220 }
1221 else
1222 {
1223 *value = 0x0;
1224 LOG_DEBUG("address: 0x%8.8x failed", address);
1225 }
1226
1227 return retval;
1228 }
1229
1230 int target_read_u8(struct target_s *target, u32 address, u8 *value)
1231 {
1232 int retval = target->type->read_memory(target, address, 1, 1, value);
1233 if (!target->type->examined)
1234 {
1235 LOG_ERROR("Target not examined yet");
1236 return ERROR_FAIL;
1237 }
1238
1239 if (retval == ERROR_OK)
1240 {
1241 LOG_DEBUG("address: 0x%8.8x, value: 0x%2.2x", address, *value);
1242 }
1243 else
1244 {
1245 *value = 0x0;
1246 LOG_DEBUG("address: 0x%8.8x failed", address);
1247 }
1248
1249 return retval;
1250 }
1251
1252 int target_write_u32(struct target_s *target, u32 address, u32 value)
1253 {
1254 int retval;
1255 u8 value_buf[4];
1256 if (!target->type->examined)
1257 {
1258 LOG_ERROR("Target not examined yet");
1259 return ERROR_FAIL;
1260 }
1261
1262 LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address, value);
1263
1264 target_buffer_set_u32(target, value_buf, value);
1265 if ((retval = target->type->write_memory(target, address, 4, 1, value_buf)) != ERROR_OK)
1266 {
1267 LOG_DEBUG("failed: %i", retval);
1268 }
1269
1270 return retval;
1271 }
1272
1273 int target_write_u16(struct target_s *target, u32 address, u16 value)
1274 {
1275 int retval;
1276 u8 value_buf[2];
1277 if (!target->type->examined)
1278 {
1279 LOG_ERROR("Target not examined yet");
1280 return ERROR_FAIL;
1281 }
1282
1283 LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address, value);
1284
1285 target_buffer_set_u16(target, value_buf, value);
1286 if ((retval = target->type->write_memory(target, address, 2, 1, value_buf)) != ERROR_OK)
1287 {
1288 LOG_DEBUG("failed: %i", retval);
1289 }
1290
1291 return retval;
1292 }
1293
1294 int target_write_u8(struct target_s *target, u32 address, u8 value)
1295 {
1296 int retval;
1297 if (!target->type->examined)
1298 {
1299 LOG_ERROR("Target not examined yet");
1300 return ERROR_FAIL;
1301 }
1302
1303 LOG_DEBUG("address: 0x%8.8x, value: 0x%2.2x", address, value);
1304
1305 if ((retval = target->type->read_memory(target, address, 1, 1, &value)) != ERROR_OK)
1306 {
1307 LOG_DEBUG("failed: %i", retval);
1308 }
1309
1310 return retval;
1311 }
1312
1313 int target_register_user_commands(struct command_context_s *cmd_ctx)
1314 {
1315 int retval = ERROR_OK;
1316 register_command(cmd_ctx, NULL, "reg", handle_reg_command, COMMAND_EXEC, NULL);
1317 register_command(cmd_ctx, NULL, "poll", handle_poll_command, COMMAND_EXEC, "poll target state");
1318 register_command(cmd_ctx, NULL, "wait_halt", handle_wait_halt_command, COMMAND_EXEC, "wait for target halt [time (s)]");
1319 register_command(cmd_ctx, NULL, "halt", handle_halt_command, COMMAND_EXEC, "halt target");
1320 register_command(cmd_ctx, NULL, "resume", handle_resume_command, COMMAND_EXEC, "resume target [addr]");
1321 register_command(cmd_ctx, NULL, "step", handle_step_command, COMMAND_EXEC, "step one instruction from current PC or [addr]");
1322 register_command(cmd_ctx, NULL, "reset", handle_reset_command, COMMAND_EXEC, "reset target [run|halt|init] - default is run");
1323 register_command(cmd_ctx, NULL, "soft_reset_halt", handle_soft_reset_halt_command, COMMAND_EXEC, "halt the target and do a soft reset");
1324
1325 register_command(cmd_ctx, NULL, "mdw", handle_md_command, COMMAND_EXEC, "display memory words <addr> [count]");
1326 register_command(cmd_ctx, NULL, "mdh", handle_md_command, COMMAND_EXEC, "display memory half-words <addr> [count]");
1327 register_command(cmd_ctx, NULL, "mdb", handle_md_command, COMMAND_EXEC, "display memory bytes <addr> [count]");
1328
1329 register_command(cmd_ctx, NULL, "mww", handle_mw_command, COMMAND_EXEC, "write memory word <addr> <value> [count]");
1330 register_command(cmd_ctx, NULL, "mwh", handle_mw_command, COMMAND_EXEC, "write memory half-word <addr> <value> [count]");
1331 register_command(cmd_ctx, NULL, "mwb", handle_mw_command, COMMAND_EXEC, "write memory byte <addr> <value> [count]");
1332
1333 register_command(cmd_ctx, NULL, "bp", handle_bp_command, COMMAND_EXEC, "set breakpoint <address> <length> [hw]");
1334 register_command(cmd_ctx, NULL, "rbp", handle_rbp_command, COMMAND_EXEC, "remove breakpoint <adress>");
1335 register_command(cmd_ctx, NULL, "wp", handle_wp_command, COMMAND_EXEC, "set watchpoint <address> <length> <r/w/a> [value] [mask]");
1336 register_command(cmd_ctx, NULL, "rwp", handle_rwp_command, COMMAND_EXEC, "remove watchpoint <adress>");
1337
1338 register_command(cmd_ctx, NULL, "load_image", handle_load_image_command, COMMAND_EXEC, "load_image <file> <address> ['bin'|'ihex'|'elf'|'s19'] [min_address] [max_length]");
1339 register_command(cmd_ctx, NULL, "dump_image", handle_dump_image_command, COMMAND_EXEC, "dump_image <file> <address> <size>");
1340 register_command(cmd_ctx, NULL, "verify_image", handle_verify_image_command, COMMAND_EXEC, "verify_image <file> [offset] [type]");
1341
1342 if((retval = target_request_register_commands(cmd_ctx)) != ERROR_OK)
1343 return retval;
1344 if((retval = trace_register_commands(cmd_ctx)) != ERROR_OK)
1345 return retval;
1346
1347
1348 return retval;
1349 }
1350
1351 int handle_targets_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1352 {
1353 char *cp;
1354 target_t *target = all_targets;
1355
1356 if (argc == 1)
1357 {
1358 /* try as tcltarget name */
1359 for( target = all_targets ; target ; target++ ){
1360 if( target->cmd_name ){
1361 if( 0 == strcmp( args[0], target->cmd_name ) ){
1362 /* MATCH */
1363 goto Match;
1364 }
1365 }
1366 }
1367 /* no match, try as number */
1368
1369 int num = strtoul(args[0], &cp, 0 );
1370 if( *cp != 0 ){
1371 /* then it was not a number */
1372 command_print( cmd_ctx, "Target: %s unknown, try one of:\n", args[0] );
1373 goto DumpTargets;
1374 }
1375
1376 target = get_target_by_num( num );
1377 if( target == NULL ){
1378 command_print(cmd_ctx,"Target: %s is unknown, try one of:\n", args[0] );
1379 goto DumpTargets;
1380 }
1381 Match:
1382 cmd_ctx->current_target = target->target_number;
1383 return ERROR_OK;
1384 }
1385 DumpTargets:
1386
1387 command_print(cmd_ctx, " CmdName Type Endian ChainPos State ");
1388 command_print(cmd_ctx, "-- ---------- ---------- ---------- -------- ----------");
1389 while (target)
1390 {
1391 /* XX: abcdefghij abcdefghij abcdefghij abcdefghij */
1392 command_print(cmd_ctx, "%2d: %-10s %-10s %-10s %8d %s",
1393 target->target_number,
1394 target->cmd_name,
1395 target->type->name,
1396 Jim_Nvp_value2name_simple( nvp_target_endian, target->endianness )->name,
1397 target->chain_position,
1398 Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name );
1399 target = target->next;
1400 }
1401
1402 return ERROR_OK;
1403 }
1404
1405
1406
1407 int handle_working_area_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1408 {
1409 int retval = ERROR_OK;
1410 target_t *target = NULL;
1411
1412 if ((argc < 4) || (argc > 5))
1413 {
1414 return ERROR_COMMAND_SYNTAX_ERROR;
1415 }
1416
1417 target = get_target_by_num(strtoul(args[0], NULL, 0));
1418 if (!target)
1419 {
1420 return ERROR_COMMAND_SYNTAX_ERROR;
1421 }
1422 target_free_all_working_areas(target);
1423
1424 target->working_area_phys = target->working_area_virt = strtoul(args[1], NULL, 0);
1425 if (argc == 5)
1426 {
1427 target->working_area_virt = strtoul(args[4], NULL, 0);
1428 }
1429 target->working_area_size = strtoul(args[2], NULL, 0);
1430
1431 if (strcmp(args[3], "backup") == 0)
1432 {
1433 target->backup_working_area = 1;
1434 }
1435 else if (strcmp(args[3], "nobackup") == 0)
1436 {
1437 target->backup_working_area = 0;
1438 }
1439 else
1440 {
1441 LOG_ERROR("unrecognized <backup|nobackup> argument (%s)", args[3]);
1442 return ERROR_COMMAND_SYNTAX_ERROR;
1443 }
1444
1445 return retval;
1446 }
1447
1448
1449 /* process target state changes */
1450 int handle_target(void *priv)
1451 {
1452 int retval = ERROR_OK;
1453 target_t *target = all_targets;
1454
1455 while (target)
1456 {
1457 if (target_continous_poll)
1458 {
1459 /* polling may fail silently until the target has been examined */
1460 if((retval = target_poll(target)) != ERROR_OK)
1461 return retval;
1462 }
1463
1464 target = target->next;
1465 }
1466
1467 return retval;
1468 }
1469
1470 int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1471 {
1472 target_t *target;
1473 reg_t *reg = NULL;
1474 int count = 0;
1475 char *value;
1476
1477 LOG_DEBUG("-");
1478
1479 target = get_current_target(cmd_ctx);
1480
1481 /* list all available registers for the current target */
1482 if (argc == 0)
1483 {
1484 reg_cache_t *cache = target->reg_cache;
1485
1486 count = 0;
1487 while(cache)
1488 {
1489 int i;
1490 for (i = 0; i < cache->num_regs; i++)
1491 {
1492 value = buf_to_str(cache->reg_list[i].value, cache->reg_list[i].size, 16);
1493 command_print(cmd_ctx, "(%i) %s (/%i): 0x%s (dirty: %i, valid: %i)", count++, cache->reg_list[i].name, cache->reg_list[i].size, value, cache->reg_list[i].dirty, cache->reg_list[i].valid);
1494 free(value);
1495 }
1496 cache = cache->next;
1497 }
1498
1499 return ERROR_OK;
1500 }
1501
1502 /* access a single register by its ordinal number */
1503 if ((args[0][0] >= '0') && (args[0][0] <= '9'))
1504 {
1505 int num = strtoul(args[0], NULL, 0);
1506 reg_cache_t *cache = target->reg_cache;
1507
1508 count = 0;
1509 while(cache)
1510 {
1511 int i;
1512 for (i = 0; i < cache->num_regs; i++)
1513 {
1514 if (count++ == num)
1515 {
1516 reg = &cache->reg_list[i];
1517 break;
1518 }
1519 }
1520 if (reg)
1521 break;
1522 cache = cache->next;
1523 }
1524
1525 if (!reg)
1526 {
1527 command_print(cmd_ctx, "%i is out of bounds, the current target has only %i registers (0 - %i)", num, count, count - 1);
1528 return ERROR_OK;
1529 }
1530 } else /* access a single register by its name */
1531 {
1532 reg = register_get_by_name(target->reg_cache, args[0], 1);
1533
1534 if (!reg)
1535 {
1536 command_print(cmd_ctx, "register %s not found in current target", args[0]);
1537 return ERROR_OK;
1538 }
1539 }
1540
1541 /* display a register */
1542 if ((argc == 1) || ((argc == 2) && !((args[1][0] >= '0') && (args[1][0] <= '9'))))
1543 {
1544 if ((argc == 2) && (strcmp(args[1], "force") == 0))
1545 reg->valid = 0;
1546
1547 if (reg->valid == 0)
1548 {
1549 reg_arch_type_t *arch_type = register_get_arch_type(reg->arch_type);
1550 arch_type->get(reg);
1551 }
1552 value = buf_to_str(reg->value, reg->size, 16);
1553 command_print(cmd_ctx, "%s (/%i): 0x%s", reg->name, reg->size, value);
1554 free(value);
1555 return ERROR_OK;
1556 }
1557
1558 /* set register value */
1559 if (argc == 2)
1560 {
1561 u8 *buf = malloc(CEIL(reg->size, 8));
1562 str_to_buf(args[1], strlen(args[1]), buf, reg->size, 0);
1563
1564 reg_arch_type_t *arch_type = register_get_arch_type(reg->arch_type);
1565 arch_type->set(reg, buf);
1566
1567 value = buf_to_str(reg->value, reg->size, 16);
1568 command_print(cmd_ctx, "%s (/%i): 0x%s", reg->name, reg->size, value);
1569 free(value);
1570
1571 free(buf);
1572
1573 return ERROR_OK;
1574 }
1575
1576 command_print(cmd_ctx, "usage: reg <#|name> [value]");
1577
1578 return ERROR_OK;
1579 }
1580
1581
1582 int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1583 {
1584 int retval = ERROR_OK;
1585 target_t *target = get_current_target(cmd_ctx);
1586
1587 if (argc == 0)
1588 {
1589 if((retval = target_poll(target)) != ERROR_OK)
1590 return retval;
1591 if((retval = target_arch_state(target)) != ERROR_OK)
1592 return retval;
1593
1594 }
1595 else if (argc==1)
1596 {
1597 if (strcmp(args[0], "on") == 0)
1598 {
1599 target_continous_poll = 1;
1600 }
1601 else if (strcmp(args[0], "off") == 0)
1602 {
1603 target_continous_poll = 0;
1604 }
1605 else
1606 {
1607 command_print(cmd_ctx, "arg is \"on\" or \"off\"");
1608 }
1609 } else
1610 {
1611 return ERROR_COMMAND_SYNTAX_ERROR;
1612 }
1613
1614
1615 return retval;
1616 }
1617
1618 int handle_wait_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1619 {
1620 int ms = 5000;
1621
1622 if (argc > 0)
1623 {
1624 char *end;
1625
1626 ms = strtoul(args[0], &end, 0) * 1000;
1627 if (*end)
1628 {
1629 command_print(cmd_ctx, "usage: %s [seconds]", cmd);
1630 return ERROR_OK;
1631 }
1632 }
1633 target_t *target = get_current_target(cmd_ctx);
1634
1635 return target_wait_state(target, TARGET_HALTED, ms);
1636 }
1637
1638 int target_wait_state(target_t *target, enum target_state state, int ms)
1639 {
1640 int retval;
1641 struct timeval timeout, now;
1642 int once=1;
1643 gettimeofday(&timeout, NULL);
1644 timeval_add_time(&timeout, 0, ms * 1000);
1645
1646 for (;;)
1647 {
1648 if ((retval=target_poll(target))!=ERROR_OK)
1649 return retval;
1650 keep_alive();
1651 if (target->state == state)
1652 {
1653 break;
1654 }
1655 if (once)
1656 {
1657 once=0;
1658 LOG_DEBUG("waiting for target %s...",
1659 Jim_Nvp_value2name_simple(nvp_target_state,state)->name);
1660 }
1661
1662 gettimeofday(&now, NULL);
1663 if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec) && (now.tv_usec >= timeout.tv_usec)))
1664 {
1665 LOG_ERROR("timed out while waiting for target %s",
1666 Jim_Nvp_value2name_simple(nvp_target_state,state)->name);
1667 return ERROR_FAIL;
1668 }
1669 }
1670
1671 return ERROR_OK;
1672 }
1673
1674 int handle_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1675 {
1676 int retval;
1677 target_t *target = get_current_target(cmd_ctx);
1678
1679 LOG_DEBUG("-");
1680
1681 if ((retval = target_halt(target)) != ERROR_OK)
1682 {
1683 return retval;
1684 }
1685
1686 return handle_wait_halt_command(cmd_ctx, cmd, args, argc);
1687 }
1688
1689 int handle_soft_reset_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1690 {
1691 target_t *target = get_current_target(cmd_ctx);
1692
1693 LOG_USER("requesting target halt and executing a soft reset");
1694
1695 target->type->soft_reset_halt(target);
1696
1697 return ERROR_OK;
1698 }
1699
1700 int handle_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1701 {
1702 const Jim_Nvp *n;
1703 enum target_reset_mode reset_mode = RESET_RUN;
1704
1705 if (argc >= 1)
1706 {
1707 n = Jim_Nvp_name2value_simple( nvp_reset_modes, args[0] );
1708 if( (n->name == NULL) || (n->value == RESET_UNKNOWN) ){
1709 return ERROR_COMMAND_SYNTAX_ERROR;
1710 }
1711 reset_mode = n->value;
1712 }
1713
1714 /* reset *all* targets */
1715 return target_process_reset(cmd_ctx, reset_mode);
1716 }
1717
1718
1719 int handle_resume_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1720 {
1721 int retval;
1722 target_t *target = get_current_target(cmd_ctx);
1723
1724 target_handle_event( target, TARGET_EVENT_OLD_pre_resume );
1725
1726 if (argc == 0)
1727 retval = target_resume(target, 1, 0, 1, 0); /* current pc, addr = 0, handle breakpoints, not debugging */
1728 else if (argc == 1)
1729 retval = target_resume(target, 0, strtoul(args[0], NULL, 0), 1, 0); /* addr = args[0], handle breakpoints, not debugging */
1730 else
1731 {
1732 retval = ERROR_COMMAND_SYNTAX_ERROR;
1733 }
1734
1735 return retval;
1736 }
1737
1738 int handle_step_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1739 {
1740 target_t *target = get_current_target(cmd_ctx);
1741
1742 LOG_DEBUG("-");
1743
1744 if (argc == 0)
1745 target->type->step(target, 1, 0, 1); /* current pc, addr = 0, handle breakpoints */
1746
1747 if (argc == 1)
1748 target->type->step(target, 0, strtoul(args[0], NULL, 0), 1); /* addr = args[0], handle breakpoints */
1749
1750 return ERROR_OK;
1751 }
1752
1753 int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1754 {
1755 const int line_bytecnt = 32;
1756 int count = 1;
1757 int size = 4;
1758 u32 address = 0;
1759 int line_modulo;
1760 int i;
1761
1762 char output[128];
1763 int output_len;
1764
1765 int retval;
1766
1767 u8 *buffer;
1768 target_t *target = get_current_target(cmd_ctx);
1769
1770 if (argc < 1)
1771 return ERROR_OK;
1772
1773 if (argc == 2)
1774 count = strtoul(args[1], NULL, 0);
1775
1776 address = strtoul(args[0], NULL, 0);
1777
1778
1779 switch (cmd[2])
1780 {
1781 case 'w':
1782 size = 4; line_modulo = line_bytecnt / 4;
1783 break;
1784 case 'h':
1785 size = 2; line_modulo = line_bytecnt / 2;
1786 break;
1787 case 'b':
1788 size = 1; line_modulo = line_bytecnt / 1;
1789 break;
1790 default:
1791 return ERROR_OK;
1792 }
1793
1794 buffer = calloc(count, size);
1795 retval = target->type->read_memory(target, address, size, count, buffer);
1796 if (retval == ERROR_OK)
1797 {
1798 output_len = 0;
1799
1800 for (i = 0; i < count; i++)
1801 {
1802 if (i%line_modulo == 0)
1803 output_len += snprintf(output + output_len, 128 - output_len, "0x%8.8x: ", address + (i*size));
1804
1805 switch (size)
1806 {
1807 case 4:
1808 output_len += snprintf(output + output_len, 128 - output_len, "%8.8x ", target_buffer_get_u32(target, &buffer[i*4]));
1809 break;
1810 case 2:
1811 output_len += snprintf(output + output_len, 128 - output_len, "%4.4x ", target_buffer_get_u16(target, &buffer[i*2]));
1812 break;
1813 case 1:
1814 output_len += snprintf(output + output_len, 128 - output_len, "%2.2x ", buffer[i*1]);
1815 break;
1816 }
1817
1818 if ((i%line_modulo == line_modulo-1) || (i == count - 1))
1819 {
1820 command_print(cmd_ctx, output);
1821 output_len = 0;
1822 }
1823 }
1824 }
1825
1826 free(buffer);
1827
1828 return retval;
1829 }
1830
1831 int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1832 {
1833 u32 address = 0;
1834 u32 value = 0;
1835 int count = 1;
1836 int i;
1837 int wordsize;
1838 target_t *target = get_current_target(cmd_ctx);
1839 u8 value_buf[4];
1840
1841 if ((argc < 2) || (argc > 3))
1842 return ERROR_COMMAND_SYNTAX_ERROR;
1843
1844 address = strtoul(args[0], NULL, 0);
1845 value = strtoul(args[1], NULL, 0);
1846 if (argc == 3)
1847 count = strtoul(args[2], NULL, 0);
1848
1849 switch (cmd[2])
1850 {
1851 case 'w':
1852 wordsize = 4;
1853 target_buffer_set_u32(target, value_buf, value);
1854 break;
1855 case 'h':
1856 wordsize = 2;
1857 target_buffer_set_u16(target, value_buf, value);
1858 break;
1859 case 'b':
1860 wordsize = 1;
1861 value_buf[0] = value;
1862 break;
1863 default:
1864 return ERROR_COMMAND_SYNTAX_ERROR;
1865 }
1866 for (i=0; i<count; i++)
1867 {
1868 int retval;
1869 switch (wordsize)
1870 {
1871 case 4:
1872 retval = target->type->write_memory(target, address + i*wordsize, 4, 1, value_buf);
1873 break;
1874 case 2:
1875 retval = target->type->write_memory(target, address + i*wordsize, 2, 1, value_buf);
1876 break;
1877 case 1:
1878 retval = target->type->write_memory(target, address + i*wordsize, 1, 1, value_buf);
1879 break;
1880 default:
1881 return ERROR_OK;
1882 }
1883 keep_alive();
1884
1885 if (retval!=ERROR_OK)
1886 {
1887 return retval;
1888 }
1889 }
1890
1891 return ERROR_OK;
1892
1893 }
1894
1895 int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1896 {
1897 u8 *buffer;
1898 u32 buf_cnt;
1899 u32 image_size;
1900 u32 min_address=0;
1901 u32 max_address=0xffffffff;
1902 int i;
1903 int retval, retvaltemp;
1904
1905 image_t image;
1906
1907 duration_t duration;
1908 char *duration_text;
1909
1910 target_t *target = get_current_target(cmd_ctx);
1911
1912 if ((argc < 1)||(argc > 5))
1913 {
1914 return ERROR_COMMAND_SYNTAX_ERROR;
1915 }
1916
1917 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
1918 if (argc >= 2)
1919 {
1920 image.base_address_set = 1;
1921 image.base_address = strtoul(args[1], NULL, 0);
1922 }
1923 else
1924 {
1925 image.base_address_set = 0;
1926 }
1927
1928
1929 image.start_address_set = 0;
1930
1931 if (argc>=4)
1932 {
1933 min_address=strtoul(args[3], NULL, 0);
1934 }
1935 if (argc>=5)
1936 {
1937 max_address=strtoul(args[4], NULL, 0)+min_address;
1938 }
1939
1940 if (min_address>max_address)
1941 {
1942 return ERROR_COMMAND_SYNTAX_ERROR;
1943 }
1944
1945
1946 duration_start_measure(&duration);
1947
1948 if (image_open(&image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
1949 {
1950 return ERROR_OK;
1951 }
1952
1953 image_size = 0x0;
1954 retval = ERROR_OK;
1955 for (i = 0; i < image.num_sections; i++)
1956 {
1957 buffer = malloc(image.sections[i].size);
1958 if (buffer == NULL)
1959 {
1960 command_print(cmd_ctx, "error allocating buffer for section (%d bytes)", image.sections[i].size);
1961 break;
1962 }
1963
1964 if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
1965 {
1966 free(buffer);
1967 break;
1968 }
1969
1970 u32 offset=0;
1971 u32 length=buf_cnt;
1972
1973
1974 /* DANGER!!! beware of unsigned comparision here!!! */
1975
1976 if ((image.sections[i].base_address+buf_cnt>=min_address)&&
1977 (image.sections[i].base_address<max_address))
1978 {
1979 if (image.sections[i].base_address<min_address)
1980 {
1981 /* clip addresses below */
1982 offset+=min_address-image.sections[i].base_address;
1983 length-=offset;
1984 }
1985
1986 if (image.sections[i].base_address+buf_cnt>max_address)
1987 {
1988 length-=(image.sections[i].base_address+buf_cnt)-max_address;
1989 }
1990
1991 if ((retval = target_write_buffer(target, image.sections[i].base_address+offset, length, buffer+offset)) != ERROR_OK)
1992 {
1993 free(buffer);
1994 break;
1995 }
1996 image_size += length;
1997 command_print(cmd_ctx, "%u byte written at address 0x%8.8x", length, image.sections[i].base_address+offset);
1998 }
1999
2000 free(buffer);
2001 }
2002
2003 if((retvaltemp = duration_stop_measure(&duration, &duration_text)) != ERROR_OK)
2004 {
2005 image_close(&image);
2006 return retvaltemp;
2007 }
2008
2009 if (retval==ERROR_OK)
2010 {
2011 command_print(cmd_ctx, "downloaded %u byte in %s", image_size, duration_text);
2012 }
2013 free(duration_text);
2014
2015 image_close(&image);
2016
2017 return retval;
2018
2019 }
2020
2021 int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2022 {
2023 fileio_t fileio;
2024
2025 u32 address;
2026 u32 size;
2027 u8 buffer[560];
2028 int retval=ERROR_OK, retvaltemp;
2029
2030 duration_t duration;
2031 char *duration_text;
2032
2033 target_t *target = get_current_target(cmd_ctx);
2034
2035 if (argc != 3)
2036 {
2037 command_print(cmd_ctx, "usage: dump_image <filename> <address> <size>");
2038 return ERROR_OK;
2039 }
2040
2041 address = strtoul(args[1], NULL, 0);
2042 size = strtoul(args[2], NULL, 0);
2043
2044 if ((address & 3) || (size & 3))
2045 {
2046 command_print(cmd_ctx, "only 32-bit aligned address and size are supported");
2047 return ERROR_OK;
2048 }
2049
2050 if (fileio_open(&fileio, args[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)
2051 {
2052 return ERROR_OK;
2053 }
2054
2055 duration_start_measure(&duration);
2056
2057 while (size > 0)
2058 {
2059 u32 size_written;
2060 u32 this_run_size = (size > 560) ? 560 : size;
2061
2062 retval = target->type->read_memory(target, address, 4, this_run_size / 4, buffer);
2063 if (retval != ERROR_OK)
2064 {
2065 break;
2066 }
2067
2068 retval = fileio_write(&fileio, this_run_size, buffer, &size_written);
2069 if (retval != ERROR_OK)
2070 {
2071 break;
2072 }
2073
2074 size -= this_run_size;
2075 address += this_run_size;
2076 }
2077
2078 if((retvaltemp = fileio_close(&fileio)) != ERROR_OK)
2079 return retvaltemp;
2080
2081 if((retvaltemp = duration_stop_measure(&duration, &duration_text)) != ERROR_OK)
2082 return retvaltemp;
2083
2084 if (retval==ERROR_OK)
2085 {
2086 command_print(cmd_ctx, "dumped %"PRIi64" byte in %s", fileio.size, duration_text);
2087 }
2088 free(duration_text);
2089
2090 return ERROR_OK;
2091 }
2092
2093 int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2094 {
2095 u8 *buffer;
2096 u32 buf_cnt;
2097 u32 image_size;
2098 int i;
2099 int retval, retvaltemp;
2100 u32 checksum = 0;
2101 u32 mem_checksum = 0;
2102
2103 image_t image;
2104
2105 duration_t duration;
2106 char *duration_text;
2107
2108 target_t *target = get_current_target(cmd_ctx);
2109
2110 if (argc < 1)
2111 {
2112 return ERROR_COMMAND_SYNTAX_ERROR;
2113 }
2114
2115 if (!target)
2116 {
2117 LOG_ERROR("no target selected");
2118 return ERROR_FAIL;
2119 }
2120
2121 duration_start_measure(&duration);
2122
2123 if (argc >= 2)
2124 {
2125 image.base_address_set = 1;
2126 image.base_address = strtoul(args[1], NULL, 0);
2127 }
2128 else
2129 {
2130 image.base_address_set = 0;
2131 image.base_address = 0x0;
2132 }
2133
2134 image.start_address_set = 0;
2135
2136 if ((retval=image_open(&image, args[0], (argc == 3) ? args[2] : NULL)) != ERROR_OK)
2137 {
2138 return retval;
2139 }
2140
2141 image_size = 0x0;
2142 retval=ERROR_OK;
2143 for (i = 0; i < image.num_sections; i++)
2144 {
2145 buffer = malloc(image.sections[i].size);
2146 if (buffer == NULL)
2147 {
2148 command_print(cmd_ctx, "error allocating buffer for section (%d bytes)", image.sections[i].size);
2149 break;
2150 }
2151 if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
2152 {
2153 free(buffer);
2154 break;
2155 }
2156
2157 /* calculate checksum of image */
2158 image_calculate_checksum( buffer, buf_cnt, &checksum );
2159
2160 retval = target_checksum_memory(target, image.sections[i].base_address, buf_cnt, &mem_checksum);
2161 if( retval != ERROR_OK )
2162 {
2163 free(buffer);
2164 break;
2165 }
2166
2167 if( checksum != mem_checksum )
2168 {
2169 /* failed crc checksum, fall back to a binary compare */
2170 u8 *data;
2171
2172 command_print(cmd_ctx, "checksum mismatch - attempting binary compare");
2173
2174 data = (u8*)malloc(buf_cnt);
2175
2176 /* Can we use 32bit word accesses? */
2177 int size = 1;
2178 int count = buf_cnt;
2179 if ((count % 4) == 0)
2180 {
2181 size *= 4;
2182 count /= 4;
2183 }
2184 retval = target->type->read_memory(target, image.sections[i].base_address, size, count, data);
2185 if (retval == ERROR_OK)
2186 {
2187 int t;
2188 for (t = 0; t < buf_cnt; t++)
2189 {
2190 if (data[t] != buffer[t])
2191 {
2192 command_print(cmd_ctx, "Verify operation failed address 0x%08x. Was 0x%02x instead of 0x%02x\n", t + image.sections[i].base_address, data[t], buffer[t]);
2193 free(data);
2194 free(buffer);
2195 retval=ERROR_FAIL;
2196 goto done;
2197 }
2198 if ((t%16384)==0)
2199 {
2200 keep_alive();
2201 }
2202 }
2203 }
2204
2205 free(data);
2206 }
2207
2208 free(buffer);
2209 image_size += buf_cnt;
2210 }
2211 done:
2212
2213 if((retvaltemp = duration_stop_measure(&duration, &duration_text)) != ERROR_OK)
2214 {
2215 image_close(&image);
2216 return retvaltemp;
2217 }
2218
2219 if (retval==ERROR_OK)
2220 {
2221 command_print(cmd_ctx, "verified %u bytes in %s", image_size, duration_text);
2222 }
2223 free(duration_text);
2224
2225 image_close(&image);
2226
2227 return retval;
2228 }
2229
2230 int handle_bp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2231 {
2232 int retval;
2233 target_t *target = get_current_target(cmd_ctx);
2234
2235 if (argc == 0)
2236 {
2237 breakpoint_t *breakpoint = target->breakpoints;
2238
2239 while (breakpoint)
2240 {
2241 if (breakpoint->type == BKPT_SOFT)
2242 {
2243 char* buf = buf_to_str(breakpoint->orig_instr, breakpoint->length, 16);
2244 command_print(cmd_ctx, "0x%8.8x, 0x%x, %i, 0x%s", breakpoint->address, breakpoint->length, breakpoint->set, buf);
2245 free(buf);
2246 }
2247 else
2248 {
2249 command_print(cmd_ctx, "0x%8.8x, 0x%x, %i", breakpoint->address, breakpoint->length, breakpoint->set);
2250 }
2251 breakpoint = breakpoint->next;
2252 }
2253 }
2254 else if (argc >= 2)
2255 {
2256 int hw = BKPT_SOFT;
2257 u32 length = 0;
2258
2259 length = strtoul(args[1], NULL, 0);
2260
2261 if (argc >= 3)
2262 if (strcmp(args[2], "hw") == 0)
2263 hw = BKPT_HARD;
2264
2265 if ((retval = breakpoint_add(target, strtoul(args[0], NULL, 0), length, hw)) != ERROR_OK)
2266 {
2267 LOG_ERROR("Failure setting breakpoints");
2268 }
2269 else
2270 {
2271 command_print(cmd_ctx, "breakpoint added at address 0x%8.8x", strtoul(args[0], NULL, 0));
2272 }
2273 }
2274 else
2275 {
2276 command_print(cmd_ctx, "usage: bp <address> <length> ['hw']");
2277 }
2278
2279 return ERROR_OK;
2280 }
2281
2282 int handle_rbp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2283 {
2284 target_t *target = get_current_target(cmd_ctx);
2285
2286 if (argc > 0)
2287 breakpoint_remove(target, strtoul(args[0], NULL, 0));
2288
2289 return ERROR_OK;
2290 }
2291
2292 int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2293 {
2294 target_t *target = get_current_target(cmd_ctx);
2295 int retval;
2296
2297 if (argc == 0)
2298 {
2299 watchpoint_t *watchpoint = target->watchpoints;
2300
2301 while (watchpoint)
2302 {
2303 command_print(cmd_ctx, "address: 0x%8.8x, len: 0x%8.8x, r/w/a: %i, value: 0x%8.8x, mask: 0x%8.8x", watchpoint->address, watchpoint->length, watchpoint->rw, watchpoint->value, watchpoint->mask);
2304 watchpoint = watchpoint->next;
2305 }
2306 }
2307 else if (argc >= 2)
2308 {
2309 enum watchpoint_rw type = WPT_ACCESS;
2310 u32 data_value = 0x0;
2311 u32 data_mask = 0xffffffff;
2312
2313 if (argc >= 3)
2314 {
2315 switch(args[2][0])
2316 {
2317 case 'r':
2318 type = WPT_READ;
2319 break;
2320 case 'w':
2321 type = WPT_WRITE;
2322 break;
2323 case 'a':
2324 type = WPT_ACCESS;
2325 break;
2326 default:
2327 command_print(cmd_ctx, "usage: wp <address> <length> [r/w/a] [value] [mask]");
2328 return ERROR_OK;
2329 }
2330 }
2331 if (argc >= 4)
2332 {
2333 data_value = strtoul(args[3], NULL, 0);
2334 }
2335 if (argc >= 5)
2336 {
2337 data_mask = strtoul(args[4], NULL, 0);
2338 }
2339
2340 if ((retval = watchpoint_add(target, strtoul(args[0], NULL, 0),
2341 strtoul(args[1], NULL, 0), type, data_value, data_mask)) != ERROR_OK)
2342 {
2343 LOG_ERROR("Failure setting breakpoints");
2344 }
2345 }
2346 else
2347 {
2348 command_print(cmd_ctx, "usage: wp <address> <length> [r/w/a] [value] [mask]");
2349 }
2350
2351 return ERROR_OK;
2352 }
2353
2354 int handle_rwp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2355 {
2356 target_t *target = get_current_target(cmd_ctx);
2357
2358 if (argc > 0)
2359 watchpoint_remove(target, strtoul(args[0], NULL, 0));
2360
2361 return ERROR_OK;
2362 }
2363
2364 int handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
2365 {
2366 int retval;
2367 target_t *target = get_current_target(cmd_ctx);
2368 u32 va;
2369 u32 pa;
2370
2371 if (argc != 1)
2372 {
2373 return ERROR_COMMAND_SYNTAX_ERROR;
2374 }
2375 va = strtoul(args[0], NULL, 0);
2376
2377 retval = target->type->virt2phys(target, va, &pa);
2378 if (retval == ERROR_OK)
2379 {
2380 command_print(cmd_ctx, "Physical address 0x%08x", pa);
2381 }
2382 else
2383 {
2384 /* lower levels will have logged a detailed error which is
2385 * forwarded to telnet/GDB session.
2386 */
2387 }
2388 return retval;
2389 }
2390 static void writeLong(FILE *f, int l)
2391 {
2392 int i;
2393 for (i=0; i<4; i++)
2394 {
2395 char c=(l>>(i*8))&0xff;
2396 fwrite(&c, 1, 1, f);
2397 }
2398
2399 }
2400 static void writeString(FILE *f, char *s)
2401 {
2402 fwrite(s, 1, strlen(s), f);
2403 }
2404
2405
2406
2407 // Dump a gmon.out histogram file.
2408 static void writeGmon(u32 *samples, int sampleNum, char *filename)
2409 {
2410 int i;
2411 FILE *f=fopen(filename, "w");
2412 if (f==NULL)
2413 return;
2414 fwrite("gmon", 1, 4, f);
2415 writeLong(f, 0x00000001); // Version
2416 writeLong(f, 0); // padding
2417 writeLong(f, 0); // padding
2418 writeLong(f, 0); // padding
2419
2420 fwrite("", 1, 1, f); // GMON_TAG_TIME_HIST
2421
2422 // figure out bucket size
2423 u32 min=samples[0];
2424 u32 max=samples[0];
2425 for (i=0; i<sampleNum; i++)
2426 {
2427 if (min>samples[i])
2428 {
2429 min=samples[i];
2430 }
2431 if (max<samples[i])
2432 {
2433 max=samples[i];
2434 }
2435 }
2436
2437 int addressSpace=(max-min+1);
2438
2439 static int const maxBuckets=256*1024; // maximum buckets.
2440 int length=addressSpace;
2441 if (length > maxBuckets)
2442 {
2443 length=maxBuckets;
2444 }
2445 int *buckets=malloc(sizeof(int)*length);
2446 if (buckets==NULL)
2447 {
2448 fclose(f);
2449 return;
2450 }
2451 memset(buckets, 0, sizeof(int)*length);
2452 for (i=0; i<sampleNum;i++)
2453 {
2454 u32 address=samples[i];
2455 long long a=address-min;
2456 long long b=length-1;
2457 long long c=addressSpace-1;
2458 int index=(a*b)/c; // danger!!!! int32 overflows
2459 buckets[index]++;
2460 }
2461
2462 // append binary memory gmon.out &profile_hist_hdr ((char*)&profile_hist_hdr + sizeof(struct gmon_hist_hdr))
2463 writeLong(f, min); // low_pc
2464 writeLong(f, max); // high_pc
2465 writeLong(f, length); // # of samples
2466 writeLong(f, 64000000); // 64MHz
2467 writeString(f, "seconds");
2468 for (i=0; i<(15-strlen("seconds")); i++)
2469 {
2470 fwrite("", 1, 1, f); // padding
2471 }
2472 writeString(f, "s");
2473
2474 // append binary memory gmon.out profile_hist_data (profile_hist_data + profile_hist_hdr.hist_size)
2475
2476 char *data=malloc(2*length);
2477 if (data!=NULL)
2478 {
2479 for (i=0; i<length;i++)
2480 {
2481 int val;
2482 val=buckets[i];
2483 if (val>65535)
2484 {
2485 val=65535;
2486 }
2487 data[i*2]=val&0xff;
2488 data[i*2+1]=(val>>8)&0xff;
2489 }
2490 free(buckets);
2491 fwrite(data, 1, length*2, f);
2492 free(data);
2493 } else
2494 {
2495 free(buckets);
2496 }
2497
2498 fclose(f);
2499 }
2500
2501 /* profiling samples the CPU PC as quickly as OpenOCD is able, which will be used as a random sampling of PC */
2502 int handle_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2503 {
2504 target_t *target = get_current_target(cmd_ctx);
2505 struct timeval timeout, now;
2506
2507 gettimeofday(&timeout, NULL);
2508 if (argc!=2)
2509 {
2510 return ERROR_COMMAND_SYNTAX_ERROR;
2511 }
2512 char *end;
2513 timeval_add_time(&timeout, strtoul(args[0], &end, 0), 0);
2514 if (*end)
2515 {
2516 return ERROR_OK;
2517 }
2518
2519 command_print(cmd_ctx, "Starting profiling. Halting and resuming the target as often as we can...");
2520
2521 static const int maxSample=10000;
2522 u32 *samples=malloc(sizeof(u32)*maxSample);
2523 if (samples==NULL)
2524 return ERROR_OK;
2525
2526 int numSamples=0;
2527 int retval=ERROR_OK;
2528 // hopefully it is safe to cache! We want to stop/restart as quickly as possible.
2529 reg_t *reg = register_get_by_name(target->reg_cache, "pc", 1);
2530
2531 for (;;)
2532 {
2533 target_poll(target);
2534 if (target->state == TARGET_HALTED)
2535 {
2536 u32 t=*((u32 *)reg->value);
2537 samples[numSamples++]=t;
2538 retval = target_resume(target, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */
2539 target_poll(target);
2540 alive_sleep(10); // sleep 10ms, i.e. <100 samples/second.
2541 } else if (target->state == TARGET_RUNNING)
2542 {
2543 // We want to quickly sample the PC.
2544 if((retval = target_halt(target)) != ERROR_OK)
2545 {
2546 free(samples);
2547 return retval;
2548 }
2549 } else
2550 {
2551 command_print(cmd_ctx, "Target not halted or running");
2552 retval=ERROR_OK;
2553 break;
2554 }
2555 if (retval!=ERROR_OK)
2556 {
2557 break;
2558 }
2559
2560 gettimeofday(&now, NULL);
2561 if ((numSamples>=maxSample) || ((now.tv_sec >= timeout.tv_sec) && (now.tv_usec >= timeout.tv_usec)))
2562 {
2563 command_print(cmd_ctx, "Profiling completed. %d samples.", numSamples);
2564 if((retval = target_poll(target)) != ERROR_OK)
2565 {
2566 free(samples);
2567 return retval;
2568 }
2569 if (target->state == TARGET_HALTED)
2570 {
2571 target_resume(target, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */
2572 }
2573 if((retval = target_poll(target)) != ERROR_OK)
2574 {
2575 free(samples);
2576 return retval;
2577 }
2578 writeGmon(samples, numSamples, args[1]);
2579 command_print(cmd_ctx, "Wrote %s", args[1]);
2580 break;
2581 }
2582 }
2583 free(samples);
2584
2585 return ERROR_OK;
2586 }
2587
2588 static int new_int_array_element(Jim_Interp * interp, const char *varname, int idx, u32 val)
2589 {
2590 char *namebuf;
2591 Jim_Obj *nameObjPtr, *valObjPtr;
2592 int result;
2593
2594 namebuf = alloc_printf("%s(%d)", varname, idx);
2595 if (!namebuf)
2596 return JIM_ERR;
2597
2598 nameObjPtr = Jim_NewStringObj(interp, namebuf, -1);
2599 valObjPtr = Jim_NewIntObj(interp, val);
2600 if (!nameObjPtr || !valObjPtr)
2601 {
2602 free(namebuf);
2603 return JIM_ERR;
2604 }
2605
2606 Jim_IncrRefCount(nameObjPtr);
2607 Jim_IncrRefCount(valObjPtr);
2608 result = Jim_SetVariable(interp, nameObjPtr, valObjPtr);
2609 Jim_DecrRefCount(interp, nameObjPtr);
2610 Jim_DecrRefCount(interp, valObjPtr);
2611 free(namebuf);
2612 /* printf("%s(%d) <= 0%08x\n", varname, idx, val); */
2613 return result;
2614 }
2615
2616 static int jim_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
2617 {
2618 command_context_t *context;
2619 target_t *target;
2620
2621 context = Jim_GetAssocData(interp, "context");
2622 if (context == NULL)
2623 {
2624 LOG_ERROR("mem2array: no command context");
2625 return JIM_ERR;
2626 }
2627 target = get_current_target(context);
2628 if (target == NULL)
2629 {
2630 LOG_ERROR("mem2array: no current target");
2631 return JIM_ERR;
2632 }
2633
2634 return target_mem2array(interp, target, argc,argv);
2635 }
2636
2637 static int target_mem2array(Jim_Interp *interp, target_t *target, int argc, Jim_Obj *const *argv)
2638 {
2639 long l;
2640 u32 width;
2641 u32 len;
2642 u32 addr;
2643 u32 count;
2644 u32 v;
2645 const char *varname;
2646 u8 buffer[4096];
2647 int i, n, e, retval;
2648
2649 /* argv[1] = name of array to receive the data
2650 * argv[2] = desired width
2651 * argv[3] = memory address
2652 * argv[4] = count of times to read
2653 */
2654 if (argc != 5) {
2655 Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems");
2656 return JIM_ERR;
2657 }
2658 varname = Jim_GetString(argv[1], &len);
2659 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
2660
2661 e = Jim_GetLong(interp, argv[2], &l);
2662 width = l;
2663 if (e != JIM_OK) {
2664 return e;
2665 }
2666
2667 e = Jim_GetLong(interp, argv[3], &l);
2668 addr = l;
2669 if (e != JIM_OK) {
2670 return e;
2671 }
2672 e = Jim_GetLong(interp, argv[4], &l);
2673 len = l;
2674 if (e != JIM_OK) {
2675 return e;
2676 }
2677 switch (width) {
2678 case 8:
2679 width = 1;
2680 break;
2681 case 16:
2682 width = 2;
2683 break;
2684 case 32:
2685 width = 4;
2686 break;
2687 default:
2688 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2689 Jim_AppendStrings( interp, Jim_GetResult(interp), "Invalid width param, must be 8/16/32", NULL );
2690 return JIM_ERR;
2691 }
2692 if (len == 0) {
2693 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2694 Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: zero width read?", NULL);
2695 return JIM_ERR;
2696 }
2697 if ((addr + (len * width)) < addr) {
2698 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2699 Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: addr + len - wraps to zero?", NULL);
2700 return JIM_ERR;
2701 }
2702 /* absurd transfer size? */
2703 if (len > 65536) {
2704 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2705 Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: absurd > 64K item request", NULL);
2706 return JIM_ERR;
2707 }
2708
2709 if ((width == 1) ||
2710 ((width == 2) && ((addr & 1) == 0)) ||
2711 ((width == 4) && ((addr & 3) == 0))) {
2712 /* all is well */
2713 } else {
2714 char buf[100];
2715 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2716 sprintf(buf, "mem2array address: 0x%08x is not aligned for %d byte reads", addr, width);
2717 Jim_AppendStrings(interp, Jim_GetResult(interp), buf , NULL);
2718 return JIM_ERR;
2719 }
2720
2721 /* Transfer loop */
2722
2723 /* index counter */
2724 n = 0;
2725 /* assume ok */
2726 e = JIM_OK;
2727 while (len) {
2728 /* Slurp... in buffer size chunks */
2729
2730 count = len; /* in objects.. */
2731 if (count > (sizeof(buffer)/width)) {
2732 count = (sizeof(buffer)/width);
2733 }
2734
2735 retval = target->type->read_memory( target, addr, width, count, buffer );
2736 if (retval != ERROR_OK) {
2737 /* BOO !*/
2738 LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed", addr, width, count);
2739 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2740 Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: cannot read memory", NULL);
2741 e = JIM_ERR;
2742 len = 0;
2743 } else {
2744 v = 0; /* shut up gcc */
2745 for (i = 0 ;i < count ;i++, n++) {
2746 switch (width) {
2747 case 4:
2748 v = target_buffer_get_u32(target, &buffer[i*width]);
2749 break;
2750 case 2:
2751 v = target_buffer_get_u16(target, &buffer[i*width]);
2752 break;
2753 case 1:
2754 v = buffer[i] & 0x0ff;
2755 break;
2756 }
2757 new_int_array_element(interp, varname, n, v);
2758 }
2759 len -= count;
2760 }
2761 }
2762
2763 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2764
2765 return JIM_OK;
2766 }
2767
2768 static int get_int_array_element(Jim_Interp * interp, const char *varname, int idx, u32 *val)
2769 {
2770 char *namebuf;
2771 Jim_Obj *nameObjPtr, *valObjPtr;
2772 int result;
2773 long l;
2774
2775 namebuf = alloc_printf("%s(%d)", varname, idx);
2776 if (!namebuf)
2777 return JIM_ERR;
2778
2779 nameObjPtr = Jim_NewStringObj(interp, namebuf, -1);
2780 if (!nameObjPtr)
2781 {
2782 free(namebuf);
2783 return JIM_ERR;
2784 }
2785
2786 Jim_IncrRefCount(nameObjPtr);
2787 valObjPtr = Jim_GetVariable(interp, nameObjPtr, JIM_ERRMSG);
2788 Jim_DecrRefCount(interp, nameObjPtr);
2789 free(namebuf);
2790 if (valObjPtr == NULL)
2791 return JIM_ERR;
2792
2793 result = Jim_GetLong(interp, valObjPtr, &l);
2794 /* printf("%s(%d) => 0%08x\n", varname, idx, val); */
2795 *val = l;
2796 return result;
2797 }
2798
2799 static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
2800 {
2801 command_context_t *context;
2802 target_t *target;
2803
2804 context = Jim_GetAssocData(interp, "context");
2805 if (context == NULL){
2806 LOG_ERROR("array2mem: no command context");
2807 return JIM_ERR;
2808 }
2809 target = get_current_target(context);
2810 if (target == NULL){
2811 LOG_ERROR("array2mem: no current target");
2812 return JIM_ERR;
2813 }
2814
2815 return target_array2mem( interp,target, argc, argv );
2816 }
2817
2818
2819 static int target_array2mem(Jim_Interp *interp, target_t *target, int argc, Jim_Obj *const *argv)
2820 {
2821 long l;
2822 u32 width;
2823 u32 len;
2824 u32 addr;
2825 u32 count;
2826 u32 v;
2827 const char *varname;
2828 u8 buffer[4096];
2829 int i, n, e, retval;
2830
2831 /* argv[1] = name of array to get the data
2832 * argv[2] = desired width
2833 * argv[3] = memory address
2834 * argv[4] = count to write
2835 */
2836 if (argc != 5) {
2837 Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems");
2838 return JIM_ERR;
2839 }
2840 varname = Jim_GetString(argv[1], &len);
2841 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
2842
2843 e = Jim_GetLong(interp, argv[2], &l);
2844 width = l;
2845 if (e != JIM_OK) {
2846 return e;
2847 }
2848
2849 e = Jim_GetLong(interp, argv[3], &l);
2850 addr = l;
2851 if (e != JIM_OK) {
2852 return e;
2853 }
2854 e = Jim_GetLong(interp, argv[4], &l);
2855 len = l;
2856 if (e != JIM_OK) {
2857 return e;
2858 }
2859 switch (width) {
2860 case 8:
2861 width = 1;
2862 break;
2863 case 16:
2864 width = 2;
2865 break;
2866 case 32:
2867 width = 4;
2868 break;
2869 default:
2870 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2871 Jim_AppendStrings( interp, Jim_GetResult(interp), "Invalid width param, must be 8/16/32", NULL );
2872 return JIM_ERR;
2873 }
2874 if (len == 0) {
2875 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2876 Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: zero width read?", NULL);
2877 return JIM_ERR;
2878 }
2879 if ((addr + (len * width)) < addr) {
2880 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2881 Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: addr + len - wraps to zero?", NULL);
2882 return JIM_ERR;
2883 }
2884 /* absurd transfer size? */
2885 if (len > 65536) {
2886 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2887 Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: absurd > 64K item request", NULL);
2888 return JIM_ERR;
2889 }
2890
2891 if ((width == 1) ||
2892 ((width == 2) && ((addr & 1) == 0)) ||
2893 ((width == 4) && ((addr & 3) == 0))) {
2894 /* all is well */
2895 } else {
2896 char buf[100];
2897 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2898 sprintf(buf, "array2mem address: 0x%08x is not aligned for %d byte reads", addr, width);
2899 Jim_AppendStrings(interp, Jim_GetResult(interp), buf , NULL);
2900 return JIM_ERR;
2901 }
2902
2903
2904 /* Transfer loop */
2905
2906 /* index counter */
2907 n = 0;
2908 /* assume ok */
2909 e = JIM_OK;
2910 while (len) {
2911 /* Slurp... in buffer size chunks */
2912
2913 count = len; /* in objects.. */
2914 if (count > (sizeof(buffer)/width)) {
2915 count = (sizeof(buffer)/width);
2916 }
2917
2918 v = 0; /* shut up gcc */
2919 for (i = 0 ;i < count ;i++, n++) {
2920 get_int_array_element(interp, varname, n, &v);
2921 switch (width) {
2922 case 4:
2923 target_buffer_set_u32(target, &buffer[i*width], v);
2924 break;
2925 case 2:
2926 target_buffer_set_u16(target, &buffer[i*width], v);
2927 break;
2928 case 1:
2929 buffer[i] = v & 0x0ff;
2930 break;
2931 }
2932 }
2933 len -= count;
2934
2935 retval = target->type->write_memory(target, addr, width, count, buffer);
2936 if (retval != ERROR_OK) {
2937 /* BOO !*/
2938 LOG_ERROR("array2mem: Write @ 0x%08x, w=%d, cnt=%d, failed", addr, width, count);
2939 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2940 Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: cannot read memory", NULL);
2941 e = JIM_ERR;
2942 len = 0;
2943 }
2944 }
2945
2946 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2947
2948 return JIM_OK;
2949 }
2950
2951 void
2952 target_all_handle_event( enum target_event e )
2953 {
2954 target_t *target;
2955
2956
2957 LOG_DEBUG( "**all*targets: event: %d, %s",
2958 e,
2959 Jim_Nvp_value2name_simple( nvp_target_event, e )->name );
2960
2961 target = all_targets;
2962 while (target){
2963 target_handle_event( target, e );
2964 target = target->next;
2965 }
2966 }
2967
2968 void
2969 target_handle_event( target_t *target, enum target_event e )
2970 {
2971 target_event_action_t *teap;
2972 int done;
2973
2974 teap = target->event_action;
2975
2976 done = 0;
2977 while( teap ){
2978 if( teap->event == e ){
2979 done = 1;
2980 LOG_DEBUG( "target: (%d) %s (%s) event: %d (%s) action: %s\n",
2981 target->target_number,
2982 target->cmd_name,
2983 target->type->name,
2984 e,
2985 Jim_Nvp_value2name_simple( nvp_target_event, e )->name,
2986 Jim_GetString( teap->body, NULL ) );
2987 if (Jim_EvalObj( interp, teap->body )!=JIM_OK)
2988 {
2989 Jim_PrintErrorMessage(interp);
2990 }
2991 }
2992 teap = teap->next;
2993 }
2994 if( !done ){
2995 LOG_DEBUG( "event: %d %s - no action",
2996 e,
2997 Jim_Nvp_value2name_simple( nvp_target_event, e )->name );
2998 }
2999 }
3000
3001 enum target_cfg_param {
3002 TCFG_TYPE,
3003 TCFG_EVENT,
3004 TCFG_WORK_AREA_VIRT,
3005 TCFG_WORK_AREA_PHYS,
3006 TCFG_WORK_AREA_SIZE,
3007 TCFG_WORK_AREA_BACKUP,
3008 TCFG_ENDIAN,
3009 TCFG_VARIANT,
3010 TCFG_CHAIN_POSITION,
3011 };
3012
3013
3014 static Jim_Nvp nvp_config_opts[] = {
3015 { .name = "-type", .value = TCFG_TYPE },
3016 { .name = "-event", .value = TCFG_EVENT },
3017 { .name = "-work-area-virt", .value = TCFG_WORK_AREA_VIRT },
3018 { .name = "-work-area-phys", .value = TCFG_WORK_AREA_PHYS },
3019 { .name = "-work-area-size", .value = TCFG_WORK_AREA_SIZE },
3020 { .name = "-work-area-backup", .value = TCFG_WORK_AREA_BACKUP },
3021 { .name = "-endian" , .value = TCFG_ENDIAN },
3022 { .name = "-variant", .value = TCFG_VARIANT },
3023 { .name = "-chain-position", .value = TCFG_CHAIN_POSITION },
3024
3025 { .name = NULL, .value = -1 }
3026 };
3027
3028
3029 static int
3030 target_configure( Jim_GetOptInfo *goi,
3031 target_t *target )
3032 {
3033 Jim_Nvp *n;
3034 Jim_Obj *o;
3035 jim_wide w;
3036 char *cp;
3037 int e;
3038
3039
3040 /* parse config or cget options ... */
3041 while( goi->argc > 0 ){
3042 Jim_SetEmptyResult( goi->interp );
3043 //Jim_GetOpt_Debug( goi );
3044
3045 if( target->type->target_jim_configure ){
3046 /* target defines a configure function */
3047 /* target gets first dibs on parameters */
3048 e = (*(target->type->target_jim_configure))( target, goi );
3049 if( e == JIM_OK ){
3050 /* more? */
3051 continue;
3052 }
3053 if( e == JIM_ERR ){
3054 /* An error */
3055 return e;
3056 }
3057 /* otherwise we 'continue' below */
3058 }
3059 e = Jim_GetOpt_Nvp( goi, nvp_config_opts, &n );
3060 if( e != JIM_OK ){
3061 Jim_GetOpt_NvpUnknown( goi, nvp_config_opts, 0 );
3062 return e;
3063 }
3064 switch( n->value ){
3065 case TCFG_TYPE:
3066 /* not setable */
3067 if( goi->isconfigure ){
3068 Jim_SetResult_sprintf( goi->interp, "not setable: %s", n->name );
3069 return JIM_ERR;
3070 } else {
3071 no_params:
3072 if( goi->argc != 0 ){
3073 Jim_WrongNumArgs( goi->interp, goi->argc, goi->argv, "NO PARAMS");
3074 return JIM_ERR;
3075 }
3076 }
3077 Jim_SetResultString( goi->interp, target->type->name, -1 );
3078 /* loop for more */
3079 break;
3080 case TCFG_EVENT:
3081 if( goi->argc == 0 ){
3082 Jim_WrongNumArgs( goi->interp, goi->argc, goi->argv, "-event ?event-name? ...");
3083 return JIM_ERR;
3084 }
3085
3086 e = Jim_GetOpt_Nvp( goi, nvp_target_event, &n );
3087 if( e != JIM_OK ){
3088 Jim_GetOpt_NvpUnknown( goi, nvp_target_event, 1 );
3089 return e;
3090 }
3091
3092 if( goi->isconfigure ){
3093 if( goi->argc != 1 ){
3094 Jim_WrongNumArgs( goi->interp, goi->argc, goi->argv, "-event ?event-name? ?EVENT-BODY?");
3095 return JIM_ERR;
3096 }
3097 } else {
3098 if( goi->argc != 0 ){
3099 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ?event-name?");
3100 return JIM_ERR;
3101 }
3102 }
3103
3104
3105 {
3106 target_event_action_t *teap;
3107
3108 teap = target->event_action;
3109 /* replace existing? */
3110 while( teap ){
3111 if( teap->event == n->value ){
3112 break;
3113 }
3114 teap = teap->next;
3115 }
3116
3117 if( goi->isconfigure ){
3118 if( teap == NULL ){
3119 /* create new */
3120 teap = calloc( 1, sizeof(*teap) );
3121 }
3122 teap->event = n->value;
3123 Jim_GetOpt_Obj( goi, &o );
3124 if( teap->body ){
3125 Jim_DecrRefCount( interp, teap->body );
3126 }
3127 teap->body = Jim_DuplicateObj( goi->interp, o );
3128 /*
3129 * FIXME:
3130 * Tcl/TK - "tk events" have a nice feature.
3131 * See the "BIND" command.
3132 * We should support that here.
3133 * You can specify %X and %Y in the event code.
3134 * The idea is: %T - target name.
3135 * The idea is: %N - target number
3136 * The idea is: %E - event name.
3137 */
3138 Jim_IncrRefCount( teap->body );
3139
3140 /* add to head of event list */
3141 teap->next = target->event_action;
3142 target->event_action = teap;
3143 Jim_SetEmptyResult(goi->interp);
3144 } else {
3145 /* get */
3146 if( teap == NULL ){
3147 Jim_SetEmptyResult( goi->interp );
3148 } else {
3149 Jim_SetResult( goi->interp, Jim_DuplicateObj( goi->interp, teap->body ) );
3150 }
3151 }
3152 }
3153 /* loop for more */
3154 break;
3155
3156 case TCFG_WORK_AREA_VIRT:
3157 if( goi->isconfigure ){
3158 target_free_all_working_areas(target);
3159 e = Jim_GetOpt_Wide( goi, &w );
3160 if( e != JIM_OK ){
3161 return e;
3162 }
3163 target->working_area_virt = w;
3164 } else {
3165 if( goi->argc != 0 ){
3166 goto no_params;
3167 }
3168 }
3169 Jim_SetResult( interp, Jim_NewIntObj( goi->interp, target->working_area_virt ) );
3170 /* loop for more */
3171 break;
3172
3173 case TCFG_WORK_AREA_PHYS:
3174 if( goi->isconfigure ){
3175 target_free_all_working_areas(target);
3176 e = Jim_GetOpt_Wide( goi, &w );
3177 if( e != JIM_OK ){
3178 return e;
3179 }
3180 target->working_area_phys = w;
3181 } else {
3182 if( goi->argc != 0 ){
3183 goto no_params;
3184 }
3185 }
3186 Jim_SetResult( interp, Jim_NewIntObj( goi->interp, target->working_area_phys ) );
3187 /* loop for more */
3188 break;
3189
3190 case TCFG_WORK_AREA_SIZE:
3191 if( goi->isconfigure ){
3192 target_free_all_working_areas(target);
3193 e = Jim_GetOpt_Wide( goi, &w );
3194 if( e != JIM_OK ){
3195 return e;
3196 }
3197 target->working_area_size = w;
3198 } else {
3199 if( goi->argc != 0 ){
3200 goto no_params;
3201 }
3202 }
3203 Jim_SetResult( interp, Jim_NewIntObj( goi->interp, target->working_area_size ) );
3204 /* loop for more */
3205 break;
3206
3207 case TCFG_WORK_AREA_BACKUP:
3208 if( goi->isconfigure ){
3209 target_free_all_working_areas(target);
3210 e = Jim_GetOpt_Wide( goi, &w );
3211 if( e != JIM_OK ){
3212 return e;
3213 }
3214 /* make this exactly 1 or 0 */
3215 target->backup_working_area = (!!w);
3216 } else {
3217 if( goi->argc != 0 ){
3218 goto no_params;
3219 }
3220 }
3221 Jim_SetResult( interp, Jim_NewIntObj( goi->interp, target->working_area_size ) );
3222 /* loop for more e*/
3223 break;
3224
3225 case TCFG_ENDIAN:
3226 if( goi->isconfigure ){
3227 e = Jim_GetOpt_Nvp( goi, nvp_target_endian, &n );
3228 if( e != JIM_OK ){
3229 Jim_GetOpt_NvpUnknown( goi, nvp_target_endian, 1 );
3230 return e;
3231 }
3232 target->endianness = n->value;
3233 } else {
3234 if( goi->argc != 0 ){
3235 goto no_params;
3236 }
3237 }
3238 n = Jim_Nvp_value2name_simple( nvp_target_endian, target->endianness );
3239 if( n->name == NULL ){
3240 target->endianness = TARGET_LITTLE_ENDIAN;
3241 n = Jim_Nvp_value2name_simple( nvp_target_endian, target->endianness );
3242 }
3243 Jim_SetResultString( goi->interp, n->name, -1 );
3244 /* loop for more */
3245 break;
3246
3247 case TCFG_VARIANT:
3248 if( goi->isconfigure ){
3249 if( goi->argc < 1 ){
3250 Jim_SetResult_sprintf( goi->interp,
3251 "%s ?STRING?",
3252 n->name );
3253 return JIM_ERR;
3254 }
3255 if( target->variant ){
3256 free((void *)(target->variant));
3257 }
3258 e = Jim_GetOpt_String( goi, &cp, NULL );
3259 target->variant = strdup(cp);
3260 } else {
3261 if( goi->argc != 0 ){
3262 goto no_params;
3263 }
3264 }
3265 Jim_SetResultString( goi->interp, target->variant,-1 );
3266 /* loop for more */
3267 break;
3268 case TCFG_CHAIN_POSITION:
3269 if( goi->isconfigure ){
3270 target_free_all_working_areas(target);
3271 e = Jim_GetOpt_Wide( goi, &w );
3272 if( e != JIM_OK ){
3273 return e;
3274 }
3275 /* make this exactly 1 or 0 */
3276 target->chain_position = w;
3277 } else {
3278 if( goi->argc != 0 ){
3279 goto no_params;
3280 }
3281 }
3282 Jim_SetResult( interp, Jim_NewIntObj( goi->interp, target->chain_position ) );
3283 /* loop for more e*/
3284 break;
3285 }
3286 } /* while( goi->argc ) */
3287 /* done - we return */
3288 return JIM_OK;
3289 }
3290
3291
3292 /** this is the 'tcl' handler for the target specific command */
3293 static int
3294 tcl_target_func( Jim_Interp *interp,
3295 int argc,
3296 Jim_Obj *const *argv )
3297 {
3298 Jim_GetOptInfo goi;
3299 jim_wide a,b,c;
3300 int x,y,z;
3301 u8 target_buf[32];
3302 Jim_Nvp *n;
3303 target_t *target;
3304 struct command_context_s *cmd_ctx;
3305 int e;
3306
3307
3308 enum {
3309 TS_CMD_CONFIGURE,
3310 TS_CMD_CGET,
3311
3312 TS_CMD_MWW, TS_CMD_MWH, TS_CMD_MWB,
3313 TS_CMD_MDW, TS_CMD_MDH, TS_CMD_MDB,
3314 TS_CMD_MRW, TS_CMD_MRH, TS_CMD_MRB,
3315 TS_CMD_MEM2ARRAY, TS_CMD_ARRAY2MEM,
3316 TS_CMD_EXAMINE,
3317 TS_CMD_POLL,
3318 TS_CMD_RESET,
3319 TS_CMD_HALT,
3320 TS_CMD_WAITSTATE,
3321 TS_CMD_EVENTLIST,
3322 TS_CMD_CURSTATE,
3323 TS_CMD_INVOKE_EVENT,
3324 };
3325
3326 static const Jim_Nvp target_options[] = {
3327 { .name = "configure", .value = TS_CMD_CONFIGURE },
3328 { .name = "cget", .value = TS_CMD_CGET },
3329 { .name = "mww", .value = TS_CMD_MWW },
3330 { .name = "mwh", .value = TS_CMD_MWH },
3331 { .name = "mwb", .value = TS_CMD_MWB },
3332 { .name = "mdw", .value = TS_CMD_MDW },
3333 { .name = "mdh", .value = TS_CMD_MDH },
3334 { .name = "mdb", .value = TS_CMD_MDB },
3335 { .name = "mem2array", .value = TS_CMD_MEM2ARRAY },
3336 { .name = "array2mem", .value = TS_CMD_ARRAY2MEM },
3337 { .name = "eventlist", .value = TS_CMD_EVENTLIST },
3338 { .name = "curstate", .value = TS_CMD_CURSTATE },
3339
3340 { .name = "arp_examine", .value = TS_CMD_EXAMINE },
3341 { .name = "arp_poll", .value = TS_CMD_POLL },
3342 { .name = "arp_reset", .value = TS_CMD_RESET },
3343 { .name = "arp_halt", .value = TS_CMD_HALT },
3344 { .name = "arp_waitstate", .value = TS_CMD_WAITSTATE },
3345 { .name = "invoke-event", .value = TS_CMD_INVOKE_EVENT },
3346
3347 { .name = NULL, .value = -1 },
3348 };
3349
3350
3351 /* go past the "command" */
3352 Jim_GetOpt_Setup( &goi, interp, argc-1, argv+1 );
3353
3354 target = Jim_CmdPrivData( goi.interp );
3355 cmd_ctx = Jim_GetAssocData(goi.interp, "context");
3356
3357 /* commands here are in an NVP table */
3358 e = Jim_GetOpt_Nvp( &goi, target_options, &n );
3359 if( e != JIM_OK ){
3360 Jim_GetOpt_NvpUnknown( &goi, target_options, 0 );
3361 return e;
3362 }
3363 // Assume blank result
3364 Jim_SetEmptyResult( goi.interp );
3365
3366 switch( n->value ){
3367 case TS_CMD_CONFIGURE:
3368 if( goi.argc < 2 ){
3369 Jim_WrongNumArgs( goi.interp, goi.argc, goi.argv, "missing: -option VALUE ...");
3370 return JIM_ERR;
3371 }
3372 goi.isconfigure = 1;
3373 return target_configure( &goi, target );
3374 case TS_CMD_CGET:
3375 // some things take params
3376 if( goi.argc < 1 ){
3377 Jim_WrongNumArgs( goi.interp, 0, goi.argv, "missing: ?-option?");
3378 return JIM_ERR;
3379 }
3380 goi.isconfigure = 0;
3381 return target_configure( &goi, target );
3382 break;
3383 case TS_CMD_MWW:
3384 case TS_CMD_MWH:
3385 case TS_CMD_MWB:
3386 /* argv[0] = cmd
3387 * argv[1] = address
3388 * argv[2] = data
3389 * argv[3] = optional count.
3390 */
3391
3392 if( (goi.argc == 3) || (goi.argc == 4) ){
3393 /* all is well */
3394 } else {
3395 mwx_error:
3396 Jim_SetResult_sprintf( goi.interp, "expected: %s ADDR DATA [COUNT]", n->name );
3397 return JIM_ERR;
3398 }
3399
3400 e = Jim_GetOpt_Wide( &goi, &a );
3401 if( e != JIM_OK ){
3402 goto mwx_error;
3403 }
3404
3405 e = Jim_GetOpt_Wide( &goi, &b );
3406 if( e != JIM_OK ){
3407 goto mwx_error;
3408 }
3409 if( goi.argc ){
3410 e = Jim_GetOpt_Wide( &goi, &c );
3411 if( e != JIM_OK ){
3412 goto mwx_error;
3413 }
3414 } else {
3415 c = 1;
3416 }
3417
3418 switch( n->value ){
3419 case TS_CMD_MWW:
3420 target_buffer_set_u32( target, target_buf, b );
3421 b = 4;
3422 break;
3423 case TS_CMD_MWH:
3424 target_buffer_set_u16( target, target_buf, b );
3425 b = 2;
3426 break;
3427 case TS_CMD_MWB:
3428 target_buffer_set_u8( target, target_buf, b );
3429 b = 1;
3430 break;
3431 }
3432 for( x = 0 ; x < c ; x++ ){
3433 e = target->type->write_memory( target, a, b, 1, target_buf );
3434 if( e != ERROR_OK ){
3435 Jim_SetResult_sprintf( interp, "Error writing @ 0x%08x: %d\n", (int)(a), e );
3436 return JIM_ERR;
3437 }
3438 /* b = width */
3439 a = a + b;
3440 }
3441 return JIM_OK;
3442 break;
3443
3444 /* display */
3445 case TS_CMD_MDW:
3446 case TS_CMD_MDH:
3447 case TS_CMD_MDB:
3448 /* argv[0] = command
3449 * argv[1] = address
3450 * argv[2] = optional count
3451 */
3452 if( (goi.argc == 2) || (goi.argc == 3) ){
3453 Jim_SetResult_sprintf( goi.interp, "expected: %s ADDR [COUNT]", n->name );
3454 return JIM_ERR;
3455 }
3456 e = Jim_GetOpt_Wide( &goi, &a );
3457 if( e != JIM_OK ){
3458 return JIM_ERR;
3459 }
3460 if( goi.argc ){
3461 e = Jim_GetOpt_Wide( &goi, &c );
3462 if( e != JIM_OK ){
3463 return JIM_ERR;
3464 }
3465 } else {
3466 c = 1;
3467 }
3468 b = 1; /* shut up gcc */
3469 switch( n->value ){
3470 case TS_CMD_MDW:
3471 b = 4;
3472 break;
3473 case TS_CMD_MDH:
3474 b = 2;
3475 break;
3476 case TS_CMD_MDB:
3477 b = 1;
3478 break;
3479 }
3480
3481 /* convert to "bytes" */
3482 c = c * b;
3483 /* count is now in 'BYTES' */
3484 while( c > 0 ){
3485 y = c;
3486 if( y > 16 ){
3487 y = 16;
3488 }
3489 e = target->type->read_memory( target, a, b, y / b, target_buf );
3490 if( e != ERROR_OK ){
3491 Jim_SetResult_sprintf( interp, "error reading target @ 0x%08lx", (int)(a) );
3492 return JIM_ERR;
3493 }
3494
3495 Jim_fprintf( interp, interp->cookie_stdout, "0x%08x ", (int)(a) );
3496 switch( b ){
3497 case 4:
3498 for( x = 0 ; (x < 16) && (x < y) ; x += 4 ){
3499 z = target_buffer_get_u32( target, &(target_buf[ x * 4 ]) );
3500 Jim_fprintf( interp, interp->cookie_stdout, "%08x ", (int)(z) );
3501 }
3502 for( ; (x < 16) ; x += 4 ){
3503 Jim_fprintf( interp, interp->cookie_stdout, " " );
3504 }
3505 break;
3506 case 2:
3507 for( x = 0 ; (x < 16) && (x < y) ; x += 2 ){
3508 z = target_buffer_get_u16( target, &(target_buf[ x * 2 ]) );
3509 Jim_fprintf( interp, interp->cookie_stdout, "%04x ", (int)(z) );
3510 }
3511 for( ; (x < 16) ; x += 2 ){
3512 Jim_fprintf( interp, interp->cookie_stdout, " " );
3513 }
3514 break;
3515 case 1:
3516 default:
3517 for( x = 0 ; (x < 16) && (x < y) ; x += 1 ){
3518 z = target_buffer_get_u8( target, &(target_buf[ x * 4 ]) );
3519 Jim_fprintf( interp, interp->cookie_stdout, "%02x ", (int)(z) );
3520 }
3521 for( ; (x < 16) ; x += 1 ){
3522 Jim_fprintf( interp, interp->cookie_stdout, " " );
3523 }
3524 break;
3525 }
3526 /* ascii-ify the bytes */
3527 for( x = 0 ; x < y ; x++ ){
3528 if( (target_buf[x] >= 0x20) &&
3529 (target_buf[x] <= 0x7e) ){
3530 /* good */
3531 } else {
3532 /* smack it */
3533 target_buf[x] = '.';
3534 }
3535 }
3536 /* space pad */
3537 while( x < 16 ){
3538 target_buf[x] = ' ';
3539 x++;
3540 }
3541 /* terminate */
3542 target_buf[16] = 0;
3543 /* print - with a newline */
3544 Jim_fprintf( interp, interp->cookie_stdout, "%s\n", target_buf );
3545 /* NEXT... */
3546 c -= 16;
3547 a += 16;
3548 }
3549 return JIM_OK;
3550 case TS_CMD_MEM2ARRAY:
3551 return target_mem2array( goi.interp, target, goi.argc, goi.argv );
3552 break;
3553 case TS_CMD_ARRAY2MEM:
3554 return target_array2mem( goi.interp, target, goi.argc, goi.argv );
3555 break;
3556 case TS_CMD_EXAMINE:
3557 if( goi.argc ){
3558 Jim_WrongNumArgs( goi.interp, 2, argv, "[no parameters]");
3559 return JIM_ERR;
3560 }
3561 e = target->type->examine( target );
3562 if( e != ERROR_OK ){
3563 Jim_SetResult_sprintf( interp, "examine-fails: %d", e );
3564 return JIM_ERR;
3565 }
3566 return JIM_OK;
3567 case TS_CMD_POLL:
3568 if( goi.argc ){
3569 Jim_WrongNumArgs( goi.interp, 2, argv, "[no parameters]");
3570 return JIM_ERR;
3571 }
3572 if( !(target->type->examined) ){
3573 e = ERROR_TARGET_NOT_EXAMINED;
3574 } else {
3575 e = target->type->poll( target );
3576 }
3577 if( e != ERROR_OK ){
3578 Jim_SetResult_sprintf( interp, "poll-fails: %d", e );
3579 return JIM_ERR;
3580 } else {
3581 return JIM_OK;
3582 }
3583 break;
3584 case TS_CMD_RESET:
3585 if( goi.argc != 2 ){
3586 Jim_WrongNumArgs( interp, 2, argv, "t|f|assert|deassert BOOL");
3587 return JIM_ERR;
3588 }
3589 e = Jim_GetOpt_Nvp( &goi, nvp_assert, &n );
3590 if( e != JIM_OK ){
3591 Jim_GetOpt_NvpUnknown( &goi, nvp_assert, 1 );
3592 return e;
3593 }
3594 // the halt or not param
3595 e = Jim_GetOpt_Wide( &goi, &a);
3596 if( e != JIM_OK ){
3597 return e;
3598 }
3599 // determine if we should halt or not.
3600 target->reset_halt = !!a;
3601 // When this happens - all workareas are invalid.
3602 target_free_all_working_areas_restore(target, 0);
3603
3604 // do the assert
3605 if( n->value == NVP_ASSERT ){
3606 target->type->assert_reset( target );
3607 } else {
3608 target->type->deassert_reset( target );
3609 }
3610 return JIM_OK;
3611 case TS_CMD_HALT:
3612 if( goi.argc ){
3613 Jim_WrongNumArgs( goi.interp, 0, argv, "halt [no parameters]");
3614 return JIM_ERR;
3615 }
3616 target->type->halt( target );
3617 return JIM_OK;
3618 case TS_CMD_WAITSTATE:
3619 // params: <name> statename timeoutmsecs
3620 if( goi.argc != 2 ){
3621 Jim_SetResult_sprintf( goi.interp, "%s STATENAME TIMEOUTMSECS", n->name );
3622 return JIM_ERR;
3623 }
3624 e = Jim_GetOpt_Nvp( &goi, nvp_target_state, &n );
3625 if( e != JIM_OK ){
3626 Jim_GetOpt_NvpUnknown( &goi, nvp_target_state,1 );
3627 return e;
3628 }
3629 e = Jim_GetOpt_Wide( &goi, &a );
3630 if( e != JIM_OK ){
3631 return e;
3632 }
3633 e = target_wait_state( target, n->value, a );
3634 if( e != ERROR_OK ){
3635 Jim_SetResult_sprintf( goi.interp,
3636 "target: %s wait %s fails (%d) %s",
3637 target->cmd_name,
3638 n->name,
3639 e, target_strerror_safe(e) );
3640 return JIM_ERR;
3641 } else {
3642 return JIM_OK;
3643 }
3644 case TS_CMD_EVENTLIST:
3645 /* List for human, Events defined for this target.
3646 * scripts/programs should use 'name cget -event NAME'
3647 */
3648 {
3649 target_event_action_t *teap;
3650 teap = target->event_action;
3651 command_print( cmd_ctx, "Event actions for target (%d) %s\n",
3652 target->target_number,
3653 target->cmd_name );
3654 command_print( cmd_ctx, "%-25s | Body", "Event");
3655 command_print( cmd_ctx, "------------------------- | ----------------------------------------");
3656 while( teap ){
3657 command_print( cmd_ctx,
3658 "%-25s | %s",
3659 Jim_Nvp_value2name_simple( nvp_target_event, teap->event )->name,
3660 Jim_GetString( teap->body, NULL ) );
3661 teap = teap->next;
3662 }
3663 command_print( cmd_ctx, "***END***");
3664 return JIM_OK;
3665 }
3666 case TS_CMD_CURSTATE:
3667 if( goi.argc != 0 ){
3668 Jim_WrongNumArgs( goi.interp, 0, argv, "[no parameters]");
3669 return JIM_ERR;
3670 }
3671 Jim_SetResultString( goi.interp,
3672 Jim_Nvp_value2name_simple(nvp_target_state,target->state)->name,-1);
3673 return JIM_OK;
3674 case TS_CMD_INVOKE_EVENT:
3675 if( goi.argc != 1 ){
3676 Jim_SetResult_sprintf( goi.interp, "%s ?EVENTNAME?",n->name);
3677 return JIM_ERR;
3678 }
3679 e = Jim_GetOpt_Nvp( &goi, nvp_target_event, &n );
3680 if( e != JIM_OK ){
3681 Jim_GetOpt_NvpUnknown( &goi, nvp_target_event, 1 );
3682 return e;
3683 }
3684 target_handle_event( target, n->value );
3685 return JIM_OK;
3686 }
3687 return JIM_ERR;
3688 }
3689
3690
3691 static int
3692 target_create( Jim_GetOptInfo *goi )
3693 {
3694
3695 Jim_Obj *new_cmd;
3696 Jim_Cmd *cmd;
3697 const char *cp;
3698 char *cp2;
3699 int e;
3700 int x;
3701 target_t *target;
3702 struct command_context_s *cmd_ctx;
3703
3704 cmd_ctx = Jim_GetAssocData(goi->interp, "context");
3705 if( goi->argc < 3 ){
3706 Jim_WrongNumArgs( goi->interp, 1, goi->argv, "?name? ?type? ..options...");
3707 return JIM_ERR;
3708 }
3709
3710 /* COMMAND */
3711 Jim_GetOpt_Obj( goi, &new_cmd );
3712 /* does this command exist? */
3713 cmd = Jim_GetCommand( goi->interp, new_cmd, JIM_ERRMSG );
3714 if( cmd ){
3715 cp = Jim_GetString( new_cmd, NULL );
3716 Jim_SetResult_sprintf(goi->interp, "Command/target: %s Exists", cp);
3717 return JIM_ERR;
3718 }
3719
3720 /* TYPE */
3721 e = Jim_GetOpt_String( goi, &cp2, NULL );
3722 cp = cp2;
3723 /* now does target type exist */
3724 for( x = 0 ; target_types[x] ; x++ ){
3725 if( 0 == strcmp( cp, target_types[x]->name ) ){
3726 /* found */
3727 break;
3728 }
3729 }
3730 if( target_types[x] == NULL ){
3731 Jim_SetResult_sprintf( goi->interp, "Unknown target type %s, try one of ", cp );
3732 for( x = 0 ; target_types[x] ; x++ ){
3733 if( target_types[x+1] ){
3734 Jim_AppendStrings( goi->interp,
3735 Jim_GetResult(goi->interp),
3736 target_types[x]->name,
3737 ", ", NULL);
3738 } else {
3739 Jim_AppendStrings( goi->interp,
3740 Jim_GetResult(goi->interp),
3741 " or ",
3742 target_types[x]->name,NULL );
3743 }
3744 }
3745 return JIM_ERR;
3746 }
3747
3748
3749 /* Create it */
3750 target = calloc(1,sizeof(target_t));
3751 /* set target number */
3752 target->target_number = new_target_number();
3753
3754 /* allocate memory for each unique target type */
3755 target->type = (target_type_t*)calloc(1,sizeof(target_type_t));
3756
3757 memcpy( target->type, target_types[x], sizeof(target_type_t));
3758
3759 /* will be set by "-endian" */
3760 target->endianness = TARGET_ENDIAN_UNKNOWN;
3761
3762 target->working_area = 0x0;
3763 target->working_area_size = 0x0;
3764 target->working_areas = NULL;
3765 target->backup_working_area = 0;
3766
3767 target->state = TARGET_UNKNOWN;
3768 target->debug_reason = DBG_REASON_UNDEFINED;
3769 target->reg_cache = NULL;
3770 target->breakpoints = NULL;
3771 target->watchpoints = NULL;
3772 target->next = NULL;
3773 target->arch_info = NULL;
3774
3775 /* initialize trace information */
3776 target->trace_info = malloc(sizeof(trace_t));
3777 target->trace_info->num_trace_points = 0;
3778 target->trace_info->trace_points_size = 0;
3779 target->trace_info->trace_points = NULL;
3780 target->trace_info->trace_history_size = 0;
3781 target->trace_info->trace_history = NULL;
3782 target->trace_info->trace_history_pos = 0;
3783 target->trace_info->trace_history_overflowed = 0;
3784
3785 target->dbgmsg = NULL;
3786 target->dbg_msg_enabled = 0;
3787
3788 target->endianness = TARGET_ENDIAN_UNKNOWN;
3789
3790 /* Do the rest as "configure" options */
3791 goi->isconfigure = 1;
3792 e = target_configure( goi, target);
3793 if( e != JIM_OK ){
3794 free( target->type );
3795 free( target );
3796 return e;
3797 }
3798
3799 if( target->endianness == TARGET_ENDIAN_UNKNOWN ){
3800 /* default endian to little if not specified */
3801 target->endianness = TARGET_LITTLE_ENDIAN;
3802 }
3803
3804 /* create the target specific commands */
3805 if( target->type->register_commands ){
3806 (*(target->type->register_commands))( cmd_ctx );
3807 }
3808 if( target->type->target_create ){
3809 (*(target->type->target_create))( target, goi->interp );
3810 }
3811
3812 /* append to end of list */
3813 {
3814 target_t **tpp;
3815 tpp = &(all_targets);
3816 while( *tpp ){
3817 tpp = &( (*tpp)->next );
3818 }
3819 *tpp = target;
3820 }
3821
3822 cp = Jim_GetString( new_cmd, NULL );
3823 target->cmd_name = strdup(cp);
3824
3825 /* now - create the new target name command */
3826 e = Jim_CreateCommand( goi->interp,
3827 /* name */
3828 cp,
3829 tcl_target_func, /* C function */
3830 target, /* private data */
3831 NULL ); /* no del proc */
3832
3833 (*(target->type->target_create))( target, goi->interp );
3834 return e;
3835 }
3836
3837 static int
3838 jim_target( Jim_Interp *interp, int argc, Jim_Obj *const *argv )
3839 {
3840 int x,r,e;
3841 jim_wide w;
3842 struct command_context_s *cmd_ctx;
3843 const char *cp;
3844 target_t *target;
3845 Jim_GetOptInfo goi;
3846 enum tcmd {
3847 /* TG = target generic */
3848 TG_CMD_CREATE,
3849 TG_CMD_TYPES,
3850 TG_CMD_NAMES,
3851 TG_CMD_CURRENT,
3852 TG_CMD_NUMBER,
3853 TG_CMD_COUNT,
3854 };
3855 const char *target_cmds[] = {
3856 "create", "types", "names", "current", "number",
3857 "count",
3858 NULL // terminate
3859 };
3860
3861 LOG_DEBUG("Target command params:");
3862 LOG_DEBUG(Jim_Debug_ArgvString( interp, argc, argv) );
3863
3864 cmd_ctx = Jim_GetAssocData( interp, "context" );
3865
3866 Jim_GetOpt_Setup( &goi, interp, argc-1, argv+1 );
3867
3868 if( goi.argc == 0 ){
3869 Jim_WrongNumArgs(interp, 1, argv, "missing: command ...");
3870 return JIM_ERR;
3871 }
3872
3873 /* is this old syntax? */
3874 /* To determine: We have to peek at argv[0]*/
3875 cp = Jim_GetString( goi.argv[0], NULL );
3876 for( x = 0 ; target_types[x] ; x++ ){
3877 if( 0 == strcmp(cp,target_types[x]->name) ){
3878 break;
3879 }
3880 }
3881 if( target_types[x] ){
3882 /* YES IT IS OLD SYNTAX */
3883 Jim_Obj *new_argv[10];
3884 int new_argc;
3885
3886 /* target_old_syntax
3887 *
3888 * argv[0] typename (above)
3889 * argv[1] endian
3890 * argv[2] reset method, deprecated/ignored
3891 * argv[3] = old param
3892 * argv[4] = old param
3893 *
3894 * We will combine all "old params" into a single param.
3895 * Then later, split them again.
3896 */
3897 if( argc < 4 ){
3898 Jim_WrongNumArgs( interp, 1, argv, "[OLDSYNTAX] ?TYPE? ?ENDIAN? ?RESET? ?old-params?");
3899 return JIM_ERR;
3900 }
3901 /* the command */
3902 new_argv[0] = argv[0];
3903 new_argv[1] = Jim_NewStringObj( interp, "create", -1 );
3904 {
3905 char buf[ 30 ];
3906 sprintf( buf, "target%d", new_target_number() );
3907 new_argv[2] = Jim_NewStringObj( interp, buf , -1 );
3908 }
3909 new_argv[3] = goi.argv[0]; /* typename */
3910 new_argv[4] = Jim_NewStringObj( interp, "-endian", -1 );
3911 new_argv[5] = goi.argv[1];
3912 new_argv[6] = Jim_NewStringObj( interp, "-chain-position", -1 );
3913 new_argv[7] = goi.argv[2];
3914 new_argv[8] = Jim_NewStringObj( interp, "-variant", -1 );
3915 new_argv[9] = goi.argv[3];
3916 new_argc = 10;
3917 /*
3918 * new arg syntax:
3919 * argv[0] = command
3920 * argv[1] = create
3921 * argv[2] = cmdname
3922 * argv[3] = typename
3923 * argv[4] = **FIRST** "configure" option.
3924 *
3925 * Here, we make them:
3926 *
3927 * argv[4] = -endian
3928 * argv[5] = little
3929 * argv[6] = -position
3930 * argv[7] = NUMBER
3931 * argv[8] = -variant
3932 * argv[9] = "somestring"
3933 */
3934
3935 /* don't let these be released */
3936 for( x = 0 ; x < new_argc ; x++ ){
3937 Jim_IncrRefCount( new_argv[x]);
3938 }
3939 /* call our self */
3940 LOG_DEBUG("Target OLD SYNTAX - converted to new syntax");
3941
3942 r = jim_target( goi.interp, new_argc, new_argv );
3943
3944 /* release? these items */
3945 for( x = 0 ; x < new_argc ; x++ ){
3946 Jim_DecrRefCount( interp, new_argv[x] );
3947 }
3948 return r;
3949 }
3950
3951 //Jim_GetOpt_Debug( &goi );
3952 r = Jim_GetOpt_Enum( &goi, target_cmds, &x );
3953 if( r != JIM_OK ){
3954 return r;
3955 }
3956
3957 switch(x){
3958 default:
3959 Jim_Panic(goi.interp,"Why am I here?");
3960 return JIM_ERR;
3961 case TG_CMD_CURRENT:
3962 if( goi.argc != 0 ){
3963 Jim_WrongNumArgs( goi.interp, 1, goi.argv, "Too many parameters");
3964 return JIM_ERR;
3965 }
3966 Jim_SetResultString( goi.interp, get_current_target( cmd_ctx )->cmd_name, -1 );
3967 return JIM_OK;
3968 case TG_CMD_TYPES:
3969 if( goi.argc != 0 ){
3970 Jim_WrongNumArgs( goi.interp, 1, goi.argv, "Too many parameters" );
3971 return JIM_ERR;
3972 }
3973 Jim_SetResult( goi.interp, Jim_NewListObj( goi.interp, NULL, 0 ) );
3974 for( x = 0 ; target_types[x] ; x++ ){
3975 Jim_ListAppendElement( goi.interp,
3976 Jim_GetResult(goi.interp),
3977 Jim_NewStringObj( goi.interp, target_types[x]->name, -1 ) );
3978 }
3979 return JIM_OK;
3980 case TG_CMD_NAMES:
3981 if( goi.argc != 0 ){
3982 Jim_WrongNumArgs( goi.interp, 1, goi.argv, "Too many parameters" );
3983 return JIM_ERR;
3984 }
3985 Jim_SetResult( goi.interp, Jim_NewListObj( goi.interp, NULL, 0 ) );
3986 target = all_targets;
3987 while( target ){
3988 Jim_ListAppendElement( goi.interp,
3989 Jim_GetResult(goi.interp),
3990 Jim_NewStringObj( goi.interp, target->cmd_name, -1 ) );
3991 target = target->next;
3992 }
3993 return JIM_OK;
3994 case TG_CMD_CREATE:
3995 if( goi.argc < 3 ){
3996 Jim_WrongNumArgs( goi.interp, goi.argc, goi.argv, "?name ... config options ...");
3997 return JIM_ERR;
3998 }
3999 return target_create( &goi );
4000 break;
4001 case TG_CMD_NUMBER:
4002 if( goi.argc != 1 ){
4003 Jim_SetResult_sprintf( goi.interp, "expected: target number ?NUMBER?");
4004 return JIM_ERR;
4005 }
4006 e = Jim_GetOpt_Wide( &goi, &w );
4007 if( e != JIM_OK ){
4008 return JIM_ERR;
4009 }
4010 {
4011 target_t *t;
4012 t = get_target_by_num(w);
4013 if( t == NULL ){
4014 Jim_SetResult_sprintf( goi.interp,"Target: number %d does not exist", (int)(w));
4015 return JIM_ERR;
4016 }
4017 Jim_SetResultString( goi.interp, t->cmd_name, -1 );
4018 return JIM_OK;
4019 }
4020 case TG_CMD_COUNT:
4021 if( goi.argc != 0 ){
4022 Jim_WrongNumArgs( goi.interp, 0, goi.argv, "<no parameters>");
4023 return JIM_ERR;
4024 }
4025 Jim_SetResult( goi.interp,
4026 Jim_NewIntObj( goi.interp, max_target_number()));
4027 return JIM_OK;
4028 }
4029
4030 return JIM_ERR;
4031 }

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)