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

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)