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" },
179 { .name
= "gdb-start", .value
= TARGET_EVENT_GDB_START
},
180 { .name
= "gdb-end", .value
= TARGET_EVENT_GDB_END
},
183 /* historical name */
185 { .value
= TARGET_EVENT_RESET_START
, .name
= "reset-start" },
187 { .value
= TARGET_EVENT_RESET_ASSERT_PRE
, .name
= "reset-assert-pre" },
188 { .value
= TARGET_EVENT_RESET_ASSERT_POST
, .name
= "reset-assert-post" },
189 { .value
= TARGET_EVENT_RESET_DEASSERT_PRE
, .name
= "reset-deassert-pre" },
190 { .value
= TARGET_EVENT_RESET_DEASSERT_POST
, .name
= "reset-deassert-post" },
191 { .value
= TARGET_EVENT_RESET_HALT_PRE
, .name
= "reset-halt-pre" },
192 { .value
= TARGET_EVENT_RESET_HALT_POST
, .name
= "reset-halt-post" },
193 { .value
= TARGET_EVENT_RESET_WAIT_PRE
, .name
= "reset-wait-pre" },
194 { .value
= TARGET_EVENT_RESET_WAIT_POST
, .name
= "reset-wait-post" },
195 { .value
= TARGET_EVENT_RESET_INIT
, .name
= "reset-init" },
196 { .value
= TARGET_EVENT_RESET_END
, .name
= "reset-end" },
202 { .value
= TARGET_EVENT_EXAMINE_START
, .name
= "examine-start" },
203 { .value
= TARGET_EVENT_EXAMINE_START
, .name
= "examine-end" },
206 { .value
= TARGET_EVENT_DEBUG_HALTED
, .name
= "debug-halted" },
207 { .value
= TARGET_EVENT_DEBUG_RESUMED
, .name
= "debug-resumed" },
209 { .value
= TARGET_EVENT_GDB_ATTACH
, .name
= "gdb-attach" },
210 { .value
= TARGET_EVENT_GDB_DETACH
, .name
= "gdb-detach" },
213 { .value
= TARGET_EVENT_GDB_FLASH_WRITE_START
, .name
= "gdb-flash-write-start" },
214 { .value
= TARGET_EVENT_GDB_FLASH_WRITE_END
, .name
= "gdb-flash-write-end" },
216 { .value
= TARGET_EVENT_GDB_FLASH_ERASE_START
, .name
= "gdb-flash-erase-start" },
217 { .value
= TARGET_EVENT_GDB_FLASH_ERASE_END
, .name
= "gdb-flash-erase-end" },
219 { .value
= TARGET_EVENT_RESUME_START
, .name
= "resume-start" },
220 { .value
= TARGET_EVENT_RESUMED
, .name
= "resume-ok" },
221 { .value
= TARGET_EVENT_RESUME_END
, .name
= "resume-end" },
223 { .name
= NULL
, .value
= -1 }
226 const Jim_Nvp nvp_target_state
[] = {
227 { .name
= "unknown", .value
= TARGET_UNKNOWN
},
228 { .name
= "running", .value
= TARGET_RUNNING
},
229 { .name
= "halted", .value
= TARGET_HALTED
},
230 { .name
= "reset", .value
= TARGET_RESET
},
231 { .name
= "debug-running", .value
= TARGET_DEBUG_RUNNING
},
232 { .name
= NULL
, .value
= -1 },
236 const Jim_Nvp nvp_target_debug_reason
[] = {
237 { .name
= "debug-request" , .value
= DBG_REASON_DBGRQ
},
238 { .name
= "breakpoint" , .value
= DBG_REASON_BREAKPOINT
},
239 { .name
= "watchpoint" , .value
= DBG_REASON_WATCHPOINT
},
240 { .name
= "watchpoint-and-breakpoint", .value
= DBG_REASON_WPTANDBKPT
},
241 { .name
= "single-step" , .value
= DBG_REASON_SINGLESTEP
},
242 { .name
= "target-not-halted" , .value
= DBG_REASON_NOTHALTED
},
243 { .name
= "undefined" , .value
= DBG_REASON_UNDEFINED
},
244 { .name
= NULL
, .value
= -1 },
248 const Jim_Nvp nvp_target_endian
[] = {
249 { .name
= "big", .value
= TARGET_BIG_ENDIAN
},
250 { .name
= "little", .value
= TARGET_LITTLE_ENDIAN
},
251 { .name
= "be", .value
= TARGET_BIG_ENDIAN
},
252 { .name
= "le", .value
= TARGET_LITTLE_ENDIAN
},
253 { .name
= NULL
, .value
= -1 },
256 const Jim_Nvp nvp_reset_modes
[] = {
257 { .name
= "unknown", .value
= RESET_UNKNOWN
},
258 { .name
= "run" , .value
= RESET_RUN
},
259 { .name
= "halt" , .value
= RESET_HALT
},
260 { .name
= "init" , .value
= RESET_INIT
},
261 { .name
= NULL
, .value
= -1 },
265 max_target_number( void )
273 if( x
< t
->target_number
){
274 x
= (t
->target_number
)+1;
281 /* determine the number of the new target */
283 new_target_number( void )
288 /* number is 0 based */
292 if( x
< t
->target_number
){
293 x
= t
->target_number
;
300 static int target_continous_poll
= 1;
302 /* read a u32 from a buffer in target memory endianness */
303 u32
target_buffer_get_u32(target_t
*target
, u8
*buffer
)
305 if (target
->endianness
== TARGET_LITTLE_ENDIAN
)
306 return le_to_h_u32(buffer
);
308 return be_to_h_u32(buffer
);
311 /* read a u16 from a buffer in target memory endianness */
312 u16
target_buffer_get_u16(target_t
*target
, u8
*buffer
)
314 if (target
->endianness
== TARGET_LITTLE_ENDIAN
)
315 return le_to_h_u16(buffer
);
317 return be_to_h_u16(buffer
);
320 /* read a u8 from a buffer in target memory endianness */
321 u8
target_buffer_get_u8(target_t
*target
, u8
*buffer
)
323 return *buffer
& 0x0ff;
326 /* write a u32 to a buffer in target memory endianness */
327 void target_buffer_set_u32(target_t
*target
, u8
*buffer
, u32 value
)
329 if (target
->endianness
== TARGET_LITTLE_ENDIAN
)
330 h_u32_to_le(buffer
, value
);
332 h_u32_to_be(buffer
, value
);
335 /* write a u16 to a buffer in target memory endianness */
336 void target_buffer_set_u16(target_t
*target
, u8
*buffer
, u16 value
)
338 if (target
->endianness
== TARGET_LITTLE_ENDIAN
)
339 h_u16_to_le(buffer
, value
);
341 h_u16_to_be(buffer
, value
);
344 /* write a u8 to a buffer in target memory endianness */
345 void target_buffer_set_u8(target_t
*target
, u8
*buffer
, u8 value
)
350 /* returns a pointer to the n-th configured target */
351 target_t
* get_target_by_num(int num
)
353 target_t
*target
= all_targets
;
356 if( target
->target_number
== num
){
359 target
= target
->next
;
365 int get_num_by_target(target_t
*query_target
)
367 return query_target
->target_number
;
370 target_t
* get_current_target(command_context_t
*cmd_ctx
)
372 target_t
*target
= get_target_by_num(cmd_ctx
->current_target
);
376 LOG_ERROR("BUG: current_target out of bounds");
384 int target_poll(struct target_s
*target
)
386 /* We can't poll until after examine */
387 if (!target
->type
->examined
)
389 /* Fail silently lest we pollute the log */
392 return target
->type
->poll(target
);
395 int target_halt(struct target_s
*target
)
397 /* We can't poll until after examine */
398 if (!target
->type
->examined
)
400 LOG_ERROR("Target not examined yet");
403 return target
->type
->halt(target
);
406 int target_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
410 /* We can't poll until after examine */
411 if (!target
->type
->examined
)
413 LOG_ERROR("Target not examined yet");
417 /* note that resume *must* be asynchronous. The CPU can halt before we poll. The CPU can
418 * even halt at the current PC as a result of a software breakpoint being inserted by (a bug?)
421 if ((retval
= target
->type
->resume(target
, current
, address
, handle_breakpoints
, debug_execution
)) != ERROR_OK
)
428 int target_process_reset(struct command_context_s
*cmd_ctx
, enum target_reset_mode reset_mode
)
433 n
= Jim_Nvp_value2name_simple( nvp_reset_modes
, reset_mode
);
434 if( n
->name
== NULL
){
435 LOG_ERROR("invalid reset mode");
439 sprintf( buf
, "ocd_process_reset %s", n
->name
);
440 retval
= Jim_Eval( interp
, buf
);
442 if(retval
!= JIM_OK
) {
443 Jim_PrintErrorMessage(interp
);
447 /* We want any events to be processed before the prompt */
448 retval
= target_call_timer_callbacks_now();
454 static int default_virt2phys(struct target_s
*target
, u32
virtual, u32
*physical
)
460 static int default_mmu(struct target_s
*target
, int *enabled
)
466 static int default_examine(struct target_s
*target
)
468 target
->type
->examined
= 1;
473 /* Targets that correctly implement init+examine, i.e.
474 * no communication with target during init:
478 int target_examine(void)
480 int retval
= ERROR_OK
;
481 target_t
*target
= all_targets
;
484 if ((retval
= target
->type
->examine(target
))!=ERROR_OK
)
486 target
= target
->next
;
491 static int target_write_memory_imp(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
493 if (!target
->type
->examined
)
495 LOG_ERROR("Target not examined yet");
498 return target
->type
->write_memory_imp(target
, address
, size
, count
, buffer
);
501 static int target_read_memory_imp(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
503 if (!target
->type
->examined
)
505 LOG_ERROR("Target not examined yet");
508 return target
->type
->read_memory_imp(target
, address
, size
, count
, buffer
);
511 static int target_soft_reset_halt_imp(struct target_s
*target
)
513 if (!target
->type
->examined
)
515 LOG_ERROR("Target not examined yet");
518 return target
->type
->soft_reset_halt_imp(target
);
521 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
)
523 if (!target
->type
->examined
)
525 LOG_ERROR("Target not examined yet");
528 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
);
531 int target_init(struct command_context_s
*cmd_ctx
)
533 target_t
*target
= all_targets
;
538 target
->type
->examined
= 0;
539 if (target
->type
->examine
== NULL
)
541 target
->type
->examine
= default_examine
;
544 if ((retval
= target
->type
->init_target(cmd_ctx
, target
)) != ERROR_OK
)
546 LOG_ERROR("target '%s' init failed", target
->type
->name
);
550 /* Set up default functions if none are provided by target */
551 if (target
->type
->virt2phys
== NULL
)
553 target
->type
->virt2phys
= default_virt2phys
;
555 target
->type
->virt2phys
= default_virt2phys
;
556 /* a non-invasive way(in terms of patches) to add some code that
557 * runs before the type->write/read_memory implementation
559 target
->type
->write_memory_imp
= target
->type
->write_memory
;
560 target
->type
->write_memory
= target_write_memory_imp
;
561 target
->type
->read_memory_imp
= target
->type
->read_memory
;
562 target
->type
->read_memory
= target_read_memory_imp
;
563 target
->type
->soft_reset_halt_imp
= target
->type
->soft_reset_halt
;
564 target
->type
->soft_reset_halt
= target_soft_reset_halt_imp
;
565 target
->type
->run_algorithm_imp
= target
->type
->run_algorithm
;
566 target
->type
->run_algorithm
= target_run_algorithm_imp
;
569 if (target
->type
->mmu
== NULL
)
571 target
->type
->mmu
= default_mmu
;
573 target
= target
->next
;
578 if((retval
= target_register_user_commands(cmd_ctx
)) != ERROR_OK
)
580 if((retval
= target_register_timer_callback(handle_target
, 100, 1, NULL
)) != ERROR_OK
)
587 int target_register_event_callback(int (*callback
)(struct target_s
*target
, enum target_event event
, void *priv
), void *priv
)
589 target_event_callback_t
**callbacks_p
= &target_event_callbacks
;
591 if (callback
== NULL
)
593 return ERROR_INVALID_ARGUMENTS
;
598 while ((*callbacks_p
)->next
)
599 callbacks_p
= &((*callbacks_p
)->next
);
600 callbacks_p
= &((*callbacks_p
)->next
);
603 (*callbacks_p
) = malloc(sizeof(target_event_callback_t
));
604 (*callbacks_p
)->callback
= callback
;
605 (*callbacks_p
)->priv
= priv
;
606 (*callbacks_p
)->next
= NULL
;
611 int target_register_timer_callback(int (*callback
)(void *priv
), int time_ms
, int periodic
, void *priv
)
613 target_timer_callback_t
**callbacks_p
= &target_timer_callbacks
;
616 if (callback
== NULL
)
618 return ERROR_INVALID_ARGUMENTS
;
623 while ((*callbacks_p
)->next
)
624 callbacks_p
= &((*callbacks_p
)->next
);
625 callbacks_p
= &((*callbacks_p
)->next
);
628 (*callbacks_p
) = malloc(sizeof(target_timer_callback_t
));
629 (*callbacks_p
)->callback
= callback
;
630 (*callbacks_p
)->periodic
= periodic
;
631 (*callbacks_p
)->time_ms
= time_ms
;
633 gettimeofday(&now
, NULL
);
634 (*callbacks_p
)->when
.tv_usec
= now
.tv_usec
+ (time_ms
% 1000) * 1000;
635 time_ms
-= (time_ms
% 1000);
636 (*callbacks_p
)->when
.tv_sec
= now
.tv_sec
+ (time_ms
/ 1000);
637 if ((*callbacks_p
)->when
.tv_usec
> 1000000)
639 (*callbacks_p
)->when
.tv_usec
= (*callbacks_p
)->when
.tv_usec
- 1000000;
640 (*callbacks_p
)->when
.tv_sec
+= 1;
643 (*callbacks_p
)->priv
= priv
;
644 (*callbacks_p
)->next
= NULL
;
649 int target_unregister_event_callback(int (*callback
)(struct target_s
*target
, enum target_event event
, void *priv
), void *priv
)
651 target_event_callback_t
**p
= &target_event_callbacks
;
652 target_event_callback_t
*c
= target_event_callbacks
;
654 if (callback
== NULL
)
656 return ERROR_INVALID_ARGUMENTS
;
661 target_event_callback_t
*next
= c
->next
;
662 if ((c
->callback
== callback
) && (c
->priv
== priv
))
676 int target_unregister_timer_callback(int (*callback
)(void *priv
), void *priv
)
678 target_timer_callback_t
**p
= &target_timer_callbacks
;
679 target_timer_callback_t
*c
= target_timer_callbacks
;
681 if (callback
== NULL
)
683 return ERROR_INVALID_ARGUMENTS
;
688 target_timer_callback_t
*next
= c
->next
;
689 if ((c
->callback
== callback
) && (c
->priv
== priv
))
703 int target_call_event_callbacks(target_t
*target
, enum target_event event
)
705 target_event_callback_t
*callback
= target_event_callbacks
;
706 target_event_callback_t
*next_callback
;
708 if (event
== TARGET_EVENT_HALTED
)
710 /* execute early halted first */
711 target_call_event_callbacks(target
, TARGET_EVENT_EARLY_HALTED
);
715 LOG_DEBUG("target event %i (%s)",
717 Jim_Nvp_value2name_simple( nvp_target_event
, event
)->name
);
719 target_handle_event( target
, event
);
723 next_callback
= callback
->next
;
724 callback
->callback(target
, event
, callback
->priv
);
725 callback
= next_callback
;
731 static int target_call_timer_callbacks_check_time(int checktime
)
733 target_timer_callback_t
*callback
= target_timer_callbacks
;
734 target_timer_callback_t
*next_callback
;
739 gettimeofday(&now
, NULL
);
743 next_callback
= callback
->next
;
745 if ((!checktime
&&callback
->periodic
)||
746 (((now
.tv_sec
>= callback
->when
.tv_sec
) && (now
.tv_usec
>= callback
->when
.tv_usec
))
747 || (now
.tv_sec
> callback
->when
.tv_sec
)))
749 if(callback
->callback
!= NULL
)
751 callback
->callback(callback
->priv
);
752 if (callback
->periodic
)
754 int time_ms
= callback
->time_ms
;
755 callback
->when
.tv_usec
= now
.tv_usec
+ (time_ms
% 1000) * 1000;
756 time_ms
-= (time_ms
% 1000);
757 callback
->when
.tv_sec
= now
.tv_sec
+ time_ms
/ 1000;
758 if (callback
->when
.tv_usec
> 1000000)
760 callback
->when
.tv_usec
= callback
->when
.tv_usec
- 1000000;
761 callback
->when
.tv_sec
+= 1;
767 if((retval
= target_unregister_timer_callback(callback
->callback
, callback
->priv
)) != ERROR_OK
)
773 callback
= next_callback
;
779 int target_call_timer_callbacks(void)
781 return target_call_timer_callbacks_check_time(1);
784 /* invoke periodic callbacks immediately */
785 int target_call_timer_callbacks_now(void)
787 return target_call_timer_callbacks_check_time(0);
790 int target_alloc_working_area(struct target_s
*target
, u32 size
, working_area_t
**area
)
792 working_area_t
*c
= target
->working_areas
;
793 working_area_t
*new_wa
= NULL
;
795 /* Reevaluate working area address based on MMU state*/
796 if (target
->working_areas
== NULL
)
800 retval
= target
->type
->mmu(target
, &enabled
);
801 if (retval
!= ERROR_OK
)
807 target
->working_area
= target
->working_area_virt
;
811 target
->working_area
= target
->working_area_phys
;
815 /* only allocate multiples of 4 byte */
818 LOG_ERROR("BUG: code tried to allocate unaligned number of bytes, padding");
819 size
= CEIL(size
, 4);
822 /* see if there's already a matching working area */
825 if ((c
->free
) && (c
->size
== size
))
833 /* if not, allocate a new one */
836 working_area_t
**p
= &target
->working_areas
;
837 u32 first_free
= target
->working_area
;
838 u32 free_size
= target
->working_area_size
;
840 LOG_DEBUG("allocating new working area");
842 c
= target
->working_areas
;
845 first_free
+= c
->size
;
846 free_size
-= c
->size
;
851 if (free_size
< size
)
853 LOG_WARNING("not enough working area available(requested %d, free %d)", size
, free_size
);
854 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
857 new_wa
= malloc(sizeof(working_area_t
));
860 new_wa
->address
= first_free
;
862 if (target
->backup_working_area
)
865 new_wa
->backup
= malloc(new_wa
->size
);
866 if((retval
= target
->type
->read_memory(target
, new_wa
->address
, 4, new_wa
->size
/ 4, new_wa
->backup
)) != ERROR_OK
)
868 free(new_wa
->backup
);
875 new_wa
->backup
= NULL
;
878 /* put new entry in list */
882 /* mark as used, and return the new (reused) area */
892 int target_free_working_area_restore(struct target_s
*target
, working_area_t
*area
, int restore
)
897 if (restore
&&target
->backup_working_area
)
900 if((retval
= target
->type
->write_memory(target
, area
->address
, 4, area
->size
/ 4, area
->backup
)) != ERROR_OK
)
906 /* mark user pointer invalid */
913 int target_free_working_area(struct target_s
*target
, working_area_t
*area
)
915 return target_free_working_area_restore(target
, area
, 1);
918 /* free resources and restore memory, if restoring memory fails,
919 * free up resources anyway
921 void target_free_all_working_areas_restore(struct target_s
*target
, int restore
)
923 working_area_t
*c
= target
->working_areas
;
927 working_area_t
*next
= c
->next
;
928 target_free_working_area_restore(target
, c
, restore
);
938 target
->working_areas
= NULL
;
941 void target_free_all_working_areas(struct target_s
*target
)
943 target_free_all_working_areas_restore(target
, 1);
946 int target_register_commands(struct command_context_s
*cmd_ctx
)
949 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)");
950 register_command(cmd_ctx
, NULL
, "working_area", handle_working_area_command
, COMMAND_ANY
, "set a new working space");
951 register_command(cmd_ctx
, NULL
, "virt2phys", handle_virt2phys_command
, COMMAND_ANY
, "translate a virtual address into a physical address");
952 register_command(cmd_ctx
, NULL
, "profile", handle_profile_command
, COMMAND_EXEC
, "profiling samples the CPU PC");
954 register_jim(cmd_ctx
, "target", jim_target
, "configure target" );
957 /* script procedures */
958 register_jim(cmd_ctx
, "ocd_mem2array", jim_mem2array
, "read memory and return as a TCL array for script processing");
959 register_jim(cmd_ctx
, "ocd_array2mem", jim_array2mem
, "convert a TCL array to memory locations and write the values");
963 int target_arch_state(struct target_s
*target
)
968 LOG_USER("No target has been configured");
972 LOG_USER("target state: %s",
973 Jim_Nvp_value2name_simple(nvp_target_state
,target
->state
)->name
);
975 if (target
->state
!=TARGET_HALTED
)
978 retval
=target
->type
->arch_state(target
);
982 /* Single aligned words are guaranteed to use 16 or 32 bit access
983 * mode respectively, otherwise data is handled as quickly as
986 int target_write_buffer(struct target_s
*target
, u32 address
, u32 size
, u8
*buffer
)
989 LOG_DEBUG("writing buffer of %i byte at 0x%8.8x", size
, address
);
991 if (!target
->type
->examined
)
993 LOG_ERROR("Target not examined yet");
997 if ((address
+ size
- 1) < address
)
999 /* GDB can request this when e.g. PC is 0xfffffffc*/
1000 LOG_ERROR("address+size wrapped(0x%08x, 0x%08x)", address
, size
);
1004 if (((address
% 2) == 0) && (size
== 2))
1006 return target
->type
->write_memory(target
, address
, 2, 1, buffer
);
1009 /* handle unaligned head bytes */
1012 int unaligned
= 4 - (address
% 4);
1014 if (unaligned
> size
)
1017 if ((retval
= target
->type
->write_memory(target
, address
, 1, unaligned
, buffer
)) != ERROR_OK
)
1020 buffer
+= unaligned
;
1021 address
+= unaligned
;
1025 /* handle aligned words */
1028 int aligned
= size
- (size
% 4);
1030 /* use bulk writes above a certain limit. This may have to be changed */
1033 if ((retval
= target
->type
->bulk_write_memory(target
, address
, aligned
/ 4, buffer
)) != ERROR_OK
)
1038 if ((retval
= target
->type
->write_memory(target
, address
, 4, aligned
/ 4, buffer
)) != ERROR_OK
)
1047 /* handle tail writes of less than 4 bytes */
1050 if ((retval
= target
->type
->write_memory(target
, address
, 1, size
, buffer
)) != ERROR_OK
)
1058 /* Single aligned words are guaranteed to use 16 or 32 bit access
1059 * mode respectively, otherwise data is handled as quickly as
1062 int target_read_buffer(struct target_s
*target
, u32 address
, u32 size
, u8
*buffer
)
1065 LOG_DEBUG("reading buffer of %i byte at 0x%8.8x", size
, address
);
1067 if (!target
->type
->examined
)
1069 LOG_ERROR("Target not examined yet");
1073 if ((address
+ size
- 1) < address
)
1075 /* GDB can request this when e.g. PC is 0xfffffffc*/
1076 LOG_ERROR("address+size wrapped(0x%08x, 0x%08x)", address
, size
);
1080 if (((address
% 2) == 0) && (size
== 2))
1082 return target
->type
->read_memory(target
, address
, 2, 1, buffer
);
1085 /* handle unaligned head bytes */
1088 int unaligned
= 4 - (address
% 4);
1090 if (unaligned
> size
)
1093 if ((retval
= target
->type
->read_memory(target
, address
, 1, unaligned
, buffer
)) != ERROR_OK
)
1096 buffer
+= unaligned
;
1097 address
+= unaligned
;
1101 /* handle aligned words */
1104 int aligned
= size
- (size
% 4);
1106 if ((retval
= target
->type
->read_memory(target
, address
, 4, aligned
/ 4, buffer
)) != ERROR_OK
)
1114 /* handle tail writes of less than 4 bytes */
1117 if ((retval
= target
->type
->read_memory(target
, address
, 1, size
, buffer
)) != ERROR_OK
)
1124 int target_checksum_memory(struct target_s
*target
, u32 address
, u32 size
, u32
* crc
)
1130 if (!target
->type
->examined
)
1132 LOG_ERROR("Target not examined yet");
1136 if ((retval
= target
->type
->checksum_memory(target
, address
,
1137 size
, &checksum
)) != ERROR_OK
)
1139 buffer
= malloc(size
);
1142 LOG_ERROR("error allocating buffer for section (%d bytes)", size
);
1143 return ERROR_INVALID_ARGUMENTS
;
1145 retval
= target_read_buffer(target
, address
, size
, buffer
);
1146 if (retval
!= ERROR_OK
)
1152 /* convert to target endianess */
1153 for (i
= 0; i
< (size
/sizeof(u32
)); i
++)
1156 target_data
= target_buffer_get_u32(target
, &buffer
[i
*sizeof(u32
)]);
1157 target_buffer_set_u32(target
, &buffer
[i
*sizeof(u32
)], target_data
);
1160 retval
= image_calculate_checksum( buffer
, size
, &checksum
);
1169 int target_blank_check_memory(struct target_s
*target
, u32 address
, u32 size
, u32
* blank
)
1172 if (!target
->type
->examined
)
1174 LOG_ERROR("Target not examined yet");
1178 if (target
->type
->blank_check_memory
== 0)
1179 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1181 retval
= target
->type
->blank_check_memory(target
, address
, size
, blank
);
1186 int target_read_u32(struct target_s
*target
, u32 address
, u32
*value
)
1189 if (!target
->type
->examined
)
1191 LOG_ERROR("Target not examined yet");
1195 int retval
= target
->type
->read_memory(target
, address
, 4, 1, value_buf
);
1197 if (retval
== ERROR_OK
)
1199 *value
= target_buffer_get_u32(target
, value_buf
);
1200 LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address
, *value
);
1205 LOG_DEBUG("address: 0x%8.8x failed", address
);
1211 int target_read_u16(struct target_s
*target
, u32 address
, u16
*value
)
1214 if (!target
->type
->examined
)
1216 LOG_ERROR("Target not examined yet");
1220 int retval
= target
->type
->read_memory(target
, address
, 2, 1, value_buf
);
1222 if (retval
== ERROR_OK
)
1224 *value
= target_buffer_get_u16(target
, value_buf
);
1225 LOG_DEBUG("address: 0x%8.8x, value: 0x%4.4x", address
, *value
);
1230 LOG_DEBUG("address: 0x%8.8x failed", address
);
1236 int target_read_u8(struct target_s
*target
, u32 address
, u8
*value
)
1238 int retval
= target
->type
->read_memory(target
, address
, 1, 1, value
);
1239 if (!target
->type
->examined
)
1241 LOG_ERROR("Target not examined yet");
1245 if (retval
== ERROR_OK
)
1247 LOG_DEBUG("address: 0x%8.8x, value: 0x%2.2x", address
, *value
);
1252 LOG_DEBUG("address: 0x%8.8x failed", address
);
1258 int target_write_u32(struct target_s
*target
, u32 address
, u32 value
)
1262 if (!target
->type
->examined
)
1264 LOG_ERROR("Target not examined yet");
1268 LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address
, value
);
1270 target_buffer_set_u32(target
, value_buf
, value
);
1271 if ((retval
= target
->type
->write_memory(target
, address
, 4, 1, value_buf
)) != ERROR_OK
)
1273 LOG_DEBUG("failed: %i", retval
);
1279 int target_write_u16(struct target_s
*target
, u32 address
, u16 value
)
1283 if (!target
->type
->examined
)
1285 LOG_ERROR("Target not examined yet");
1289 LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address
, value
);
1291 target_buffer_set_u16(target
, value_buf
, value
);
1292 if ((retval
= target
->type
->write_memory(target
, address
, 2, 1, value_buf
)) != ERROR_OK
)
1294 LOG_DEBUG("failed: %i", retval
);
1300 int target_write_u8(struct target_s
*target
, u32 address
, u8 value
)
1303 if (!target
->type
->examined
)
1305 LOG_ERROR("Target not examined yet");
1309 LOG_DEBUG("address: 0x%8.8x, value: 0x%2.2x", address
, value
);
1311 if ((retval
= target
->type
->write_memory(target
, address
, 1, 1, &value
)) != ERROR_OK
)
1313 LOG_DEBUG("failed: %i", retval
);
1319 int target_register_user_commands(struct command_context_s
*cmd_ctx
)
1321 int retval
= ERROR_OK
;
1322 register_command(cmd_ctx
, NULL
, "reg", handle_reg_command
, COMMAND_EXEC
, "display or set a register");
1323 register_command(cmd_ctx
, NULL
, "poll", handle_poll_command
, COMMAND_EXEC
, "poll target state");
1324 register_command(cmd_ctx
, NULL
, "wait_halt", handle_wait_halt_command
, COMMAND_EXEC
, "wait for target halt [time (s)]");
1325 register_command(cmd_ctx
, NULL
, "halt", handle_halt_command
, COMMAND_EXEC
, "halt target");
1326 register_command(cmd_ctx
, NULL
, "resume", handle_resume_command
, COMMAND_EXEC
, "resume target [addr]");
1327 register_command(cmd_ctx
, NULL
, "step", handle_step_command
, COMMAND_EXEC
, "step one instruction from current PC or [addr]");
1328 register_command(cmd_ctx
, NULL
, "reset", handle_reset_command
, COMMAND_EXEC
, "reset target [run|halt|init] - default is run");
1329 register_command(cmd_ctx
, NULL
, "soft_reset_halt", handle_soft_reset_halt_command
, COMMAND_EXEC
, "halt the target and do a soft reset");
1331 register_command(cmd_ctx
, NULL
, "mdw", handle_md_command
, COMMAND_EXEC
, "display memory words <addr> [count]");
1332 register_command(cmd_ctx
, NULL
, "mdh", handle_md_command
, COMMAND_EXEC
, "display memory half-words <addr> [count]");
1333 register_command(cmd_ctx
, NULL
, "mdb", handle_md_command
, COMMAND_EXEC
, "display memory bytes <addr> [count]");
1335 register_command(cmd_ctx
, NULL
, "mww", handle_mw_command
, COMMAND_EXEC
, "write memory word <addr> <value> [count]");
1336 register_command(cmd_ctx
, NULL
, "mwh", handle_mw_command
, COMMAND_EXEC
, "write memory half-word <addr> <value> [count]");
1337 register_command(cmd_ctx
, NULL
, "mwb", handle_mw_command
, COMMAND_EXEC
, "write memory byte <addr> <value> [count]");
1339 register_command(cmd_ctx
, NULL
, "bp", handle_bp_command
, COMMAND_EXEC
, "set breakpoint <address> <length> [hw]");
1340 register_command(cmd_ctx
, NULL
, "rbp", handle_rbp_command
, COMMAND_EXEC
, "remove breakpoint <adress>");
1341 register_command(cmd_ctx
, NULL
, "wp", handle_wp_command
, COMMAND_EXEC
, "set watchpoint <address> <length> <r/w/a> [value] [mask]");
1342 register_command(cmd_ctx
, NULL
, "rwp", handle_rwp_command
, COMMAND_EXEC
, "remove watchpoint <adress>");
1344 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]");
1345 register_command(cmd_ctx
, NULL
, "dump_image", handle_dump_image_command
, COMMAND_EXEC
, "dump_image <file> <address> <size>");
1346 register_command(cmd_ctx
, NULL
, "verify_image", handle_verify_image_command
, COMMAND_EXEC
, "verify_image <file> [offset] [type]");
1348 if((retval
= target_request_register_commands(cmd_ctx
)) != ERROR_OK
)
1350 if((retval
= trace_register_commands(cmd_ctx
)) != ERROR_OK
)
1357 int handle_targets_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1360 target_t
*target
= all_targets
;
1364 /* try as tcltarget name */
1365 for( target
= all_targets
; target
; target
++ ){
1366 if( target
->cmd_name
){
1367 if( 0 == strcmp( args
[0], target
->cmd_name
) ){
1373 /* no match, try as number */
1375 int num
= strtoul(args
[0], &cp
, 0 );
1377 /* then it was not a number */
1378 command_print( cmd_ctx
, "Target: %s unknown, try one of:\n", args
[0] );
1382 target
= get_target_by_num( num
);
1383 if( target
== NULL
){
1384 command_print(cmd_ctx
,"Target: %s is unknown, try one of:\n", args
[0] );
1388 cmd_ctx
->current_target
= target
->target_number
;
1393 command_print(cmd_ctx
, " CmdName Type Endian ChainPos State ");
1394 command_print(cmd_ctx
, "-- ---------- ---------- ---------- -------- ----------");
1397 /* XX: abcdefghij abcdefghij abcdefghij abcdefghij */
1398 command_print(cmd_ctx
, "%2d: %-10s %-10s %-10s %8d %s",
1399 target
->target_number
,
1402 Jim_Nvp_value2name_simple( nvp_target_endian
, target
->endianness
)->name
,
1403 target
->chain_position
,
1404 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
1405 target
= target
->next
;
1413 int handle_working_area_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1415 int retval
= ERROR_OK
;
1416 target_t
*target
= NULL
;
1418 if ((argc
< 4) || (argc
> 5))
1420 return ERROR_COMMAND_SYNTAX_ERROR
;
1423 target
= get_target_by_num(strtoul(args
[0], NULL
, 0));
1426 return ERROR_COMMAND_SYNTAX_ERROR
;
1428 target_free_all_working_areas(target
);
1430 target
->working_area_phys
= target
->working_area_virt
= strtoul(args
[1], NULL
, 0);
1433 target
->working_area_virt
= strtoul(args
[4], NULL
, 0);
1435 target
->working_area_size
= strtoul(args
[2], NULL
, 0);
1437 if (strcmp(args
[3], "backup") == 0)
1439 target
->backup_working_area
= 1;
1441 else if (strcmp(args
[3], "nobackup") == 0)
1443 target
->backup_working_area
= 0;
1447 LOG_ERROR("unrecognized <backup|nobackup> argument (%s)", args
[3]);
1448 return ERROR_COMMAND_SYNTAX_ERROR
;
1455 // every 300ms we check for reset & powerdropout and issue a "reset halt" if
1458 static int powerDropout
;
1459 static int srstAsserted
;
1461 static int sense_handler()
1463 static int prevSrstAsserted
= 0;
1464 static int prevPowerdropout
= 0;
1467 if ((retval
=jtag_power_dropout(&powerDropout
))!=ERROR_OK
)
1471 powerRestored
= prevPowerdropout
&& !powerDropout
;
1474 LOG_USER("Sensed power restore.");
1477 long long current
= timeval_ms();
1478 static long long lastPower
= 0;
1479 int waitMore
= lastPower
+ 2000 > current
;
1480 if (powerDropout
&& !waitMore
)
1482 LOG_USER("Sensed power dropout.");
1483 lastPower
= current
;
1486 if ((retval
=jtag_srst_asserted(&srstAsserted
))!=ERROR_OK
)
1490 srstDeasserted
= prevSrstAsserted
&& !srstAsserted
;
1492 static long long lastSrst
= 0;
1493 waitMore
= lastSrst
+ 2000 > current
;
1494 if (srstDeasserted
&& !waitMore
)
1496 LOG_USER("Sensed nSRST deasserted");
1500 if (!prevSrstAsserted
&& srstAsserted
)
1502 LOG_USER("Sensed nSRST asserted");
1505 prevSrstAsserted
= srstAsserted
;
1506 prevPowerdropout
= powerDropout
;
1508 if (srstDeasserted
|| powerRestored
)
1510 /* Other than logging the event we can't do anything here.
1511 * Issuing a reset is a particularly bad idea as we might
1512 * be inside a reset already.
1520 /* process target state changes */
1521 int handle_target(void *priv
)
1523 int retval
= ERROR_OK
;
1524 target_t
*target
= all_targets
;
1530 /* only poll target if we've got power and srst isn't asserted */
1531 if (target_continous_poll
&&!powerDropout
&&!srstAsserted
)
1533 /* polling may fail silently until the target has been examined */
1534 if((retval
= target_poll(target
)) != ERROR_OK
)
1538 target
= target
->next
;
1544 int handle_reg_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1553 target
= get_current_target(cmd_ctx
);
1555 /* list all available registers for the current target */
1558 reg_cache_t
*cache
= target
->reg_cache
;
1564 for (i
= 0; i
< cache
->num_regs
; i
++)
1566 value
= buf_to_str(cache
->reg_list
[i
].value
, cache
->reg_list
[i
].size
, 16);
1567 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
);
1570 cache
= cache
->next
;
1576 /* access a single register by its ordinal number */
1577 if ((args
[0][0] >= '0') && (args
[0][0] <= '9'))
1579 int num
= strtoul(args
[0], NULL
, 0);
1580 reg_cache_t
*cache
= target
->reg_cache
;
1586 for (i
= 0; i
< cache
->num_regs
; i
++)
1590 reg
= &cache
->reg_list
[i
];
1596 cache
= cache
->next
;
1601 command_print(cmd_ctx
, "%i is out of bounds, the current target has only %i registers (0 - %i)", num
, count
, count
- 1);
1604 } else /* access a single register by its name */
1606 reg
= register_get_by_name(target
->reg_cache
, args
[0], 1);
1610 command_print(cmd_ctx
, "register %s not found in current target", args
[0]);
1615 /* display a register */
1616 if ((argc
== 1) || ((argc
== 2) && !((args
[1][0] >= '0') && (args
[1][0] <= '9'))))
1618 if ((argc
== 2) && (strcmp(args
[1], "force") == 0))
1621 if (reg
->valid
== 0)
1623 reg_arch_type_t
*arch_type
= register_get_arch_type(reg
->arch_type
);
1624 arch_type
->get(reg
);
1626 value
= buf_to_str(reg
->value
, reg
->size
, 16);
1627 command_print(cmd_ctx
, "%s (/%i): 0x%s", reg
->name
, reg
->size
, value
);
1632 /* set register value */
1635 u8
*buf
= malloc(CEIL(reg
->size
, 8));
1636 str_to_buf(args
[1], strlen(args
[1]), buf
, reg
->size
, 0);
1638 reg_arch_type_t
*arch_type
= register_get_arch_type(reg
->arch_type
);
1639 arch_type
->set(reg
, buf
);
1641 value
= buf_to_str(reg
->value
, reg
->size
, 16);
1642 command_print(cmd_ctx
, "%s (/%i): 0x%s", reg
->name
, reg
->size
, value
);
1650 command_print(cmd_ctx
, "usage: reg <#|name> [value]");
1656 int handle_poll_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1658 int retval
= ERROR_OK
;
1659 target_t
*target
= get_current_target(cmd_ctx
);
1663 if((retval
= target_poll(target
)) != ERROR_OK
)
1665 if((retval
= target_arch_state(target
)) != ERROR_OK
)
1671 if (strcmp(args
[0], "on") == 0)
1673 target_continous_poll
= 1;
1675 else if (strcmp(args
[0], "off") == 0)
1677 target_continous_poll
= 0;
1681 command_print(cmd_ctx
, "arg is \"on\" or \"off\"");
1685 return ERROR_COMMAND_SYNTAX_ERROR
;
1692 int handle_wait_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1700 ms
= strtoul(args
[0], &end
, 0) * 1000;
1703 command_print(cmd_ctx
, "usage: %s [seconds]", cmd
);
1707 target_t
*target
= get_current_target(cmd_ctx
);
1709 return target_wait_state(target
, TARGET_HALTED
, ms
);
1712 int target_wait_state(target_t
*target
, enum target_state state
, int ms
)
1715 struct timeval timeout
, now
;
1717 gettimeofday(&timeout
, NULL
);
1718 timeval_add_time(&timeout
, 0, ms
* 1000);
1722 if ((retval
=target_poll(target
))!=ERROR_OK
)
1725 if (target
->state
== state
)
1732 LOG_DEBUG("waiting for target %s...",
1733 Jim_Nvp_value2name_simple(nvp_target_state
,state
)->name
);
1736 gettimeofday(&now
, NULL
);
1737 if ((now
.tv_sec
> timeout
.tv_sec
) || ((now
.tv_sec
== timeout
.tv_sec
) && (now
.tv_usec
>= timeout
.tv_usec
)))
1739 LOG_ERROR("timed out while waiting for target %s",
1740 Jim_Nvp_value2name_simple(nvp_target_state
,state
)->name
);
1748 int handle_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1751 target_t
*target
= get_current_target(cmd_ctx
);
1755 if ((retval
= target_halt(target
)) != ERROR_OK
)
1760 return handle_wait_halt_command(cmd_ctx
, cmd
, args
, argc
);
1763 int handle_soft_reset_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1765 target_t
*target
= get_current_target(cmd_ctx
);
1767 LOG_USER("requesting target halt and executing a soft reset");
1769 target
->type
->soft_reset_halt(target
);
1774 int handle_reset_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1777 enum target_reset_mode reset_mode
= RESET_RUN
;
1781 n
= Jim_Nvp_name2value_simple( nvp_reset_modes
, args
[0] );
1782 if( (n
->name
== NULL
) || (n
->value
== RESET_UNKNOWN
) ){
1783 return ERROR_COMMAND_SYNTAX_ERROR
;
1785 reset_mode
= n
->value
;
1788 /* reset *all* targets */
1789 return target_process_reset(cmd_ctx
, reset_mode
);
1793 int handle_resume_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1796 target_t
*target
= get_current_target(cmd_ctx
);
1798 target_handle_event( target
, TARGET_EVENT_OLD_pre_resume
);
1801 retval
= target_resume(target
, 1, 0, 1, 0); /* current pc, addr = 0, handle breakpoints, not debugging */
1803 retval
= target_resume(target
, 0, strtoul(args
[0], NULL
, 0), 1, 0); /* addr = args[0], handle breakpoints, not debugging */
1806 retval
= ERROR_COMMAND_SYNTAX_ERROR
;
1812 int handle_step_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1814 target_t
*target
= get_current_target(cmd_ctx
);
1819 return target
->type
->step(target
, 1, 0, 1); /* current pc, addr = 0, handle breakpoints */
1822 return target
->type
->step(target
, 0, strtoul(args
[0], NULL
, 0), 1); /* addr = args[0], handle breakpoints */
1827 int handle_md_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1829 const int line_bytecnt
= 32;
1842 target_t
*target
= get_current_target(cmd_ctx
);
1848 count
= strtoul(args
[1], NULL
, 0);
1850 address
= strtoul(args
[0], NULL
, 0);
1856 size
= 4; line_modulo
= line_bytecnt
/ 4;
1859 size
= 2; line_modulo
= line_bytecnt
/ 2;
1862 size
= 1; line_modulo
= line_bytecnt
/ 1;
1868 buffer
= calloc(count
, size
);
1869 retval
= target
->type
->read_memory(target
, address
, size
, count
, buffer
);
1870 if (retval
== ERROR_OK
)
1874 for (i
= 0; i
< count
; i
++)
1876 if (i
%line_modulo
== 0)
1877 output_len
+= snprintf(output
+ output_len
, 128 - output_len
, "0x%8.8x: ", address
+ (i
*size
));
1882 output_len
+= snprintf(output
+ output_len
, 128 - output_len
, "%8.8x ", target_buffer_get_u32(target
, &buffer
[i
*4]));
1885 output_len
+= snprintf(output
+ output_len
, 128 - output_len
, "%4.4x ", target_buffer_get_u16(target
, &buffer
[i
*2]));
1888 output_len
+= snprintf(output
+ output_len
, 128 - output_len
, "%2.2x ", buffer
[i
*1]);
1892 if ((i
%line_modulo
== line_modulo
-1) || (i
== count
- 1))
1894 command_print(cmd_ctx
, output
);
1905 int handle_mw_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1912 target_t
*target
= get_current_target(cmd_ctx
);
1915 if ((argc
< 2) || (argc
> 3))
1916 return ERROR_COMMAND_SYNTAX_ERROR
;
1918 address
= strtoul(args
[0], NULL
, 0);
1919 value
= strtoul(args
[1], NULL
, 0);
1921 count
= strtoul(args
[2], NULL
, 0);
1927 target_buffer_set_u32(target
, value_buf
, value
);
1931 target_buffer_set_u16(target
, value_buf
, value
);
1935 value_buf
[0] = value
;
1938 return ERROR_COMMAND_SYNTAX_ERROR
;
1940 for (i
=0; i
<count
; i
++)
1946 retval
= target
->type
->write_memory(target
, address
+ i
*wordsize
, 4, 1, value_buf
);
1949 retval
= target
->type
->write_memory(target
, address
+ i
*wordsize
, 2, 1, value_buf
);
1952 retval
= target
->type
->write_memory(target
, address
+ i
*wordsize
, 1, 1, value_buf
);
1959 if (retval
!=ERROR_OK
)
1969 int handle_load_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1975 u32 max_address
=0xffffffff;
1977 int retval
, retvaltemp
;
1981 duration_t duration
;
1982 char *duration_text
;
1984 target_t
*target
= get_current_target(cmd_ctx
);
1986 if ((argc
< 1)||(argc
> 5))
1988 return ERROR_COMMAND_SYNTAX_ERROR
;
1991 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
1994 image
.base_address_set
= 1;
1995 image
.base_address
= strtoul(args
[1], NULL
, 0);
1999 image
.base_address_set
= 0;
2003 image
.start_address_set
= 0;
2007 min_address
=strtoul(args
[3], NULL
, 0);
2011 max_address
=strtoul(args
[4], NULL
, 0)+min_address
;
2014 if (min_address
>max_address
)
2016 return ERROR_COMMAND_SYNTAX_ERROR
;
2020 duration_start_measure(&duration
);
2022 if (image_open(&image
, args
[0], (argc
>= 3) ? args
[2] : NULL
) != ERROR_OK
)
2029 for (i
= 0; i
< image
.num_sections
; i
++)
2031 buffer
= malloc(image
.sections
[i
].size
);
2034 command_print(cmd_ctx
, "error allocating buffer for section (%d bytes)", image
.sections
[i
].size
);
2038 if ((retval
= image_read_section(&image
, i
, 0x0, image
.sections
[i
].size
, buffer
, &buf_cnt
)) != ERROR_OK
)
2048 /* DANGER!!! beware of unsigned comparision here!!! */
2050 if ((image
.sections
[i
].base_address
+buf_cnt
>=min_address
)&&
2051 (image
.sections
[i
].base_address
<max_address
))
2053 if (image
.sections
[i
].base_address
<min_address
)
2055 /* clip addresses below */
2056 offset
+=min_address
-image
.sections
[i
].base_address
;
2060 if (image
.sections
[i
].base_address
+buf_cnt
>max_address
)
2062 length
-=(image
.sections
[i
].base_address
+buf_cnt
)-max_address
;
2065 if ((retval
= target_write_buffer(target
, image
.sections
[i
].base_address
+offset
, length
, buffer
+offset
)) != ERROR_OK
)
2070 image_size
+= length
;
2071 command_print(cmd_ctx
, "%u byte written at address 0x%8.8x", length
, image
.sections
[i
].base_address
+offset
);
2077 if((retvaltemp
= duration_stop_measure(&duration
, &duration_text
)) != ERROR_OK
)
2079 image_close(&image
);
2083 if (retval
==ERROR_OK
)
2085 command_print(cmd_ctx
, "downloaded %u byte in %s", image_size
, duration_text
);
2087 free(duration_text
);
2089 image_close(&image
);
2095 int handle_dump_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2102 int retval
=ERROR_OK
, retvaltemp
;
2104 duration_t duration
;
2105 char *duration_text
;
2107 target_t
*target
= get_current_target(cmd_ctx
);
2111 command_print(cmd_ctx
, "usage: dump_image <filename> <address> <size>");
2115 address
= strtoul(args
[1], NULL
, 0);
2116 size
= strtoul(args
[2], NULL
, 0);
2118 if ((address
& 3) || (size
& 3))
2120 command_print(cmd_ctx
, "only 32-bit aligned address and size are supported");
2124 if (fileio_open(&fileio
, args
[0], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
)
2129 duration_start_measure(&duration
);
2134 u32 this_run_size
= (size
> 560) ? 560 : size
;
2136 retval
= target
->type
->read_memory(target
, address
, 4, this_run_size
/ 4, buffer
);
2137 if (retval
!= ERROR_OK
)
2142 retval
= fileio_write(&fileio
, this_run_size
, buffer
, &size_written
);
2143 if (retval
!= ERROR_OK
)
2148 size
-= this_run_size
;
2149 address
+= this_run_size
;
2152 if((retvaltemp
= fileio_close(&fileio
)) != ERROR_OK
)
2155 if((retvaltemp
= duration_stop_measure(&duration
, &duration_text
)) != ERROR_OK
)
2158 if (retval
==ERROR_OK
)
2160 command_print(cmd_ctx
, "dumped %"PRIi64
" byte in %s", fileio
.size
, duration_text
);
2162 free(duration_text
);
2167 int handle_verify_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2173 int retval
, retvaltemp
;
2175 u32 mem_checksum
= 0;
2179 duration_t duration
;
2180 char *duration_text
;
2182 target_t
*target
= get_current_target(cmd_ctx
);
2186 return ERROR_COMMAND_SYNTAX_ERROR
;
2191 LOG_ERROR("no target selected");
2195 duration_start_measure(&duration
);
2199 image
.base_address_set
= 1;
2200 image
.base_address
= strtoul(args
[1], NULL
, 0);
2204 image
.base_address_set
= 0;
2205 image
.base_address
= 0x0;
2208 image
.start_address_set
= 0;
2210 if ((retval
=image_open(&image
, args
[0], (argc
== 3) ? args
[2] : NULL
)) != ERROR_OK
)
2217 for (i
= 0; i
< image
.num_sections
; i
++)
2219 buffer
= malloc(image
.sections
[i
].size
);
2222 command_print(cmd_ctx
, "error allocating buffer for section (%d bytes)", image
.sections
[i
].size
);
2225 if ((retval
= image_read_section(&image
, i
, 0x0, image
.sections
[i
].size
, buffer
, &buf_cnt
)) != ERROR_OK
)
2231 /* calculate checksum of image */
2232 image_calculate_checksum( buffer
, buf_cnt
, &checksum
);
2234 retval
= target_checksum_memory(target
, image
.sections
[i
].base_address
, buf_cnt
, &mem_checksum
);
2235 if( retval
!= ERROR_OK
)
2241 if( checksum
!= mem_checksum
)
2243 /* failed crc checksum, fall back to a binary compare */
2246 command_print(cmd_ctx
, "checksum mismatch - attempting binary compare");
2248 data
= (u8
*)malloc(buf_cnt
);
2250 /* Can we use 32bit word accesses? */
2252 int count
= buf_cnt
;
2253 if ((count
% 4) == 0)
2258 retval
= target
->type
->read_memory(target
, image
.sections
[i
].base_address
, size
, count
, data
);
2259 if (retval
== ERROR_OK
)
2262 for (t
= 0; t
< buf_cnt
; t
++)
2264 if (data
[t
] != buffer
[t
])
2266 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
]);
2283 image_size
+= buf_cnt
;
2287 if((retvaltemp
= duration_stop_measure(&duration
, &duration_text
)) != ERROR_OK
)
2289 image_close(&image
);
2293 if (retval
==ERROR_OK
)
2295 command_print(cmd_ctx
, "verified %u bytes in %s", image_size
, duration_text
);
2297 free(duration_text
);
2299 image_close(&image
);
2304 int handle_bp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2307 target_t
*target
= get_current_target(cmd_ctx
);
2311 breakpoint_t
*breakpoint
= target
->breakpoints
;
2315 if (breakpoint
->type
== BKPT_SOFT
)
2317 char* buf
= buf_to_str(breakpoint
->orig_instr
, breakpoint
->length
, 16);
2318 command_print(cmd_ctx
, "0x%8.8x, 0x%x, %i, 0x%s", breakpoint
->address
, breakpoint
->length
, breakpoint
->set
, buf
);
2323 command_print(cmd_ctx
, "0x%8.8x, 0x%x, %i", breakpoint
->address
, breakpoint
->length
, breakpoint
->set
);
2325 breakpoint
= breakpoint
->next
;
2333 length
= strtoul(args
[1], NULL
, 0);
2336 if (strcmp(args
[2], "hw") == 0)
2339 if ((retval
= breakpoint_add(target
, strtoul(args
[0], NULL
, 0), length
, hw
)) != ERROR_OK
)
2341 LOG_ERROR("Failure setting breakpoints");
2345 command_print(cmd_ctx
, "breakpoint added at address 0x%8.8x", strtoul(args
[0], NULL
, 0));
2350 command_print(cmd_ctx
, "usage: bp <address> <length> ['hw']");
2356 int handle_rbp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2358 target_t
*target
= get_current_target(cmd_ctx
);
2361 breakpoint_remove(target
, strtoul(args
[0], NULL
, 0));
2366 int handle_wp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2368 target_t
*target
= get_current_target(cmd_ctx
);
2373 watchpoint_t
*watchpoint
= target
->watchpoints
;
2377 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
);
2378 watchpoint
= watchpoint
->next
;
2383 enum watchpoint_rw type
= WPT_ACCESS
;
2384 u32 data_value
= 0x0;
2385 u32 data_mask
= 0xffffffff;
2401 command_print(cmd_ctx
, "usage: wp <address> <length> [r/w/a] [value] [mask]");
2407 data_value
= strtoul(args
[3], NULL
, 0);
2411 data_mask
= strtoul(args
[4], NULL
, 0);
2414 if ((retval
= watchpoint_add(target
, strtoul(args
[0], NULL
, 0),
2415 strtoul(args
[1], NULL
, 0), type
, data_value
, data_mask
)) != ERROR_OK
)
2417 LOG_ERROR("Failure setting breakpoints");
2422 command_print(cmd_ctx
, "usage: wp <address> <length> [r/w/a] [value] [mask]");
2428 int handle_rwp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2430 target_t
*target
= get_current_target(cmd_ctx
);
2433 watchpoint_remove(target
, strtoul(args
[0], NULL
, 0));
2438 int handle_virt2phys_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2441 target_t
*target
= get_current_target(cmd_ctx
);
2447 return ERROR_COMMAND_SYNTAX_ERROR
;
2449 va
= strtoul(args
[0], NULL
, 0);
2451 retval
= target
->type
->virt2phys(target
, va
, &pa
);
2452 if (retval
== ERROR_OK
)
2454 command_print(cmd_ctx
, "Physical address 0x%08x", pa
);
2458 /* lower levels will have logged a detailed error which is
2459 * forwarded to telnet/GDB session.
2464 static void writeLong(FILE *f
, int l
)
2469 char c
=(l
>>(i
*8))&0xff;
2470 fwrite(&c
, 1, 1, f
);
2474 static void writeString(FILE *f
, char *s
)
2476 fwrite(s
, 1, strlen(s
), f
);
2481 // Dump a gmon.out histogram file.
2482 static void writeGmon(u32
*samples
, int sampleNum
, char *filename
)
2485 FILE *f
=fopen(filename
, "w");
2488 fwrite("gmon", 1, 4, f
);
2489 writeLong(f
, 0x00000001); // Version
2490 writeLong(f
, 0); // padding
2491 writeLong(f
, 0); // padding
2492 writeLong(f
, 0); // padding
2494 fwrite("", 1, 1, f
); // GMON_TAG_TIME_HIST
2496 // figure out bucket size
2499 for (i
=0; i
<sampleNum
; i
++)
2511 int addressSpace
=(max
-min
+1);
2513 static int const maxBuckets
=256*1024; // maximum buckets.
2514 int length
=addressSpace
;
2515 if (length
> maxBuckets
)
2519 int *buckets
=malloc(sizeof(int)*length
);
2525 memset(buckets
, 0, sizeof(int)*length
);
2526 for (i
=0; i
<sampleNum
;i
++)
2528 u32 address
=samples
[i
];
2529 long long a
=address
-min
;
2530 long long b
=length
-1;
2531 long long c
=addressSpace
-1;
2532 int index
=(a
*b
)/c
; // danger!!!! int32 overflows
2536 // append binary memory gmon.out &profile_hist_hdr ((char*)&profile_hist_hdr + sizeof(struct gmon_hist_hdr))
2537 writeLong(f
, min
); // low_pc
2538 writeLong(f
, max
); // high_pc
2539 writeLong(f
, length
); // # of samples
2540 writeLong(f
, 64000000); // 64MHz
2541 writeString(f
, "seconds");
2542 for (i
=0; i
<(15-strlen("seconds")); i
++)
2544 fwrite("", 1, 1, f
); // padding
2546 writeString(f
, "s");
2548 // append binary memory gmon.out profile_hist_data (profile_hist_data + profile_hist_hdr.hist_size)
2550 char *data
=malloc(2*length
);
2553 for (i
=0; i
<length
;i
++)
2562 data
[i
*2+1]=(val
>>8)&0xff;
2565 fwrite(data
, 1, length
*2, f
);
2575 /* profiling samples the CPU PC as quickly as OpenOCD is able, which will be used as a random sampling of PC */
2576 int handle_profile_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2578 target_t
*target
= get_current_target(cmd_ctx
);
2579 struct timeval timeout
, now
;
2581 gettimeofday(&timeout
, NULL
);
2584 return ERROR_COMMAND_SYNTAX_ERROR
;
2587 timeval_add_time(&timeout
, strtoul(args
[0], &end
, 0), 0);
2593 command_print(cmd_ctx
, "Starting profiling. Halting and resuming the target as often as we can...");
2595 static const int maxSample
=10000;
2596 u32
*samples
=malloc(sizeof(u32
)*maxSample
);
2601 int retval
=ERROR_OK
;
2602 // hopefully it is safe to cache! We want to stop/restart as quickly as possible.
2603 reg_t
*reg
= register_get_by_name(target
->reg_cache
, "pc", 1);
2607 target_poll(target
);
2608 if (target
->state
== TARGET_HALTED
)
2610 u32 t
=*((u32
*)reg
->value
);
2611 samples
[numSamples
++]=t
;
2612 retval
= target_resume(target
, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */
2613 target_poll(target
);
2614 alive_sleep(10); // sleep 10ms, i.e. <100 samples/second.
2615 } else if (target
->state
== TARGET_RUNNING
)
2617 // We want to quickly sample the PC.
2618 if((retval
= target_halt(target
)) != ERROR_OK
)
2625 command_print(cmd_ctx
, "Target not halted or running");
2629 if (retval
!=ERROR_OK
)
2634 gettimeofday(&now
, NULL
);
2635 if ((numSamples
>=maxSample
) || ((now
.tv_sec
>= timeout
.tv_sec
) && (now
.tv_usec
>= timeout
.tv_usec
)))
2637 command_print(cmd_ctx
, "Profiling completed. %d samples.", numSamples
);
2638 if((retval
= target_poll(target
)) != ERROR_OK
)
2643 if (target
->state
== TARGET_HALTED
)
2645 target_resume(target
, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */
2647 if((retval
= target_poll(target
)) != ERROR_OK
)
2652 writeGmon(samples
, numSamples
, args
[1]);
2653 command_print(cmd_ctx
, "Wrote %s", args
[1]);
2662 static int new_int_array_element(Jim_Interp
* interp
, const char *varname
, int idx
, u32 val
)
2665 Jim_Obj
*nameObjPtr
, *valObjPtr
;
2668 namebuf
= alloc_printf("%s(%d)", varname
, idx
);
2672 nameObjPtr
= Jim_NewStringObj(interp
, namebuf
, -1);
2673 valObjPtr
= Jim_NewIntObj(interp
, val
);
2674 if (!nameObjPtr
|| !valObjPtr
)
2680 Jim_IncrRefCount(nameObjPtr
);
2681 Jim_IncrRefCount(valObjPtr
);
2682 result
= Jim_SetVariable(interp
, nameObjPtr
, valObjPtr
);
2683 Jim_DecrRefCount(interp
, nameObjPtr
);
2684 Jim_DecrRefCount(interp
, valObjPtr
);
2686 /* printf("%s(%d) <= 0%08x\n", varname, idx, val); */
2690 static int jim_mem2array(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
2692 command_context_t
*context
;
2695 context
= Jim_GetAssocData(interp
, "context");
2696 if (context
== NULL
)
2698 LOG_ERROR("mem2array: no command context");
2701 target
= get_current_target(context
);
2704 LOG_ERROR("mem2array: no current target");
2708 return target_mem2array(interp
, target
, argc
,argv
);
2711 static int target_mem2array(Jim_Interp
*interp
, target_t
*target
, int argc
, Jim_Obj
*const *argv
)
2719 const char *varname
;
2721 int i
, n
, e
, retval
;
2723 /* argv[1] = name of array to receive the data
2724 * argv[2] = desired width
2725 * argv[3] = memory address
2726 * argv[4] = count of times to read
2729 Jim_WrongNumArgs(interp
, 1, argv
, "varname width addr nelems");
2732 varname
= Jim_GetString(argv
[1], &len
);
2733 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
2735 e
= Jim_GetLong(interp
, argv
[2], &l
);
2741 e
= Jim_GetLong(interp
, argv
[3], &l
);
2746 e
= Jim_GetLong(interp
, argv
[4], &l
);
2762 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2763 Jim_AppendStrings( interp
, Jim_GetResult(interp
), "Invalid width param, must be 8/16/32", NULL
);
2767 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2768 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: zero width read?", NULL
);
2771 if ((addr
+ (len
* width
)) < addr
) {
2772 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2773 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: addr + len - wraps to zero?", NULL
);
2776 /* absurd transfer size? */
2778 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2779 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: absurd > 64K item request", NULL
);
2784 ((width
== 2) && ((addr
& 1) == 0)) ||
2785 ((width
== 4) && ((addr
& 3) == 0))) {
2789 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2790 sprintf(buf
, "mem2array address: 0x%08x is not aligned for %d byte reads", addr
, width
);
2791 Jim_AppendStrings(interp
, Jim_GetResult(interp
), buf
, NULL
);
2802 /* Slurp... in buffer size chunks */
2804 count
= len
; /* in objects.. */
2805 if (count
> (sizeof(buffer
)/width
)) {
2806 count
= (sizeof(buffer
)/width
);
2809 retval
= target
->type
->read_memory( target
, addr
, width
, count
, buffer
);
2810 if (retval
!= ERROR_OK
) {
2812 LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed", addr
, width
, count
);
2813 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2814 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: cannot read memory", NULL
);
2818 v
= 0; /* shut up gcc */
2819 for (i
= 0 ;i
< count
;i
++, n
++) {
2822 v
= target_buffer_get_u32(target
, &buffer
[i
*width
]);
2825 v
= target_buffer_get_u16(target
, &buffer
[i
*width
]);
2828 v
= buffer
[i
] & 0x0ff;
2831 new_int_array_element(interp
, varname
, n
, v
);
2837 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2842 static int get_int_array_element(Jim_Interp
* interp
, const char *varname
, int idx
, u32
*val
)
2845 Jim_Obj
*nameObjPtr
, *valObjPtr
;
2849 namebuf
= alloc_printf("%s(%d)", varname
, idx
);
2853 nameObjPtr
= Jim_NewStringObj(interp
, namebuf
, -1);
2860 Jim_IncrRefCount(nameObjPtr
);
2861 valObjPtr
= Jim_GetVariable(interp
, nameObjPtr
, JIM_ERRMSG
);
2862 Jim_DecrRefCount(interp
, nameObjPtr
);
2864 if (valObjPtr
== NULL
)
2867 result
= Jim_GetLong(interp
, valObjPtr
, &l
);
2868 /* printf("%s(%d) => 0%08x\n", varname, idx, val); */
2873 static int jim_array2mem(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
2875 command_context_t
*context
;
2878 context
= Jim_GetAssocData(interp
, "context");
2879 if (context
== NULL
){
2880 LOG_ERROR("array2mem: no command context");
2883 target
= get_current_target(context
);
2884 if (target
== NULL
){
2885 LOG_ERROR("array2mem: no current target");
2889 return target_array2mem( interp
,target
, argc
, argv
);
2893 static int target_array2mem(Jim_Interp
*interp
, target_t
*target
, int argc
, Jim_Obj
*const *argv
)
2901 const char *varname
;
2903 int i
, n
, e
, retval
;
2905 /* argv[1] = name of array to get the data
2906 * argv[2] = desired width
2907 * argv[3] = memory address
2908 * argv[4] = count to write
2911 Jim_WrongNumArgs(interp
, 1, argv
, "varname width addr nelems");
2914 varname
= Jim_GetString(argv
[1], &len
);
2915 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
2917 e
= Jim_GetLong(interp
, argv
[2], &l
);
2923 e
= Jim_GetLong(interp
, argv
[3], &l
);
2928 e
= Jim_GetLong(interp
, argv
[4], &l
);
2944 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2945 Jim_AppendStrings( interp
, Jim_GetResult(interp
), "Invalid width param, must be 8/16/32", NULL
);
2949 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2950 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: zero width read?", NULL
);
2953 if ((addr
+ (len
* width
)) < addr
) {
2954 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2955 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: addr + len - wraps to zero?", NULL
);
2958 /* absurd transfer size? */
2960 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2961 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: absurd > 64K item request", NULL
);
2966 ((width
== 2) && ((addr
& 1) == 0)) ||
2967 ((width
== 4) && ((addr
& 3) == 0))) {
2971 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2972 sprintf(buf
, "array2mem address: 0x%08x is not aligned for %d byte reads", addr
, width
);
2973 Jim_AppendStrings(interp
, Jim_GetResult(interp
), buf
, NULL
);
2985 /* Slurp... in buffer size chunks */
2987 count
= len
; /* in objects.. */
2988 if (count
> (sizeof(buffer
)/width
)) {
2989 count
= (sizeof(buffer
)/width
);
2992 v
= 0; /* shut up gcc */
2993 for (i
= 0 ;i
< count
;i
++, n
++) {
2994 get_int_array_element(interp
, varname
, n
, &v
);
2997 target_buffer_set_u32(target
, &buffer
[i
*width
], v
);
3000 target_buffer_set_u16(target
, &buffer
[i
*width
], v
);
3003 buffer
[i
] = v
& 0x0ff;
3009 retval
= target
->type
->write_memory(target
, addr
, width
, count
, buffer
);
3010 if (retval
!= ERROR_OK
) {
3012 LOG_ERROR("array2mem: Write @ 0x%08x, w=%d, cnt=%d, failed", addr
, width
, count
);
3013 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
3014 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: cannot read memory", NULL
);
3020 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
3026 target_all_handle_event( enum target_event e
)
3031 LOG_DEBUG( "**all*targets: event: %d, %s",
3033 Jim_Nvp_value2name_simple( nvp_target_event
, e
)->name
);
3035 target
= all_targets
;
3037 target_handle_event( target
, e
);
3038 target
= target
->next
;
3043 target_handle_event( target_t
*target
, enum target_event e
)
3045 target_event_action_t
*teap
;
3048 teap
= target
->event_action
;
3052 if( teap
->event
== e
){
3054 LOG_DEBUG( "target: (%d) %s (%s) event: %d (%s) action: %s\n",
3055 target
->target_number
,
3059 Jim_Nvp_value2name_simple( nvp_target_event
, e
)->name
,
3060 Jim_GetString( teap
->body
, NULL
) );
3061 if (Jim_EvalObj( interp
, teap
->body
)!=JIM_OK
)
3063 Jim_PrintErrorMessage(interp
);
3069 LOG_DEBUG( "event: %d %s - no action",
3071 Jim_Nvp_value2name_simple( nvp_target_event
, e
)->name
);
3075 enum target_cfg_param
{
3078 TCFG_WORK_AREA_VIRT
,
3079 TCFG_WORK_AREA_PHYS
,
3080 TCFG_WORK_AREA_SIZE
,
3081 TCFG_WORK_AREA_BACKUP
,
3084 TCFG_CHAIN_POSITION
,
3088 static Jim_Nvp nvp_config_opts
[] = {
3089 { .name
= "-type", .value
= TCFG_TYPE
},
3090 { .name
= "-event", .value
= TCFG_EVENT
},
3091 { .name
= "-work-area-virt", .value
= TCFG_WORK_AREA_VIRT
},
3092 { .name
= "-work-area-phys", .value
= TCFG_WORK_AREA_PHYS
},
3093 { .name
= "-work-area-size", .value
= TCFG_WORK_AREA_SIZE
},
3094 { .name
= "-work-area-backup", .value
= TCFG_WORK_AREA_BACKUP
},
3095 { .name
= "-endian" , .value
= TCFG_ENDIAN
},
3096 { .name
= "-variant", .value
= TCFG_VARIANT
},
3097 { .name
= "-chain-position", .value
= TCFG_CHAIN_POSITION
},
3099 { .name
= NULL
, .value
= -1 }
3104 target_configure( Jim_GetOptInfo
*goi
,
3114 /* parse config or cget options ... */
3115 while( goi
->argc
> 0 ){
3116 Jim_SetEmptyResult( goi
->interp
);
3117 //Jim_GetOpt_Debug( goi );
3119 if( target
->type
->target_jim_configure
){
3120 /* target defines a configure function */
3121 /* target gets first dibs on parameters */
3122 e
= (*(target
->type
->target_jim_configure
))( target
, goi
);
3131 /* otherwise we 'continue' below */
3133 e
= Jim_GetOpt_Nvp( goi
, nvp_config_opts
, &n
);
3135 Jim_GetOpt_NvpUnknown( goi
, nvp_config_opts
, 0 );
3141 if( goi
->isconfigure
){
3142 Jim_SetResult_sprintf( goi
->interp
, "not setable: %s", n
->name
);
3146 if( goi
->argc
!= 0 ){
3147 Jim_WrongNumArgs( goi
->interp
, goi
->argc
, goi
->argv
, "NO PARAMS");
3151 Jim_SetResultString( goi
->interp
, target
->type
->name
, -1 );
3155 if( goi
->argc
== 0 ){
3156 Jim_WrongNumArgs( goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name? ...");
3160 e
= Jim_GetOpt_Nvp( goi
, nvp_target_event
, &n
);
3162 Jim_GetOpt_NvpUnknown( goi
, nvp_target_event
, 1 );
3166 if( goi
->isconfigure
){
3167 if( goi
->argc
!= 1 ){
3168 Jim_WrongNumArgs( goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name? ?EVENT-BODY?");
3172 if( goi
->argc
!= 0 ){
3173 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name?");
3180 target_event_action_t
*teap
;
3182 teap
= target
->event_action
;
3183 /* replace existing? */
3185 if( teap
->event
== n
->value
){
3191 if( goi
->isconfigure
){
3194 teap
= calloc( 1, sizeof(*teap
) );
3196 teap
->event
= n
->value
;
3197 Jim_GetOpt_Obj( goi
, &o
);
3199 Jim_DecrRefCount( interp
, teap
->body
);
3201 teap
->body
= Jim_DuplicateObj( goi
->interp
, o
);
3204 * Tcl/TK - "tk events" have a nice feature.
3205 * See the "BIND" command.
3206 * We should support that here.
3207 * You can specify %X and %Y in the event code.
3208 * The idea is: %T - target name.
3209 * The idea is: %N - target number
3210 * The idea is: %E - event name.
3212 Jim_IncrRefCount( teap
->body
);
3214 /* add to head of event list */
3215 teap
->next
= target
->event_action
;
3216 target
->event_action
= teap
;
3217 Jim_SetEmptyResult(goi
->interp
);
3221 Jim_SetEmptyResult( goi
->interp
);
3223 Jim_SetResult( goi
->interp
, Jim_DuplicateObj( goi
->interp
, teap
->body
) );
3230 case TCFG_WORK_AREA_VIRT
:
3231 if( goi
->isconfigure
){
3232 target_free_all_working_areas(target
);
3233 e
= Jim_GetOpt_Wide( goi
, &w
);
3237 target
->working_area_virt
= w
;
3239 if( goi
->argc
!= 0 ){
3243 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_virt
) );
3247 case TCFG_WORK_AREA_PHYS
:
3248 if( goi
->isconfigure
){
3249 target_free_all_working_areas(target
);
3250 e
= Jim_GetOpt_Wide( goi
, &w
);
3254 target
->working_area_phys
= w
;
3256 if( goi
->argc
!= 0 ){
3260 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_phys
) );
3264 case TCFG_WORK_AREA_SIZE
:
3265 if( goi
->isconfigure
){
3266 target_free_all_working_areas(target
);
3267 e
= Jim_GetOpt_Wide( goi
, &w
);
3271 target
->working_area_size
= w
;
3273 if( goi
->argc
!= 0 ){
3277 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_size
) );
3281 case TCFG_WORK_AREA_BACKUP
:
3282 if( goi
->isconfigure
){
3283 target_free_all_working_areas(target
);
3284 e
= Jim_GetOpt_Wide( goi
, &w
);
3288 /* make this exactly 1 or 0 */
3289 target
->backup_working_area
= (!!w
);
3291 if( goi
->argc
!= 0 ){
3295 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_size
) );
3296 /* loop for more e*/
3300 if( goi
->isconfigure
){
3301 e
= Jim_GetOpt_Nvp( goi
, nvp_target_endian
, &n
);
3303 Jim_GetOpt_NvpUnknown( goi
, nvp_target_endian
, 1 );
3306 target
->endianness
= n
->value
;
3308 if( goi
->argc
!= 0 ){
3312 n
= Jim_Nvp_value2name_simple( nvp_target_endian
, target
->endianness
);
3313 if( n
->name
== NULL
){
3314 target
->endianness
= TARGET_LITTLE_ENDIAN
;
3315 n
= Jim_Nvp_value2name_simple( nvp_target_endian
, target
->endianness
);
3317 Jim_SetResultString( goi
->interp
, n
->name
, -1 );
3322 if( goi
->isconfigure
){
3323 if( goi
->argc
< 1 ){
3324 Jim_SetResult_sprintf( goi
->interp
,
3329 if( target
->variant
){
3330 free((void *)(target
->variant
));
3332 e
= Jim_GetOpt_String( goi
, &cp
, NULL
);
3333 target
->variant
= strdup(cp
);
3335 if( goi
->argc
!= 0 ){
3339 Jim_SetResultString( goi
->interp
, target
->variant
,-1 );
3342 case TCFG_CHAIN_POSITION
:
3343 if( goi
->isconfigure
){
3344 target_free_all_working_areas(target
);
3345 e
= Jim_GetOpt_Wide( goi
, &w
);
3349 /* make this exactly 1 or 0 */
3350 target
->chain_position
= w
;
3352 if( goi
->argc
!= 0 ){
3356 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->chain_position
) );
3357 /* loop for more e*/
3360 } /* while( goi->argc ) */
3361 /* done - we return */
3366 /** this is the 'tcl' handler for the target specific command */
3368 tcl_target_func( Jim_Interp
*interp
,
3370 Jim_Obj
*const *argv
)
3378 struct command_context_s
*cmd_ctx
;
3386 TS_CMD_MWW
, TS_CMD_MWH
, TS_CMD_MWB
,
3387 TS_CMD_MDW
, TS_CMD_MDH
, TS_CMD_MDB
,
3388 TS_CMD_MRW
, TS_CMD_MRH
, TS_CMD_MRB
,
3389 TS_CMD_MEM2ARRAY
, TS_CMD_ARRAY2MEM
,
3397 TS_CMD_INVOKE_EVENT
,
3400 static const Jim_Nvp target_options
[] = {
3401 { .name
= "configure", .value
= TS_CMD_CONFIGURE
},
3402 { .name
= "cget", .value
= TS_CMD_CGET
},
3403 { .name
= "mww", .value
= TS_CMD_MWW
},
3404 { .name
= "mwh", .value
= TS_CMD_MWH
},
3405 { .name
= "mwb", .value
= TS_CMD_MWB
},
3406 { .name
= "mdw", .value
= TS_CMD_MDW
},
3407 { .name
= "mdh", .value
= TS_CMD_MDH
},
3408 { .name
= "mdb", .value
= TS_CMD_MDB
},
3409 { .name
= "mem2array", .value
= TS_CMD_MEM2ARRAY
},
3410 { .name
= "array2mem", .value
= TS_CMD_ARRAY2MEM
},
3411 { .name
= "eventlist", .value
= TS_CMD_EVENTLIST
},
3412 { .name
= "curstate", .value
= TS_CMD_CURSTATE
},
3414 { .name
= "arp_examine", .value
= TS_CMD_EXAMINE
},
3415 { .name
= "arp_poll", .value
= TS_CMD_POLL
},
3416 { .name
= "arp_reset", .value
= TS_CMD_RESET
},
3417 { .name
= "arp_halt", .value
= TS_CMD_HALT
},
3418 { .name
= "arp_waitstate", .value
= TS_CMD_WAITSTATE
},
3419 { .name
= "invoke-event", .value
= TS_CMD_INVOKE_EVENT
},
3421 { .name
= NULL
, .value
= -1 },
3425 /* go past the "command" */
3426 Jim_GetOpt_Setup( &goi
, interp
, argc
-1, argv
+1 );
3428 target
= Jim_CmdPrivData( goi
.interp
);
3429 cmd_ctx
= Jim_GetAssocData(goi
.interp
, "context");
3431 /* commands here are in an NVP table */
3432 e
= Jim_GetOpt_Nvp( &goi
, target_options
, &n
);
3434 Jim_GetOpt_NvpUnknown( &goi
, target_options
, 0 );
3437 // Assume blank result
3438 Jim_SetEmptyResult( goi
.interp
);
3441 case TS_CMD_CONFIGURE
:
3443 Jim_WrongNumArgs( goi
.interp
, goi
.argc
, goi
.argv
, "missing: -option VALUE ...");
3446 goi
.isconfigure
= 1;
3447 return target_configure( &goi
, target
);
3449 // some things take params
3451 Jim_WrongNumArgs( goi
.interp
, 0, goi
.argv
, "missing: ?-option?");
3454 goi
.isconfigure
= 0;
3455 return target_configure( &goi
, target
);
3463 * argv[3] = optional count.
3466 if( (goi
.argc
== 3) || (goi
.argc
== 4) ){
3470 Jim_SetResult_sprintf( goi
.interp
, "expected: %s ADDR DATA [COUNT]", n
->name
);
3474 e
= Jim_GetOpt_Wide( &goi
, &a
);
3479 e
= Jim_GetOpt_Wide( &goi
, &b
);
3484 e
= Jim_GetOpt_Wide( &goi
, &c
);
3494 target_buffer_set_u32( target
, target_buf
, b
);
3498 target_buffer_set_u16( target
, target_buf
, b
);
3502 target_buffer_set_u8( target
, target_buf
, b
);
3506 for( x
= 0 ; x
< c
; x
++ ){
3507 e
= target
->type
->write_memory( target
, a
, b
, 1, target_buf
);
3508 if( e
!= ERROR_OK
){
3509 Jim_SetResult_sprintf( interp
, "Error writing @ 0x%08x: %d\n", (int)(a
), e
);
3522 /* argv[0] = command
3524 * argv[2] = optional count
3526 if( (goi
.argc
== 2) || (goi
.argc
== 3) ){
3527 Jim_SetResult_sprintf( goi
.interp
, "expected: %s ADDR [COUNT]", n
->name
);
3530 e
= Jim_GetOpt_Wide( &goi
, &a
);
3535 e
= Jim_GetOpt_Wide( &goi
, &c
);
3542 b
= 1; /* shut up gcc */
3555 /* convert to "bytes" */
3557 /* count is now in 'BYTES' */
3563 e
= target
->type
->read_memory( target
, a
, b
, y
/ b
, target_buf
);
3564 if( e
!= ERROR_OK
){
3565 Jim_SetResult_sprintf( interp
, "error reading target @ 0x%08lx", (int)(a
) );
3569 Jim_fprintf( interp
, interp
->cookie_stdout
, "0x%08x ", (int)(a
) );
3572 for( x
= 0 ; (x
< 16) && (x
< y
) ; x
+= 4 ){
3573 z
= target_buffer_get_u32( target
, &(target_buf
[ x
* 4 ]) );
3574 Jim_fprintf( interp
, interp
->cookie_stdout
, "%08x ", (int)(z
) );
3576 for( ; (x
< 16) ; x
+= 4 ){
3577 Jim_fprintf( interp
, interp
->cookie_stdout
, " " );
3581 for( x
= 0 ; (x
< 16) && (x
< y
) ; x
+= 2 ){
3582 z
= target_buffer_get_u16( target
, &(target_buf
[ x
* 2 ]) );
3583 Jim_fprintf( interp
, interp
->cookie_stdout
, "%04x ", (int)(z
) );
3585 for( ; (x
< 16) ; x
+= 2 ){
3586 Jim_fprintf( interp
, interp
->cookie_stdout
, " " );
3591 for( x
= 0 ; (x
< 16) && (x
< y
) ; x
+= 1 ){
3592 z
= target_buffer_get_u8( target
, &(target_buf
[ x
* 4 ]) );
3593 Jim_fprintf( interp
, interp
->cookie_stdout
, "%02x ", (int)(z
) );
3595 for( ; (x
< 16) ; x
+= 1 ){
3596 Jim_fprintf( interp
, interp
->cookie_stdout
, " " );
3600 /* ascii-ify the bytes */
3601 for( x
= 0 ; x
< y
; x
++ ){
3602 if( (target_buf
[x
] >= 0x20) &&
3603 (target_buf
[x
] <= 0x7e) ){
3607 target_buf
[x
] = '.';
3612 target_buf
[x
] = ' ';
3617 /* print - with a newline */
3618 Jim_fprintf( interp
, interp
->cookie_stdout
, "%s\n", target_buf
);
3624 case TS_CMD_MEM2ARRAY
:
3625 return target_mem2array( goi
.interp
, target
, goi
.argc
, goi
.argv
);
3627 case TS_CMD_ARRAY2MEM
:
3628 return target_array2mem( goi
.interp
, target
, goi
.argc
, goi
.argv
);
3630 case TS_CMD_EXAMINE
:
3632 Jim_WrongNumArgs( goi
.interp
, 2, argv
, "[no parameters]");
3635 e
= target
->type
->examine( target
);
3636 if( e
!= ERROR_OK
){
3637 Jim_SetResult_sprintf( interp
, "examine-fails: %d", e
);
3643 Jim_WrongNumArgs( goi
.interp
, 2, argv
, "[no parameters]");
3646 if( !(target
->type
->examined
) ){
3647 e
= ERROR_TARGET_NOT_EXAMINED
;
3649 e
= target
->type
->poll( target
);
3651 if( e
!= ERROR_OK
){
3652 Jim_SetResult_sprintf( interp
, "poll-fails: %d", e
);
3659 if( goi
.argc
!= 2 ){
3660 Jim_WrongNumArgs( interp
, 2, argv
, "t|f|assert|deassert BOOL");
3663 e
= Jim_GetOpt_Nvp( &goi
, nvp_assert
, &n
);
3665 Jim_GetOpt_NvpUnknown( &goi
, nvp_assert
, 1 );
3668 // the halt or not param
3669 e
= Jim_GetOpt_Wide( &goi
, &a
);
3673 // determine if we should halt or not.
3674 target
->reset_halt
= !!a
;
3675 // When this happens - all workareas are invalid.
3676 target_free_all_working_areas_restore(target
, 0);
3679 if( n
->value
== NVP_ASSERT
){
3680 target
->type
->assert_reset( target
);
3682 target
->type
->deassert_reset( target
);
3687 Jim_WrongNumArgs( goi
.interp
, 0, argv
, "halt [no parameters]");
3690 target
->type
->halt( target
);
3692 case TS_CMD_WAITSTATE
:
3693 // params: <name> statename timeoutmsecs
3694 if( goi
.argc
!= 2 ){
3695 Jim_SetResult_sprintf( goi
.interp
, "%s STATENAME TIMEOUTMSECS", n
->name
);
3698 e
= Jim_GetOpt_Nvp( &goi
, nvp_target_state
, &n
);
3700 Jim_GetOpt_NvpUnknown( &goi
, nvp_target_state
,1 );
3703 e
= Jim_GetOpt_Wide( &goi
, &a
);
3707 e
= target_wait_state( target
, n
->value
, a
);
3708 if( e
!= ERROR_OK
){
3709 Jim_SetResult_sprintf( goi
.interp
,
3710 "target: %s wait %s fails (%d) %s",
3713 e
, target_strerror_safe(e
) );
3718 case TS_CMD_EVENTLIST
:
3719 /* List for human, Events defined for this target.
3720 * scripts/programs should use 'name cget -event NAME'
3723 target_event_action_t
*teap
;
3724 teap
= target
->event_action
;
3725 command_print( cmd_ctx
, "Event actions for target (%d) %s\n",
3726 target
->target_number
,
3728 command_print( cmd_ctx
, "%-25s | Body", "Event");
3729 command_print( cmd_ctx
, "------------------------- | ----------------------------------------");
3731 command_print( cmd_ctx
,
3733 Jim_Nvp_value2name_simple( nvp_target_event
, teap
->event
)->name
,
3734 Jim_GetString( teap
->body
, NULL
) );
3737 command_print( cmd_ctx
, "***END***");
3740 case TS_CMD_CURSTATE
:
3741 if( goi
.argc
!= 0 ){
3742 Jim_WrongNumArgs( goi
.interp
, 0, argv
, "[no parameters]");
3745 Jim_SetResultString( goi
.interp
,
3746 Jim_Nvp_value2name_simple(nvp_target_state
,target
->state
)->name
,-1);
3748 case TS_CMD_INVOKE_EVENT
:
3749 if( goi
.argc
!= 1 ){
3750 Jim_SetResult_sprintf( goi
.interp
, "%s ?EVENTNAME?",n
->name
);
3753 e
= Jim_GetOpt_Nvp( &goi
, nvp_target_event
, &n
);
3755 Jim_GetOpt_NvpUnknown( &goi
, nvp_target_event
, 1 );
3758 target_handle_event( target
, n
->value
);
3766 target_create( Jim_GetOptInfo
*goi
)
3776 struct command_context_s
*cmd_ctx
;
3778 cmd_ctx
= Jim_GetAssocData(goi
->interp
, "context");
3779 if( goi
->argc
< 3 ){
3780 Jim_WrongNumArgs( goi
->interp
, 1, goi
->argv
, "?name? ?type? ..options...");
3785 Jim_GetOpt_Obj( goi
, &new_cmd
);
3786 /* does this command exist? */
3787 cmd
= Jim_GetCommand( goi
->interp
, new_cmd
, JIM_ERRMSG
);
3789 cp
= Jim_GetString( new_cmd
, NULL
);
3790 Jim_SetResult_sprintf(goi
->interp
, "Command/target: %s Exists", cp
);
3795 e
= Jim_GetOpt_String( goi
, &cp2
, NULL
);
3797 /* now does target type exist */
3798 for( x
= 0 ; target_types
[x
] ; x
++ ){
3799 if( 0 == strcmp( cp
, target_types
[x
]->name
) ){
3804 if( target_types
[x
] == NULL
){
3805 Jim_SetResult_sprintf( goi
->interp
, "Unknown target type %s, try one of ", cp
);
3806 for( x
= 0 ; target_types
[x
] ; x
++ ){
3807 if( target_types
[x
+1] ){
3808 Jim_AppendStrings( goi
->interp
,
3809 Jim_GetResult(goi
->interp
),
3810 target_types
[x
]->name
,
3813 Jim_AppendStrings( goi
->interp
,
3814 Jim_GetResult(goi
->interp
),
3816 target_types
[x
]->name
,NULL
);
3824 target
= calloc(1,sizeof(target_t
));
3825 /* set target number */
3826 target
->target_number
= new_target_number();
3828 /* allocate memory for each unique target type */
3829 target
->type
= (target_type_t
*)calloc(1,sizeof(target_type_t
));
3831 memcpy( target
->type
, target_types
[x
], sizeof(target_type_t
));
3833 /* will be set by "-endian" */
3834 target
->endianness
= TARGET_ENDIAN_UNKNOWN
;
3836 target
->working_area
= 0x0;
3837 target
->working_area_size
= 0x0;
3838 target
->working_areas
= NULL
;
3839 target
->backup_working_area
= 0;
3841 target
->state
= TARGET_UNKNOWN
;
3842 target
->debug_reason
= DBG_REASON_UNDEFINED
;
3843 target
->reg_cache
= NULL
;
3844 target
->breakpoints
= NULL
;
3845 target
->watchpoints
= NULL
;
3846 target
->next
= NULL
;
3847 target
->arch_info
= NULL
;
3849 target
->display
= 1;
3851 /* initialize trace information */
3852 target
->trace_info
= malloc(sizeof(trace_t
));
3853 target
->trace_info
->num_trace_points
= 0;
3854 target
->trace_info
->trace_points_size
= 0;
3855 target
->trace_info
->trace_points
= NULL
;
3856 target
->trace_info
->trace_history_size
= 0;
3857 target
->trace_info
->trace_history
= NULL
;
3858 target
->trace_info
->trace_history_pos
= 0;
3859 target
->trace_info
->trace_history_overflowed
= 0;
3861 target
->dbgmsg
= NULL
;
3862 target
->dbg_msg_enabled
= 0;
3864 target
->endianness
= TARGET_ENDIAN_UNKNOWN
;
3866 /* Do the rest as "configure" options */
3867 goi
->isconfigure
= 1;
3868 e
= target_configure( goi
, target
);
3870 free( target
->type
);
3875 if( target
->endianness
== TARGET_ENDIAN_UNKNOWN
){
3876 /* default endian to little if not specified */
3877 target
->endianness
= TARGET_LITTLE_ENDIAN
;
3880 /* create the target specific commands */
3881 if( target
->type
->register_commands
){
3882 (*(target
->type
->register_commands
))( cmd_ctx
);
3884 if( target
->type
->target_create
){
3885 (*(target
->type
->target_create
))( target
, goi
->interp
);
3888 /* append to end of list */
3891 tpp
= &(all_targets
);
3893 tpp
= &( (*tpp
)->next
);
3898 cp
= Jim_GetString( new_cmd
, NULL
);
3899 target
->cmd_name
= strdup(cp
);
3901 /* now - create the new target name command */
3902 e
= Jim_CreateCommand( goi
->interp
,
3905 tcl_target_func
, /* C function */
3906 target
, /* private data */
3907 NULL
); /* no del proc */
3913 jim_target( Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
3917 struct command_context_s
*cmd_ctx
;
3922 /* TG = target generic */
3930 const char *target_cmds
[] = {
3931 "create", "types", "names", "current", "number",
3936 LOG_DEBUG("Target command params:");
3937 LOG_DEBUG(Jim_Debug_ArgvString( interp
, argc
, argv
) );
3939 cmd_ctx
= Jim_GetAssocData( interp
, "context" );
3941 Jim_GetOpt_Setup( &goi
, interp
, argc
-1, argv
+1 );
3943 if( goi
.argc
== 0 ){
3944 Jim_WrongNumArgs(interp
, 1, argv
, "missing: command ...");
3948 /* is this old syntax? */
3949 /* To determine: We have to peek at argv[0]*/
3950 cp
= Jim_GetString( goi
.argv
[0], NULL
);
3951 for( x
= 0 ; target_types
[x
] ; x
++ ){
3952 if( 0 == strcmp(cp
,target_types
[x
]->name
) ){
3956 if( target_types
[x
] ){
3957 /* YES IT IS OLD SYNTAX */
3958 Jim_Obj
*new_argv
[10];
3961 /* target_old_syntax
3963 * It appears that there are 2 old syntaxes:
3965 * target <typename> <endian> <chain position> <variant>
3969 * target <typename> <endian> <reset mode> <chain position> <variant>
3973 /* The minimum number of arguments is 4 */
3975 Jim_WrongNumArgs( interp
, 1, argv
, "[OLDSYNTAX] ?TYPE? ?ENDIAN? ?CHAIN-POSITION? ?VARIANT?");
3980 new_argv
[0] = argv
[0];
3981 new_argv
[1] = Jim_NewStringObj( interp
, "create", -1 );
3984 sprintf( buf
, "target%d", new_target_number() );
3985 new_argv
[2] = Jim_NewStringObj( interp
, buf
, -1 );
3987 new_argv
[3] = goi
.argv
[0]; /* typename */
3988 new_argv
[4] = Jim_NewStringObj( interp
, "-endian", -1 );
3989 new_argv
[5] = goi
.argv
[1];
3990 new_argv
[6] = Jim_NewStringObj( interp
, "-chain-position", -1 );
3992 /* If goi.argv[2] is not a number, we need to skip it since it is the reset mode. */
3994 int chain_position_argv
= 2;
3995 if (JIM_ERR
== Jim_GetWide(interp
, goi
.argv
[chain_position_argv
], &w
)) {
3996 if (chain_position_argv
+ 1 < goi
.argc
) {
3997 chain_position_argv
+= 1;
3999 Jim_WrongNumArgs( interp
, 1, argv
, "[OLDSYNTAX] ?TYPE? ?ENDIAN? ?RESET? ?CHAIN-POSITION? ?VARIANT?");
4004 new_argv
[7] = goi
.argv
[chain_position_argv
];
4006 /* Only provide a variant configure option if there was a variant specified */
4007 if (chain_position_argv
+ 1 < goi
.argc
) {
4008 new_argv
[8] = Jim_NewStringObj( interp
, "-variant", -1 );
4009 new_argv
[9] = goi
.argv
[chain_position_argv
+ 1];
4020 * argv[3] = typename
4023 * argv[6] = -position
4025 * argv[8] = -variant
4026 * argv[9] = "somestring"
4029 /* don't let these be released */
4030 for( x
= 0 ; x
< new_argc
; x
++ ){
4031 Jim_IncrRefCount( new_argv
[x
]);
4034 LOG_DEBUG("Target OLD SYNTAX - converted to new syntax");
4036 r
= jim_target( goi
.interp
, new_argc
, new_argv
);
4038 /* release? these items */
4039 for( x
= 0 ; x
< new_argc
; x
++ ){
4040 Jim_DecrRefCount( interp
, new_argv
[x
] );
4045 //Jim_GetOpt_Debug( &goi );
4046 r
= Jim_GetOpt_Enum( &goi
, target_cmds
, &x
);
4053 Jim_Panic(goi
.interp
,"Why am I here?");
4055 case TG_CMD_CURRENT
:
4056 if( goi
.argc
!= 0 ){
4057 Jim_WrongNumArgs( goi
.interp
, 1, goi
.argv
, "Too many parameters");
4060 Jim_SetResultString( goi
.interp
, get_current_target( cmd_ctx
)->cmd_name
, -1 );
4063 if( goi
.argc
!= 0 ){
4064 Jim_WrongNumArgs( goi
.interp
, 1, goi
.argv
, "Too many parameters" );
4067 Jim_SetResult( goi
.interp
, Jim_NewListObj( goi
.interp
, NULL
, 0 ) );
4068 for( x
= 0 ; target_types
[x
] ; x
++ ){
4069 Jim_ListAppendElement( goi
.interp
,
4070 Jim_GetResult(goi
.interp
),
4071 Jim_NewStringObj( goi
.interp
, target_types
[x
]->name
, -1 ) );
4075 if( goi
.argc
!= 0 ){
4076 Jim_WrongNumArgs( goi
.interp
, 1, goi
.argv
, "Too many parameters" );
4079 Jim_SetResult( goi
.interp
, Jim_NewListObj( goi
.interp
, NULL
, 0 ) );
4080 target
= all_targets
;
4082 Jim_ListAppendElement( goi
.interp
,
4083 Jim_GetResult(goi
.interp
),
4084 Jim_NewStringObj( goi
.interp
, target
->cmd_name
, -1 ) );
4085 target
= target
->next
;
4090 Jim_WrongNumArgs( goi
.interp
, goi
.argc
, goi
.argv
, "?name ... config options ...");
4093 return target_create( &goi
);
4096 if( goi
.argc
!= 1 ){
4097 Jim_SetResult_sprintf( goi
.interp
, "expected: target number ?NUMBER?");
4100 e
= Jim_GetOpt_Wide( &goi
, &w
);
4106 t
= get_target_by_num(w
);
4108 Jim_SetResult_sprintf( goi
.interp
,"Target: number %d does not exist", (int)(w
));
4111 Jim_SetResultString( goi
.interp
, t
->cmd_name
, -1 );
4115 if( goi
.argc
!= 0 ){
4116 Jim_WrongNumArgs( goi
.interp
, 0, goi
.argv
, "<no parameters>");
4119 Jim_SetResult( goi
.interp
,
4120 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)