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 ***************************************************************************/
37 #include "target_request.h"
38 #include "time_support.h"
47 static int handle_targets_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
49 static int handle_reg_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
50 static int handle_poll_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
51 static int handle_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
52 static int handle_wait_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
53 static int handle_reset_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
54 static int handle_soft_reset_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
55 static int handle_resume_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
56 static int handle_step_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
57 static int handle_md_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
58 static int handle_mw_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
59 static int handle_load_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
60 static int handle_dump_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
61 static int handle_verify_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
62 static int handle_test_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
63 static int handle_bp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
64 static int handle_rbp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
65 static int handle_wp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
66 static int handle_rwp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
67 static int handle_virt2phys_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
);
68 static int handle_profile_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
69 static int handle_fast_load_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
70 static int handle_fast_load_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
72 static int jim_array2mem(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
);
73 static int jim_mem2array(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
);
74 static int jim_target( Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
);
76 static int target_array2mem(Jim_Interp
*interp
, target_t
*target
, int argc
, Jim_Obj
*const *argv
);
77 static int target_mem2array(Jim_Interp
*interp
, target_t
*target
, int argc
, Jim_Obj
*const *argv
);
80 extern target_type_t arm7tdmi_target
;
81 extern target_type_t arm720t_target
;
82 extern target_type_t arm9tdmi_target
;
83 extern target_type_t arm920t_target
;
84 extern target_type_t arm966e_target
;
85 extern target_type_t arm926ejs_target
;
86 extern target_type_t feroceon_target
;
87 extern target_type_t xscale_target
;
88 extern target_type_t cortexm3_target
;
89 extern target_type_t cortexa8_target
;
90 extern target_type_t arm11_target
;
91 extern target_type_t mips_m4k_target
;
92 extern target_type_t avr_target
;
94 target_type_t
*target_types
[] =
112 target_t
*all_targets
= NULL
;
113 target_event_callback_t
*target_event_callbacks
= NULL
;
114 target_timer_callback_t
*target_timer_callbacks
= NULL
;
116 const Jim_Nvp nvp_assert
[] = {
117 { .name
= "assert", NVP_ASSERT
},
118 { .name
= "deassert", NVP_DEASSERT
},
119 { .name
= "T", NVP_ASSERT
},
120 { .name
= "F", NVP_DEASSERT
},
121 { .name
= "t", NVP_ASSERT
},
122 { .name
= "f", NVP_DEASSERT
},
123 { .name
= NULL
, .value
= -1 }
126 const Jim_Nvp nvp_error_target
[] = {
127 { .value
= ERROR_TARGET_INVALID
, .name
= "err-invalid" },
128 { .value
= ERROR_TARGET_INIT_FAILED
, .name
= "err-init-failed" },
129 { .value
= ERROR_TARGET_TIMEOUT
, .name
= "err-timeout" },
130 { .value
= ERROR_TARGET_NOT_HALTED
, .name
= "err-not-halted" },
131 { .value
= ERROR_TARGET_FAILURE
, .name
= "err-failure" },
132 { .value
= ERROR_TARGET_UNALIGNED_ACCESS
, .name
= "err-unaligned-access" },
133 { .value
= ERROR_TARGET_DATA_ABORT
, .name
= "err-data-abort" },
134 { .value
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
, .name
= "err-resource-not-available" },
135 { .value
= ERROR_TARGET_TRANSLATION_FAULT
, .name
= "err-translation-fault" },
136 { .value
= ERROR_TARGET_NOT_RUNNING
, .name
= "err-not-running" },
137 { .value
= ERROR_TARGET_NOT_EXAMINED
, .name
= "err-not-examined" },
138 { .value
= -1, .name
= NULL
}
141 const char *target_strerror_safe( int err
)
145 n
= Jim_Nvp_value2name_simple( nvp_error_target
, err
);
146 if( n
->name
== NULL
){
153 const Jim_Nvp nvp_target_event
[] = {
154 { .value
= TARGET_EVENT_OLD_gdb_program_config
, .name
= "old-gdb_program_config" },
155 { .value
= TARGET_EVENT_OLD_pre_resume
, .name
= "old-pre_resume" },
157 { .value
= TARGET_EVENT_EARLY_HALTED
, .name
= "early-halted" },
158 { .value
= TARGET_EVENT_HALTED
, .name
= "halted" },
159 { .value
= TARGET_EVENT_RESUMED
, .name
= "resumed" },
160 { .value
= TARGET_EVENT_RESUME_START
, .name
= "resume-start" },
161 { .value
= TARGET_EVENT_RESUME_END
, .name
= "resume-end" },
163 { .name
= "gdb-start", .value
= TARGET_EVENT_GDB_START
},
164 { .name
= "gdb-end", .value
= TARGET_EVENT_GDB_END
},
166 /* historical name */
168 { .value
= TARGET_EVENT_RESET_START
, .name
= "reset-start" },
170 { .value
= TARGET_EVENT_RESET_ASSERT_PRE
, .name
= "reset-assert-pre" },
171 { .value
= TARGET_EVENT_RESET_ASSERT_POST
, .name
= "reset-assert-post" },
172 { .value
= TARGET_EVENT_RESET_DEASSERT_PRE
, .name
= "reset-deassert-pre" },
173 { .value
= TARGET_EVENT_RESET_DEASSERT_POST
, .name
= "reset-deassert-post" },
174 { .value
= TARGET_EVENT_RESET_HALT_PRE
, .name
= "reset-halt-pre" },
175 { .value
= TARGET_EVENT_RESET_HALT_POST
, .name
= "reset-halt-post" },
176 { .value
= TARGET_EVENT_RESET_WAIT_PRE
, .name
= "reset-wait-pre" },
177 { .value
= TARGET_EVENT_RESET_WAIT_POST
, .name
= "reset-wait-post" },
178 { .value
= TARGET_EVENT_RESET_INIT
, .name
= "reset-init" },
179 { .value
= TARGET_EVENT_RESET_END
, .name
= "reset-end" },
181 { .value
= TARGET_EVENT_EXAMINE_START
, .name
= "examine-start" },
182 { .value
= TARGET_EVENT_EXAMINE_END
, .name
= "examine-end" },
184 { .value
= TARGET_EVENT_DEBUG_HALTED
, .name
= "debug-halted" },
185 { .value
= TARGET_EVENT_DEBUG_RESUMED
, .name
= "debug-resumed" },
187 { .value
= TARGET_EVENT_GDB_ATTACH
, .name
= "gdb-attach" },
188 { .value
= TARGET_EVENT_GDB_DETACH
, .name
= "gdb-detach" },
190 { .value
= TARGET_EVENT_GDB_FLASH_WRITE_START
, .name
= "gdb-flash-write-start" },
191 { .value
= TARGET_EVENT_GDB_FLASH_WRITE_END
, .name
= "gdb-flash-write-end" },
193 { .value
= TARGET_EVENT_GDB_FLASH_ERASE_START
, .name
= "gdb-flash-erase-start" },
194 { .value
= TARGET_EVENT_GDB_FLASH_ERASE_END
, .name
= "gdb-flash-erase-end" },
196 { .value
= TARGET_EVENT_RESUME_START
, .name
= "resume-start" },
197 { .value
= TARGET_EVENT_RESUMED
, .name
= "resume-ok" },
198 { .value
= TARGET_EVENT_RESUME_END
, .name
= "resume-end" },
200 { .name
= NULL
, .value
= -1 }
203 const Jim_Nvp nvp_target_state
[] = {
204 { .name
= "unknown", .value
= TARGET_UNKNOWN
},
205 { .name
= "running", .value
= TARGET_RUNNING
},
206 { .name
= "halted", .value
= TARGET_HALTED
},
207 { .name
= "reset", .value
= TARGET_RESET
},
208 { .name
= "debug-running", .value
= TARGET_DEBUG_RUNNING
},
209 { .name
= NULL
, .value
= -1 },
212 const Jim_Nvp nvp_target_debug_reason
[] = {
213 { .name
= "debug-request" , .value
= DBG_REASON_DBGRQ
},
214 { .name
= "breakpoint" , .value
= DBG_REASON_BREAKPOINT
},
215 { .name
= "watchpoint" , .value
= DBG_REASON_WATCHPOINT
},
216 { .name
= "watchpoint-and-breakpoint", .value
= DBG_REASON_WPTANDBKPT
},
217 { .name
= "single-step" , .value
= DBG_REASON_SINGLESTEP
},
218 { .name
= "target-not-halted" , .value
= DBG_REASON_NOTHALTED
},
219 { .name
= "undefined" , .value
= DBG_REASON_UNDEFINED
},
220 { .name
= NULL
, .value
= -1 },
223 const Jim_Nvp nvp_target_endian
[] = {
224 { .name
= "big", .value
= TARGET_BIG_ENDIAN
},
225 { .name
= "little", .value
= TARGET_LITTLE_ENDIAN
},
226 { .name
= "be", .value
= TARGET_BIG_ENDIAN
},
227 { .name
= "le", .value
= TARGET_LITTLE_ENDIAN
},
228 { .name
= NULL
, .value
= -1 },
231 const Jim_Nvp nvp_reset_modes
[] = {
232 { .name
= "unknown", .value
= RESET_UNKNOWN
},
233 { .name
= "run" , .value
= RESET_RUN
},
234 { .name
= "halt" , .value
= RESET_HALT
},
235 { .name
= "init" , .value
= RESET_INIT
},
236 { .name
= NULL
, .value
= -1 },
239 static int max_target_number(void)
247 if( x
< t
->target_number
){
248 x
= (t
->target_number
)+1;
255 /* determine the number of the new target */
256 static int new_target_number(void)
261 /* number is 0 based */
265 if( x
< t
->target_number
){
266 x
= t
->target_number
;
273 static int target_continous_poll
= 1;
275 /* read a u32 from a buffer in target memory endianness */
276 u32
target_buffer_get_u32(target_t
*target
, u8
*buffer
)
278 if (target
->endianness
== TARGET_LITTLE_ENDIAN
)
279 return le_to_h_u32(buffer
);
281 return be_to_h_u32(buffer
);
284 /* read a u16 from a buffer in target memory endianness */
285 u16
target_buffer_get_u16(target_t
*target
, u8
*buffer
)
287 if (target
->endianness
== TARGET_LITTLE_ENDIAN
)
288 return le_to_h_u16(buffer
);
290 return be_to_h_u16(buffer
);
293 /* read a u8 from a buffer in target memory endianness */
294 u8
target_buffer_get_u8(target_t
*target
, u8
*buffer
)
296 return *buffer
& 0x0ff;
299 /* write a u32 to a buffer in target memory endianness */
300 void target_buffer_set_u32(target_t
*target
, u8
*buffer
, u32 value
)
302 if (target
->endianness
== TARGET_LITTLE_ENDIAN
)
303 h_u32_to_le(buffer
, value
);
305 h_u32_to_be(buffer
, value
);
308 /* write a u16 to a buffer in target memory endianness */
309 void target_buffer_set_u16(target_t
*target
, u8
*buffer
, u16 value
)
311 if (target
->endianness
== TARGET_LITTLE_ENDIAN
)
312 h_u16_to_le(buffer
, value
);
314 h_u16_to_be(buffer
, value
);
317 /* write a u8 to a buffer in target memory endianness */
318 void target_buffer_set_u8(target_t
*target
, u8
*buffer
, u8 value
)
323 /* returns a pointer to the n-th configured target */
324 target_t
* get_target_by_num(int num
)
326 target_t
*target
= all_targets
;
329 if( target
->target_number
== num
){
332 target
= target
->next
;
338 int get_num_by_target(target_t
*query_target
)
340 return query_target
->target_number
;
343 target_t
* get_current_target(command_context_t
*cmd_ctx
)
345 target_t
*target
= get_target_by_num(cmd_ctx
->current_target
);
349 LOG_ERROR("BUG: current_target out of bounds");
356 int target_poll(struct target_s
*target
)
358 /* We can't poll until after examine */
359 if (!target
->type
->examined
)
361 /* Fail silently lest we pollute the log */
364 return target
->type
->poll(target
);
367 int target_halt(struct target_s
*target
)
369 /* We can't poll until after examine */
370 if (!target
->type
->examined
)
372 LOG_ERROR("Target not examined yet");
375 return target
->type
->halt(target
);
378 int target_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
382 /* We can't poll until after examine */
383 if (!target
->type
->examined
)
385 LOG_ERROR("Target not examined yet");
389 /* note that resume *must* be asynchronous. The CPU can halt before we poll. The CPU can
390 * even halt at the current PC as a result of a software breakpoint being inserted by (a bug?)
393 if ((retval
= target
->type
->resume(target
, current
, address
, handle_breakpoints
, debug_execution
)) != ERROR_OK
)
399 int target_process_reset(struct command_context_s
*cmd_ctx
, enum target_reset_mode reset_mode
)
404 n
= Jim_Nvp_value2name_simple( nvp_reset_modes
, reset_mode
);
405 if( n
->name
== NULL
){
406 LOG_ERROR("invalid reset mode");
410 sprintf( buf
, "ocd_process_reset %s", n
->name
);
411 retval
= Jim_Eval( interp
, buf
);
413 if(retval
!= JIM_OK
) {
414 Jim_PrintErrorMessage(interp
);
418 /* We want any events to be processed before the prompt */
419 retval
= target_call_timer_callbacks_now();
424 static int default_virt2phys(struct target_s
*target
, u32
virtual, u32
*physical
)
430 static int default_mmu(struct target_s
*target
, int *enabled
)
436 static int default_examine(struct target_s
*target
)
438 target
->type
->examined
= 1;
442 /* Targets that correctly implement init+examine, i.e.
443 * no communication with target during init:
447 int target_examine(void)
449 int retval
= ERROR_OK
;
450 target_t
*target
= all_targets
;
453 if ((retval
= target
->type
->examine(target
))!=ERROR_OK
)
455 target
= target
->next
;
460 static int target_write_memory_imp(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
462 if (!target
->type
->examined
)
464 LOG_ERROR("Target not examined yet");
467 return target
->type
->write_memory_imp(target
, address
, size
, count
, buffer
);
470 static int target_read_memory_imp(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
472 if (!target
->type
->examined
)
474 LOG_ERROR("Target not examined yet");
477 return target
->type
->read_memory_imp(target
, address
, size
, count
, buffer
);
480 static int target_soft_reset_halt_imp(struct target_s
*target
)
482 if (!target
->type
->examined
)
484 LOG_ERROR("Target not examined yet");
487 return target
->type
->soft_reset_halt_imp(target
);
490 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
)
492 if (!target
->type
->examined
)
494 LOG_ERROR("Target not examined yet");
497 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
);
500 int target_init(struct command_context_s
*cmd_ctx
)
502 target_t
*target
= all_targets
;
507 target
->type
->examined
= 0;
508 if (target
->type
->examine
== NULL
)
510 target
->type
->examine
= default_examine
;
513 if ((retval
= target
->type
->init_target(cmd_ctx
, target
)) != ERROR_OK
)
515 LOG_ERROR("target '%s' init failed", target
->type
->name
);
519 /* Set up default functions if none are provided by target */
520 if (target
->type
->virt2phys
== NULL
)
522 target
->type
->virt2phys
= default_virt2phys
;
524 target
->type
->virt2phys
= default_virt2phys
;
525 /* a non-invasive way(in terms of patches) to add some code that
526 * runs before the type->write/read_memory implementation
528 target
->type
->write_memory_imp
= target
->type
->write_memory
;
529 target
->type
->write_memory
= target_write_memory_imp
;
530 target
->type
->read_memory_imp
= target
->type
->read_memory
;
531 target
->type
->read_memory
= target_read_memory_imp
;
532 target
->type
->soft_reset_halt_imp
= target
->type
->soft_reset_halt
;
533 target
->type
->soft_reset_halt
= target_soft_reset_halt_imp
;
534 target
->type
->run_algorithm_imp
= target
->type
->run_algorithm
;
535 target
->type
->run_algorithm
= target_run_algorithm_imp
;
537 if (target
->type
->mmu
== NULL
)
539 target
->type
->mmu
= default_mmu
;
541 target
= target
->next
;
546 if((retval
= target_register_user_commands(cmd_ctx
)) != ERROR_OK
)
548 if((retval
= target_register_timer_callback(handle_target
, 100, 1, NULL
)) != ERROR_OK
)
555 int target_register_event_callback(int (*callback
)(struct target_s
*target
, enum target_event event
, void *priv
), void *priv
)
557 target_event_callback_t
**callbacks_p
= &target_event_callbacks
;
559 if (callback
== NULL
)
561 return ERROR_INVALID_ARGUMENTS
;
566 while ((*callbacks_p
)->next
)
567 callbacks_p
= &((*callbacks_p
)->next
);
568 callbacks_p
= &((*callbacks_p
)->next
);
571 (*callbacks_p
) = malloc(sizeof(target_event_callback_t
));
572 (*callbacks_p
)->callback
= callback
;
573 (*callbacks_p
)->priv
= priv
;
574 (*callbacks_p
)->next
= NULL
;
579 int target_register_timer_callback(int (*callback
)(void *priv
), int time_ms
, int periodic
, void *priv
)
581 target_timer_callback_t
**callbacks_p
= &target_timer_callbacks
;
584 if (callback
== NULL
)
586 return ERROR_INVALID_ARGUMENTS
;
591 while ((*callbacks_p
)->next
)
592 callbacks_p
= &((*callbacks_p
)->next
);
593 callbacks_p
= &((*callbacks_p
)->next
);
596 (*callbacks_p
) = malloc(sizeof(target_timer_callback_t
));
597 (*callbacks_p
)->callback
= callback
;
598 (*callbacks_p
)->periodic
= periodic
;
599 (*callbacks_p
)->time_ms
= time_ms
;
601 gettimeofday(&now
, NULL
);
602 (*callbacks_p
)->when
.tv_usec
= now
.tv_usec
+ (time_ms
% 1000) * 1000;
603 time_ms
-= (time_ms
% 1000);
604 (*callbacks_p
)->when
.tv_sec
= now
.tv_sec
+ (time_ms
/ 1000);
605 if ((*callbacks_p
)->when
.tv_usec
> 1000000)
607 (*callbacks_p
)->when
.tv_usec
= (*callbacks_p
)->when
.tv_usec
- 1000000;
608 (*callbacks_p
)->when
.tv_sec
+= 1;
611 (*callbacks_p
)->priv
= priv
;
612 (*callbacks_p
)->next
= NULL
;
617 int target_unregister_event_callback(int (*callback
)(struct target_s
*target
, enum target_event event
, void *priv
), void *priv
)
619 target_event_callback_t
**p
= &target_event_callbacks
;
620 target_event_callback_t
*c
= target_event_callbacks
;
622 if (callback
== NULL
)
624 return ERROR_INVALID_ARGUMENTS
;
629 target_event_callback_t
*next
= c
->next
;
630 if ((c
->callback
== callback
) && (c
->priv
== priv
))
644 int target_unregister_timer_callback(int (*callback
)(void *priv
), void *priv
)
646 target_timer_callback_t
**p
= &target_timer_callbacks
;
647 target_timer_callback_t
*c
= target_timer_callbacks
;
649 if (callback
== NULL
)
651 return ERROR_INVALID_ARGUMENTS
;
656 target_timer_callback_t
*next
= c
->next
;
657 if ((c
->callback
== callback
) && (c
->priv
== priv
))
671 int target_call_event_callbacks(target_t
*target
, enum target_event event
)
673 target_event_callback_t
*callback
= target_event_callbacks
;
674 target_event_callback_t
*next_callback
;
676 if (event
== TARGET_EVENT_HALTED
)
678 /* execute early halted first */
679 target_call_event_callbacks(target
, TARGET_EVENT_EARLY_HALTED
);
682 LOG_DEBUG("target event %i (%s)",
684 Jim_Nvp_value2name_simple( nvp_target_event
, event
)->name
);
686 target_handle_event( target
, event
);
690 next_callback
= callback
->next
;
691 callback
->callback(target
, event
, callback
->priv
);
692 callback
= next_callback
;
698 static int target_call_timer_callbacks_check_time(int checktime
)
700 target_timer_callback_t
*callback
= target_timer_callbacks
;
701 target_timer_callback_t
*next_callback
;
706 gettimeofday(&now
, NULL
);
710 next_callback
= callback
->next
;
712 if ((!checktime
&&callback
->periodic
)||
713 (((now
.tv_sec
>= callback
->when
.tv_sec
) && (now
.tv_usec
>= callback
->when
.tv_usec
))
714 || (now
.tv_sec
> callback
->when
.tv_sec
)))
716 if(callback
->callback
!= NULL
)
718 callback
->callback(callback
->priv
);
719 if (callback
->periodic
)
721 int time_ms
= callback
->time_ms
;
722 callback
->when
.tv_usec
= now
.tv_usec
+ (time_ms
% 1000) * 1000;
723 time_ms
-= (time_ms
% 1000);
724 callback
->when
.tv_sec
= now
.tv_sec
+ time_ms
/ 1000;
725 if (callback
->when
.tv_usec
> 1000000)
727 callback
->when
.tv_usec
= callback
->when
.tv_usec
- 1000000;
728 callback
->when
.tv_sec
+= 1;
734 if((retval
= target_unregister_timer_callback(callback
->callback
, callback
->priv
)) != ERROR_OK
)
740 callback
= next_callback
;
746 int target_call_timer_callbacks(void)
748 return target_call_timer_callbacks_check_time(1);
751 /* invoke periodic callbacks immediately */
752 int target_call_timer_callbacks_now(void)
754 return target_call_timer_callbacks_check_time(0);
757 int target_alloc_working_area(struct target_s
*target
, u32 size
, working_area_t
**area
)
759 working_area_t
*c
= target
->working_areas
;
760 working_area_t
*new_wa
= NULL
;
762 /* Reevaluate working area address based on MMU state*/
763 if (target
->working_areas
== NULL
)
767 retval
= target
->type
->mmu(target
, &enabled
);
768 if (retval
!= ERROR_OK
)
774 target
->working_area
= target
->working_area_virt
;
778 target
->working_area
= target
->working_area_phys
;
782 /* only allocate multiples of 4 byte */
785 LOG_ERROR("BUG: code tried to allocate unaligned number of bytes, padding");
786 size
= CEIL(size
, 4);
789 /* see if there's already a matching working area */
792 if ((c
->free
) && (c
->size
== size
))
800 /* if not, allocate a new one */
803 working_area_t
**p
= &target
->working_areas
;
804 u32 first_free
= target
->working_area
;
805 u32 free_size
= target
->working_area_size
;
807 LOG_DEBUG("allocating new working area");
809 c
= target
->working_areas
;
812 first_free
+= c
->size
;
813 free_size
-= c
->size
;
818 if (free_size
< size
)
820 LOG_WARNING("not enough working area available(requested %d, free %d)", size
, free_size
);
821 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
824 new_wa
= malloc(sizeof(working_area_t
));
827 new_wa
->address
= first_free
;
829 if (target
->backup_working_area
)
832 new_wa
->backup
= malloc(new_wa
->size
);
833 if((retval
= target
->type
->read_memory(target
, new_wa
->address
, 4, new_wa
->size
/ 4, new_wa
->backup
)) != ERROR_OK
)
835 free(new_wa
->backup
);
842 new_wa
->backup
= NULL
;
845 /* put new entry in list */
849 /* mark as used, and return the new (reused) area */
859 int target_free_working_area_restore(struct target_s
*target
, working_area_t
*area
, int restore
)
864 if (restore
&&target
->backup_working_area
)
867 if((retval
= target
->type
->write_memory(target
, area
->address
, 4, area
->size
/ 4, area
->backup
)) != ERROR_OK
)
873 /* mark user pointer invalid */
880 int target_free_working_area(struct target_s
*target
, working_area_t
*area
)
882 return target_free_working_area_restore(target
, area
, 1);
885 /* free resources and restore memory, if restoring memory fails,
886 * free up resources anyway
888 void target_free_all_working_areas_restore(struct target_s
*target
, int restore
)
890 working_area_t
*c
= target
->working_areas
;
894 working_area_t
*next
= c
->next
;
895 target_free_working_area_restore(target
, c
, restore
);
905 target
->working_areas
= NULL
;
908 void target_free_all_working_areas(struct target_s
*target
)
910 target_free_all_working_areas_restore(target
, 1);
913 int target_register_commands(struct command_context_s
*cmd_ctx
)
916 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)");
921 register_jim(cmd_ctx
, "target", jim_target
, "configure target" );
926 int target_arch_state(struct target_s
*target
)
931 LOG_USER("No target has been configured");
935 LOG_USER("target state: %s",
936 Jim_Nvp_value2name_simple(nvp_target_state
,target
->state
)->name
);
938 if (target
->state
!=TARGET_HALTED
)
941 retval
=target
->type
->arch_state(target
);
945 /* Single aligned words are guaranteed to use 16 or 32 bit access
946 * mode respectively, otherwise data is handled as quickly as
949 int target_write_buffer(struct target_s
*target
, u32 address
, u32 size
, u8
*buffer
)
952 LOG_DEBUG("writing buffer of %i byte at 0x%8.8x", size
, address
);
954 if (!target
->type
->examined
)
956 LOG_ERROR("Target not examined yet");
960 if ((address
+ size
- 1) < address
)
962 /* GDB can request this when e.g. PC is 0xfffffffc*/
963 LOG_ERROR("address+size wrapped(0x%08x, 0x%08x)", address
, size
);
967 if (((address
% 2) == 0) && (size
== 2))
969 return target
->type
->write_memory(target
, address
, 2, 1, buffer
);
972 /* handle unaligned head bytes */
975 u32 unaligned
= 4 - (address
% 4);
977 if (unaligned
> size
)
980 if ((retval
= target
->type
->write_memory(target
, address
, 1, unaligned
, buffer
)) != ERROR_OK
)
984 address
+= unaligned
;
988 /* handle aligned words */
991 int aligned
= size
- (size
% 4);
993 /* use bulk writes above a certain limit. This may have to be changed */
996 if ((retval
= target
->type
->bulk_write_memory(target
, address
, aligned
/ 4, buffer
)) != ERROR_OK
)
1001 if ((retval
= target
->type
->write_memory(target
, address
, 4, aligned
/ 4, buffer
)) != ERROR_OK
)
1010 /* handle tail writes of less than 4 bytes */
1013 if ((retval
= target
->type
->write_memory(target
, address
, 1, size
, buffer
)) != ERROR_OK
)
1020 /* Single aligned words are guaranteed to use 16 or 32 bit access
1021 * mode respectively, otherwise data is handled as quickly as
1024 int target_read_buffer(struct target_s
*target
, u32 address
, u32 size
, u8
*buffer
)
1027 LOG_DEBUG("reading buffer of %i byte at 0x%8.8x", size
, address
);
1029 if (!target
->type
->examined
)
1031 LOG_ERROR("Target not examined yet");
1035 if ((address
+ size
- 1) < address
)
1037 /* GDB can request this when e.g. PC is 0xfffffffc*/
1038 LOG_ERROR("address+size wrapped(0x%08x, 0x%08x)", address
, size
);
1042 if (((address
% 2) == 0) && (size
== 2))
1044 return target
->type
->read_memory(target
, address
, 2, 1, buffer
);
1047 /* handle unaligned head bytes */
1050 u32 unaligned
= 4 - (address
% 4);
1052 if (unaligned
> size
)
1055 if ((retval
= target
->type
->read_memory(target
, address
, 1, unaligned
, buffer
)) != ERROR_OK
)
1058 buffer
+= unaligned
;
1059 address
+= unaligned
;
1063 /* handle aligned words */
1066 int aligned
= size
- (size
% 4);
1068 if ((retval
= target
->type
->read_memory(target
, address
, 4, aligned
/ 4, buffer
)) != ERROR_OK
)
1076 /* handle tail writes of less than 4 bytes */
1079 if ((retval
= target
->type
->read_memory(target
, address
, 1, size
, buffer
)) != ERROR_OK
)
1086 int target_checksum_memory(struct target_s
*target
, u32 address
, u32 size
, u32
* crc
)
1092 if (!target
->type
->examined
)
1094 LOG_ERROR("Target not examined yet");
1098 if ((retval
= target
->type
->checksum_memory(target
, address
,
1099 size
, &checksum
)) != ERROR_OK
)
1101 buffer
= malloc(size
);
1104 LOG_ERROR("error allocating buffer for section (%d bytes)", size
);
1105 return ERROR_INVALID_ARGUMENTS
;
1107 retval
= target_read_buffer(target
, address
, size
, buffer
);
1108 if (retval
!= ERROR_OK
)
1114 /* convert to target endianess */
1115 for (i
= 0; i
< (size
/sizeof(u32
)); i
++)
1118 target_data
= target_buffer_get_u32(target
, &buffer
[i
*sizeof(u32
)]);
1119 target_buffer_set_u32(target
, &buffer
[i
*sizeof(u32
)], target_data
);
1122 retval
= image_calculate_checksum( buffer
, size
, &checksum
);
1131 int target_blank_check_memory(struct target_s
*target
, u32 address
, u32 size
, u32
* blank
)
1134 if (!target
->type
->examined
)
1136 LOG_ERROR("Target not examined yet");
1140 if (target
->type
->blank_check_memory
== 0)
1141 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1143 retval
= target
->type
->blank_check_memory(target
, address
, size
, blank
);
1148 int target_read_u32(struct target_s
*target
, u32 address
, u32
*value
)
1151 if (!target
->type
->examined
)
1153 LOG_ERROR("Target not examined yet");
1157 int retval
= target
->type
->read_memory(target
, address
, 4, 1, value_buf
);
1159 if (retval
== ERROR_OK
)
1161 *value
= target_buffer_get_u32(target
, value_buf
);
1162 LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address
, *value
);
1167 LOG_DEBUG("address: 0x%8.8x failed", address
);
1173 int target_read_u16(struct target_s
*target
, u32 address
, u16
*value
)
1176 if (!target
->type
->examined
)
1178 LOG_ERROR("Target not examined yet");
1182 int retval
= target
->type
->read_memory(target
, address
, 2, 1, value_buf
);
1184 if (retval
== ERROR_OK
)
1186 *value
= target_buffer_get_u16(target
, value_buf
);
1187 LOG_DEBUG("address: 0x%8.8x, value: 0x%4.4x", address
, *value
);
1192 LOG_DEBUG("address: 0x%8.8x failed", address
);
1198 int target_read_u8(struct target_s
*target
, u32 address
, u8
*value
)
1200 int retval
= target
->type
->read_memory(target
, address
, 1, 1, value
);
1201 if (!target
->type
->examined
)
1203 LOG_ERROR("Target not examined yet");
1207 if (retval
== ERROR_OK
)
1209 LOG_DEBUG("address: 0x%8.8x, value: 0x%2.2x", address
, *value
);
1214 LOG_DEBUG("address: 0x%8.8x failed", address
);
1220 int target_write_u32(struct target_s
*target
, u32 address
, u32 value
)
1224 if (!target
->type
->examined
)
1226 LOG_ERROR("Target not examined yet");
1230 LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address
, value
);
1232 target_buffer_set_u32(target
, value_buf
, value
);
1233 if ((retval
= target
->type
->write_memory(target
, address
, 4, 1, value_buf
)) != ERROR_OK
)
1235 LOG_DEBUG("failed: %i", retval
);
1241 int target_write_u16(struct target_s
*target
, u32 address
, u16 value
)
1245 if (!target
->type
->examined
)
1247 LOG_ERROR("Target not examined yet");
1251 LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address
, value
);
1253 target_buffer_set_u16(target
, value_buf
, value
);
1254 if ((retval
= target
->type
->write_memory(target
, address
, 2, 1, value_buf
)) != ERROR_OK
)
1256 LOG_DEBUG("failed: %i", retval
);
1262 int target_write_u8(struct target_s
*target
, u32 address
, u8 value
)
1265 if (!target
->type
->examined
)
1267 LOG_ERROR("Target not examined yet");
1271 LOG_DEBUG("address: 0x%8.8x, value: 0x%2.2x", address
, value
);
1273 if ((retval
= target
->type
->write_memory(target
, address
, 1, 1, &value
)) != ERROR_OK
)
1275 LOG_DEBUG("failed: %i", retval
);
1281 int target_register_user_commands(struct command_context_s
*cmd_ctx
)
1283 int retval
= ERROR_OK
;
1286 /* script procedures */
1287 register_command(cmd_ctx
, NULL
, "profile", handle_profile_command
, COMMAND_EXEC
, "profiling samples the CPU PC");
1288 register_jim(cmd_ctx
, "ocd_mem2array", jim_mem2array
, "read memory and return as a TCL array for script processing <ARRAYNAME> <WIDTH=32/16/8> <ADDRESS> <COUNT>");
1289 register_jim(cmd_ctx
, "ocd_array2mem", jim_array2mem
, "convert a TCL array to memory locations and write the values <ARRAYNAME> <WIDTH=32/16/8> <ADDRESS> <COUNT>");
1291 register_command(cmd_ctx
, NULL
, "fast_load_image", handle_fast_load_image_command
, COMMAND_ANY
,
1292 "same args as load_image, image stored in memory - mainly for profiling purposes");
1294 register_command(cmd_ctx
, NULL
, "fast_load", handle_fast_load_command
, COMMAND_ANY
,
1295 "loads active fast load image to current target - mainly for profiling purposes");
1298 register_command(cmd_ctx
, NULL
, "virt2phys", handle_virt2phys_command
, COMMAND_ANY
, "translate a virtual address into a physical address");
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]");
1324 register_command(cmd_ctx
, NULL
, "test_image", handle_test_image_command
, COMMAND_EXEC
, "test_image <file> [offset] [type]");
1326 if((retval
= target_request_register_commands(cmd_ctx
)) != ERROR_OK
)
1328 if((retval
= trace_register_commands(cmd_ctx
)) != ERROR_OK
)
1334 static int handle_targets_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1337 target_t
*target
= all_targets
;
1341 /* try as tcltarget name */
1342 for( target
= all_targets
; target
; target
= target
->next
){
1343 if( target
->cmd_name
){
1344 if( 0 == strcmp( args
[0], target
->cmd_name
) ){
1350 /* no match, try as number */
1352 int num
= strtoul(args
[0], &cp
, 0 );
1354 /* then it was not a number */
1355 command_print( cmd_ctx
, "Target: %s unknown, try one of:\n", args
[0] );
1359 target
= get_target_by_num( num
);
1360 if( target
== NULL
){
1361 command_print(cmd_ctx
,"Target: %s is unknown, try one of:\n", args
[0] );
1365 cmd_ctx
->current_target
= target
->target_number
;
1370 target
= all_targets
;
1371 command_print(cmd_ctx
, " CmdName Type Endian AbsChainPos Name State ");
1372 command_print(cmd_ctx
, "-- ---------- ---------- ---------- ----------- ------------- ----------");
1375 /* XX: abcdefghij abcdefghij abcdefghij abcdefghij */
1376 command_print(cmd_ctx
, "%2d: %-10s %-10s %-10s %10d %14s %s",
1377 target
->target_number
,
1380 Jim_Nvp_value2name_simple( nvp_target_endian
, target
->endianness
)->name
,
1381 target
->tap
->abs_chain_position
,
1382 target
->tap
->dotted_name
,
1383 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
1384 target
= target
->next
;
1390 /* every 300ms we check for reset & powerdropout and issue a "reset halt" if so. */
1392 static int powerDropout
;
1393 static int srstAsserted
;
1395 static int runPowerRestore
;
1396 static int runPowerDropout
;
1397 static int runSrstAsserted
;
1398 static int runSrstDeasserted
;
1400 static int sense_handler(void)
1402 static int prevSrstAsserted
= 0;
1403 static int prevPowerdropout
= 0;
1406 if ((retval
=jtag_power_dropout(&powerDropout
))!=ERROR_OK
)
1410 powerRestored
= prevPowerdropout
&& !powerDropout
;
1413 runPowerRestore
= 1;
1416 long long current
= timeval_ms();
1417 static long long lastPower
= 0;
1418 int waitMore
= lastPower
+ 2000 > current
;
1419 if (powerDropout
&& !waitMore
)
1421 runPowerDropout
= 1;
1422 lastPower
= current
;
1425 if ((retval
=jtag_srst_asserted(&srstAsserted
))!=ERROR_OK
)
1429 srstDeasserted
= prevSrstAsserted
&& !srstAsserted
;
1431 static long long lastSrst
= 0;
1432 waitMore
= lastSrst
+ 2000 > current
;
1433 if (srstDeasserted
&& !waitMore
)
1435 runSrstDeasserted
= 1;
1439 if (!prevSrstAsserted
&& srstAsserted
)
1441 runSrstAsserted
= 1;
1444 prevSrstAsserted
= srstAsserted
;
1445 prevPowerdropout
= powerDropout
;
1447 if (srstDeasserted
|| powerRestored
)
1449 /* Other than logging the event we can't do anything here.
1450 * Issuing a reset is a particularly bad idea as we might
1451 * be inside a reset already.
1458 /* process target state changes */
1459 int handle_target(void *priv
)
1461 int retval
= ERROR_OK
;
1463 /* we do not want to recurse here... */
1464 static int recursive
= 0;
1469 /* danger! running these procedures can trigger srst assertions and power dropouts.
1470 * We need to avoid an infinite loop/recursion here and we do that by
1471 * clearing the flags after running these events.
1473 int did_something
= 0;
1474 if (runSrstAsserted
)
1476 Jim_Eval( interp
, "srst_asserted");
1479 if (runSrstDeasserted
)
1481 Jim_Eval( interp
, "srst_deasserted");
1484 if (runPowerDropout
)
1486 Jim_Eval( interp
, "power_dropout");
1489 if (runPowerRestore
)
1491 Jim_Eval( interp
, "power_restore");
1497 /* clear detect flags */
1501 /* clear action flags */
1504 runSrstDeasserted
=0;
1511 target_t
*target
= all_targets
;
1516 /* only poll target if we've got power and srst isn't asserted */
1517 if (target_continous_poll
&&!powerDropout
&&!srstAsserted
)
1519 /* polling may fail silently until the target has been examined */
1520 if((retval
= target_poll(target
)) != ERROR_OK
)
1524 target
= target
->next
;
1530 static int handle_reg_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1539 target
= get_current_target(cmd_ctx
);
1541 /* list all available registers for the current target */
1544 reg_cache_t
*cache
= target
->reg_cache
;
1550 for (i
= 0; i
< cache
->num_regs
; i
++)
1552 value
= buf_to_str(cache
->reg_list
[i
].value
, cache
->reg_list
[i
].size
, 16);
1553 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
);
1556 cache
= cache
->next
;
1562 /* access a single register by its ordinal number */
1563 if ((args
[0][0] >= '0') && (args
[0][0] <= '9'))
1565 int num
= strtoul(args
[0], NULL
, 0);
1566 reg_cache_t
*cache
= target
->reg_cache
;
1572 for (i
= 0; i
< cache
->num_regs
; i
++)
1576 reg
= &cache
->reg_list
[i
];
1582 cache
= cache
->next
;
1587 command_print(cmd_ctx
, "%i is out of bounds, the current target has only %i registers (0 - %i)", num
, count
, count
- 1);
1590 } else /* access a single register by its name */
1592 reg
= register_get_by_name(target
->reg_cache
, args
[0], 1);
1596 command_print(cmd_ctx
, "register %s not found in current target", args
[0]);
1601 /* display a register */
1602 if ((argc
== 1) || ((argc
== 2) && !((args
[1][0] >= '0') && (args
[1][0] <= '9'))))
1604 if ((argc
== 2) && (strcmp(args
[1], "force") == 0))
1607 if (reg
->valid
== 0)
1609 reg_arch_type_t
*arch_type
= register_get_arch_type(reg
->arch_type
);
1610 arch_type
->get(reg
);
1612 value
= buf_to_str(reg
->value
, reg
->size
, 16);
1613 command_print(cmd_ctx
, "%s (/%i): 0x%s", reg
->name
, reg
->size
, value
);
1618 /* set register value */
1621 u8
*buf
= malloc(CEIL(reg
->size
, 8));
1622 str_to_buf(args
[1], strlen(args
[1]), buf
, reg
->size
, 0);
1624 reg_arch_type_t
*arch_type
= register_get_arch_type(reg
->arch_type
);
1625 arch_type
->set(reg
, buf
);
1627 value
= buf_to_str(reg
->value
, reg
->size
, 16);
1628 command_print(cmd_ctx
, "%s (/%i): 0x%s", reg
->name
, reg
->size
, value
);
1636 command_print(cmd_ctx
, "usage: reg <#|name> [value]");
1641 static int handle_poll_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1643 int retval
= ERROR_OK
;
1644 target_t
*target
= get_current_target(cmd_ctx
);
1648 if((retval
= target_poll(target
)) != ERROR_OK
)
1650 if((retval
= target_arch_state(target
)) != ERROR_OK
)
1656 if (strcmp(args
[0], "on") == 0)
1658 target_continous_poll
= 1;
1660 else if (strcmp(args
[0], "off") == 0)
1662 target_continous_poll
= 0;
1666 command_print(cmd_ctx
, "arg is \"on\" or \"off\"");
1670 return ERROR_COMMAND_SYNTAX_ERROR
;
1676 static int handle_wait_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1684 ms
= strtoul(args
[0], &end
, 0) * 1000;
1687 command_print(cmd_ctx
, "usage: %s [seconds]", cmd
);
1691 target_t
*target
= get_current_target(cmd_ctx
);
1693 return target_wait_state(target
, TARGET_HALTED
, ms
);
1696 /* wait for target state to change. The trick here is to have a low
1697 * latency for short waits and not to suck up all the CPU time
1700 * After 500ms, keep_alive() is invoked
1702 int target_wait_state(target_t
*target
, enum target_state state
, int ms
)
1705 long long then
=0, cur
;
1710 if ((retval
=target_poll(target
))!=ERROR_OK
)
1712 if (target
->state
== state
)
1720 then
= timeval_ms();
1721 LOG_DEBUG("waiting for target %s...",
1722 Jim_Nvp_value2name_simple(nvp_target_state
,state
)->name
);
1732 LOG_ERROR("timed out while waiting for target %s",
1733 Jim_Nvp_value2name_simple(nvp_target_state
,state
)->name
);
1741 static int handle_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1744 target_t
*target
= get_current_target(cmd_ctx
);
1748 if ((retval
= target_halt(target
)) != ERROR_OK
)
1758 wait
= strtoul(args
[0], &end
, 0);
1763 return handle_wait_halt_command(cmd_ctx
, cmd
, args
, argc
);
1766 static int handle_soft_reset_halt_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1768 target_t
*target
= get_current_target(cmd_ctx
);
1770 LOG_USER("requesting target halt and executing a soft reset");
1772 target
->type
->soft_reset_halt(target
);
1777 static int handle_reset_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1780 enum target_reset_mode reset_mode
= RESET_RUN
;
1784 n
= Jim_Nvp_name2value_simple( nvp_reset_modes
, args
[0] );
1785 if( (n
->name
== NULL
) || (n
->value
== RESET_UNKNOWN
) ){
1786 return ERROR_COMMAND_SYNTAX_ERROR
;
1788 reset_mode
= n
->value
;
1791 /* reset *all* targets */
1792 return target_process_reset(cmd_ctx
, reset_mode
);
1796 static int handle_resume_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1799 target_t
*target
= get_current_target(cmd_ctx
);
1801 target_handle_event( target
, TARGET_EVENT_OLD_pre_resume
);
1804 retval
= target_resume(target
, 1, 0, 1, 0); /* current pc, addr = 0, handle breakpoints, not debugging */
1806 retval
= target_resume(target
, 0, strtoul(args
[0], NULL
, 0), 1, 0); /* addr = args[0], handle breakpoints, not debugging */
1809 retval
= ERROR_COMMAND_SYNTAX_ERROR
;
1815 static int handle_step_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1817 target_t
*target
= get_current_target(cmd_ctx
);
1822 return target
->type
->step(target
, 1, 0, 1); /* current pc, addr = 0, handle breakpoints */
1825 return target
->type
->step(target
, 0, strtoul(args
[0], NULL
, 0), 1); /* addr = args[0], handle breakpoints */
1830 static int handle_md_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1832 const int line_bytecnt
= 32;
1845 target_t
*target
= get_current_target(cmd_ctx
);
1851 count
= strtoul(args
[1], NULL
, 0);
1853 address
= strtoul(args
[0], NULL
, 0);
1858 size
= 4; line_modulo
= line_bytecnt
/ 4;
1861 size
= 2; line_modulo
= line_bytecnt
/ 2;
1864 size
= 1; line_modulo
= line_bytecnt
/ 1;
1870 buffer
= calloc(count
, size
);
1871 retval
= target
->type
->read_memory(target
, address
, size
, count
, buffer
);
1872 if (retval
== ERROR_OK
)
1876 for (i
= 0; i
< count
; i
++)
1878 if (i
%line_modulo
== 0)
1879 output_len
+= snprintf(output
+ output_len
, 128 - output_len
, "0x%8.8x: ", address
+ (i
*size
));
1884 output_len
+= snprintf(output
+ output_len
, 128 - output_len
, "%8.8x ", target_buffer_get_u32(target
, &buffer
[i
*4]));
1887 output_len
+= snprintf(output
+ output_len
, 128 - output_len
, "%4.4x ", target_buffer_get_u16(target
, &buffer
[i
*2]));
1890 output_len
+= snprintf(output
+ output_len
, 128 - output_len
, "%2.2x ", buffer
[i
*1]);
1894 if ((i
%line_modulo
== line_modulo
-1) || (i
== count
- 1))
1896 command_print(cmd_ctx
, output
);
1907 static int handle_mw_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1914 target_t
*target
= get_current_target(cmd_ctx
);
1917 if ((argc
< 2) || (argc
> 3))
1918 return ERROR_COMMAND_SYNTAX_ERROR
;
1920 address
= strtoul(args
[0], NULL
, 0);
1921 value
= strtoul(args
[1], NULL
, 0);
1923 count
= strtoul(args
[2], NULL
, 0);
1929 target_buffer_set_u32(target
, value_buf
, value
);
1933 target_buffer_set_u16(target
, value_buf
, value
);
1937 value_buf
[0] = value
;
1940 return ERROR_COMMAND_SYNTAX_ERROR
;
1942 for (i
=0; i
<count
; i
++)
1948 retval
= target
->type
->write_memory(target
, address
+ i
*wordsize
, 4, 1, value_buf
);
1951 retval
= target
->type
->write_memory(target
, address
+ i
*wordsize
, 2, 1, value_buf
);
1954 retval
= target
->type
->write_memory(target
, address
+ i
*wordsize
, 1, 1, value_buf
);
1961 if (retval
!=ERROR_OK
)
1971 static int handle_load_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1977 u32 max_address
=0xffffffff;
1979 int retval
, retvaltemp
;
1983 duration_t duration
;
1984 char *duration_text
;
1986 target_t
*target
= get_current_target(cmd_ctx
);
1988 if ((argc
< 1)||(argc
> 5))
1990 return ERROR_COMMAND_SYNTAX_ERROR
;
1993 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
1996 image
.base_address_set
= 1;
1997 image
.base_address
= strtoul(args
[1], NULL
, 0);
2001 image
.base_address_set
= 0;
2005 image
.start_address_set
= 0;
2009 min_address
=strtoul(args
[3], NULL
, 0);
2013 max_address
=strtoul(args
[4], NULL
, 0)+min_address
;
2016 if (min_address
>max_address
)
2018 return ERROR_COMMAND_SYNTAX_ERROR
;
2021 duration_start_measure(&duration
);
2023 if (image_open(&image
, args
[0], (argc
>= 3) ? args
[2] : NULL
) != ERROR_OK
)
2030 for (i
= 0; i
< image
.num_sections
; i
++)
2032 buffer
= malloc(image
.sections
[i
].size
);
2035 command_print(cmd_ctx
, "error allocating buffer for section (%d bytes)", image
.sections
[i
].size
);
2039 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 static 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 (fileio_open(&fileio
, args
[0], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
)
2123 duration_start_measure(&duration
);
2128 u32 this_run_size
= (size
> 560) ? 560 : size
;
2130 retval
= target_read_buffer(target
, address
, this_run_size
, buffer
);
2131 if (retval
!= ERROR_OK
)
2136 retval
= fileio_write(&fileio
, this_run_size
, buffer
, &size_written
);
2137 if (retval
!= ERROR_OK
)
2142 size
-= this_run_size
;
2143 address
+= this_run_size
;
2146 if((retvaltemp
= fileio_close(&fileio
)) != ERROR_OK
)
2149 if((retvaltemp
= duration_stop_measure(&duration
, &duration_text
)) != ERROR_OK
)
2152 if (retval
==ERROR_OK
)
2154 command_print(cmd_ctx
, "dumped %"PRIi64
" byte in %s", fileio
.size
, duration_text
);
2155 free(duration_text
);
2161 static int handle_verify_image_command_internal(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, int verify
)
2167 int retval
, retvaltemp
;
2169 u32 mem_checksum
= 0;
2173 duration_t duration
;
2174 char *duration_text
;
2176 target_t
*target
= get_current_target(cmd_ctx
);
2180 return ERROR_COMMAND_SYNTAX_ERROR
;
2185 LOG_ERROR("no target selected");
2189 duration_start_measure(&duration
);
2193 image
.base_address_set
= 1;
2194 image
.base_address
= strtoul(args
[1], NULL
, 0);
2198 image
.base_address_set
= 0;
2199 image
.base_address
= 0x0;
2202 image
.start_address_set
= 0;
2204 if ((retval
=image_open(&image
, args
[0], (argc
== 3) ? args
[2] : NULL
)) != ERROR_OK
)
2211 for (i
= 0; i
< image
.num_sections
; i
++)
2213 buffer
= malloc(image
.sections
[i
].size
);
2216 command_print(cmd_ctx
, "error allocating buffer for section (%d bytes)", image
.sections
[i
].size
);
2219 if ((retval
= image_read_section(&image
, i
, 0x0, image
.sections
[i
].size
, buffer
, &buf_cnt
)) != ERROR_OK
)
2227 /* calculate checksum of image */
2228 image_calculate_checksum( buffer
, buf_cnt
, &checksum
);
2230 retval
= target_checksum_memory(target
, image
.sections
[i
].base_address
, buf_cnt
, &mem_checksum
);
2231 if( retval
!= ERROR_OK
)
2237 if( checksum
!= mem_checksum
)
2239 /* failed crc checksum, fall back to a binary compare */
2242 command_print(cmd_ctx
, "checksum mismatch - attempting binary compare");
2244 data
= (u8
*)malloc(buf_cnt
);
2246 /* Can we use 32bit word accesses? */
2248 int count
= buf_cnt
;
2249 if ((count
% 4) == 0)
2254 retval
= target
->type
->read_memory(target
, image
.sections
[i
].base_address
, size
, count
, data
);
2255 if (retval
== ERROR_OK
)
2258 for (t
= 0; t
< buf_cnt
; t
++)
2260 if (data
[t
] != buffer
[t
])
2262 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
]);
2279 command_print(cmd_ctx
, "address 0x%08x length 0x%08x", image
.sections
[i
].base_address
, buf_cnt
);
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 static int handle_verify_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2306 return handle_verify_image_command_internal(cmd_ctx
, cmd
, args
, argc
, 1);
2309 static int handle_test_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2311 return handle_verify_image_command_internal(cmd_ctx
, cmd
, args
, argc
, 0);
2314 static int handle_bp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2317 target_t
*target
= get_current_target(cmd_ctx
);
2321 breakpoint_t
*breakpoint
= target
->breakpoints
;
2325 if (breakpoint
->type
== BKPT_SOFT
)
2327 char* buf
= buf_to_str(breakpoint
->orig_instr
, breakpoint
->length
, 16);
2328 command_print(cmd_ctx
, "0x%8.8x, 0x%x, %i, 0x%s", breakpoint
->address
, breakpoint
->length
, breakpoint
->set
, buf
);
2333 command_print(cmd_ctx
, "0x%8.8x, 0x%x, %i", breakpoint
->address
, breakpoint
->length
, breakpoint
->set
);
2335 breakpoint
= breakpoint
->next
;
2343 length
= strtoul(args
[1], NULL
, 0);
2346 if (strcmp(args
[2], "hw") == 0)
2349 if ((retval
= breakpoint_add(target
, strtoul(args
[0], NULL
, 0), length
, hw
)) != ERROR_OK
)
2351 LOG_ERROR("Failure setting breakpoints");
2355 command_print(cmd_ctx
, "breakpoint added at address 0x%8.8x", strtoul(args
[0], NULL
, 0));
2360 command_print(cmd_ctx
, "usage: bp <address> <length> ['hw']");
2366 static int handle_rbp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2368 target_t
*target
= get_current_target(cmd_ctx
);
2371 breakpoint_remove(target
, strtoul(args
[0], NULL
, 0));
2376 static int handle_wp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2378 target_t
*target
= get_current_target(cmd_ctx
);
2383 watchpoint_t
*watchpoint
= target
->watchpoints
;
2387 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
);
2388 watchpoint
= watchpoint
->next
;
2393 enum watchpoint_rw type
= WPT_ACCESS
;
2394 u32 data_value
= 0x0;
2395 u32 data_mask
= 0xffffffff;
2411 command_print(cmd_ctx
, "usage: wp <address> <length> [r/w/a] [value] [mask]");
2417 data_value
= strtoul(args
[3], NULL
, 0);
2421 data_mask
= strtoul(args
[4], NULL
, 0);
2424 if ((retval
= watchpoint_add(target
, strtoul(args
[0], NULL
, 0),
2425 strtoul(args
[1], NULL
, 0), type
, data_value
, data_mask
)) != ERROR_OK
)
2427 LOG_ERROR("Failure setting breakpoints");
2432 command_print(cmd_ctx
, "usage: wp <address> <length> [r/w/a] [value] [mask]");
2438 static int handle_rwp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2440 target_t
*target
= get_current_target(cmd_ctx
);
2443 watchpoint_remove(target
, strtoul(args
[0], NULL
, 0));
2448 static int handle_virt2phys_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2451 target_t
*target
= get_current_target(cmd_ctx
);
2457 return ERROR_COMMAND_SYNTAX_ERROR
;
2459 va
= strtoul(args
[0], NULL
, 0);
2461 retval
= target
->type
->virt2phys(target
, va
, &pa
);
2462 if (retval
== ERROR_OK
)
2464 command_print(cmd_ctx
, "Physical address 0x%08x", pa
);
2468 /* lower levels will have logged a detailed error which is
2469 * forwarded to telnet/GDB session.
2475 static void writeData(FILE *f
, const void *data
, size_t len
)
2477 size_t written
= fwrite(data
, len
, 1, f
);
2479 LOG_ERROR("failed to write %zu bytes: %s", len
, strerror(errno
));
2482 static void writeLong(FILE *f
, int l
)
2487 char c
=(l
>>(i
*8))&0xff;
2488 writeData(f
, &c
, 1);
2493 static void writeString(FILE *f
, char *s
)
2495 writeData(f
, s
, strlen(s
));
2498 /* Dump a gmon.out histogram file. */
2499 static void writeGmon(u32
*samples
, u32 sampleNum
, char *filename
)
2502 FILE *f
=fopen(filename
, "w");
2505 writeString(f
, "gmon");
2506 writeLong(f
, 0x00000001); /* Version */
2507 writeLong(f
, 0); /* padding */
2508 writeLong(f
, 0); /* padding */
2509 writeLong(f
, 0); /* padding */
2511 u8 zero
= 0; /* GMON_TAG_TIME_HIST */
2512 writeData(f
, &zero
, 1);
2514 /* figure out bucket size */
2517 for (i
=0; i
<sampleNum
; i
++)
2529 int addressSpace
=(max
-min
+1);
2531 static const u32 maxBuckets
= 256 * 1024; /* maximum buckets. */
2532 u32 length
= addressSpace
;
2533 if (length
> maxBuckets
)
2537 int *buckets
=malloc(sizeof(int)*length
);
2543 memset(buckets
, 0, sizeof(int)*length
);
2544 for (i
=0; i
<sampleNum
;i
++)
2546 u32 address
=samples
[i
];
2547 long long a
=address
-min
;
2548 long long b
=length
-1;
2549 long long c
=addressSpace
-1;
2550 int index
=(a
*b
)/c
; /* danger!!!! int32 overflows */
2554 /* append binary memory gmon.out &profile_hist_hdr ((char*)&profile_hist_hdr + sizeof(struct gmon_hist_hdr)) */
2555 writeLong(f
, min
); /* low_pc */
2556 writeLong(f
, max
); /* high_pc */
2557 writeLong(f
, length
); /* # of samples */
2558 writeLong(f
, 64000000); /* 64MHz */
2559 writeString(f
, "seconds");
2560 for (i
=0; i
<(15-strlen("seconds")); i
++)
2561 writeData(f
, &zero
, 1);
2562 writeString(f
, "s");
2564 /*append binary memory gmon.out profile_hist_data (profile_hist_data + profile_hist_hdr.hist_size) */
2566 char *data
=malloc(2*length
);
2569 for (i
=0; i
<length
;i
++)
2578 data
[i
*2+1]=(val
>>8)&0xff;
2581 writeData(f
, data
, length
* 2);
2591 /* profiling samples the CPU PC as quickly as OpenOCD is able, which will be used as a random sampling of PC */
2592 static int handle_profile_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2594 target_t
*target
= get_current_target(cmd_ctx
);
2595 struct timeval timeout
, now
;
2597 gettimeofday(&timeout
, NULL
);
2600 return ERROR_COMMAND_SYNTAX_ERROR
;
2603 timeval_add_time(&timeout
, strtoul(args
[0], &end
, 0), 0);
2609 command_print(cmd_ctx
, "Starting profiling. Halting and resuming the target as often as we can...");
2611 static const int maxSample
=10000;
2612 u32
*samples
=malloc(sizeof(u32
)*maxSample
);
2617 int retval
=ERROR_OK
;
2618 /* hopefully it is safe to cache! We want to stop/restart as quickly as possible. */
2619 reg_t
*reg
= register_get_by_name(target
->reg_cache
, "pc", 1);
2623 target_poll(target
);
2624 if (target
->state
== TARGET_HALTED
)
2626 u32 t
=*((u32
*)reg
->value
);
2627 samples
[numSamples
++]=t
;
2628 retval
= target_resume(target
, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */
2629 target_poll(target
);
2630 alive_sleep(10); /* sleep 10ms, i.e. <100 samples/second. */
2631 } else if (target
->state
== TARGET_RUNNING
)
2633 /* We want to quickly sample the PC. */
2634 if((retval
= target_halt(target
)) != ERROR_OK
)
2641 command_print(cmd_ctx
, "Target not halted or running");
2645 if (retval
!=ERROR_OK
)
2650 gettimeofday(&now
, NULL
);
2651 if ((numSamples
>=maxSample
) || ((now
.tv_sec
>= timeout
.tv_sec
) && (now
.tv_usec
>= timeout
.tv_usec
)))
2653 command_print(cmd_ctx
, "Profiling completed. %d samples.", numSamples
);
2654 if((retval
= target_poll(target
)) != ERROR_OK
)
2659 if (target
->state
== TARGET_HALTED
)
2661 target_resume(target
, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */
2663 if((retval
= target_poll(target
)) != ERROR_OK
)
2668 writeGmon(samples
, numSamples
, args
[1]);
2669 command_print(cmd_ctx
, "Wrote %s", args
[1]);
2678 static int new_int_array_element(Jim_Interp
* interp
, const char *varname
, int idx
, u32 val
)
2681 Jim_Obj
*nameObjPtr
, *valObjPtr
;
2684 namebuf
= alloc_printf("%s(%d)", varname
, idx
);
2688 nameObjPtr
= Jim_NewStringObj(interp
, namebuf
, -1);
2689 valObjPtr
= Jim_NewIntObj(interp
, val
);
2690 if (!nameObjPtr
|| !valObjPtr
)
2696 Jim_IncrRefCount(nameObjPtr
);
2697 Jim_IncrRefCount(valObjPtr
);
2698 result
= Jim_SetVariable(interp
, nameObjPtr
, valObjPtr
);
2699 Jim_DecrRefCount(interp
, nameObjPtr
);
2700 Jim_DecrRefCount(interp
, valObjPtr
);
2702 /* printf("%s(%d) <= 0%08x\n", varname, idx, val); */
2706 static int jim_mem2array(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
2708 command_context_t
*context
;
2711 context
= Jim_GetAssocData(interp
, "context");
2712 if (context
== NULL
)
2714 LOG_ERROR("mem2array: no command context");
2717 target
= get_current_target(context
);
2720 LOG_ERROR("mem2array: no current target");
2724 return target_mem2array(interp
, target
, argc
-1, argv
+1);
2727 static int target_mem2array(Jim_Interp
*interp
, target_t
*target
, int argc
, Jim_Obj
*const *argv
)
2735 const char *varname
;
2740 /* argv[1] = name of array to receive the data
2741 * argv[2] = desired width
2742 * argv[3] = memory address
2743 * argv[4] = count of times to read
2746 Jim_WrongNumArgs(interp
, 1, argv
, "varname width addr nelems");
2749 varname
= Jim_GetString(argv
[0], &len
);
2750 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
2752 e
= Jim_GetLong(interp
, argv
[1], &l
);
2758 e
= Jim_GetLong(interp
, argv
[2], &l
);
2763 e
= Jim_GetLong(interp
, argv
[3], &l
);
2779 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2780 Jim_AppendStrings( interp
, Jim_GetResult(interp
), "Invalid width param, must be 8/16/32", NULL
);
2784 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2785 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: zero width read?", NULL
);
2788 if ((addr
+ (len
* width
)) < addr
) {
2789 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2790 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: addr + len - wraps to zero?", NULL
);
2793 /* absurd transfer size? */
2795 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2796 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: absurd > 64K item request", NULL
);
2801 ((width
== 2) && ((addr
& 1) == 0)) ||
2802 ((width
== 4) && ((addr
& 3) == 0))) {
2806 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2807 sprintf(buf
, "mem2array address: 0x%08x is not aligned for %d byte reads", addr
, width
);
2808 Jim_AppendStrings(interp
, Jim_GetResult(interp
), buf
, NULL
);
2819 /* Slurp... in buffer size chunks */
2821 count
= len
; /* in objects.. */
2822 if (count
> (sizeof(buffer
)/width
)) {
2823 count
= (sizeof(buffer
)/width
);
2826 retval
= target
->type
->read_memory( target
, addr
, width
, count
, buffer
);
2827 if (retval
!= ERROR_OK
) {
2829 LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed", addr
, width
, count
);
2830 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2831 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: cannot read memory", NULL
);
2835 v
= 0; /* shut up gcc */
2836 for (i
= 0 ;i
< count
;i
++, n
++) {
2839 v
= target_buffer_get_u32(target
, &buffer
[i
*width
]);
2842 v
= target_buffer_get_u16(target
, &buffer
[i
*width
]);
2845 v
= buffer
[i
] & 0x0ff;
2848 new_int_array_element(interp
, varname
, n
, v
);
2854 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2859 static int get_int_array_element(Jim_Interp
* interp
, const char *varname
, int idx
, u32
*val
)
2862 Jim_Obj
*nameObjPtr
, *valObjPtr
;
2866 namebuf
= alloc_printf("%s(%d)", varname
, idx
);
2870 nameObjPtr
= Jim_NewStringObj(interp
, namebuf
, -1);
2877 Jim_IncrRefCount(nameObjPtr
);
2878 valObjPtr
= Jim_GetVariable(interp
, nameObjPtr
, JIM_ERRMSG
);
2879 Jim_DecrRefCount(interp
, nameObjPtr
);
2881 if (valObjPtr
== NULL
)
2884 result
= Jim_GetLong(interp
, valObjPtr
, &l
);
2885 /* printf("%s(%d) => 0%08x\n", varname, idx, val); */
2890 static int jim_array2mem(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
2892 command_context_t
*context
;
2895 context
= Jim_GetAssocData(interp
, "context");
2896 if (context
== NULL
){
2897 LOG_ERROR("array2mem: no command context");
2900 target
= get_current_target(context
);
2901 if (target
== NULL
){
2902 LOG_ERROR("array2mem: no current target");
2906 return target_array2mem( interp
,target
, argc
-1, argv
+1 );
2909 static int target_array2mem(Jim_Interp
*interp
, target_t
*target
, int argc
, Jim_Obj
*const *argv
)
2917 const char *varname
;
2922 /* argv[1] = name of array to get the data
2923 * argv[2] = desired width
2924 * argv[3] = memory address
2925 * argv[4] = count to write
2928 Jim_WrongNumArgs(interp
, 1, argv
, "varname width addr nelems");
2931 varname
= Jim_GetString(argv
[0], &len
);
2932 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
2934 e
= Jim_GetLong(interp
, argv
[1], &l
);
2940 e
= Jim_GetLong(interp
, argv
[2], &l
);
2945 e
= Jim_GetLong(interp
, argv
[3], &l
);
2961 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2962 Jim_AppendStrings( interp
, Jim_GetResult(interp
), "Invalid width param, must be 8/16/32", NULL
);
2966 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2967 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: zero width read?", NULL
);
2970 if ((addr
+ (len
* width
)) < addr
) {
2971 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2972 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: addr + len - wraps to zero?", NULL
);
2975 /* absurd transfer size? */
2977 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2978 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: absurd > 64K item request", NULL
);
2983 ((width
== 2) && ((addr
& 1) == 0)) ||
2984 ((width
== 4) && ((addr
& 3) == 0))) {
2988 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2989 sprintf(buf
, "array2mem address: 0x%08x is not aligned for %d byte reads", addr
, width
);
2990 Jim_AppendStrings(interp
, Jim_GetResult(interp
), buf
, NULL
);
3001 /* Slurp... in buffer size chunks */
3003 count
= len
; /* in objects.. */
3004 if (count
> (sizeof(buffer
)/width
)) {
3005 count
= (sizeof(buffer
)/width
);
3008 v
= 0; /* shut up gcc */
3009 for (i
= 0 ;i
< count
;i
++, n
++) {
3010 get_int_array_element(interp
, varname
, n
, &v
);
3013 target_buffer_set_u32(target
, &buffer
[i
*width
], v
);
3016 target_buffer_set_u16(target
, &buffer
[i
*width
], v
);
3019 buffer
[i
] = v
& 0x0ff;
3025 retval
= target
->type
->write_memory(target
, addr
, width
, count
, buffer
);
3026 if (retval
!= ERROR_OK
) {
3028 LOG_ERROR("array2mem: Write @ 0x%08x, w=%d, cnt=%d, failed", addr
, width
, count
);
3029 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
3030 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: cannot read memory", NULL
);
3036 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
3041 void target_all_handle_event( enum target_event e
)
3045 LOG_DEBUG( "**all*targets: event: %d, %s",
3047 Jim_Nvp_value2name_simple( nvp_target_event
, e
)->name
);
3049 target
= all_targets
;
3051 target_handle_event( target
, e
);
3052 target
= target
->next
;
3056 void target_handle_event( target_t
*target
, enum target_event e
)
3058 target_event_action_t
*teap
;
3061 teap
= target
->event_action
;
3065 if( teap
->event
== e
){
3067 LOG_DEBUG( "target: (%d) %s (%s) event: %d (%s) action: %s\n",
3068 target
->target_number
,
3072 Jim_Nvp_value2name_simple( nvp_target_event
, e
)->name
,
3073 Jim_GetString( teap
->body
, NULL
) );
3074 if (Jim_EvalObj( interp
, teap
->body
)!=JIM_OK
)
3076 Jim_PrintErrorMessage(interp
);
3082 LOG_DEBUG( "event: %d %s - no action",
3084 Jim_Nvp_value2name_simple( nvp_target_event
, e
)->name
);
3088 enum target_cfg_param
{
3091 TCFG_WORK_AREA_VIRT
,
3092 TCFG_WORK_AREA_PHYS
,
3093 TCFG_WORK_AREA_SIZE
,
3094 TCFG_WORK_AREA_BACKUP
,
3097 TCFG_CHAIN_POSITION
,
3100 static Jim_Nvp nvp_config_opts
[] = {
3101 { .name
= "-type", .value
= TCFG_TYPE
},
3102 { .name
= "-event", .value
= TCFG_EVENT
},
3103 { .name
= "-work-area-virt", .value
= TCFG_WORK_AREA_VIRT
},
3104 { .name
= "-work-area-phys", .value
= TCFG_WORK_AREA_PHYS
},
3105 { .name
= "-work-area-size", .value
= TCFG_WORK_AREA_SIZE
},
3106 { .name
= "-work-area-backup", .value
= TCFG_WORK_AREA_BACKUP
},
3107 { .name
= "-endian" , .value
= TCFG_ENDIAN
},
3108 { .name
= "-variant", .value
= TCFG_VARIANT
},
3109 { .name
= "-chain-position", .value
= TCFG_CHAIN_POSITION
},
3111 { .name
= NULL
, .value
= -1 }
3114 static int target_configure( Jim_GetOptInfo
*goi
, target_t
*target
)
3122 /* parse config or cget options ... */
3123 while( goi
->argc
> 0 ){
3124 Jim_SetEmptyResult( goi
->interp
);
3125 /* Jim_GetOpt_Debug( goi ); */
3127 if( target
->type
->target_jim_configure
){
3128 /* target defines a configure function */
3129 /* target gets first dibs on parameters */
3130 e
= (*(target
->type
->target_jim_configure
))( target
, goi
);
3139 /* otherwise we 'continue' below */
3141 e
= Jim_GetOpt_Nvp( goi
, nvp_config_opts
, &n
);
3143 Jim_GetOpt_NvpUnknown( goi
, nvp_config_opts
, 0 );
3149 if( goi
->isconfigure
){
3150 Jim_SetResult_sprintf( goi
->interp
, "not setable: %s", n
->name
);
3154 if( goi
->argc
!= 0 ){
3155 Jim_WrongNumArgs( goi
->interp
, goi
->argc
, goi
->argv
, "NO PARAMS");
3159 Jim_SetResultString( goi
->interp
, target
->type
->name
, -1 );
3163 if( goi
->argc
== 0 ){
3164 Jim_WrongNumArgs( goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name? ...");
3168 e
= Jim_GetOpt_Nvp( goi
, nvp_target_event
, &n
);
3170 Jim_GetOpt_NvpUnknown( goi
, nvp_target_event
, 1 );
3174 if( goi
->isconfigure
){
3175 if( goi
->argc
!= 1 ){
3176 Jim_WrongNumArgs( goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name? ?EVENT-BODY?");
3180 if( goi
->argc
!= 0 ){
3181 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name?");
3187 target_event_action_t
*teap
;
3189 teap
= target
->event_action
;
3190 /* replace existing? */
3192 if( teap
->event
== (enum target_event
)n
->value
){
3198 if( goi
->isconfigure
){
3201 teap
= calloc( 1, sizeof(*teap
) );
3203 teap
->event
= n
->value
;
3204 Jim_GetOpt_Obj( goi
, &o
);
3206 Jim_DecrRefCount( interp
, teap
->body
);
3208 teap
->body
= Jim_DuplicateObj( goi
->interp
, o
);
3211 * Tcl/TK - "tk events" have a nice feature.
3212 * See the "BIND" command.
3213 * We should support that here.
3214 * You can specify %X and %Y in the event code.
3215 * The idea is: %T - target name.
3216 * The idea is: %N - target number
3217 * The idea is: %E - event name.
3219 Jim_IncrRefCount( teap
->body
);
3221 /* add to head of event list */
3222 teap
->next
= target
->event_action
;
3223 target
->event_action
= teap
;
3224 Jim_SetEmptyResult(goi
->interp
);
3228 Jim_SetEmptyResult( goi
->interp
);
3230 Jim_SetResult( goi
->interp
, Jim_DuplicateObj( goi
->interp
, teap
->body
) );
3237 case TCFG_WORK_AREA_VIRT
:
3238 if( goi
->isconfigure
){
3239 target_free_all_working_areas(target
);
3240 e
= Jim_GetOpt_Wide( goi
, &w
);
3244 target
->working_area_virt
= w
;
3246 if( goi
->argc
!= 0 ){
3250 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_virt
) );
3254 case TCFG_WORK_AREA_PHYS
:
3255 if( goi
->isconfigure
){
3256 target_free_all_working_areas(target
);
3257 e
= Jim_GetOpt_Wide( goi
, &w
);
3261 target
->working_area_phys
= w
;
3263 if( goi
->argc
!= 0 ){
3267 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_phys
) );
3271 case TCFG_WORK_AREA_SIZE
:
3272 if( goi
->isconfigure
){
3273 target_free_all_working_areas(target
);
3274 e
= Jim_GetOpt_Wide( goi
, &w
);
3278 target
->working_area_size
= w
;
3280 if( goi
->argc
!= 0 ){
3284 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_size
) );
3288 case TCFG_WORK_AREA_BACKUP
:
3289 if( goi
->isconfigure
){
3290 target_free_all_working_areas(target
);
3291 e
= Jim_GetOpt_Wide( goi
, &w
);
3295 /* make this exactly 1 or 0 */
3296 target
->backup_working_area
= (!!w
);
3298 if( goi
->argc
!= 0 ){
3302 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_size
) );
3303 /* loop for more e*/
3307 if( goi
->isconfigure
){
3308 e
= Jim_GetOpt_Nvp( goi
, nvp_target_endian
, &n
);
3310 Jim_GetOpt_NvpUnknown( goi
, nvp_target_endian
, 1 );
3313 target
->endianness
= n
->value
;
3315 if( goi
->argc
!= 0 ){
3319 n
= Jim_Nvp_value2name_simple( nvp_target_endian
, target
->endianness
);
3320 if( n
->name
== NULL
){
3321 target
->endianness
= TARGET_LITTLE_ENDIAN
;
3322 n
= Jim_Nvp_value2name_simple( nvp_target_endian
, target
->endianness
);
3324 Jim_SetResultString( goi
->interp
, n
->name
, -1 );
3329 if( goi
->isconfigure
){
3330 if( goi
->argc
< 1 ){
3331 Jim_SetResult_sprintf( goi
->interp
,
3336 if( target
->variant
){
3337 free((void *)(target
->variant
));
3339 e
= Jim_GetOpt_String( goi
, &cp
, NULL
);
3340 target
->variant
= strdup(cp
);
3342 if( goi
->argc
!= 0 ){
3346 Jim_SetResultString( goi
->interp
, target
->variant
,-1 );
3349 case TCFG_CHAIN_POSITION
:
3350 if( goi
->isconfigure
){
3353 target_free_all_working_areas(target
);
3354 e
= Jim_GetOpt_Obj( goi
, &o
);
3358 tap
= jtag_TapByJimObj( goi
->interp
, o
);
3362 /* make this exactly 1 or 0 */
3365 if( goi
->argc
!= 0 ){
3369 Jim_SetResultString( interp
, target
->tap
->dotted_name
, -1 );
3370 /* loop for more e*/
3373 } /* while( goi->argc ) */
3376 /* done - we return */
3380 /** this is the 'tcl' handler for the target specific command */
3381 static int tcl_target_func( Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
3389 struct command_context_s
*cmd_ctx
;
3396 TS_CMD_MWW
, TS_CMD_MWH
, TS_CMD_MWB
,
3397 TS_CMD_MDW
, TS_CMD_MDH
, TS_CMD_MDB
,
3398 TS_CMD_MRW
, TS_CMD_MRH
, TS_CMD_MRB
,
3399 TS_CMD_MEM2ARRAY
, TS_CMD_ARRAY2MEM
,
3407 TS_CMD_INVOKE_EVENT
,
3410 static const Jim_Nvp target_options
[] = {
3411 { .name
= "configure", .value
= TS_CMD_CONFIGURE
},
3412 { .name
= "cget", .value
= TS_CMD_CGET
},
3413 { .name
= "mww", .value
= TS_CMD_MWW
},
3414 { .name
= "mwh", .value
= TS_CMD_MWH
},
3415 { .name
= "mwb", .value
= TS_CMD_MWB
},
3416 { .name
= "mdw", .value
= TS_CMD_MDW
},
3417 { .name
= "mdh", .value
= TS_CMD_MDH
},
3418 { .name
= "mdb", .value
= TS_CMD_MDB
},
3419 { .name
= "mem2array", .value
= TS_CMD_MEM2ARRAY
},
3420 { .name
= "array2mem", .value
= TS_CMD_ARRAY2MEM
},
3421 { .name
= "eventlist", .value
= TS_CMD_EVENTLIST
},
3422 { .name
= "curstate", .value
= TS_CMD_CURSTATE
},
3424 { .name
= "arp_examine", .value
= TS_CMD_EXAMINE
},
3425 { .name
= "arp_poll", .value
= TS_CMD_POLL
},
3426 { .name
= "arp_reset", .value
= TS_CMD_RESET
},
3427 { .name
= "arp_halt", .value
= TS_CMD_HALT
},
3428 { .name
= "arp_waitstate", .value
= TS_CMD_WAITSTATE
},
3429 { .name
= "invoke-event", .value
= TS_CMD_INVOKE_EVENT
},
3431 { .name
= NULL
, .value
= -1 },
3434 /* go past the "command" */
3435 Jim_GetOpt_Setup( &goi
, interp
, argc
-1, argv
+1 );
3437 target
= Jim_CmdPrivData( goi
.interp
);
3438 cmd_ctx
= Jim_GetAssocData(goi
.interp
, "context");
3440 /* commands here are in an NVP table */
3441 e
= Jim_GetOpt_Nvp( &goi
, target_options
, &n
);
3443 Jim_GetOpt_NvpUnknown( &goi
, target_options
, 0 );
3446 /* Assume blank result */
3447 Jim_SetEmptyResult( goi
.interp
);
3450 case TS_CMD_CONFIGURE
:
3452 Jim_WrongNumArgs( goi
.interp
, goi
.argc
, goi
.argv
, "missing: -option VALUE ...");
3455 goi
.isconfigure
= 1;
3456 return target_configure( &goi
, target
);
3458 // some things take params
3460 Jim_WrongNumArgs( goi
.interp
, 0, goi
.argv
, "missing: ?-option?");
3463 goi
.isconfigure
= 0;
3464 return target_configure( &goi
, target
);
3472 * argv[3] = optional count.
3475 if( (goi
.argc
== 3) || (goi
.argc
== 4) ){
3479 Jim_SetResult_sprintf( goi
.interp
, "expected: %s ADDR DATA [COUNT]", n
->name
);
3483 e
= Jim_GetOpt_Wide( &goi
, &a
);
3488 e
= Jim_GetOpt_Wide( &goi
, &b
);
3493 e
= Jim_GetOpt_Wide( &goi
, &c
);
3503 target_buffer_set_u32( target
, target_buf
, b
);
3507 target_buffer_set_u16( target
, target_buf
, b
);
3511 target_buffer_set_u8( target
, target_buf
, b
);
3515 for( x
= 0 ; x
< c
; x
++ ){
3516 e
= target
->type
->write_memory( target
, a
, b
, 1, target_buf
);
3517 if( e
!= ERROR_OK
){
3518 Jim_SetResult_sprintf( interp
, "Error writing @ 0x%08x: %d\n", (int)(a
), e
);
3531 /* argv[0] = command
3533 * argv[2] = optional count
3535 if( (goi
.argc
== 2) || (goi
.argc
== 3) ){
3536 Jim_SetResult_sprintf( goi
.interp
, "expected: %s ADDR [COUNT]", n
->name
);
3539 e
= Jim_GetOpt_Wide( &goi
, &a
);
3544 e
= Jim_GetOpt_Wide( &goi
, &c
);
3551 b
= 1; /* shut up gcc */
3564 /* convert to "bytes" */
3566 /* count is now in 'BYTES' */
3572 e
= target
->type
->read_memory( target
, a
, b
, y
/ b
, target_buf
);
3573 if( e
!= ERROR_OK
){
3574 Jim_SetResult_sprintf( interp
, "error reading target @ 0x%08lx", (int)(a
) );
3578 Jim_fprintf( interp
, interp
->cookie_stdout
, "0x%08x ", (int)(a
) );
3581 for( x
= 0 ; (x
< 16) && (x
< y
) ; x
+= 4 ){
3582 z
= target_buffer_get_u32( target
, &(target_buf
[ x
* 4 ]) );
3583 Jim_fprintf( interp
, interp
->cookie_stdout
, "%08x ", (int)(z
) );
3585 for( ; (x
< 16) ; x
+= 4 ){
3586 Jim_fprintf( interp
, interp
->cookie_stdout
, " " );
3590 for( x
= 0 ; (x
< 16) && (x
< y
) ; x
+= 2 ){
3591 z
= target_buffer_get_u16( target
, &(target_buf
[ x
* 2 ]) );
3592 Jim_fprintf( interp
, interp
->cookie_stdout
, "%04x ", (int)(z
) );
3594 for( ; (x
< 16) ; x
+= 2 ){
3595 Jim_fprintf( interp
, interp
->cookie_stdout
, " " );
3600 for( x
= 0 ; (x
< 16) && (x
< y
) ; x
+= 1 ){
3601 z
= target_buffer_get_u8( target
, &(target_buf
[ x
* 4 ]) );
3602 Jim_fprintf( interp
, interp
->cookie_stdout
, "%02x ", (int)(z
) );
3604 for( ; (x
< 16) ; x
+= 1 ){
3605 Jim_fprintf( interp
, interp
->cookie_stdout
, " " );
3609 /* ascii-ify the bytes */
3610 for( x
= 0 ; x
< y
; x
++ ){
3611 if( (target_buf
[x
] >= 0x20) &&
3612 (target_buf
[x
] <= 0x7e) ){
3616 target_buf
[x
] = '.';
3621 target_buf
[x
] = ' ';
3626 /* print - with a newline */
3627 Jim_fprintf( interp
, interp
->cookie_stdout
, "%s\n", target_buf
);
3633 case TS_CMD_MEM2ARRAY
:
3634 return target_mem2array( goi
.interp
, target
, goi
.argc
, goi
.argv
);
3636 case TS_CMD_ARRAY2MEM
:
3637 return target_array2mem( goi
.interp
, target
, goi
.argc
, goi
.argv
);
3639 case TS_CMD_EXAMINE
:
3641 Jim_WrongNumArgs( goi
.interp
, 2, argv
, "[no parameters]");
3644 e
= target
->type
->examine( target
);
3645 if( e
!= ERROR_OK
){
3646 Jim_SetResult_sprintf( interp
, "examine-fails: %d", e
);
3652 Jim_WrongNumArgs( goi
.interp
, 2, argv
, "[no parameters]");
3655 if( !(target
->type
->examined
) ){
3656 e
= ERROR_TARGET_NOT_EXAMINED
;
3658 e
= target
->type
->poll( target
);
3660 if( e
!= ERROR_OK
){
3661 Jim_SetResult_sprintf( interp
, "poll-fails: %d", e
);
3668 if( goi
.argc
!= 2 ){
3669 Jim_WrongNumArgs( interp
, 2, argv
, "t|f|assert|deassert BOOL");
3672 e
= Jim_GetOpt_Nvp( &goi
, nvp_assert
, &n
);
3674 Jim_GetOpt_NvpUnknown( &goi
, nvp_assert
, 1 );
3677 /* the halt or not param */
3678 e
= Jim_GetOpt_Wide( &goi
, &a
);
3682 /* determine if we should halt or not. */
3683 target
->reset_halt
= !!a
;
3684 /* When this happens - all workareas are invalid. */
3685 target_free_all_working_areas_restore(target
, 0);
3688 if( n
->value
== NVP_ASSERT
){
3689 target
->type
->assert_reset( target
);
3691 target
->type
->deassert_reset( target
);
3696 Jim_WrongNumArgs( goi
.interp
, 0, argv
, "halt [no parameters]");
3699 target
->type
->halt( target
);
3701 case TS_CMD_WAITSTATE
:
3702 /* params: <name> statename timeoutmsecs */
3703 if( goi
.argc
!= 2 ){
3704 Jim_SetResult_sprintf( goi
.interp
, "%s STATENAME TIMEOUTMSECS", n
->name
);
3707 e
= Jim_GetOpt_Nvp( &goi
, nvp_target_state
, &n
);
3709 Jim_GetOpt_NvpUnknown( &goi
, nvp_target_state
,1 );
3712 e
= Jim_GetOpt_Wide( &goi
, &a
);
3716 e
= target_wait_state( target
, n
->value
, a
);
3717 if( e
!= ERROR_OK
){
3718 Jim_SetResult_sprintf( goi
.interp
,
3719 "target: %s wait %s fails (%d) %s",
3722 e
, target_strerror_safe(e
) );
3727 case TS_CMD_EVENTLIST
:
3728 /* List for human, Events defined for this target.
3729 * scripts/programs should use 'name cget -event NAME'
3732 target_event_action_t
*teap
;
3733 teap
= target
->event_action
;
3734 command_print( cmd_ctx
, "Event actions for target (%d) %s\n",
3735 target
->target_number
,
3737 command_print( cmd_ctx
, "%-25s | Body", "Event");
3738 command_print( cmd_ctx
, "------------------------- | ----------------------------------------");
3740 command_print( cmd_ctx
,
3742 Jim_Nvp_value2name_simple( nvp_target_event
, teap
->event
)->name
,
3743 Jim_GetString( teap
->body
, NULL
) );
3746 command_print( cmd_ctx
, "***END***");
3749 case TS_CMD_CURSTATE
:
3750 if( goi
.argc
!= 0 ){
3751 Jim_WrongNumArgs( goi
.interp
, 0, argv
, "[no parameters]");
3754 Jim_SetResultString( goi
.interp
,
3755 Jim_Nvp_value2name_simple(nvp_target_state
,target
->state
)->name
,-1);
3757 case TS_CMD_INVOKE_EVENT
:
3758 if( goi
.argc
!= 1 ){
3759 Jim_SetResult_sprintf( goi
.interp
, "%s ?EVENTNAME?",n
->name
);
3762 e
= Jim_GetOpt_Nvp( &goi
, nvp_target_event
, &n
);
3764 Jim_GetOpt_NvpUnknown( &goi
, nvp_target_event
, 1 );
3767 target_handle_event( target
, n
->value
);
3773 static int target_create( Jim_GetOptInfo
*goi
)
3782 struct command_context_s
*cmd_ctx
;
3784 cmd_ctx
= Jim_GetAssocData(goi
->interp
, "context");
3785 if( goi
->argc
< 3 ){
3786 Jim_WrongNumArgs( goi
->interp
, 1, goi
->argv
, "?name? ?type? ..options...");
3791 Jim_GetOpt_Obj( goi
, &new_cmd
);
3792 /* does this command exist? */
3793 cmd
= Jim_GetCommand( goi
->interp
, new_cmd
, JIM_ERRMSG
);
3795 cp
= Jim_GetString( new_cmd
, NULL
);
3796 Jim_SetResult_sprintf(goi
->interp
, "Command/target: %s Exists", cp
);
3801 e
= Jim_GetOpt_String( goi
, &cp2
, NULL
);
3803 /* now does target type exist */
3804 for( x
= 0 ; target_types
[x
] ; x
++ ){
3805 if( 0 == strcmp( cp
, target_types
[x
]->name
) ){
3810 if( target_types
[x
] == NULL
){
3811 Jim_SetResult_sprintf( goi
->interp
, "Unknown target type %s, try one of ", cp
);
3812 for( x
= 0 ; target_types
[x
] ; x
++ ){
3813 if( target_types
[x
+1] ){
3814 Jim_AppendStrings( goi
->interp
,
3815 Jim_GetResult(goi
->interp
),
3816 target_types
[x
]->name
,
3819 Jim_AppendStrings( goi
->interp
,
3820 Jim_GetResult(goi
->interp
),
3822 target_types
[x
]->name
,NULL
);
3829 target
= calloc(1,sizeof(target_t
));
3830 /* set target number */
3831 target
->target_number
= new_target_number();
3833 /* allocate memory for each unique target type */
3834 target
->type
= (target_type_t
*)calloc(1,sizeof(target_type_t
));
3836 memcpy( target
->type
, target_types
[x
], sizeof(target_type_t
));
3838 /* will be set by "-endian" */
3839 target
->endianness
= TARGET_ENDIAN_UNKNOWN
;
3841 target
->working_area
= 0x0;
3842 target
->working_area_size
= 0x0;
3843 target
->working_areas
= NULL
;
3844 target
->backup_working_area
= 0;
3846 target
->state
= TARGET_UNKNOWN
;
3847 target
->debug_reason
= DBG_REASON_UNDEFINED
;
3848 target
->reg_cache
= NULL
;
3849 target
->breakpoints
= NULL
;
3850 target
->watchpoints
= NULL
;
3851 target
->next
= NULL
;
3852 target
->arch_info
= NULL
;
3854 target
->display
= 1;
3856 /* initialize trace information */
3857 target
->trace_info
= malloc(sizeof(trace_t
));
3858 target
->trace_info
->num_trace_points
= 0;
3859 target
->trace_info
->trace_points_size
= 0;
3860 target
->trace_info
->trace_points
= NULL
;
3861 target
->trace_info
->trace_history_size
= 0;
3862 target
->trace_info
->trace_history
= NULL
;
3863 target
->trace_info
->trace_history_pos
= 0;
3864 target
->trace_info
->trace_history_overflowed
= 0;
3866 target
->dbgmsg
= NULL
;
3867 target
->dbg_msg_enabled
= 0;
3869 target
->endianness
= TARGET_ENDIAN_UNKNOWN
;
3871 /* Do the rest as "configure" options */
3872 goi
->isconfigure
= 1;
3873 e
= target_configure( goi
, target
);
3875 if (target
->tap
== NULL
)
3877 Jim_SetResultString( interp
, "-chain-position required when creating target", -1);
3882 free( target
->type
);
3887 if( target
->endianness
== TARGET_ENDIAN_UNKNOWN
){
3888 /* default endian to little if not specified */
3889 target
->endianness
= TARGET_LITTLE_ENDIAN
;
3892 /* incase variant is not set */
3893 if (!target
->variant
)
3894 target
->variant
= strdup("");
3896 /* create the target specific commands */
3897 if( target
->type
->register_commands
){
3898 (*(target
->type
->register_commands
))( cmd_ctx
);
3900 if( target
->type
->target_create
){
3901 (*(target
->type
->target_create
))( target
, goi
->interp
);
3904 /* append to end of list */
3907 tpp
= &(all_targets
);
3909 tpp
= &( (*tpp
)->next
);
3914 cp
= Jim_GetString( new_cmd
, NULL
);
3915 target
->cmd_name
= strdup(cp
);
3917 /* now - create the new target name command */
3918 e
= Jim_CreateCommand( goi
->interp
,
3921 tcl_target_func
, /* C function */
3922 target
, /* private data */
3923 NULL
); /* no del proc */
3928 static int jim_target( Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
3932 struct command_context_s
*cmd_ctx
;
3936 /* TG = target generic */
3944 const char *target_cmds
[] = {
3945 "create", "types", "names", "current", "number",
3947 NULL
/* terminate */
3950 LOG_DEBUG("Target command params:");
3951 LOG_DEBUG("%s", Jim_Debug_ArgvString(interp
, argc
, argv
));
3953 cmd_ctx
= Jim_GetAssocData( interp
, "context" );
3955 Jim_GetOpt_Setup( &goi
, interp
, argc
-1, argv
+1 );
3957 if( goi
.argc
== 0 ){
3958 Jim_WrongNumArgs(interp
, 1, argv
, "missing: command ...");
3962 /* Jim_GetOpt_Debug( &goi ); */
3963 r
= Jim_GetOpt_Enum( &goi
, target_cmds
, &x
);
3970 Jim_Panic(goi
.interp
,"Why am I here?");
3972 case TG_CMD_CURRENT
:
3973 if( goi
.argc
!= 0 ){
3974 Jim_WrongNumArgs( goi
.interp
, 1, goi
.argv
, "Too many parameters");
3977 Jim_SetResultString( goi
.interp
, get_current_target( cmd_ctx
)->cmd_name
, -1 );
3980 if( goi
.argc
!= 0 ){
3981 Jim_WrongNumArgs( goi
.interp
, 1, goi
.argv
, "Too many parameters" );
3984 Jim_SetResult( goi
.interp
, Jim_NewListObj( goi
.interp
, NULL
, 0 ) );
3985 for( x
= 0 ; target_types
[x
] ; x
++ ){
3986 Jim_ListAppendElement( goi
.interp
,
3987 Jim_GetResult(goi
.interp
),
3988 Jim_NewStringObj( goi
.interp
, target_types
[x
]->name
, -1 ) );
3992 if( goi
.argc
!= 0 ){
3993 Jim_WrongNumArgs( goi
.interp
, 1, goi
.argv
, "Too many parameters" );
3996 Jim_SetResult( goi
.interp
, Jim_NewListObj( goi
.interp
, NULL
, 0 ) );
3997 target
= all_targets
;
3999 Jim_ListAppendElement( goi
.interp
,
4000 Jim_GetResult(goi
.interp
),
4001 Jim_NewStringObj( goi
.interp
, target
->cmd_name
, -1 ) );
4002 target
= target
->next
;
4007 Jim_WrongNumArgs( goi
.interp
, goi
.argc
, goi
.argv
, "?name ... config options ...");
4010 return target_create( &goi
);
4013 if( goi
.argc
!= 1 ){
4014 Jim_SetResult_sprintf( goi
.interp
, "expected: target number ?NUMBER?");
4017 e
= Jim_GetOpt_Wide( &goi
, &w
);
4023 t
= get_target_by_num(w
);
4025 Jim_SetResult_sprintf( goi
.interp
,"Target: number %d does not exist", (int)(w
));
4028 Jim_SetResultString( goi
.interp
, t
->cmd_name
, -1 );
4032 if( goi
.argc
!= 0 ){
4033 Jim_WrongNumArgs( goi
.interp
, 0, goi
.argv
, "<no parameters>");
4036 Jim_SetResult( goi
.interp
,
4037 Jim_NewIntObj( goi
.interp
, max_target_number()));
4053 static int fastload_num
;
4054 static struct FastLoad
*fastload
;
4056 static void free_fastload(void)
4061 for (i
=0; i
<fastload_num
; i
++)
4063 if (fastload
[i
].data
)
4064 free(fastload
[i
].data
);
4074 static int handle_fast_load_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
4080 u32 max_address
=0xffffffff;
4086 duration_t duration
;
4087 char *duration_text
;
4089 if ((argc
< 1)||(argc
> 5))
4091 return ERROR_COMMAND_SYNTAX_ERROR
;
4094 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
4097 image
.base_address_set
= 1;
4098 image
.base_address
= strtoul(args
[1], NULL
, 0);
4102 image
.base_address_set
= 0;
4106 image
.start_address_set
= 0;
4110 min_address
=strtoul(args
[3], NULL
, 0);
4114 max_address
=strtoul(args
[4], NULL
, 0)+min_address
;
4117 if (min_address
>max_address
)
4119 return ERROR_COMMAND_SYNTAX_ERROR
;
4122 duration_start_measure(&duration
);
4124 if (image_open(&image
, args
[0], (argc
>= 3) ? args
[2] : NULL
) != ERROR_OK
)
4131 fastload_num
=image
.num_sections
;
4132 fastload
=(struct FastLoad
*)malloc(sizeof(struct FastLoad
)*image
.num_sections
);
4135 image_close(&image
);
4138 memset(fastload
, 0, sizeof(struct FastLoad
)*image
.num_sections
);
4139 for (i
= 0; i
< image
.num_sections
; i
++)
4141 buffer
= malloc(image
.sections
[i
].size
);
4144 command_print(cmd_ctx
, "error allocating buffer for section (%d bytes)", image
.sections
[i
].size
);
4148 if ((retval
= image_read_section(&image
, i
, 0x0, image
.sections
[i
].size
, buffer
, &buf_cnt
)) != ERROR_OK
)
4158 /* DANGER!!! beware of unsigned comparision here!!! */
4160 if ((image
.sections
[i
].base_address
+buf_cnt
>=min_address
)&&
4161 (image
.sections
[i
].base_address
<max_address
))
4163 if (image
.sections
[i
].base_address
<min_address
)
4165 /* clip addresses below */
4166 offset
+=min_address
-image
.sections
[i
].base_address
;
4170 if (image
.sections
[i
].base_address
+buf_cnt
>max_address
)
4172 length
-=(image
.sections
[i
].base_address
+buf_cnt
)-max_address
;
4175 fastload
[i
].address
=image
.sections
[i
].base_address
+offset
;
4176 fastload
[i
].data
=malloc(length
);
4177 if (fastload
[i
].data
==NULL
)
4182 memcpy(fastload
[i
].data
, buffer
+offset
, length
);
4183 fastload
[i
].length
=length
;
4185 image_size
+= length
;
4186 command_print(cmd_ctx
, "%u byte written at address 0x%8.8x", length
, image
.sections
[i
].base_address
+offset
);
4192 duration_stop_measure(&duration
, &duration_text
);
4193 if (retval
==ERROR_OK
)
4195 command_print(cmd_ctx
, "Loaded %u bytes in %s", image_size
, duration_text
);
4196 command_print(cmd_ctx
, "NB!!! image has not been loaded to target, issue a subsequent 'fast_load' to do so.");
4198 free(duration_text
);
4200 image_close(&image
);
4202 if (retval
!=ERROR_OK
)
4210 static int handle_fast_load_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
4213 return ERROR_COMMAND_SYNTAX_ERROR
;
4216 LOG_ERROR("No image in memory");
4220 int ms
=timeval_ms();
4222 int retval
=ERROR_OK
;
4223 for (i
=0; i
<fastload_num
;i
++)
4225 target_t
*target
= get_current_target(cmd_ctx
);
4226 command_print(cmd_ctx
, "Write to 0x%08x, length 0x%08x", fastload
[i
].address
, fastload
[i
].length
);
4227 if (retval
==ERROR_OK
)
4229 retval
= target_write_buffer(target
, fastload
[i
].address
, fastload
[i
].length
, fastload
[i
].data
);
4231 size
+=fastload
[i
].length
;
4233 int after
=timeval_ms();
4234 command_print(cmd_ctx
, "Loaded image %f kBytes/s", (float)(size
/1024.0)/((float)(after
-ms
)/1000.0));
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)