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

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)