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");
1289 register_jim(cmd_ctx
, "ocd_array2mem", jim_array2mem
, "convert a TCL array to memory locations and write the values");
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 ((address
& 3) || (size
& 3))
2120 command_print(cmd_ctx
, "only 32-bit aligned address and size are supported");
2124 if (fileio_open(&fileio
, args
[0], FILEIO_WRITE
, FILEIO_BINARY
) != ERROR_OK
)
2129 duration_start_measure(&duration
);
2134 u32 this_run_size
= (size
> 560) ? 560 : size
;
2136 retval
= target
->type
->read_memory(target
, address
, 4, this_run_size
/ 4, buffer
);
2137 if (retval
!= ERROR_OK
)
2142 retval
= fileio_write(&fileio
, this_run_size
, buffer
, &size_written
);
2143 if (retval
!= ERROR_OK
)
2148 size
-= this_run_size
;
2149 address
+= this_run_size
;
2152 if((retvaltemp
= fileio_close(&fileio
)) != ERROR_OK
)
2155 if((retvaltemp
= duration_stop_measure(&duration
, &duration_text
)) != ERROR_OK
)
2158 if (retval
==ERROR_OK
)
2160 command_print(cmd_ctx
, "dumped %"PRIi64
" byte in %s", fileio
.size
, duration_text
);
2161 free(duration_text
);
2167 static int handle_verify_image_command_internal(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, int verify
)
2173 int retval
, retvaltemp
;
2175 u32 mem_checksum
= 0;
2179 duration_t duration
;
2180 char *duration_text
;
2182 target_t
*target
= get_current_target(cmd_ctx
);
2186 return ERROR_COMMAND_SYNTAX_ERROR
;
2191 LOG_ERROR("no target selected");
2195 duration_start_measure(&duration
);
2199 image
.base_address_set
= 1;
2200 image
.base_address
= strtoul(args
[1], NULL
, 0);
2204 image
.base_address_set
= 0;
2205 image
.base_address
= 0x0;
2208 image
.start_address_set
= 0;
2210 if ((retval
=image_open(&image
, args
[0], (argc
== 3) ? args
[2] : NULL
)) != ERROR_OK
)
2217 for (i
= 0; i
< image
.num_sections
; i
++)
2219 buffer
= malloc(image
.sections
[i
].size
);
2222 command_print(cmd_ctx
, "error allocating buffer for section (%d bytes)", image
.sections
[i
].size
);
2225 if ((retval
= image_read_section(&image
, i
, 0x0, image
.sections
[i
].size
, buffer
, &buf_cnt
)) != ERROR_OK
)
2233 /* calculate checksum of image */
2234 image_calculate_checksum( buffer
, buf_cnt
, &checksum
);
2236 retval
= target_checksum_memory(target
, image
.sections
[i
].base_address
, buf_cnt
, &mem_checksum
);
2237 if( retval
!= ERROR_OK
)
2243 if( checksum
!= mem_checksum
)
2245 /* failed crc checksum, fall back to a binary compare */
2248 command_print(cmd_ctx
, "checksum mismatch - attempting binary compare");
2250 data
= (u8
*)malloc(buf_cnt
);
2252 /* Can we use 32bit word accesses? */
2254 int count
= buf_cnt
;
2255 if ((count
% 4) == 0)
2260 retval
= target
->type
->read_memory(target
, image
.sections
[i
].base_address
, size
, count
, data
);
2261 if (retval
== ERROR_OK
)
2264 for (t
= 0; t
< buf_cnt
; t
++)
2266 if (data
[t
] != buffer
[t
])
2268 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
]);
2285 command_print(cmd_ctx
, "address 0x%08x length 0x%08x", image
.sections
[i
].base_address
, buf_cnt
);
2289 image_size
+= buf_cnt
;
2293 if((retvaltemp
= duration_stop_measure(&duration
, &duration_text
)) != ERROR_OK
)
2295 image_close(&image
);
2299 if (retval
==ERROR_OK
)
2301 command_print(cmd_ctx
, "verified %u bytes in %s", image_size
, duration_text
);
2303 free(duration_text
);
2305 image_close(&image
);
2310 static int handle_verify_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2312 return handle_verify_image_command_internal(cmd_ctx
, cmd
, args
, argc
, 1);
2315 static int handle_test_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2317 return handle_verify_image_command_internal(cmd_ctx
, cmd
, args
, argc
, 0);
2320 static int handle_bp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2323 target_t
*target
= get_current_target(cmd_ctx
);
2327 breakpoint_t
*breakpoint
= target
->breakpoints
;
2331 if (breakpoint
->type
== BKPT_SOFT
)
2333 char* buf
= buf_to_str(breakpoint
->orig_instr
, breakpoint
->length
, 16);
2334 command_print(cmd_ctx
, "0x%8.8x, 0x%x, %i, 0x%s", breakpoint
->address
, breakpoint
->length
, breakpoint
->set
, buf
);
2339 command_print(cmd_ctx
, "0x%8.8x, 0x%x, %i", breakpoint
->address
, breakpoint
->length
, breakpoint
->set
);
2341 breakpoint
= breakpoint
->next
;
2349 length
= strtoul(args
[1], NULL
, 0);
2352 if (strcmp(args
[2], "hw") == 0)
2355 if ((retval
= breakpoint_add(target
, strtoul(args
[0], NULL
, 0), length
, hw
)) != ERROR_OK
)
2357 LOG_ERROR("Failure setting breakpoints");
2361 command_print(cmd_ctx
, "breakpoint added at address 0x%8.8x", strtoul(args
[0], NULL
, 0));
2366 command_print(cmd_ctx
, "usage: bp <address> <length> ['hw']");
2372 static int handle_rbp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2374 target_t
*target
= get_current_target(cmd_ctx
);
2377 breakpoint_remove(target
, strtoul(args
[0], NULL
, 0));
2382 static int handle_wp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2384 target_t
*target
= get_current_target(cmd_ctx
);
2389 watchpoint_t
*watchpoint
= target
->watchpoints
;
2393 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
);
2394 watchpoint
= watchpoint
->next
;
2399 enum watchpoint_rw type
= WPT_ACCESS
;
2400 u32 data_value
= 0x0;
2401 u32 data_mask
= 0xffffffff;
2417 command_print(cmd_ctx
, "usage: wp <address> <length> [r/w/a] [value] [mask]");
2423 data_value
= strtoul(args
[3], NULL
, 0);
2427 data_mask
= strtoul(args
[4], NULL
, 0);
2430 if ((retval
= watchpoint_add(target
, strtoul(args
[0], NULL
, 0),
2431 strtoul(args
[1], NULL
, 0), type
, data_value
, data_mask
)) != ERROR_OK
)
2433 LOG_ERROR("Failure setting breakpoints");
2438 command_print(cmd_ctx
, "usage: wp <address> <length> [r/w/a] [value] [mask]");
2444 static int handle_rwp_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2446 target_t
*target
= get_current_target(cmd_ctx
);
2449 watchpoint_remove(target
, strtoul(args
[0], NULL
, 0));
2454 static int handle_virt2phys_command(command_context_t
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2457 target_t
*target
= get_current_target(cmd_ctx
);
2463 return ERROR_COMMAND_SYNTAX_ERROR
;
2465 va
= strtoul(args
[0], NULL
, 0);
2467 retval
= target
->type
->virt2phys(target
, va
, &pa
);
2468 if (retval
== ERROR_OK
)
2470 command_print(cmd_ctx
, "Physical address 0x%08x", pa
);
2474 /* lower levels will have logged a detailed error which is
2475 * forwarded to telnet/GDB session.
2481 static void writeData(FILE *f
, const void *data
, size_t len
)
2483 size_t written
= fwrite(data
, len
, 1, f
);
2485 LOG_ERROR("failed to write %zu bytes: %s", len
, strerror(errno
));
2488 static void writeLong(FILE *f
, int l
)
2493 char c
=(l
>>(i
*8))&0xff;
2494 writeData(f
, &c
, 1);
2499 static void writeString(FILE *f
, char *s
)
2501 writeData(f
, s
, strlen(s
));
2504 /* Dump a gmon.out histogram file. */
2505 static void writeGmon(u32
*samples
, u32 sampleNum
, char *filename
)
2508 FILE *f
=fopen(filename
, "w");
2511 writeString(f
, "gmon");
2512 writeLong(f
, 0x00000001); /* Version */
2513 writeLong(f
, 0); /* padding */
2514 writeLong(f
, 0); /* padding */
2515 writeLong(f
, 0); /* padding */
2517 u8 zero
= 0; /* GMON_TAG_TIME_HIST */
2518 writeData(f
, &zero
, 1);
2520 /* figure out bucket size */
2523 for (i
=0; i
<sampleNum
; i
++)
2535 int addressSpace
=(max
-min
+1);
2537 static const u32 maxBuckets
= 256 * 1024; /* maximum buckets. */
2538 u32 length
= addressSpace
;
2539 if (length
> maxBuckets
)
2543 int *buckets
=malloc(sizeof(int)*length
);
2549 memset(buckets
, 0, sizeof(int)*length
);
2550 for (i
=0; i
<sampleNum
;i
++)
2552 u32 address
=samples
[i
];
2553 long long a
=address
-min
;
2554 long long b
=length
-1;
2555 long long c
=addressSpace
-1;
2556 int index
=(a
*b
)/c
; /* danger!!!! int32 overflows */
2560 /* append binary memory gmon.out &profile_hist_hdr ((char*)&profile_hist_hdr + sizeof(struct gmon_hist_hdr)) */
2561 writeLong(f
, min
); /* low_pc */
2562 writeLong(f
, max
); /* high_pc */
2563 writeLong(f
, length
); /* # of samples */
2564 writeLong(f
, 64000000); /* 64MHz */
2565 writeString(f
, "seconds");
2566 for (i
=0; i
<(15-strlen("seconds")); i
++)
2567 writeData(f
, &zero
, 1);
2568 writeString(f
, "s");
2570 /*append binary memory gmon.out profile_hist_data (profile_hist_data + profile_hist_hdr.hist_size) */
2572 char *data
=malloc(2*length
);
2575 for (i
=0; i
<length
;i
++)
2584 data
[i
*2+1]=(val
>>8)&0xff;
2587 writeData(f
, data
, length
* 2);
2597 /* profiling samples the CPU PC as quickly as OpenOCD is able, which will be used as a random sampling of PC */
2598 static int handle_profile_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
2600 target_t
*target
= get_current_target(cmd_ctx
);
2601 struct timeval timeout
, now
;
2603 gettimeofday(&timeout
, NULL
);
2606 return ERROR_COMMAND_SYNTAX_ERROR
;
2609 timeval_add_time(&timeout
, strtoul(args
[0], &end
, 0), 0);
2615 command_print(cmd_ctx
, "Starting profiling. Halting and resuming the target as often as we can...");
2617 static const int maxSample
=10000;
2618 u32
*samples
=malloc(sizeof(u32
)*maxSample
);
2623 int retval
=ERROR_OK
;
2624 /* hopefully it is safe to cache! We want to stop/restart as quickly as possible. */
2625 reg_t
*reg
= register_get_by_name(target
->reg_cache
, "pc", 1);
2629 target_poll(target
);
2630 if (target
->state
== TARGET_HALTED
)
2632 u32 t
=*((u32
*)reg
->value
);
2633 samples
[numSamples
++]=t
;
2634 retval
= target_resume(target
, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */
2635 target_poll(target
);
2636 alive_sleep(10); /* sleep 10ms, i.e. <100 samples/second. */
2637 } else if (target
->state
== TARGET_RUNNING
)
2639 /* We want to quickly sample the PC. */
2640 if((retval
= target_halt(target
)) != ERROR_OK
)
2647 command_print(cmd_ctx
, "Target not halted or running");
2651 if (retval
!=ERROR_OK
)
2656 gettimeofday(&now
, NULL
);
2657 if ((numSamples
>=maxSample
) || ((now
.tv_sec
>= timeout
.tv_sec
) && (now
.tv_usec
>= timeout
.tv_usec
)))
2659 command_print(cmd_ctx
, "Profiling completed. %d samples.", numSamples
);
2660 if((retval
= target_poll(target
)) != ERROR_OK
)
2665 if (target
->state
== TARGET_HALTED
)
2667 target_resume(target
, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */
2669 if((retval
= target_poll(target
)) != ERROR_OK
)
2674 writeGmon(samples
, numSamples
, args
[1]);
2675 command_print(cmd_ctx
, "Wrote %s", args
[1]);
2684 static int new_int_array_element(Jim_Interp
* interp
, const char *varname
, int idx
, u32 val
)
2687 Jim_Obj
*nameObjPtr
, *valObjPtr
;
2690 namebuf
= alloc_printf("%s(%d)", varname
, idx
);
2694 nameObjPtr
= Jim_NewStringObj(interp
, namebuf
, -1);
2695 valObjPtr
= Jim_NewIntObj(interp
, val
);
2696 if (!nameObjPtr
|| !valObjPtr
)
2702 Jim_IncrRefCount(nameObjPtr
);
2703 Jim_IncrRefCount(valObjPtr
);
2704 result
= Jim_SetVariable(interp
, nameObjPtr
, valObjPtr
);
2705 Jim_DecrRefCount(interp
, nameObjPtr
);
2706 Jim_DecrRefCount(interp
, valObjPtr
);
2708 /* printf("%s(%d) <= 0%08x\n", varname, idx, val); */
2712 static int jim_mem2array(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
2714 command_context_t
*context
;
2717 context
= Jim_GetAssocData(interp
, "context");
2718 if (context
== NULL
)
2720 LOG_ERROR("mem2array: no command context");
2723 target
= get_current_target(context
);
2726 LOG_ERROR("mem2array: no current target");
2730 return target_mem2array(interp
, target
, argc
,argv
);
2733 static int target_mem2array(Jim_Interp
*interp
, target_t
*target
, int argc
, Jim_Obj
*const *argv
)
2741 const char *varname
;
2746 /* argv[1] = name of array to receive the data
2747 * argv[2] = desired width
2748 * argv[3] = memory address
2749 * argv[4] = count of times to read
2752 Jim_WrongNumArgs(interp
, 1, argv
, "varname width addr nelems");
2755 varname
= Jim_GetString(argv
[1], &len
);
2756 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
2758 e
= Jim_GetLong(interp
, argv
[2], &l
);
2764 e
= Jim_GetLong(interp
, argv
[3], &l
);
2769 e
= Jim_GetLong(interp
, argv
[4], &l
);
2785 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2786 Jim_AppendStrings( interp
, Jim_GetResult(interp
), "Invalid width param, must be 8/16/32", NULL
);
2790 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2791 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: zero width read?", NULL
);
2794 if ((addr
+ (len
* width
)) < addr
) {
2795 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2796 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: addr + len - wraps to zero?", NULL
);
2799 /* absurd transfer size? */
2801 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2802 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: absurd > 64K item request", NULL
);
2807 ((width
== 2) && ((addr
& 1) == 0)) ||
2808 ((width
== 4) && ((addr
& 3) == 0))) {
2812 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2813 sprintf(buf
, "mem2array address: 0x%08x is not aligned for %d byte reads", addr
, width
);
2814 Jim_AppendStrings(interp
, Jim_GetResult(interp
), buf
, NULL
);
2825 /* Slurp... in buffer size chunks */
2827 count
= len
; /* in objects.. */
2828 if (count
> (sizeof(buffer
)/width
)) {
2829 count
= (sizeof(buffer
)/width
);
2832 retval
= target
->type
->read_memory( target
, addr
, width
, count
, buffer
);
2833 if (retval
!= ERROR_OK
) {
2835 LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed", addr
, width
, count
);
2836 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2837 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "mem2array: cannot read memory", NULL
);
2841 v
= 0; /* shut up gcc */
2842 for (i
= 0 ;i
< count
;i
++, n
++) {
2845 v
= target_buffer_get_u32(target
, &buffer
[i
*width
]);
2848 v
= target_buffer_get_u16(target
, &buffer
[i
*width
]);
2851 v
= buffer
[i
] & 0x0ff;
2854 new_int_array_element(interp
, varname
, n
, v
);
2860 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2865 static int get_int_array_element(Jim_Interp
* interp
, const char *varname
, int idx
, u32
*val
)
2868 Jim_Obj
*nameObjPtr
, *valObjPtr
;
2872 namebuf
= alloc_printf("%s(%d)", varname
, idx
);
2876 nameObjPtr
= Jim_NewStringObj(interp
, namebuf
, -1);
2883 Jim_IncrRefCount(nameObjPtr
);
2884 valObjPtr
= Jim_GetVariable(interp
, nameObjPtr
, JIM_ERRMSG
);
2885 Jim_DecrRefCount(interp
, nameObjPtr
);
2887 if (valObjPtr
== NULL
)
2890 result
= Jim_GetLong(interp
, valObjPtr
, &l
);
2891 /* printf("%s(%d) => 0%08x\n", varname, idx, val); */
2896 static int jim_array2mem(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
2898 command_context_t
*context
;
2901 context
= Jim_GetAssocData(interp
, "context");
2902 if (context
== NULL
){
2903 LOG_ERROR("array2mem: no command context");
2906 target
= get_current_target(context
);
2907 if (target
== NULL
){
2908 LOG_ERROR("array2mem: no current target");
2912 return target_array2mem( interp
,target
, argc
, argv
);
2915 static int target_array2mem(Jim_Interp
*interp
, target_t
*target
, int argc
, Jim_Obj
*const *argv
)
2923 const char *varname
;
2928 /* argv[1] = name of array to get the data
2929 * argv[2] = desired width
2930 * argv[3] = memory address
2931 * argv[4] = count to write
2934 Jim_WrongNumArgs(interp
, 1, argv
, "varname width addr nelems");
2937 varname
= Jim_GetString(argv
[1], &len
);
2938 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
2940 e
= Jim_GetLong(interp
, argv
[2], &l
);
2946 e
= Jim_GetLong(interp
, argv
[3], &l
);
2951 e
= Jim_GetLong(interp
, argv
[4], &l
);
2967 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2968 Jim_AppendStrings( interp
, Jim_GetResult(interp
), "Invalid width param, must be 8/16/32", NULL
);
2972 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2973 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: zero width read?", NULL
);
2976 if ((addr
+ (len
* width
)) < addr
) {
2977 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2978 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: addr + len - wraps to zero?", NULL
);
2981 /* absurd transfer size? */
2983 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2984 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: absurd > 64K item request", NULL
);
2989 ((width
== 2) && ((addr
& 1) == 0)) ||
2990 ((width
== 4) && ((addr
& 3) == 0))) {
2994 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
2995 sprintf(buf
, "array2mem address: 0x%08x is not aligned for %d byte reads", addr
, width
);
2996 Jim_AppendStrings(interp
, Jim_GetResult(interp
), buf
, NULL
);
3007 /* Slurp... in buffer size chunks */
3009 count
= len
; /* in objects.. */
3010 if (count
> (sizeof(buffer
)/width
)) {
3011 count
= (sizeof(buffer
)/width
);
3014 v
= 0; /* shut up gcc */
3015 for (i
= 0 ;i
< count
;i
++, n
++) {
3016 get_int_array_element(interp
, varname
, n
, &v
);
3019 target_buffer_set_u32(target
, &buffer
[i
*width
], v
);
3022 target_buffer_set_u16(target
, &buffer
[i
*width
], v
);
3025 buffer
[i
] = v
& 0x0ff;
3031 retval
= target
->type
->write_memory(target
, addr
, width
, count
, buffer
);
3032 if (retval
!= ERROR_OK
) {
3034 LOG_ERROR("array2mem: Write @ 0x%08x, w=%d, cnt=%d, failed", addr
, width
, count
);
3035 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
3036 Jim_AppendStrings(interp
, Jim_GetResult(interp
), "array2mem: cannot read memory", NULL
);
3042 Jim_SetResult(interp
, Jim_NewEmptyStringObj(interp
));
3047 void target_all_handle_event( enum target_event e
)
3051 LOG_DEBUG( "**all*targets: event: %d, %s",
3053 Jim_Nvp_value2name_simple( nvp_target_event
, e
)->name
);
3055 target
= all_targets
;
3057 target_handle_event( target
, e
);
3058 target
= target
->next
;
3062 void target_handle_event( target_t
*target
, enum target_event e
)
3064 target_event_action_t
*teap
;
3067 teap
= target
->event_action
;
3071 if( teap
->event
== e
){
3073 LOG_DEBUG( "target: (%d) %s (%s) event: %d (%s) action: %s\n",
3074 target
->target_number
,
3078 Jim_Nvp_value2name_simple( nvp_target_event
, e
)->name
,
3079 Jim_GetString( teap
->body
, NULL
) );
3080 if (Jim_EvalObj( interp
, teap
->body
)!=JIM_OK
)
3082 Jim_PrintErrorMessage(interp
);
3088 LOG_DEBUG( "event: %d %s - no action",
3090 Jim_Nvp_value2name_simple( nvp_target_event
, e
)->name
);
3094 enum target_cfg_param
{
3097 TCFG_WORK_AREA_VIRT
,
3098 TCFG_WORK_AREA_PHYS
,
3099 TCFG_WORK_AREA_SIZE
,
3100 TCFG_WORK_AREA_BACKUP
,
3103 TCFG_CHAIN_POSITION
,
3106 static Jim_Nvp nvp_config_opts
[] = {
3107 { .name
= "-type", .value
= TCFG_TYPE
},
3108 { .name
= "-event", .value
= TCFG_EVENT
},
3109 { .name
= "-work-area-virt", .value
= TCFG_WORK_AREA_VIRT
},
3110 { .name
= "-work-area-phys", .value
= TCFG_WORK_AREA_PHYS
},
3111 { .name
= "-work-area-size", .value
= TCFG_WORK_AREA_SIZE
},
3112 { .name
= "-work-area-backup", .value
= TCFG_WORK_AREA_BACKUP
},
3113 { .name
= "-endian" , .value
= TCFG_ENDIAN
},
3114 { .name
= "-variant", .value
= TCFG_VARIANT
},
3115 { .name
= "-chain-position", .value
= TCFG_CHAIN_POSITION
},
3117 { .name
= NULL
, .value
= -1 }
3120 static int target_configure( Jim_GetOptInfo
*goi
, target_t
*target
)
3128 /* parse config or cget options ... */
3129 while( goi
->argc
> 0 ){
3130 Jim_SetEmptyResult( goi
->interp
);
3131 /* Jim_GetOpt_Debug( goi ); */
3133 if( target
->type
->target_jim_configure
){
3134 /* target defines a configure function */
3135 /* target gets first dibs on parameters */
3136 e
= (*(target
->type
->target_jim_configure
))( target
, goi
);
3145 /* otherwise we 'continue' below */
3147 e
= Jim_GetOpt_Nvp( goi
, nvp_config_opts
, &n
);
3149 Jim_GetOpt_NvpUnknown( goi
, nvp_config_opts
, 0 );
3155 if( goi
->isconfigure
){
3156 Jim_SetResult_sprintf( goi
->interp
, "not setable: %s", n
->name
);
3160 if( goi
->argc
!= 0 ){
3161 Jim_WrongNumArgs( goi
->interp
, goi
->argc
, goi
->argv
, "NO PARAMS");
3165 Jim_SetResultString( goi
->interp
, target
->type
->name
, -1 );
3169 if( goi
->argc
== 0 ){
3170 Jim_WrongNumArgs( goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name? ...");
3174 e
= Jim_GetOpt_Nvp( goi
, nvp_target_event
, &n
);
3176 Jim_GetOpt_NvpUnknown( goi
, nvp_target_event
, 1 );
3180 if( goi
->isconfigure
){
3181 if( goi
->argc
!= 1 ){
3182 Jim_WrongNumArgs( goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name? ?EVENT-BODY?");
3186 if( goi
->argc
!= 0 ){
3187 Jim_WrongNumArgs(goi
->interp
, goi
->argc
, goi
->argv
, "-event ?event-name?");
3193 target_event_action_t
*teap
;
3195 teap
= target
->event_action
;
3196 /* replace existing? */
3198 if( teap
->event
== (enum target_event
)n
->value
){
3204 if( goi
->isconfigure
){
3207 teap
= calloc( 1, sizeof(*teap
) );
3209 teap
->event
= n
->value
;
3210 Jim_GetOpt_Obj( goi
, &o
);
3212 Jim_DecrRefCount( interp
, teap
->body
);
3214 teap
->body
= Jim_DuplicateObj( goi
->interp
, o
);
3217 * Tcl/TK - "tk events" have a nice feature.
3218 * See the "BIND" command.
3219 * We should support that here.
3220 * You can specify %X and %Y in the event code.
3221 * The idea is: %T - target name.
3222 * The idea is: %N - target number
3223 * The idea is: %E - event name.
3225 Jim_IncrRefCount( teap
->body
);
3227 /* add to head of event list */
3228 teap
->next
= target
->event_action
;
3229 target
->event_action
= teap
;
3230 Jim_SetEmptyResult(goi
->interp
);
3234 Jim_SetEmptyResult( goi
->interp
);
3236 Jim_SetResult( goi
->interp
, Jim_DuplicateObj( goi
->interp
, teap
->body
) );
3243 case TCFG_WORK_AREA_VIRT
:
3244 if( goi
->isconfigure
){
3245 target_free_all_working_areas(target
);
3246 e
= Jim_GetOpt_Wide( goi
, &w
);
3250 target
->working_area_virt
= w
;
3252 if( goi
->argc
!= 0 ){
3256 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_virt
) );
3260 case TCFG_WORK_AREA_PHYS
:
3261 if( goi
->isconfigure
){
3262 target_free_all_working_areas(target
);
3263 e
= Jim_GetOpt_Wide( goi
, &w
);
3267 target
->working_area_phys
= w
;
3269 if( goi
->argc
!= 0 ){
3273 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_phys
) );
3277 case TCFG_WORK_AREA_SIZE
:
3278 if( goi
->isconfigure
){
3279 target_free_all_working_areas(target
);
3280 e
= Jim_GetOpt_Wide( goi
, &w
);
3284 target
->working_area_size
= w
;
3286 if( goi
->argc
!= 0 ){
3290 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_size
) );
3294 case TCFG_WORK_AREA_BACKUP
:
3295 if( goi
->isconfigure
){
3296 target_free_all_working_areas(target
);
3297 e
= Jim_GetOpt_Wide( goi
, &w
);
3301 /* make this exactly 1 or 0 */
3302 target
->backup_working_area
= (!!w
);
3304 if( goi
->argc
!= 0 ){
3308 Jim_SetResult( interp
, Jim_NewIntObj( goi
->interp
, target
->working_area_size
) );
3309 /* loop for more e*/
3313 if( goi
->isconfigure
){
3314 e
= Jim_GetOpt_Nvp( goi
, nvp_target_endian
, &n
);
3316 Jim_GetOpt_NvpUnknown( goi
, nvp_target_endian
, 1 );
3319 target
->endianness
= n
->value
;
3321 if( goi
->argc
!= 0 ){
3325 n
= Jim_Nvp_value2name_simple( nvp_target_endian
, target
->endianness
);
3326 if( n
->name
== NULL
){
3327 target
->endianness
= TARGET_LITTLE_ENDIAN
;
3328 n
= Jim_Nvp_value2name_simple( nvp_target_endian
, target
->endianness
);
3330 Jim_SetResultString( goi
->interp
, n
->name
, -1 );
3335 if( goi
->isconfigure
){
3336 if( goi
->argc
< 1 ){
3337 Jim_SetResult_sprintf( goi
->interp
,
3342 if( target
->variant
){
3343 free((void *)(target
->variant
));
3345 e
= Jim_GetOpt_String( goi
, &cp
, NULL
);
3346 target
->variant
= strdup(cp
);
3348 if( goi
->argc
!= 0 ){
3352 Jim_SetResultString( goi
->interp
, target
->variant
,-1 );
3355 case TCFG_CHAIN_POSITION
:
3356 if( goi
->isconfigure
){
3359 target_free_all_working_areas(target
);
3360 e
= Jim_GetOpt_Obj( goi
, &o
);
3364 tap
= jtag_TapByJimObj( goi
->interp
, o
);
3368 /* make this exactly 1 or 0 */
3371 if( goi
->argc
!= 0 ){
3375 Jim_SetResultString( interp
, target
->tap
->dotted_name
, -1 );
3376 /* loop for more e*/
3379 } /* while( goi->argc ) */
3382 /* done - we return */
3386 /** this is the 'tcl' handler for the target specific command */
3387 static int tcl_target_func( Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
3395 struct command_context_s
*cmd_ctx
;
3402 TS_CMD_MWW
, TS_CMD_MWH
, TS_CMD_MWB
,
3403 TS_CMD_MDW
, TS_CMD_MDH
, TS_CMD_MDB
,
3404 TS_CMD_MRW
, TS_CMD_MRH
, TS_CMD_MRB
,
3405 TS_CMD_MEM2ARRAY
, TS_CMD_ARRAY2MEM
,
3413 TS_CMD_INVOKE_EVENT
,
3416 static const Jim_Nvp target_options
[] = {
3417 { .name
= "configure", .value
= TS_CMD_CONFIGURE
},
3418 { .name
= "cget", .value
= TS_CMD_CGET
},
3419 { .name
= "mww", .value
= TS_CMD_MWW
},
3420 { .name
= "mwh", .value
= TS_CMD_MWH
},
3421 { .name
= "mwb", .value
= TS_CMD_MWB
},
3422 { .name
= "mdw", .value
= TS_CMD_MDW
},
3423 { .name
= "mdh", .value
= TS_CMD_MDH
},
3424 { .name
= "mdb", .value
= TS_CMD_MDB
},
3425 { .name
= "mem2array", .value
= TS_CMD_MEM2ARRAY
},
3426 { .name
= "array2mem", .value
= TS_CMD_ARRAY2MEM
},
3427 { .name
= "eventlist", .value
= TS_CMD_EVENTLIST
},
3428 { .name
= "curstate", .value
= TS_CMD_CURSTATE
},
3430 { .name
= "arp_examine", .value
= TS_CMD_EXAMINE
},
3431 { .name
= "arp_poll", .value
= TS_CMD_POLL
},
3432 { .name
= "arp_reset", .value
= TS_CMD_RESET
},
3433 { .name
= "arp_halt", .value
= TS_CMD_HALT
},
3434 { .name
= "arp_waitstate", .value
= TS_CMD_WAITSTATE
},
3435 { .name
= "invoke-event", .value
= TS_CMD_INVOKE_EVENT
},
3437 { .name
= NULL
, .value
= -1 },
3440 /* go past the "command" */
3441 Jim_GetOpt_Setup( &goi
, interp
, argc
-1, argv
+1 );
3443 target
= Jim_CmdPrivData( goi
.interp
);
3444 cmd_ctx
= Jim_GetAssocData(goi
.interp
, "context");
3446 /* commands here are in an NVP table */
3447 e
= Jim_GetOpt_Nvp( &goi
, target_options
, &n
);
3449 Jim_GetOpt_NvpUnknown( &goi
, target_options
, 0 );
3452 /* Assume blank result */
3453 Jim_SetEmptyResult( goi
.interp
);
3456 case TS_CMD_CONFIGURE
:
3458 Jim_WrongNumArgs( goi
.interp
, goi
.argc
, goi
.argv
, "missing: -option VALUE ...");
3461 goi
.isconfigure
= 1;
3462 return target_configure( &goi
, target
);
3464 // some things take params
3466 Jim_WrongNumArgs( goi
.interp
, 0, goi
.argv
, "missing: ?-option?");
3469 goi
.isconfigure
= 0;
3470 return target_configure( &goi
, target
);
3478 * argv[3] = optional count.
3481 if( (goi
.argc
== 3) || (goi
.argc
== 4) ){
3485 Jim_SetResult_sprintf( goi
.interp
, "expected: %s ADDR DATA [COUNT]", n
->name
);
3489 e
= Jim_GetOpt_Wide( &goi
, &a
);
3494 e
= Jim_GetOpt_Wide( &goi
, &b
);
3499 e
= Jim_GetOpt_Wide( &goi
, &c
);
3509 target_buffer_set_u32( target
, target_buf
, b
);
3513 target_buffer_set_u16( target
, target_buf
, b
);
3517 target_buffer_set_u8( target
, target_buf
, b
);
3521 for( x
= 0 ; x
< c
; x
++ ){
3522 e
= target
->type
->write_memory( target
, a
, b
, 1, target_buf
);
3523 if( e
!= ERROR_OK
){
3524 Jim_SetResult_sprintf( interp
, "Error writing @ 0x%08x: %d\n", (int)(a
), e
);
3537 /* argv[0] = command
3539 * argv[2] = optional count
3541 if( (goi
.argc
== 2) || (goi
.argc
== 3) ){
3542 Jim_SetResult_sprintf( goi
.interp
, "expected: %s ADDR [COUNT]", n
->name
);
3545 e
= Jim_GetOpt_Wide( &goi
, &a
);
3550 e
= Jim_GetOpt_Wide( &goi
, &c
);
3557 b
= 1; /* shut up gcc */
3570 /* convert to "bytes" */
3572 /* count is now in 'BYTES' */
3578 e
= target
->type
->read_memory( target
, a
, b
, y
/ b
, target_buf
);
3579 if( e
!= ERROR_OK
){
3580 Jim_SetResult_sprintf( interp
, "error reading target @ 0x%08lx", (int)(a
) );
3584 Jim_fprintf( interp
, interp
->cookie_stdout
, "0x%08x ", (int)(a
) );
3587 for( x
= 0 ; (x
< 16) && (x
< y
) ; x
+= 4 ){
3588 z
= target_buffer_get_u32( target
, &(target_buf
[ x
* 4 ]) );
3589 Jim_fprintf( interp
, interp
->cookie_stdout
, "%08x ", (int)(z
) );
3591 for( ; (x
< 16) ; x
+= 4 ){
3592 Jim_fprintf( interp
, interp
->cookie_stdout
, " " );
3596 for( x
= 0 ; (x
< 16) && (x
< y
) ; x
+= 2 ){
3597 z
= target_buffer_get_u16( target
, &(target_buf
[ x
* 2 ]) );
3598 Jim_fprintf( interp
, interp
->cookie_stdout
, "%04x ", (int)(z
) );
3600 for( ; (x
< 16) ; x
+= 2 ){
3601 Jim_fprintf( interp
, interp
->cookie_stdout
, " " );
3606 for( x
= 0 ; (x
< 16) && (x
< y
) ; x
+= 1 ){
3607 z
= target_buffer_get_u8( target
, &(target_buf
[ x
* 4 ]) );
3608 Jim_fprintf( interp
, interp
->cookie_stdout
, "%02x ", (int)(z
) );
3610 for( ; (x
< 16) ; x
+= 1 ){
3611 Jim_fprintf( interp
, interp
->cookie_stdout
, " " );
3615 /* ascii-ify the bytes */
3616 for( x
= 0 ; x
< y
; x
++ ){
3617 if( (target_buf
[x
] >= 0x20) &&
3618 (target_buf
[x
] <= 0x7e) ){
3622 target_buf
[x
] = '.';
3627 target_buf
[x
] = ' ';
3632 /* print - with a newline */
3633 Jim_fprintf( interp
, interp
->cookie_stdout
, "%s\n", target_buf
);
3639 case TS_CMD_MEM2ARRAY
:
3640 return target_mem2array( goi
.interp
, target
, goi
.argc
, goi
.argv
);
3642 case TS_CMD_ARRAY2MEM
:
3643 return target_array2mem( goi
.interp
, target
, goi
.argc
, goi
.argv
);
3645 case TS_CMD_EXAMINE
:
3647 Jim_WrongNumArgs( goi
.interp
, 2, argv
, "[no parameters]");
3650 e
= target
->type
->examine( target
);
3651 if( e
!= ERROR_OK
){
3652 Jim_SetResult_sprintf( interp
, "examine-fails: %d", e
);
3658 Jim_WrongNumArgs( goi
.interp
, 2, argv
, "[no parameters]");
3661 if( !(target
->type
->examined
) ){
3662 e
= ERROR_TARGET_NOT_EXAMINED
;
3664 e
= target
->type
->poll( target
);
3666 if( e
!= ERROR_OK
){
3667 Jim_SetResult_sprintf( interp
, "poll-fails: %d", e
);
3674 if( goi
.argc
!= 2 ){
3675 Jim_WrongNumArgs( interp
, 2, argv
, "t|f|assert|deassert BOOL");
3678 e
= Jim_GetOpt_Nvp( &goi
, nvp_assert
, &n
);
3680 Jim_GetOpt_NvpUnknown( &goi
, nvp_assert
, 1 );
3683 /* the halt or not param */
3684 e
= Jim_GetOpt_Wide( &goi
, &a
);
3688 /* determine if we should halt or not. */
3689 target
->reset_halt
= !!a
;
3690 /* When this happens - all workareas are invalid. */
3691 target_free_all_working_areas_restore(target
, 0);
3694 if( n
->value
== NVP_ASSERT
){
3695 target
->type
->assert_reset( target
);
3697 target
->type
->deassert_reset( target
);
3702 Jim_WrongNumArgs( goi
.interp
, 0, argv
, "halt [no parameters]");
3705 target
->type
->halt( target
);
3707 case TS_CMD_WAITSTATE
:
3708 /* params: <name> statename timeoutmsecs */
3709 if( goi
.argc
!= 2 ){
3710 Jim_SetResult_sprintf( goi
.interp
, "%s STATENAME TIMEOUTMSECS", n
->name
);
3713 e
= Jim_GetOpt_Nvp( &goi
, nvp_target_state
, &n
);
3715 Jim_GetOpt_NvpUnknown( &goi
, nvp_target_state
,1 );
3718 e
= Jim_GetOpt_Wide( &goi
, &a
);
3722 e
= target_wait_state( target
, n
->value
, a
);
3723 if( e
!= ERROR_OK
){
3724 Jim_SetResult_sprintf( goi
.interp
,
3725 "target: %s wait %s fails (%d) %s",
3728 e
, target_strerror_safe(e
) );
3733 case TS_CMD_EVENTLIST
:
3734 /* List for human, Events defined for this target.
3735 * scripts/programs should use 'name cget -event NAME'
3738 target_event_action_t
*teap
;
3739 teap
= target
->event_action
;
3740 command_print( cmd_ctx
, "Event actions for target (%d) %s\n",
3741 target
->target_number
,
3743 command_print( cmd_ctx
, "%-25s | Body", "Event");
3744 command_print( cmd_ctx
, "------------------------- | ----------------------------------------");
3746 command_print( cmd_ctx
,
3748 Jim_Nvp_value2name_simple( nvp_target_event
, teap
->event
)->name
,
3749 Jim_GetString( teap
->body
, NULL
) );
3752 command_print( cmd_ctx
, "***END***");
3755 case TS_CMD_CURSTATE
:
3756 if( goi
.argc
!= 0 ){
3757 Jim_WrongNumArgs( goi
.interp
, 0, argv
, "[no parameters]");
3760 Jim_SetResultString( goi
.interp
,
3761 Jim_Nvp_value2name_simple(nvp_target_state
,target
->state
)->name
,-1);
3763 case TS_CMD_INVOKE_EVENT
:
3764 if( goi
.argc
!= 1 ){
3765 Jim_SetResult_sprintf( goi
.interp
, "%s ?EVENTNAME?",n
->name
);
3768 e
= Jim_GetOpt_Nvp( &goi
, nvp_target_event
, &n
);
3770 Jim_GetOpt_NvpUnknown( &goi
, nvp_target_event
, 1 );
3773 target_handle_event( target
, n
->value
);
3779 static int target_create( Jim_GetOptInfo
*goi
)
3788 struct command_context_s
*cmd_ctx
;
3790 cmd_ctx
= Jim_GetAssocData(goi
->interp
, "context");
3791 if( goi
->argc
< 3 ){
3792 Jim_WrongNumArgs( goi
->interp
, 1, goi
->argv
, "?name? ?type? ..options...");
3797 Jim_GetOpt_Obj( goi
, &new_cmd
);
3798 /* does this command exist? */
3799 cmd
= Jim_GetCommand( goi
->interp
, new_cmd
, JIM_ERRMSG
);
3801 cp
= Jim_GetString( new_cmd
, NULL
);
3802 Jim_SetResult_sprintf(goi
->interp
, "Command/target: %s Exists", cp
);
3807 e
= Jim_GetOpt_String( goi
, &cp2
, NULL
);
3809 /* now does target type exist */
3810 for( x
= 0 ; target_types
[x
] ; x
++ ){
3811 if( 0 == strcmp( cp
, target_types
[x
]->name
) ){
3816 if( target_types
[x
] == NULL
){
3817 Jim_SetResult_sprintf( goi
->interp
, "Unknown target type %s, try one of ", cp
);
3818 for( x
= 0 ; target_types
[x
] ; x
++ ){
3819 if( target_types
[x
+1] ){
3820 Jim_AppendStrings( goi
->interp
,
3821 Jim_GetResult(goi
->interp
),
3822 target_types
[x
]->name
,
3825 Jim_AppendStrings( goi
->interp
,
3826 Jim_GetResult(goi
->interp
),
3828 target_types
[x
]->name
,NULL
);
3835 target
= calloc(1,sizeof(target_t
));
3836 /* set target number */
3837 target
->target_number
= new_target_number();
3839 /* allocate memory for each unique target type */
3840 target
->type
= (target_type_t
*)calloc(1,sizeof(target_type_t
));
3842 memcpy( target
->type
, target_types
[x
], sizeof(target_type_t
));
3844 /* will be set by "-endian" */
3845 target
->endianness
= TARGET_ENDIAN_UNKNOWN
;
3847 target
->working_area
= 0x0;
3848 target
->working_area_size
= 0x0;
3849 target
->working_areas
= NULL
;
3850 target
->backup_working_area
= 0;
3852 target
->state
= TARGET_UNKNOWN
;
3853 target
->debug_reason
= DBG_REASON_UNDEFINED
;
3854 target
->reg_cache
= NULL
;
3855 target
->breakpoints
= NULL
;
3856 target
->watchpoints
= NULL
;
3857 target
->next
= NULL
;
3858 target
->arch_info
= NULL
;
3860 target
->display
= 1;
3862 /* initialize trace information */
3863 target
->trace_info
= malloc(sizeof(trace_t
));
3864 target
->trace_info
->num_trace_points
= 0;
3865 target
->trace_info
->trace_points_size
= 0;
3866 target
->trace_info
->trace_points
= NULL
;
3867 target
->trace_info
->trace_history_size
= 0;
3868 target
->trace_info
->trace_history
= NULL
;
3869 target
->trace_info
->trace_history_pos
= 0;
3870 target
->trace_info
->trace_history_overflowed
= 0;
3872 target
->dbgmsg
= NULL
;
3873 target
->dbg_msg_enabled
= 0;
3875 target
->endianness
= TARGET_ENDIAN_UNKNOWN
;
3877 /* Do the rest as "configure" options */
3878 goi
->isconfigure
= 1;
3879 e
= target_configure( goi
, target
);
3881 if (target
->tap
== NULL
)
3883 Jim_SetResultString( interp
, "-chain-position required when creating target", -1);
3888 free( target
->type
);
3893 if( target
->endianness
== TARGET_ENDIAN_UNKNOWN
){
3894 /* default endian to little if not specified */
3895 target
->endianness
= TARGET_LITTLE_ENDIAN
;
3898 /* incase variant is not set */
3899 if (!target
->variant
)
3900 target
->variant
= strdup("");
3902 /* create the target specific commands */
3903 if( target
->type
->register_commands
){
3904 (*(target
->type
->register_commands
))( cmd_ctx
);
3906 if( target
->type
->target_create
){
3907 (*(target
->type
->target_create
))( target
, goi
->interp
);
3910 /* append to end of list */
3913 tpp
= &(all_targets
);
3915 tpp
= &( (*tpp
)->next
);
3920 cp
= Jim_GetString( new_cmd
, NULL
);
3921 target
->cmd_name
= strdup(cp
);
3923 /* now - create the new target name command */
3924 e
= Jim_CreateCommand( goi
->interp
,
3927 tcl_target_func
, /* C function */
3928 target
, /* private data */
3929 NULL
); /* no del proc */
3934 static int jim_target( Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
3938 struct command_context_s
*cmd_ctx
;
3942 /* TG = target generic */
3950 const char *target_cmds
[] = {
3951 "create", "types", "names", "current", "number",
3953 NULL
/* terminate */
3956 LOG_DEBUG("Target command params:");
3957 LOG_DEBUG("%s", Jim_Debug_ArgvString(interp
, argc
, argv
));
3959 cmd_ctx
= Jim_GetAssocData( interp
, "context" );
3961 Jim_GetOpt_Setup( &goi
, interp
, argc
-1, argv
+1 );
3963 if( goi
.argc
== 0 ){
3964 Jim_WrongNumArgs(interp
, 1, argv
, "missing: command ...");
3968 /* Jim_GetOpt_Debug( &goi ); */
3969 r
= Jim_GetOpt_Enum( &goi
, target_cmds
, &x
);
3976 Jim_Panic(goi
.interp
,"Why am I here?");
3978 case TG_CMD_CURRENT
:
3979 if( goi
.argc
!= 0 ){
3980 Jim_WrongNumArgs( goi
.interp
, 1, goi
.argv
, "Too many parameters");
3983 Jim_SetResultString( goi
.interp
, get_current_target( cmd_ctx
)->cmd_name
, -1 );
3986 if( goi
.argc
!= 0 ){
3987 Jim_WrongNumArgs( goi
.interp
, 1, goi
.argv
, "Too many parameters" );
3990 Jim_SetResult( goi
.interp
, Jim_NewListObj( goi
.interp
, NULL
, 0 ) );
3991 for( x
= 0 ; target_types
[x
] ; x
++ ){
3992 Jim_ListAppendElement( goi
.interp
,
3993 Jim_GetResult(goi
.interp
),
3994 Jim_NewStringObj( goi
.interp
, target_types
[x
]->name
, -1 ) );
3998 if( goi
.argc
!= 0 ){
3999 Jim_WrongNumArgs( goi
.interp
, 1, goi
.argv
, "Too many parameters" );
4002 Jim_SetResult( goi
.interp
, Jim_NewListObj( goi
.interp
, NULL
, 0 ) );
4003 target
= all_targets
;
4005 Jim_ListAppendElement( goi
.interp
,
4006 Jim_GetResult(goi
.interp
),
4007 Jim_NewStringObj( goi
.interp
, target
->cmd_name
, -1 ) );
4008 target
= target
->next
;
4013 Jim_WrongNumArgs( goi
.interp
, goi
.argc
, goi
.argv
, "?name ... config options ...");
4016 return target_create( &goi
);
4019 if( goi
.argc
!= 1 ){
4020 Jim_SetResult_sprintf( goi
.interp
, "expected: target number ?NUMBER?");
4023 e
= Jim_GetOpt_Wide( &goi
, &w
);
4029 t
= get_target_by_num(w
);
4031 Jim_SetResult_sprintf( goi
.interp
,"Target: number %d does not exist", (int)(w
));
4034 Jim_SetResultString( goi
.interp
, t
->cmd_name
, -1 );
4038 if( goi
.argc
!= 0 ){
4039 Jim_WrongNumArgs( goi
.interp
, 0, goi
.argv
, "<no parameters>");
4042 Jim_SetResult( goi
.interp
,
4043 Jim_NewIntObj( goi
.interp
, max_target_number()));
4059 static int fastload_num
;
4060 static struct FastLoad
*fastload
;
4062 static void free_fastload(void)
4067 for (i
=0; i
<fastload_num
; i
++)
4069 if (fastload
[i
].data
)
4070 free(fastload
[i
].data
);
4080 static int handle_fast_load_image_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
4086 u32 max_address
=0xffffffff;
4092 duration_t duration
;
4093 char *duration_text
;
4095 if ((argc
< 1)||(argc
> 5))
4097 return ERROR_COMMAND_SYNTAX_ERROR
;
4100 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
4103 image
.base_address_set
= 1;
4104 image
.base_address
= strtoul(args
[1], NULL
, 0);
4108 image
.base_address_set
= 0;
4112 image
.start_address_set
= 0;
4116 min_address
=strtoul(args
[3], NULL
, 0);
4120 max_address
=strtoul(args
[4], NULL
, 0)+min_address
;
4123 if (min_address
>max_address
)
4125 return ERROR_COMMAND_SYNTAX_ERROR
;
4128 duration_start_measure(&duration
);
4130 if (image_open(&image
, args
[0], (argc
>= 3) ? args
[2] : NULL
) != ERROR_OK
)
4137 fastload_num
=image
.num_sections
;
4138 fastload
=(struct FastLoad
*)malloc(sizeof(struct FastLoad
)*image
.num_sections
);
4141 image_close(&image
);
4144 memset(fastload
, 0, sizeof(struct FastLoad
)*image
.num_sections
);
4145 for (i
= 0; i
< image
.num_sections
; i
++)
4147 buffer
= malloc(image
.sections
[i
].size
);
4150 command_print(cmd_ctx
, "error allocating buffer for section (%d bytes)", image
.sections
[i
].size
);
4154 if ((retval
= image_read_section(&image
, i
, 0x0, image
.sections
[i
].size
, buffer
, &buf_cnt
)) != ERROR_OK
)
4164 /* DANGER!!! beware of unsigned comparision here!!! */
4166 if ((image
.sections
[i
].base_address
+buf_cnt
>=min_address
)&&
4167 (image
.sections
[i
].base_address
<max_address
))
4169 if (image
.sections
[i
].base_address
<min_address
)
4171 /* clip addresses below */
4172 offset
+=min_address
-image
.sections
[i
].base_address
;
4176 if (image
.sections
[i
].base_address
+buf_cnt
>max_address
)
4178 length
-=(image
.sections
[i
].base_address
+buf_cnt
)-max_address
;
4181 fastload
[i
].address
=image
.sections
[i
].base_address
+offset
;
4182 fastload
[i
].data
=malloc(length
);
4183 if (fastload
[i
].data
==NULL
)
4188 memcpy(fastload
[i
].data
, buffer
+offset
, length
);
4189 fastload
[i
].length
=length
;
4191 image_size
+= length
;
4192 command_print(cmd_ctx
, "%u byte written at address 0x%8.8x", length
, image
.sections
[i
].base_address
+offset
);
4198 duration_stop_measure(&duration
, &duration_text
);
4199 if (retval
==ERROR_OK
)
4201 command_print(cmd_ctx
, "Loaded %u bytes in %s", image_size
, duration_text
);
4202 command_print(cmd_ctx
, "NB!!! image has not been loaded to target, issue a subsequent 'fast_load' to do so.");
4204 free(duration_text
);
4206 image_close(&image
);
4208 if (retval
!=ERROR_OK
)
4216 static int handle_fast_load_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
4219 return ERROR_COMMAND_SYNTAX_ERROR
;
4222 LOG_ERROR("No image in memory");
4226 int ms
=timeval_ms();
4228 int retval
=ERROR_OK
;
4229 for (i
=0; i
<fastload_num
;i
++)
4231 target_t
*target
= get_current_target(cmd_ctx
);
4232 command_print(cmd_ctx
, "Write to 0x%08x, length 0x%08x", fastload
[i
].address
, fastload
[i
].length
);
4233 if (retval
==ERROR_OK
)
4235 retval
= target_write_buffer(target
, fastload
[i
].address
, fastload
[i
].length
, fastload
[i
].data
);
4237 size
+=fastload
[i
].length
;
4239 int after
=timeval_ms();
4240 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)