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

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)