1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2007,2008 Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
8 * Copyright (C) 2008, Duane Ellis *
9 * openocd@duaneeellis.com *
11 * Copyright (C) 2008 by Spencer Oliver *
12 * spen@spen-soft.co.uk *
14 * Copyright (C) 2008 by Rick Altherr *
15 * kc8apf@kc8apf.net> *
17 * This program is free software; you can redistribute it and/or modify *
18 * it under the terms of the GNU General Public License as published by *
19 * the Free Software Foundation; either version 2 of the License, or *
20 * (at your option) any later version. *
22 * This program is distributed in the hope that it will be useful, *
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
25 * GNU General Public License for more details. *
27 * You should have received a copy of the GNU General Public License *
28 * along with this program; if not, write to the *
29 * Free Software Foundation, Inc., *
30 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
31 ***************************************************************************/
36 #include "replacements.h"
38 #include "target_request.h"
41 #include "configuration.h"
42 #include "binarybuffer.h"
49 #include <sys/types.h>
57 #include <time_support.h>
62 int cli_target_callback_event_handler(struct target_s
*target
, enum target_event event
, void *priv
);
65 int handle_targets_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
67 int handle_working_area_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
69 int handle_reg_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
70 int handle_poll_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
71 int handle_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
72 int handle_wait_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
73 int handle_reset_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
74 int handle_soft_reset_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
75 int handle_resume_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
76 int handle_step_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
77 int handle_md_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
78 int handle_mw_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
79 int handle_load_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
80 int handle_dump_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
81 int handle_verify_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
82 int handle_bp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
83 int handle_rbp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
84 int handle_wp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
85 int handle_rwp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
86 int handle_virt2phys_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
);
87 int handle_profile_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
88 static int jim_array2mem(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
);
89 static int jim_mem2array(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
);
90 static int jim_target( Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
);
92 static int target_array2mem(Jim_Interp
*interp
, target_t
*target
, int argc
, Jim_Obj
*const *argv
);
93 static int target_mem2array(Jim_Interp
*interp
, target_t
*target
, int argc
, Jim_Obj
*const *argv
);
98 extern target_type_t arm7tdmi_target
;
99 extern target_type_t arm720t_target
;
100 extern target_type_t arm9tdmi_target
;
101 extern target_type_t arm920t_target
;
102 extern target_type_t arm966e_target
;
103 extern target_type_t arm926ejs_target
;
104 extern target_type_t feroceon_target
;
105 extern target_type_t xscale_target
;
106 extern target_type_t cortexm3_target
;
107 extern target_type_t arm11_target
;
108 extern target_type_t mips_m4k_target
;
110 target_type_t
*target_types
[] =
126 target_t
*all_targets
= NULL
;
127 target_event_callback_t
*target_event_callbacks
= NULL
;
128 target_timer_callback_t
*target_timer_callbacks
= NULL
;
130 const Jim_Nvp nvp_assert
[] = {
131 { .name
= "assert", NVP_ASSERT
},
132 { .name
= "deassert", NVP_DEASSERT
},
133 { .name
= "T", NVP_ASSERT
},
134 { .name
= "F", NVP_DEASSERT
},
135 { .name
= "t", NVP_ASSERT
},
136 { .name
= "f", NVP_DEASSERT
},
137 { .name
= NULL
, .value
= -1 }
140 const Jim_Nvp nvp_error_target
[] = {
141 { .value
= ERROR_TARGET_INVALID
, .name
= "err-invalid" },
142 { .value
= ERROR_TARGET_INIT_FAILED
, .name
= "err-init-failed" },
143 { .value
= ERROR_TARGET_TIMEOUT
, .name
= "err-timeout" },
144 { .value
= ERROR_TARGET_NOT_HALTED
, .name
= "err-not-halted" },
145 { .value
= ERROR_TARGET_FAILURE
, .name
= "err-failure" },
146 { .value
= ERROR_TARGET_UNALIGNED_ACCESS
, .name
= "err-unaligned-access" },
147 { .value
= ERROR_TARGET_DATA_ABORT
, .name
= "err-data-abort" },
148 { .value
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
, .name
= "err-resource-not-available" },
149 { .value
= ERROR_TARGET_TRANSLATION_FAULT
, .name
= "err-translation-fault" },
150 { .value
= ERROR_TARGET_NOT_RUNNING
, .name
= "err-not-running" },
151 { .value
= ERROR_TARGET_NOT_EXAMINED
, .name
= "err-not-examined" },
152 { .value
= -1, .name
= NULL
}
155 const char *target_strerror_safe( int err
)
159 n
= Jim_Nvp_value2name_simple( nvp_error_target
, err
);
160 if( n
->name
== NULL
){
167 const Jim_Nvp nvp_target_event
[] = {
168 { .value
= TARGET_EVENT_OLD_gdb_program_config
, .name
= "old-gdb_program_config" },
169 { .value
= TARGET_EVENT_OLD_pre_resume
, .name
= "old-pre_resume" },
172 { .value
= TARGET_EVENT_EARLY_HALTED
, .name
= "early-halted" },
173 { .value
= TARGET_EVENT_HALTED
, .name
= "halted" },
174 { .value
= TARGET_EVENT_RESUMED
, .name
= "resumed" },
175 { .value
= TARGET_EVENT_RESUME_START
, .name
= "resume-start" },
176 { .value
= TARGET_EVENT_RESUME_END
, .name
= "resume-end" },
178 /* historical name */
180 { .value
= TARGET_EVENT_RESET_START
, .name
= "reset-start" },
182 { .value
= TARGET_EVENT_RESET_ASSERT_PRE
, .name
= "reset-assert-pre" },
183 { .value
= TARGET_EVENT_RESET_ASSERT_POST
, .name
= "reset-assert-post" },
184 { .value
= TARGET_EVENT_RESET_DEASSERT_PRE
, .name
= "reset-deassert-pre" },
185 { .value
= TARGET_EVENT_RESET_DEASSERT_POST
, .name
= "reset-deassert-post" },
186 { .value
= TARGET_EVENT_RESET_HALT_PRE
, .name
= "reset-halt-pre" },
187 { .value
= TARGET_EVENT_RESET_HALT_POST
, .name
= "reset-halt-post" },
188 { .value
= TARGET_EVENT_RESET_WAIT_PRE
, .name
= "reset-wait-pre" },
189 { .value
= TARGET_EVENT_RESET_WAIT_POST
, .name
= "reset-wait-post" },
190 { .value
= TARGET_EVENT_RESET_INIT
, .name
= "reset-init" },
191 { .value
= TARGET_EVENT_RESET_END
, .name
= "reset-end" },
197 { .value
= TARGET_EVENT_EXAMINE_START
, .name
= "examine-start" },
198 { .value
= TARGET_EVENT_EXAMINE_START
, .name
= "examine-end" },
201 { .value
= TARGET_EVENT_DEBUG_HALTED
, .name
= "debug-halted" },
202 { .value
= TARGET_EVENT_DEBUG_RESUMED
, .name
= "debug-resumed" },
204 { .value
= TARGET_EVENT_GDB_ATTACH
, .name
= "gdb-attach" },
205 { .value
= TARGET_EVENT_GDB_DETACH
, .name
= "gdb-detach" },
208 { .value
= TARGET_EVENT_GDB_FLASH_WRITE_START
, .name
= "gdb-flash-write-start" },
209 { .value
= TARGET_EVENT_GDB_FLASH_WRITE_END
, .name
= "gdb-flash-write-end" },
211 { .value
= TARGET_EVENT_GDB_FLASH_ERASE_START
, .name
= "gdb-flash-erase-start" },
212 { .value
= TARGET_EVENT_GDB_FLASH_ERASE_END
, .name
= "gdb-flash-erase-end" },
214 { .value
= TARGET_EVENT_RESUME_START
, .name
= "resume-start" },
215 { .value
= TARGET_EVENT_RESUMED
, .name
= "resume-ok" },
216 { .value
= TARGET_EVENT_RESUME_END
, .name
= "resume-end" },
218 { .name
= NULL
, .value
= -1 }
221 const Jim_Nvp nvp_target_state
[] = {
222 { .name
= "unknown", .value
= TARGET_UNKNOWN
},
223 { .name
= "running", .value
= TARGET_RUNNING
},
224 { .name
= "halted", .value
= TARGET_HALTED
},
225 { .name
= "reset", .value
= TARGET_RESET
},
226 { .name
= "debug-running", .value
= TARGET_DEBUG_RUNNING
},
227 { .name
= NULL
, .value
= -1 },
231 const Jim_Nvp nvp_target_debug_reason
[] = {
232 { .name
= "debug-request" , .value
= DBG_REASON_DBGRQ
},
233 { .name
= "breakpoint" , .value
= DBG_REASON_BREAKPOINT
},
234 { .name
= "watchpoint" , .value
= DBG_REASON_WATCHPOINT
},
235 { .name
= "watchpoint-and-breakpoint", .value
= DBG_REASON_WPTANDBKPT
},
236 { .name
= "single-step" , .value
= DBG_REASON_SINGLESTEP
},
237 { .name
= "target-not-halted" , .value
= DBG_REASON_NOTHALTED
},
238 { .name
= "undefined" , .value
= DBG_REASON_UNDEFINED
},
239 { .name
= NULL
, .value
= -1 },
243 const Jim_Nvp nvp_target_endian
[] = {
244 { .name
= "big", .value
= TARGET_BIG_ENDIAN
},
245 { .name
= "little", .value
= TARGET_LITTLE_ENDIAN
},
246 { .name
= "be", .value
= TARGET_BIG_ENDIAN
},
247 { .name
= "le", .value
= TARGET_LITTLE_ENDIAN
},
248 { .name
= NULL
, .value
= -1 },
251 const Jim_Nvp nvp_reset_modes
[] = {
252 { .name
= "unknown", .value
= RESET_UNKNOWN
},
253 { .name
= "run" , .value
= RESET_RUN
},
254 { .name
= "halt" , .value
= RESET_HALT
},
255 { .name
= "init" , .value
= RESET_INIT
},
256 { .name
= NULL
, .value
= -1 },
260 max_target_number( void )
268 if( x
< t
->target_number
){
269 x
= (t
->target_number
)+1;
276 /* determine the number of the new target */
278 new_target_number( void )
283 /* number is 0 based */
287 if( x
< t
->target_number
){
288 x
= t
->target_number
;
295 static int target_continous_poll
= 1;
297 /* read a u32 from a buffer in target memory endianness */
298 u32
target_buffer_get_u32(target_t
*target
, u8
*buffer
)
300 if (target
->endianness
== TARGET_LITTLE_ENDIAN
)
301 return le_to_h_u32(buffer
);
303 return be_to_h_u32(buffer
);
306 /* read a u16 from a buffer in target memory endianness */
307 u16
target_buffer_get_u16(target_t
*target
, u8
*buffer
)
309 if (target
->endianness
== TARGET_LITTLE_ENDIAN
)
310 return le_to_h_u16(buffer
);
312 return be_to_h_u16(buffer
);
315 /* read a u8 from a buffer in target memory endianness */
316 u8
target_buffer_get_u8(target_t
*target
, u8
*buffer
)
318 return *buffer
& 0x0ff;
321 /* write a u32 to a buffer in target memory endianness */
322 void target_buffer_set_u32(target_t
*target
, u8
*buffer
, u32 value
)
324 if (target
->endianness
== TARGET_LITTLE_ENDIAN
)
325 h_u32_to_le(buffer
, value
);
327 h_u32_to_be(buffer
, value
);
330 /* write a u16 to a buffer in target memory endianness */
331 void target_buffer_set_u16(target_t
*target
, u8
*buffer
, u16 value
)
333 if (target
->endianness
== TARGET_LITTLE_ENDIAN
)
334 h_u16_to_le(buffer
, value
);
336 h_u16_to_be(buffer
, value
);
339 /* write a u8 to a buffer in target memory endianness */
340 void target_buffer_set_u8(target_t
*target
, u8
*buffer
, u8 value
)
345 /* returns a pointer to the n-th configured target */
346 target_t
* get_target_by_num(int num
)
348 target_t
*target
= all_targets
;
351 if( target
->target_number
== num
){
354 target
= target
->next
;
360 int get_num_by_target(target_t
*query_target
)
362 return query_target
->target_number
;
365 target_t
* get_current_target(command_context_t
*cmd_ctx
)
367 target_t
*target
= get_target_by_num(cmd_ctx
->current_target
);
371 LOG_ERROR("BUG: current_target out of bounds");
379 int target_poll(struct target_s
*target
)
381 /* We can't poll until after examine */
382 if (!target
->type
->examined
)
384 /* Fail silently lest we pollute the log */
387 return target
->type
->poll(target
);
390 int target_halt(struct target_s
*target
)
392 /* We can't poll until after examine */
393 if (!target
->type
->examined
)
395 LOG_ERROR("Target not examined yet");
398 return target
->type
->halt(target
);
401 int target_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
405 /* We can't poll until after examine */
406 if (!target
->type
->examined
)
408 LOG_ERROR("Target not examined yet");
412 /* note that resume *must* be asynchronous. The CPU can halt before we poll. The CPU can
413 * even halt at the current PC as a result of a software breakpoint being inserted by (a bug?)
416 if ((retval
= target
->type
->resume(target
, current
, address
, handle_breakpoints
, debug_execution
)) != ERROR_OK
)
423 int target_process_reset(struct command_context_s
*cmd_ctx
, enum target_reset_mode reset_mode
)
428 n
= Jim_Nvp_value2name_simple( nvp_reset_modes
, reset_mode
);
429 if( n
->name
== NULL
){
430 LOG_ERROR("invalid reset mode");
434 sprintf( buf
, "ocd_process_reset %s", n
->name
);
435 retval
= Jim_Eval( interp
, buf
);
437 if(retval
!= JIM_OK
) {
438 Jim_PrintErrorMessage(interp
);
442 /* We want any events to be processed before the prompt */
443 retval
= target_call_timer_callbacks_now();
449 static int default_virt2phys(struct target_s
*target
, u32
virtual, u32
*physical
)
455 static int default_mmu(struct target_s
*target
, int *enabled
)
461 static int default_examine(struct target_s
*target
)
463 target
->type
->examined
= 1;
468 /* Targets that correctly implement init+examine, i.e.
469 * no communication with target during init:
473 int target_examine(void)
475 int retval
= ERROR_OK
;
476 target_t
*target
= all_targets
;
479 if ((retval
= target
->type
->examine(target
))!=ERROR_OK
)
481 target
= target
->next
;
486 static int target_write_memory_imp(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
488 if (!target
->type
->examined
)
490 LOG_ERROR("Target not examined yet");
493 return target
->type
->write_memory_imp(target
, address
, size
, count
, buffer
);
496 static int target_read_memory_imp(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
498 if (!target
->type
->examined
)
500 LOG_ERROR("Target not examined yet");
503 return target
->type
->read_memory_imp(target
, address
, size
, count
, buffer
);
506 static int target_soft_reset_halt_imp(struct target_s
*target
)
508 if (!target
->type
->examined
)
510 LOG_ERROR("Target not examined yet");
513 return target
->type
->soft_reset_halt_imp(target
);
516 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
)
518 if (!target
->type
->examined
)
520 LOG_ERROR("Target not examined yet");
523 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
);
526 int target_init(struct command_context_s
*cmd_ctx
)
528 target_t
*target
= all_targets
;
533 target
->type
->examined
= 0;
534 if (target
->type
->examine
== NULL
)
536 target
->type
->examine
= default_examine
;
539 if ((retval
= target
->type
->init_target(cmd_ctx
, target
)) != ERROR_OK
)
541 LOG_ERROR("target '%s' init failed", target
->type
->name
);
545 /* Set up default functions if none are provided by target */
546 if (target
->type
->virt2phys
== NULL
)
548 target
->type
->virt2phys
= default_virt2phys
;
550 target
->type
->virt2phys
= default_virt2phys
;
551 /* a non-invasive way(in terms of patches) to add some code that
552 * runs before the type->write/read_memory implementation
554 target
->type
->write_memory_imp
= target
->type
->write_memory
;
555 target
->type
->write_memory
= target_write_memory_imp
;
556 target
->type
->read_memory_imp
= target
->type
->read_memory
;
557 target
->type
->read_memory
= target_read_memory_imp
;
558 target
->type
->soft_reset_halt_imp
= target
->type
->soft_reset_halt
;
559 target
->type
->soft_reset_halt
= target_soft_reset_halt_imp
;
560 target
->type
->run_algorithm_imp
= target
->type
->run_algorithm
;
561 target
->type
->run_algorithm
= target_run_algorithm_imp
;
564 if (target
->type
->mmu
== NULL
)
566 target
->type
->mmu
= default_mmu
;
568 target
= target
->next
;
573 if((retval
= target_register_user_commands(cmd_ctx
)) != ERROR_OK
)
575 if((retval
= target_register_timer_callback(handle_target
, 100, 1, NULL
)) != ERROR_OK
)
582 int target_register_event_callback(int (*callback
)(struct target_s
*target
, enum target_event event
, void *priv
), void *priv
)
584 target_event_callback_t
**callbacks_p
= &target_event_callbacks
;
586 if (callback
== NULL
)
588 return ERROR_INVALID_ARGUMENTS
;
593 while ((*callbacks_p
)->next
)
594 callbacks_p
= &((*callbacks_p
)->next
);
595 callbacks_p
= &((*callbacks_p
)->next
);
598 (*callbacks_p
) = malloc(sizeof(target_event_callback_t
));
599 (*callbacks_p
)->callback
= callback
;
600 (*callbacks_p
)->priv
= priv
;
601 (*callbacks_p
)->next
= NULL
;
606 int target_register_timer_callback(int (*callback
)(void *priv
), int time_ms
, int periodic
, void *priv
)
608 target_timer_callback_t
**callbacks_p
= &target_timer_callbacks
;
611 if (callback
== NULL
)
613 return ERROR_INVALID_ARGUMENTS
;
618 while ((*callbacks_p
)->next
)
619 callbacks_p
= &((*callbacks_p
)->next
);
620 callbacks_p
= &((*callbacks_p
)->next
);
623 (*callbacks_p
) = malloc(sizeof(target_timer_callback_t
));
624 (*callbacks_p
)->callback
= callback
;
625 (*callbacks_p
)->periodic
= periodic
;
626 (*callbacks_p
)->time_ms
= time_ms
;
628 gettimeofday(&now
, NULL
);
629 (*callbacks_p
)->when
.tv_usec
= now
.tv_usec
+ (time_ms
% 1000) * 1000;
630 time_ms
-= (time_ms
% 1000);
631 (*callbacks_p
)->when
.tv_sec
= now
.tv_sec
+ (time_ms
/ 1000);
632 if ((*callbacks_p
)->when
.tv_usec
> 1000000)
634 (*callbacks_p
)->when
.tv_usec
= (*callbacks_p
)->when
.tv_usec
- 1000000;
635 (*callbacks_p
)->when
.tv_sec
+= 1;
638 (*callbacks_p
)->priv
= priv
;
639 (*callbacks_p
)->next
= NULL
;
644 int target_unregister_event_callback(int (*callback
)(struct target_s
*target
, enum target_event event
, void *priv
), void *priv
)
646 target_event_callback_t
**p
= &target_event_callbacks
;
647 target_event_callback_t
*c
= target_event_callbacks
;
649 if (callback
== NULL
)
651 return ERROR_INVALID_ARGUMENTS
;
656 target_event_callback_t
*next
= c
->next
;
657 if ((c
->callback
== callback
) && (c
->priv
== priv
))
671 int target_unregister_timer_callback(int (*callback
)(void *priv
), void *priv
)
673 target_timer_callback_t
**p
= &target_timer_callbacks
;
674 target_timer_callback_t
*c
= target_timer_callbacks
;
676 if (callback
== NULL
)
678 return ERROR_INVALID_ARGUMENTS
;
683 target_timer_callback_t
*next
= c
->next
;
684 if ((c
->callback
== callback
) && (c
->priv
== priv
))
698 int target_call_event_callbacks(target_t
*target
, enum target_event event
)
700 target_event_callback_t
*callback
= target_event_callbacks
;
701 target_event_callback_t
*next_callback
;
703 if (event
== TARGET_EVENT_HALTED
)
705 /* execute early halted first */
706 target_call_event_callbacks(target
, TARGET_EVENT_EARLY_HALTED
);
710 LOG_DEBUG("target event %i (%s)",
712 Jim_Nvp_value2name_simple( nvp_target_event
, event
)->name
);
714 target_handle_event( target
, event
);
718 next_callback
= callback
->next
;
719 callback
->callback(target
, event
, callback
->priv
);
720 callback
= next_callback
;
726 static int target_call_timer_callbacks_check_time(int checktime
)
728 target_timer_callback_t
*callback
= target_timer_callbacks
;
729 target_timer_callback_t
*next_callback
;
734 gettimeofday(&now
, NULL
);
738 next_callback
= callback
->next
;
740 if ((!checktime
&&callback
->periodic
)||
741 (((now
.tv_sec
>= callback
->when
.tv_sec
) && (now
.tv_usec
>= callback
->when
.tv_usec
))
742 || (now
.tv_sec
> callback
->when
.tv_sec
)))
744 if(callback
->callback
!= NULL
)
746 callback
->callback(callback
->priv
);
747 if (callback
->periodic
)
749 int time_ms
= callback
->time_ms
;
750 callback
->when
.tv_usec
= now
.tv_usec
+ (time_ms
% 1000) * 1000;
751 time_ms
-= (time_ms
% 1000);
752 callback
->when
.tv_sec
= now
.tv_sec
+ time_ms
/ 1000;
753 if (callback
->when
.tv_usec
> 1000000)
755 callback
->when
.tv_usec
= callback
->when
.tv_usec
- 1000000;
756 callback
->when
.tv_sec
+= 1;
762 if((retval
= target_unregister_timer_callback(callback
->callback
, callback
->priv
)) != ERROR_OK
)
768 callback
= next_callback
;
774 int target_call_timer_callbacks(void)
776 return target_call_timer_callbacks_check_time(1);
779 /* invoke periodic callbacks immediately */
780 int target_call_timer_callbacks_now(void)
782 return target_call_timer_callbacks_check_time(0);
785 int target_alloc_working_area(struct target_s
*target
, u32 size
, working_area_t
**area
)
787 working_area_t
*c
= target
->working_areas
;
788 working_area_t
*new_wa
= NULL
;
790 /* Reevaluate working area address based on MMU state*/
791 if (target
->working_areas
== NULL
)
795 retval
= target
->type
->mmu(target
, &enabled
);
796 if (retval
!= ERROR_OK
)
802 target
->working_area
= target
->working_area_virt
;
806 target
->working_area
= target
->working_area_phys
;
810 /* only allocate multiples of 4 byte */
813 LOG_ERROR("BUG: code tried to allocate unaligned number of bytes, padding");
814 size
= CEIL(size
, 4);
817 /* see if there's already a matching working area */
820 if ((c
->free
) && (c
->size
== size
))
828 /* if not, allocate a new one */
831 working_area_t
**p
= &target
->working_areas
;
832 u32 first_free
= target
->working_area
;
833 u32 free_size
= target
->working_area_size
;
835 LOG_DEBUG("allocating new working area");
837 c
= target
->working_areas
;
840 first_free
+= c
->size
;
841 free_size
-= c
->size
;
846 if (free_size
< size
)
848 LOG_WARNING("not enough working area available(requested %d, free %d)", size
, free_size
);
849 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
852 new_wa
= malloc(sizeof(working_area_t
));
855 new_wa
->address
= first_free
;
857 if (target
->backup_working_area
)
860 new_wa
->backup
= malloc(new_wa
->size
);
861 if((retval
= target
->type
->read_memory(target
, new_wa
->address
, 4, new_wa
->size
/ 4, new_wa
->backup
)) != ERROR_OK
)
863 free(new_wa
->backup
);
870 new_wa
->backup
= NULL
;
873 /* put new entry in list */
877 /* mark as used, and return the new (reused) area */
887 int target_free_working_area_restore(struct target_s
*target
, working_area_t
*area
, int restore
)
892 if (restore
&&target
->backup_working_area
)
895 if((retval
= target
->type
->write_memory(target
, area
->address
, 4, area
->size
/ 4, area
->backup
)) != ERROR_OK
)
901 /* mark user pointer invalid */
908 int target_free_working_area(struct target_s
*target
, working_area_t
*area
)
910 return target_free_working_area_restore(target
, area
, 1);
913 /* free resources and restore memory, if restoring memory fails,
914 * free up resources anyway
916 void target_free_all_working_areas_restore(struct target_s
*target
, int restore
)
918 working_area_t
*c
= target
->working_areas
;
922 working_area_t
*next
= c
->next
;
923 target_free_working_area_restore(target
, c
, restore
);
933 target
->working_areas
= NULL
;
936 void target_free_all_working_areas(struct target_s
*target
)
938 target_free_all_working_areas_restore(target
, 1);
941 int target_register_commands(struct command_context_s
*cmd_ctx
)
944 register_command(cmd_ctx
, NULL
, "targets", handle_targets_command
, COMMAND_EXEC
, "change the current command line target (one parameter) or lists targets (with no parameter)");
945 register_command(cmd_ctx
, NULL
, "working_area", handle_working_area_command
, COMMAND_ANY
, "set a new working space");
946 register_command(cmd_ctx
, NULL
, "virt2phys", handle_virt2phys_command
, COMMAND_ANY
, "translate a virtual address into a physical address");
947 register_command(cmd_ctx
, NULL
, "profile", handle_profile_command
, COMMAND_EXEC
, "profiling samples the CPU PC");
949 register_jim(cmd_ctx
, "target", jim_target
, "configure target" );
952 /* script procedures */
953 register_jim(cmd_ctx
, "ocd_mem2array", jim_mem2array
, "read memory and return as a TCL array for script processing");
954 register_jim(cmd_ctx
, "ocd_array2mem", jim_array2mem
, "convert a TCL array to memory locations and write the values");
958 int target_arch_state(struct target_s
*target
)
963 LOG_USER("No target has been configured");
967 LOG_USER("target state: %s",
968 Jim_Nvp_value2name_simple(nvp_target_state
,target
->state
)->name
);
970 if (target
->state
!=TARGET_HALTED
)
973 retval
=target
->type
->arch_state(target
);
977 /* Single aligned words are guaranteed to use 16 or 32 bit access
978 * mode respectively, otherwise data is handled as quickly as
981 int target_write_buffer(struct target_s
*target
, u32 address
, u32 size
, u8
*buffer
)
984 LOG_DEBUG("writing buffer of %i byte at 0x%8.8x", size
, address
);
986 if (!target
->type
->examined
)
988 LOG_ERROR("Target not examined yet");
992 if ((address
+ size
- 1) < address
)
994 /* GDB can request this when e.g. PC is 0xfffffffc*/
995 LOG_ERROR("address+size wrapped(0x%08x, 0x%08x)", address
, size
);
999 if (((address
% 2) == 0) && (size
== 2))
1001 return target
->type
->write_memory(target
, address
, 2, 1, buffer
);
1004 /* handle unaligned head bytes */
1007 int unaligned
= 4 - (address
% 4);
1009 if (unaligned
> size
)
1012 if ((retval
= target
->type
->write_memory(target
, address
, 1, unaligned
, buffer
)) != ERROR_OK
)
1015 buffer
+= unaligned
;
1016 address
+= unaligned
;
1020 /* handle aligned words */
1023 int aligned
= size
- (size
% 4);
1025 /* use bulk writes above a certain limit. This may have to be changed */
1028 if ((retval
= target
->type
->bulk_write_memory(target
, address
, aligned
/ 4, buffer
)) != ERROR_OK
)
1033 if ((retval
= target
->type
->write_memory(target
, address
, 4, aligned
/ 4, buffer
)) != ERROR_OK
)
1042 /* handle tail writes of less than 4 bytes */
1045 if ((retval
= target
->type
->write_memory(target
, address
, 1, size
, buffer
)) != ERROR_OK
)
1053 /* Single aligned words are guaranteed to use 16 or 32 bit access
1054 * mode respectively, otherwise data is handled as quickly as
1057 int target_read_buffer(struct target_s
*target
, u32 address
, u32 size
, u8
*buffer
)
1060 LOG_DEBUG("reading buffer of %i byte at 0x%8.8x", size
, address
);
1062 if (!target
->type
->examined
)
1064 LOG_ERROR("Target not examined yet");
1068 if ((address
+ size
- 1) < address
)
1070 /* GDB can request this when e.g. PC is 0xfffffffc*/
1071 LOG_ERROR("address+size wrapped(0x%08x, 0x%08x)", address
, size
);
1075 if (((address
% 2) == 0) && (size
== 2))
1077 return target
->type
->read_memory(target
, address
, 2, 1, buffer
);
1080 /* handle unaligned head bytes */
1083 int unaligned
= 4 - (address
% 4);
1085 if (unaligned
> size
)
1088 if ((retval
= target
->type
->read_memory(target
, address
, 1, unaligned
, buffer
)) != ERROR_OK
)
1091 buffer
+= unaligned
;
1092 address
+= unaligned
;
1096 /* handle aligned words */
1099 int aligned
= size
- (size
% 4);
1101 if ((retval
= target
->type
->read_memory(target
, address
, 4, aligned
/ 4, buffer
)) != ERROR_OK
)
1109 /* handle tail writes of less than 4 bytes */
1112 if ((retval
= target
->type
->read_memory(target
, address
, 1, size
, buffer
)) != ERROR_OK
)
1119 int target_checksum_memory(struct target_s
*target
, u32 address
, u32 size
, u32
* crc
)
1125 if (!target
->type
->examined
)
1127 LOG_ERROR("Target not examined yet");
1131 if ((retval
= target
->type
->checksum_memory(target
, address
,
1132 size
, &checksum
)) != ERROR_OK
)
1134 buffer
= malloc(size
);
1137 LOG_ERROR("error allocating buffer for section (%d bytes)", size
);
1138 return ERROR_INVALID_ARGUMENTS
;
1140 retval
= target_read_buffer(target
, address
, size
, buffer
);
1141 if (retval
!= ERROR_OK
)
1147 /* convert to target endianess */
1148 for (i
= 0; i
< (size
/sizeof(u32
)); i
++)
1151 target_data
= target_buffer_get_u32(target
, &buffer
[i
*sizeof(u32
)]);
1152 target_buffer_set_u32(target
, &buffer
[i
*sizeof(u32
)], target_data
);
1155 retval
= image_calculate_checksum( buffer
, size
, &checksum
);
1164 int target_blank_check_memory(struct target_s
*target
, u32 address
, u32 size
, u32
* blank
)
1167 if (!target
->type
->examined
)
1169 LOG_ERROR("Target not examined yet");
1173 if (target
->type
->blank_check_memory
== 0)
1174 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1176 retval
= target
->type
->blank_check_memory(target
, address
, size
, blank
);
1181 int target_read_u32(struct target_s
*target
, u32 address
, u32
*value
)
1184 if (!target
->type
->examined
)
1186 LOG_ERROR("Target not examined yet");
1190 int retval
= target
->type
->read_memory(target
, address
, 4, 1, value_buf
);
1192 if (retval
== ERROR_OK
)
1194 *value
= target_buffer_get_u32(target
, value_buf
);
1195 LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address
, *value
);
1200 LOG_DEBUG("address: 0x%8.8x failed", address
);
1206 int target_read_u16(struct target_s
*target
, u32 address
, u16
*value
)
1209 if (!target
->type
->examined
)
1211 LOG_ERROR("Target not examined yet");
1215 int retval
= target
->type
->read_memory(target
, address
, 2, 1, value_buf
);
1217 if (retval
== ERROR_OK
)
1219 *value
= target_buffer_get_u16(target
, value_buf
);
1220 LOG_DEBUG("address: 0x%8.8x, value: 0x%4.4x", address
, *value
);
1225 LOG_DEBUG("address: 0x%8.8x failed", address
);
1231 int target_read_u8(struct target_s
*target
, u32 address
, u8
*value
)
1233 int retval
= target
->type
->read_memory(target
, address
, 1, 1, value
);
1234 if (!target
->type
->examined
)
1236 LOG_ERROR("Target not examined yet");
1240 if (retval
== ERROR_OK
)
1242 LOG_DEBUG("address: 0x%8.8x, value: 0x%2.2x", address
, *value
);
1247 LOG_DEBUG("address: 0x%8.8x failed", address
);
1253 int target_write_u32(struct target_s
*target
, u32 address
, u32 value
)
1257 if (!target
->type
->examined
)
1259 LOG_ERROR("Target not examined yet");
1263 LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address
, value
);
1265 target_buffer_set_u32(target
, value_buf
, value
);
1266 if ((retval
= target
->type
->write_memory(target
, address
, 4, 1, value_buf
)) != ERROR_OK
)
1268 LOG_DEBUG("failed: %i", retval
);
1274 int target_write_u16(struct target_s
*target
, u32 address
, u16 value
)
1278 if (!target
->type
->examined
)
1280 LOG_ERROR("Target not examined yet");
1284 LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address
, value
);
1286 target_buffer_set_u16(target
, value_buf
, value
);
1287 if ((retval
= target
->type
->write_memory(target
, address
, 2, 1, value_buf
)) != ERROR_OK
)
1289 LOG_DEBUG("failed: %i", retval
);
1295 int target_write_u8(struct target_s
*target
, u32 address
, u8 value
)
1298 if (!target
->type
->examined
)
1300 LOG_ERROR("Target not examined yet");
1304 LOG_DEBUG("address: 0x%8.8x, value: 0x%2.2x", address
, value
);
1306 if ((retval
= target
->type
->write_memory(target
, address
, 1, 1, &value
)) != ERROR_OK
)
1308 LOG_DEBUG("failed: %i", retval
);
1314 int target_register_user_commands(struct command_context_s
*cmd_ctx
)
1316 int retval
= ERROR_OK
;
1317 register_command(cmd_ctx
, NULL
, "reg", handle_reg_command
, COMMAND_EXEC
, "display or set a register");
1318 register_command(cmd_ctx
, NULL
, "poll", handle_poll_command
, COMMAND_EXEC
, "poll target state");
1319 register_command(cmd_ctx
, NULL
, "wait_halt", handle_wait_halt_command
, COMMAND_EXEC
, "wait for target halt [time (s)]");
1320 register_command(cmd_ctx
, NULL
, "halt", handle_halt_command
, COMMAND_EXEC
, "halt target");
1321 register_command(cmd_ctx
, NULL
, "resume", handle_resume_command
, COMMAND_EXEC
, "resume target [addr]");
1322 register_command(cmd_ctx
, NULL
, "step", handle_step_command
, COMMAND_EXEC
, "step one instruction from current PC or [addr]");
1323 register_command(cmd_ctx
, NULL
, "reset", handle_reset_command
, COMMAND_EXEC
, "reset target [run|halt|init] - default is run");
1324 register_command(cmd_ctx
, NULL
, "soft_reset_halt", handle_soft_reset_halt_command
, COMMAND_EXEC
, "halt the target and do a soft reset");
1326 register_command(cmd_ctx
, NULL
, "mdw", handle_md_command
, COMMAND_EXEC
, "display memory words <addr> [count]");
1327 register_command(cmd_ctx
, NULL
, "mdh", handle_md_command
, COMMAND_EXEC
, "display memory half-words <addr> [count]");
1328 register_command(cmd_ctx
, NULL
, "mdb", handle_md_command
, COMMAND_EXEC
, "display memory bytes <addr> [count]");
1330 register_command(cmd_ctx
, NULL
, "mww", handle_mw_command
, COMMAND_EXEC
, "write memory word <addr> <value> [count]");
1331 register_command(cmd_ctx
, NULL
, "mwh", handle_mw_command
, COMMAND_EXEC
, "write memory half-word <addr> <value> [count]");
1332 register_command(cmd_ctx
, NULL
, "mwb", handle_mw_command
, COMMAND_EXEC
, "write memory byte <addr> <value> [count]");
1334 register_command(cmd_ctx
, NULL
, "bp", handle_bp_command
, COMMAND_EXEC
, "set breakpoint <address> <length> [hw]");
1335 register_command(cmd_ctx
, NULL
, "rbp", handle_rbp_command
, COMMAND_EXEC
, "remove breakpoint <adress>");
1336 register_command(cmd_ctx
, NULL
, "wp", handle_wp_command
, COMMAND_EXEC
, "set watchpoint <address> <length> <r/w/a> [value] [mask]");
1337 register_command(cmd_ctx
, NULL
, "rwp", handle_rwp_command
, COMMAND_EXEC
, "remove watchpoint <adress>");
1339 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]");
1340 register_command(cmd_ctx
, NULL
, "dump_image", handle_dump_image_command
, COMMAND_EXEC
, "dump_image <file> <address> <size>");
1341 register_command(cmd_ctx
, NULL
, "verify_image", handle_verify_image_command
, COMMAND_EXEC
, "verify_image <file> [offset] [type]");
1343 if((retval
= target_request_register_commands(cmd_ctx
)) != ERROR_OK
)
1345 if((retval
= trace_register_commands(cmd_ctx
)) != ERROR_OK
)
1352 int handle_targets_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1355 target_t
*target
= all_targets
;
1359 /* try as tcltarget name */
1360 for( target
= all_targets
; target
; target
++ ){
1361 if( target
->cmd_name
){
1362 if( 0 == strcmp( args
[0], target
->cmd_name
) ){
1368 /* no match, try as number */
1370 int num
= strtoul(args
[0], &cp
, 0 );
1372 /* then it was not a number */
1373 command_print( cmd_ctx
, "Target: %s unknown, try one of:\n", args
[0] );
1377 target
= get_target_by_num( num
);
1378 if( target
== NULL
){
1379 command_print(cmd_ctx
,"Target: %s is unknown, try one of:\n", args
[0] );
1383 cmd_ctx
->current_target
= target
->target_number
;
1388 command_print(cmd_ctx
, " CmdName Type Endian ChainPos State ");
1389 command_print(cmd_ctx
, "-- ---------- ---------- ---------- -------- ----------");
1392 /* XX: abcdefghij abcdefghij abcdefghij abcdefghij */
1393 command_print(cmd_ctx
, "%2d: %-10s %-10s %-10s %8d %s",
1394 target
->target_number
,
1397 Jim_Nvp_value2name_simple( nvp_target_endian
, target
->endianness
)->name
,
1398 target
->chain_position
,
1399 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
1400 target
= target
->next
;
1408 int handle_working_area_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1410 int retval
= ERROR_OK
;
1411 target_t
*target
= NULL
;
1413 if ((argc
< 4) || (argc
> 5))
1415 return ERROR_COMMAND_SYNTAX_ERROR
;
1418 target
= get_target_by_num(strtoul(args
[0], NULL
, 0));
1421 return ERROR_COMMAND_SYNTAX_ERROR
;
1423 target_free_all_working_areas(target
);
1425 target
->working_area_phys
= target
->working_area_virt
= strtoul(args
[1], NULL
, 0);
1428 target
->working_area_virt
= strtoul(args
[4], NULL
, 0);
1430 target
->working_area_size
= strtoul(args
[2], NULL
, 0);
1432 if (strcmp(args
[3], "backup") == 0)
1434 target
->backup_working_area
= 1;
1436 else if (strcmp(args
[3], "nobackup") == 0)
1438 target
->backup_working_area
= 0;
1442 LOG_ERROR("unrecognized <backup|nobackup> argument (%s)", args
[3]);
1443 return ERROR_COMMAND_SYNTAX_ERROR
;
1450 /* process target state changes */
1451 int handle_target(void *priv
)
1453 int retval
= ERROR_OK
;
1454 target_t
*target
= all_targets
;
1458 if (target_continous_poll
)
1460 /* polling may fail silently until the target has been examined */
1461 if((retval
= target_poll(target
)) != ERROR_OK
)
1465 target
= target
->next
;
1471 int handle_reg_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1480 target
= get_current_target(cmd_ctx
);
1482 /* list all available registers for the current target */
1485 reg_cache_t
*cache
= target
->reg_cache
;
1491 for (i
= 0; i
< cache
->num_regs
; i
++)
1493 value
= buf_to_str(cache
->reg_list
[i
].value
, cache
->reg_list
[i
].size
, 16);
1494 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
);
1497 cache
= cache
->next
;
1503 /* access a single register by its ordinal number */
1504 if ((args
[0][0] >= '0') && (args
[0][0] <= '9'))
1506 int num
= strtoul(args
[0], NULL
, 0);
1507 reg_cache_t
*cache
= target
->reg_cache
;
1513 for (i
= 0; i
< cache
->num_regs
; i
++)
1517 reg
= &cache
->reg_list
[i
];
1523 cache
= cache
->next
;
1528 command_print(cmd_ctx
, "%i is out of bounds, the current target has only %i registers (0 - %i)", num
, count
, count
- 1);
1531 } else /* access a single register by its name */
1533 reg
= register_get_by_name(target
->reg_cache
, args
[0], 1);
1537 command_print(cmd_ctx
, "register %s not found in current target", args
[0]);
1542 /* display a register */
1543 if ((argc
== 1) || ((argc
== 2) && !((args
[1][0] >= '0') && (args
[1][0] <= '9'))))
1545 if ((argc
== 2) && (strcmp(args
[1], "force") == 0))
1548 if (reg
->valid
== 0)
1550 reg_arch_type_t
*arch_type
= register_get_arch_type(reg
->arch_type
);
1551 arch_type
->get(reg
);
1553 value
= buf_to_str(reg
->value
, reg
->size
, 16);
1554 command_print(cmd_ctx
, "%s (/%i): 0x%s", reg
->name
, reg
->size
, value
);
1559 /* set register value */
1562 u8
*buf
= malloc(CEIL(reg
->size
, 8));
1563 str_to_buf(args
[1], strlen(args
[1]), buf
, reg
->size
, 0);
1565 reg_arch_type_t
*arch_type
= register_get_arch_type(reg
->arch_type
);
1566 arch_type
->set(reg
, buf
);
1568 value
= buf_to_str(reg
->value
, reg
->size
, 16);
1569 command_print(cmd_ctx
, "%s (/%i): 0x%s", reg
->name
, reg
->size
, value
);
1577 command_print(cmd_ctx
, "usage: reg <#|name> [value]");
1583 int handle_poll_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1585 int retval
= ERROR_OK
;
1586 target_t
*target
= get_current_target(cmd_ctx
);
1590 if((retval
= target_poll(target
)) != ERROR_OK
)
1592 if((retval
= target_arch_state(target
)) != ERROR_OK
)
1598 if (strcmp(args
[0], "on") == 0)
1600 target_continous_poll
= 1;
1602 else if (strcmp(args
[0], "off") == 0)
1604 target_continous_poll
= 0;
1608 command_print(cmd_ctx
, "arg is \"on\" or \"off\"");
1612 return ERROR_COMMAND_SYNTAX_ERROR
;
1619 int handle_wait_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1627 ms
= strtoul(args
[0], &end
, 0) * 1000;
1630 command_print(cmd_ctx
, "usage: %s [seconds]", cmd
);
1634 target_t
*target
= get_current_target(cmd_ctx
);
1636 return target_wait_state(target
, TARGET_HALTED
, ms
);
1639 int target_wait_state(target_t
*target
, enum target_state state
, int ms
)
1642 struct timeval timeout
, now
;
1644 gettimeofday(&timeout
, NULL
);
1645 timeval_add_time(&timeout
, 0, ms
* 1000);
1649 if ((retval
=target_poll(target
))!=ERROR_OK
)
1652 if (target
->state
== state
)
1659 LOG_DEBUG("waiting for target %s...",
1660 Jim_Nvp_value2name_simple(nvp_target_state
,state
)->name
);
1663 gettimeofday(&now
, NULL
);
1664 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
) && (now
.tv_usec
>= timeout
.tv_usec
)))
1666 LOG_ERROR("timed out while waiting for target %s",
1667 Jim_Nvp_value2name_simple(nvp_target_state
,state
)->name
);
1675 int handle_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1678 target_t
*target
= get_current_target(cmd_ctx
);
1682 if ((retval
= target_halt(target
)) != ERROR_OK
)
1687 return handle_wait_halt_command(cmd_ctx
, cmd
, args
, argc
);
1690 int handle_soft_reset_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1692 target_t
*target
= get_current_target(cmd_ctx
);
1694 LOG_USER("requesting target halt and executing a soft reset");
1696 target
->type
->soft_reset_halt(target
);
1701 int handle_reset_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1704 enum target_reset_mode reset_mode
= RESET_RUN
;
1708 n
= Jim_Nvp_name2value_simple( nvp_reset_modes
, args
[0] );
1709 if( (n
->name
== NULL
) || (n
->value
== RESET_UNKNOWN
) ){
1710 return ERROR_COMMAND_SYNTAX_ERROR
;
1712 reset_mode
= n
->value
;
1715 /* reset *all* targets */
1716 return target_process_reset(cmd_ctx
, reset_mode
);
1720 int handle_resume_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1723 target_t
*target
= get_current_target(cmd_ctx
);
1725 target_handle_event( target
, TARGET_EVENT_OLD_pre_resume
);
1728 retval
= target_resume(target
, 1, 0, 1, 0); /* current pc, addr = 0, handle breakpoints, not debugging */
1730 retval
= target_resume(target
, 0, strtoul(args
[0], NULL
, 0), 1, 0); /* addr = args[0], handle breakpoints, not debugging */
1733 retval
= ERROR_COMMAND_SYNTAX_ERROR
;
1739 int handle_step_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1741 target_t
*target
= get_current_target(cmd_ctx
);
1746 return target
->type
->step(target
, 1, 0, 1); /* current pc, addr = 0, handle breakpoints */
1749 return target
->type
->step(target
, 0, strtoul(args
[0], NULL
, 0), 1); /* addr = args[0], handle breakpoints */
1754 int handle_md_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1756 const int line_bytecnt
= 32;
1769 target_t
*target
= get_current_target(cmd_ctx
);
1775 count
= strtoul(args
[1], NULL
, 0);
1777 address
= strtoul(args
[0], NULL
, 0);
1783 size
= 4; line_modulo
= line_bytecnt
/ 4;
1786 size
= 2; line_modulo
= line_bytecnt
/ 2;
1789 size
= 1; line_modulo
= line_bytecnt
/ 1;
1795 buffer
= calloc(count
, size
);
1796 retval
= target
->type
->read_memory(target
, address
, size
, count
, buffer
);
1797 if (retval
== ERROR_OK
)
1801 for (i
= 0; i
< count
; i
++)
1803 if (i
%line_modulo
== 0)
1804 output_len
+= snprintf(output
+ output_len
, 128 - output_len
, "0x%8.8x: ", address
+ (i
*size
));
1809 output_len
+= snprintf(output
+ output_len
, 128 - output_len
, "%8.8x ", target_buffer_get_u32(target
, &buffer
[i
*4]));
1812 output_len
+= snprintf(output
+ output_len
, 128 - output_len
, "%4.4x ", target_buffer_get_u16(target
, &buffer
[i
*2]));
1815 output_len
+= snprintf(output
+ output_len
, 128 - output_len
, "%2.2x ", buffer
[i
*1]);
1819 if ((i
%line_modulo
== line_modulo
-1) || (i
== count
- 1))
1821 command_print(cmd_ctx
, output
);
1832 int handle_mw_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1839 target_t
*target
= get_current_target(cmd_ctx
);
1842 if ((argc
< 2) || (argc
> 3))
1843 return ERROR_COMMAND_SYNTAX_ERROR
;
1845 address
= strtoul(args
[0], NULL
, 0);
1846 value
= strtoul(args
[1], NULL
, 0);
1848 count
= strtoul(args
[2], NULL
, 0);
1854 target_buffer_set_u32(target
, value_buf
, value
);
1858 target_buffer_set_u16(target
, value_buf
, value
);
1862 value_buf
[0] = value
;
1865 return ERROR_COMMAND_SYNTAX_ERROR
;
1867 for (i
=0; i
<count
; i
++)
1873 retval
= target
->type
->write_memory(target
, address
+ i
*wordsize
, 4, 1, value_buf
);
1876 retval
= target
->type
->write_memory(target
, address
+ i
*wordsize
, 2, 1, value_buf
);
1879 retval
= target
->type
->write_memory(target
, address
+ i
*wordsize
, 1, 1, value_buf
);
1886 if (retval
!=ERROR_OK
)
1896 int handle_load_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1902 u32 max_address
=0xffffffff;
1904 int retval
, retvaltemp
;
1908 duration_t duration
;
1909 char *duration_text
;
1911 target_t
*target
= get_current_target(cmd_ctx
);
1913 if ((argc
< 1)||(argc
> 5))
1915 return ERROR_COMMAND_SYNTAX_ERROR
;
1918 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
1921 image
.base_address_set
= 1;
1922 image
.base_address
= strtoul(args
[1], NULL
, 0);
1926 image
.base_address_set
= 0;
1930 image
.start_address_set
= 0;
1934 min_address
=strtoul(args
[3], NULL
, 0);
1938 max_address
=strtoul(args
[4], NULL
, 0)+min_address
;
1941 if (min_address
>max_address
)
1943 return ERROR_COMMAND_SYNTAX_ERROR
;
1947 duration_start_measure(&duration
);
1949 if (image_open(&image
, args
[0], (argc
>= 3) ? args
[2] : NULL
) != ERROR_OK
)
1956 for (i
= 0; i
< image
.num_sections
; i
++)
1958 buffer
= malloc(image
.sections
[i
].size
);
1961 command_print(cmd_ctx
, "error allocating buffer for section (%d bytes)", image
.sections
[i
].size
);
1965 if ((retval
= image_read_section(&image
, i
, 0x0, image
.sections
[i
].size
, buffer
, &buf_cnt
)) != ERROR_OK
)
1975 /* DANGER!!! beware of unsigned comparision here!!! */
1977 if ((image
.sections
[i
].base_address
+buf_cnt
>=min_address
)&&
1978 (image
.sections
[i
].base_address
<max_address
))
1980 if (image
.sections
[i
].base_address
<min_address
)
1982 /* clip addresses below */
1983 offset
+=min_address
-image
.sections
[i
].base_address
;
1987 if (image
.sections
[i
].base_address
+buf_cnt
>max_address
)
1989 length
-=(image
.sections
[i
].base_address
+buf_cnt
)-max_address
;
1992 if ((retval
= target_write_buffer(target
, image
.sections
[i
].base_address
+offset
, length
, buffer
+offset
)) != ERROR_OK
)
1997 image_size
+= length
;
1998 command_print(cmd_ctx
, "%u byte written at address 0x%8.8x", length
, image
.sections
[i
].base_address
+offset
);
2004 if((retvaltemp
= duration_stop_measure(&duration
, &duration_text
)) != ERROR_OK
)
2006 image_close(&image
);
2010 if (retval
==ERROR_OK
)
2012 command_print(cmd_ctx
, "downloaded %u byte in %s", image_size
, duration_text
);
2014 free(duration_text
);
2016 image_close(&image
);
2022 int handle_dump_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2029 int retval
=ERROR_OK
, retvaltemp
;
2031 duration_t duration
;
2032 char *duration_text
;
2034 target_t
*target
= get_current_target(cmd_ctx
);
2038 command_print(cmd_ctx
, "usage: dump_image <filename> <address> <size>");
2042 address
= strtoul(args
[1], NULL
, 0);
2043 size
= strtoul(args
[2], NULL
, 0);
2045 if ((address
& 3) || (size
& 3))
2047 command_print(cmd_ctx
, "only 32-bit aligned address and size are supported");
2051 if (fileio_open(&fileio
, args
[0], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
)
2056 duration_start_measure(&duration
);
2061 u32 this_run_size
= (size
> 560) ? 560 : size
;
2063 retval
= target
->type
->read_memory(target
, address
, 4, this_run_size
/ 4, buffer
);
2064 if (retval
!= ERROR_OK
)
2069 retval
= fileio_write(&fileio
, this_run_size
, buffer
, &size_written
);
2070 if (retval
!= ERROR_OK
)
2075 size
-= this_run_size
;
2076 address
+= this_run_size
;
2079 if((retvaltemp
= fileio_close(&fileio
)) != ERROR_OK
)
2082 if((retvaltemp
= duration_stop_measure(&duration
, &duration_text
)) != ERROR_OK
)
2085 if (retval
==ERROR_OK
)
2087 command_print(cmd_ctx
, "dumped %"PRIi64
" byte in %s", fileio
.size
, duration_text
);
2089 free(duration_text
);
2094 int handle_verify_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2100 int retval
, retvaltemp
;
2102 u32 mem_checksum
= 0;
2106 duration_t duration
;
2107 char *duration_text
;
2109 target_t
*target
= get_current_target(cmd_ctx
);
2113 return ERROR_COMMAND_SYNTAX_ERROR
;
2118 LOG_ERROR("no target selected");
2122 duration_start_measure(&duration
);
2126 image
.base_address_set
= 1;
2127 image
.base_address
= strtoul(args
[1], NULL
, 0);
2131 image
.base_address_set
= 0;
2132 image
.base_address
= 0x0;
2135 image
.start_address_set
= 0;
2137 if ((retval
=image_open(&image
, args
[0], (argc
== 3) ? args
[2] : NULL
)) != ERROR_OK
)
2144 for (i
= 0; i
< image
.num_sections
; i
++)
2146 buffer
= malloc(image
.sections
[i
].size
);
2149 command_print(cmd_ctx
, "error allocating buffer for section (%d bytes)", image
.sections
[i
].size
);
2152 if ((retval
= image_read_section(&image
, i
, 0x0, image
.sections
[i
].size
, buffer
, &buf_cnt
)) != ERROR_OK
)
2158 /* calculate checksum of image */
2159 image_calculate_checksum( buffer
, buf_cnt
, &checksum
);
2161 retval
= target_checksum_memory(target
, image
.sections
[i
].base_address
, buf_cnt
, &mem_checksum
);
2162 if( retval
!= ERROR_OK
)
2168 if( checksum
!= mem_checksum
)
2170 /* failed crc checksum, fall back to a binary compare */
2173 command_print(cmd_ctx
, "checksum mismatch - attempting binary compare");
2175 data
= (u8
*)malloc(buf_cnt
);
2177 /* Can we use 32bit word accesses? */
2179 int count
= buf_cnt
;
2180 if ((count
% 4) == 0)
2185 retval
= target
->type
->read_memory(target
, image
.sections
[i
].base_address
, size
, count
, data
);
2186 if (retval
== ERROR_OK
)
2189 for (t
= 0; t
< buf_cnt
; t
++)
2191 if (data
[t
] != buffer
[t
])
2193 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
]);
2210 image_size
+= buf_cnt
;
2214 if((retvaltemp
= duration_stop_measure(&duration
, &duration_text
)) != ERROR_OK
)
2216 image_close(&image
);
2220 if (retval
==ERROR_OK
)
2222 command_print(cmd_ctx
, "verified %u bytes in %s", image_size
, duration_text
);
2224 free(duration_text
);
2226 image_close(&image
);
2231 int handle_bp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2234 target_t
*target
= get_current_target(cmd_ctx
);
2238 breakpoint_t
*breakpoint
= target
->breakpoints
;
2242 if (breakpoint
->type
== BKPT_SOFT
)
2244 char* buf
= buf_to_str(breakpoint
->orig_instr
, breakpoint
->length
, 16);
2245 command_print(cmd_ctx
, "0x%8.8x, 0x%x, %i, 0x%s", breakpoint
->address
, breakpoint
->length
, breakpoint
->set
, buf
);
2250 command_print(cmd_ctx
, "0x%8.8x, 0x%x, %i", breakpoint
->address
, breakpoint
->length
, breakpoint
->set
);
2252 breakpoint
= breakpoint
->next
;
2260 length
= strtoul(args
[1], NULL
, 0);
2263 if (strcmp(args
[2], "hw") == 0)
2266 if ((retval
= breakpoint_add(target
, strtoul(args
[0], NULL
, 0), length
, hw
)) != ERROR_OK
)
2268 LOG_ERROR("Failure setting breakpoints");
2272 command_print(cmd_ctx
, "breakpoint added at address 0x%8.8x", strtoul(args
[0], NULL
, 0));
2277 command_print(cmd_ctx
, "usage: bp <address> <length> ['hw']");
2283 int handle_rbp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2285 target_t
*target
= get_current_target(cmd_ctx
);
2288 breakpoint_remove(target
, strtoul(args
[0], NULL
, 0));
2293 int handle_wp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2295 target_t
*target
= get_current_target(cmd_ctx
);
2300 watchpoint_t
*watchpoint
= target
->watchpoints
;
2304 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
);
2305 watchpoint
= watchpoint
->next
;
2310 enum watchpoint_rw type
= WPT_ACCESS
;
2311 u32 data_value
= 0x0;
2312 u32 data_mask
= 0xffffffff;
2328 command_print(cmd_ctx
, "usage: wp <address> <length> [r/w/a] [value] [mask]");
2334 data_value
= strtoul(args
[3], NULL
, 0);
2338 data_mask
= strtoul(args
[4], NULL
, 0);
2341 if ((retval
= watchpoint_add(target
, strtoul(args
[0], NULL
, 0),
2342 strtoul(args
[1], NULL
, 0), type
, data_value
, data_mask
)) != ERROR_OK
)
2344 LOG_ERROR("Failure setting breakpoints");
2349 command_print(cmd_ctx
, "usage: wp <address> <length> [r/w/a] [value] [mask]");
2355 int handle_rwp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2357 target_t
*target
= get_current_target(cmd_ctx
);
2360 watchpoint_remove(target
, strtoul(args
[0], NULL
, 0));
2365 int handle_virt2phys_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2368 target_t
*target
= get_current_target(cmd_ctx
);
2374 return ERROR_COMMAND_SYNTAX_ERROR
;
2376 va
= strtoul(args
[0], NULL
, 0);
2378 retval
= target
->type
->virt2phys(target
, va
, &pa
);
2379 if (retval
== ERROR_OK
)
2381 command_print(cmd_ctx
, "Physical address 0x%08x", pa
);
2385 /* lower levels will have logged a detailed error which is
2386 * forwarded to telnet/GDB session.
2391 static void writeLong(FILE *f
, int l
)
2396 char c
=(l
>>(i
*8))&0xff;
2397 fwrite(&c
, 1, 1, f
);
2401 static void writeString(FILE *f
, char *s
)
2403 fwrite(s
, 1, strlen(s
), f
);
2408 // Dump a gmon.out histogram file.
2409 static void writeGmon(u32
*samples
, int sampleNum
, char *filename
)
2412 FILE *f
=fopen(filename
, "w");
2415 fwrite("gmon", 1, 4, f
);
2416 writeLong(f
, 0x00000001); // Version
2417 writeLong(f
, 0); // padding
2418 writeLong(f
, 0); // padding
2419 writeLong(f
, 0); // padding
2421 fwrite("", 1, 1, f
); // GMON_TAG_TIME_HIST
2423 // figure out bucket size
2426 for (i
=0; i
<sampleNum
; i
++)
2438 int addressSpace
=(max
-min
+1);
2440 static int const maxBuckets
=256*1024; // maximum buckets.
2441 int length
=addressSpace
;
2442 if (length
> maxBuckets
)
2446 int *buckets
=malloc(sizeof(int)*length
);
2452 memset(buckets
, 0, sizeof(int)*length
);
2453 for (i
=0; i
<sampleNum
;i
++)
2455 u32 address
=samples
[i
];
2456 long long a
=address
-min
;
2457 long long b
=length
-1;
2458 long long c
=addressSpace
-1;
2459 int index
=(a
*b
)/c
; // danger!!!! int32 overflows
2463 // append binary memory gmon.out &profile_hist_hdr ((char*)&profile_hist_hdr + sizeof(struct gmon_hist_hdr))
2464 writeLong(f
, min
); // low_pc
2465 writeLong(f
, max
); // high_pc
2466 writeLong(f
, length
); // # of samples
2467 writeLong(f
, 64000000); // 64MHz
2468 writeString(f
, "seconds");
2469 for (i
=0; i
<(15-strlen("seconds")); i
++)
2471 fwrite("", 1, 1, f
); // padding
2473 writeString(f
, "s");
2475 // append binary memory gmon.out profile_hist_data (profile_hist_data + profile_hist_hdr.hist_size)
2477 char *data
=malloc(2*length
);
2480 for (i
=0; i
<length
;i
++)
2489 data
[i
*2+1]=(val
>>8)&0xff;
2492 fwrite(data
, 1, length
*2, f
);
2502 /* profiling samples the CPU PC as quickly as OpenOCD is able, which will be used as a random sampling of PC */
2503 int handle_profile_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2505 target_t
*target
= get_current_target(cmd_ctx
);
2506 struct timeval timeout
, now
;
2508 gettimeofday(&timeout
, NULL
);
2511 return ERROR_COMMAND_SYNTAX_ERROR
;
2514 timeval_add_time(&timeout
, strtoul(args
[0], &end
, 0), 0);
2520 command_print(cmd_ctx
, "Starting profiling. Halting and resuming the target as often as we can...");
2522 static const int maxSample
=10000;
2523 u32
*samples
=malloc(sizeof(u32
)*maxSample
);
2528 int retval
=ERROR_OK
;
2529 // hopefully it is safe to cache! We want to stop/restart as quickly as possible.
2530 reg_t
*reg
= register_get_by_name(target
->reg_cache
, "pc", 1);
2534 target_poll(target
);
2535 if (target
->state
== TARGET_HALTED
)
2537 u32 t
=*((u32
*)reg
->value
);
2538 samples
[numSamples
++]=t
;
2539 retval
= target_resume(target
, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */
2540 target_poll(target
);
2541 alive_sleep(10); // sleep 10ms, i.e. <100 samples/second.
2542 } else if (target
->state
== TARGET_RUNNING
)
2544 // We want to quickly sample the PC.
2545 if((retval
= target_halt(target
)) != ERROR_OK
)
2552 command_print(cmd_ctx
, "Target not halted or running");
2556 if (retval
!=ERROR_OK
)
2561 gettimeofday(&now
, NULL
);
2562 if ((numSamples
>=maxSample
) || ((now
.tv_sec
>= timeout
.tv_sec
) && (now
.tv_usec
>= timeout
.tv_usec
)))
2564 command_print(cmd_ctx
, "Profiling completed. %d samples.", numSamples
);
2565 if((retval
= target_poll(target
)) != ERROR_OK
)
2570 if (target
->state
== TARGET_HALTED
)
2572 target_resume(target
, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */
2574 if((retval
= target_poll(target
)) != ERROR_OK
)
2579 writeGmon(samples
, numSamples
, args
[1]);
2580 command_print(cmd_ctx
, "Wrote %s", args
[1]);
2589 static int new_int_array_element(Jim_Interp
* interp
, const char *varname
, int idx
, u32 val
)
2592 Jim_Obj
*nameObjPtr
, *valObjPtr
;
2595 namebuf
= alloc_printf("%s(%d)", varname
, idx
);
2599 nameObjPtr
= Jim_NewStringObj(interp
, namebuf
, -1);
2600 valObjPtr
= Jim_NewIntObj(interp
, val
);
2601 if (!nameObjPtr
|| !valObjPtr
)
2607 Jim_IncrRefCount(nameObjPtr
);
2608 Jim_IncrRefCount(valObjPtr
);
2609 result
= Jim_SetVariable(interp
, nameObjPtr
, valObjPtr
);
2610 Jim_DecrRefCount(interp
, nameObjPtr
);
2611 Jim_DecrRefCount(interp
, valObjPtr
);
2613 /* printf("%s(%d) <= 0%08x\n", varname, idx, val); */
2617 static int jim_mem2array(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
2619 command_context_t
*context
;
2622 context
= Jim_GetAssocData(interp
, "context");
2623 if (context
== NULL
)
2625 LOG_ERROR("mem2array: no command context");
2628 target
= get_current_target(context
);
2631 LOG_ERROR("mem2array: no current target");
2635 return target_mem2array(interp
, target
, argc
,argv
);
2638 static int target_mem2array(Jim_Interp
*interp
, target_t
*target
, int argc
, Jim_Obj
*const *argv
)
2646 const char *varname
;
2648 int i
, n
, e
, retval
;
2650 /* argv[1] = name of array to receive the data
2651 * argv[2] = desired width
2652 * argv[3] = memory address
2653 * argv[4] = count of times to read
2656 Jim_WrongNumArgs(interp
, 1, argv
, "varname width addr nelems");
2659 varname
= Jim_GetString(argv
[1], &len
);
2660 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
2662 e
= Jim_GetLong(interp
, argv
[2], &l
);
2668 e
= Jim_GetLong(interp
, argv
[3], &l
);
2673 e
= Jim_GetLong(interp
, argv
[4], &l
);
2689 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2690 Jim_AppendStrings( interp
, Jim_GetResult(interp
), "Invalid width param, must be 8/16/32", NULL
);
2694 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2695 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: zero width read?", NULL
);
2698 if ((addr
+ (len
* width
)) < addr
) {
2699 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2700 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: addr + len - wraps to zero?", NULL
);
2703 /* absurd transfer size? */
2705 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2706 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: absurd > 64K item request", NULL
);
2711 ((width
== 2) && ((addr
& 1) == 0)) ||
2712 ((width
== 4) && ((addr
& 3) == 0))) {
2716 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2717 sprintf(buf
, "mem2array address: 0x%08x is not aligned for %d byte reads", addr
, width
);
2718 Jim_AppendStrings(interp
, Jim_GetResult(interp
), buf
, NULL
);
2729 /* Slurp... in buffer size chunks */
2731 count
= len
; /* in objects.. */
2732 if (count
> (sizeof(buffer
)/width
)) {
2733 count
= (sizeof(buffer
)/width
);
2736 retval
= target
->type
->read_memory( target
, addr
, width
, count
, buffer
);
2737 if (retval
!= ERROR_OK
) {
2739 LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed", addr
, width
, count
);
2740 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2741 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: cannot read memory", NULL
);
2745 v
= 0; /* shut up gcc */
2746 for (i
= 0 ;i
< count
;i
++, n
++) {
2749 v
= target_buffer_get_u32(target
, &buffer
[i
*width
]);
2752 v
= target_buffer_get_u16(target
, &buffer
[i
*width
]);
2755 v
= buffer
[i
] & 0x0ff;
2758 new_int_array_element(interp
, varname
, n
, v
);
2764 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2769 static int get_int_array_element(Jim_Interp
* interp
, const char *varname
, int idx
, u32
*val
)
2772 Jim_Obj
*nameObjPtr
, *valObjPtr
;
2776 namebuf
= alloc_printf("%s(%d)", varname
, idx
);
2780 nameObjPtr
= Jim_NewStringObj(interp
, namebuf
, -1);
2787 Jim_IncrRefCount(nameObjPtr
);
2788 valObjPtr
= Jim_GetVariable(interp
, nameObjPtr
, JIM_ERRMSG
);
2789 Jim_DecrRefCount(interp
, nameObjPtr
);
2791 if (valObjPtr
== NULL
)
2794 result
= Jim_GetLong(interp
, valObjPtr
, &l
);
2795 /* printf("%s(%d) => 0%08x\n", varname, idx, val); */
2800 static int jim_array2mem(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
2802 command_context_t
*context
;
2805 context
= Jim_GetAssocData(interp
, "context");
2806 if (context
== NULL
){
2807 LOG_ERROR("array2mem: no command context");
2810 target
= get_current_target(context
);
2811 if (target
== NULL
){
2812 LOG_ERROR("array2mem: no current target");
2816 return target_array2mem( interp
,target
, argc
, argv
);
2820 static int target_array2mem(Jim_Interp
*interp
, target_t
*target
, int argc
, Jim_Obj
*const *argv
)
2828 const char *varname
;
2830 int i
, n
, e
, retval
;
2832 /* argv[1] = name of array to get the data
2833 * argv[2] = desired width
2834 * argv[3] = memory address
2835 * argv[4] = count to write
2838 Jim_WrongNumArgs(interp
, 1, argv
, "varname width addr nelems");
2841 varname
= Jim_GetString(argv
[1], &len
);
2842 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
2844 e
= Jim_GetLong(interp
, argv
[2], &l
);
2850 e
= Jim_GetLong(interp
, argv
[3], &l
);
2855 e
= Jim_GetLong(interp
, argv
[4], &l
);
2871 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2872 Jim_AppendStrings( interp
, Jim_GetResult(interp
), "Invalid width param, must be 8/16/32", NULL
);
2876 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2877 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: zero width read?", NULL
);
2880 if ((addr
+ (len
* width
)) < addr
) {
2881 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2882 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: addr + len - wraps to zero?", NULL
);
2885 /* absurd transfer size? */
2887 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2888 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: absurd > 64K item request", NULL
);
2893 ((width
== 2) && ((addr
& 1) == 0)) ||
2894 ((width
== 4) && ((addr
& 3) == 0))) {
2898 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2899 sprintf(buf
, "array2mem address: 0x%08x is not aligned for %d byte reads", addr
, width
);
2900 Jim_AppendStrings(interp
, Jim_GetResult(interp
), buf
, NULL
);
2912 /* Slurp... in buffer size chunks */
2914 count
= len
; /* in objects.. */
2915 if (count
> (sizeof(buffer
)/width
)) {
2916 count
= (sizeof(buffer
)/width
);
2919 v
= 0; /* shut up gcc */
2920 for (i
= 0 ;i
< count
;i
++, n
++) {
2921 get_int_array_element(interp
, varname
, n
, &v
);
2924 target_buffer_set_u32(target
, &buffer
[i
*width
], v
);
2927 target_buffer_set_u16(target
, &buffer
[i
*width
], v
);
2930 buffer
[i
] = v
& 0x0ff;
2936 retval
= target
->type
->write_memory(target
, addr
, width
, count
, buffer
);
2937 if (retval
!= ERROR_OK
) {
2939 LOG_ERROR("array2mem: Write @ 0x%08x, w=%d, cnt=%d, failed", addr
, width
, count
);
2940 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2941 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: cannot read memory", NULL
);
2947 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2953 target_all_handle_event( enum target_event e
)
2958 LOG_DEBUG( "**all*targets: event: %d, %s",
2960 Jim_Nvp_value2name_simple( nvp_target_event
, e
)->name
);
2962 target
= all_targets
;
2964 target_handle_event( target
, e
);
2965 target
= target
->next
;
2970 target_handle_event( target_t
*target
, enum target_event e
)
2972 target_event_action_t
*teap
;
2975 teap
= target
->event_action
;
2979 if( teap
->event
== e
){
2981 LOG_DEBUG( "target: (%d) %s (%s) event: %d (%s) action: %s\n",
2982 target
->target_number
,
2986 Jim_Nvp_value2name_simple( nvp_target_event
, e
)->name
,
2987 Jim_GetString( teap
->body
, NULL
) );
2988 if (Jim_EvalObj( interp
, teap
->body
)!=JIM_OK
)
2990 Jim_PrintErrorMessage(interp
);
2996 LOG_DEBUG( "event: %d %s - no action",
2998 Jim_Nvp_value2name_simple( nvp_target_event
, e
)->name
);
3002 enum target_cfg_param
{
3005 TCFG_WORK_AREA_VIRT
,
3006 TCFG_WORK_AREA_PHYS
,
3007 TCFG_WORK_AREA_SIZE
,
3008 TCFG_WORK_AREA_BACKUP
,
3011 TCFG_CHAIN_POSITION
,
3015 static Jim_Nvp nvp_config_opts
[] = {
3016 { .name
= "-type", .value
= TCFG_TYPE
},
3017 { .name
= "-event", .value
= TCFG_EVENT
},
3018 { .name
= "-work-area-virt", .value
= TCFG_WORK_AREA_VIRT
},
3019 { .name
= "-work-area-phys", .value
= TCFG_WORK_AREA_PHYS
},
3020 { .name
= "-work-area-size", .value
= TCFG_WORK_AREA_SIZE
},
3021 { .name
= "-work-area-backup", .value
= TCFG_WORK_AREA_BACKUP
},
3022 { .name
= "-endian" , .value
= TCFG_ENDIAN
},
3023 { .name
= "-variant", .value
= TCFG_VARIANT
},
3024 { .name
= "-chain-position", .value
= TCFG_CHAIN_POSITION
},
3026 { .name
= NULL
, .value
= -1 }
3031 target_configure( Jim_GetOptInfo
*goi
,
3041 /* parse config or cget options ... */
3042 while( goi
->argc
> 0 ){
3043 Jim_SetEmptyResult( goi
->interp
);
3044 //Jim_GetOpt_Debug( goi );
3046 if( target
->type
->target_jim_configure
){
3047 /* target defines a configure function */
3048 /* target gets first dibs on parameters */
3049 e
= (*(target
->type
->target_jim_configure
))( target
, goi
);
3058 /* otherwise we 'continue' below */
3060 e
= Jim_GetOpt_Nvp( goi
, nvp_config_opts
, &n
);
3062 Jim_GetOpt_NvpUnknown( goi
, nvp_config_opts
, 0 );
3068 if( goi
->isconfigure
){
3069 Jim_SetResult_sprintf( goi
->interp
, "not setable: %s", n
->name
);
3073 if( goi
->argc
!= 0 ){
3074 Jim_WrongNumArgs( goi
->interp
, goi
->argc
, goi
->argv
, "NO PARAMS");
3078 Jim_SetResultString( goi
->interp
, target
->type
->name
, -1 );
3082 if( goi
->argc
== 0 ){
3083 Jim_WrongNumArgs( goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name? ...");
3087 e
= Jim_GetOpt_Nvp( goi
, nvp_target_event
, &n
);
3089 Jim_GetOpt_NvpUnknown( goi
, nvp_target_event
, 1 );
3093 if( goi
->isconfigure
){
3094 if( goi
->argc
!= 1 ){
3095 Jim_WrongNumArgs( goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name? ?EVENT-BODY?");
3099 if( goi
->argc
!= 0 ){
3100 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name?");
3107 target_event_action_t
*teap
;
3109 teap
= target
->event_action
;
3110 /* replace existing? */
3112 if( teap
->event
== n
->value
){
3118 if( goi
->isconfigure
){
3121 teap
= calloc( 1, sizeof(*teap
) );
3123 teap
->event
= n
->value
;
3124 Jim_GetOpt_Obj( goi
, &o
);
3126 Jim_DecrRefCount( interp
, teap
->body
);
3128 teap
->body
= Jim_DuplicateObj( goi
->interp
, o
);
3131 * Tcl/TK - "tk events" have a nice feature.
3132 * See the "BIND" command.
3133 * We should support that here.
3134 * You can specify %X and %Y in the event code.
3135 * The idea is: %T - target name.
3136 * The idea is: %N - target number
3137 * The idea is: %E - event name.
3139 Jim_IncrRefCount( teap
->body
);
3141 /* add to head of event list */
3142 teap
->next
= target
->event_action
;
3143 target
->event_action
= teap
;
3144 Jim_SetEmptyResult(goi
->interp
);
3148 Jim_SetEmptyResult( goi
->interp
);
3150 Jim_SetResult( goi
->interp
, Jim_DuplicateObj( goi
->interp
, teap
->body
) );
3157 case TCFG_WORK_AREA_VIRT
:
3158 if( goi
->isconfigure
){
3159 target_free_all_working_areas(target
);
3160 e
= Jim_GetOpt_Wide( goi
, &w
);
3164 target
->working_area_virt
= w
;
3166 if( goi
->argc
!= 0 ){
3170 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_virt
) );
3174 case TCFG_WORK_AREA_PHYS
:
3175 if( goi
->isconfigure
){
3176 target_free_all_working_areas(target
);
3177 e
= Jim_GetOpt_Wide( goi
, &w
);
3181 target
->working_area_phys
= w
;
3183 if( goi
->argc
!= 0 ){
3187 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_phys
) );
3191 case TCFG_WORK_AREA_SIZE
:
3192 if( goi
->isconfigure
){
3193 target_free_all_working_areas(target
);
3194 e
= Jim_GetOpt_Wide( goi
, &w
);
3198 target
->working_area_size
= w
;
3200 if( goi
->argc
!= 0 ){
3204 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_size
) );
3208 case TCFG_WORK_AREA_BACKUP
:
3209 if( goi
->isconfigure
){
3210 target_free_all_working_areas(target
);
3211 e
= Jim_GetOpt_Wide( goi
, &w
);
3215 /* make this exactly 1 or 0 */
3216 target
->backup_working_area
= (!!w
);
3218 if( goi
->argc
!= 0 ){
3222 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_size
) );
3223 /* loop for more e*/
3227 if( goi
->isconfigure
){
3228 e
= Jim_GetOpt_Nvp( goi
, nvp_target_endian
, &n
);
3230 Jim_GetOpt_NvpUnknown( goi
, nvp_target_endian
, 1 );
3233 target
->endianness
= n
->value
;
3235 if( goi
->argc
!= 0 ){
3239 n
= Jim_Nvp_value2name_simple( nvp_target_endian
, target
->endianness
);
3240 if( n
->name
== NULL
){
3241 target
->endianness
= TARGET_LITTLE_ENDIAN
;
3242 n
= Jim_Nvp_value2name_simple( nvp_target_endian
, target
->endianness
);
3244 Jim_SetResultString( goi
->interp
, n
->name
, -1 );
3249 if( goi
->isconfigure
){
3250 if( goi
->argc
< 1 ){
3251 Jim_SetResult_sprintf( goi
->interp
,
3256 if( target
->variant
){
3257 free((void *)(target
->variant
));
3259 e
= Jim_GetOpt_String( goi
, &cp
, NULL
);
3260 target
->variant
= strdup(cp
);
3262 if( goi
->argc
!= 0 ){
3266 Jim_SetResultString( goi
->interp
, target
->variant
,-1 );
3269 case TCFG_CHAIN_POSITION
:
3270 if( goi
->isconfigure
){
3271 target_free_all_working_areas(target
);
3272 e
= Jim_GetOpt_Wide( goi
, &w
);
3276 /* make this exactly 1 or 0 */
3277 target
->chain_position
= w
;
3279 if( goi
->argc
!= 0 ){
3283 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->chain_position
) );
3284 /* loop for more e*/
3287 } /* while( goi->argc ) */
3288 /* done - we return */
3293 /** this is the 'tcl' handler for the target specific command */
3295 tcl_target_func( Jim_Interp
*interp
,
3297 Jim_Obj
*const *argv
)
3305 struct command_context_s
*cmd_ctx
;
3313 TS_CMD_MWW
, TS_CMD_MWH
, TS_CMD_MWB
,
3314 TS_CMD_MDW
, TS_CMD_MDH
, TS_CMD_MDB
,
3315 TS_CMD_MRW
, TS_CMD_MRH
, TS_CMD_MRB
,
3316 TS_CMD_MEM2ARRAY
, TS_CMD_ARRAY2MEM
,
3324 TS_CMD_INVOKE_EVENT
,
3327 static const Jim_Nvp target_options
[] = {
3328 { .name
= "configure", .value
= TS_CMD_CONFIGURE
},
3329 { .name
= "cget", .value
= TS_CMD_CGET
},
3330 { .name
= "mww", .value
= TS_CMD_MWW
},
3331 { .name
= "mwh", .value
= TS_CMD_MWH
},
3332 { .name
= "mwb", .value
= TS_CMD_MWB
},
3333 { .name
= "mdw", .value
= TS_CMD_MDW
},
3334 { .name
= "mdh", .value
= TS_CMD_MDH
},
3335 { .name
= "mdb", .value
= TS_CMD_MDB
},
3336 { .name
= "mem2array", .value
= TS_CMD_MEM2ARRAY
},
3337 { .name
= "array2mem", .value
= TS_CMD_ARRAY2MEM
},
3338 { .name
= "eventlist", .value
= TS_CMD_EVENTLIST
},
3339 { .name
= "curstate", .value
= TS_CMD_CURSTATE
},
3341 { .name
= "arp_examine", .value
= TS_CMD_EXAMINE
},
3342 { .name
= "arp_poll", .value
= TS_CMD_POLL
},
3343 { .name
= "arp_reset", .value
= TS_CMD_RESET
},
3344 { .name
= "arp_halt", .value
= TS_CMD_HALT
},
3345 { .name
= "arp_waitstate", .value
= TS_CMD_WAITSTATE
},
3346 { .name
= "invoke-event", .value
= TS_CMD_INVOKE_EVENT
},
3348 { .name
= NULL
, .value
= -1 },
3352 /* go past the "command" */
3353 Jim_GetOpt_Setup( &goi
, interp
, argc
-1, argv
+1 );
3355 target
= Jim_CmdPrivData( goi
.interp
);
3356 cmd_ctx
= Jim_GetAssocData(goi
.interp
, "context");
3358 /* commands here are in an NVP table */
3359 e
= Jim_GetOpt_Nvp( &goi
, target_options
, &n
);
3361 Jim_GetOpt_NvpUnknown( &goi
, target_options
, 0 );
3364 // Assume blank result
3365 Jim_SetEmptyResult( goi
.interp
);
3368 case TS_CMD_CONFIGURE
:
3370 Jim_WrongNumArgs( goi
.interp
, goi
.argc
, goi
.argv
, "missing: -option VALUE ...");
3373 goi
.isconfigure
= 1;
3374 return target_configure( &goi
, target
);
3376 // some things take params
3378 Jim_WrongNumArgs( goi
.interp
, 0, goi
.argv
, "missing: ?-option?");
3381 goi
.isconfigure
= 0;
3382 return target_configure( &goi
, target
);
3390 * argv[3] = optional count.
3393 if( (goi
.argc
== 3) || (goi
.argc
== 4) ){
3397 Jim_SetResult_sprintf( goi
.interp
, "expected: %s ADDR DATA [COUNT]", n
->name
);
3401 e
= Jim_GetOpt_Wide( &goi
, &a
);
3406 e
= Jim_GetOpt_Wide( &goi
, &b
);
3411 e
= Jim_GetOpt_Wide( &goi
, &c
);
3421 target_buffer_set_u32( target
, target_buf
, b
);
3425 target_buffer_set_u16( target
, target_buf
, b
);
3429 target_buffer_set_u8( target
, target_buf
, b
);
3433 for( x
= 0 ; x
< c
; x
++ ){
3434 e
= target
->type
->write_memory( target
, a
, b
, 1, target_buf
);
3435 if( e
!= ERROR_OK
){
3436 Jim_SetResult_sprintf( interp
, "Error writing @ 0x%08x: %d\n", (int)(a
), e
);
3449 /* argv[0] = command
3451 * argv[2] = optional count
3453 if( (goi
.argc
== 2) || (goi
.argc
== 3) ){
3454 Jim_SetResult_sprintf( goi
.interp
, "expected: %s ADDR [COUNT]", n
->name
);
3457 e
= Jim_GetOpt_Wide( &goi
, &a
);
3462 e
= Jim_GetOpt_Wide( &goi
, &c
);
3469 b
= 1; /* shut up gcc */
3482 /* convert to "bytes" */
3484 /* count is now in 'BYTES' */
3490 e
= target
->type
->read_memory( target
, a
, b
, y
/ b
, target_buf
);
3491 if( e
!= ERROR_OK
){
3492 Jim_SetResult_sprintf( interp
, "error reading target @ 0x%08lx", (int)(a
) );
3496 Jim_fprintf( interp
, interp
->cookie_stdout
, "0x%08x ", (int)(a
) );
3499 for( x
= 0 ; (x
< 16) && (x
< y
) ; x
+= 4 ){
3500 z
= target_buffer_get_u32( target
, &(target_buf
[ x
* 4 ]) );
3501 Jim_fprintf( interp
, interp
->cookie_stdout
, "%08x ", (int)(z
) );
3503 for( ; (x
< 16) ; x
+= 4 ){
3504 Jim_fprintf( interp
, interp
->cookie_stdout
, " " );
3508 for( x
= 0 ; (x
< 16) && (x
< y
) ; x
+= 2 ){
3509 z
= target_buffer_get_u16( target
, &(target_buf
[ x
* 2 ]) );
3510 Jim_fprintf( interp
, interp
->cookie_stdout
, "%04x ", (int)(z
) );
3512 for( ; (x
< 16) ; x
+= 2 ){
3513 Jim_fprintf( interp
, interp
->cookie_stdout
, " " );
3518 for( x
= 0 ; (x
< 16) && (x
< y
) ; x
+= 1 ){
3519 z
= target_buffer_get_u8( target
, &(target_buf
[ x
* 4 ]) );
3520 Jim_fprintf( interp
, interp
->cookie_stdout
, "%02x ", (int)(z
) );
3522 for( ; (x
< 16) ; x
+= 1 ){
3523 Jim_fprintf( interp
, interp
->cookie_stdout
, " " );
3527 /* ascii-ify the bytes */
3528 for( x
= 0 ; x
< y
; x
++ ){
3529 if( (target_buf
[x
] >= 0x20) &&
3530 (target_buf
[x
] <= 0x7e) ){
3534 target_buf
[x
] = '.';
3539 target_buf
[x
] = ' ';
3544 /* print - with a newline */
3545 Jim_fprintf( interp
, interp
->cookie_stdout
, "%s\n", target_buf
);
3551 case TS_CMD_MEM2ARRAY
:
3552 return target_mem2array( goi
.interp
, target
, goi
.argc
, goi
.argv
);
3554 case TS_CMD_ARRAY2MEM
:
3555 return target_array2mem( goi
.interp
, target
, goi
.argc
, goi
.argv
);
3557 case TS_CMD_EXAMINE
:
3559 Jim_WrongNumArgs( goi
.interp
, 2, argv
, "[no parameters]");
3562 e
= target
->type
->examine( target
);
3563 if( e
!= ERROR_OK
){
3564 Jim_SetResult_sprintf( interp
, "examine-fails: %d", e
);
3570 Jim_WrongNumArgs( goi
.interp
, 2, argv
, "[no parameters]");
3573 if( !(target
->type
->examined
) ){
3574 e
= ERROR_TARGET_NOT_EXAMINED
;
3576 e
= target
->type
->poll( target
);
3578 if( e
!= ERROR_OK
){
3579 Jim_SetResult_sprintf( interp
, "poll-fails: %d", e
);
3586 if( goi
.argc
!= 2 ){
3587 Jim_WrongNumArgs( interp
, 2, argv
, "t|f|assert|deassert BOOL");
3590 e
= Jim_GetOpt_Nvp( &goi
, nvp_assert
, &n
);
3592 Jim_GetOpt_NvpUnknown( &goi
, nvp_assert
, 1 );
3595 // the halt or not param
3596 e
= Jim_GetOpt_Wide( &goi
, &a
);
3600 // determine if we should halt or not.
3601 target
->reset_halt
= !!a
;
3602 // When this happens - all workareas are invalid.
3603 target_free_all_working_areas_restore(target
, 0);
3606 if( n
->value
== NVP_ASSERT
){
3607 target
->type
->assert_reset( target
);
3609 target
->type
->deassert_reset( target
);
3614 Jim_WrongNumArgs( goi
.interp
, 0, argv
, "halt [no parameters]");
3617 target
->type
->halt( target
);
3619 case TS_CMD_WAITSTATE
:
3620 // params: <name> statename timeoutmsecs
3621 if( goi
.argc
!= 2 ){
3622 Jim_SetResult_sprintf( goi
.interp
, "%s STATENAME TIMEOUTMSECS", n
->name
);
3625 e
= Jim_GetOpt_Nvp( &goi
, nvp_target_state
, &n
);
3627 Jim_GetOpt_NvpUnknown( &goi
, nvp_target_state
,1 );
3630 e
= Jim_GetOpt_Wide( &goi
, &a
);
3634 e
= target_wait_state( target
, n
->value
, a
);
3635 if( e
!= ERROR_OK
){
3636 Jim_SetResult_sprintf( goi
.interp
,
3637 "target: %s wait %s fails (%d) %s",
3640 e
, target_strerror_safe(e
) );
3645 case TS_CMD_EVENTLIST
:
3646 /* List for human, Events defined for this target.
3647 * scripts/programs should use 'name cget -event NAME'
3650 target_event_action_t
*teap
;
3651 teap
= target
->event_action
;
3652 command_print( cmd_ctx
, "Event actions for target (%d) %s\n",
3653 target
->target_number
,
3655 command_print( cmd_ctx
, "%-25s | Body", "Event");
3656 command_print( cmd_ctx
, "------------------------- | ----------------------------------------");
3658 command_print( cmd_ctx
,
3660 Jim_Nvp_value2name_simple( nvp_target_event
, teap
->event
)->name
,
3661 Jim_GetString( teap
->body
, NULL
) );
3664 command_print( cmd_ctx
, "***END***");
3667 case TS_CMD_CURSTATE
:
3668 if( goi
.argc
!= 0 ){
3669 Jim_WrongNumArgs( goi
.interp
, 0, argv
, "[no parameters]");
3672 Jim_SetResultString( goi
.interp
,
3673 Jim_Nvp_value2name_simple(nvp_target_state
,target
->state
)->name
,-1);
3675 case TS_CMD_INVOKE_EVENT
:
3676 if( goi
.argc
!= 1 ){
3677 Jim_SetResult_sprintf( goi
.interp
, "%s ?EVENTNAME?",n
->name
);
3680 e
= Jim_GetOpt_Nvp( &goi
, nvp_target_event
, &n
);
3682 Jim_GetOpt_NvpUnknown( &goi
, nvp_target_event
, 1 );
3685 target_handle_event( target
, n
->value
);
3693 target_create( Jim_GetOptInfo
*goi
)
3703 struct command_context_s
*cmd_ctx
;
3705 cmd_ctx
= Jim_GetAssocData(goi
->interp
, "context");
3706 if( goi
->argc
< 3 ){
3707 Jim_WrongNumArgs( goi
->interp
, 1, goi
->argv
, "?name? ?type? ..options...");
3712 Jim_GetOpt_Obj( goi
, &new_cmd
);
3713 /* does this command exist? */
3714 cmd
= Jim_GetCommand( goi
->interp
, new_cmd
, JIM_ERRMSG
);
3716 cp
= Jim_GetString( new_cmd
, NULL
);
3717 Jim_SetResult_sprintf(goi
->interp
, "Command/target: %s Exists", cp
);
3722 e
= Jim_GetOpt_String( goi
, &cp2
, NULL
);
3724 /* now does target type exist */
3725 for( x
= 0 ; target_types
[x
] ; x
++ ){
3726 if( 0 == strcmp( cp
, target_types
[x
]->name
) ){
3731 if( target_types
[x
] == NULL
){
3732 Jim_SetResult_sprintf( goi
->interp
, "Unknown target type %s, try one of ", cp
);
3733 for( x
= 0 ; target_types
[x
] ; x
++ ){
3734 if( target_types
[x
+1] ){
3735 Jim_AppendStrings( goi
->interp
,
3736 Jim_GetResult(goi
->interp
),
3737 target_types
[x
]->name
,
3740 Jim_AppendStrings( goi
->interp
,
3741 Jim_GetResult(goi
->interp
),
3743 target_types
[x
]->name
,NULL
);
3751 target
= calloc(1,sizeof(target_t
));
3752 /* set target number */
3753 target
->target_number
= new_target_number();
3755 /* allocate memory for each unique target type */
3756 target
->type
= (target_type_t
*)calloc(1,sizeof(target_type_t
));
3758 memcpy( target
->type
, target_types
[x
], sizeof(target_type_t
));
3760 /* will be set by "-endian" */
3761 target
->endianness
= TARGET_ENDIAN_UNKNOWN
;
3763 target
->working_area
= 0x0;
3764 target
->working_area_size
= 0x0;
3765 target
->working_areas
= NULL
;
3766 target
->backup_working_area
= 0;
3768 target
->state
= TARGET_UNKNOWN
;
3769 target
->debug_reason
= DBG_REASON_UNDEFINED
;
3770 target
->reg_cache
= NULL
;
3771 target
->breakpoints
= NULL
;
3772 target
->watchpoints
= NULL
;
3773 target
->next
= NULL
;
3774 target
->arch_info
= NULL
;
3776 /* initialize trace information */
3777 target
->trace_info
= malloc(sizeof(trace_t
));
3778 target
->trace_info
->num_trace_points
= 0;
3779 target
->trace_info
->trace_points_size
= 0;
3780 target
->trace_info
->trace_points
= NULL
;
3781 target
->trace_info
->trace_history_size
= 0;
3782 target
->trace_info
->trace_history
= NULL
;
3783 target
->trace_info
->trace_history_pos
= 0;
3784 target
->trace_info
->trace_history_overflowed
= 0;
3786 target
->dbgmsg
= NULL
;
3787 target
->dbg_msg_enabled
= 0;
3789 target
->endianness
= TARGET_ENDIAN_UNKNOWN
;
3791 /* Do the rest as "configure" options */
3792 goi
->isconfigure
= 1;
3793 e
= target_configure( goi
, target
);
3795 free( target
->type
);
3800 if( target
->endianness
== TARGET_ENDIAN_UNKNOWN
){
3801 /* default endian to little if not specified */
3802 target
->endianness
= TARGET_LITTLE_ENDIAN
;
3805 /* create the target specific commands */
3806 if( target
->type
->register_commands
){
3807 (*(target
->type
->register_commands
))( cmd_ctx
);
3809 if( target
->type
->target_create
){
3810 (*(target
->type
->target_create
))( target
, goi
->interp
);
3813 /* append to end of list */
3816 tpp
= &(all_targets
);
3818 tpp
= &( (*tpp
)->next
);
3823 cp
= Jim_GetString( new_cmd
, NULL
);
3824 target
->cmd_name
= strdup(cp
);
3826 /* now - create the new target name command */
3827 e
= Jim_CreateCommand( goi
->interp
,
3830 tcl_target_func
, /* C function */
3831 target
, /* private data */
3832 NULL
); /* no del proc */
3838 jim_target( Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
3842 struct command_context_s
*cmd_ctx
;
3847 /* TG = target generic */
3855 const char *target_cmds
[] = {
3856 "create", "types", "names", "current", "number",
3861 LOG_DEBUG("Target command params:");
3862 LOG_DEBUG(Jim_Debug_ArgvString( interp
, argc
, argv
) );
3864 cmd_ctx
= Jim_GetAssocData( interp
, "context" );
3866 Jim_GetOpt_Setup( &goi
, interp
, argc
-1, argv
+1 );
3868 if( goi
.argc
== 0 ){
3869 Jim_WrongNumArgs(interp
, 1, argv
, "missing: command ...");
3873 /* is this old syntax? */
3874 /* To determine: We have to peek at argv[0]*/
3875 cp
= Jim_GetString( goi
.argv
[0], NULL
);
3876 for( x
= 0 ; target_types
[x
] ; x
++ ){
3877 if( 0 == strcmp(cp
,target_types
[x
]->name
) ){
3881 if( target_types
[x
] ){
3882 /* YES IT IS OLD SYNTAX */
3883 Jim_Obj
*new_argv
[10];
3886 /* target_old_syntax
3888 * It appears that there are 2 old syntaxes:
3890 * target <typename> <endian> <chain position> <variant>
3894 * target <typename> <endian> <reset mode> <chain position> <variant>
3898 /* The minimum number of arguments is 4 */
3900 Jim_WrongNumArgs( interp
, 1, argv
, "[OLDSYNTAX] ?TYPE? ?ENDIAN? ?CHAIN-POSITION? ?VARIANT?");
3905 new_argv
[0] = argv
[0];
3906 new_argv
[1] = Jim_NewStringObj( interp
, "create", -1 );
3909 sprintf( buf
, "target%d", new_target_number() );
3910 new_argv
[2] = Jim_NewStringObj( interp
, buf
, -1 );
3912 new_argv
[3] = goi
.argv
[0]; /* typename */
3913 new_argv
[4] = Jim_NewStringObj( interp
, "-endian", -1 );
3914 new_argv
[5] = goi
.argv
[1];
3915 new_argv
[6] = Jim_NewStringObj( interp
, "-chain-position", -1 );
3917 /* If goi.argv[2] is not a number, we need to skip it since it is the reset mode. */
3919 int chain_position_argv
= 2;
3920 if (JIM_ERR
== Jim_GetWide(interp
, goi
.argv
[chain_position_argv
], &w
)) {
3921 if (chain_position_argv
+ 1 < goi
.argc
) {
3922 chain_position_argv
+= 1;
3924 Jim_WrongNumArgs( interp
, 1, argv
, "[OLDSYNTAX] ?TYPE? ?ENDIAN? ?RESET? ?CHAIN-POSITION? ?VARIANT?");
3929 new_argv
[7] = goi
.argv
[chain_position_argv
];
3931 /* Only provide a variant configure option if there was a variant specified */
3932 if (chain_position_argv
+ 1 < goi
.argc
) {
3933 new_argv
[8] = Jim_NewStringObj( interp
, "-variant", -1 );
3934 new_argv
[9] = goi
.argv
[chain_position_argv
+ 1];
3945 * argv[3] = typename
3948 * argv[6] = -position
3950 * argv[8] = -variant
3951 * argv[9] = "somestring"
3954 /* don't let these be released */
3955 for( x
= 0 ; x
< new_argc
; x
++ ){
3956 Jim_IncrRefCount( new_argv
[x
]);
3959 LOG_DEBUG("Target OLD SYNTAX - converted to new syntax");
3961 r
= jim_target( goi
.interp
, new_argc
, new_argv
);
3963 /* release? these items */
3964 for( x
= 0 ; x
< new_argc
; x
++ ){
3965 Jim_DecrRefCount( interp
, new_argv
[x
] );
3970 //Jim_GetOpt_Debug( &goi );
3971 r
= Jim_GetOpt_Enum( &goi
, target_cmds
, &x
);
3978 Jim_Panic(goi
.interp
,"Why am I here?");
3980 case TG_CMD_CURRENT
:
3981 if( goi
.argc
!= 0 ){
3982 Jim_WrongNumArgs( goi
.interp
, 1, goi
.argv
, "Too many parameters");
3985 Jim_SetResultString( goi
.interp
, get_current_target( cmd_ctx
)->cmd_name
, -1 );
3988 if( goi
.argc
!= 0 ){
3989 Jim_WrongNumArgs( goi
.interp
, 1, goi
.argv
, "Too many parameters" );
3992 Jim_SetResult( goi
.interp
, Jim_NewListObj( goi
.interp
, NULL
, 0 ) );
3993 for( x
= 0 ; target_types
[x
] ; x
++ ){
3994 Jim_ListAppendElement( goi
.interp
,
3995 Jim_GetResult(goi
.interp
),
3996 Jim_NewStringObj( goi
.interp
, target_types
[x
]->name
, -1 ) );
4000 if( goi
.argc
!= 0 ){
4001 Jim_WrongNumArgs( goi
.interp
, 1, goi
.argv
, "Too many parameters" );
4004 Jim_SetResult( goi
.interp
, Jim_NewListObj( goi
.interp
, NULL
, 0 ) );
4005 target
= all_targets
;
4007 Jim_ListAppendElement( goi
.interp
,
4008 Jim_GetResult(goi
.interp
),
4009 Jim_NewStringObj( goi
.interp
, target
->cmd_name
, -1 ) );
4010 target
= target
->next
;
4015 Jim_WrongNumArgs( goi
.interp
, goi
.argc
, goi
.argv
, "?name ... config options ...");
4018 return target_create( &goi
);
4021 if( goi
.argc
!= 1 ){
4022 Jim_SetResult_sprintf( goi
.interp
, "expected: target number ?NUMBER?");
4025 e
= Jim_GetOpt_Wide( &goi
, &w
);
4031 t
= get_target_by_num(w
);
4033 Jim_SetResult_sprintf( goi
.interp
,"Target: number %d does not exist", (int)(w
));
4036 Jim_SetResultString( goi
.interp
, t
->cmd_name
, -1 );
4040 if( goi
.argc
!= 0 ){
4041 Jim_WrongNumArgs( goi
.interp
, 0, goi
.argv
, "<no parameters>");
4044 Jim_SetResult( goi
.interp
,
4045 Jim_NewIntObj( goi
.interp
, max_target_number()));
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)