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

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)