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

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)