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
);
64 int handle_targets_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
);
93 extern target_type_t arm7tdmi_target
;
94 extern target_type_t arm720t_target
;
95 extern target_type_t arm9tdmi_target
;
96 extern target_type_t arm920t_target
;
97 extern target_type_t arm966e_target
;
98 extern target_type_t arm926ejs_target
;
99 extern target_type_t feroceon_target
;
100 extern target_type_t xscale_target
;
101 extern target_type_t cortexm3_target
;
102 extern target_type_t arm11_target
;
103 extern target_type_t mips_m4k_target
;
105 target_type_t
*target_types
[] =
121 target_t
*all_targets
= NULL
;
122 target_event_callback_t
*target_event_callbacks
= NULL
;
123 target_timer_callback_t
*target_timer_callbacks
= NULL
;
125 const Jim_Nvp nvp_assert
[] = {
126 { .name
= "assert", NVP_ASSERT
},
127 { .name
= "deassert", NVP_DEASSERT
},
128 { .name
= "T", NVP_ASSERT
},
129 { .name
= "F", NVP_DEASSERT
},
130 { .name
= "t", NVP_ASSERT
},
131 { .name
= "f", NVP_DEASSERT
},
132 { .name
= NULL
, .value
= -1 }
135 const Jim_Nvp nvp_error_target
[] = {
136 { .value
= ERROR_TARGET_INVALID
, .name
= "err-invalid" },
137 { .value
= ERROR_TARGET_INIT_FAILED
, .name
= "err-init-failed" },
138 { .value
= ERROR_TARGET_TIMEOUT
, .name
= "err-timeout" },
139 { .value
= ERROR_TARGET_NOT_HALTED
, .name
= "err-not-halted" },
140 { .value
= ERROR_TARGET_FAILURE
, .name
= "err-failure" },
141 { .value
= ERROR_TARGET_UNALIGNED_ACCESS
, .name
= "err-unaligned-access" },
142 { .value
= ERROR_TARGET_DATA_ABORT
, .name
= "err-data-abort" },
143 { .value
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
, .name
= "err-resource-not-available" },
144 { .value
= ERROR_TARGET_TRANSLATION_FAULT
, .name
= "err-translation-fault" },
145 { .value
= ERROR_TARGET_NOT_RUNNING
, .name
= "err-not-running" },
146 { .value
= ERROR_TARGET_NOT_EXAMINED
, .name
= "err-not-examined" },
147 { .value
= -1, .name
= NULL
}
150 const char *target_strerror_safe( int err
)
154 n
= Jim_Nvp_value2name_simple( nvp_error_target
, err
);
155 if( n
->name
== NULL
){
162 const Jim_Nvp nvp_target_event
[] = {
163 { .value
= TARGET_EVENT_OLD_gdb_program_config
, .name
= "old-gdb_program_config" },
164 { .value
= TARGET_EVENT_OLD_pre_resume
, .name
= "old-pre_resume" },
166 { .value
= TARGET_EVENT_EARLY_HALTED
, .name
= "early-halted" },
167 { .value
= TARGET_EVENT_HALTED
, .name
= "halted" },
168 { .value
= TARGET_EVENT_RESUMED
, .name
= "resumed" },
169 { .value
= TARGET_EVENT_RESUME_START
, .name
= "resume-start" },
170 { .value
= TARGET_EVENT_RESUME_END
, .name
= "resume-end" },
172 { .name
= "gdb-start", .value
= TARGET_EVENT_GDB_START
},
173 { .name
= "gdb-end", .value
= TARGET_EVENT_GDB_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" },
190 { .value
= TARGET_EVENT_EXAMINE_START
, .name
= "examine-start" },
191 { .value
= TARGET_EVENT_EXAMINE_END
, .name
= "examine-end" },
193 { .value
= TARGET_EVENT_DEBUG_HALTED
, .name
= "debug-halted" },
194 { .value
= TARGET_EVENT_DEBUG_RESUMED
, .name
= "debug-resumed" },
196 { .value
= TARGET_EVENT_GDB_ATTACH
, .name
= "gdb-attach" },
197 { .value
= TARGET_EVENT_GDB_DETACH
, .name
= "gdb-detach" },
199 { .value
= TARGET_EVENT_GDB_FLASH_WRITE_START
, .name
= "gdb-flash-write-start" },
200 { .value
= TARGET_EVENT_GDB_FLASH_WRITE_END
, .name
= "gdb-flash-write-end" },
202 { .value
= TARGET_EVENT_GDB_FLASH_ERASE_START
, .name
= "gdb-flash-erase-start" },
203 { .value
= TARGET_EVENT_GDB_FLASH_ERASE_END
, .name
= "gdb-flash-erase-end" },
205 { .value
= TARGET_EVENT_RESUME_START
, .name
= "resume-start" },
206 { .value
= TARGET_EVENT_RESUMED
, .name
= "resume-ok" },
207 { .value
= TARGET_EVENT_RESUME_END
, .name
= "resume-end" },
209 { .name
= NULL
, .value
= -1 }
212 const Jim_Nvp nvp_target_state
[] = {
213 { .name
= "unknown", .value
= TARGET_UNKNOWN
},
214 { .name
= "running", .value
= TARGET_RUNNING
},
215 { .name
= "halted", .value
= TARGET_HALTED
},
216 { .name
= "reset", .value
= TARGET_RESET
},
217 { .name
= "debug-running", .value
= TARGET_DEBUG_RUNNING
},
218 { .name
= NULL
, .value
= -1 },
221 const Jim_Nvp nvp_target_debug_reason
[] = {
222 { .name
= "debug-request" , .value
= DBG_REASON_DBGRQ
},
223 { .name
= "breakpoint" , .value
= DBG_REASON_BREAKPOINT
},
224 { .name
= "watchpoint" , .value
= DBG_REASON_WATCHPOINT
},
225 { .name
= "watchpoint-and-breakpoint", .value
= DBG_REASON_WPTANDBKPT
},
226 { .name
= "single-step" , .value
= DBG_REASON_SINGLESTEP
},
227 { .name
= "target-not-halted" , .value
= DBG_REASON_NOTHALTED
},
228 { .name
= "undefined" , .value
= DBG_REASON_UNDEFINED
},
229 { .name
= NULL
, .value
= -1 },
233 const Jim_Nvp nvp_target_endian
[] = {
234 { .name
= "big", .value
= TARGET_BIG_ENDIAN
},
235 { .name
= "little", .value
= TARGET_LITTLE_ENDIAN
},
236 { .name
= "be", .value
= TARGET_BIG_ENDIAN
},
237 { .name
= "le", .value
= TARGET_LITTLE_ENDIAN
},
238 { .name
= NULL
, .value
= -1 },
241 const Jim_Nvp nvp_reset_modes
[] = {
242 { .name
= "unknown", .value
= RESET_UNKNOWN
},
243 { .name
= "run" , .value
= RESET_RUN
},
244 { .name
= "halt" , .value
= RESET_HALT
},
245 { .name
= "init" , .value
= RESET_INIT
},
246 { .name
= NULL
, .value
= -1 },
250 max_target_number( void )
258 if( x
< t
->target_number
){
259 x
= (t
->target_number
)+1;
266 /* determine the number of the new target */
268 new_target_number( void )
273 /* number is 0 based */
277 if( x
< t
->target_number
){
278 x
= t
->target_number
;
285 static int target_continous_poll
= 1;
287 /* read a u32 from a buffer in target memory endianness */
288 u32
target_buffer_get_u32(target_t
*target
, u8
*buffer
)
290 if (target
->endianness
== TARGET_LITTLE_ENDIAN
)
291 return le_to_h_u32(buffer
);
293 return be_to_h_u32(buffer
);
296 /* read a u16 from a buffer in target memory endianness */
297 u16
target_buffer_get_u16(target_t
*target
, u8
*buffer
)
299 if (target
->endianness
== TARGET_LITTLE_ENDIAN
)
300 return le_to_h_u16(buffer
);
302 return be_to_h_u16(buffer
);
305 /* read a u8 from a buffer in target memory endianness */
306 u8
target_buffer_get_u8(target_t
*target
, u8
*buffer
)
308 return *buffer
& 0x0ff;
311 /* write a u32 to a buffer in target memory endianness */
312 void target_buffer_set_u32(target_t
*target
, u8
*buffer
, u32 value
)
314 if (target
->endianness
== TARGET_LITTLE_ENDIAN
)
315 h_u32_to_le(buffer
, value
);
317 h_u32_to_be(buffer
, value
);
320 /* write a u16 to a buffer in target memory endianness */
321 void target_buffer_set_u16(target_t
*target
, u8
*buffer
, u16 value
)
323 if (target
->endianness
== TARGET_LITTLE_ENDIAN
)
324 h_u16_to_le(buffer
, value
);
326 h_u16_to_be(buffer
, value
);
329 /* write a u8 to a buffer in target memory endianness */
330 void target_buffer_set_u8(target_t
*target
, u8
*buffer
, u8 value
)
335 /* returns a pointer to the n-th configured target */
336 target_t
* get_target_by_num(int num
)
338 target_t
*target
= all_targets
;
341 if( target
->target_number
== num
){
344 target
= target
->next
;
350 int get_num_by_target(target_t
*query_target
)
352 return query_target
->target_number
;
355 target_t
* get_current_target(command_context_t
*cmd_ctx
)
357 target_t
*target
= get_target_by_num(cmd_ctx
->current_target
);
361 LOG_ERROR("BUG: current_target out of bounds");
368 int target_poll(struct target_s
*target
)
370 /* We can't poll until after examine */
371 if (!target
->type
->examined
)
373 /* Fail silently lest we pollute the log */
376 return target
->type
->poll(target
);
379 int target_halt(struct target_s
*target
)
381 /* We can't poll until after examine */
382 if (!target
->type
->examined
)
384 LOG_ERROR("Target not examined yet");
387 return target
->type
->halt(target
);
390 int target_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
394 /* We can't poll until after examine */
395 if (!target
->type
->examined
)
397 LOG_ERROR("Target not examined yet");
401 /* note that resume *must* be asynchronous. The CPU can halt before we poll. The CPU can
402 * even halt at the current PC as a result of a software breakpoint being inserted by (a bug?)
405 if ((retval
= target
->type
->resume(target
, current
, address
, handle_breakpoints
, debug_execution
)) != ERROR_OK
)
411 int target_process_reset(struct command_context_s
*cmd_ctx
, enum target_reset_mode reset_mode
)
416 n
= Jim_Nvp_value2name_simple( nvp_reset_modes
, reset_mode
);
417 if( n
->name
== NULL
){
418 LOG_ERROR("invalid reset mode");
422 sprintf( buf
, "ocd_process_reset %s", n
->name
);
423 retval
= Jim_Eval( interp
, buf
);
425 if(retval
!= JIM_OK
) {
426 Jim_PrintErrorMessage(interp
);
430 /* We want any events to be processed before the prompt */
431 retval
= target_call_timer_callbacks_now();
436 static int default_virt2phys(struct target_s
*target
, u32
virtual, u32
*physical
)
442 static int default_mmu(struct target_s
*target
, int *enabled
)
448 static int default_examine(struct target_s
*target
)
450 target
->type
->examined
= 1;
454 /* Targets that correctly implement init+examine, i.e.
455 * no communication with target during init:
459 int target_examine(void)
461 int retval
= ERROR_OK
;
462 target_t
*target
= all_targets
;
465 if ((retval
= target
->type
->examine(target
))!=ERROR_OK
)
467 target
= target
->next
;
472 static int target_write_memory_imp(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
474 if (!target
->type
->examined
)
476 LOG_ERROR("Target not examined yet");
479 return target
->type
->write_memory_imp(target
, address
, size
, count
, buffer
);
482 static int target_read_memory_imp(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
484 if (!target
->type
->examined
)
486 LOG_ERROR("Target not examined yet");
489 return target
->type
->read_memory_imp(target
, address
, size
, count
, buffer
);
492 static int target_soft_reset_halt_imp(struct target_s
*target
)
494 if (!target
->type
->examined
)
496 LOG_ERROR("Target not examined yet");
499 return target
->type
->soft_reset_halt_imp(target
);
502 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
)
504 if (!target
->type
->examined
)
506 LOG_ERROR("Target not examined yet");
509 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
);
512 int target_init(struct command_context_s
*cmd_ctx
)
514 target_t
*target
= all_targets
;
519 target
->type
->examined
= 0;
520 if (target
->type
->examine
== NULL
)
522 target
->type
->examine
= default_examine
;
525 if ((retval
= target
->type
->init_target(cmd_ctx
, target
)) != ERROR_OK
)
527 LOG_ERROR("target '%s' init failed", target
->type
->name
);
531 /* Set up default functions if none are provided by target */
532 if (target
->type
->virt2phys
== NULL
)
534 target
->type
->virt2phys
= default_virt2phys
;
536 target
->type
->virt2phys
= default_virt2phys
;
537 /* a non-invasive way(in terms of patches) to add some code that
538 * runs before the type->write/read_memory implementation
540 target
->type
->write_memory_imp
= target
->type
->write_memory
;
541 target
->type
->write_memory
= target_write_memory_imp
;
542 target
->type
->read_memory_imp
= target
->type
->read_memory
;
543 target
->type
->read_memory
= target_read_memory_imp
;
544 target
->type
->soft_reset_halt_imp
= target
->type
->soft_reset_halt
;
545 target
->type
->soft_reset_halt
= target_soft_reset_halt_imp
;
546 target
->type
->run_algorithm_imp
= target
->type
->run_algorithm
;
547 target
->type
->run_algorithm
= target_run_algorithm_imp
;
549 if (target
->type
->mmu
== NULL
)
551 target
->type
->mmu
= default_mmu
;
553 target
= target
->next
;
558 if((retval
= target_register_user_commands(cmd_ctx
)) != ERROR_OK
)
560 if((retval
= target_register_timer_callback(handle_target
, 100, 1, NULL
)) != ERROR_OK
)
567 int target_register_event_callback(int (*callback
)(struct target_s
*target
, enum target_event event
, void *priv
), void *priv
)
569 target_event_callback_t
**callbacks_p
= &target_event_callbacks
;
571 if (callback
== NULL
)
573 return ERROR_INVALID_ARGUMENTS
;
578 while ((*callbacks_p
)->next
)
579 callbacks_p
= &((*callbacks_p
)->next
);
580 callbacks_p
= &((*callbacks_p
)->next
);
583 (*callbacks_p
) = malloc(sizeof(target_event_callback_t
));
584 (*callbacks_p
)->callback
= callback
;
585 (*callbacks_p
)->priv
= priv
;
586 (*callbacks_p
)->next
= NULL
;
591 int target_register_timer_callback(int (*callback
)(void *priv
), int time_ms
, int periodic
, void *priv
)
593 target_timer_callback_t
**callbacks_p
= &target_timer_callbacks
;
596 if (callback
== NULL
)
598 return ERROR_INVALID_ARGUMENTS
;
603 while ((*callbacks_p
)->next
)
604 callbacks_p
= &((*callbacks_p
)->next
);
605 callbacks_p
= &((*callbacks_p
)->next
);
608 (*callbacks_p
) = malloc(sizeof(target_timer_callback_t
));
609 (*callbacks_p
)->callback
= callback
;
610 (*callbacks_p
)->periodic
= periodic
;
611 (*callbacks_p
)->time_ms
= time_ms
;
613 gettimeofday(&now
, NULL
);
614 (*callbacks_p
)->when
.tv_usec
= now
.tv_usec
+ (time_ms
% 1000) * 1000;
615 time_ms
-= (time_ms
% 1000);
616 (*callbacks_p
)->when
.tv_sec
= now
.tv_sec
+ (time_ms
/ 1000);
617 if ((*callbacks_p
)->when
.tv_usec
> 1000000)
619 (*callbacks_p
)->when
.tv_usec
= (*callbacks_p
)->when
.tv_usec
- 1000000;
620 (*callbacks_p
)->when
.tv_sec
+= 1;
623 (*callbacks_p
)->priv
= priv
;
624 (*callbacks_p
)->next
= NULL
;
629 int target_unregister_event_callback(int (*callback
)(struct target_s
*target
, enum target_event event
, void *priv
), void *priv
)
631 target_event_callback_t
**p
= &target_event_callbacks
;
632 target_event_callback_t
*c
= target_event_callbacks
;
634 if (callback
== NULL
)
636 return ERROR_INVALID_ARGUMENTS
;
641 target_event_callback_t
*next
= c
->next
;
642 if ((c
->callback
== callback
) && (c
->priv
== priv
))
656 int target_unregister_timer_callback(int (*callback
)(void *priv
), void *priv
)
658 target_timer_callback_t
**p
= &target_timer_callbacks
;
659 target_timer_callback_t
*c
= target_timer_callbacks
;
661 if (callback
== NULL
)
663 return ERROR_INVALID_ARGUMENTS
;
668 target_timer_callback_t
*next
= c
->next
;
669 if ((c
->callback
== callback
) && (c
->priv
== priv
))
683 int target_call_event_callbacks(target_t
*target
, enum target_event event
)
685 target_event_callback_t
*callback
= target_event_callbacks
;
686 target_event_callback_t
*next_callback
;
688 if (event
== TARGET_EVENT_HALTED
)
690 /* execute early halted first */
691 target_call_event_callbacks(target
, TARGET_EVENT_EARLY_HALTED
);
694 LOG_DEBUG("target event %i (%s)",
696 Jim_Nvp_value2name_simple( nvp_target_event
, event
)->name
);
698 target_handle_event( target
, event
);
702 next_callback
= callback
->next
;
703 callback
->callback(target
, event
, callback
->priv
);
704 callback
= next_callback
;
710 static int target_call_timer_callbacks_check_time(int checktime
)
712 target_timer_callback_t
*callback
= target_timer_callbacks
;
713 target_timer_callback_t
*next_callback
;
718 gettimeofday(&now
, NULL
);
722 next_callback
= callback
->next
;
724 if ((!checktime
&&callback
->periodic
)||
725 (((now
.tv_sec
>= callback
->when
.tv_sec
) && (now
.tv_usec
>= callback
->when
.tv_usec
))
726 || (now
.tv_sec
> callback
->when
.tv_sec
)))
728 if(callback
->callback
!= NULL
)
730 callback
->callback(callback
->priv
);
731 if (callback
->periodic
)
733 int time_ms
= callback
->time_ms
;
734 callback
->when
.tv_usec
= now
.tv_usec
+ (time_ms
% 1000) * 1000;
735 time_ms
-= (time_ms
% 1000);
736 callback
->when
.tv_sec
= now
.tv_sec
+ time_ms
/ 1000;
737 if (callback
->when
.tv_usec
> 1000000)
739 callback
->when
.tv_usec
= callback
->when
.tv_usec
- 1000000;
740 callback
->when
.tv_sec
+= 1;
746 if((retval
= target_unregister_timer_callback(callback
->callback
, callback
->priv
)) != ERROR_OK
)
752 callback
= next_callback
;
758 int target_call_timer_callbacks(void)
760 return target_call_timer_callbacks_check_time(1);
763 /* invoke periodic callbacks immediately */
764 int target_call_timer_callbacks_now(void)
766 return target_call_timer_callbacks_check_time(0);
769 int target_alloc_working_area(struct target_s
*target
, u32 size
, working_area_t
**area
)
771 working_area_t
*c
= target
->working_areas
;
772 working_area_t
*new_wa
= NULL
;
774 /* Reevaluate working area address based on MMU state*/
775 if (target
->working_areas
== NULL
)
779 retval
= target
->type
->mmu(target
, &enabled
);
780 if (retval
!= ERROR_OK
)
786 target
->working_area
= target
->working_area_virt
;
790 target
->working_area
= target
->working_area_phys
;
794 /* only allocate multiples of 4 byte */
797 LOG_ERROR("BUG: code tried to allocate unaligned number of bytes, padding");
798 size
= CEIL(size
, 4);
801 /* see if there's already a matching working area */
804 if ((c
->free
) && (c
->size
== size
))
812 /* if not, allocate a new one */
815 working_area_t
**p
= &target
->working_areas
;
816 u32 first_free
= target
->working_area
;
817 u32 free_size
= target
->working_area_size
;
819 LOG_DEBUG("allocating new working area");
821 c
= target
->working_areas
;
824 first_free
+= c
->size
;
825 free_size
-= c
->size
;
830 if (free_size
< size
)
832 LOG_WARNING("not enough working area available(requested %d, free %d)", size
, free_size
);
833 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
836 new_wa
= malloc(sizeof(working_area_t
));
839 new_wa
->address
= first_free
;
841 if (target
->backup_working_area
)
844 new_wa
->backup
= malloc(new_wa
->size
);
845 if((retval
= target
->type
->read_memory(target
, new_wa
->address
, 4, new_wa
->size
/ 4, new_wa
->backup
)) != ERROR_OK
)
847 free(new_wa
->backup
);
854 new_wa
->backup
= NULL
;
857 /* put new entry in list */
861 /* mark as used, and return the new (reused) area */
871 int target_free_working_area_restore(struct target_s
*target
, working_area_t
*area
, int restore
)
876 if (restore
&&target
->backup_working_area
)
879 if((retval
= target
->type
->write_memory(target
, area
->address
, 4, area
->size
/ 4, area
->backup
)) != ERROR_OK
)
885 /* mark user pointer invalid */
892 int target_free_working_area(struct target_s
*target
, working_area_t
*area
)
894 return target_free_working_area_restore(target
, area
, 1);
897 /* free resources and restore memory, if restoring memory fails,
898 * free up resources anyway
900 void target_free_all_working_areas_restore(struct target_s
*target
, int restore
)
902 working_area_t
*c
= target
->working_areas
;
906 working_area_t
*next
= c
->next
;
907 target_free_working_area_restore(target
, c
, restore
);
917 target
->working_areas
= NULL
;
920 void target_free_all_working_areas(struct target_s
*target
)
922 target_free_all_working_areas_restore(target
, 1);
925 int target_register_commands(struct command_context_s
*cmd_ctx
)
928 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)");
929 register_command(cmd_ctx
, NULL
, "virt2phys", handle_virt2phys_command
, COMMAND_ANY
, "translate a virtual address into a physical address");
930 register_command(cmd_ctx
, NULL
, "profile", handle_profile_command
, COMMAND_EXEC
, "profiling samples the CPU PC");
932 register_jim(cmd_ctx
, "target", jim_target
, "configure target" );
935 /* script procedures */
936 register_jim(cmd_ctx
, "ocd_mem2array", jim_mem2array
, "read memory and return as a TCL array for script processing");
937 register_jim(cmd_ctx
, "ocd_array2mem", jim_array2mem
, "convert a TCL array to memory locations and write the values");
941 int target_arch_state(struct target_s
*target
)
946 LOG_USER("No target has been configured");
950 LOG_USER("target state: %s",
951 Jim_Nvp_value2name_simple(nvp_target_state
,target
->state
)->name
);
953 if (target
->state
!=TARGET_HALTED
)
956 retval
=target
->type
->arch_state(target
);
960 /* Single aligned words are guaranteed to use 16 or 32 bit access
961 * mode respectively, otherwise data is handled as quickly as
964 int target_write_buffer(struct target_s
*target
, u32 address
, u32 size
, u8
*buffer
)
967 LOG_DEBUG("writing buffer of %i byte at 0x%8.8x", size
, address
);
969 if (!target
->type
->examined
)
971 LOG_ERROR("Target not examined yet");
975 if ((address
+ size
- 1) < address
)
977 /* GDB can request this when e.g. PC is 0xfffffffc*/
978 LOG_ERROR("address+size wrapped(0x%08x, 0x%08x)", address
, size
);
982 if (((address
% 2) == 0) && (size
== 2))
984 return target
->type
->write_memory(target
, address
, 2, 1, buffer
);
987 /* handle unaligned head bytes */
990 int unaligned
= 4 - (address
% 4);
992 if (unaligned
> size
)
995 if ((retval
= target
->type
->write_memory(target
, address
, 1, unaligned
, buffer
)) != ERROR_OK
)
999 address
+= unaligned
;
1003 /* handle aligned words */
1006 int aligned
= size
- (size
% 4);
1008 /* use bulk writes above a certain limit. This may have to be changed */
1011 if ((retval
= target
->type
->bulk_write_memory(target
, address
, aligned
/ 4, buffer
)) != ERROR_OK
)
1016 if ((retval
= target
->type
->write_memory(target
, address
, 4, aligned
/ 4, buffer
)) != ERROR_OK
)
1025 /* handle tail writes of less than 4 bytes */
1028 if ((retval
= target
->type
->write_memory(target
, address
, 1, size
, buffer
)) != ERROR_OK
)
1035 /* Single aligned words are guaranteed to use 16 or 32 bit access
1036 * mode respectively, otherwise data is handled as quickly as
1039 int target_read_buffer(struct target_s
*target
, u32 address
, u32 size
, u8
*buffer
)
1042 LOG_DEBUG("reading buffer of %i byte at 0x%8.8x", size
, address
);
1044 if (!target
->type
->examined
)
1046 LOG_ERROR("Target not examined yet");
1050 if ((address
+ size
- 1) < address
)
1052 /* GDB can request this when e.g. PC is 0xfffffffc*/
1053 LOG_ERROR("address+size wrapped(0x%08x, 0x%08x)", address
, size
);
1057 if (((address
% 2) == 0) && (size
== 2))
1059 return target
->type
->read_memory(target
, address
, 2, 1, buffer
);
1062 /* handle unaligned head bytes */
1065 int unaligned
= 4 - (address
% 4);
1067 if (unaligned
> size
)
1070 if ((retval
= target
->type
->read_memory(target
, address
, 1, unaligned
, buffer
)) != ERROR_OK
)
1073 buffer
+= unaligned
;
1074 address
+= unaligned
;
1078 /* handle aligned words */
1081 int aligned
= size
- (size
% 4);
1083 if ((retval
= target
->type
->read_memory(target
, address
, 4, aligned
/ 4, buffer
)) != ERROR_OK
)
1091 /* handle tail writes of less than 4 bytes */
1094 if ((retval
= target
->type
->read_memory(target
, address
, 1, size
, buffer
)) != ERROR_OK
)
1101 int target_checksum_memory(struct target_s
*target
, u32 address
, u32 size
, u32
* crc
)
1107 if (!target
->type
->examined
)
1109 LOG_ERROR("Target not examined yet");
1113 if ((retval
= target
->type
->checksum_memory(target
, address
,
1114 size
, &checksum
)) != ERROR_OK
)
1116 buffer
= malloc(size
);
1119 LOG_ERROR("error allocating buffer for section (%d bytes)", size
);
1120 return ERROR_INVALID_ARGUMENTS
;
1122 retval
= target_read_buffer(target
, address
, size
, buffer
);
1123 if (retval
!= ERROR_OK
)
1129 /* convert to target endianess */
1130 for (i
= 0; i
< (size
/sizeof(u32
)); i
++)
1133 target_data
= target_buffer_get_u32(target
, &buffer
[i
*sizeof(u32
)]);
1134 target_buffer_set_u32(target
, &buffer
[i
*sizeof(u32
)], target_data
);
1137 retval
= image_calculate_checksum( buffer
, size
, &checksum
);
1146 int target_blank_check_memory(struct target_s
*target
, u32 address
, u32 size
, u32
* blank
)
1149 if (!target
->type
->examined
)
1151 LOG_ERROR("Target not examined yet");
1155 if (target
->type
->blank_check_memory
== 0)
1156 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1158 retval
= target
->type
->blank_check_memory(target
, address
, size
, blank
);
1163 int target_read_u32(struct target_s
*target
, u32 address
, u32
*value
)
1166 if (!target
->type
->examined
)
1168 LOG_ERROR("Target not examined yet");
1172 int retval
= target
->type
->read_memory(target
, address
, 4, 1, value_buf
);
1174 if (retval
== ERROR_OK
)
1176 *value
= target_buffer_get_u32(target
, value_buf
);
1177 LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address
, *value
);
1182 LOG_DEBUG("address: 0x%8.8x failed", address
);
1188 int target_read_u16(struct target_s
*target
, u32 address
, u16
*value
)
1191 if (!target
->type
->examined
)
1193 LOG_ERROR("Target not examined yet");
1197 int retval
= target
->type
->read_memory(target
, address
, 2, 1, value_buf
);
1199 if (retval
== ERROR_OK
)
1201 *value
= target_buffer_get_u16(target
, value_buf
);
1202 LOG_DEBUG("address: 0x%8.8x, value: 0x%4.4x", address
, *value
);
1207 LOG_DEBUG("address: 0x%8.8x failed", address
);
1213 int target_read_u8(struct target_s
*target
, u32 address
, u8
*value
)
1215 int retval
= target
->type
->read_memory(target
, address
, 1, 1, value
);
1216 if (!target
->type
->examined
)
1218 LOG_ERROR("Target not examined yet");
1222 if (retval
== ERROR_OK
)
1224 LOG_DEBUG("address: 0x%8.8x, value: 0x%2.2x", address
, *value
);
1229 LOG_DEBUG("address: 0x%8.8x failed", address
);
1235 int target_write_u32(struct target_s
*target
, u32 address
, u32 value
)
1239 if (!target
->type
->examined
)
1241 LOG_ERROR("Target not examined yet");
1245 LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address
, value
);
1247 target_buffer_set_u32(target
, value_buf
, value
);
1248 if ((retval
= target
->type
->write_memory(target
, address
, 4, 1, value_buf
)) != ERROR_OK
)
1250 LOG_DEBUG("failed: %i", retval
);
1256 int target_write_u16(struct target_s
*target
, u32 address
, u16 value
)
1260 if (!target
->type
->examined
)
1262 LOG_ERROR("Target not examined yet");
1266 LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address
, value
);
1268 target_buffer_set_u16(target
, value_buf
, value
);
1269 if ((retval
= target
->type
->write_memory(target
, address
, 2, 1, value_buf
)) != ERROR_OK
)
1271 LOG_DEBUG("failed: %i", retval
);
1277 int target_write_u8(struct target_s
*target
, u32 address
, u8 value
)
1280 if (!target
->type
->examined
)
1282 LOG_ERROR("Target not examined yet");
1286 LOG_DEBUG("address: 0x%8.8x, value: 0x%2.2x", address
, value
);
1288 if ((retval
= target
->type
->write_memory(target
, address
, 1, 1, &value
)) != ERROR_OK
)
1290 LOG_DEBUG("failed: %i", retval
);
1296 int target_register_user_commands(struct command_context_s
*cmd_ctx
)
1298 int retval
= ERROR_OK
;
1299 register_command(cmd_ctx
, NULL
, "reg", handle_reg_command
, COMMAND_EXEC
, "display or set a register");
1300 register_command(cmd_ctx
, NULL
, "poll", handle_poll_command
, COMMAND_EXEC
, "poll target state");
1301 register_command(cmd_ctx
, NULL
, "wait_halt", handle_wait_halt_command
, COMMAND_EXEC
, "wait for target halt [time (s)]");
1302 register_command(cmd_ctx
, NULL
, "halt", handle_halt_command
, COMMAND_EXEC
, "halt target");
1303 register_command(cmd_ctx
, NULL
, "resume", handle_resume_command
, COMMAND_EXEC
, "resume target [addr]");
1304 register_command(cmd_ctx
, NULL
, "step", handle_step_command
, COMMAND_EXEC
, "step one instruction from current PC or [addr]");
1305 register_command(cmd_ctx
, NULL
, "reset", handle_reset_command
, COMMAND_EXEC
, "reset target [run|halt|init] - default is run");
1306 register_command(cmd_ctx
, NULL
, "soft_reset_halt", handle_soft_reset_halt_command
, COMMAND_EXEC
, "halt the target and do a soft reset");
1308 register_command(cmd_ctx
, NULL
, "mdw", handle_md_command
, COMMAND_EXEC
, "display memory words <addr> [count]");
1309 register_command(cmd_ctx
, NULL
, "mdh", handle_md_command
, COMMAND_EXEC
, "display memory half-words <addr> [count]");
1310 register_command(cmd_ctx
, NULL
, "mdb", handle_md_command
, COMMAND_EXEC
, "display memory bytes <addr> [count]");
1312 register_command(cmd_ctx
, NULL
, "mww", handle_mw_command
, COMMAND_EXEC
, "write memory word <addr> <value> [count]");
1313 register_command(cmd_ctx
, NULL
, "mwh", handle_mw_command
, COMMAND_EXEC
, "write memory half-word <addr> <value> [count]");
1314 register_command(cmd_ctx
, NULL
, "mwb", handle_mw_command
, COMMAND_EXEC
, "write memory byte <addr> <value> [count]");
1316 register_command(cmd_ctx
, NULL
, "bp", handle_bp_command
, COMMAND_EXEC
, "set breakpoint <address> <length> [hw]");
1317 register_command(cmd_ctx
, NULL
, "rbp", handle_rbp_command
, COMMAND_EXEC
, "remove breakpoint <adress>");
1318 register_command(cmd_ctx
, NULL
, "wp", handle_wp_command
, COMMAND_EXEC
, "set watchpoint <address> <length> <r/w/a> [value] [mask]");
1319 register_command(cmd_ctx
, NULL
, "rwp", handle_rwp_command
, COMMAND_EXEC
, "remove watchpoint <adress>");
1321 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]");
1322 register_command(cmd_ctx
, NULL
, "dump_image", handle_dump_image_command
, COMMAND_EXEC
, "dump_image <file> <address> <size>");
1323 register_command(cmd_ctx
, NULL
, "verify_image", handle_verify_image_command
, COMMAND_EXEC
, "verify_image <file> [offset] [type]");
1325 if((retval
= target_request_register_commands(cmd_ctx
)) != ERROR_OK
)
1327 if((retval
= trace_register_commands(cmd_ctx
)) != ERROR_OK
)
1333 int handle_targets_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1336 target_t
*target
= all_targets
;
1340 /* try as tcltarget name */
1341 for( target
= all_targets
; target
; target
= target
->next
){
1342 if( target
->cmd_name
){
1343 if( 0 == strcmp( args
[0], target
->cmd_name
) ){
1349 /* no match, try as number */
1351 int num
= strtoul(args
[0], &cp
, 0 );
1353 /* then it was not a number */
1354 command_print( cmd_ctx
, "Target: %s unknown, try one of:\n", args
[0] );
1358 target
= get_target_by_num( num
);
1359 if( target
== NULL
){
1360 command_print(cmd_ctx
,"Target: %s is unknown, try one of:\n", args
[0] );
1364 cmd_ctx
->current_target
= target
->target_number
;
1369 target
= all_targets
;
1370 command_print(cmd_ctx
, " CmdName Type Endian AbsChainPos Name State ");
1371 command_print(cmd_ctx
, "-- ---------- ---------- ---------- ----------- ------------- ----------");
1374 /* XX: abcdefghij abcdefghij abcdefghij abcdefghij */
1375 command_print(cmd_ctx
, "%2d: %-10s %-10s %-10s %10d %14s %s",
1376 target
->target_number
,
1379 Jim_Nvp_value2name_simple( nvp_target_endian
, target
->endianness
)->name
,
1380 target
->tap
->abs_chain_position
,
1381 target
->tap
->dotted_name
,
1382 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
1383 target
= target
->next
;
1389 /* every 300ms we check for reset & powerdropout and issue a "reset halt" if so. */
1391 static int powerDropout
;
1392 static int srstAsserted
;
1394 static int runPowerRestore
;
1395 static int runPowerDropout
;
1396 static int runSrstAsserted
;
1397 static int runSrstDeasserted
;
1399 static int sense_handler(void)
1401 static int prevSrstAsserted
= 0;
1402 static int prevPowerdropout
= 0;
1405 if ((retval
=jtag_power_dropout(&powerDropout
))!=ERROR_OK
)
1409 powerRestored
= prevPowerdropout
&& !powerDropout
;
1412 runPowerRestore
= 1;
1415 long long current
= timeval_ms();
1416 static long long lastPower
= 0;
1417 int waitMore
= lastPower
+ 2000 > current
;
1418 if (powerDropout
&& !waitMore
)
1420 runPowerDropout
= 1;
1421 lastPower
= current
;
1424 if ((retval
=jtag_srst_asserted(&srstAsserted
))!=ERROR_OK
)
1428 srstDeasserted
= prevSrstAsserted
&& !srstAsserted
;
1430 static long long lastSrst
= 0;
1431 waitMore
= lastSrst
+ 2000 > current
;
1432 if (srstDeasserted
&& !waitMore
)
1434 runSrstDeasserted
= 1;
1438 if (!prevSrstAsserted
&& srstAsserted
)
1440 runSrstAsserted
= 1;
1443 prevSrstAsserted
= srstAsserted
;
1444 prevPowerdropout
= powerDropout
;
1446 if (srstDeasserted
|| powerRestored
)
1448 /* Other than logging the event we can't do anything here.
1449 * Issuing a reset is a particularly bad idea as we might
1450 * be inside a reset already.
1457 /* process target state changes */
1458 int handle_target(void *priv
)
1460 int retval
= ERROR_OK
;
1462 /* we do not want to recurse here... */
1463 static int recursive
= 0;
1468 /* danger! running these procedures can trigger srst assertions and power dropouts.
1469 * We need to avoid an infinite loop/recursion here and we do that by
1470 * clearing the flags after running these events.
1472 int did_something
= 0;
1473 if (runSrstAsserted
)
1475 Jim_Eval( interp
, "srst_asserted");
1478 if (runSrstDeasserted
)
1480 Jim_Eval( interp
, "srst_deasserted");
1483 if (runPowerDropout
)
1485 Jim_Eval( interp
, "power_dropout");
1488 if (runPowerRestore
)
1490 Jim_Eval( interp
, "power_restore");
1496 /* clear detect flags */
1500 /* clear action flags */
1503 runSrstDeasserted
=0;
1510 target_t
*target
= all_targets
;
1515 /* only poll target if we've got power and srst isn't asserted */
1516 if (target_continous_poll
&&!powerDropout
&&!srstAsserted
)
1518 /* polling may fail silently until the target has been examined */
1519 if((retval
= target_poll(target
)) != ERROR_OK
)
1523 target
= target
->next
;
1529 int handle_reg_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1538 target
= get_current_target(cmd_ctx
);
1540 /* list all available registers for the current target */
1543 reg_cache_t
*cache
= target
->reg_cache
;
1549 for (i
= 0; i
< cache
->num_regs
; i
++)
1551 value
= buf_to_str(cache
->reg_list
[i
].value
, cache
->reg_list
[i
].size
, 16);
1552 command_print(cmd_ctx
, "(%i) %s (/%i): 0x%s (dirty: %i, valid: %i)", count
++, cache
->reg_list
[i
].name
, cache
->reg_list
[i
].size
, value
, cache
->reg_list
[i
].dirty
, cache
->reg_list
[i
].valid
);
1555 cache
= cache
->next
;
1561 /* access a single register by its ordinal number */
1562 if ((args
[0][0] >= '0') && (args
[0][0] <= '9'))
1564 int num
= strtoul(args
[0], NULL
, 0);
1565 reg_cache_t
*cache
= target
->reg_cache
;
1571 for (i
= 0; i
< cache
->num_regs
; i
++)
1575 reg
= &cache
->reg_list
[i
];
1581 cache
= cache
->next
;
1586 command_print(cmd_ctx
, "%i is out of bounds, the current target has only %i registers (0 - %i)", num
, count
, count
- 1);
1589 } else /* access a single register by its name */
1591 reg
= register_get_by_name(target
->reg_cache
, args
[0], 1);
1595 command_print(cmd_ctx
, "register %s not found in current target", args
[0]);
1600 /* display a register */
1601 if ((argc
== 1) || ((argc
== 2) && !((args
[1][0] >= '0') && (args
[1][0] <= '9'))))
1603 if ((argc
== 2) && (strcmp(args
[1], "force") == 0))
1606 if (reg
->valid
== 0)
1608 reg_arch_type_t
*arch_type
= register_get_arch_type(reg
->arch_type
);
1609 arch_type
->get(reg
);
1611 value
= buf_to_str(reg
->value
, reg
->size
, 16);
1612 command_print(cmd_ctx
, "%s (/%i): 0x%s", reg
->name
, reg
->size
, value
);
1617 /* set register value */
1620 u8
*buf
= malloc(CEIL(reg
->size
, 8));
1621 str_to_buf(args
[1], strlen(args
[1]), buf
, reg
->size
, 0);
1623 reg_arch_type_t
*arch_type
= register_get_arch_type(reg
->arch_type
);
1624 arch_type
->set(reg
, buf
);
1626 value
= buf_to_str(reg
->value
, reg
->size
, 16);
1627 command_print(cmd_ctx
, "%s (/%i): 0x%s", reg
->name
, reg
->size
, value
);
1635 command_print(cmd_ctx
, "usage: reg <#|name> [value]");
1640 int handle_poll_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1642 int retval
= ERROR_OK
;
1643 target_t
*target
= get_current_target(cmd_ctx
);
1647 if((retval
= target_poll(target
)) != ERROR_OK
)
1649 if((retval
= target_arch_state(target
)) != ERROR_OK
)
1655 if (strcmp(args
[0], "on") == 0)
1657 target_continous_poll
= 1;
1659 else if (strcmp(args
[0], "off") == 0)
1661 target_continous_poll
= 0;
1665 command_print(cmd_ctx
, "arg is \"on\" or \"off\"");
1669 return ERROR_COMMAND_SYNTAX_ERROR
;
1675 int handle_wait_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1683 ms
= strtoul(args
[0], &end
, 0) * 1000;
1686 command_print(cmd_ctx
, "usage: %s [seconds]", cmd
);
1690 target_t
*target
= get_current_target(cmd_ctx
);
1692 return target_wait_state(target
, TARGET_HALTED
, ms
);
1695 int target_wait_state(target_t
*target
, enum target_state state
, int ms
)
1698 struct timeval timeout
, now
;
1700 gettimeofday(&timeout
, NULL
);
1701 timeval_add_time(&timeout
, 0, ms
* 1000);
1705 if ((retval
=target_poll(target
))!=ERROR_OK
)
1708 if (target
->state
== state
)
1715 LOG_DEBUG("waiting for target %s...",
1716 Jim_Nvp_value2name_simple(nvp_target_state
,state
)->name
);
1719 gettimeofday(&now
, NULL
);
1720 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
) && (now
.tv_usec
>= timeout
.tv_usec
)))
1722 LOG_ERROR("timed out while waiting for target %s",
1723 Jim_Nvp_value2name_simple(nvp_target_state
,state
)->name
);
1731 int handle_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1734 target_t
*target
= get_current_target(cmd_ctx
);
1738 if ((retval
= target_halt(target
)) != ERROR_OK
)
1743 return handle_wait_halt_command(cmd_ctx
, cmd
, args
, argc
);
1746 int handle_soft_reset_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1748 target_t
*target
= get_current_target(cmd_ctx
);
1750 LOG_USER("requesting target halt and executing a soft reset");
1752 target
->type
->soft_reset_halt(target
);
1757 int handle_reset_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1760 enum target_reset_mode reset_mode
= RESET_RUN
;
1764 n
= Jim_Nvp_name2value_simple( nvp_reset_modes
, args
[0] );
1765 if( (n
->name
== NULL
) || (n
->value
== RESET_UNKNOWN
) ){
1766 return ERROR_COMMAND_SYNTAX_ERROR
;
1768 reset_mode
= n
->value
;
1771 /* reset *all* targets */
1772 return target_process_reset(cmd_ctx
, reset_mode
);
1776 int handle_resume_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1779 target_t
*target
= get_current_target(cmd_ctx
);
1781 target_handle_event( target
, TARGET_EVENT_OLD_pre_resume
);
1784 retval
= target_resume(target
, 1, 0, 1, 0); /* current pc, addr = 0, handle breakpoints, not debugging */
1786 retval
= target_resume(target
, 0, strtoul(args
[0], NULL
, 0), 1, 0); /* addr = args[0], handle breakpoints, not debugging */
1789 retval
= ERROR_COMMAND_SYNTAX_ERROR
;
1795 int handle_step_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1797 target_t
*target
= get_current_target(cmd_ctx
);
1802 return target
->type
->step(target
, 1, 0, 1); /* current pc, addr = 0, handle breakpoints */
1805 return target
->type
->step(target
, 0, strtoul(args
[0], NULL
, 0), 1); /* addr = args[0], handle breakpoints */
1810 int handle_md_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1812 const int line_bytecnt
= 32;
1825 target_t
*target
= get_current_target(cmd_ctx
);
1831 count
= strtoul(args
[1], NULL
, 0);
1833 address
= strtoul(args
[0], NULL
, 0);
1838 size
= 4; line_modulo
= line_bytecnt
/ 4;
1841 size
= 2; line_modulo
= line_bytecnt
/ 2;
1844 size
= 1; line_modulo
= line_bytecnt
/ 1;
1850 buffer
= calloc(count
, size
);
1851 retval
= target
->type
->read_memory(target
, address
, size
, count
, buffer
);
1852 if (retval
== ERROR_OK
)
1856 for (i
= 0; i
< count
; i
++)
1858 if (i
%line_modulo
== 0)
1859 output_len
+= snprintf(output
+ output_len
, 128 - output_len
, "0x%8.8x: ", address
+ (i
*size
));
1864 output_len
+= snprintf(output
+ output_len
, 128 - output_len
, "%8.8x ", target_buffer_get_u32(target
, &buffer
[i
*4]));
1867 output_len
+= snprintf(output
+ output_len
, 128 - output_len
, "%4.4x ", target_buffer_get_u16(target
, &buffer
[i
*2]));
1870 output_len
+= snprintf(output
+ output_len
, 128 - output_len
, "%2.2x ", buffer
[i
*1]);
1874 if ((i
%line_modulo
== line_modulo
-1) || (i
== count
- 1))
1876 command_print(cmd_ctx
, output
);
1887 int handle_mw_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1894 target_t
*target
= get_current_target(cmd_ctx
);
1897 if ((argc
< 2) || (argc
> 3))
1898 return ERROR_COMMAND_SYNTAX_ERROR
;
1900 address
= strtoul(args
[0], NULL
, 0);
1901 value
= strtoul(args
[1], NULL
, 0);
1903 count
= strtoul(args
[2], NULL
, 0);
1909 target_buffer_set_u32(target
, value_buf
, value
);
1913 target_buffer_set_u16(target
, value_buf
, value
);
1917 value_buf
[0] = value
;
1920 return ERROR_COMMAND_SYNTAX_ERROR
;
1922 for (i
=0; i
<count
; i
++)
1928 retval
= target
->type
->write_memory(target
, address
+ i
*wordsize
, 4, 1, value_buf
);
1931 retval
= target
->type
->write_memory(target
, address
+ i
*wordsize
, 2, 1, value_buf
);
1934 retval
= target
->type
->write_memory(target
, address
+ i
*wordsize
, 1, 1, value_buf
);
1941 if (retval
!=ERROR_OK
)
1951 int handle_load_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1957 u32 max_address
=0xffffffff;
1959 int retval
, retvaltemp
;
1963 duration_t duration
;
1964 char *duration_text
;
1966 target_t
*target
= get_current_target(cmd_ctx
);
1968 if ((argc
< 1)||(argc
> 5))
1970 return ERROR_COMMAND_SYNTAX_ERROR
;
1973 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
1976 image
.base_address_set
= 1;
1977 image
.base_address
= strtoul(args
[1], NULL
, 0);
1981 image
.base_address_set
= 0;
1985 image
.start_address_set
= 0;
1989 min_address
=strtoul(args
[3], NULL
, 0);
1993 max_address
=strtoul(args
[4], NULL
, 0)+min_address
;
1996 if (min_address
>max_address
)
1998 return ERROR_COMMAND_SYNTAX_ERROR
;
2001 duration_start_measure(&duration
);
2003 if (image_open(&image
, args
[0], (argc
>= 3) ? args
[2] : NULL
) != ERROR_OK
)
2010 for (i
= 0; i
< image
.num_sections
; i
++)
2012 buffer
= malloc(image
.sections
[i
].size
);
2015 command_print(cmd_ctx
, "error allocating buffer for section (%d bytes)", image
.sections
[i
].size
);
2019 if ((retval
= image_read_section(&image
, i
, 0x0, image
.sections
[i
].size
, buffer
, &buf_cnt
)) != ERROR_OK
)
2028 /* DANGER!!! beware of unsigned comparision here!!! */
2030 if ((image
.sections
[i
].base_address
+buf_cnt
>=min_address
)&&
2031 (image
.sections
[i
].base_address
<max_address
))
2033 if (image
.sections
[i
].base_address
<min_address
)
2035 /* clip addresses below */
2036 offset
+=min_address
-image
.sections
[i
].base_address
;
2040 if (image
.sections
[i
].base_address
+buf_cnt
>max_address
)
2042 length
-=(image
.sections
[i
].base_address
+buf_cnt
)-max_address
;
2045 if ((retval
= target_write_buffer(target
, image
.sections
[i
].base_address
+offset
, length
, buffer
+offset
)) != ERROR_OK
)
2050 image_size
+= length
;
2051 command_print(cmd_ctx
, "%u byte written at address 0x%8.8x", length
, image
.sections
[i
].base_address
+offset
);
2057 if((retvaltemp
= duration_stop_measure(&duration
, &duration_text
)) != ERROR_OK
)
2059 image_close(&image
);
2063 if (retval
==ERROR_OK
)
2065 command_print(cmd_ctx
, "downloaded %u byte in %s", image_size
, duration_text
);
2067 free(duration_text
);
2069 image_close(&image
);
2075 int handle_dump_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2082 int retval
=ERROR_OK
, retvaltemp
;
2084 duration_t duration
;
2085 char *duration_text
;
2087 target_t
*target
= get_current_target(cmd_ctx
);
2091 command_print(cmd_ctx
, "usage: dump_image <filename> <address> <size>");
2095 address
= strtoul(args
[1], NULL
, 0);
2096 size
= strtoul(args
[2], NULL
, 0);
2098 if ((address
& 3) || (size
& 3))
2100 command_print(cmd_ctx
, "only 32-bit aligned address and size are supported");
2104 if (fileio_open(&fileio
, args
[0], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
)
2109 duration_start_measure(&duration
);
2114 u32 this_run_size
= (size
> 560) ? 560 : size
;
2116 retval
= target
->type
->read_memory(target
, address
, 4, this_run_size
/ 4, buffer
);
2117 if (retval
!= ERROR_OK
)
2122 retval
= fileio_write(&fileio
, this_run_size
, buffer
, &size_written
);
2123 if (retval
!= ERROR_OK
)
2128 size
-= this_run_size
;
2129 address
+= this_run_size
;
2132 if((retvaltemp
= fileio_close(&fileio
)) != ERROR_OK
)
2135 if((retvaltemp
= duration_stop_measure(&duration
, &duration_text
)) != ERROR_OK
)
2138 if (retval
==ERROR_OK
)
2140 command_print(cmd_ctx
, "dumped %"PRIi64
" byte in %s", fileio
.size
, duration_text
);
2142 free(duration_text
);
2147 int handle_verify_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2153 int retval
, retvaltemp
;
2155 u32 mem_checksum
= 0;
2159 duration_t duration
;
2160 char *duration_text
;
2162 target_t
*target
= get_current_target(cmd_ctx
);
2166 return ERROR_COMMAND_SYNTAX_ERROR
;
2171 LOG_ERROR("no target selected");
2175 duration_start_measure(&duration
);
2179 image
.base_address_set
= 1;
2180 image
.base_address
= strtoul(args
[1], NULL
, 0);
2184 image
.base_address_set
= 0;
2185 image
.base_address
= 0x0;
2188 image
.start_address_set
= 0;
2190 if ((retval
=image_open(&image
, args
[0], (argc
== 3) ? args
[2] : NULL
)) != ERROR_OK
)
2197 for (i
= 0; i
< image
.num_sections
; i
++)
2199 buffer
= malloc(image
.sections
[i
].size
);
2202 command_print(cmd_ctx
, "error allocating buffer for section (%d bytes)", image
.sections
[i
].size
);
2205 if ((retval
= image_read_section(&image
, i
, 0x0, image
.sections
[i
].size
, buffer
, &buf_cnt
)) != ERROR_OK
)
2211 /* calculate checksum of image */
2212 image_calculate_checksum( buffer
, buf_cnt
, &checksum
);
2214 retval
= target_checksum_memory(target
, image
.sections
[i
].base_address
, buf_cnt
, &mem_checksum
);
2215 if( retval
!= ERROR_OK
)
2221 if( checksum
!= mem_checksum
)
2223 /* failed crc checksum, fall back to a binary compare */
2226 command_print(cmd_ctx
, "checksum mismatch - attempting binary compare");
2228 data
= (u8
*)malloc(buf_cnt
);
2230 /* Can we use 32bit word accesses? */
2232 int count
= buf_cnt
;
2233 if ((count
% 4) == 0)
2238 retval
= target
->type
->read_memory(target
, image
.sections
[i
].base_address
, size
, count
, data
);
2239 if (retval
== ERROR_OK
)
2242 for (t
= 0; t
< buf_cnt
; t
++)
2244 if (data
[t
] != buffer
[t
])
2246 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
]);
2263 image_size
+= buf_cnt
;
2267 if((retvaltemp
= duration_stop_measure(&duration
, &duration_text
)) != ERROR_OK
)
2269 image_close(&image
);
2273 if (retval
==ERROR_OK
)
2275 command_print(cmd_ctx
, "verified %u bytes in %s", image_size
, duration_text
);
2277 free(duration_text
);
2279 image_close(&image
);
2284 int handle_bp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2287 target_t
*target
= get_current_target(cmd_ctx
);
2291 breakpoint_t
*breakpoint
= target
->breakpoints
;
2295 if (breakpoint
->type
== BKPT_SOFT
)
2297 char* buf
= buf_to_str(breakpoint
->orig_instr
, breakpoint
->length
, 16);
2298 command_print(cmd_ctx
, "0x%8.8x, 0x%x, %i, 0x%s", breakpoint
->address
, breakpoint
->length
, breakpoint
->set
, buf
);
2303 command_print(cmd_ctx
, "0x%8.8x, 0x%x, %i", breakpoint
->address
, breakpoint
->length
, breakpoint
->set
);
2305 breakpoint
= breakpoint
->next
;
2313 length
= strtoul(args
[1], NULL
, 0);
2316 if (strcmp(args
[2], "hw") == 0)
2319 if ((retval
= breakpoint_add(target
, strtoul(args
[0], NULL
, 0), length
, hw
)) != ERROR_OK
)
2321 LOG_ERROR("Failure setting breakpoints");
2325 command_print(cmd_ctx
, "breakpoint added at address 0x%8.8x", strtoul(args
[0], NULL
, 0));
2330 command_print(cmd_ctx
, "usage: bp <address> <length> ['hw']");
2336 int handle_rbp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2338 target_t
*target
= get_current_target(cmd_ctx
);
2341 breakpoint_remove(target
, strtoul(args
[0], NULL
, 0));
2346 int handle_wp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2348 target_t
*target
= get_current_target(cmd_ctx
);
2353 watchpoint_t
*watchpoint
= target
->watchpoints
;
2357 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
);
2358 watchpoint
= watchpoint
->next
;
2363 enum watchpoint_rw type
= WPT_ACCESS
;
2364 u32 data_value
= 0x0;
2365 u32 data_mask
= 0xffffffff;
2381 command_print(cmd_ctx
, "usage: wp <address> <length> [r/w/a] [value] [mask]");
2387 data_value
= strtoul(args
[3], NULL
, 0);
2391 data_mask
= strtoul(args
[4], NULL
, 0);
2394 if ((retval
= watchpoint_add(target
, strtoul(args
[0], NULL
, 0),
2395 strtoul(args
[1], NULL
, 0), type
, data_value
, data_mask
)) != ERROR_OK
)
2397 LOG_ERROR("Failure setting breakpoints");
2402 command_print(cmd_ctx
, "usage: wp <address> <length> [r/w/a] [value] [mask]");
2408 int handle_rwp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2410 target_t
*target
= get_current_target(cmd_ctx
);
2413 watchpoint_remove(target
, strtoul(args
[0], NULL
, 0));
2418 int handle_virt2phys_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2421 target_t
*target
= get_current_target(cmd_ctx
);
2427 return ERROR_COMMAND_SYNTAX_ERROR
;
2429 va
= strtoul(args
[0], NULL
, 0);
2431 retval
= target
->type
->virt2phys(target
, va
, &pa
);
2432 if (retval
== ERROR_OK
)
2434 command_print(cmd_ctx
, "Physical address 0x%08x", pa
);
2438 /* lower levels will have logged a detailed error which is
2439 * forwarded to telnet/GDB session.
2445 static void writeLong(FILE *f
, int l
)
2450 char c
=(l
>>(i
*8))&0xff;
2451 fwrite(&c
, 1, 1, f
);
2456 static void writeString(FILE *f
, char *s
)
2458 fwrite(s
, 1, strlen(s
), f
);
2461 /* Dump a gmon.out histogram file. */
2462 static void writeGmon(u32
*samples
, int sampleNum
, char *filename
)
2465 FILE *f
=fopen(filename
, "w");
2468 fwrite("gmon", 1, 4, f
);
2469 writeLong(f
, 0x00000001); /* Version */
2470 writeLong(f
, 0); /* padding */
2471 writeLong(f
, 0); /* padding */
2472 writeLong(f
, 0); /* padding */
2474 fwrite("", 1, 1, f
); /* GMON_TAG_TIME_HIST */
2476 /* figure out bucket size */
2479 for (i
=0; i
<sampleNum
; i
++)
2491 int addressSpace
=(max
-min
+1);
2493 static int const maxBuckets
=256*1024; /* maximum buckets. */
2494 int length
=addressSpace
;
2495 if (length
> maxBuckets
)
2499 int *buckets
=malloc(sizeof(int)*length
);
2505 memset(buckets
, 0, sizeof(int)*length
);
2506 for (i
=0; i
<sampleNum
;i
++)
2508 u32 address
=samples
[i
];
2509 long long a
=address
-min
;
2510 long long b
=length
-1;
2511 long long c
=addressSpace
-1;
2512 int index
=(a
*b
)/c
; /* danger!!!! int32 overflows */
2516 /* append binary memory gmon.out &profile_hist_hdr ((char*)&profile_hist_hdr + sizeof(struct gmon_hist_hdr)) */
2517 writeLong(f
, min
); /* low_pc */
2518 writeLong(f
, max
); /* high_pc */
2519 writeLong(f
, length
); /* # of samples */
2520 writeLong(f
, 64000000); /* 64MHz */
2521 writeString(f
, "seconds");
2522 for (i
=0; i
<(15-strlen("seconds")); i
++)
2524 fwrite("", 1, 1, f
); /* padding */
2526 writeString(f
, "s");
2528 /*append binary memory gmon.out profile_hist_data (profile_hist_data + profile_hist_hdr.hist_size) */
2530 char *data
=malloc(2*length
);
2533 for (i
=0; i
<length
;i
++)
2542 data
[i
*2+1]=(val
>>8)&0xff;
2545 fwrite(data
, 1, length
*2, f
);
2555 /* profiling samples the CPU PC as quickly as OpenOCD is able, which will be used as a random sampling of PC */
2556 int handle_profile_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2558 target_t
*target
= get_current_target(cmd_ctx
);
2559 struct timeval timeout
, now
;
2561 gettimeofday(&timeout
, NULL
);
2564 return ERROR_COMMAND_SYNTAX_ERROR
;
2567 timeval_add_time(&timeout
, strtoul(args
[0], &end
, 0), 0);
2573 command_print(cmd_ctx
, "Starting profiling. Halting and resuming the target as often as we can...");
2575 static const int maxSample
=10000;
2576 u32
*samples
=malloc(sizeof(u32
)*maxSample
);
2581 int retval
=ERROR_OK
;
2582 /* hopefully it is safe to cache! We want to stop/restart as quickly as possible. */
2583 reg_t
*reg
= register_get_by_name(target
->reg_cache
, "pc", 1);
2587 target_poll(target
);
2588 if (target
->state
== TARGET_HALTED
)
2590 u32 t
=*((u32
*)reg
->value
);
2591 samples
[numSamples
++]=t
;
2592 retval
= target_resume(target
, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */
2593 target_poll(target
);
2594 alive_sleep(10); /* sleep 10ms, i.e. <100 samples/second. */
2595 } else if (target
->state
== TARGET_RUNNING
)
2597 /* We want to quickly sample the PC. */
2598 if((retval
= target_halt(target
)) != ERROR_OK
)
2605 command_print(cmd_ctx
, "Target not halted or running");
2609 if (retval
!=ERROR_OK
)
2614 gettimeofday(&now
, NULL
);
2615 if ((numSamples
>=maxSample
) || ((now
.tv_sec
>= timeout
.tv_sec
) && (now
.tv_usec
>= timeout
.tv_usec
)))
2617 command_print(cmd_ctx
, "Profiling completed. %d samples.", numSamples
);
2618 if((retval
= target_poll(target
)) != ERROR_OK
)
2623 if (target
->state
== TARGET_HALTED
)
2625 target_resume(target
, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */
2627 if((retval
= target_poll(target
)) != ERROR_OK
)
2632 writeGmon(samples
, numSamples
, args
[1]);
2633 command_print(cmd_ctx
, "Wrote %s", args
[1]);
2642 static int new_int_array_element(Jim_Interp
* interp
, const char *varname
, int idx
, u32 val
)
2645 Jim_Obj
*nameObjPtr
, *valObjPtr
;
2648 namebuf
= alloc_printf("%s(%d)", varname
, idx
);
2652 nameObjPtr
= Jim_NewStringObj(interp
, namebuf
, -1);
2653 valObjPtr
= Jim_NewIntObj(interp
, val
);
2654 if (!nameObjPtr
|| !valObjPtr
)
2660 Jim_IncrRefCount(nameObjPtr
);
2661 Jim_IncrRefCount(valObjPtr
);
2662 result
= Jim_SetVariable(interp
, nameObjPtr
, valObjPtr
);
2663 Jim_DecrRefCount(interp
, nameObjPtr
);
2664 Jim_DecrRefCount(interp
, valObjPtr
);
2666 /* printf("%s(%d) <= 0%08x\n", varname, idx, val); */
2670 static int jim_mem2array(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
2672 command_context_t
*context
;
2675 context
= Jim_GetAssocData(interp
, "context");
2676 if (context
== NULL
)
2678 LOG_ERROR("mem2array: no command context");
2681 target
= get_current_target(context
);
2684 LOG_ERROR("mem2array: no current target");
2688 return target_mem2array(interp
, target
, argc
,argv
);
2691 static int target_mem2array(Jim_Interp
*interp
, target_t
*target
, int argc
, Jim_Obj
*const *argv
)
2699 const char *varname
;
2701 int i
, n
, e
, retval
;
2703 /* argv[1] = name of array to receive the data
2704 * argv[2] = desired width
2705 * argv[3] = memory address
2706 * argv[4] = count of times to read
2709 Jim_WrongNumArgs(interp
, 1, argv
, "varname width addr nelems");
2712 varname
= Jim_GetString(argv
[1], &len
);
2713 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
2715 e
= Jim_GetLong(interp
, argv
[2], &l
);
2721 e
= Jim_GetLong(interp
, argv
[3], &l
);
2726 e
= Jim_GetLong(interp
, argv
[4], &l
);
2742 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2743 Jim_AppendStrings( interp
, Jim_GetResult(interp
), "Invalid width param, must be 8/16/32", NULL
);
2747 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2748 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: zero width read?", NULL
);
2751 if ((addr
+ (len
* width
)) < addr
) {
2752 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2753 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: addr + len - wraps to zero?", NULL
);
2756 /* absurd transfer size? */
2758 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2759 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: absurd > 64K item request", NULL
);
2764 ((width
== 2) && ((addr
& 1) == 0)) ||
2765 ((width
== 4) && ((addr
& 3) == 0))) {
2769 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2770 sprintf(buf
, "mem2array address: 0x%08x is not aligned for %d byte reads", addr
, width
);
2771 Jim_AppendStrings(interp
, Jim_GetResult(interp
), buf
, NULL
);
2782 /* Slurp... in buffer size chunks */
2784 count
= len
; /* in objects.. */
2785 if (count
> (sizeof(buffer
)/width
)) {
2786 count
= (sizeof(buffer
)/width
);
2789 retval
= target
->type
->read_memory( target
, addr
, width
, count
, buffer
);
2790 if (retval
!= ERROR_OK
) {
2792 LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed", addr
, width
, count
);
2793 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2794 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: cannot read memory", NULL
);
2798 v
= 0; /* shut up gcc */
2799 for (i
= 0 ;i
< count
;i
++, n
++) {
2802 v
= target_buffer_get_u32(target
, &buffer
[i
*width
]);
2805 v
= target_buffer_get_u16(target
, &buffer
[i
*width
]);
2808 v
= buffer
[i
] & 0x0ff;
2811 new_int_array_element(interp
, varname
, n
, v
);
2817 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2822 static int get_int_array_element(Jim_Interp
* interp
, const char *varname
, int idx
, u32
*val
)
2825 Jim_Obj
*nameObjPtr
, *valObjPtr
;
2829 namebuf
= alloc_printf("%s(%d)", varname
, idx
);
2833 nameObjPtr
= Jim_NewStringObj(interp
, namebuf
, -1);
2840 Jim_IncrRefCount(nameObjPtr
);
2841 valObjPtr
= Jim_GetVariable(interp
, nameObjPtr
, JIM_ERRMSG
);
2842 Jim_DecrRefCount(interp
, nameObjPtr
);
2844 if (valObjPtr
== NULL
)
2847 result
= Jim_GetLong(interp
, valObjPtr
, &l
);
2848 /* printf("%s(%d) => 0%08x\n", varname, idx, val); */
2853 static int jim_array2mem(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
2855 command_context_t
*context
;
2858 context
= Jim_GetAssocData(interp
, "context");
2859 if (context
== NULL
){
2860 LOG_ERROR("array2mem: no command context");
2863 target
= get_current_target(context
);
2864 if (target
== NULL
){
2865 LOG_ERROR("array2mem: no current target");
2869 return target_array2mem( interp
,target
, argc
, argv
);
2872 static int target_array2mem(Jim_Interp
*interp
, target_t
*target
, int argc
, Jim_Obj
*const *argv
)
2880 const char *varname
;
2882 int i
, n
, e
, retval
;
2884 /* argv[1] = name of array to get the data
2885 * argv[2] = desired width
2886 * argv[3] = memory address
2887 * argv[4] = count to write
2890 Jim_WrongNumArgs(interp
, 1, argv
, "varname width addr nelems");
2893 varname
= Jim_GetString(argv
[1], &len
);
2894 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
2896 e
= Jim_GetLong(interp
, argv
[2], &l
);
2902 e
= Jim_GetLong(interp
, argv
[3], &l
);
2907 e
= Jim_GetLong(interp
, argv
[4], &l
);
2923 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2924 Jim_AppendStrings( interp
, Jim_GetResult(interp
), "Invalid width param, must be 8/16/32", NULL
);
2928 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2929 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: zero width read?", NULL
);
2932 if ((addr
+ (len
* width
)) < addr
) {
2933 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2934 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: addr + len - wraps to zero?", NULL
);
2937 /* absurd transfer size? */
2939 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2940 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: absurd > 64K item request", NULL
);
2945 ((width
== 2) && ((addr
& 1) == 0)) ||
2946 ((width
== 4) && ((addr
& 3) == 0))) {
2950 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2951 sprintf(buf
, "array2mem address: 0x%08x is not aligned for %d byte reads", addr
, width
);
2952 Jim_AppendStrings(interp
, Jim_GetResult(interp
), buf
, NULL
);
2963 /* Slurp... in buffer size chunks */
2965 count
= len
; /* in objects.. */
2966 if (count
> (sizeof(buffer
)/width
)) {
2967 count
= (sizeof(buffer
)/width
);
2970 v
= 0; /* shut up gcc */
2971 for (i
= 0 ;i
< count
;i
++, n
++) {
2972 get_int_array_element(interp
, varname
, n
, &v
);
2975 target_buffer_set_u32(target
, &buffer
[i
*width
], v
);
2978 target_buffer_set_u16(target
, &buffer
[i
*width
], v
);
2981 buffer
[i
] = v
& 0x0ff;
2987 retval
= target
->type
->write_memory(target
, addr
, width
, count
, buffer
);
2988 if (retval
!= ERROR_OK
) {
2990 LOG_ERROR("array2mem: Write @ 0x%08x, w=%d, cnt=%d, failed", addr
, width
, count
);
2991 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2992 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: cannot read memory", NULL
);
2998 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
3003 void target_all_handle_event( enum target_event e
)
3007 LOG_DEBUG( "**all*targets: event: %d, %s",
3009 Jim_Nvp_value2name_simple( nvp_target_event
, e
)->name
);
3011 target
= all_targets
;
3013 target_handle_event( target
, e
);
3014 target
= target
->next
;
3018 void target_handle_event( target_t
*target
, enum target_event e
)
3020 target_event_action_t
*teap
;
3023 teap
= target
->event_action
;
3027 if( teap
->event
== e
){
3029 LOG_DEBUG( "target: (%d) %s (%s) event: %d (%s) action: %s\n",
3030 target
->target_number
,
3034 Jim_Nvp_value2name_simple( nvp_target_event
, e
)->name
,
3035 Jim_GetString( teap
->body
, NULL
) );
3036 if (Jim_EvalObj( interp
, teap
->body
)!=JIM_OK
)
3038 Jim_PrintErrorMessage(interp
);
3044 LOG_DEBUG( "event: %d %s - no action",
3046 Jim_Nvp_value2name_simple( nvp_target_event
, e
)->name
);
3050 enum target_cfg_param
{
3053 TCFG_WORK_AREA_VIRT
,
3054 TCFG_WORK_AREA_PHYS
,
3055 TCFG_WORK_AREA_SIZE
,
3056 TCFG_WORK_AREA_BACKUP
,
3059 TCFG_CHAIN_POSITION
,
3062 static Jim_Nvp nvp_config_opts
[] = {
3063 { .name
= "-type", .value
= TCFG_TYPE
},
3064 { .name
= "-event", .value
= TCFG_EVENT
},
3065 { .name
= "-work-area-virt", .value
= TCFG_WORK_AREA_VIRT
},
3066 { .name
= "-work-area-phys", .value
= TCFG_WORK_AREA_PHYS
},
3067 { .name
= "-work-area-size", .value
= TCFG_WORK_AREA_SIZE
},
3068 { .name
= "-work-area-backup", .value
= TCFG_WORK_AREA_BACKUP
},
3069 { .name
= "-endian" , .value
= TCFG_ENDIAN
},
3070 { .name
= "-variant", .value
= TCFG_VARIANT
},
3071 { .name
= "-chain-position", .value
= TCFG_CHAIN_POSITION
},
3073 { .name
= NULL
, .value
= -1 }
3076 static int target_configure( Jim_GetOptInfo
*goi
, target_t
*target
)
3084 /* parse config or cget options ... */
3085 while( goi
->argc
> 0 ){
3086 Jim_SetEmptyResult( goi
->interp
);
3087 /* Jim_GetOpt_Debug( goi ); */
3089 if( target
->type
->target_jim_configure
){
3090 /* target defines a configure function */
3091 /* target gets first dibs on parameters */
3092 e
= (*(target
->type
->target_jim_configure
))( target
, goi
);
3101 /* otherwise we 'continue' below */
3103 e
= Jim_GetOpt_Nvp( goi
, nvp_config_opts
, &n
);
3105 Jim_GetOpt_NvpUnknown( goi
, nvp_config_opts
, 0 );
3111 if( goi
->isconfigure
){
3112 Jim_SetResult_sprintf( goi
->interp
, "not setable: %s", n
->name
);
3116 if( goi
->argc
!= 0 ){
3117 Jim_WrongNumArgs( goi
->interp
, goi
->argc
, goi
->argv
, "NO PARAMS");
3121 Jim_SetResultString( goi
->interp
, target
->type
->name
, -1 );
3125 if( goi
->argc
== 0 ){
3126 Jim_WrongNumArgs( goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name? ...");
3130 e
= Jim_GetOpt_Nvp( goi
, nvp_target_event
, &n
);
3132 Jim_GetOpt_NvpUnknown( goi
, nvp_target_event
, 1 );
3136 if( goi
->isconfigure
){
3137 if( goi
->argc
!= 1 ){
3138 Jim_WrongNumArgs( goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name? ?EVENT-BODY?");
3142 if( goi
->argc
!= 0 ){
3143 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name?");
3149 target_event_action_t
*teap
;
3151 teap
= target
->event_action
;
3152 /* replace existing? */
3154 if( teap
->event
== n
->value
){
3160 if( goi
->isconfigure
){
3163 teap
= calloc( 1, sizeof(*teap
) );
3165 teap
->event
= n
->value
;
3166 Jim_GetOpt_Obj( goi
, &o
);
3168 Jim_DecrRefCount( interp
, teap
->body
);
3170 teap
->body
= Jim_DuplicateObj( goi
->interp
, o
);
3173 * Tcl/TK - "tk events" have a nice feature.
3174 * See the "BIND" command.
3175 * We should support that here.
3176 * You can specify %X and %Y in the event code.
3177 * The idea is: %T - target name.
3178 * The idea is: %N - target number
3179 * The idea is: %E - event name.
3181 Jim_IncrRefCount( teap
->body
);
3183 /* add to head of event list */
3184 teap
->next
= target
->event_action
;
3185 target
->event_action
= teap
;
3186 Jim_SetEmptyResult(goi
->interp
);
3190 Jim_SetEmptyResult( goi
->interp
);
3192 Jim_SetResult( goi
->interp
, Jim_DuplicateObj( goi
->interp
, teap
->body
) );
3199 case TCFG_WORK_AREA_VIRT
:
3200 if( goi
->isconfigure
){
3201 target_free_all_working_areas(target
);
3202 e
= Jim_GetOpt_Wide( goi
, &w
);
3206 target
->working_area_virt
= w
;
3208 if( goi
->argc
!= 0 ){
3212 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_virt
) );
3216 case TCFG_WORK_AREA_PHYS
:
3217 if( goi
->isconfigure
){
3218 target_free_all_working_areas(target
);
3219 e
= Jim_GetOpt_Wide( goi
, &w
);
3223 target
->working_area_phys
= w
;
3225 if( goi
->argc
!= 0 ){
3229 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_phys
) );
3233 case TCFG_WORK_AREA_SIZE
:
3234 if( goi
->isconfigure
){
3235 target_free_all_working_areas(target
);
3236 e
= Jim_GetOpt_Wide( goi
, &w
);
3240 target
->working_area_size
= w
;
3242 if( goi
->argc
!= 0 ){
3246 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_size
) );
3250 case TCFG_WORK_AREA_BACKUP
:
3251 if( goi
->isconfigure
){
3252 target_free_all_working_areas(target
);
3253 e
= Jim_GetOpt_Wide( goi
, &w
);
3257 /* make this exactly 1 or 0 */
3258 target
->backup_working_area
= (!!w
);
3260 if( goi
->argc
!= 0 ){
3264 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_size
) );
3265 /* loop for more e*/
3269 if( goi
->isconfigure
){
3270 e
= Jim_GetOpt_Nvp( goi
, nvp_target_endian
, &n
);
3272 Jim_GetOpt_NvpUnknown( goi
, nvp_target_endian
, 1 );
3275 target
->endianness
= n
->value
;
3277 if( goi
->argc
!= 0 ){
3281 n
= Jim_Nvp_value2name_simple( nvp_target_endian
, target
->endianness
);
3282 if( n
->name
== NULL
){
3283 target
->endianness
= TARGET_LITTLE_ENDIAN
;
3284 n
= Jim_Nvp_value2name_simple( nvp_target_endian
, target
->endianness
);
3286 Jim_SetResultString( goi
->interp
, n
->name
, -1 );
3291 if( goi
->isconfigure
){
3292 if( goi
->argc
< 1 ){
3293 Jim_SetResult_sprintf( goi
->interp
,
3298 if( target
->variant
){
3299 free((void *)(target
->variant
));
3301 e
= Jim_GetOpt_String( goi
, &cp
, NULL
);
3302 target
->variant
= strdup(cp
);
3304 if( goi
->argc
!= 0 ){
3308 Jim_SetResultString( goi
->interp
, target
->variant
,-1 );
3311 case TCFG_CHAIN_POSITION
:
3312 if( goi
->isconfigure
){
3315 target_free_all_working_areas(target
);
3316 e
= Jim_GetOpt_Obj( goi
, &o
);
3320 tap
= jtag_TapByJimObj( goi
->interp
, o
);
3324 /* make this exactly 1 or 0 */
3327 if( goi
->argc
!= 0 ){
3331 Jim_SetResultString( interp
, target
->tap
->dotted_name
, -1 );
3332 /* loop for more e*/
3335 } /* while( goi->argc ) */
3336 /* done - we return */
3340 /** this is the 'tcl' handler for the target specific command */
3341 static int tcl_target_func( Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
3349 struct command_context_s
*cmd_ctx
;
3356 TS_CMD_MWW
, TS_CMD_MWH
, TS_CMD_MWB
,
3357 TS_CMD_MDW
, TS_CMD_MDH
, TS_CMD_MDB
,
3358 TS_CMD_MRW
, TS_CMD_MRH
, TS_CMD_MRB
,
3359 TS_CMD_MEM2ARRAY
, TS_CMD_ARRAY2MEM
,
3367 TS_CMD_INVOKE_EVENT
,
3370 static const Jim_Nvp target_options
[] = {
3371 { .name
= "configure", .value
= TS_CMD_CONFIGURE
},
3372 { .name
= "cget", .value
= TS_CMD_CGET
},
3373 { .name
= "mww", .value
= TS_CMD_MWW
},
3374 { .name
= "mwh", .value
= TS_CMD_MWH
},
3375 { .name
= "mwb", .value
= TS_CMD_MWB
},
3376 { .name
= "mdw", .value
= TS_CMD_MDW
},
3377 { .name
= "mdh", .value
= TS_CMD_MDH
},
3378 { .name
= "mdb", .value
= TS_CMD_MDB
},
3379 { .name
= "mem2array", .value
= TS_CMD_MEM2ARRAY
},
3380 { .name
= "array2mem", .value
= TS_CMD_ARRAY2MEM
},
3381 { .name
= "eventlist", .value
= TS_CMD_EVENTLIST
},
3382 { .name
= "curstate", .value
= TS_CMD_CURSTATE
},
3384 { .name
= "arp_examine", .value
= TS_CMD_EXAMINE
},
3385 { .name
= "arp_poll", .value
= TS_CMD_POLL
},
3386 { .name
= "arp_reset", .value
= TS_CMD_RESET
},
3387 { .name
= "arp_halt", .value
= TS_CMD_HALT
},
3388 { .name
= "arp_waitstate", .value
= TS_CMD_WAITSTATE
},
3389 { .name
= "invoke-event", .value
= TS_CMD_INVOKE_EVENT
},
3391 { .name
= NULL
, .value
= -1 },
3394 /* go past the "command" */
3395 Jim_GetOpt_Setup( &goi
, interp
, argc
-1, argv
+1 );
3397 target
= Jim_CmdPrivData( goi
.interp
);
3398 cmd_ctx
= Jim_GetAssocData(goi
.interp
, "context");
3400 /* commands here are in an NVP table */
3401 e
= Jim_GetOpt_Nvp( &goi
, target_options
, &n
);
3403 Jim_GetOpt_NvpUnknown( &goi
, target_options
, 0 );
3406 /* Assume blank result */
3407 Jim_SetEmptyResult( goi
.interp
);
3410 case TS_CMD_CONFIGURE
:
3412 Jim_WrongNumArgs( goi
.interp
, goi
.argc
, goi
.argv
, "missing: -option VALUE ...");
3415 goi
.isconfigure
= 1;
3416 return target_configure( &goi
, target
);
3418 // some things take params
3420 Jim_WrongNumArgs( goi
.interp
, 0, goi
.argv
, "missing: ?-option?");
3423 goi
.isconfigure
= 0;
3424 return target_configure( &goi
, target
);
3432 * argv[3] = optional count.
3435 if( (goi
.argc
== 3) || (goi
.argc
== 4) ){
3439 Jim_SetResult_sprintf( goi
.interp
, "expected: %s ADDR DATA [COUNT]", n
->name
);
3443 e
= Jim_GetOpt_Wide( &goi
, &a
);
3448 e
= Jim_GetOpt_Wide( &goi
, &b
);
3453 e
= Jim_GetOpt_Wide( &goi
, &c
);
3463 target_buffer_set_u32( target
, target_buf
, b
);
3467 target_buffer_set_u16( target
, target_buf
, b
);
3471 target_buffer_set_u8( target
, target_buf
, b
);
3475 for( x
= 0 ; x
< c
; x
++ ){
3476 e
= target
->type
->write_memory( target
, a
, b
, 1, target_buf
);
3477 if( e
!= ERROR_OK
){
3478 Jim_SetResult_sprintf( interp
, "Error writing @ 0x%08x: %d\n", (int)(a
), e
);
3491 /* argv[0] = command
3493 * argv[2] = optional count
3495 if( (goi
.argc
== 2) || (goi
.argc
== 3) ){
3496 Jim_SetResult_sprintf( goi
.interp
, "expected: %s ADDR [COUNT]", n
->name
);
3499 e
= Jim_GetOpt_Wide( &goi
, &a
);
3504 e
= Jim_GetOpt_Wide( &goi
, &c
);
3511 b
= 1; /* shut up gcc */
3524 /* convert to "bytes" */
3526 /* count is now in 'BYTES' */
3532 e
= target
->type
->read_memory( target
, a
, b
, y
/ b
, target_buf
);
3533 if( e
!= ERROR_OK
){
3534 Jim_SetResult_sprintf( interp
, "error reading target @ 0x%08lx", (int)(a
) );
3538 Jim_fprintf( interp
, interp
->cookie_stdout
, "0x%08x ", (int)(a
) );
3541 for( x
= 0 ; (x
< 16) && (x
< y
) ; x
+= 4 ){
3542 z
= target_buffer_get_u32( target
, &(target_buf
[ x
* 4 ]) );
3543 Jim_fprintf( interp
, interp
->cookie_stdout
, "%08x ", (int)(z
) );
3545 for( ; (x
< 16) ; x
+= 4 ){
3546 Jim_fprintf( interp
, interp
->cookie_stdout
, " " );
3550 for( x
= 0 ; (x
< 16) && (x
< y
) ; x
+= 2 ){
3551 z
= target_buffer_get_u16( target
, &(target_buf
[ x
* 2 ]) );
3552 Jim_fprintf( interp
, interp
->cookie_stdout
, "%04x ", (int)(z
) );
3554 for( ; (x
< 16) ; x
+= 2 ){
3555 Jim_fprintf( interp
, interp
->cookie_stdout
, " " );
3560 for( x
= 0 ; (x
< 16) && (x
< y
) ; x
+= 1 ){
3561 z
= target_buffer_get_u8( target
, &(target_buf
[ x
* 4 ]) );
3562 Jim_fprintf( interp
, interp
->cookie_stdout
, "%02x ", (int)(z
) );
3564 for( ; (x
< 16) ; x
+= 1 ){
3565 Jim_fprintf( interp
, interp
->cookie_stdout
, " " );
3569 /* ascii-ify the bytes */
3570 for( x
= 0 ; x
< y
; x
++ ){
3571 if( (target_buf
[x
] >= 0x20) &&
3572 (target_buf
[x
] <= 0x7e) ){
3576 target_buf
[x
] = '.';
3581 target_buf
[x
] = ' ';
3586 /* print - with a newline */
3587 Jim_fprintf( interp
, interp
->cookie_stdout
, "%s\n", target_buf
);
3593 case TS_CMD_MEM2ARRAY
:
3594 return target_mem2array( goi
.interp
, target
, goi
.argc
, goi
.argv
);
3596 case TS_CMD_ARRAY2MEM
:
3597 return target_array2mem( goi
.interp
, target
, goi
.argc
, goi
.argv
);
3599 case TS_CMD_EXAMINE
:
3601 Jim_WrongNumArgs( goi
.interp
, 2, argv
, "[no parameters]");
3604 e
= target
->type
->examine( target
);
3605 if( e
!= ERROR_OK
){
3606 Jim_SetResult_sprintf( interp
, "examine-fails: %d", e
);
3612 Jim_WrongNumArgs( goi
.interp
, 2, argv
, "[no parameters]");
3615 if( !(target
->type
->examined
) ){
3616 e
= ERROR_TARGET_NOT_EXAMINED
;
3618 e
= target
->type
->poll( target
);
3620 if( e
!= ERROR_OK
){
3621 Jim_SetResult_sprintf( interp
, "poll-fails: %d", e
);
3628 if( goi
.argc
!= 2 ){
3629 Jim_WrongNumArgs( interp
, 2, argv
, "t|f|assert|deassert BOOL");
3632 e
= Jim_GetOpt_Nvp( &goi
, nvp_assert
, &n
);
3634 Jim_GetOpt_NvpUnknown( &goi
, nvp_assert
, 1 );
3637 /* the halt or not param */
3638 e
= Jim_GetOpt_Wide( &goi
, &a
);
3642 /* determine if we should halt or not. */
3643 target
->reset_halt
= !!a
;
3644 /* When this happens - all workareas are invalid. */
3645 target_free_all_working_areas_restore(target
, 0);
3648 if( n
->value
== NVP_ASSERT
){
3649 target
->type
->assert_reset( target
);
3651 target
->type
->deassert_reset( target
);
3656 Jim_WrongNumArgs( goi
.interp
, 0, argv
, "halt [no parameters]");
3659 target
->type
->halt( target
);
3661 case TS_CMD_WAITSTATE
:
3662 /* params: <name> statename timeoutmsecs */
3663 if( goi
.argc
!= 2 ){
3664 Jim_SetResult_sprintf( goi
.interp
, "%s STATENAME TIMEOUTMSECS", n
->name
);
3667 e
= Jim_GetOpt_Nvp( &goi
, nvp_target_state
, &n
);
3669 Jim_GetOpt_NvpUnknown( &goi
, nvp_target_state
,1 );
3672 e
= Jim_GetOpt_Wide( &goi
, &a
);
3676 e
= target_wait_state( target
, n
->value
, a
);
3677 if( e
!= ERROR_OK
){
3678 Jim_SetResult_sprintf( goi
.interp
,
3679 "target: %s wait %s fails (%d) %s",
3682 e
, target_strerror_safe(e
) );
3687 case TS_CMD_EVENTLIST
:
3688 /* List for human, Events defined for this target.
3689 * scripts/programs should use 'name cget -event NAME'
3692 target_event_action_t
*teap
;
3693 teap
= target
->event_action
;
3694 command_print( cmd_ctx
, "Event actions for target (%d) %s\n",
3695 target
->target_number
,
3697 command_print( cmd_ctx
, "%-25s | Body", "Event");
3698 command_print( cmd_ctx
, "------------------------- | ----------------------------------------");
3700 command_print( cmd_ctx
,
3702 Jim_Nvp_value2name_simple( nvp_target_event
, teap
->event
)->name
,
3703 Jim_GetString( teap
->body
, NULL
) );
3706 command_print( cmd_ctx
, "***END***");
3709 case TS_CMD_CURSTATE
:
3710 if( goi
.argc
!= 0 ){
3711 Jim_WrongNumArgs( goi
.interp
, 0, argv
, "[no parameters]");
3714 Jim_SetResultString( goi
.interp
,
3715 Jim_Nvp_value2name_simple(nvp_target_state
,target
->state
)->name
,-1);
3717 case TS_CMD_INVOKE_EVENT
:
3718 if( goi
.argc
!= 1 ){
3719 Jim_SetResult_sprintf( goi
.interp
, "%s ?EVENTNAME?",n
->name
);
3722 e
= Jim_GetOpt_Nvp( &goi
, nvp_target_event
, &n
);
3724 Jim_GetOpt_NvpUnknown( &goi
, nvp_target_event
, 1 );
3727 target_handle_event( target
, n
->value
);
3733 static int target_create( Jim_GetOptInfo
*goi
)
3742 struct command_context_s
*cmd_ctx
;
3744 cmd_ctx
= Jim_GetAssocData(goi
->interp
, "context");
3745 if( goi
->argc
< 3 ){
3746 Jim_WrongNumArgs( goi
->interp
, 1, goi
->argv
, "?name? ?type? ..options...");
3751 Jim_GetOpt_Obj( goi
, &new_cmd
);
3752 /* does this command exist? */
3753 cmd
= Jim_GetCommand( goi
->interp
, new_cmd
, JIM_ERRMSG
);
3755 cp
= Jim_GetString( new_cmd
, NULL
);
3756 Jim_SetResult_sprintf(goi
->interp
, "Command/target: %s Exists", cp
);
3761 e
= Jim_GetOpt_String( goi
, &cp2
, NULL
);
3763 /* now does target type exist */
3764 for( x
= 0 ; target_types
[x
] ; x
++ ){
3765 if( 0 == strcmp( cp
, target_types
[x
]->name
) ){
3770 if( target_types
[x
] == NULL
){
3771 Jim_SetResult_sprintf( goi
->interp
, "Unknown target type %s, try one of ", cp
);
3772 for( x
= 0 ; target_types
[x
] ; x
++ ){
3773 if( target_types
[x
+1] ){
3774 Jim_AppendStrings( goi
->interp
,
3775 Jim_GetResult(goi
->interp
),
3776 target_types
[x
]->name
,
3779 Jim_AppendStrings( goi
->interp
,
3780 Jim_GetResult(goi
->interp
),
3782 target_types
[x
]->name
,NULL
);
3789 target
= calloc(1,sizeof(target_t
));
3790 /* set target number */
3791 target
->target_number
= new_target_number();
3793 /* allocate memory for each unique target type */
3794 target
->type
= (target_type_t
*)calloc(1,sizeof(target_type_t
));
3796 memcpy( target
->type
, target_types
[x
], sizeof(target_type_t
));
3798 /* will be set by "-endian" */
3799 target
->endianness
= TARGET_ENDIAN_UNKNOWN
;
3801 target
->working_area
= 0x0;
3802 target
->working_area_size
= 0x0;
3803 target
->working_areas
= NULL
;
3804 target
->backup_working_area
= 0;
3806 target
->state
= TARGET_UNKNOWN
;
3807 target
->debug_reason
= DBG_REASON_UNDEFINED
;
3808 target
->reg_cache
= NULL
;
3809 target
->breakpoints
= NULL
;
3810 target
->watchpoints
= NULL
;
3811 target
->next
= NULL
;
3812 target
->arch_info
= NULL
;
3814 target
->display
= 1;
3816 /* initialize trace information */
3817 target
->trace_info
= malloc(sizeof(trace_t
));
3818 target
->trace_info
->num_trace_points
= 0;
3819 target
->trace_info
->trace_points_size
= 0;
3820 target
->trace_info
->trace_points
= NULL
;
3821 target
->trace_info
->trace_history_size
= 0;
3822 target
->trace_info
->trace_history
= NULL
;
3823 target
->trace_info
->trace_history_pos
= 0;
3824 target
->trace_info
->trace_history_overflowed
= 0;
3826 target
->dbgmsg
= NULL
;
3827 target
->dbg_msg_enabled
= 0;
3829 target
->endianness
= TARGET_ENDIAN_UNKNOWN
;
3831 /* Do the rest as "configure" options */
3832 goi
->isconfigure
= 1;
3833 e
= target_configure( goi
, target
);
3835 free( target
->type
);
3840 if( target
->endianness
== TARGET_ENDIAN_UNKNOWN
){
3841 /* default endian to little if not specified */
3842 target
->endianness
= TARGET_LITTLE_ENDIAN
;
3845 /* incase variant is not set */
3846 if (!target
->variant
)
3847 target
->variant
= strdup("");
3849 /* create the target specific commands */
3850 if( target
->type
->register_commands
){
3851 (*(target
->type
->register_commands
))( cmd_ctx
);
3853 if( target
->type
->target_create
){
3854 (*(target
->type
->target_create
))( target
, goi
->interp
);
3857 /* append to end of list */
3860 tpp
= &(all_targets
);
3862 tpp
= &( (*tpp
)->next
);
3867 cp
= Jim_GetString( new_cmd
, NULL
);
3868 target
->cmd_name
= strdup(cp
);
3870 /* now - create the new target name command */
3871 e
= Jim_CreateCommand( goi
->interp
,
3874 tcl_target_func
, /* C function */
3875 target
, /* private data */
3876 NULL
); /* no del proc */
3881 static int jim_target( Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
3885 struct command_context_s
*cmd_ctx
;
3889 /* TG = target generic */
3897 const char *target_cmds
[] = {
3898 "create", "types", "names", "current", "number",
3900 NULL
/* terminate */
3903 LOG_DEBUG("Target command params:");
3904 LOG_DEBUG(Jim_Debug_ArgvString( interp
, argc
, argv
) );
3906 cmd_ctx
= Jim_GetAssocData( interp
, "context" );
3908 Jim_GetOpt_Setup( &goi
, interp
, argc
-1, argv
+1 );
3910 if( goi
.argc
== 0 ){
3911 Jim_WrongNumArgs(interp
, 1, argv
, "missing: command ...");
3915 /* Jim_GetOpt_Debug( &goi ); */
3916 r
= Jim_GetOpt_Enum( &goi
, target_cmds
, &x
);
3923 Jim_Panic(goi
.interp
,"Why am I here?");
3925 case TG_CMD_CURRENT
:
3926 if( goi
.argc
!= 0 ){
3927 Jim_WrongNumArgs( goi
.interp
, 1, goi
.argv
, "Too many parameters");
3930 Jim_SetResultString( goi
.interp
, get_current_target( cmd_ctx
)->cmd_name
, -1 );
3933 if( goi
.argc
!= 0 ){
3934 Jim_WrongNumArgs( goi
.interp
, 1, goi
.argv
, "Too many parameters" );
3937 Jim_SetResult( goi
.interp
, Jim_NewListObj( goi
.interp
, NULL
, 0 ) );
3938 for( x
= 0 ; target_types
[x
] ; x
++ ){
3939 Jim_ListAppendElement( goi
.interp
,
3940 Jim_GetResult(goi
.interp
),
3941 Jim_NewStringObj( goi
.interp
, target_types
[x
]->name
, -1 ) );
3945 if( goi
.argc
!= 0 ){
3946 Jim_WrongNumArgs( goi
.interp
, 1, goi
.argv
, "Too many parameters" );
3949 Jim_SetResult( goi
.interp
, Jim_NewListObj( goi
.interp
, NULL
, 0 ) );
3950 target
= all_targets
;
3952 Jim_ListAppendElement( goi
.interp
,
3953 Jim_GetResult(goi
.interp
),
3954 Jim_NewStringObj( goi
.interp
, target
->cmd_name
, -1 ) );
3955 target
= target
->next
;
3960 Jim_WrongNumArgs( goi
.interp
, goi
.argc
, goi
.argv
, "?name ... config options ...");
3963 return target_create( &goi
);
3966 if( goi
.argc
!= 1 ){
3967 Jim_SetResult_sprintf( goi
.interp
, "expected: target number ?NUMBER?");
3970 e
= Jim_GetOpt_Wide( &goi
, &w
);
3976 t
= get_target_by_num(w
);
3978 Jim_SetResult_sprintf( goi
.interp
,"Target: number %d does not exist", (int)(w
));
3981 Jim_SetResultString( goi
.interp
, t
->cmd_name
, -1 );
3985 if( goi
.argc
!= 0 ){
3986 Jim_WrongNumArgs( goi
.interp
, 0, goi
.argv
, "<no parameters>");
3989 Jim_SetResult( goi
.interp
,
3990 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)