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 // every 300ms we check for reset & powerdropout and issue a "reset halt" if
1453 static int powerDropout
;
1454 static int srstAsserted
;
1456 static int sense_handler()
1458 static int prevSrstAsserted
= 0;
1459 static int prevPowerdropout
= 0;
1462 if ((retval
=jtag_power_dropout(&powerDropout
))!=ERROR_OK
)
1466 powerRestored
= prevPowerdropout
&& !powerDropout
;
1469 LOG_USER("Sensed power restore.");
1472 long long current
= timeval_ms();
1473 static long long lastPower
= 0;
1474 int waitMore
= lastPower
+ 2000 > current
;
1475 if (powerDropout
&& !waitMore
)
1477 LOG_USER("Sensed power dropout.");
1478 lastPower
= current
;
1481 if ((retval
=jtag_srst_asserted(&srstAsserted
))!=ERROR_OK
)
1485 srstDeasserted
= prevSrstAsserted
&& !srstAsserted
;
1487 static long long lastSrst
= 0;
1488 waitMore
= lastSrst
+ 2000 > current
;
1489 if (srstDeasserted
&& !waitMore
)
1491 LOG_USER("Sensed nSRST deasserted");
1495 if (!prevSrstAsserted
&& srstAsserted
)
1497 LOG_USER("Sensed nSRST asserted");
1500 prevSrstAsserted
= srstAsserted
;
1501 prevPowerdropout
= powerDropout
;
1503 if (srstDeasserted
|| powerRestored
)
1505 /* Other than logging the event we can't do anything here.
1506 * Issuing a reset is a particularly bad idea as we might
1507 * be inside a reset already.
1515 /* process target state changes */
1516 int handle_target(void *priv
)
1518 int retval
= ERROR_OK
;
1519 target_t
*target
= all_targets
;
1525 /* only poll target if we've got power and srst isn't asserted */
1526 if (target_continous_poll
&&!powerDropout
&&!srstAsserted
)
1528 /* polling may fail silently until the target has been examined */
1529 if((retval
= target_poll(target
)) != ERROR_OK
)
1533 target
= target
->next
;
1539 int handle_reg_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1548 target
= get_current_target(cmd_ctx
);
1550 /* list all available registers for the current target */
1553 reg_cache_t
*cache
= target
->reg_cache
;
1559 for (i
= 0; i
< cache
->num_regs
; i
++)
1561 value
= buf_to_str(cache
->reg_list
[i
].value
, cache
->reg_list
[i
].size
, 16);
1562 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
);
1565 cache
= cache
->next
;
1571 /* access a single register by its ordinal number */
1572 if ((args
[0][0] >= '0') && (args
[0][0] <= '9'))
1574 int num
= strtoul(args
[0], NULL
, 0);
1575 reg_cache_t
*cache
= target
->reg_cache
;
1581 for (i
= 0; i
< cache
->num_regs
; i
++)
1585 reg
= &cache
->reg_list
[i
];
1591 cache
= cache
->next
;
1596 command_print(cmd_ctx
, "%i is out of bounds, the current target has only %i registers (0 - %i)", num
, count
, count
- 1);
1599 } else /* access a single register by its name */
1601 reg
= register_get_by_name(target
->reg_cache
, args
[0], 1);
1605 command_print(cmd_ctx
, "register %s not found in current target", args
[0]);
1610 /* display a register */
1611 if ((argc
== 1) || ((argc
== 2) && !((args
[1][0] >= '0') && (args
[1][0] <= '9'))))
1613 if ((argc
== 2) && (strcmp(args
[1], "force") == 0))
1616 if (reg
->valid
== 0)
1618 reg_arch_type_t
*arch_type
= register_get_arch_type(reg
->arch_type
);
1619 arch_type
->get(reg
);
1621 value
= buf_to_str(reg
->value
, reg
->size
, 16);
1622 command_print(cmd_ctx
, "%s (/%i): 0x%s", reg
->name
, reg
->size
, value
);
1627 /* set register value */
1630 u8
*buf
= malloc(CEIL(reg
->size
, 8));
1631 str_to_buf(args
[1], strlen(args
[1]), buf
, reg
->size
, 0);
1633 reg_arch_type_t
*arch_type
= register_get_arch_type(reg
->arch_type
);
1634 arch_type
->set(reg
, buf
);
1636 value
= buf_to_str(reg
->value
, reg
->size
, 16);
1637 command_print(cmd_ctx
, "%s (/%i): 0x%s", reg
->name
, reg
->size
, value
);
1645 command_print(cmd_ctx
, "usage: reg <#|name> [value]");
1651 int handle_poll_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1653 int retval
= ERROR_OK
;
1654 target_t
*target
= get_current_target(cmd_ctx
);
1658 if((retval
= target_poll(target
)) != ERROR_OK
)
1660 if((retval
= target_arch_state(target
)) != ERROR_OK
)
1666 if (strcmp(args
[0], "on") == 0)
1668 target_continous_poll
= 1;
1670 else if (strcmp(args
[0], "off") == 0)
1672 target_continous_poll
= 0;
1676 command_print(cmd_ctx
, "arg is \"on\" or \"off\"");
1680 return ERROR_COMMAND_SYNTAX_ERROR
;
1687 int handle_wait_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1695 ms
= strtoul(args
[0], &end
, 0) * 1000;
1698 command_print(cmd_ctx
, "usage: %s [seconds]", cmd
);
1702 target_t
*target
= get_current_target(cmd_ctx
);
1704 return target_wait_state(target
, TARGET_HALTED
, ms
);
1707 int target_wait_state(target_t
*target
, enum target_state state
, int ms
)
1710 struct timeval timeout
, now
;
1712 gettimeofday(&timeout
, NULL
);
1713 timeval_add_time(&timeout
, 0, ms
* 1000);
1717 if ((retval
=target_poll(target
))!=ERROR_OK
)
1720 if (target
->state
== state
)
1727 LOG_DEBUG("waiting for target %s...",
1728 Jim_Nvp_value2name_simple(nvp_target_state
,state
)->name
);
1731 gettimeofday(&now
, NULL
);
1732 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
) && (now
.tv_usec
>= timeout
.tv_usec
)))
1734 LOG_ERROR("timed out while waiting for target %s",
1735 Jim_Nvp_value2name_simple(nvp_target_state
,state
)->name
);
1743 int handle_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1746 target_t
*target
= get_current_target(cmd_ctx
);
1750 if ((retval
= target_halt(target
)) != ERROR_OK
)
1755 return handle_wait_halt_command(cmd_ctx
, cmd
, args
, argc
);
1758 int handle_soft_reset_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1760 target_t
*target
= get_current_target(cmd_ctx
);
1762 LOG_USER("requesting target halt and executing a soft reset");
1764 target
->type
->soft_reset_halt(target
);
1769 int handle_reset_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1772 enum target_reset_mode reset_mode
= RESET_RUN
;
1776 n
= Jim_Nvp_name2value_simple( nvp_reset_modes
, args
[0] );
1777 if( (n
->name
== NULL
) || (n
->value
== RESET_UNKNOWN
) ){
1778 return ERROR_COMMAND_SYNTAX_ERROR
;
1780 reset_mode
= n
->value
;
1783 /* reset *all* targets */
1784 return target_process_reset(cmd_ctx
, reset_mode
);
1788 int handle_resume_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1791 target_t
*target
= get_current_target(cmd_ctx
);
1793 target_handle_event( target
, TARGET_EVENT_OLD_pre_resume
);
1796 retval
= target_resume(target
, 1, 0, 1, 0); /* current pc, addr = 0, handle breakpoints, not debugging */
1798 retval
= target_resume(target
, 0, strtoul(args
[0], NULL
, 0), 1, 0); /* addr = args[0], handle breakpoints, not debugging */
1801 retval
= ERROR_COMMAND_SYNTAX_ERROR
;
1807 int handle_step_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1809 target_t
*target
= get_current_target(cmd_ctx
);
1814 return target
->type
->step(target
, 1, 0, 1); /* current pc, addr = 0, handle breakpoints */
1817 return target
->type
->step(target
, 0, strtoul(args
[0], NULL
, 0), 1); /* addr = args[0], handle breakpoints */
1822 int handle_md_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1824 const int line_bytecnt
= 32;
1837 target_t
*target
= get_current_target(cmd_ctx
);
1843 count
= strtoul(args
[1], NULL
, 0);
1845 address
= strtoul(args
[0], NULL
, 0);
1851 size
= 4; line_modulo
= line_bytecnt
/ 4;
1854 size
= 2; line_modulo
= line_bytecnt
/ 2;
1857 size
= 1; line_modulo
= line_bytecnt
/ 1;
1863 buffer
= calloc(count
, size
);
1864 retval
= target
->type
->read_memory(target
, address
, size
, count
, buffer
);
1865 if (retval
== ERROR_OK
)
1869 for (i
= 0; i
< count
; i
++)
1871 if (i
%line_modulo
== 0)
1872 output_len
+= snprintf(output
+ output_len
, 128 - output_len
, "0x%8.8x: ", address
+ (i
*size
));
1877 output_len
+= snprintf(output
+ output_len
, 128 - output_len
, "%8.8x ", target_buffer_get_u32(target
, &buffer
[i
*4]));
1880 output_len
+= snprintf(output
+ output_len
, 128 - output_len
, "%4.4x ", target_buffer_get_u16(target
, &buffer
[i
*2]));
1883 output_len
+= snprintf(output
+ output_len
, 128 - output_len
, "%2.2x ", buffer
[i
*1]);
1887 if ((i
%line_modulo
== line_modulo
-1) || (i
== count
- 1))
1889 command_print(cmd_ctx
, output
);
1900 int handle_mw_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1907 target_t
*target
= get_current_target(cmd_ctx
);
1910 if ((argc
< 2) || (argc
> 3))
1911 return ERROR_COMMAND_SYNTAX_ERROR
;
1913 address
= strtoul(args
[0], NULL
, 0);
1914 value
= strtoul(args
[1], NULL
, 0);
1916 count
= strtoul(args
[2], NULL
, 0);
1922 target_buffer_set_u32(target
, value_buf
, value
);
1926 target_buffer_set_u16(target
, value_buf
, value
);
1930 value_buf
[0] = value
;
1933 return ERROR_COMMAND_SYNTAX_ERROR
;
1935 for (i
=0; i
<count
; i
++)
1941 retval
= target
->type
->write_memory(target
, address
+ i
*wordsize
, 4, 1, value_buf
);
1944 retval
= target
->type
->write_memory(target
, address
+ i
*wordsize
, 2, 1, value_buf
);
1947 retval
= target
->type
->write_memory(target
, address
+ i
*wordsize
, 1, 1, value_buf
);
1954 if (retval
!=ERROR_OK
)
1964 int handle_load_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1970 u32 max_address
=0xffffffff;
1972 int retval
, retvaltemp
;
1976 duration_t duration
;
1977 char *duration_text
;
1979 target_t
*target
= get_current_target(cmd_ctx
);
1981 if ((argc
< 1)||(argc
> 5))
1983 return ERROR_COMMAND_SYNTAX_ERROR
;
1986 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
1989 image
.base_address_set
= 1;
1990 image
.base_address
= strtoul(args
[1], NULL
, 0);
1994 image
.base_address_set
= 0;
1998 image
.start_address_set
= 0;
2002 min_address
=strtoul(args
[3], NULL
, 0);
2006 max_address
=strtoul(args
[4], NULL
, 0)+min_address
;
2009 if (min_address
>max_address
)
2011 return ERROR_COMMAND_SYNTAX_ERROR
;
2015 duration_start_measure(&duration
);
2017 if (image_open(&image
, args
[0], (argc
>= 3) ? args
[2] : NULL
) != ERROR_OK
)
2024 for (i
= 0; i
< image
.num_sections
; i
++)
2026 buffer
= malloc(image
.sections
[i
].size
);
2029 command_print(cmd_ctx
, "error allocating buffer for section (%d bytes)", image
.sections
[i
].size
);
2033 if ((retval
= image_read_section(&image
, i
, 0x0, image
.sections
[i
].size
, buffer
, &buf_cnt
)) != ERROR_OK
)
2043 /* DANGER!!! beware of unsigned comparision here!!! */
2045 if ((image
.sections
[i
].base_address
+buf_cnt
>=min_address
)&&
2046 (image
.sections
[i
].base_address
<max_address
))
2048 if (image
.sections
[i
].base_address
<min_address
)
2050 /* clip addresses below */
2051 offset
+=min_address
-image
.sections
[i
].base_address
;
2055 if (image
.sections
[i
].base_address
+buf_cnt
>max_address
)
2057 length
-=(image
.sections
[i
].base_address
+buf_cnt
)-max_address
;
2060 if ((retval
= target_write_buffer(target
, image
.sections
[i
].base_address
+offset
, length
, buffer
+offset
)) != ERROR_OK
)
2065 image_size
+= length
;
2066 command_print(cmd_ctx
, "%u byte written at address 0x%8.8x", length
, image
.sections
[i
].base_address
+offset
);
2072 if((retvaltemp
= duration_stop_measure(&duration
, &duration_text
)) != ERROR_OK
)
2074 image_close(&image
);
2078 if (retval
==ERROR_OK
)
2080 command_print(cmd_ctx
, "downloaded %u byte in %s", image_size
, duration_text
);
2082 free(duration_text
);
2084 image_close(&image
);
2090 int handle_dump_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2097 int retval
=ERROR_OK
, retvaltemp
;
2099 duration_t duration
;
2100 char *duration_text
;
2102 target_t
*target
= get_current_target(cmd_ctx
);
2106 command_print(cmd_ctx
, "usage: dump_image <filename> <address> <size>");
2110 address
= strtoul(args
[1], NULL
, 0);
2111 size
= strtoul(args
[2], NULL
, 0);
2113 if ((address
& 3) || (size
& 3))
2115 command_print(cmd_ctx
, "only 32-bit aligned address and size are supported");
2119 if (fileio_open(&fileio
, args
[0], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
)
2124 duration_start_measure(&duration
);
2129 u32 this_run_size
= (size
> 560) ? 560 : size
;
2131 retval
= target
->type
->read_memory(target
, address
, 4, this_run_size
/ 4, buffer
);
2132 if (retval
!= ERROR_OK
)
2137 retval
= fileio_write(&fileio
, this_run_size
, buffer
, &size_written
);
2138 if (retval
!= ERROR_OK
)
2143 size
-= this_run_size
;
2144 address
+= this_run_size
;
2147 if((retvaltemp
= fileio_close(&fileio
)) != ERROR_OK
)
2150 if((retvaltemp
= duration_stop_measure(&duration
, &duration_text
)) != ERROR_OK
)
2153 if (retval
==ERROR_OK
)
2155 command_print(cmd_ctx
, "dumped %"PRIi64
" byte in %s", fileio
.size
, duration_text
);
2157 free(duration_text
);
2162 int handle_verify_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2168 int retval
, retvaltemp
;
2170 u32 mem_checksum
= 0;
2174 duration_t duration
;
2175 char *duration_text
;
2177 target_t
*target
= get_current_target(cmd_ctx
);
2181 return ERROR_COMMAND_SYNTAX_ERROR
;
2186 LOG_ERROR("no target selected");
2190 duration_start_measure(&duration
);
2194 image
.base_address_set
= 1;
2195 image
.base_address
= strtoul(args
[1], NULL
, 0);
2199 image
.base_address_set
= 0;
2200 image
.base_address
= 0x0;
2203 image
.start_address_set
= 0;
2205 if ((retval
=image_open(&image
, args
[0], (argc
== 3) ? args
[2] : NULL
)) != ERROR_OK
)
2212 for (i
= 0; i
< image
.num_sections
; i
++)
2214 buffer
= malloc(image
.sections
[i
].size
);
2217 command_print(cmd_ctx
, "error allocating buffer for section (%d bytes)", image
.sections
[i
].size
);
2220 if ((retval
= image_read_section(&image
, i
, 0x0, image
.sections
[i
].size
, buffer
, &buf_cnt
)) != ERROR_OK
)
2226 /* calculate checksum of image */
2227 image_calculate_checksum( buffer
, buf_cnt
, &checksum
);
2229 retval
= target_checksum_memory(target
, image
.sections
[i
].base_address
, buf_cnt
, &mem_checksum
);
2230 if( retval
!= ERROR_OK
)
2236 if( checksum
!= mem_checksum
)
2238 /* failed crc checksum, fall back to a binary compare */
2241 command_print(cmd_ctx
, "checksum mismatch - attempting binary compare");
2243 data
= (u8
*)malloc(buf_cnt
);
2245 /* Can we use 32bit word accesses? */
2247 int count
= buf_cnt
;
2248 if ((count
% 4) == 0)
2253 retval
= target
->type
->read_memory(target
, image
.sections
[i
].base_address
, size
, count
, data
);
2254 if (retval
== ERROR_OK
)
2257 for (t
= 0; t
< buf_cnt
; t
++)
2259 if (data
[t
] != buffer
[t
])
2261 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
]);
2278 image_size
+= buf_cnt
;
2282 if((retvaltemp
= duration_stop_measure(&duration
, &duration_text
)) != ERROR_OK
)
2284 image_close(&image
);
2288 if (retval
==ERROR_OK
)
2290 command_print(cmd_ctx
, "verified %u bytes in %s", image_size
, duration_text
);
2292 free(duration_text
);
2294 image_close(&image
);
2299 int handle_bp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2302 target_t
*target
= get_current_target(cmd_ctx
);
2306 breakpoint_t
*breakpoint
= target
->breakpoints
;
2310 if (breakpoint
->type
== BKPT_SOFT
)
2312 char* buf
= buf_to_str(breakpoint
->orig_instr
, breakpoint
->length
, 16);
2313 command_print(cmd_ctx
, "0x%8.8x, 0x%x, %i, 0x%s", breakpoint
->address
, breakpoint
->length
, breakpoint
->set
, buf
);
2318 command_print(cmd_ctx
, "0x%8.8x, 0x%x, %i", breakpoint
->address
, breakpoint
->length
, breakpoint
->set
);
2320 breakpoint
= breakpoint
->next
;
2328 length
= strtoul(args
[1], NULL
, 0);
2331 if (strcmp(args
[2], "hw") == 0)
2334 if ((retval
= breakpoint_add(target
, strtoul(args
[0], NULL
, 0), length
, hw
)) != ERROR_OK
)
2336 LOG_ERROR("Failure setting breakpoints");
2340 command_print(cmd_ctx
, "breakpoint added at address 0x%8.8x", strtoul(args
[0], NULL
, 0));
2345 command_print(cmd_ctx
, "usage: bp <address> <length> ['hw']");
2351 int handle_rbp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2353 target_t
*target
= get_current_target(cmd_ctx
);
2356 breakpoint_remove(target
, strtoul(args
[0], NULL
, 0));
2361 int handle_wp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2363 target_t
*target
= get_current_target(cmd_ctx
);
2368 watchpoint_t
*watchpoint
= target
->watchpoints
;
2372 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
);
2373 watchpoint
= watchpoint
->next
;
2378 enum watchpoint_rw type
= WPT_ACCESS
;
2379 u32 data_value
= 0x0;
2380 u32 data_mask
= 0xffffffff;
2396 command_print(cmd_ctx
, "usage: wp <address> <length> [r/w/a] [value] [mask]");
2402 data_value
= strtoul(args
[3], NULL
, 0);
2406 data_mask
= strtoul(args
[4], NULL
, 0);
2409 if ((retval
= watchpoint_add(target
, strtoul(args
[0], NULL
, 0),
2410 strtoul(args
[1], NULL
, 0), type
, data_value
, data_mask
)) != ERROR_OK
)
2412 LOG_ERROR("Failure setting breakpoints");
2417 command_print(cmd_ctx
, "usage: wp <address> <length> [r/w/a] [value] [mask]");
2423 int handle_rwp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2425 target_t
*target
= get_current_target(cmd_ctx
);
2428 watchpoint_remove(target
, strtoul(args
[0], NULL
, 0));
2433 int handle_virt2phys_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2436 target_t
*target
= get_current_target(cmd_ctx
);
2442 return ERROR_COMMAND_SYNTAX_ERROR
;
2444 va
= strtoul(args
[0], NULL
, 0);
2446 retval
= target
->type
->virt2phys(target
, va
, &pa
);
2447 if (retval
== ERROR_OK
)
2449 command_print(cmd_ctx
, "Physical address 0x%08x", pa
);
2453 /* lower levels will have logged a detailed error which is
2454 * forwarded to telnet/GDB session.
2459 static void writeLong(FILE *f
, int l
)
2464 char c
=(l
>>(i
*8))&0xff;
2465 fwrite(&c
, 1, 1, f
);
2469 static void writeString(FILE *f
, char *s
)
2471 fwrite(s
, 1, strlen(s
), f
);
2476 // Dump a gmon.out histogram file.
2477 static void writeGmon(u32
*samples
, int sampleNum
, char *filename
)
2480 FILE *f
=fopen(filename
, "w");
2483 fwrite("gmon", 1, 4, f
);
2484 writeLong(f
, 0x00000001); // Version
2485 writeLong(f
, 0); // padding
2486 writeLong(f
, 0); // padding
2487 writeLong(f
, 0); // padding
2489 fwrite("", 1, 1, f
); // GMON_TAG_TIME_HIST
2491 // figure out bucket size
2494 for (i
=0; i
<sampleNum
; i
++)
2506 int addressSpace
=(max
-min
+1);
2508 static int const maxBuckets
=256*1024; // maximum buckets.
2509 int length
=addressSpace
;
2510 if (length
> maxBuckets
)
2514 int *buckets
=malloc(sizeof(int)*length
);
2520 memset(buckets
, 0, sizeof(int)*length
);
2521 for (i
=0; i
<sampleNum
;i
++)
2523 u32 address
=samples
[i
];
2524 long long a
=address
-min
;
2525 long long b
=length
-1;
2526 long long c
=addressSpace
-1;
2527 int index
=(a
*b
)/c
; // danger!!!! int32 overflows
2531 // append binary memory gmon.out &profile_hist_hdr ((char*)&profile_hist_hdr + sizeof(struct gmon_hist_hdr))
2532 writeLong(f
, min
); // low_pc
2533 writeLong(f
, max
); // high_pc
2534 writeLong(f
, length
); // # of samples
2535 writeLong(f
, 64000000); // 64MHz
2536 writeString(f
, "seconds");
2537 for (i
=0; i
<(15-strlen("seconds")); i
++)
2539 fwrite("", 1, 1, f
); // padding
2541 writeString(f
, "s");
2543 // append binary memory gmon.out profile_hist_data (profile_hist_data + profile_hist_hdr.hist_size)
2545 char *data
=malloc(2*length
);
2548 for (i
=0; i
<length
;i
++)
2557 data
[i
*2+1]=(val
>>8)&0xff;
2560 fwrite(data
, 1, length
*2, f
);
2570 /* profiling samples the CPU PC as quickly as OpenOCD is able, which will be used as a random sampling of PC */
2571 int handle_profile_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2573 target_t
*target
= get_current_target(cmd_ctx
);
2574 struct timeval timeout
, now
;
2576 gettimeofday(&timeout
, NULL
);
2579 return ERROR_COMMAND_SYNTAX_ERROR
;
2582 timeval_add_time(&timeout
, strtoul(args
[0], &end
, 0), 0);
2588 command_print(cmd_ctx
, "Starting profiling. Halting and resuming the target as often as we can...");
2590 static const int maxSample
=10000;
2591 u32
*samples
=malloc(sizeof(u32
)*maxSample
);
2596 int retval
=ERROR_OK
;
2597 // hopefully it is safe to cache! We want to stop/restart as quickly as possible.
2598 reg_t
*reg
= register_get_by_name(target
->reg_cache
, "pc", 1);
2602 target_poll(target
);
2603 if (target
->state
== TARGET_HALTED
)
2605 u32 t
=*((u32
*)reg
->value
);
2606 samples
[numSamples
++]=t
;
2607 retval
= target_resume(target
, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */
2608 target_poll(target
);
2609 alive_sleep(10); // sleep 10ms, i.e. <100 samples/second.
2610 } else if (target
->state
== TARGET_RUNNING
)
2612 // We want to quickly sample the PC.
2613 if((retval
= target_halt(target
)) != ERROR_OK
)
2620 command_print(cmd_ctx
, "Target not halted or running");
2624 if (retval
!=ERROR_OK
)
2629 gettimeofday(&now
, NULL
);
2630 if ((numSamples
>=maxSample
) || ((now
.tv_sec
>= timeout
.tv_sec
) && (now
.tv_usec
>= timeout
.tv_usec
)))
2632 command_print(cmd_ctx
, "Profiling completed. %d samples.", numSamples
);
2633 if((retval
= target_poll(target
)) != ERROR_OK
)
2638 if (target
->state
== TARGET_HALTED
)
2640 target_resume(target
, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */
2642 if((retval
= target_poll(target
)) != ERROR_OK
)
2647 writeGmon(samples
, numSamples
, args
[1]);
2648 command_print(cmd_ctx
, "Wrote %s", args
[1]);
2657 static int new_int_array_element(Jim_Interp
* interp
, const char *varname
, int idx
, u32 val
)
2660 Jim_Obj
*nameObjPtr
, *valObjPtr
;
2663 namebuf
= alloc_printf("%s(%d)", varname
, idx
);
2667 nameObjPtr
= Jim_NewStringObj(interp
, namebuf
, -1);
2668 valObjPtr
= Jim_NewIntObj(interp
, val
);
2669 if (!nameObjPtr
|| !valObjPtr
)
2675 Jim_IncrRefCount(nameObjPtr
);
2676 Jim_IncrRefCount(valObjPtr
);
2677 result
= Jim_SetVariable(interp
, nameObjPtr
, valObjPtr
);
2678 Jim_DecrRefCount(interp
, nameObjPtr
);
2679 Jim_DecrRefCount(interp
, valObjPtr
);
2681 /* printf("%s(%d) <= 0%08x\n", varname, idx, val); */
2685 static int jim_mem2array(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
2687 command_context_t
*context
;
2690 context
= Jim_GetAssocData(interp
, "context");
2691 if (context
== NULL
)
2693 LOG_ERROR("mem2array: no command context");
2696 target
= get_current_target(context
);
2699 LOG_ERROR("mem2array: no current target");
2703 return target_mem2array(interp
, target
, argc
,argv
);
2706 static int target_mem2array(Jim_Interp
*interp
, target_t
*target
, int argc
, Jim_Obj
*const *argv
)
2714 const char *varname
;
2716 int i
, n
, e
, retval
;
2718 /* argv[1] = name of array to receive the data
2719 * argv[2] = desired width
2720 * argv[3] = memory address
2721 * argv[4] = count of times to read
2724 Jim_WrongNumArgs(interp
, 1, argv
, "varname width addr nelems");
2727 varname
= Jim_GetString(argv
[1], &len
);
2728 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
2730 e
= Jim_GetLong(interp
, argv
[2], &l
);
2736 e
= Jim_GetLong(interp
, argv
[3], &l
);
2741 e
= Jim_GetLong(interp
, argv
[4], &l
);
2757 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2758 Jim_AppendStrings( interp
, Jim_GetResult(interp
), "Invalid width param, must be 8/16/32", NULL
);
2762 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2763 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: zero width read?", NULL
);
2766 if ((addr
+ (len
* width
)) < addr
) {
2767 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2768 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: addr + len - wraps to zero?", NULL
);
2771 /* absurd transfer size? */
2773 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2774 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: absurd > 64K item request", NULL
);
2779 ((width
== 2) && ((addr
& 1) == 0)) ||
2780 ((width
== 4) && ((addr
& 3) == 0))) {
2784 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2785 sprintf(buf
, "mem2array address: 0x%08x is not aligned for %d byte reads", addr
, width
);
2786 Jim_AppendStrings(interp
, Jim_GetResult(interp
), buf
, NULL
);
2797 /* Slurp... in buffer size chunks */
2799 count
= len
; /* in objects.. */
2800 if (count
> (sizeof(buffer
)/width
)) {
2801 count
= (sizeof(buffer
)/width
);
2804 retval
= target
->type
->read_memory( target
, addr
, width
, count
, buffer
);
2805 if (retval
!= ERROR_OK
) {
2807 LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed", addr
, width
, count
);
2808 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2809 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: cannot read memory", NULL
);
2813 v
= 0; /* shut up gcc */
2814 for (i
= 0 ;i
< count
;i
++, n
++) {
2817 v
= target_buffer_get_u32(target
, &buffer
[i
*width
]);
2820 v
= target_buffer_get_u16(target
, &buffer
[i
*width
]);
2823 v
= buffer
[i
] & 0x0ff;
2826 new_int_array_element(interp
, varname
, n
, v
);
2832 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2837 static int get_int_array_element(Jim_Interp
* interp
, const char *varname
, int idx
, u32
*val
)
2840 Jim_Obj
*nameObjPtr
, *valObjPtr
;
2844 namebuf
= alloc_printf("%s(%d)", varname
, idx
);
2848 nameObjPtr
= Jim_NewStringObj(interp
, namebuf
, -1);
2855 Jim_IncrRefCount(nameObjPtr
);
2856 valObjPtr
= Jim_GetVariable(interp
, nameObjPtr
, JIM_ERRMSG
);
2857 Jim_DecrRefCount(interp
, nameObjPtr
);
2859 if (valObjPtr
== NULL
)
2862 result
= Jim_GetLong(interp
, valObjPtr
, &l
);
2863 /* printf("%s(%d) => 0%08x\n", varname, idx, val); */
2868 static int jim_array2mem(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
2870 command_context_t
*context
;
2873 context
= Jim_GetAssocData(interp
, "context");
2874 if (context
== NULL
){
2875 LOG_ERROR("array2mem: no command context");
2878 target
= get_current_target(context
);
2879 if (target
== NULL
){
2880 LOG_ERROR("array2mem: no current target");
2884 return target_array2mem( interp
,target
, argc
, argv
);
2888 static int target_array2mem(Jim_Interp
*interp
, target_t
*target
, int argc
, Jim_Obj
*const *argv
)
2896 const char *varname
;
2898 int i
, n
, e
, retval
;
2900 /* argv[1] = name of array to get the data
2901 * argv[2] = desired width
2902 * argv[3] = memory address
2903 * argv[4] = count to write
2906 Jim_WrongNumArgs(interp
, 1, argv
, "varname width addr nelems");
2909 varname
= Jim_GetString(argv
[1], &len
);
2910 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
2912 e
= Jim_GetLong(interp
, argv
[2], &l
);
2918 e
= Jim_GetLong(interp
, argv
[3], &l
);
2923 e
= Jim_GetLong(interp
, argv
[4], &l
);
2939 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2940 Jim_AppendStrings( interp
, Jim_GetResult(interp
), "Invalid width param, must be 8/16/32", NULL
);
2944 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2945 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: zero width read?", NULL
);
2948 if ((addr
+ (len
* width
)) < addr
) {
2949 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2950 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: addr + len - wraps to zero?", NULL
);
2953 /* absurd transfer size? */
2955 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2956 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: absurd > 64K item request", NULL
);
2961 ((width
== 2) && ((addr
& 1) == 0)) ||
2962 ((width
== 4) && ((addr
& 3) == 0))) {
2966 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2967 sprintf(buf
, "array2mem address: 0x%08x is not aligned for %d byte reads", addr
, width
);
2968 Jim_AppendStrings(interp
, Jim_GetResult(interp
), buf
, NULL
);
2980 /* Slurp... in buffer size chunks */
2982 count
= len
; /* in objects.. */
2983 if (count
> (sizeof(buffer
)/width
)) {
2984 count
= (sizeof(buffer
)/width
);
2987 v
= 0; /* shut up gcc */
2988 for (i
= 0 ;i
< count
;i
++, n
++) {
2989 get_int_array_element(interp
, varname
, n
, &v
);
2992 target_buffer_set_u32(target
, &buffer
[i
*width
], v
);
2995 target_buffer_set_u16(target
, &buffer
[i
*width
], v
);
2998 buffer
[i
] = v
& 0x0ff;
3004 retval
= target
->type
->write_memory(target
, addr
, width
, count
, buffer
);
3005 if (retval
!= ERROR_OK
) {
3007 LOG_ERROR("array2mem: Write @ 0x%08x, w=%d, cnt=%d, failed", addr
, width
, count
);
3008 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
3009 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: cannot read memory", NULL
);
3015 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
3021 target_all_handle_event( enum target_event e
)
3026 LOG_DEBUG( "**all*targets: event: %d, %s",
3028 Jim_Nvp_value2name_simple( nvp_target_event
, e
)->name
);
3030 target
= all_targets
;
3032 target_handle_event( target
, e
);
3033 target
= target
->next
;
3038 target_handle_event( target_t
*target
, enum target_event e
)
3040 target_event_action_t
*teap
;
3043 teap
= target
->event_action
;
3047 if( teap
->event
== e
){
3049 LOG_DEBUG( "target: (%d) %s (%s) event: %d (%s) action: %s\n",
3050 target
->target_number
,
3054 Jim_Nvp_value2name_simple( nvp_target_event
, e
)->name
,
3055 Jim_GetString( teap
->body
, NULL
) );
3056 if (Jim_EvalObj( interp
, teap
->body
)!=JIM_OK
)
3058 Jim_PrintErrorMessage(interp
);
3064 LOG_DEBUG( "event: %d %s - no action",
3066 Jim_Nvp_value2name_simple( nvp_target_event
, e
)->name
);
3070 enum target_cfg_param
{
3073 TCFG_WORK_AREA_VIRT
,
3074 TCFG_WORK_AREA_PHYS
,
3075 TCFG_WORK_AREA_SIZE
,
3076 TCFG_WORK_AREA_BACKUP
,
3079 TCFG_CHAIN_POSITION
,
3083 static Jim_Nvp nvp_config_opts
[] = {
3084 { .name
= "-type", .value
= TCFG_TYPE
},
3085 { .name
= "-event", .value
= TCFG_EVENT
},
3086 { .name
= "-work-area-virt", .value
= TCFG_WORK_AREA_VIRT
},
3087 { .name
= "-work-area-phys", .value
= TCFG_WORK_AREA_PHYS
},
3088 { .name
= "-work-area-size", .value
= TCFG_WORK_AREA_SIZE
},
3089 { .name
= "-work-area-backup", .value
= TCFG_WORK_AREA_BACKUP
},
3090 { .name
= "-endian" , .value
= TCFG_ENDIAN
},
3091 { .name
= "-variant", .value
= TCFG_VARIANT
},
3092 { .name
= "-chain-position", .value
= TCFG_CHAIN_POSITION
},
3094 { .name
= NULL
, .value
= -1 }
3099 target_configure( Jim_GetOptInfo
*goi
,
3109 /* parse config or cget options ... */
3110 while( goi
->argc
> 0 ){
3111 Jim_SetEmptyResult( goi
->interp
);
3112 //Jim_GetOpt_Debug( goi );
3114 if( target
->type
->target_jim_configure
){
3115 /* target defines a configure function */
3116 /* target gets first dibs on parameters */
3117 e
= (*(target
->type
->target_jim_configure
))( target
, goi
);
3126 /* otherwise we 'continue' below */
3128 e
= Jim_GetOpt_Nvp( goi
, nvp_config_opts
, &n
);
3130 Jim_GetOpt_NvpUnknown( goi
, nvp_config_opts
, 0 );
3136 if( goi
->isconfigure
){
3137 Jim_SetResult_sprintf( goi
->interp
, "not setable: %s", n
->name
);
3141 if( goi
->argc
!= 0 ){
3142 Jim_WrongNumArgs( goi
->interp
, goi
->argc
, goi
->argv
, "NO PARAMS");
3146 Jim_SetResultString( goi
->interp
, target
->type
->name
, -1 );
3150 if( goi
->argc
== 0 ){
3151 Jim_WrongNumArgs( goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name? ...");
3155 e
= Jim_GetOpt_Nvp( goi
, nvp_target_event
, &n
);
3157 Jim_GetOpt_NvpUnknown( goi
, nvp_target_event
, 1 );
3161 if( goi
->isconfigure
){
3162 if( goi
->argc
!= 1 ){
3163 Jim_WrongNumArgs( goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name? ?EVENT-BODY?");
3167 if( goi
->argc
!= 0 ){
3168 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name?");
3175 target_event_action_t
*teap
;
3177 teap
= target
->event_action
;
3178 /* replace existing? */
3180 if( teap
->event
== n
->value
){
3186 if( goi
->isconfigure
){
3189 teap
= calloc( 1, sizeof(*teap
) );
3191 teap
->event
= n
->value
;
3192 Jim_GetOpt_Obj( goi
, &o
);
3194 Jim_DecrRefCount( interp
, teap
->body
);
3196 teap
->body
= Jim_DuplicateObj( goi
->interp
, o
);
3199 * Tcl/TK - "tk events" have a nice feature.
3200 * See the "BIND" command.
3201 * We should support that here.
3202 * You can specify %X and %Y in the event code.
3203 * The idea is: %T - target name.
3204 * The idea is: %N - target number
3205 * The idea is: %E - event name.
3207 Jim_IncrRefCount( teap
->body
);
3209 /* add to head of event list */
3210 teap
->next
= target
->event_action
;
3211 target
->event_action
= teap
;
3212 Jim_SetEmptyResult(goi
->interp
);
3216 Jim_SetEmptyResult( goi
->interp
);
3218 Jim_SetResult( goi
->interp
, Jim_DuplicateObj( goi
->interp
, teap
->body
) );
3225 case TCFG_WORK_AREA_VIRT
:
3226 if( goi
->isconfigure
){
3227 target_free_all_working_areas(target
);
3228 e
= Jim_GetOpt_Wide( goi
, &w
);
3232 target
->working_area_virt
= w
;
3234 if( goi
->argc
!= 0 ){
3238 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_virt
) );
3242 case TCFG_WORK_AREA_PHYS
:
3243 if( goi
->isconfigure
){
3244 target_free_all_working_areas(target
);
3245 e
= Jim_GetOpt_Wide( goi
, &w
);
3249 target
->working_area_phys
= w
;
3251 if( goi
->argc
!= 0 ){
3255 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_phys
) );
3259 case TCFG_WORK_AREA_SIZE
:
3260 if( goi
->isconfigure
){
3261 target_free_all_working_areas(target
);
3262 e
= Jim_GetOpt_Wide( goi
, &w
);
3266 target
->working_area_size
= w
;
3268 if( goi
->argc
!= 0 ){
3272 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_size
) );
3276 case TCFG_WORK_AREA_BACKUP
:
3277 if( goi
->isconfigure
){
3278 target_free_all_working_areas(target
);
3279 e
= Jim_GetOpt_Wide( goi
, &w
);
3283 /* make this exactly 1 or 0 */
3284 target
->backup_working_area
= (!!w
);
3286 if( goi
->argc
!= 0 ){
3290 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_size
) );
3291 /* loop for more e*/
3295 if( goi
->isconfigure
){
3296 e
= Jim_GetOpt_Nvp( goi
, nvp_target_endian
, &n
);
3298 Jim_GetOpt_NvpUnknown( goi
, nvp_target_endian
, 1 );
3301 target
->endianness
= n
->value
;
3303 if( goi
->argc
!= 0 ){
3307 n
= Jim_Nvp_value2name_simple( nvp_target_endian
, target
->endianness
);
3308 if( n
->name
== NULL
){
3309 target
->endianness
= TARGET_LITTLE_ENDIAN
;
3310 n
= Jim_Nvp_value2name_simple( nvp_target_endian
, target
->endianness
);
3312 Jim_SetResultString( goi
->interp
, n
->name
, -1 );
3317 if( goi
->isconfigure
){
3318 if( goi
->argc
< 1 ){
3319 Jim_SetResult_sprintf( goi
->interp
,
3324 if( target
->variant
){
3325 free((void *)(target
->variant
));
3327 e
= Jim_GetOpt_String( goi
, &cp
, NULL
);
3328 target
->variant
= strdup(cp
);
3330 if( goi
->argc
!= 0 ){
3334 Jim_SetResultString( goi
->interp
, target
->variant
,-1 );
3337 case TCFG_CHAIN_POSITION
:
3338 if( goi
->isconfigure
){
3339 target_free_all_working_areas(target
);
3340 e
= Jim_GetOpt_Wide( goi
, &w
);
3344 /* make this exactly 1 or 0 */
3345 target
->chain_position
= w
;
3347 if( goi
->argc
!= 0 ){
3351 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->chain_position
) );
3352 /* loop for more e*/
3355 } /* while( goi->argc ) */
3356 /* done - we return */
3361 /** this is the 'tcl' handler for the target specific command */
3363 tcl_target_func( Jim_Interp
*interp
,
3365 Jim_Obj
*const *argv
)
3373 struct command_context_s
*cmd_ctx
;
3381 TS_CMD_MWW
, TS_CMD_MWH
, TS_CMD_MWB
,
3382 TS_CMD_MDW
, TS_CMD_MDH
, TS_CMD_MDB
,
3383 TS_CMD_MRW
, TS_CMD_MRH
, TS_CMD_MRB
,
3384 TS_CMD_MEM2ARRAY
, TS_CMD_ARRAY2MEM
,
3392 TS_CMD_INVOKE_EVENT
,
3395 static const Jim_Nvp target_options
[] = {
3396 { .name
= "configure", .value
= TS_CMD_CONFIGURE
},
3397 { .name
= "cget", .value
= TS_CMD_CGET
},
3398 { .name
= "mww", .value
= TS_CMD_MWW
},
3399 { .name
= "mwh", .value
= TS_CMD_MWH
},
3400 { .name
= "mwb", .value
= TS_CMD_MWB
},
3401 { .name
= "mdw", .value
= TS_CMD_MDW
},
3402 { .name
= "mdh", .value
= TS_CMD_MDH
},
3403 { .name
= "mdb", .value
= TS_CMD_MDB
},
3404 { .name
= "mem2array", .value
= TS_CMD_MEM2ARRAY
},
3405 { .name
= "array2mem", .value
= TS_CMD_ARRAY2MEM
},
3406 { .name
= "eventlist", .value
= TS_CMD_EVENTLIST
},
3407 { .name
= "curstate", .value
= TS_CMD_CURSTATE
},
3409 { .name
= "arp_examine", .value
= TS_CMD_EXAMINE
},
3410 { .name
= "arp_poll", .value
= TS_CMD_POLL
},
3411 { .name
= "arp_reset", .value
= TS_CMD_RESET
},
3412 { .name
= "arp_halt", .value
= TS_CMD_HALT
},
3413 { .name
= "arp_waitstate", .value
= TS_CMD_WAITSTATE
},
3414 { .name
= "invoke-event", .value
= TS_CMD_INVOKE_EVENT
},
3416 { .name
= NULL
, .value
= -1 },
3420 /* go past the "command" */
3421 Jim_GetOpt_Setup( &goi
, interp
, argc
-1, argv
+1 );
3423 target
= Jim_CmdPrivData( goi
.interp
);
3424 cmd_ctx
= Jim_GetAssocData(goi
.interp
, "context");
3426 /* commands here are in an NVP table */
3427 e
= Jim_GetOpt_Nvp( &goi
, target_options
, &n
);
3429 Jim_GetOpt_NvpUnknown( &goi
, target_options
, 0 );
3432 // Assume blank result
3433 Jim_SetEmptyResult( goi
.interp
);
3436 case TS_CMD_CONFIGURE
:
3438 Jim_WrongNumArgs( goi
.interp
, goi
.argc
, goi
.argv
, "missing: -option VALUE ...");
3441 goi
.isconfigure
= 1;
3442 return target_configure( &goi
, target
);
3444 // some things take params
3446 Jim_WrongNumArgs( goi
.interp
, 0, goi
.argv
, "missing: ?-option?");
3449 goi
.isconfigure
= 0;
3450 return target_configure( &goi
, target
);
3458 * argv[3] = optional count.
3461 if( (goi
.argc
== 3) || (goi
.argc
== 4) ){
3465 Jim_SetResult_sprintf( goi
.interp
, "expected: %s ADDR DATA [COUNT]", n
->name
);
3469 e
= Jim_GetOpt_Wide( &goi
, &a
);
3474 e
= Jim_GetOpt_Wide( &goi
, &b
);
3479 e
= Jim_GetOpt_Wide( &goi
, &c
);
3489 target_buffer_set_u32( target
, target_buf
, b
);
3493 target_buffer_set_u16( target
, target_buf
, b
);
3497 target_buffer_set_u8( target
, target_buf
, b
);
3501 for( x
= 0 ; x
< c
; x
++ ){
3502 e
= target
->type
->write_memory( target
, a
, b
, 1, target_buf
);
3503 if( e
!= ERROR_OK
){
3504 Jim_SetResult_sprintf( interp
, "Error writing @ 0x%08x: %d\n", (int)(a
), e
);
3517 /* argv[0] = command
3519 * argv[2] = optional count
3521 if( (goi
.argc
== 2) || (goi
.argc
== 3) ){
3522 Jim_SetResult_sprintf( goi
.interp
, "expected: %s ADDR [COUNT]", n
->name
);
3525 e
= Jim_GetOpt_Wide( &goi
, &a
);
3530 e
= Jim_GetOpt_Wide( &goi
, &c
);
3537 b
= 1; /* shut up gcc */
3550 /* convert to "bytes" */
3552 /* count is now in 'BYTES' */
3558 e
= target
->type
->read_memory( target
, a
, b
, y
/ b
, target_buf
);
3559 if( e
!= ERROR_OK
){
3560 Jim_SetResult_sprintf( interp
, "error reading target @ 0x%08lx", (int)(a
) );
3564 Jim_fprintf( interp
, interp
->cookie_stdout
, "0x%08x ", (int)(a
) );
3567 for( x
= 0 ; (x
< 16) && (x
< y
) ; x
+= 4 ){
3568 z
= target_buffer_get_u32( target
, &(target_buf
[ x
* 4 ]) );
3569 Jim_fprintf( interp
, interp
->cookie_stdout
, "%08x ", (int)(z
) );
3571 for( ; (x
< 16) ; x
+= 4 ){
3572 Jim_fprintf( interp
, interp
->cookie_stdout
, " " );
3576 for( x
= 0 ; (x
< 16) && (x
< y
) ; x
+= 2 ){
3577 z
= target_buffer_get_u16( target
, &(target_buf
[ x
* 2 ]) );
3578 Jim_fprintf( interp
, interp
->cookie_stdout
, "%04x ", (int)(z
) );
3580 for( ; (x
< 16) ; x
+= 2 ){
3581 Jim_fprintf( interp
, interp
->cookie_stdout
, " " );
3586 for( x
= 0 ; (x
< 16) && (x
< y
) ; x
+= 1 ){
3587 z
= target_buffer_get_u8( target
, &(target_buf
[ x
* 4 ]) );
3588 Jim_fprintf( interp
, interp
->cookie_stdout
, "%02x ", (int)(z
) );
3590 for( ; (x
< 16) ; x
+= 1 ){
3591 Jim_fprintf( interp
, interp
->cookie_stdout
, " " );
3595 /* ascii-ify the bytes */
3596 for( x
= 0 ; x
< y
; x
++ ){
3597 if( (target_buf
[x
] >= 0x20) &&
3598 (target_buf
[x
] <= 0x7e) ){
3602 target_buf
[x
] = '.';
3607 target_buf
[x
] = ' ';
3612 /* print - with a newline */
3613 Jim_fprintf( interp
, interp
->cookie_stdout
, "%s\n", target_buf
);
3619 case TS_CMD_MEM2ARRAY
:
3620 return target_mem2array( goi
.interp
, target
, goi
.argc
, goi
.argv
);
3622 case TS_CMD_ARRAY2MEM
:
3623 return target_array2mem( goi
.interp
, target
, goi
.argc
, goi
.argv
);
3625 case TS_CMD_EXAMINE
:
3627 Jim_WrongNumArgs( goi
.interp
, 2, argv
, "[no parameters]");
3630 e
= target
->type
->examine( target
);
3631 if( e
!= ERROR_OK
){
3632 Jim_SetResult_sprintf( interp
, "examine-fails: %d", e
);
3638 Jim_WrongNumArgs( goi
.interp
, 2, argv
, "[no parameters]");
3641 if( !(target
->type
->examined
) ){
3642 e
= ERROR_TARGET_NOT_EXAMINED
;
3644 e
= target
->type
->poll( target
);
3646 if( e
!= ERROR_OK
){
3647 Jim_SetResult_sprintf( interp
, "poll-fails: %d", e
);
3654 if( goi
.argc
!= 2 ){
3655 Jim_WrongNumArgs( interp
, 2, argv
, "t|f|assert|deassert BOOL");
3658 e
= Jim_GetOpt_Nvp( &goi
, nvp_assert
, &n
);
3660 Jim_GetOpt_NvpUnknown( &goi
, nvp_assert
, 1 );
3663 // the halt or not param
3664 e
= Jim_GetOpt_Wide( &goi
, &a
);
3668 // determine if we should halt or not.
3669 target
->reset_halt
= !!a
;
3670 // When this happens - all workareas are invalid.
3671 target_free_all_working_areas_restore(target
, 0);
3674 if( n
->value
== NVP_ASSERT
){
3675 target
->type
->assert_reset( target
);
3677 target
->type
->deassert_reset( target
);
3682 Jim_WrongNumArgs( goi
.interp
, 0, argv
, "halt [no parameters]");
3685 target
->type
->halt( target
);
3687 case TS_CMD_WAITSTATE
:
3688 // params: <name> statename timeoutmsecs
3689 if( goi
.argc
!= 2 ){
3690 Jim_SetResult_sprintf( goi
.interp
, "%s STATENAME TIMEOUTMSECS", n
->name
);
3693 e
= Jim_GetOpt_Nvp( &goi
, nvp_target_state
, &n
);
3695 Jim_GetOpt_NvpUnknown( &goi
, nvp_target_state
,1 );
3698 e
= Jim_GetOpt_Wide( &goi
, &a
);
3702 e
= target_wait_state( target
, n
->value
, a
);
3703 if( e
!= ERROR_OK
){
3704 Jim_SetResult_sprintf( goi
.interp
,
3705 "target: %s wait %s fails (%d) %s",
3708 e
, target_strerror_safe(e
) );
3713 case TS_CMD_EVENTLIST
:
3714 /* List for human, Events defined for this target.
3715 * scripts/programs should use 'name cget -event NAME'
3718 target_event_action_t
*teap
;
3719 teap
= target
->event_action
;
3720 command_print( cmd_ctx
, "Event actions for target (%d) %s\n",
3721 target
->target_number
,
3723 command_print( cmd_ctx
, "%-25s | Body", "Event");
3724 command_print( cmd_ctx
, "------------------------- | ----------------------------------------");
3726 command_print( cmd_ctx
,
3728 Jim_Nvp_value2name_simple( nvp_target_event
, teap
->event
)->name
,
3729 Jim_GetString( teap
->body
, NULL
) );
3732 command_print( cmd_ctx
, "***END***");
3735 case TS_CMD_CURSTATE
:
3736 if( goi
.argc
!= 0 ){
3737 Jim_WrongNumArgs( goi
.interp
, 0, argv
, "[no parameters]");
3740 Jim_SetResultString( goi
.interp
,
3741 Jim_Nvp_value2name_simple(nvp_target_state
,target
->state
)->name
,-1);
3743 case TS_CMD_INVOKE_EVENT
:
3744 if( goi
.argc
!= 1 ){
3745 Jim_SetResult_sprintf( goi
.interp
, "%s ?EVENTNAME?",n
->name
);
3748 e
= Jim_GetOpt_Nvp( &goi
, nvp_target_event
, &n
);
3750 Jim_GetOpt_NvpUnknown( &goi
, nvp_target_event
, 1 );
3753 target_handle_event( target
, n
->value
);
3761 target_create( Jim_GetOptInfo
*goi
)
3771 struct command_context_s
*cmd_ctx
;
3773 cmd_ctx
= Jim_GetAssocData(goi
->interp
, "context");
3774 if( goi
->argc
< 3 ){
3775 Jim_WrongNumArgs( goi
->interp
, 1, goi
->argv
, "?name? ?type? ..options...");
3780 Jim_GetOpt_Obj( goi
, &new_cmd
);
3781 /* does this command exist? */
3782 cmd
= Jim_GetCommand( goi
->interp
, new_cmd
, JIM_ERRMSG
);
3784 cp
= Jim_GetString( new_cmd
, NULL
);
3785 Jim_SetResult_sprintf(goi
->interp
, "Command/target: %s Exists", cp
);
3790 e
= Jim_GetOpt_String( goi
, &cp2
, NULL
);
3792 /* now does target type exist */
3793 for( x
= 0 ; target_types
[x
] ; x
++ ){
3794 if( 0 == strcmp( cp
, target_types
[x
]->name
) ){
3799 if( target_types
[x
] == NULL
){
3800 Jim_SetResult_sprintf( goi
->interp
, "Unknown target type %s, try one of ", cp
);
3801 for( x
= 0 ; target_types
[x
] ; x
++ ){
3802 if( target_types
[x
+1] ){
3803 Jim_AppendStrings( goi
->interp
,
3804 Jim_GetResult(goi
->interp
),
3805 target_types
[x
]->name
,
3808 Jim_AppendStrings( goi
->interp
,
3809 Jim_GetResult(goi
->interp
),
3811 target_types
[x
]->name
,NULL
);
3819 target
= calloc(1,sizeof(target_t
));
3820 /* set target number */
3821 target
->target_number
= new_target_number();
3823 /* allocate memory for each unique target type */
3824 target
->type
= (target_type_t
*)calloc(1,sizeof(target_type_t
));
3826 memcpy( target
->type
, target_types
[x
], sizeof(target_type_t
));
3828 /* will be set by "-endian" */
3829 target
->endianness
= TARGET_ENDIAN_UNKNOWN
;
3831 target
->working_area
= 0x0;
3832 target
->working_area_size
= 0x0;
3833 target
->working_areas
= NULL
;
3834 target
->backup_working_area
= 0;
3836 target
->state
= TARGET_UNKNOWN
;
3837 target
->debug_reason
= DBG_REASON_UNDEFINED
;
3838 target
->reg_cache
= NULL
;
3839 target
->breakpoints
= NULL
;
3840 target
->watchpoints
= NULL
;
3841 target
->next
= NULL
;
3842 target
->arch_info
= NULL
;
3844 /* initialize trace information */
3845 target
->trace_info
= malloc(sizeof(trace_t
));
3846 target
->trace_info
->num_trace_points
= 0;
3847 target
->trace_info
->trace_points_size
= 0;
3848 target
->trace_info
->trace_points
= NULL
;
3849 target
->trace_info
->trace_history_size
= 0;
3850 target
->trace_info
->trace_history
= NULL
;
3851 target
->trace_info
->trace_history_pos
= 0;
3852 target
->trace_info
->trace_history_overflowed
= 0;
3854 target
->dbgmsg
= NULL
;
3855 target
->dbg_msg_enabled
= 0;
3857 target
->endianness
= TARGET_ENDIAN_UNKNOWN
;
3859 /* Do the rest as "configure" options */
3860 goi
->isconfigure
= 1;
3861 e
= target_configure( goi
, target
);
3863 free( target
->type
);
3868 if( target
->endianness
== TARGET_ENDIAN_UNKNOWN
){
3869 /* default endian to little if not specified */
3870 target
->endianness
= TARGET_LITTLE_ENDIAN
;
3873 /* create the target specific commands */
3874 if( target
->type
->register_commands
){
3875 (*(target
->type
->register_commands
))( cmd_ctx
);
3877 if( target
->type
->target_create
){
3878 (*(target
->type
->target_create
))( target
, goi
->interp
);
3881 /* append to end of list */
3884 tpp
= &(all_targets
);
3886 tpp
= &( (*tpp
)->next
);
3891 cp
= Jim_GetString( new_cmd
, NULL
);
3892 target
->cmd_name
= strdup(cp
);
3894 /* now - create the new target name command */
3895 e
= Jim_CreateCommand( goi
->interp
,
3898 tcl_target_func
, /* C function */
3899 target
, /* private data */
3900 NULL
); /* no del proc */
3906 jim_target( Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
3910 struct command_context_s
*cmd_ctx
;
3915 /* TG = target generic */
3923 const char *target_cmds
[] = {
3924 "create", "types", "names", "current", "number",
3929 LOG_DEBUG("Target command params:");
3930 LOG_DEBUG(Jim_Debug_ArgvString( interp
, argc
, argv
) );
3932 cmd_ctx
= Jim_GetAssocData( interp
, "context" );
3934 Jim_GetOpt_Setup( &goi
, interp
, argc
-1, argv
+1 );
3936 if( goi
.argc
== 0 ){
3937 Jim_WrongNumArgs(interp
, 1, argv
, "missing: command ...");
3941 /* is this old syntax? */
3942 /* To determine: We have to peek at argv[0]*/
3943 cp
= Jim_GetString( goi
.argv
[0], NULL
);
3944 for( x
= 0 ; target_types
[x
] ; x
++ ){
3945 if( 0 == strcmp(cp
,target_types
[x
]->name
) ){
3949 if( target_types
[x
] ){
3950 /* YES IT IS OLD SYNTAX */
3951 Jim_Obj
*new_argv
[10];
3954 /* target_old_syntax
3956 * It appears that there are 2 old syntaxes:
3958 * target <typename> <endian> <chain position> <variant>
3962 * target <typename> <endian> <reset mode> <chain position> <variant>
3966 /* The minimum number of arguments is 4 */
3968 Jim_WrongNumArgs( interp
, 1, argv
, "[OLDSYNTAX] ?TYPE? ?ENDIAN? ?CHAIN-POSITION? ?VARIANT?");
3973 new_argv
[0] = argv
[0];
3974 new_argv
[1] = Jim_NewStringObj( interp
, "create", -1 );
3977 sprintf( buf
, "target%d", new_target_number() );
3978 new_argv
[2] = Jim_NewStringObj( interp
, buf
, -1 );
3980 new_argv
[3] = goi
.argv
[0]; /* typename */
3981 new_argv
[4] = Jim_NewStringObj( interp
, "-endian", -1 );
3982 new_argv
[5] = goi
.argv
[1];
3983 new_argv
[6] = Jim_NewStringObj( interp
, "-chain-position", -1 );
3985 /* If goi.argv[2] is not a number, we need to skip it since it is the reset mode. */
3987 int chain_position_argv
= 2;
3988 if (JIM_ERR
== Jim_GetWide(interp
, goi
.argv
[chain_position_argv
], &w
)) {
3989 if (chain_position_argv
+ 1 < goi
.argc
) {
3990 chain_position_argv
+= 1;
3992 Jim_WrongNumArgs( interp
, 1, argv
, "[OLDSYNTAX] ?TYPE? ?ENDIAN? ?RESET? ?CHAIN-POSITION? ?VARIANT?");
3997 new_argv
[7] = goi
.argv
[chain_position_argv
];
3999 /* Only provide a variant configure option if there was a variant specified */
4000 if (chain_position_argv
+ 1 < goi
.argc
) {
4001 new_argv
[8] = Jim_NewStringObj( interp
, "-variant", -1 );
4002 new_argv
[9] = goi
.argv
[chain_position_argv
+ 1];
4013 * argv[3] = typename
4016 * argv[6] = -position
4018 * argv[8] = -variant
4019 * argv[9] = "somestring"
4022 /* don't let these be released */
4023 for( x
= 0 ; x
< new_argc
; x
++ ){
4024 Jim_IncrRefCount( new_argv
[x
]);
4027 LOG_DEBUG("Target OLD SYNTAX - converted to new syntax");
4029 r
= jim_target( goi
.interp
, new_argc
, new_argv
);
4031 /* release? these items */
4032 for( x
= 0 ; x
< new_argc
; x
++ ){
4033 Jim_DecrRefCount( interp
, new_argv
[x
] );
4038 //Jim_GetOpt_Debug( &goi );
4039 r
= Jim_GetOpt_Enum( &goi
, target_cmds
, &x
);
4046 Jim_Panic(goi
.interp
,"Why am I here?");
4048 case TG_CMD_CURRENT
:
4049 if( goi
.argc
!= 0 ){
4050 Jim_WrongNumArgs( goi
.interp
, 1, goi
.argv
, "Too many parameters");
4053 Jim_SetResultString( goi
.interp
, get_current_target( cmd_ctx
)->cmd_name
, -1 );
4056 if( goi
.argc
!= 0 ){
4057 Jim_WrongNumArgs( goi
.interp
, 1, goi
.argv
, "Too many parameters" );
4060 Jim_SetResult( goi
.interp
, Jim_NewListObj( goi
.interp
, NULL
, 0 ) );
4061 for( x
= 0 ; target_types
[x
] ; x
++ ){
4062 Jim_ListAppendElement( goi
.interp
,
4063 Jim_GetResult(goi
.interp
),
4064 Jim_NewStringObj( goi
.interp
, target_types
[x
]->name
, -1 ) );
4068 if( goi
.argc
!= 0 ){
4069 Jim_WrongNumArgs( goi
.interp
, 1, goi
.argv
, "Too many parameters" );
4072 Jim_SetResult( goi
.interp
, Jim_NewListObj( goi
.interp
, NULL
, 0 ) );
4073 target
= all_targets
;
4075 Jim_ListAppendElement( goi
.interp
,
4076 Jim_GetResult(goi
.interp
),
4077 Jim_NewStringObj( goi
.interp
, target
->cmd_name
, -1 ) );
4078 target
= target
->next
;
4083 Jim_WrongNumArgs( goi
.interp
, goi
.argc
, goi
.argv
, "?name ... config options ...");
4086 return target_create( &goi
);
4089 if( goi
.argc
!= 1 ){
4090 Jim_SetResult_sprintf( goi
.interp
, "expected: target number ?NUMBER?");
4093 e
= Jim_GetOpt_Wide( &goi
, &w
);
4099 t
= get_target_by_num(w
);
4101 Jim_SetResult_sprintf( goi
.interp
,"Target: number %d does not exist", (int)(w
));
4104 Jim_SetResultString( goi
.interp
, t
->cmd_name
, -1 );
4108 if( goi
.argc
!= 0 ){
4109 Jim_WrongNumArgs( goi
.interp
, 0, goi
.argv
, "<no parameters>");
4112 Jim_SetResult( goi
.interp
,
4113 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)