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 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program; if not, write to the *
26 * Free Software Foundation, Inc., *
27 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
28 ***************************************************************************/
33 #include "replacements.h"
35 #include "target_request.h"
38 #include "configuration.h"
39 #include "binarybuffer.h"
46 #include <sys/types.h>
54 #include <time_support.h>
59 int cli_target_callback_event_handler(struct target_s
*target
, enum target_event event
, void *priv
);
62 int handle_targets_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
64 int handle_working_area_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
66 int handle_reg_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
67 int handle_poll_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
68 int handle_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
69 int handle_wait_halt_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
);
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
);
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
;
107 target_type_t
*target_types
[] =
123 target_t
*all_targets
= NULL
;
124 target_event_callback_t
*target_event_callbacks
= NULL
;
125 target_timer_callback_t
*target_timer_callbacks
= NULL
;
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 }
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
}
152 const char *target_strerror_safe( int err
)
156 n
= Jim_Nvp_value2name_simple( nvp_error_target
, err
);
157 if( n
->name
== NULL
){
164 const Jim_Nvp nvp_target_event
[] = {
165 { .value
= TARGET_EVENT_OLD_gdb_program_config
, .name
= "old-gdb_program_config" },
166 { .value
= TARGET_EVENT_OLD_pre_resume
, .name
= "old-pre_resume" },
169 { .value
= TARGET_EVENT_EARLY_HALTED
, .name
= "early-halted" },
170 { .value
= TARGET_EVENT_HALTED
, .name
= "halted" },
171 { .value
= TARGET_EVENT_RESUMED
, .name
= "resumed" },
172 { .value
= TARGET_EVENT_RESUME_START
, .name
= "resume-start" },
173 { .value
= TARGET_EVENT_RESUME_END
, .name
= "resume-end" },
175 /* historical name */
177 { .value
= TARGET_EVENT_RESET_START
, .name
= "reset-start" },
179 { .value
= TARGET_EVENT_RESET_ASSERT_PRE
, .name
= "reset-assert-pre" },
180 { .value
= TARGET_EVENT_RESET_ASSERT_POST
, .name
= "reset-assert-post" },
181 { .value
= TARGET_EVENT_RESET_DEASSERT_PRE
, .name
= "reset-deassert-pre" },
182 { .value
= TARGET_EVENT_RESET_DEASSERT_POST
, .name
= "reset-deassert-post" },
183 { .value
= TARGET_EVENT_RESET_HALT_PRE
, .name
= "reset-halt-pre" },
184 { .value
= TARGET_EVENT_RESET_HALT_POST
, .name
= "reset-halt-post" },
185 { .value
= TARGET_EVENT_RESET_WAIT_PRE
, .name
= "reset-wait-pre" },
186 { .value
= TARGET_EVENT_RESET_WAIT_POST
, .name
= "reset-wait-post" },
187 { .value
= TARGET_EVENT_RESET_INIT
, .name
= "reset-init" },
188 { .value
= TARGET_EVENT_RESET_END
, .name
= "reset-end" },
194 { .value
= TARGET_EVENT_EXAMINE_START
, .name
= "examine-start" },
195 { .value
= TARGET_EVENT_EXAMINE_START
, .name
= "examine-end" },
198 { .value
= TARGET_EVENT_DEBUG_HALTED
, .name
= "debug-halted" },
199 { .value
= TARGET_EVENT_DEBUG_RESUMED
, .name
= "debug-resumed" },
201 { .value
= TARGET_EVENT_GDB_ATTACH
, .name
= "gdb-attach" },
202 { .value
= TARGET_EVENT_GDB_DETACH
, .name
= "gdb-detach" },
205 { .value
= TARGET_EVENT_GDB_FLASH_WRITE_START
, .name
= "gdb-flash-write-start" },
206 { .value
= TARGET_EVENT_GDB_FLASH_WRITE_END
, .name
= "gdb-flash-write-end" },
208 { .value
= TARGET_EVENT_GDB_FLASH_ERASE_START
, .name
= "gdb-flash-erase-start" },
209 { .value
= TARGET_EVENT_GDB_FLASH_ERASE_END
, .name
= "gdb-flash-erase-end" },
211 { .value
= TARGET_EVENT_RESUME_START
, .name
= "resume-start" },
212 { .value
= TARGET_EVENT_RESUMED
, .name
= "resume-ok" },
213 { .value
= TARGET_EVENT_RESUME_END
, .name
= "resume-end" },
215 { .name
= NULL
, .value
= -1 }
218 const Jim_Nvp nvp_target_state
[] = {
219 { .name
= "unknown", .value
= TARGET_UNKNOWN
},
220 { .name
= "running", .value
= TARGET_RUNNING
},
221 { .name
= "halted", .value
= TARGET_HALTED
},
222 { .name
= "reset", .value
= TARGET_RESET
},
223 { .name
= "debug-running", .value
= TARGET_DEBUG_RUNNING
},
224 { .name
= NULL
, .value
= -1 },
228 const Jim_Nvp nvp_target_debug_reason
[] = {
229 { .name
= "debug-request" , .value
= DBG_REASON_DBGRQ
},
230 { .name
= "breakpoint" , .value
= DBG_REASON_BREAKPOINT
},
231 { .name
= "watchpoint" , .value
= DBG_REASON_WATCHPOINT
},
232 { .name
= "watchpoint-and-breakpoint", .value
= DBG_REASON_WPTANDBKPT
},
233 { .name
= "single-step" , .value
= DBG_REASON_SINGLESTEP
},
234 { .name
= "target-not-halted" , .value
= DBG_REASON_NOTHALTED
},
235 { .name
= "undefined" , .value
= DBG_REASON_UNDEFINED
},
236 { .name
= NULL
, .value
= -1 },
240 const Jim_Nvp nvp_target_endian
[] = {
241 { .name
= "big", .value
= TARGET_BIG_ENDIAN
},
242 { .name
= "little", .value
= TARGET_LITTLE_ENDIAN
},
243 { .name
= "be", .value
= TARGET_BIG_ENDIAN
},
244 { .name
= "le", .value
= TARGET_LITTLE_ENDIAN
},
245 { .name
= NULL
, .value
= -1 },
248 const Jim_Nvp nvp_reset_modes
[] = {
249 { .name
= "unknown", .value
= RESET_UNKNOWN
},
250 { .name
= "run" , .value
= RESET_RUN
},
251 { .name
= "halt" , .value
= RESET_HALT
},
252 { .name
= "init" , .value
= RESET_INIT
},
253 { .name
= NULL
, .value
= -1 },
257 max_target_number( void )
265 if( x
< t
->target_number
){
266 x
= (t
->target_number
)+1;
273 /* determine the number of the new target */
275 new_target_number( void )
280 /* number is 0 based */
284 if( x
< t
->target_number
){
285 x
= t
->target_number
;
292 static int target_continous_poll
= 1;
294 /* read a u32 from a buffer in target memory endianness */
295 u32
target_buffer_get_u32(target_t
*target
, u8
*buffer
)
297 if (target
->endianness
== TARGET_LITTLE_ENDIAN
)
298 return le_to_h_u32(buffer
);
300 return be_to_h_u32(buffer
);
303 /* read a u16 from a buffer in target memory endianness */
304 u16
target_buffer_get_u16(target_t
*target
, u8
*buffer
)
306 if (target
->endianness
== TARGET_LITTLE_ENDIAN
)
307 return le_to_h_u16(buffer
);
309 return be_to_h_u16(buffer
);
312 /* read a u8 from a buffer in target memory endianness */
313 u8
target_buffer_get_u8(target_t
*target
, u8
*buffer
)
315 return *buffer
& 0x0ff;
318 /* write a u32 to a buffer in target memory endianness */
319 void target_buffer_set_u32(target_t
*target
, u8
*buffer
, u32 value
)
321 if (target
->endianness
== TARGET_LITTLE_ENDIAN
)
322 h_u32_to_le(buffer
, value
);
324 h_u32_to_be(buffer
, value
);
327 /* write a u16 to a buffer in target memory endianness */
328 void target_buffer_set_u16(target_t
*target
, u8
*buffer
, u16 value
)
330 if (target
->endianness
== TARGET_LITTLE_ENDIAN
)
331 h_u16_to_le(buffer
, value
);
333 h_u16_to_be(buffer
, value
);
336 /* write a u8 to a buffer in target memory endianness */
337 void target_buffer_set_u8(target_t
*target
, u8
*buffer
, u8 value
)
342 /* returns a pointer to the n-th configured target */
343 target_t
* get_target_by_num(int num
)
345 target_t
*target
= all_targets
;
348 if( target
->target_number
== num
){
351 target
= target
->next
;
357 int get_num_by_target(target_t
*query_target
)
359 return query_target
->target_number
;
362 target_t
* get_current_target(command_context_t
*cmd_ctx
)
364 target_t
*target
= get_target_by_num(cmd_ctx
->current_target
);
368 LOG_ERROR("BUG: current_target out of bounds");
376 int target_poll(struct target_s
*target
)
378 /* We can't poll until after examine */
379 if (!target
->type
->examined
)
381 /* Fail silently lest we pollute the log */
384 return target
->type
->poll(target
);
387 int target_halt(struct target_s
*target
)
389 /* We can't poll until after examine */
390 if (!target
->type
->examined
)
392 LOG_ERROR("Target not examined yet");
395 return target
->type
->halt(target
);
398 int target_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
402 /* We can't poll until after examine */
403 if (!target
->type
->examined
)
405 LOG_ERROR("Target not examined yet");
409 /* note that resume *must* be asynchronous. The CPU can halt before we poll. The CPU can
410 * even halt at the current PC as a result of a software breakpoint being inserted by (a bug?)
413 if ((retval
= target
->type
->resume(target
, current
, address
, handle_breakpoints
, debug_execution
)) != ERROR_OK
)
420 int target_process_reset(struct command_context_s
*cmd_ctx
, enum target_reset_mode reset_mode
)
425 n
= Jim_Nvp_value2name_simple( nvp_reset_modes
, reset_mode
);
426 if( n
->name
== NULL
){
427 LOG_ERROR("invalid reset mode");
431 sprintf( buf
, "ocd_process_reset %s", n
->name
);
432 retval
= Jim_Eval( interp
, buf
);
434 if(retval
!= JIM_OK
) {
435 Jim_PrintErrorMessage(interp
);
439 /* We want any events to be processed before the prompt */
440 retval
= target_call_timer_callbacks_now();
446 static int default_virt2phys(struct target_s
*target
, u32
virtual, u32
*physical
)
452 static int default_mmu(struct target_s
*target
, int *enabled
)
458 static int default_examine(struct target_s
*target
)
460 target
->type
->examined
= 1;
465 /* Targets that correctly implement init+examine, i.e.
466 * no communication with target during init:
470 int target_examine(void)
472 int retval
= ERROR_OK
;
473 target_t
*target
= all_targets
;
476 if ((retval
= target
->type
->examine(target
))!=ERROR_OK
)
478 target
= target
->next
;
483 static int target_write_memory_imp(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
485 if (!target
->type
->examined
)
487 LOG_ERROR("Target not examined yet");
490 return target
->type
->write_memory_imp(target
, address
, size
, count
, buffer
);
493 static int target_read_memory_imp(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
495 if (!target
->type
->examined
)
497 LOG_ERROR("Target not examined yet");
500 return target
->type
->read_memory_imp(target
, address
, size
, count
, buffer
);
503 static int target_soft_reset_halt_imp(struct target_s
*target
)
505 if (!target
->type
->examined
)
507 LOG_ERROR("Target not examined yet");
510 return target
->type
->soft_reset_halt_imp(target
);
513 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
)
515 if (!target
->type
->examined
)
517 LOG_ERROR("Target not examined yet");
520 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
);
523 int target_init(struct command_context_s
*cmd_ctx
)
525 target_t
*target
= all_targets
;
530 target
->type
->examined
= 0;
531 if (target
->type
->examine
== NULL
)
533 target
->type
->examine
= default_examine
;
536 if (target
->type
->init_target(cmd_ctx
, target
) != ERROR_OK
)
538 LOG_ERROR("target '%s' init failed", target
->type
->name
);
542 /* Set up default functions if none are provided by target */
543 if (target
->type
->virt2phys
== NULL
)
545 target
->type
->virt2phys
= default_virt2phys
;
547 target
->type
->virt2phys
= default_virt2phys
;
548 /* a non-invasive way(in terms of patches) to add some code that
549 * runs before the type->write/read_memory implementation
551 target
->type
->write_memory_imp
= target
->type
->write_memory
;
552 target
->type
->write_memory
= target_write_memory_imp
;
553 target
->type
->read_memory_imp
= target
->type
->read_memory
;
554 target
->type
->read_memory
= target_read_memory_imp
;
555 target
->type
->soft_reset_halt_imp
= target
->type
->soft_reset_halt
;
556 target
->type
->soft_reset_halt
= target_soft_reset_halt_imp
;
557 target
->type
->run_algorithm_imp
= target
->type
->run_algorithm
;
558 target
->type
->run_algorithm
= target_run_algorithm_imp
;
561 if (target
->type
->mmu
== NULL
)
563 target
->type
->mmu
= default_mmu
;
565 target
= target
->next
;
570 if((retval
= target_register_user_commands(cmd_ctx
)) != ERROR_OK
)
572 if((retval
= target_register_timer_callback(handle_target
, 100, 1, NULL
)) != ERROR_OK
)
579 int target_register_event_callback(int (*callback
)(struct target_s
*target
, enum target_event event
, void *priv
), void *priv
)
581 target_event_callback_t
**callbacks_p
= &target_event_callbacks
;
583 if (callback
== NULL
)
585 return ERROR_INVALID_ARGUMENTS
;
590 while ((*callbacks_p
)->next
)
591 callbacks_p
= &((*callbacks_p
)->next
);
592 callbacks_p
= &((*callbacks_p
)->next
);
595 (*callbacks_p
) = malloc(sizeof(target_event_callback_t
));
596 (*callbacks_p
)->callback
= callback
;
597 (*callbacks_p
)->priv
= priv
;
598 (*callbacks_p
)->next
= NULL
;
603 int target_register_timer_callback(int (*callback
)(void *priv
), int time_ms
, int periodic
, void *priv
)
605 target_timer_callback_t
**callbacks_p
= &target_timer_callbacks
;
608 if (callback
== NULL
)
610 return ERROR_INVALID_ARGUMENTS
;
615 while ((*callbacks_p
)->next
)
616 callbacks_p
= &((*callbacks_p
)->next
);
617 callbacks_p
= &((*callbacks_p
)->next
);
620 (*callbacks_p
) = malloc(sizeof(target_timer_callback_t
));
621 (*callbacks_p
)->callback
= callback
;
622 (*callbacks_p
)->periodic
= periodic
;
623 (*callbacks_p
)->time_ms
= time_ms
;
625 gettimeofday(&now
, NULL
);
626 (*callbacks_p
)->when
.tv_usec
= now
.tv_usec
+ (time_ms
% 1000) * 1000;
627 time_ms
-= (time_ms
% 1000);
628 (*callbacks_p
)->when
.tv_sec
= now
.tv_sec
+ (time_ms
/ 1000);
629 if ((*callbacks_p
)->when
.tv_usec
> 1000000)
631 (*callbacks_p
)->when
.tv_usec
= (*callbacks_p
)->when
.tv_usec
- 1000000;
632 (*callbacks_p
)->when
.tv_sec
+= 1;
635 (*callbacks_p
)->priv
= priv
;
636 (*callbacks_p
)->next
= NULL
;
641 int target_unregister_event_callback(int (*callback
)(struct target_s
*target
, enum target_event event
, void *priv
), void *priv
)
643 target_event_callback_t
**p
= &target_event_callbacks
;
644 target_event_callback_t
*c
= target_event_callbacks
;
646 if (callback
== NULL
)
648 return ERROR_INVALID_ARGUMENTS
;
653 target_event_callback_t
*next
= c
->next
;
654 if ((c
->callback
== callback
) && (c
->priv
== priv
))
668 int target_unregister_timer_callback(int (*callback
)(void *priv
), void *priv
)
670 target_timer_callback_t
**p
= &target_timer_callbacks
;
671 target_timer_callback_t
*c
= target_timer_callbacks
;
673 if (callback
== NULL
)
675 return ERROR_INVALID_ARGUMENTS
;
680 target_timer_callback_t
*next
= c
->next
;
681 if ((c
->callback
== callback
) && (c
->priv
== priv
))
695 int target_call_event_callbacks(target_t
*target
, enum target_event event
)
697 target_event_callback_t
*callback
= target_event_callbacks
;
698 target_event_callback_t
*next_callback
;
700 if (event
== TARGET_EVENT_HALTED
)
702 /* execute early halted first */
703 target_call_event_callbacks(target
, TARGET_EVENT_EARLY_HALTED
);
707 LOG_DEBUG("target event %i (%s)",
709 Jim_Nvp_value2name_simple( nvp_target_event
, event
)->name
);
711 target_handle_event( target
, event
);
715 next_callback
= callback
->next
;
716 callback
->callback(target
, event
, callback
->priv
);
717 callback
= next_callback
;
723 static int target_call_timer_callbacks_check_time(int checktime
)
725 target_timer_callback_t
*callback
= target_timer_callbacks
;
726 target_timer_callback_t
*next_callback
;
731 gettimeofday(&now
, NULL
);
735 next_callback
= callback
->next
;
737 if ((!checktime
&&callback
->periodic
)||
738 (((now
.tv_sec
>= callback
->when
.tv_sec
) && (now
.tv_usec
>= callback
->when
.tv_usec
))
739 || (now
.tv_sec
> callback
->when
.tv_sec
)))
741 if(callback
->callback
!= NULL
)
743 callback
->callback(callback
->priv
);
744 if (callback
->periodic
)
746 int time_ms
= callback
->time_ms
;
747 callback
->when
.tv_usec
= now
.tv_usec
+ (time_ms
% 1000) * 1000;
748 time_ms
-= (time_ms
% 1000);
749 callback
->when
.tv_sec
= now
.tv_sec
+ time_ms
/ 1000;
750 if (callback
->when
.tv_usec
> 1000000)
752 callback
->when
.tv_usec
= callback
->when
.tv_usec
- 1000000;
753 callback
->when
.tv_sec
+= 1;
759 if((retval
= target_unregister_timer_callback(callback
->callback
, callback
->priv
)) != ERROR_OK
)
765 callback
= next_callback
;
771 int target_call_timer_callbacks(void)
773 return target_call_timer_callbacks_check_time(1);
776 /* invoke periodic callbacks immediately */
777 int target_call_timer_callbacks_now(void)
779 return target_call_timer_callbacks_check_time(0);
782 int target_alloc_working_area(struct target_s
*target
, u32 size
, working_area_t
**area
)
784 working_area_t
*c
= target
->working_areas
;
785 working_area_t
*new_wa
= NULL
;
787 /* Reevaluate working area address based on MMU state*/
788 if (target
->working_areas
== NULL
)
792 retval
= target
->type
->mmu(target
, &enabled
);
793 if (retval
!= ERROR_OK
)
799 target
->working_area
= target
->working_area_virt
;
803 target
->working_area
= target
->working_area_phys
;
807 /* only allocate multiples of 4 byte */
810 LOG_ERROR("BUG: code tried to allocate unaligned number of bytes, padding");
811 size
= CEIL(size
, 4);
814 /* see if there's already a matching working area */
817 if ((c
->free
) && (c
->size
== size
))
825 /* if not, allocate a new one */
828 working_area_t
**p
= &target
->working_areas
;
829 u32 first_free
= target
->working_area
;
830 u32 free_size
= target
->working_area_size
;
832 LOG_DEBUG("allocating new working area");
834 c
= target
->working_areas
;
837 first_free
+= c
->size
;
838 free_size
-= c
->size
;
843 if (free_size
< size
)
845 LOG_WARNING("not enough working area available(requested %d, free %d)", size
, free_size
);
846 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
849 new_wa
= malloc(sizeof(working_area_t
));
852 new_wa
->address
= first_free
;
854 if (target
->backup_working_area
)
857 new_wa
->backup
= malloc(new_wa
->size
);
858 if((retval
= target
->type
->read_memory(target
, new_wa
->address
, 4, new_wa
->size
/ 4, new_wa
->backup
)) != ERROR_OK
)
860 free(new_wa
->backup
);
867 new_wa
->backup
= NULL
;
870 /* put new entry in list */
874 /* mark as used, and return the new (reused) area */
884 int target_free_working_area_restore(struct target_s
*target
, working_area_t
*area
, int restore
)
889 if (restore
&&target
->backup_working_area
)
892 if((retval
= target
->type
->write_memory(target
, area
->address
, 4, area
->size
/ 4, area
->backup
)) != ERROR_OK
)
898 /* mark user pointer invalid */
905 int target_free_working_area(struct target_s
*target
, working_area_t
*area
)
907 return target_free_working_area_restore(target
, area
, 1);
910 /* free resources and restore memory, if restoring memory fails,
911 * free up resources anyway
913 void target_free_all_working_areas_restore(struct target_s
*target
, int restore
)
915 working_area_t
*c
= target
->working_areas
;
919 working_area_t
*next
= c
->next
;
920 target_free_working_area_restore(target
, c
, restore
);
930 target
->working_areas
= NULL
;
933 void target_free_all_working_areas(struct target_s
*target
)
935 target_free_all_working_areas_restore(target
, 1);
938 int target_register_commands(struct command_context_s
*cmd_ctx
)
941 register_command(cmd_ctx
, NULL
, "targets", handle_targets_command
, COMMAND_EXEC
, NULL
);
942 register_command(cmd_ctx
, NULL
, "working_area", handle_working_area_command
, COMMAND_ANY
, "working_area <target#> <address> <size> <'backup'|'nobackup'> [virtual address]");
943 register_command(cmd_ctx
, NULL
, "virt2phys", handle_virt2phys_command
, COMMAND_ANY
, "virt2phys <virtual address>");
944 register_command(cmd_ctx
, NULL
, "profile", handle_profile_command
, COMMAND_EXEC
, "PRELIMINARY! - profile <seconds> <gmon.out>");
946 register_jim(cmd_ctx
, "target", jim_target
, "configure target" );
949 /* script procedures */
950 register_jim(cmd_ctx
, "ocd_mem2array", jim_mem2array
, "read memory and return as a TCL array for script processing");
951 register_jim(cmd_ctx
, "ocd_array2mem", jim_array2mem
, "convert a TCL array to memory locations and write the values");
955 int target_arch_state(struct target_s
*target
)
960 LOG_USER("No target has been configured");
964 LOG_USER("target state: %s",
965 Jim_Nvp_value2name_simple(nvp_target_state
,target
->state
)->name
);
967 if (target
->state
!=TARGET_HALTED
)
970 retval
=target
->type
->arch_state(target
);
974 /* Single aligned words are guaranteed to use 16 or 32 bit access
975 * mode respectively, otherwise data is handled as quickly as
978 int target_write_buffer(struct target_s
*target
, u32 address
, u32 size
, u8
*buffer
)
981 LOG_DEBUG("writing buffer of %i byte at 0x%8.8x", size
, address
);
983 if (!target
->type
->examined
)
985 LOG_ERROR("Target not examined yet");
989 if ((address
+ size
- 1) < address
)
991 /* GDB can request this when e.g. PC is 0xfffffffc*/
992 LOG_ERROR("address+size wrapped(0x%08x, 0x%08x)", address
, size
);
996 if (((address
% 2) == 0) && (size
== 2))
998 return target
->type
->write_memory(target
, address
, 2, 1, buffer
);
1001 /* handle unaligned head bytes */
1004 int unaligned
= 4 - (address
% 4);
1006 if (unaligned
> size
)
1009 if ((retval
= target
->type
->write_memory(target
, address
, 1, unaligned
, buffer
)) != ERROR_OK
)
1012 buffer
+= unaligned
;
1013 address
+= unaligned
;
1017 /* handle aligned words */
1020 int aligned
= size
- (size
% 4);
1022 /* use bulk writes above a certain limit. This may have to be changed */
1025 if ((retval
= target
->type
->bulk_write_memory(target
, address
, aligned
/ 4, buffer
)) != ERROR_OK
)
1030 if ((retval
= target
->type
->write_memory(target
, address
, 4, aligned
/ 4, buffer
)) != ERROR_OK
)
1039 /* handle tail writes of less than 4 bytes */
1042 if ((retval
= target
->type
->write_memory(target
, address
, 1, size
, buffer
)) != ERROR_OK
)
1050 /* Single aligned words are guaranteed to use 16 or 32 bit access
1051 * mode respectively, otherwise data is handled as quickly as
1054 int target_read_buffer(struct target_s
*target
, u32 address
, u32 size
, u8
*buffer
)
1057 LOG_DEBUG("reading buffer of %i byte at 0x%8.8x", size
, address
);
1059 if (!target
->type
->examined
)
1061 LOG_ERROR("Target not examined yet");
1065 if ((address
+ size
- 1) < address
)
1067 /* GDB can request this when e.g. PC is 0xfffffffc*/
1068 LOG_ERROR("address+size wrapped(0x%08x, 0x%08x)", address
, size
);
1072 if (((address
% 2) == 0) && (size
== 2))
1074 return target
->type
->read_memory(target
, address
, 2, 1, buffer
);
1077 /* handle unaligned head bytes */
1080 int unaligned
= 4 - (address
% 4);
1082 if (unaligned
> size
)
1085 if ((retval
= target
->type
->read_memory(target
, address
, 1, unaligned
, buffer
)) != ERROR_OK
)
1088 buffer
+= unaligned
;
1089 address
+= unaligned
;
1093 /* handle aligned words */
1096 int aligned
= size
- (size
% 4);
1098 if ((retval
= target
->type
->read_memory(target
, address
, 4, aligned
/ 4, buffer
)) != ERROR_OK
)
1106 /* handle tail writes of less than 4 bytes */
1109 if ((retval
= target
->type
->read_memory(target
, address
, 1, size
, buffer
)) != ERROR_OK
)
1116 int target_checksum_memory(struct target_s
*target
, u32 address
, u32 size
, u32
* crc
)
1122 if (!target
->type
->examined
)
1124 LOG_ERROR("Target not examined yet");
1128 if ((retval
= target
->type
->checksum_memory(target
, address
,
1129 size
, &checksum
)) != ERROR_OK
)
1131 buffer
= malloc(size
);
1134 LOG_ERROR("error allocating buffer for section (%d bytes)", size
);
1135 return ERROR_INVALID_ARGUMENTS
;
1137 retval
= target_read_buffer(target
, address
, size
, buffer
);
1138 if (retval
!= ERROR_OK
)
1144 /* convert to target endianess */
1145 for (i
= 0; i
< (size
/sizeof(u32
)); i
++)
1148 target_data
= target_buffer_get_u32(target
, &buffer
[i
*sizeof(u32
)]);
1149 target_buffer_set_u32(target
, &buffer
[i
*sizeof(u32
)], target_data
);
1152 retval
= image_calculate_checksum( buffer
, size
, &checksum
);
1161 int target_blank_check_memory(struct target_s
*target
, u32 address
, u32 size
, u32
* blank
)
1164 if (!target
->type
->examined
)
1166 LOG_ERROR("Target not examined yet");
1170 if (target
->type
->blank_check_memory
== 0)
1171 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1173 retval
= target
->type
->blank_check_memory(target
, address
, size
, blank
);
1178 int target_read_u32(struct target_s
*target
, u32 address
, u32
*value
)
1181 if (!target
->type
->examined
)
1183 LOG_ERROR("Target not examined yet");
1187 int retval
= target
->type
->read_memory(target
, address
, 4, 1, value_buf
);
1189 if (retval
== ERROR_OK
)
1191 *value
= target_buffer_get_u32(target
, value_buf
);
1192 LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address
, *value
);
1197 LOG_DEBUG("address: 0x%8.8x failed", address
);
1203 int target_read_u16(struct target_s
*target
, u32 address
, u16
*value
)
1206 if (!target
->type
->examined
)
1208 LOG_ERROR("Target not examined yet");
1212 int retval
= target
->type
->read_memory(target
, address
, 2, 1, value_buf
);
1214 if (retval
== ERROR_OK
)
1216 *value
= target_buffer_get_u16(target
, value_buf
);
1217 LOG_DEBUG("address: 0x%8.8x, value: 0x%4.4x", address
, *value
);
1222 LOG_DEBUG("address: 0x%8.8x failed", address
);
1228 int target_read_u8(struct target_s
*target
, u32 address
, u8
*value
)
1230 int retval
= target
->type
->read_memory(target
, address
, 1, 1, value
);
1231 if (!target
->type
->examined
)
1233 LOG_ERROR("Target not examined yet");
1237 if (retval
== ERROR_OK
)
1239 LOG_DEBUG("address: 0x%8.8x, value: 0x%2.2x", address
, *value
);
1244 LOG_DEBUG("address: 0x%8.8x failed", address
);
1250 int target_write_u32(struct target_s
*target
, u32 address
, u32 value
)
1254 if (!target
->type
->examined
)
1256 LOG_ERROR("Target not examined yet");
1260 LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address
, value
);
1262 target_buffer_set_u32(target
, value_buf
, value
);
1263 if ((retval
= target
->type
->write_memory(target
, address
, 4, 1, value_buf
)) != ERROR_OK
)
1265 LOG_DEBUG("failed: %i", retval
);
1271 int target_write_u16(struct target_s
*target
, u32 address
, u16 value
)
1275 if (!target
->type
->examined
)
1277 LOG_ERROR("Target not examined yet");
1281 LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address
, value
);
1283 target_buffer_set_u16(target
, value_buf
, value
);
1284 if ((retval
= target
->type
->write_memory(target
, address
, 2, 1, value_buf
)) != ERROR_OK
)
1286 LOG_DEBUG("failed: %i", retval
);
1292 int target_write_u8(struct target_s
*target
, u32 address
, u8 value
)
1295 if (!target
->type
->examined
)
1297 LOG_ERROR("Target not examined yet");
1301 LOG_DEBUG("address: 0x%8.8x, value: 0x%2.2x", address
, value
);
1303 if ((retval
= target
->type
->write_memory(target
, address
, 1, 1, &value
)) != ERROR_OK
)
1305 LOG_DEBUG("failed: %i", retval
);
1311 int target_register_user_commands(struct command_context_s
*cmd_ctx
)
1313 int retval
= ERROR_OK
;
1314 register_command(cmd_ctx
, NULL
, "reg", handle_reg_command
, COMMAND_EXEC
, NULL
);
1315 register_command(cmd_ctx
, NULL
, "poll", handle_poll_command
, COMMAND_EXEC
, "poll target state");
1316 register_command(cmd_ctx
, NULL
, "wait_halt", handle_wait_halt_command
, COMMAND_EXEC
, "wait for target halt [time (s)]");
1317 register_command(cmd_ctx
, NULL
, "halt", handle_halt_command
, COMMAND_EXEC
, "halt target");
1318 register_command(cmd_ctx
, NULL
, "resume", handle_resume_command
, COMMAND_EXEC
, "resume target [addr]");
1319 register_command(cmd_ctx
, NULL
, "step", handle_step_command
, COMMAND_EXEC
, "step one instruction from current PC or [addr]");
1320 register_command(cmd_ctx
, NULL
, "reset", handle_reset_command
, COMMAND_EXEC
, "reset target [run|halt|init] - default is run");
1321 register_command(cmd_ctx
, NULL
, "soft_reset_halt", handle_soft_reset_halt_command
, COMMAND_EXEC
, "halt the target and do a soft reset");
1323 register_command(cmd_ctx
, NULL
, "mdw", handle_md_command
, COMMAND_EXEC
, "display memory words <addr> [count]");
1324 register_command(cmd_ctx
, NULL
, "mdh", handle_md_command
, COMMAND_EXEC
, "display memory half-words <addr> [count]");
1325 register_command(cmd_ctx
, NULL
, "mdb", handle_md_command
, COMMAND_EXEC
, "display memory bytes <addr> [count]");
1327 register_command(cmd_ctx
, NULL
, "mww", handle_mw_command
, COMMAND_EXEC
, "write memory word <addr> <value> [count]");
1328 register_command(cmd_ctx
, NULL
, "mwh", handle_mw_command
, COMMAND_EXEC
, "write memory half-word <addr> <value> [count]");
1329 register_command(cmd_ctx
, NULL
, "mwb", handle_mw_command
, COMMAND_EXEC
, "write memory byte <addr> <value> [count]");
1331 register_command(cmd_ctx
, NULL
, "bp", handle_bp_command
, COMMAND_EXEC
, "set breakpoint <address> <length> [hw]");
1332 register_command(cmd_ctx
, NULL
, "rbp", handle_rbp_command
, COMMAND_EXEC
, "remove breakpoint <adress>");
1333 register_command(cmd_ctx
, NULL
, "wp", handle_wp_command
, COMMAND_EXEC
, "set watchpoint <address> <length> <r/w/a> [value] [mask]");
1334 register_command(cmd_ctx
, NULL
, "rwp", handle_rwp_command
, COMMAND_EXEC
, "remove watchpoint <adress>");
1336 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]");
1337 register_command(cmd_ctx
, NULL
, "dump_image", handle_dump_image_command
, COMMAND_EXEC
, "dump_image <file> <address> <size>");
1338 register_command(cmd_ctx
, NULL
, "verify_image", handle_verify_image_command
, COMMAND_EXEC
, "verify_image <file> [offset] [type]");
1340 if((retval
= target_request_register_commands(cmd_ctx
)) != ERROR_OK
)
1342 if((retval
= trace_register_commands(cmd_ctx
)) != ERROR_OK
)
1349 int handle_targets_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1352 target_t
*target
= all_targets
;
1356 /* try as tcltarget name */
1357 for( target
= all_targets
; target
; target
++ ){
1358 if( target
->cmd_name
){
1359 if( 0 == strcmp( args
[0], target
->cmd_name
) ){
1365 /* no match, try as number */
1367 int num
= strtoul(args
[0], &cp
, 0 );
1369 /* then it was not a number */
1370 command_print( cmd_ctx
, "Target: %s unknown, try one of:\n", args
[0] );
1374 target
= get_target_by_num( num
);
1375 if( target
== NULL
){
1376 command_print(cmd_ctx
,"Target: %s is unknown, try one of:\n", args
[0] );
1380 cmd_ctx
->current_target
= target
->target_number
;
1385 command_print(cmd_ctx
, " CmdName Type Endian ChainPos State ");
1386 command_print(cmd_ctx
, "-- ---------- ---------- ---------- -------- ----------");
1389 /* XX: abcdefghij abcdefghij abcdefghij abcdefghij */
1390 command_print(cmd_ctx
, "%2d: %-10s %-10s %-10s %8d %s",
1391 target
->target_number
,
1394 Jim_Nvp_value2name_simple( nvp_target_endian
, target
->endianness
)->name
,
1395 target
->chain_position
,
1396 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
1397 target
= target
->next
;
1405 int handle_working_area_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1407 int retval
= ERROR_OK
;
1408 target_t
*target
= NULL
;
1410 if ((argc
< 4) || (argc
> 5))
1412 return ERROR_COMMAND_SYNTAX_ERROR
;
1415 target
= get_target_by_num(strtoul(args
[0], NULL
, 0));
1418 return ERROR_COMMAND_SYNTAX_ERROR
;
1420 target_free_all_working_areas(target
);
1422 target
->working_area_phys
= target
->working_area_virt
= strtoul(args
[1], NULL
, 0);
1425 target
->working_area_virt
= strtoul(args
[4], NULL
, 0);
1427 target
->working_area_size
= strtoul(args
[2], NULL
, 0);
1429 if (strcmp(args
[3], "backup") == 0)
1431 target
->backup_working_area
= 1;
1433 else if (strcmp(args
[3], "nobackup") == 0)
1435 target
->backup_working_area
= 0;
1439 LOG_ERROR("unrecognized <backup|nobackup> argument (%s)", args
[3]);
1440 return ERROR_COMMAND_SYNTAX_ERROR
;
1447 /* process target state changes */
1448 int handle_target(void *priv
)
1450 int retval
= ERROR_OK
;
1451 target_t
*target
= all_targets
;
1455 if (target_continous_poll
)
1457 /* polling may fail silently until the target has been examined */
1458 if((retval
= target_poll(target
)) != ERROR_OK
)
1462 target
= target
->next
;
1468 int handle_reg_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1477 target
= get_current_target(cmd_ctx
);
1479 /* list all available registers for the current target */
1482 reg_cache_t
*cache
= target
->reg_cache
;
1488 for (i
= 0; i
< cache
->num_regs
; i
++)
1490 value
= buf_to_str(cache
->reg_list
[i
].value
, cache
->reg_list
[i
].size
, 16);
1491 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
);
1494 cache
= cache
->next
;
1500 /* access a single register by its ordinal number */
1501 if ((args
[0][0] >= '0') && (args
[0][0] <= '9'))
1503 int num
= strtoul(args
[0], NULL
, 0);
1504 reg_cache_t
*cache
= target
->reg_cache
;
1510 for (i
= 0; i
< cache
->num_regs
; i
++)
1514 reg
= &cache
->reg_list
[i
];
1520 cache
= cache
->next
;
1525 command_print(cmd_ctx
, "%i is out of bounds, the current target has only %i registers (0 - %i)", num
, count
, count
- 1);
1528 } else /* access a single register by its name */
1530 reg
= register_get_by_name(target
->reg_cache
, args
[0], 1);
1534 command_print(cmd_ctx
, "register %s not found in current target", args
[0]);
1539 /* display a register */
1540 if ((argc
== 1) || ((argc
== 2) && !((args
[1][0] >= '0') && (args
[1][0] <= '9'))))
1542 if ((argc
== 2) && (strcmp(args
[1], "force") == 0))
1545 if (reg
->valid
== 0)
1547 reg_arch_type_t
*arch_type
= register_get_arch_type(reg
->arch_type
);
1548 arch_type
->get(reg
);
1550 value
= buf_to_str(reg
->value
, reg
->size
, 16);
1551 command_print(cmd_ctx
, "%s (/%i): 0x%s", reg
->name
, reg
->size
, value
);
1556 /* set register value */
1559 u8
*buf
= malloc(CEIL(reg
->size
, 8));
1560 str_to_buf(args
[1], strlen(args
[1]), buf
, reg
->size
, 0);
1562 reg_arch_type_t
*arch_type
= register_get_arch_type(reg
->arch_type
);
1563 arch_type
->set(reg
, buf
);
1565 value
= buf_to_str(reg
->value
, reg
->size
, 16);
1566 command_print(cmd_ctx
, "%s (/%i): 0x%s", reg
->name
, reg
->size
, value
);
1574 command_print(cmd_ctx
, "usage: reg <#|name> [value]");
1580 int handle_poll_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1582 int retval
= ERROR_OK
;
1583 target_t
*target
= get_current_target(cmd_ctx
);
1587 if((retval
= target_poll(target
)) != ERROR_OK
)
1589 if((retval
= target_arch_state(target
)) != ERROR_OK
)
1595 if (strcmp(args
[0], "on") == 0)
1597 target_continous_poll
= 1;
1599 else if (strcmp(args
[0], "off") == 0)
1601 target_continous_poll
= 0;
1605 command_print(cmd_ctx
, "arg is \"on\" or \"off\"");
1609 return ERROR_COMMAND_SYNTAX_ERROR
;
1616 int handle_wait_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1624 ms
= strtoul(args
[0], &end
, 0) * 1000;
1627 command_print(cmd_ctx
, "usage: %s [seconds]", cmd
);
1631 target_t
*target
= get_current_target(cmd_ctx
);
1633 return target_wait_state(target
, TARGET_HALTED
, ms
);
1636 int target_wait_state(target_t
*target
, enum target_state state
, int ms
)
1639 struct timeval timeout
, now
;
1641 gettimeofday(&timeout
, NULL
);
1642 timeval_add_time(&timeout
, 0, ms
* 1000);
1646 if ((retval
=target_poll(target
))!=ERROR_OK
)
1649 if (target
->state
== state
)
1656 LOG_DEBUG("waiting for target %s...",
1657 Jim_Nvp_value2name_simple(nvp_target_state
,state
)->name
);
1660 gettimeofday(&now
, NULL
);
1661 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
) && (now
.tv_usec
>= timeout
.tv_usec
)))
1663 LOG_ERROR("timed out while waiting for target %s",
1664 Jim_Nvp_value2name_simple(nvp_target_state
,state
)->name
);
1672 int handle_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1675 target_t
*target
= get_current_target(cmd_ctx
);
1679 if ((retval
= target_halt(target
)) != ERROR_OK
)
1684 return handle_wait_halt_command(cmd_ctx
, cmd
, args
, argc
);
1687 int handle_soft_reset_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1689 target_t
*target
= get_current_target(cmd_ctx
);
1691 LOG_USER("requesting target halt and executing a soft reset");
1693 target
->type
->soft_reset_halt(target
);
1698 int handle_reset_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1701 enum target_reset_mode reset_mode
= RESET_RUN
;
1705 n
= Jim_Nvp_name2value_simple( nvp_reset_modes
, args
[0] );
1706 if( (n
->name
== NULL
) || (n
->value
== RESET_UNKNOWN
) ){
1707 return ERROR_COMMAND_SYNTAX_ERROR
;
1709 reset_mode
= n
->value
;
1712 /* reset *all* targets */
1713 return target_process_reset(cmd_ctx
, reset_mode
);
1717 int handle_resume_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1720 target_t
*target
= get_current_target(cmd_ctx
);
1722 target_handle_event( target
, TARGET_EVENT_OLD_pre_resume
);
1725 retval
= target_resume(target
, 1, 0, 1, 0); /* current pc, addr = 0, handle breakpoints, not debugging */
1727 retval
= target_resume(target
, 0, strtoul(args
[0], NULL
, 0), 1, 0); /* addr = args[0], handle breakpoints, not debugging */
1730 retval
= ERROR_COMMAND_SYNTAX_ERROR
;
1736 int handle_step_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1738 target_t
*target
= get_current_target(cmd_ctx
);
1743 target
->type
->step(target
, 1, 0, 1); /* current pc, addr = 0, handle breakpoints */
1746 target
->type
->step(target
, 0, strtoul(args
[0], NULL
, 0), 1); /* addr = args[0], handle breakpoints */
1751 int handle_md_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1753 const int line_bytecnt
= 32;
1766 target_t
*target
= get_current_target(cmd_ctx
);
1772 count
= strtoul(args
[1], NULL
, 0);
1774 address
= strtoul(args
[0], NULL
, 0);
1780 size
= 4; line_modulo
= line_bytecnt
/ 4;
1783 size
= 2; line_modulo
= line_bytecnt
/ 2;
1786 size
= 1; line_modulo
= line_bytecnt
/ 1;
1792 buffer
= calloc(count
, size
);
1793 retval
= target
->type
->read_memory(target
, address
, size
, count
, buffer
);
1794 if (retval
== ERROR_OK
)
1798 for (i
= 0; i
< count
; i
++)
1800 if (i
%line_modulo
== 0)
1801 output_len
+= snprintf(output
+ output_len
, 128 - output_len
, "0x%8.8x: ", address
+ (i
*size
));
1806 output_len
+= snprintf(output
+ output_len
, 128 - output_len
, "%8.8x ", target_buffer_get_u32(target
, &buffer
[i
*4]));
1809 output_len
+= snprintf(output
+ output_len
, 128 - output_len
, "%4.4x ", target_buffer_get_u16(target
, &buffer
[i
*2]));
1812 output_len
+= snprintf(output
+ output_len
, 128 - output_len
, "%2.2x ", buffer
[i
*1]);
1816 if ((i
%line_modulo
== line_modulo
-1) || (i
== count
- 1))
1818 command_print(cmd_ctx
, output
);
1829 int handle_mw_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1836 target_t
*target
= get_current_target(cmd_ctx
);
1839 if ((argc
< 2) || (argc
> 3))
1840 return ERROR_COMMAND_SYNTAX_ERROR
;
1842 address
= strtoul(args
[0], NULL
, 0);
1843 value
= strtoul(args
[1], NULL
, 0);
1845 count
= strtoul(args
[2], NULL
, 0);
1851 target_buffer_set_u32(target
, value_buf
, value
);
1855 target_buffer_set_u16(target
, value_buf
, value
);
1859 value_buf
[0] = value
;
1862 return ERROR_COMMAND_SYNTAX_ERROR
;
1864 for (i
=0; i
<count
; i
++)
1870 retval
= target
->type
->write_memory(target
, address
+ i
*wordsize
, 4, 1, value_buf
);
1873 retval
= target
->type
->write_memory(target
, address
+ i
*wordsize
, 2, 1, value_buf
);
1876 retval
= target
->type
->write_memory(target
, address
+ i
*wordsize
, 1, 1, value_buf
);
1883 if (retval
!=ERROR_OK
)
1893 int handle_load_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1899 u32 max_address
=0xffffffff;
1901 int retval
, retvaltemp
;
1905 duration_t duration
;
1906 char *duration_text
;
1908 target_t
*target
= get_current_target(cmd_ctx
);
1910 if ((argc
< 1)||(argc
> 5))
1912 return ERROR_COMMAND_SYNTAX_ERROR
;
1915 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
1918 image
.base_address_set
= 1;
1919 image
.base_address
= strtoul(args
[1], NULL
, 0);
1923 image
.base_address_set
= 0;
1927 image
.start_address_set
= 0;
1931 min_address
=strtoul(args
[3], NULL
, 0);
1935 max_address
=strtoul(args
[4], NULL
, 0)+min_address
;
1938 if (min_address
>max_address
)
1940 return ERROR_COMMAND_SYNTAX_ERROR
;
1944 duration_start_measure(&duration
);
1946 if (image_open(&image
, args
[0], (argc
>= 3) ? args
[2] : NULL
) != ERROR_OK
)
1953 for (i
= 0; i
< image
.num_sections
; i
++)
1955 buffer
= malloc(image
.sections
[i
].size
);
1958 command_print(cmd_ctx
, "error allocating buffer for section (%d bytes)", image
.sections
[i
].size
);
1962 if ((retval
= image_read_section(&image
, i
, 0x0, image
.sections
[i
].size
, buffer
, &buf_cnt
)) != ERROR_OK
)
1972 /* DANGER!!! beware of unsigned comparision here!!! */
1974 if ((image
.sections
[i
].base_address
+buf_cnt
>=min_address
)&&
1975 (image
.sections
[i
].base_address
<max_address
))
1977 if (image
.sections
[i
].base_address
<min_address
)
1979 /* clip addresses below */
1980 offset
+=min_address
-image
.sections
[i
].base_address
;
1984 if (image
.sections
[i
].base_address
+buf_cnt
>max_address
)
1986 length
-=(image
.sections
[i
].base_address
+buf_cnt
)-max_address
;
1989 if ((retval
= target_write_buffer(target
, image
.sections
[i
].base_address
+offset
, length
, buffer
+offset
)) != ERROR_OK
)
1994 image_size
+= length
;
1995 command_print(cmd_ctx
, "%u byte written at address 0x%8.8x", length
, image
.sections
[i
].base_address
+offset
);
2001 if((retvaltemp
= duration_stop_measure(&duration
, &duration_text
)) != ERROR_OK
)
2003 image_close(&image
);
2007 if (retval
==ERROR_OK
)
2009 command_print(cmd_ctx
, "downloaded %u byte in %s", image_size
, duration_text
);
2011 free(duration_text
);
2013 image_close(&image
);
2019 int handle_dump_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2026 int retval
=ERROR_OK
, retvaltemp
;
2028 duration_t duration
;
2029 char *duration_text
;
2031 target_t
*target
= get_current_target(cmd_ctx
);
2035 command_print(cmd_ctx
, "usage: dump_image <filename> <address> <size>");
2039 address
= strtoul(args
[1], NULL
, 0);
2040 size
= strtoul(args
[2], NULL
, 0);
2042 if ((address
& 3) || (size
& 3))
2044 command_print(cmd_ctx
, "only 32-bit aligned address and size are supported");
2048 if (fileio_open(&fileio
, args
[0], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
)
2053 duration_start_measure(&duration
);
2058 u32 this_run_size
= (size
> 560) ? 560 : size
;
2060 retval
= target
->type
->read_memory(target
, address
, 4, this_run_size
/ 4, buffer
);
2061 if (retval
!= ERROR_OK
)
2066 retval
= fileio_write(&fileio
, this_run_size
, buffer
, &size_written
);
2067 if (retval
!= ERROR_OK
)
2072 size
-= this_run_size
;
2073 address
+= this_run_size
;
2076 if((retvaltemp
= fileio_close(&fileio
)) != ERROR_OK
)
2079 if((retvaltemp
= duration_stop_measure(&duration
, &duration_text
)) != ERROR_OK
)
2082 if (retval
==ERROR_OK
)
2084 command_print(cmd_ctx
, "dumped %"PRIi64
" byte in %s", fileio
.size
, duration_text
);
2086 free(duration_text
);
2091 int handle_verify_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2097 int retval
, retvaltemp
;
2099 u32 mem_checksum
= 0;
2103 duration_t duration
;
2104 char *duration_text
;
2106 target_t
*target
= get_current_target(cmd_ctx
);
2110 return ERROR_COMMAND_SYNTAX_ERROR
;
2115 LOG_ERROR("no target selected");
2119 duration_start_measure(&duration
);
2123 image
.base_address_set
= 1;
2124 image
.base_address
= strtoul(args
[1], NULL
, 0);
2128 image
.base_address_set
= 0;
2129 image
.base_address
= 0x0;
2132 image
.start_address_set
= 0;
2134 if ((retval
=image_open(&image
, args
[0], (argc
== 3) ? args
[2] : NULL
)) != ERROR_OK
)
2141 for (i
= 0; i
< image
.num_sections
; i
++)
2143 buffer
= malloc(image
.sections
[i
].size
);
2146 command_print(cmd_ctx
, "error allocating buffer for section (%d bytes)", image
.sections
[i
].size
);
2149 if ((retval
= image_read_section(&image
, i
, 0x0, image
.sections
[i
].size
, buffer
, &buf_cnt
)) != ERROR_OK
)
2155 /* calculate checksum of image */
2156 image_calculate_checksum( buffer
, buf_cnt
, &checksum
);
2158 retval
= target_checksum_memory(target
, image
.sections
[i
].base_address
, buf_cnt
, &mem_checksum
);
2159 if( retval
!= ERROR_OK
)
2165 if( checksum
!= mem_checksum
)
2167 /* failed crc checksum, fall back to a binary compare */
2170 command_print(cmd_ctx
, "checksum mismatch - attempting binary compare");
2172 data
= (u8
*)malloc(buf_cnt
);
2174 /* Can we use 32bit word accesses? */
2176 int count
= buf_cnt
;
2177 if ((count
% 4) == 0)
2182 retval
= target
->type
->read_memory(target
, image
.sections
[i
].base_address
, size
, count
, data
);
2183 if (retval
== ERROR_OK
)
2186 for (t
= 0; t
< buf_cnt
; t
++)
2188 if (data
[t
] != buffer
[t
])
2190 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
]);
2207 image_size
+= buf_cnt
;
2211 if((retvaltemp
= duration_stop_measure(&duration
, &duration_text
)) != ERROR_OK
)
2213 image_close(&image
);
2217 if (retval
==ERROR_OK
)
2219 command_print(cmd_ctx
, "verified %u bytes in %s", image_size
, duration_text
);
2221 free(duration_text
);
2223 image_close(&image
);
2228 int handle_bp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2231 target_t
*target
= get_current_target(cmd_ctx
);
2235 breakpoint_t
*breakpoint
= target
->breakpoints
;
2239 if (breakpoint
->type
== BKPT_SOFT
)
2241 char* buf
= buf_to_str(breakpoint
->orig_instr
, breakpoint
->length
, 16);
2242 command_print(cmd_ctx
, "0x%8.8x, 0x%x, %i, 0x%s", breakpoint
->address
, breakpoint
->length
, breakpoint
->set
, buf
);
2247 command_print(cmd_ctx
, "0x%8.8x, 0x%x, %i", breakpoint
->address
, breakpoint
->length
, breakpoint
->set
);
2249 breakpoint
= breakpoint
->next
;
2257 length
= strtoul(args
[1], NULL
, 0);
2260 if (strcmp(args
[2], "hw") == 0)
2263 if ((retval
= breakpoint_add(target
, strtoul(args
[0], NULL
, 0), length
, hw
)) != ERROR_OK
)
2265 LOG_ERROR("Failure setting breakpoints");
2269 command_print(cmd_ctx
, "breakpoint added at address 0x%8.8x", strtoul(args
[0], NULL
, 0));
2274 command_print(cmd_ctx
, "usage: bp <address> <length> ['hw']");
2280 int handle_rbp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2282 target_t
*target
= get_current_target(cmd_ctx
);
2285 breakpoint_remove(target
, strtoul(args
[0], NULL
, 0));
2290 int handle_wp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2292 target_t
*target
= get_current_target(cmd_ctx
);
2297 watchpoint_t
*watchpoint
= target
->watchpoints
;
2301 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
);
2302 watchpoint
= watchpoint
->next
;
2307 enum watchpoint_rw type
= WPT_ACCESS
;
2308 u32 data_value
= 0x0;
2309 u32 data_mask
= 0xffffffff;
2325 command_print(cmd_ctx
, "usage: wp <address> <length> [r/w/a] [value] [mask]");
2331 data_value
= strtoul(args
[3], NULL
, 0);
2335 data_mask
= strtoul(args
[4], NULL
, 0);
2338 if ((retval
= watchpoint_add(target
, strtoul(args
[0], NULL
, 0),
2339 strtoul(args
[1], NULL
, 0), type
, data_value
, data_mask
)) != ERROR_OK
)
2341 LOG_ERROR("Failure setting breakpoints");
2346 command_print(cmd_ctx
, "usage: wp <address> <length> [r/w/a] [value] [mask]");
2352 int handle_rwp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2354 target_t
*target
= get_current_target(cmd_ctx
);
2357 watchpoint_remove(target
, strtoul(args
[0], NULL
, 0));
2362 int handle_virt2phys_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2365 target_t
*target
= get_current_target(cmd_ctx
);
2371 return ERROR_COMMAND_SYNTAX_ERROR
;
2373 va
= strtoul(args
[0], NULL
, 0);
2375 retval
= target
->type
->virt2phys(target
, va
, &pa
);
2376 if (retval
== ERROR_OK
)
2378 command_print(cmd_ctx
, "Physical address 0x%08x", pa
);
2382 /* lower levels will have logged a detailed error which is
2383 * forwarded to telnet/GDB session.
2388 static void writeLong(FILE *f
, int l
)
2393 char c
=(l
>>(i
*8))&0xff;
2394 fwrite(&c
, 1, 1, f
);
2398 static void writeString(FILE *f
, char *s
)
2400 fwrite(s
, 1, strlen(s
), f
);
2405 // Dump a gmon.out histogram file.
2406 static void writeGmon(u32
*samples
, int sampleNum
, char *filename
)
2409 FILE *f
=fopen(filename
, "w");
2412 fwrite("gmon", 1, 4, f
);
2413 writeLong(f
, 0x00000001); // Version
2414 writeLong(f
, 0); // padding
2415 writeLong(f
, 0); // padding
2416 writeLong(f
, 0); // padding
2418 fwrite("", 1, 1, f
); // GMON_TAG_TIME_HIST
2420 // figure out bucket size
2423 for (i
=0; i
<sampleNum
; i
++)
2435 int addressSpace
=(max
-min
+1);
2437 static int const maxBuckets
=256*1024; // maximum buckets.
2438 int length
=addressSpace
;
2439 if (length
> maxBuckets
)
2443 int *buckets
=malloc(sizeof(int)*length
);
2449 memset(buckets
, 0, sizeof(int)*length
);
2450 for (i
=0; i
<sampleNum
;i
++)
2452 u32 address
=samples
[i
];
2453 long long a
=address
-min
;
2454 long long b
=length
-1;
2455 long long c
=addressSpace
-1;
2456 int index
=(a
*b
)/c
; // danger!!!! int32 overflows
2460 // append binary memory gmon.out &profile_hist_hdr ((char*)&profile_hist_hdr + sizeof(struct gmon_hist_hdr))
2461 writeLong(f
, min
); // low_pc
2462 writeLong(f
, max
); // high_pc
2463 writeLong(f
, length
); // # of samples
2464 writeLong(f
, 64000000); // 64MHz
2465 writeString(f
, "seconds");
2466 for (i
=0; i
<(15-strlen("seconds")); i
++)
2468 fwrite("", 1, 1, f
); // padding
2470 writeString(f
, "s");
2472 // append binary memory gmon.out profile_hist_data (profile_hist_data + profile_hist_hdr.hist_size)
2474 char *data
=malloc(2*length
);
2477 for (i
=0; i
<length
;i
++)
2486 data
[i
*2+1]=(val
>>8)&0xff;
2489 fwrite(data
, 1, length
*2, f
);
2499 /* profiling samples the CPU PC as quickly as OpenOCD is able, which will be used as a random sampling of PC */
2500 int handle_profile_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2502 target_t
*target
= get_current_target(cmd_ctx
);
2503 struct timeval timeout
, now
;
2505 gettimeofday(&timeout
, NULL
);
2508 return ERROR_COMMAND_SYNTAX_ERROR
;
2511 timeval_add_time(&timeout
, strtoul(args
[0], &end
, 0), 0);
2517 command_print(cmd_ctx
, "Starting profiling. Halting and resuming the target as often as we can...");
2519 static const int maxSample
=10000;
2520 u32
*samples
=malloc(sizeof(u32
)*maxSample
);
2525 int retval
=ERROR_OK
;
2526 // hopefully it is safe to cache! We want to stop/restart as quickly as possible.
2527 reg_t
*reg
= register_get_by_name(target
->reg_cache
, "pc", 1);
2531 target_poll(target
);
2532 if (target
->state
== TARGET_HALTED
)
2534 u32 t
=*((u32
*)reg
->value
);
2535 samples
[numSamples
++]=t
;
2536 retval
= target_resume(target
, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */
2537 target_poll(target
);
2538 alive_sleep(10); // sleep 10ms, i.e. <100 samples/second.
2539 } else if (target
->state
== TARGET_RUNNING
)
2541 // We want to quickly sample the PC.
2542 if((retval
= target_halt(target
)) != ERROR_OK
)
2549 command_print(cmd_ctx
, "Target not halted or running");
2553 if (retval
!=ERROR_OK
)
2558 gettimeofday(&now
, NULL
);
2559 if ((numSamples
>=maxSample
) || ((now
.tv_sec
>= timeout
.tv_sec
) && (now
.tv_usec
>= timeout
.tv_usec
)))
2561 command_print(cmd_ctx
, "Profiling completed. %d samples.", numSamples
);
2562 if((retval
= target_poll(target
)) != ERROR_OK
)
2567 if (target
->state
== TARGET_HALTED
)
2569 target_resume(target
, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */
2571 if((retval
= target_poll(target
)) != ERROR_OK
)
2576 writeGmon(samples
, numSamples
, args
[1]);
2577 command_print(cmd_ctx
, "Wrote %s", args
[1]);
2586 static int new_int_array_element(Jim_Interp
* interp
, const char *varname
, int idx
, u32 val
)
2589 Jim_Obj
*nameObjPtr
, *valObjPtr
;
2592 namebuf
= alloc_printf("%s(%d)", varname
, idx
);
2596 nameObjPtr
= Jim_NewStringObj(interp
, namebuf
, -1);
2597 valObjPtr
= Jim_NewIntObj(interp
, val
);
2598 if (!nameObjPtr
|| !valObjPtr
)
2604 Jim_IncrRefCount(nameObjPtr
);
2605 Jim_IncrRefCount(valObjPtr
);
2606 result
= Jim_SetVariable(interp
, nameObjPtr
, valObjPtr
);
2607 Jim_DecrRefCount(interp
, nameObjPtr
);
2608 Jim_DecrRefCount(interp
, valObjPtr
);
2610 /* printf("%s(%d) <= 0%08x\n", varname, idx, val); */
2614 static int jim_mem2array(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
2616 command_context_t
*context
;
2619 context
= Jim_GetAssocData(interp
, "context");
2620 if (context
== NULL
)
2622 LOG_ERROR("mem2array: no command context");
2625 target
= get_current_target(context
);
2628 LOG_ERROR("mem2array: no current target");
2632 return target_mem2array(interp
, target
, argc
,argv
);
2635 static int target_mem2array(Jim_Interp
*interp
, target_t
*target
, int argc
, Jim_Obj
*const *argv
)
2643 const char *varname
;
2645 int i
, n
, e
, retval
;
2647 /* argv[1] = name of array to receive the data
2648 * argv[2] = desired width
2649 * argv[3] = memory address
2650 * argv[4] = count of times to read
2653 Jim_WrongNumArgs(interp
, 1, argv
, "varname width addr nelems");
2656 varname
= Jim_GetString(argv
[1], &len
);
2657 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
2659 e
= Jim_GetLong(interp
, argv
[2], &l
);
2665 e
= Jim_GetLong(interp
, argv
[3], &l
);
2670 e
= Jim_GetLong(interp
, argv
[4], &l
);
2686 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2687 Jim_AppendStrings( interp
, Jim_GetResult(interp
), "Invalid width param, must be 8/16/32", NULL
);
2691 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2692 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: zero width read?", NULL
);
2695 if ((addr
+ (len
* width
)) < addr
) {
2696 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2697 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: addr + len - wraps to zero?", NULL
);
2700 /* absurd transfer size? */
2702 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2703 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: absurd > 64K item request", NULL
);
2708 ((width
== 2) && ((addr
& 1) == 0)) ||
2709 ((width
== 4) && ((addr
& 3) == 0))) {
2713 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2714 sprintf(buf
, "mem2array address: 0x%08x is not aligned for %d byte reads", addr
, width
);
2715 Jim_AppendStrings(interp
, Jim_GetResult(interp
), buf
, NULL
);
2726 /* Slurp... in buffer size chunks */
2728 count
= len
; /* in objects.. */
2729 if (count
> (sizeof(buffer
)/width
)) {
2730 count
= (sizeof(buffer
)/width
);
2733 retval
= target
->type
->read_memory( target
, addr
, width
, count
, buffer
);
2734 if (retval
!= ERROR_OK
) {
2736 LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed", addr
, width
, count
);
2737 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2738 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: cannot read memory", NULL
);
2742 v
= 0; /* shut up gcc */
2743 for (i
= 0 ;i
< count
;i
++, n
++) {
2746 v
= target_buffer_get_u32(target
, &buffer
[i
*width
]);
2749 v
= target_buffer_get_u16(target
, &buffer
[i
*width
]);
2752 v
= buffer
[i
] & 0x0ff;
2755 new_int_array_element(interp
, varname
, n
, v
);
2761 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2766 static int get_int_array_element(Jim_Interp
* interp
, const char *varname
, int idx
, u32
*val
)
2769 Jim_Obj
*nameObjPtr
, *valObjPtr
;
2773 namebuf
= alloc_printf("%s(%d)", varname
, idx
);
2777 nameObjPtr
= Jim_NewStringObj(interp
, namebuf
, -1);
2784 Jim_IncrRefCount(nameObjPtr
);
2785 valObjPtr
= Jim_GetVariable(interp
, nameObjPtr
, JIM_ERRMSG
);
2786 Jim_DecrRefCount(interp
, nameObjPtr
);
2788 if (valObjPtr
== NULL
)
2791 result
= Jim_GetLong(interp
, valObjPtr
, &l
);
2792 /* printf("%s(%d) => 0%08x\n", varname, idx, val); */
2797 static int jim_array2mem(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
2799 command_context_t
*context
;
2802 context
= Jim_GetAssocData(interp
, "context");
2803 if (context
== NULL
){
2804 LOG_ERROR("array2mem: no command context");
2807 target
= get_current_target(context
);
2808 if (target
== NULL
){
2809 LOG_ERROR("array2mem: no current target");
2813 return target_array2mem( interp
,target
, argc
, argv
);
2817 static int target_array2mem(Jim_Interp
*interp
, target_t
*target
, int argc
, Jim_Obj
*const *argv
)
2825 const char *varname
;
2827 int i
, n
, e
, retval
;
2829 /* argv[1] = name of array to get the data
2830 * argv[2] = desired width
2831 * argv[3] = memory address
2832 * argv[4] = count to write
2835 Jim_WrongNumArgs(interp
, 1, argv
, "varname width addr nelems");
2838 varname
= Jim_GetString(argv
[1], &len
);
2839 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
2841 e
= Jim_GetLong(interp
, argv
[2], &l
);
2847 e
= Jim_GetLong(interp
, argv
[3], &l
);
2852 e
= Jim_GetLong(interp
, argv
[4], &l
);
2868 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2869 Jim_AppendStrings( interp
, Jim_GetResult(interp
), "Invalid width param, must be 8/16/32", NULL
);
2873 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2874 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: zero width read?", NULL
);
2877 if ((addr
+ (len
* width
)) < addr
) {
2878 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2879 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: addr + len - wraps to zero?", NULL
);
2882 /* absurd transfer size? */
2884 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2885 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: absurd > 64K item request", NULL
);
2890 ((width
== 2) && ((addr
& 1) == 0)) ||
2891 ((width
== 4) && ((addr
& 3) == 0))) {
2895 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2896 sprintf(buf
, "array2mem address: 0x%08x is not aligned for %d byte reads", addr
, width
);
2897 Jim_AppendStrings(interp
, Jim_GetResult(interp
), buf
, NULL
);
2909 /* Slurp... in buffer size chunks */
2911 count
= len
; /* in objects.. */
2912 if (count
> (sizeof(buffer
)/width
)) {
2913 count
= (sizeof(buffer
)/width
);
2916 v
= 0; /* shut up gcc */
2917 for (i
= 0 ;i
< count
;i
++, n
++) {
2918 get_int_array_element(interp
, varname
, n
, &v
);
2921 target_buffer_set_u32(target
, &buffer
[i
*width
], v
);
2924 target_buffer_set_u16(target
, &buffer
[i
*width
], v
);
2927 buffer
[i
] = v
& 0x0ff;
2933 retval
= target
->type
->write_memory(target
, addr
, width
, count
, buffer
);
2934 if (retval
!= ERROR_OK
) {
2936 LOG_ERROR("array2mem: Write @ 0x%08x, w=%d, cnt=%d, failed", addr
, width
, count
);
2937 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2938 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: cannot read memory", NULL
);
2944 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2950 target_all_handle_event( enum target_event e
)
2955 LOG_DEBUG( "**all*targets: event: %d, %s",
2957 Jim_Nvp_value2name_simple( nvp_target_event
, e
)->name
);
2959 target
= all_targets
;
2961 target_handle_event( target
, e
);
2962 target
= target
->next
;
2967 target_handle_event( target_t
*target
, enum target_event e
)
2969 target_event_action_t
*teap
;
2972 teap
= target
->event_action
;
2976 if( teap
->event
== e
){
2978 LOG_DEBUG( "target: (%d) %s (%s) event: %d (%s) action: %s\n",
2979 target
->target_number
,
2983 Jim_Nvp_value2name_simple( nvp_target_event
, e
)->name
,
2984 Jim_GetString( teap
->body
, NULL
) );
2985 if (Jim_EvalObj( interp
, teap
->body
)!=JIM_OK
)
2987 Jim_PrintErrorMessage(interp
);
2993 LOG_DEBUG( "event: %d %s - no action",
2995 Jim_Nvp_value2name_simple( nvp_target_event
, e
)->name
);
2999 enum target_cfg_param
{
3002 TCFG_WORK_AREA_VIRT
,
3003 TCFG_WORK_AREA_PHYS
,
3004 TCFG_WORK_AREA_SIZE
,
3005 TCFG_WORK_AREA_BACKUP
,
3008 TCFG_CHAIN_POSITION
,
3012 static Jim_Nvp nvp_config_opts
[] = {
3013 { .name
= "-type", .value
= TCFG_TYPE
},
3014 { .name
= "-event", .value
= TCFG_EVENT
},
3015 { .name
= "-work-area-virt", .value
= TCFG_WORK_AREA_VIRT
},
3016 { .name
= "-work-area-phys", .value
= TCFG_WORK_AREA_PHYS
},
3017 { .name
= "-work-area-size", .value
= TCFG_WORK_AREA_SIZE
},
3018 { .name
= "-work-area-backup", .value
= TCFG_WORK_AREA_BACKUP
},
3019 { .name
= "-endian" , .value
= TCFG_ENDIAN
},
3020 { .name
= "-variant", .value
= TCFG_VARIANT
},
3021 { .name
= "-chain-position", .value
= TCFG_CHAIN_POSITION
},
3023 { .name
= NULL
, .value
= -1 }
3028 target_configure( Jim_GetOptInfo
*goi
,
3038 /* parse config or cget options ... */
3039 while( goi
->argc
> 0 ){
3040 Jim_SetEmptyResult( goi
->interp
);
3041 //Jim_GetOpt_Debug( goi );
3043 if( target
->type
->target_jim_configure
){
3044 /* target defines a configure function */
3045 /* target gets first dibs on parameters */
3046 e
= (*(target
->type
->target_jim_configure
))( target
, goi
);
3055 /* otherwise we 'continue' below */
3057 e
= Jim_GetOpt_Nvp( goi
, nvp_config_opts
, &n
);
3059 Jim_GetOpt_NvpUnknown( goi
, nvp_config_opts
, 0 );
3065 if( goi
->isconfigure
){
3066 Jim_SetResult_sprintf( goi
->interp
, "not setable: %s", n
->name
);
3070 if( goi
->argc
!= 0 ){
3071 Jim_WrongNumArgs( goi
->interp
, goi
->argc
, goi
->argv
, "NO PARAMS");
3075 Jim_SetResultString( goi
->interp
, target
->type
->name
, -1 );
3079 if( goi
->argc
== 0 ){
3080 Jim_WrongNumArgs( goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name? ...");
3084 e
= Jim_GetOpt_Nvp( goi
, nvp_target_event
, &n
);
3086 Jim_GetOpt_NvpUnknown( goi
, nvp_target_event
, 1 );
3090 if( goi
->isconfigure
){
3091 if( goi
->argc
!= 1 ){
3092 Jim_WrongNumArgs( goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name? ?EVENT-BODY?");
3096 if( goi
->argc
!= 0 ){
3097 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name?");
3104 target_event_action_t
*teap
;
3106 teap
= target
->event_action
;
3107 /* replace existing? */
3109 if( teap
->event
== n
->value
){
3115 if( goi
->isconfigure
){
3118 teap
= calloc( 1, sizeof(*teap
) );
3120 teap
->event
= n
->value
;
3121 Jim_GetOpt_Obj( goi
, &o
);
3123 Jim_DecrRefCount( interp
, teap
->body
);
3125 teap
->body
= Jim_DuplicateObj( goi
->interp
, o
);
3128 * Tcl/TK - "tk events" have a nice feature.
3129 * See the "BIND" command.
3130 * We should support that here.
3131 * You can specify %X and %Y in the event code.
3132 * The idea is: %T - target name.
3133 * The idea is: %N - target number
3134 * The idea is: %E - event name.
3136 Jim_IncrRefCount( teap
->body
);
3138 /* add to head of event list */
3139 teap
->next
= target
->event_action
;
3140 target
->event_action
= teap
;
3141 Jim_SetEmptyResult(goi
->interp
);
3145 Jim_SetEmptyResult( goi
->interp
);
3147 Jim_SetResult( goi
->interp
, Jim_DuplicateObj( goi
->interp
, teap
->body
) );
3154 case TCFG_WORK_AREA_VIRT
:
3155 if( goi
->isconfigure
){
3156 target_free_all_working_areas(target
);
3157 e
= Jim_GetOpt_Wide( goi
, &w
);
3161 target
->working_area_virt
= w
;
3163 if( goi
->argc
!= 0 ){
3167 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_virt
) );
3171 case TCFG_WORK_AREA_PHYS
:
3172 if( goi
->isconfigure
){
3173 target_free_all_working_areas(target
);
3174 e
= Jim_GetOpt_Wide( goi
, &w
);
3178 target
->working_area_phys
= w
;
3180 if( goi
->argc
!= 0 ){
3184 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_phys
) );
3188 case TCFG_WORK_AREA_SIZE
:
3189 if( goi
->isconfigure
){
3190 target_free_all_working_areas(target
);
3191 e
= Jim_GetOpt_Wide( goi
, &w
);
3195 target
->working_area_size
= w
;
3197 if( goi
->argc
!= 0 ){
3201 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_size
) );
3205 case TCFG_WORK_AREA_BACKUP
:
3206 if( goi
->isconfigure
){
3207 target_free_all_working_areas(target
);
3208 e
= Jim_GetOpt_Wide( goi
, &w
);
3212 /* make this exactly 1 or 0 */
3213 target
->backup_working_area
= (!!w
);
3215 if( goi
->argc
!= 0 ){
3219 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_size
) );
3220 /* loop for more e*/
3224 if( goi
->isconfigure
){
3225 e
= Jim_GetOpt_Nvp( goi
, nvp_target_endian
, &n
);
3227 Jim_GetOpt_NvpUnknown( goi
, nvp_target_endian
, 1 );
3230 target
->endianness
= n
->value
;
3232 if( goi
->argc
!= 0 ){
3236 n
= Jim_Nvp_value2name_simple( nvp_target_endian
, target
->endianness
);
3237 if( n
->name
== NULL
){
3238 target
->endianness
= TARGET_LITTLE_ENDIAN
;
3239 n
= Jim_Nvp_value2name_simple( nvp_target_endian
, target
->endianness
);
3241 Jim_SetResultString( goi
->interp
, n
->name
, -1 );
3246 if( goi
->isconfigure
){
3247 if( goi
->argc
< 1 ){
3248 Jim_SetResult_sprintf( goi
->interp
,
3253 if( target
->variant
){
3254 free((void *)(target
->variant
));
3256 e
= Jim_GetOpt_String( goi
, &cp
, NULL
);
3257 target
->variant
= strdup(cp
);
3259 if( goi
->argc
!= 0 ){
3263 Jim_SetResultString( goi
->interp
, target
->variant
,-1 );
3266 case TCFG_CHAIN_POSITION
:
3267 if( goi
->isconfigure
){
3268 target_free_all_working_areas(target
);
3269 e
= Jim_GetOpt_Wide( goi
, &w
);
3273 /* make this exactly 1 or 0 */
3274 target
->chain_position
= w
;
3276 if( goi
->argc
!= 0 ){
3280 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->chain_position
) );
3281 /* loop for more e*/
3284 } /* while( goi->argc ) */
3285 /* done - we return */
3290 /** this is the 'tcl' handler for the target specific command */
3292 tcl_target_func( Jim_Interp
*interp
,
3294 Jim_Obj
*const *argv
)
3302 struct command_context_s
*cmd_ctx
;
3310 TS_CMD_MWW
, TS_CMD_MWH
, TS_CMD_MWB
,
3311 TS_CMD_MDW
, TS_CMD_MDH
, TS_CMD_MDB
,
3312 TS_CMD_MRW
, TS_CMD_MRH
, TS_CMD_MRB
,
3313 TS_CMD_MEM2ARRAY
, TS_CMD_ARRAY2MEM
,
3321 TS_CMD_INVOKE_EVENT
,
3324 static const Jim_Nvp target_options
[] = {
3325 { .name
= "configure", .value
= TS_CMD_CONFIGURE
},
3326 { .name
= "cget", .value
= TS_CMD_CGET
},
3327 { .name
= "mww", .value
= TS_CMD_MWW
},
3328 { .name
= "mwh", .value
= TS_CMD_MWH
},
3329 { .name
= "mwb", .value
= TS_CMD_MWB
},
3330 { .name
= "mdw", .value
= TS_CMD_MDW
},
3331 { .name
= "mdh", .value
= TS_CMD_MDH
},
3332 { .name
= "mdb", .value
= TS_CMD_MDB
},
3333 { .name
= "mem2array", .value
= TS_CMD_MEM2ARRAY
},
3334 { .name
= "array2mem", .value
= TS_CMD_ARRAY2MEM
},
3335 { .name
= "eventlist", .value
= TS_CMD_EVENTLIST
},
3336 { .name
= "curstate", .value
= TS_CMD_CURSTATE
},
3338 { .name
= "arp_examine", .value
= TS_CMD_EXAMINE
},
3339 { .name
= "arp_poll", .value
= TS_CMD_POLL
},
3340 { .name
= "arp_reset", .value
= TS_CMD_RESET
},
3341 { .name
= "arp_halt", .value
= TS_CMD_HALT
},
3342 { .name
= "arp_waitstate", .value
= TS_CMD_WAITSTATE
},
3343 { .name
= "invoke-event", .value
= TS_CMD_INVOKE_EVENT
},
3345 { .name
= NULL
, .value
= -1 },
3349 /* go past the "command" */
3350 Jim_GetOpt_Setup( &goi
, interp
, argc
-1, argv
+1 );
3352 target
= Jim_CmdPrivData( goi
.interp
);
3353 cmd_ctx
= Jim_GetAssocData(goi
.interp
, "context");
3355 /* commands here are in an NVP table */
3356 e
= Jim_GetOpt_Nvp( &goi
, target_options
, &n
);
3358 Jim_GetOpt_NvpUnknown( &goi
, target_options
, 0 );
3361 // Assume blank result
3362 Jim_SetEmptyResult( goi
.interp
);
3365 case TS_CMD_CONFIGURE
:
3367 Jim_WrongNumArgs( goi
.interp
, goi
.argc
, goi
.argv
, "missing: -option VALUE ...");
3370 goi
.isconfigure
= 1;
3371 return target_configure( &goi
, target
);
3373 // some things take params
3375 Jim_WrongNumArgs( goi
.interp
, 0, goi
.argv
, "missing: ?-option?");
3378 goi
.isconfigure
= 0;
3379 return target_configure( &goi
, target
);
3387 * argv[3] = optional count.
3390 if( (goi
.argc
== 3) || (goi
.argc
== 4) ){
3394 Jim_SetResult_sprintf( goi
.interp
, "expected: %s ADDR DATA [COUNT]", n
->name
);
3398 e
= Jim_GetOpt_Wide( &goi
, &a
);
3403 e
= Jim_GetOpt_Wide( &goi
, &b
);
3408 e
= Jim_GetOpt_Wide( &goi
, &c
);
3418 target_buffer_set_u32( target
, target_buf
, b
);
3422 target_buffer_set_u16( target
, target_buf
, b
);
3426 target_buffer_set_u8( target
, target_buf
, b
);
3430 for( x
= 0 ; x
< c
; x
++ ){
3431 e
= target
->type
->write_memory( target
, a
, b
, 1, target_buf
);
3432 if( e
!= ERROR_OK
){
3433 Jim_SetResult_sprintf( interp
, "Error writing @ 0x%08x: %d\n", (int)(a
), e
);
3446 /* argv[0] = command
3448 * argv[2] = optional count
3450 if( (goi
.argc
== 2) || (goi
.argc
== 3) ){
3451 Jim_SetResult_sprintf( goi
.interp
, "expected: %s ADDR [COUNT]", n
->name
);
3454 e
= Jim_GetOpt_Wide( &goi
, &a
);
3459 e
= Jim_GetOpt_Wide( &goi
, &c
);
3466 b
= 1; /* shut up gcc */
3479 /* convert to "bytes" */
3481 /* count is now in 'BYTES' */
3487 e
= target
->type
->read_memory( target
, a
, b
, y
/ b
, target_buf
);
3488 if( e
!= ERROR_OK
){
3489 Jim_SetResult_sprintf( interp
, "error reading target @ 0x%08lx", (int)(a
) );
3493 Jim_fprintf( interp
, interp
->cookie_stdout
, "0x%08x ", (int)(a
) );
3496 for( x
= 0 ; (x
< 16) && (x
< y
) ; x
+= 4 ){
3497 z
= target_buffer_get_u32( target
, &(target_buf
[ x
* 4 ]) );
3498 Jim_fprintf( interp
, interp
->cookie_stdout
, "%08x ", (int)(z
) );
3500 for( ; (x
< 16) ; x
+= 4 ){
3501 Jim_fprintf( interp
, interp
->cookie_stdout
, " " );
3505 for( x
= 0 ; (x
< 16) && (x
< y
) ; x
+= 2 ){
3506 z
= target_buffer_get_u16( target
, &(target_buf
[ x
* 2 ]) );
3507 Jim_fprintf( interp
, interp
->cookie_stdout
, "%04x ", (int)(z
) );
3509 for( ; (x
< 16) ; x
+= 2 ){
3510 Jim_fprintf( interp
, interp
->cookie_stdout
, " " );
3515 for( x
= 0 ; (x
< 16) && (x
< y
) ; x
+= 1 ){
3516 z
= target_buffer_get_u8( target
, &(target_buf
[ x
* 4 ]) );
3517 Jim_fprintf( interp
, interp
->cookie_stdout
, "%02x ", (int)(z
) );
3519 for( ; (x
< 16) ; x
+= 1 ){
3520 Jim_fprintf( interp
, interp
->cookie_stdout
, " " );
3524 /* ascii-ify the bytes */
3525 for( x
= 0 ; x
< y
; x
++ ){
3526 if( (target_buf
[x
] >= 0x20) &&
3527 (target_buf
[x
] <= 0x7e) ){
3531 target_buf
[x
] = '.';
3536 target_buf
[x
] = ' ';
3541 /* print - with a newline */
3542 Jim_fprintf( interp
, interp
->cookie_stdout
, "%s\n", target_buf
);
3548 case TS_CMD_MEM2ARRAY
:
3549 return target_mem2array( goi
.interp
, target
, goi
.argc
, goi
.argv
);
3551 case TS_CMD_ARRAY2MEM
:
3552 return target_array2mem( goi
.interp
, target
, goi
.argc
, goi
.argv
);
3554 case TS_CMD_EXAMINE
:
3556 Jim_WrongNumArgs( goi
.interp
, 2, argv
, "[no parameters]");
3559 e
= target
->type
->examine( target
);
3560 if( e
!= ERROR_OK
){
3561 Jim_SetResult_sprintf( interp
, "examine-fails: %d", e
);
3567 Jim_WrongNumArgs( goi
.interp
, 2, argv
, "[no parameters]");
3570 if( !(target
->type
->examined
) ){
3571 e
= ERROR_TARGET_NOT_EXAMINED
;
3573 e
= target
->type
->poll( target
);
3575 if( e
!= ERROR_OK
){
3576 Jim_SetResult_sprintf( interp
, "poll-fails: %d", e
);
3583 if( goi
.argc
!= 2 ){
3584 Jim_WrongNumArgs( interp
, 2, argv
, "t|f|assert|deassert BOOL");
3587 e
= Jim_GetOpt_Nvp( &goi
, nvp_assert
, &n
);
3589 Jim_GetOpt_NvpUnknown( &goi
, nvp_assert
, 1 );
3592 // the halt or not param
3593 e
= Jim_GetOpt_Wide( &goi
, &a
);
3597 // determine if we should halt or not.
3598 target
->reset_halt
= !!a
;
3599 // When this happens - all workareas are invalid.
3600 target_free_all_working_areas_restore(target
, 0);
3603 if( n
->value
== NVP_ASSERT
){
3604 target
->type
->assert_reset( target
);
3606 target
->type
->deassert_reset( target
);
3611 Jim_WrongNumArgs( goi
.interp
, 0, argv
, "halt [no parameters]");
3614 target
->type
->halt( target
);
3616 case TS_CMD_WAITSTATE
:
3617 // params: <name> statename timeoutmsecs
3618 if( goi
.argc
!= 2 ){
3619 Jim_SetResult_sprintf( goi
.interp
, "%s STATENAME TIMEOUTMSECS", n
->name
);
3622 e
= Jim_GetOpt_Nvp( &goi
, nvp_target_state
, &n
);
3624 Jim_GetOpt_NvpUnknown( &goi
, nvp_target_state
,1 );
3627 e
= Jim_GetOpt_Wide( &goi
, &a
);
3631 e
= target_wait_state( target
, n
->value
, a
);
3632 if( e
!= ERROR_OK
){
3633 Jim_SetResult_sprintf( goi
.interp
,
3634 "target: %s wait %s fails (%d) %s",
3637 e
, target_strerror_safe(e
) );
3642 case TS_CMD_EVENTLIST
:
3643 /* List for human, Events defined for this target.
3644 * scripts/programs should use 'name cget -event NAME'
3647 target_event_action_t
*teap
;
3648 teap
= target
->event_action
;
3649 command_print( cmd_ctx
, "Event actions for target (%d) %s\n",
3650 target
->target_number
,
3652 command_print( cmd_ctx
, "%-25s | Body", "Event");
3653 command_print( cmd_ctx
, "------------------------- | ----------------------------------------");
3655 command_print( cmd_ctx
,
3657 Jim_Nvp_value2name_simple( nvp_target_event
, teap
->event
)->name
,
3658 Jim_GetString( teap
->body
, NULL
) );
3661 command_print( cmd_ctx
, "***END***");
3664 case TS_CMD_CURSTATE
:
3665 if( goi
.argc
!= 0 ){
3666 Jim_WrongNumArgs( goi
.interp
, 0, argv
, "[no parameters]");
3669 Jim_SetResultString( goi
.interp
,
3670 Jim_Nvp_value2name_simple(nvp_target_state
,target
->state
)->name
,-1);
3672 case TS_CMD_INVOKE_EVENT
:
3673 if( goi
.argc
!= 1 ){
3674 Jim_SetResult_sprintf( goi
.interp
, "%s ?EVENTNAME?",n
->name
);
3677 e
= Jim_GetOpt_Nvp( &goi
, nvp_target_event
, &n
);
3679 Jim_GetOpt_NvpUnknown( &goi
, nvp_target_event
, 1 );
3682 target_handle_event( target
, n
->value
);
3690 target_create( Jim_GetOptInfo
*goi
)
3700 struct command_context_s
*cmd_ctx
;
3702 cmd_ctx
= Jim_GetAssocData(goi
->interp
, "context");
3703 if( goi
->argc
< 3 ){
3704 Jim_WrongNumArgs( goi
->interp
, 1, goi
->argv
, "?name? ?type? ..options...");
3709 Jim_GetOpt_Obj( goi
, &new_cmd
);
3710 /* does this command exist? */
3711 cmd
= Jim_GetCommand( goi
->interp
, new_cmd
, JIM_ERRMSG
);
3713 cp
= Jim_GetString( new_cmd
, NULL
);
3714 Jim_SetResult_sprintf(goi
->interp
, "Command/target: %s Exists", cp
);
3719 e
= Jim_GetOpt_String( goi
, &cp2
, NULL
);
3721 /* now does target type exist */
3722 for( x
= 0 ; target_types
[x
] ; x
++ ){
3723 if( 0 == strcmp( cp
, target_types
[x
]->name
) ){
3728 if( target_types
[x
] == NULL
){
3729 Jim_SetResult_sprintf( goi
->interp
, "Unknown target type %s, try one of ", cp
);
3730 for( x
= 0 ; target_types
[x
] ; x
++ ){
3731 if( target_types
[x
+1] ){
3732 Jim_AppendStrings( goi
->interp
,
3733 Jim_GetResult(goi
->interp
),
3734 target_types
[x
]->name
,
3737 Jim_AppendStrings( goi
->interp
,
3738 Jim_GetResult(goi
->interp
),
3740 target_types
[x
]->name
,NULL
);
3748 target
= calloc(1,sizeof(target_t
));
3749 /* set target number */
3750 target
->target_number
= new_target_number();
3752 /* allocate memory for each unique target type */
3753 target
->type
= (target_type_t
*)calloc(1,sizeof(target_type_t
));
3755 memcpy( target
->type
, target_types
[x
], sizeof(target_type_t
));
3757 /* will be set by "-endian" */
3758 target
->endianness
= TARGET_ENDIAN_UNKNOWN
;
3760 target
->working_area
= 0x0;
3761 target
->working_area_size
= 0x0;
3762 target
->working_areas
= NULL
;
3763 target
->backup_working_area
= 0;
3765 target
->state
= TARGET_UNKNOWN
;
3766 target
->debug_reason
= DBG_REASON_UNDEFINED
;
3767 target
->reg_cache
= NULL
;
3768 target
->breakpoints
= NULL
;
3769 target
->watchpoints
= NULL
;
3770 target
->next
= NULL
;
3771 target
->arch_info
= NULL
;
3773 /* initialize trace information */
3774 target
->trace_info
= malloc(sizeof(trace_t
));
3775 target
->trace_info
->num_trace_points
= 0;
3776 target
->trace_info
->trace_points_size
= 0;
3777 target
->trace_info
->trace_points
= NULL
;
3778 target
->trace_info
->trace_history_size
= 0;
3779 target
->trace_info
->trace_history
= NULL
;
3780 target
->trace_info
->trace_history_pos
= 0;
3781 target
->trace_info
->trace_history_overflowed
= 0;
3783 target
->dbgmsg
= NULL
;
3784 target
->dbg_msg_enabled
= 0;
3786 target
->endianness
= TARGET_ENDIAN_UNKNOWN
;
3788 /* Do the rest as "configure" options */
3789 goi
->isconfigure
= 1;
3790 e
= target_configure( goi
, target
);
3792 free( target
->type
);
3797 if( target
->endianness
== TARGET_ENDIAN_UNKNOWN
){
3798 /* default endian to little if not specified */
3799 target
->endianness
= TARGET_LITTLE_ENDIAN
;
3802 /* create the target specific commands */
3803 if( target
->type
->register_commands
){
3804 (*(target
->type
->register_commands
))( cmd_ctx
);
3806 if( target
->type
->target_create
){
3807 (*(target
->type
->target_create
))( target
, goi
->interp
);
3810 /* append to end of list */
3813 tpp
= &(all_targets
);
3815 tpp
= &( (*tpp
)->next
);
3820 cp
= Jim_GetString( new_cmd
, NULL
);
3821 target
->cmd_name
= strdup(cp
);
3823 /* now - create the new target name command */
3824 e
= Jim_CreateCommand( goi
->interp
,
3827 tcl_target_func
, /* C function */
3828 target
, /* private data */
3829 NULL
); /* no del proc */
3831 (*(target
->type
->target_create
))( target
, goi
->interp
);
3836 jim_target( Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
3840 struct command_context_s
*cmd_ctx
;
3845 /* TG = target generic */
3853 const char *target_cmds
[] = {
3854 "create", "types", "names", "current", "number",
3859 LOG_DEBUG("Target command params:");
3860 LOG_DEBUG(Jim_Debug_ArgvString( interp
, argc
, argv
) );
3862 cmd_ctx
= Jim_GetAssocData( interp
, "context" );
3864 Jim_GetOpt_Setup( &goi
, interp
, argc
-1, argv
+1 );
3866 if( goi
.argc
== 0 ){
3867 Jim_WrongNumArgs(interp
, 1, argv
, "missing: command ...");
3871 /* is this old syntax? */
3872 /* To determine: We have to peek at argv[0]*/
3873 cp
= Jim_GetString( goi
.argv
[0], NULL
);
3874 for( x
= 0 ; target_types
[x
] ; x
++ ){
3875 if( 0 == strcmp(cp
,target_types
[x
]->name
) ){
3879 if( target_types
[x
] ){
3880 /* YES IT IS OLD SYNTAX */
3881 Jim_Obj
*new_argv
[10];
3884 /* target_old_syntax
3886 * argv[0] typename (above)
3888 * argv[2] reset method, deprecated/ignored
3889 * argv[3] = old param
3890 * argv[4] = old param
3892 * We will combine all "old params" into a single param.
3893 * Then later, split them again.
3896 Jim_WrongNumArgs( interp
, 1, argv
, "[OLDSYNTAX] ?TYPE? ?ENDIAN? ?RESET? ?old-params?");
3900 new_argv
[0] = argv
[0];
3901 new_argv
[1] = Jim_NewStringObj( interp
, "create", -1 );
3904 sprintf( buf
, "target%d", new_target_number() );
3905 new_argv
[2] = Jim_NewStringObj( interp
, buf
, -1 );
3907 new_argv
[3] = goi
.argv
[0]; /* typename */
3908 new_argv
[4] = Jim_NewStringObj( interp
, "-endian", -1 );
3909 new_argv
[5] = goi
.argv
[1];
3910 new_argv
[6] = Jim_NewStringObj( interp
, "-chain-position", -1 );
3911 new_argv
[7] = goi
.argv
[2];
3912 new_argv
[8] = Jim_NewStringObj( interp
, "-variant", -1 );
3913 new_argv
[9] = goi
.argv
[3];
3920 * argv[3] = typename
3921 * argv[4] = **FIRST** "configure" option.
3923 * Here, we make them:
3927 * argv[6] = -position
3929 * argv[8] = -variant
3930 * argv[9] = "somestring"
3933 /* don't let these be released */
3934 for( x
= 0 ; x
< new_argc
; x
++ ){
3935 Jim_IncrRefCount( new_argv
[x
]);
3938 LOG_DEBUG("Target OLD SYNTAX - converted to new syntax");
3940 r
= jim_target( goi
.interp
, new_argc
, new_argv
);
3942 /* release? these items */
3943 for( x
= 0 ; x
< new_argc
; x
++ ){
3944 Jim_DecrRefCount( interp
, new_argv
[x
] );
3949 //Jim_GetOpt_Debug( &goi );
3950 r
= Jim_GetOpt_Enum( &goi
, target_cmds
, &x
);
3957 Jim_Panic(goi
.interp
,"Why am I here?");
3959 case TG_CMD_CURRENT
:
3960 if( goi
.argc
!= 0 ){
3961 Jim_WrongNumArgs( goi
.interp
, 1, goi
.argv
, "Too many parameters");
3964 Jim_SetResultString( goi
.interp
, get_current_target( cmd_ctx
)->cmd_name
, -1 );
3967 if( goi
.argc
!= 0 ){
3968 Jim_WrongNumArgs( goi
.interp
, 1, goi
.argv
, "Too many parameters" );
3971 Jim_SetResult( goi
.interp
, Jim_NewListObj( goi
.interp
, NULL
, 0 ) );
3972 for( x
= 0 ; target_types
[x
] ; x
++ ){
3973 Jim_ListAppendElement( goi
.interp
,
3974 Jim_GetResult(goi
.interp
),
3975 Jim_NewStringObj( goi
.interp
, target_types
[x
]->name
, -1 ) );
3979 if( goi
.argc
!= 0 ){
3980 Jim_WrongNumArgs( goi
.interp
, 1, goi
.argv
, "Too many parameters" );
3983 Jim_SetResult( goi
.interp
, Jim_NewListObj( goi
.interp
, NULL
, 0 ) );
3984 target
= all_targets
;
3986 Jim_ListAppendElement( goi
.interp
,
3987 Jim_GetResult(goi
.interp
),
3988 Jim_NewStringObj( goi
.interp
, target
->cmd_name
, -1 ) );
3989 target
= target
->next
;
3994 Jim_WrongNumArgs( goi
.interp
, goi
.argc
, goi
.argv
, "?name ... config options ...");
3997 return target_create( &goi
);
4000 if( goi
.argc
!= 1 ){
4001 Jim_SetResult_sprintf( goi
.interp
, "expected: target number ?NUMBER?");
4004 e
= Jim_GetOpt_Wide( &goi
, &w
);
4010 t
= get_target_by_num(w
);
4012 Jim_SetResult_sprintf( goi
.interp
,"Target: number %d does not exist", (int)(w
));
4015 Jim_SetResultString( goi
.interp
, t
->cmd_name
, -1 );
4019 if( goi
.argc
!= 0 ){
4020 Jim_WrongNumArgs( goi
.interp
, 0, goi
.argv
, "<no parameters>");
4023 Jim_SetResult( goi
.interp
,
4024 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)