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

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)