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

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)