Improve handle_md_command argument handling:
[openocd.git] / src / target / target.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2007,2008 Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
7 * *
8 * Copyright (C) 2008, Duane Ellis *
9 * openocd@duaneeellis.com *
10 * *
11 * Copyright (C) 2008 by Spencer Oliver *
12 * spen@spen-soft.co.uk *
13 * *
14 * Copyright (C) 2008 by Rick Altherr *
15 * kc8apf@kc8apf.net> *
16 * *
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. *
21 * *
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. *
26 * *
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 ***************************************************************************/
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #include "target.h"
37 #include "target_type.h"
38 #include "target_request.h"
39 #include "time_support.h"
40 #include "register.h"
41 #include "trace.h"
42 #include "image.h"
43 #include "jtag.h"
44
45
46 static int handle_targets_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
47
48 static int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
49 static int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
50 static int handle_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
51 static int handle_wait_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
52 static int handle_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
53 static int handle_soft_reset_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
54 static int handle_resume_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
55 static int handle_step_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
56 static int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
57 static int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
58 static int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
59 static int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
60 static int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
61 static int handle_test_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
62 static int handle_bp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
63 static int handle_rbp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
64 static int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
65 static int handle_rwp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
66 static int handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc);
67 static int handle_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
68 static int handle_fast_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
69 static int handle_fast_load_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
70
71 static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
72 static int jim_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
73 static int jim_target( Jim_Interp *interp, int argc, Jim_Obj *const *argv);
74
75 static int target_array2mem(Jim_Interp *interp, target_t *target, int argc, Jim_Obj *const *argv);
76 static int target_mem2array(Jim_Interp *interp, target_t *target, int argc, Jim_Obj *const *argv);
77
78 /* targets */
79 extern target_type_t arm7tdmi_target;
80 extern target_type_t arm720t_target;
81 extern target_type_t arm9tdmi_target;
82 extern target_type_t arm920t_target;
83 extern target_type_t arm966e_target;
84 extern target_type_t arm926ejs_target;
85 extern target_type_t feroceon_target;
86 extern target_type_t xscale_target;
87 extern target_type_t cortexm3_target;
88 extern target_type_t cortexa8_target;
89 extern target_type_t arm11_target;
90 extern target_type_t mips_m4k_target;
91 extern target_type_t avr_target;
92
93 target_type_t *target_types[] =
94 {
95 &arm7tdmi_target,
96 &arm9tdmi_target,
97 &arm920t_target,
98 &arm720t_target,
99 &arm966e_target,
100 &arm926ejs_target,
101 &feroceon_target,
102 &xscale_target,
103 &cortexm3_target,
104 &cortexa8_target,
105 &arm11_target,
106 &mips_m4k_target,
107 &avr_target,
108 NULL,
109 };
110
111 target_t *all_targets = NULL;
112 target_event_callback_t *target_event_callbacks = NULL;
113 target_timer_callback_t *target_timer_callbacks = NULL;
114
115 const Jim_Nvp nvp_assert[] = {
116 { .name = "assert", NVP_ASSERT },
117 { .name = "deassert", NVP_DEASSERT },
118 { .name = "T", NVP_ASSERT },
119 { .name = "F", NVP_DEASSERT },
120 { .name = "t", NVP_ASSERT },
121 { .name = "f", NVP_DEASSERT },
122 { .name = NULL, .value = -1 }
123 };
124
125 const Jim_Nvp nvp_error_target[] = {
126 { .value = ERROR_TARGET_INVALID, .name = "err-invalid" },
127 { .value = ERROR_TARGET_INIT_FAILED, .name = "err-init-failed" },
128 { .value = ERROR_TARGET_TIMEOUT, .name = "err-timeout" },
129 { .value = ERROR_TARGET_NOT_HALTED, .name = "err-not-halted" },
130 { .value = ERROR_TARGET_FAILURE, .name = "err-failure" },
131 { .value = ERROR_TARGET_UNALIGNED_ACCESS , .name = "err-unaligned-access" },
132 { .value = ERROR_TARGET_DATA_ABORT , .name = "err-data-abort" },
133 { .value = ERROR_TARGET_RESOURCE_NOT_AVAILABLE , .name = "err-resource-not-available" },
134 { .value = ERROR_TARGET_TRANSLATION_FAULT , .name = "err-translation-fault" },
135 { .value = ERROR_TARGET_NOT_RUNNING, .name = "err-not-running" },
136 { .value = ERROR_TARGET_NOT_EXAMINED, .name = "err-not-examined" },
137 { .value = -1, .name = NULL }
138 };
139
140 const char *target_strerror_safe( int err )
141 {
142 const Jim_Nvp *n;
143
144 n = Jim_Nvp_value2name_simple( nvp_error_target, err );
145 if( n->name == NULL ){
146 return "unknown";
147 } else {
148 return n->name;
149 }
150 }
151
152 static const Jim_Nvp nvp_target_event[] = {
153 { .value = TARGET_EVENT_OLD_gdb_program_config , .name = "old-gdb_program_config" },
154 { .value = TARGET_EVENT_OLD_pre_resume , .name = "old-pre_resume" },
155
156 { .value = TARGET_EVENT_EARLY_HALTED, .name = "early-halted" },
157 { .value = TARGET_EVENT_HALTED, .name = "halted" },
158 { .value = TARGET_EVENT_RESUMED, .name = "resumed" },
159 { .value = TARGET_EVENT_RESUME_START, .name = "resume-start" },
160 { .value = TARGET_EVENT_RESUME_END, .name = "resume-end" },
161
162 { .name = "gdb-start", .value = TARGET_EVENT_GDB_START },
163 { .name = "gdb-end", .value = TARGET_EVENT_GDB_END },
164
165 /* historical name */
166
167 { .value = TARGET_EVENT_RESET_START, .name = "reset-start" },
168
169 { .value = TARGET_EVENT_RESET_ASSERT_PRE, .name = "reset-assert-pre" },
170 { .value = TARGET_EVENT_RESET_ASSERT_POST, .name = "reset-assert-post" },
171 { .value = TARGET_EVENT_RESET_DEASSERT_PRE, .name = "reset-deassert-pre" },
172 { .value = TARGET_EVENT_RESET_DEASSERT_POST, .name = "reset-deassert-post" },
173 { .value = TARGET_EVENT_RESET_HALT_PRE, .name = "reset-halt-pre" },
174 { .value = TARGET_EVENT_RESET_HALT_POST, .name = "reset-halt-post" },
175 { .value = TARGET_EVENT_RESET_WAIT_PRE, .name = "reset-wait-pre" },
176 { .value = TARGET_EVENT_RESET_WAIT_POST, .name = "reset-wait-post" },
177 { .value = TARGET_EVENT_RESET_INIT , .name = "reset-init" },
178 { .value = TARGET_EVENT_RESET_END, .name = "reset-end" },
179
180 { .value = TARGET_EVENT_EXAMINE_START, .name = "examine-start" },
181 { .value = TARGET_EVENT_EXAMINE_END, .name = "examine-end" },
182
183 { .value = TARGET_EVENT_DEBUG_HALTED, .name = "debug-halted" },
184 { .value = TARGET_EVENT_DEBUG_RESUMED, .name = "debug-resumed" },
185
186 { .value = TARGET_EVENT_GDB_ATTACH, .name = "gdb-attach" },
187 { .value = TARGET_EVENT_GDB_DETACH, .name = "gdb-detach" },
188
189 { .value = TARGET_EVENT_GDB_FLASH_WRITE_START, .name = "gdb-flash-write-start" },
190 { .value = TARGET_EVENT_GDB_FLASH_WRITE_END , .name = "gdb-flash-write-end" },
191
192 { .value = TARGET_EVENT_GDB_FLASH_ERASE_START, .name = "gdb-flash-erase-start" },
193 { .value = TARGET_EVENT_GDB_FLASH_ERASE_END , .name = "gdb-flash-erase-end" },
194
195 { .value = TARGET_EVENT_RESUME_START, .name = "resume-start" },
196 { .value = TARGET_EVENT_RESUMED , .name = "resume-ok" },
197 { .value = TARGET_EVENT_RESUME_END , .name = "resume-end" },
198
199 { .name = NULL, .value = -1 }
200 };
201
202 const Jim_Nvp nvp_target_state[] = {
203 { .name = "unknown", .value = TARGET_UNKNOWN },
204 { .name = "running", .value = TARGET_RUNNING },
205 { .name = "halted", .value = TARGET_HALTED },
206 { .name = "reset", .value = TARGET_RESET },
207 { .name = "debug-running", .value = TARGET_DEBUG_RUNNING },
208 { .name = NULL, .value = -1 },
209 };
210
211 const Jim_Nvp nvp_target_debug_reason [] = {
212 { .name = "debug-request" , .value = DBG_REASON_DBGRQ },
213 { .name = "breakpoint" , .value = DBG_REASON_BREAKPOINT },
214 { .name = "watchpoint" , .value = DBG_REASON_WATCHPOINT },
215 { .name = "watchpoint-and-breakpoint", .value = DBG_REASON_WPTANDBKPT },
216 { .name = "single-step" , .value = DBG_REASON_SINGLESTEP },
217 { .name = "target-not-halted" , .value = DBG_REASON_NOTHALTED },
218 { .name = "undefined" , .value = DBG_REASON_UNDEFINED },
219 { .name = NULL, .value = -1 },
220 };
221
222 const Jim_Nvp nvp_target_endian[] = {
223 { .name = "big", .value = TARGET_BIG_ENDIAN },
224 { .name = "little", .value = TARGET_LITTLE_ENDIAN },
225 { .name = "be", .value = TARGET_BIG_ENDIAN },
226 { .name = "le", .value = TARGET_LITTLE_ENDIAN },
227 { .name = NULL, .value = -1 },
228 };
229
230 const Jim_Nvp nvp_reset_modes[] = {
231 { .name = "unknown", .value = RESET_UNKNOWN },
232 { .name = "run" , .value = RESET_RUN },
233 { .name = "halt" , .value = RESET_HALT },
234 { .name = "init" , .value = RESET_INIT },
235 { .name = NULL , .value = -1 },
236 };
237
238 static int max_target_number(void)
239 {
240 target_t *t;
241 int x;
242
243 x = -1;
244 t = all_targets;
245 while( t ){
246 if( x < t->target_number ){
247 x = (t->target_number)+1;
248 }
249 t = t->next;
250 }
251 return x;
252 }
253
254 /* determine the number of the new target */
255 static int new_target_number(void)
256 {
257 target_t *t;
258 int x;
259
260 /* number is 0 based */
261 x = -1;
262 t = all_targets;
263 while(t){
264 if( x < t->target_number ){
265 x = t->target_number;
266 }
267 t = t->next;
268 }
269 return x+1;
270 }
271
272 static int target_continous_poll = 1;
273
274 /* read a u32 from a buffer in target memory endianness */
275 u32 target_buffer_get_u32(target_t *target, const u8 *buffer)
276 {
277 if (target->endianness == TARGET_LITTLE_ENDIAN)
278 return le_to_h_u32(buffer);
279 else
280 return be_to_h_u32(buffer);
281 }
282
283 /* read a u16 from a buffer in target memory endianness */
284 u16 target_buffer_get_u16(target_t *target, const u8 *buffer)
285 {
286 if (target->endianness == TARGET_LITTLE_ENDIAN)
287 return le_to_h_u16(buffer);
288 else
289 return be_to_h_u16(buffer);
290 }
291
292 /* read a u8 from a buffer in target memory endianness */
293 u8 target_buffer_get_u8(target_t *target, const u8 *buffer)
294 {
295 return *buffer & 0x0ff;
296 }
297
298 /* write a u32 to a buffer in target memory endianness */
299 void target_buffer_set_u32(target_t *target, u8 *buffer, u32 value)
300 {
301 if (target->endianness == TARGET_LITTLE_ENDIAN)
302 h_u32_to_le(buffer, value);
303 else
304 h_u32_to_be(buffer, value);
305 }
306
307 /* write a u16 to a buffer in target memory endianness */
308 void target_buffer_set_u16(target_t *target, u8 *buffer, u16 value)
309 {
310 if (target->endianness == TARGET_LITTLE_ENDIAN)
311 h_u16_to_le(buffer, value);
312 else
313 h_u16_to_be(buffer, value);
314 }
315
316 /* write a u8 to a buffer in target memory endianness */
317 void target_buffer_set_u8(target_t *target, u8 *buffer, u8 value)
318 {
319 *buffer = value;
320 }
321
322 /* return a pointer to a configured target; id is name or number */
323 target_t *get_target(const char *id)
324 {
325 target_t *target;
326
327 /* try as tcltarget name */
328 for (target = all_targets; target; target = target->next) {
329 if (target->cmd_name == NULL)
330 continue;
331 if (strcmp(id, target->cmd_name) == 0)
332 return target;
333 }
334
335 /* no match, try as number */
336 unsigned num;
337 if (parse_uint(id, &num) != ERROR_OK)
338 return NULL;
339
340 for (target = all_targets; target; target = target->next) {
341 if (target->target_number == (int)num)
342 return target;
343 }
344
345 return NULL;
346 }
347
348 /* returns a pointer to the n-th configured target */
349 static target_t *get_target_by_num(int num)
350 {
351 target_t *target = all_targets;
352
353 while (target){
354 if( target->target_number == num ){
355 return target;
356 }
357 target = target->next;
358 }
359
360 return NULL;
361 }
362
363 int get_num_by_target(target_t *query_target)
364 {
365 return query_target->target_number;
366 }
367
368 target_t* get_current_target(command_context_t *cmd_ctx)
369 {
370 target_t *target = get_target_by_num(cmd_ctx->current_target);
371
372 if (target == NULL)
373 {
374 LOG_ERROR("BUG: current_target out of bounds");
375 exit(-1);
376 }
377
378 return target;
379 }
380
381 int target_poll(struct target_s *target)
382 {
383 /* We can't poll until after examine */
384 if (!target_was_examined(target))
385 {
386 /* Fail silently lest we pollute the log */
387 return ERROR_FAIL;
388 }
389 return target->type->poll(target);
390 }
391
392 int target_halt(struct target_s *target)
393 {
394 /* We can't poll until after examine */
395 if (!target_was_examined(target))
396 {
397 LOG_ERROR("Target not examined yet");
398 return ERROR_FAIL;
399 }
400 return target->type->halt(target);
401 }
402
403 int target_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution)
404 {
405 int retval;
406
407 /* We can't poll until after examine */
408 if (!target_was_examined(target))
409 {
410 LOG_ERROR("Target not examined yet");
411 return ERROR_FAIL;
412 }
413
414 /* note that resume *must* be asynchronous. The CPU can halt before we poll. The CPU can
415 * even halt at the current PC as a result of a software breakpoint being inserted by (a bug?)
416 * the application.
417 */
418 if ((retval = target->type->resume(target, current, address, handle_breakpoints, debug_execution)) != ERROR_OK)
419 return retval;
420
421 return retval;
422 }
423
424 int target_process_reset(struct command_context_s *cmd_ctx, enum target_reset_mode reset_mode)
425 {
426 char buf[100];
427 int retval;
428 Jim_Nvp *n;
429 n = Jim_Nvp_value2name_simple( nvp_reset_modes, reset_mode );
430 if( n->name == NULL ){
431 LOG_ERROR("invalid reset mode");
432 return ERROR_FAIL;
433 }
434
435 /* disable polling during reset to make reset event scripts
436 * more predictable, i.e. dr/irscan & pathmove in events will
437 * not have JTAG operations injected into the middle of a sequence.
438 */
439 int save_poll = target_continous_poll;
440 target_continous_poll = 0;
441
442 sprintf( buf, "ocd_process_reset %s", n->name );
443 retval = Jim_Eval( interp, buf );
444
445 target_continous_poll = save_poll;
446
447 if(retval != JIM_OK) {
448 Jim_PrintErrorMessage(interp);
449 return ERROR_FAIL;
450 }
451
452 /* We want any events to be processed before the prompt */
453 retval = target_call_timer_callbacks_now();
454
455 return retval;
456 }
457
458 static int default_virt2phys(struct target_s *target, u32 virtual, u32 *physical)
459 {
460 *physical = virtual;
461 return ERROR_OK;
462 }
463
464 static int default_mmu(struct target_s *target, int *enabled)
465 {
466 *enabled = 0;
467 return ERROR_OK;
468 }
469
470 static int default_examine(struct target_s *target)
471 {
472 target_set_examined(target);
473 return ERROR_OK;
474 }
475
476 int target_examine_one(struct target_s *target)
477 {
478 return target->type->examine(target);
479 }
480
481 /* Targets that correctly implement init+examine, i.e.
482 * no communication with target during init:
483 *
484 * XScale
485 */
486 int target_examine(void)
487 {
488 int retval = ERROR_OK;
489 target_t *target;
490
491 for (target = all_targets; target; target = target->next)
492 {
493 if (!target->tap->enabled)
494 continue;
495 if ((retval = target_examine_one(target)) != ERROR_OK)
496 return retval;
497 }
498 return retval;
499 }
500 const char *target_get_name(struct target_s *target)
501 {
502 return target->type->name;
503 }
504
505 static int target_write_memory_imp(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
506 {
507 if (!target_was_examined(target))
508 {
509 LOG_ERROR("Target not examined yet");
510 return ERROR_FAIL;
511 }
512 return target->type->write_memory_imp(target, address, size, count, buffer);
513 }
514
515 static int target_read_memory_imp(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
516 {
517 if (!target_was_examined(target))
518 {
519 LOG_ERROR("Target not examined yet");
520 return ERROR_FAIL;
521 }
522 return target->type->read_memory_imp(target, address, size, count, buffer);
523 }
524
525 static int target_soft_reset_halt_imp(struct target_s *target)
526 {
527 if (!target_was_examined(target))
528 {
529 LOG_ERROR("Target not examined yet");
530 return ERROR_FAIL;
531 }
532 return target->type->soft_reset_halt_imp(target);
533 }
534
535 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)
536 {
537 if (!target_was_examined(target))
538 {
539 LOG_ERROR("Target not examined yet");
540 return ERROR_FAIL;
541 }
542 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);
543 }
544
545 int target_read_memory(struct target_s *target,
546 u32 address, u32 size, u32 count, u8 *buffer)
547 {
548 return target->type->read_memory(target, address, size, count, buffer);
549 }
550
551 int target_write_memory(struct target_s *target,
552 u32 address, u32 size, u32 count, u8 *buffer)
553 {
554 return target->type->write_memory(target, address, size, count, buffer);
555 }
556 int target_bulk_write_memory(struct target_s *target,
557 u32 address, u32 count, u8 *buffer)
558 {
559 return target->type->bulk_write_memory(target, address, count, buffer);
560 }
561
562 int target_add_breakpoint(struct target_s *target,
563 struct breakpoint_s *breakpoint)
564 {
565 return target->type->add_breakpoint(target, breakpoint);
566 }
567 int target_remove_breakpoint(struct target_s *target,
568 struct breakpoint_s *breakpoint)
569 {
570 return target->type->remove_breakpoint(target, breakpoint);
571 }
572
573 int target_add_watchpoint(struct target_s *target,
574 struct watchpoint_s *watchpoint)
575 {
576 return target->type->add_watchpoint(target, watchpoint);
577 }
578 int target_remove_watchpoint(struct target_s *target,
579 struct watchpoint_s *watchpoint)
580 {
581 return target->type->remove_watchpoint(target, watchpoint);
582 }
583
584 int target_get_gdb_reg_list(struct target_s *target,
585 struct reg_s **reg_list[], int *reg_list_size)
586 {
587 return target->type->get_gdb_reg_list(target, reg_list, reg_list_size);
588 }
589 int target_step(struct target_s *target,
590 int current, u32 address, int handle_breakpoints)
591 {
592 return target->type->step(target, current, address, handle_breakpoints);
593 }
594
595
596 int target_run_algorithm(struct target_s *target,
597 int num_mem_params, mem_param_t *mem_params,
598 int num_reg_params, reg_param_t *reg_param,
599 u32 entry_point, u32 exit_point,
600 int timeout_ms, void *arch_info)
601 {
602 return target->type->run_algorithm(target,
603 num_mem_params, mem_params, num_reg_params, reg_param,
604 entry_point, exit_point, timeout_ms, arch_info);
605 }
606
607 /// @returns @c true if the target has been examined.
608 bool target_was_examined(struct target_s *target)
609 {
610 return target->type->examined;
611 }
612 /// Sets the @c examined flag for the given target.
613 void target_set_examined(struct target_s *target)
614 {
615 target->type->examined = true;
616 }
617 // Reset the @c examined flag for the given target.
618 void target_reset_examined(struct target_s *target)
619 {
620 target->type->examined = false;
621 }
622
623
624 int target_init(struct command_context_s *cmd_ctx)
625 {
626 target_t *target = all_targets;
627 int retval;
628
629 while (target)
630 {
631 target_reset_examined(target);
632 if (target->type->examine == NULL)
633 {
634 target->type->examine = default_examine;
635 }
636
637 if ((retval = target->type->init_target(cmd_ctx, target)) != ERROR_OK)
638 {
639 LOG_ERROR("target '%s' init failed", target_get_name(target));
640 return retval;
641 }
642
643 /* Set up default functions if none are provided by target */
644 if (target->type->virt2phys == NULL)
645 {
646 target->type->virt2phys = default_virt2phys;
647 }
648 target->type->virt2phys = default_virt2phys;
649 /* a non-invasive way(in terms of patches) to add some code that
650 * runs before the type->write/read_memory implementation
651 */
652 target->type->write_memory_imp = target->type->write_memory;
653 target->type->write_memory = target_write_memory_imp;
654 target->type->read_memory_imp = target->type->read_memory;
655 target->type->read_memory = target_read_memory_imp;
656 target->type->soft_reset_halt_imp = target->type->soft_reset_halt;
657 target->type->soft_reset_halt = target_soft_reset_halt_imp;
658 target->type->run_algorithm_imp = target->type->run_algorithm;
659 target->type->run_algorithm = target_run_algorithm_imp;
660
661 if (target->type->mmu == NULL)
662 {
663 target->type->mmu = default_mmu;
664 }
665 target = target->next;
666 }
667
668 if (all_targets)
669 {
670 if((retval = target_register_user_commands(cmd_ctx)) != ERROR_OK)
671 return retval;
672 if((retval = target_register_timer_callback(handle_target, 100, 1, NULL)) != ERROR_OK)
673 return retval;
674 }
675
676 return ERROR_OK;
677 }
678
679 int target_register_event_callback(int (*callback)(struct target_s *target, enum target_event event, void *priv), void *priv)
680 {
681 target_event_callback_t **callbacks_p = &target_event_callbacks;
682
683 if (callback == NULL)
684 {
685 return ERROR_INVALID_ARGUMENTS;
686 }
687
688 if (*callbacks_p)
689 {
690 while ((*callbacks_p)->next)
691 callbacks_p = &((*callbacks_p)->next);
692 callbacks_p = &((*callbacks_p)->next);
693 }
694
695 (*callbacks_p) = malloc(sizeof(target_event_callback_t));
696 (*callbacks_p)->callback = callback;
697 (*callbacks_p)->priv = priv;
698 (*callbacks_p)->next = NULL;
699
700 return ERROR_OK;
701 }
702
703 int target_register_timer_callback(int (*callback)(void *priv), int time_ms, int periodic, void *priv)
704 {
705 target_timer_callback_t **callbacks_p = &target_timer_callbacks;
706 struct timeval now;
707
708 if (callback == NULL)
709 {
710 return ERROR_INVALID_ARGUMENTS;
711 }
712
713 if (*callbacks_p)
714 {
715 while ((*callbacks_p)->next)
716 callbacks_p = &((*callbacks_p)->next);
717 callbacks_p = &((*callbacks_p)->next);
718 }
719
720 (*callbacks_p) = malloc(sizeof(target_timer_callback_t));
721 (*callbacks_p)->callback = callback;
722 (*callbacks_p)->periodic = periodic;
723 (*callbacks_p)->time_ms = time_ms;
724
725 gettimeofday(&now, NULL);
726 (*callbacks_p)->when.tv_usec = now.tv_usec + (time_ms % 1000) * 1000;
727 time_ms -= (time_ms % 1000);
728 (*callbacks_p)->when.tv_sec = now.tv_sec + (time_ms / 1000);
729 if ((*callbacks_p)->when.tv_usec > 1000000)
730 {
731 (*callbacks_p)->when.tv_usec = (*callbacks_p)->when.tv_usec - 1000000;
732 (*callbacks_p)->when.tv_sec += 1;
733 }
734
735 (*callbacks_p)->priv = priv;
736 (*callbacks_p)->next = NULL;
737
738 return ERROR_OK;
739 }
740
741 int target_unregister_event_callback(int (*callback)(struct target_s *target, enum target_event event, void *priv), void *priv)
742 {
743 target_event_callback_t **p = &target_event_callbacks;
744 target_event_callback_t *c = target_event_callbacks;
745
746 if (callback == NULL)
747 {
748 return ERROR_INVALID_ARGUMENTS;
749 }
750
751 while (c)
752 {
753 target_event_callback_t *next = c->next;
754 if ((c->callback == callback) && (c->priv == priv))
755 {
756 *p = next;
757 free(c);
758 return ERROR_OK;
759 }
760 else
761 p = &(c->next);
762 c = next;
763 }
764
765 return ERROR_OK;
766 }
767
768 int target_unregister_timer_callback(int (*callback)(void *priv), void *priv)
769 {
770 target_timer_callback_t **p = &target_timer_callbacks;
771 target_timer_callback_t *c = target_timer_callbacks;
772
773 if (callback == NULL)
774 {
775 return ERROR_INVALID_ARGUMENTS;
776 }
777
778 while (c)
779 {
780 target_timer_callback_t *next = c->next;
781 if ((c->callback == callback) && (c->priv == priv))
782 {
783 *p = next;
784 free(c);
785 return ERROR_OK;
786 }
787 else
788 p = &(c->next);
789 c = next;
790 }
791
792 return ERROR_OK;
793 }
794
795 int target_call_event_callbacks(target_t *target, enum target_event event)
796 {
797 target_event_callback_t *callback = target_event_callbacks;
798 target_event_callback_t *next_callback;
799
800 if (event == TARGET_EVENT_HALTED)
801 {
802 /* execute early halted first */
803 target_call_event_callbacks(target, TARGET_EVENT_EARLY_HALTED);
804 }
805
806 LOG_DEBUG("target event %i (%s)",
807 event,
808 Jim_Nvp_value2name_simple( nvp_target_event, event )->name );
809
810 target_handle_event( target, event );
811
812 while (callback)
813 {
814 next_callback = callback->next;
815 callback->callback(target, event, callback->priv);
816 callback = next_callback;
817 }
818
819 return ERROR_OK;
820 }
821
822 static int target_timer_callback_periodic_restart(
823 target_timer_callback_t *cb, struct timeval *now)
824 {
825 int time_ms = cb->time_ms;
826 cb->when.tv_usec = now->tv_usec + (time_ms % 1000) * 1000;
827 time_ms -= (time_ms % 1000);
828 cb->when.tv_sec = now->tv_sec + time_ms / 1000;
829 if (cb->when.tv_usec > 1000000)
830 {
831 cb->when.tv_usec = cb->when.tv_usec - 1000000;
832 cb->when.tv_sec += 1;
833 }
834 return ERROR_OK;
835 }
836
837 static int target_call_timer_callback(target_timer_callback_t *cb,
838 struct timeval *now)
839 {
840 cb->callback(cb->priv);
841
842 if (cb->periodic)
843 return target_timer_callback_periodic_restart(cb, now);
844
845 return target_unregister_timer_callback(cb->callback, cb->priv);
846 }
847
848 static int target_call_timer_callbacks_check_time(int checktime)
849 {
850 keep_alive();
851
852 struct timeval now;
853 gettimeofday(&now, NULL);
854
855 target_timer_callback_t *callback = target_timer_callbacks;
856 while (callback)
857 {
858 // cleaning up may unregister and free this callback
859 target_timer_callback_t *next_callback = callback->next;
860
861 bool call_it = callback->callback &&
862 ((!checktime && callback->periodic) ||
863 now.tv_sec > callback->when.tv_sec ||
864 (now.tv_sec == callback->when.tv_sec &&
865 now.tv_usec >= callback->when.tv_usec));
866
867 if (call_it)
868 {
869 int retval = target_call_timer_callback(callback, &now);
870 if (retval != ERROR_OK)
871 return retval;
872 }
873
874 callback = next_callback;
875 }
876
877 return ERROR_OK;
878 }
879
880 int target_call_timer_callbacks(void)
881 {
882 return target_call_timer_callbacks_check_time(1);
883 }
884
885 /* invoke periodic callbacks immediately */
886 int target_call_timer_callbacks_now(void)
887 {
888 return target_call_timer_callbacks_check_time(0);
889 }
890
891 int target_alloc_working_area(struct target_s *target, u32 size, working_area_t **area)
892 {
893 working_area_t *c = target->working_areas;
894 working_area_t *new_wa = NULL;
895
896 /* Reevaluate working area address based on MMU state*/
897 if (target->working_areas == NULL)
898 {
899 int retval;
900 int enabled;
901 retval = target->type->mmu(target, &enabled);
902 if (retval != ERROR_OK)
903 {
904 return retval;
905 }
906 if (enabled)
907 {
908 target->working_area = target->working_area_virt;
909 }
910 else
911 {
912 target->working_area = target->working_area_phys;
913 }
914 }
915
916 /* only allocate multiples of 4 byte */
917 if (size % 4)
918 {
919 LOG_ERROR("BUG: code tried to allocate unaligned number of bytes, padding");
920 size = CEIL(size, 4);
921 }
922
923 /* see if there's already a matching working area */
924 while (c)
925 {
926 if ((c->free) && (c->size == size))
927 {
928 new_wa = c;
929 break;
930 }
931 c = c->next;
932 }
933
934 /* if not, allocate a new one */
935 if (!new_wa)
936 {
937 working_area_t **p = &target->working_areas;
938 u32 first_free = target->working_area;
939 u32 free_size = target->working_area_size;
940
941 LOG_DEBUG("allocating new working area");
942
943 c = target->working_areas;
944 while (c)
945 {
946 first_free += c->size;
947 free_size -= c->size;
948 p = &c->next;
949 c = c->next;
950 }
951
952 if (free_size < size)
953 {
954 LOG_WARNING("not enough working area available(requested %d, free %d)", size, free_size);
955 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
956 }
957
958 new_wa = malloc(sizeof(working_area_t));
959 new_wa->next = NULL;
960 new_wa->size = size;
961 new_wa->address = first_free;
962
963 if (target->backup_working_area)
964 {
965 int retval;
966 new_wa->backup = malloc(new_wa->size);
967 if((retval = target_read_memory(target, new_wa->address, 4, new_wa->size / 4, new_wa->backup)) != ERROR_OK)
968 {
969 free(new_wa->backup);
970 free(new_wa);
971 return retval;
972 }
973 }
974 else
975 {
976 new_wa->backup = NULL;
977 }
978
979 /* put new entry in list */
980 *p = new_wa;
981 }
982
983 /* mark as used, and return the new (reused) area */
984 new_wa->free = 0;
985 *area = new_wa;
986
987 /* user pointer */
988 new_wa->user = area;
989
990 return ERROR_OK;
991 }
992
993 int target_free_working_area_restore(struct target_s *target, working_area_t *area, int restore)
994 {
995 if (area->free)
996 return ERROR_OK;
997
998 if (restore&&target->backup_working_area)
999 {
1000 int retval;
1001 if((retval = target_write_memory(target, area->address, 4, area->size / 4, area->backup)) != ERROR_OK)
1002 return retval;
1003 }
1004
1005 area->free = 1;
1006
1007 /* mark user pointer invalid */
1008 *area->user = NULL;
1009 area->user = NULL;
1010
1011 return ERROR_OK;
1012 }
1013
1014 int target_free_working_area(struct target_s *target, working_area_t *area)
1015 {
1016 return target_free_working_area_restore(target, area, 1);
1017 }
1018
1019 /* free resources and restore memory, if restoring memory fails,
1020 * free up resources anyway
1021 */
1022 void target_free_all_working_areas_restore(struct target_s *target, int restore)
1023 {
1024 working_area_t *c = target->working_areas;
1025
1026 while (c)
1027 {
1028 working_area_t *next = c->next;
1029 target_free_working_area_restore(target, c, restore);
1030
1031 if (c->backup)
1032 free(c->backup);
1033
1034 free(c);
1035
1036 c = next;
1037 }
1038
1039 target->working_areas = NULL;
1040 }
1041
1042 void target_free_all_working_areas(struct target_s *target)
1043 {
1044 target_free_all_working_areas_restore(target, 1);
1045 }
1046
1047 int target_register_commands(struct command_context_s *cmd_ctx)
1048 {
1049
1050 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)");
1051
1052
1053
1054
1055 register_jim(cmd_ctx, "target", jim_target, "configure target" );
1056
1057 return ERROR_OK;
1058 }
1059
1060 int target_arch_state(struct target_s *target)
1061 {
1062 int retval;
1063 if (target==NULL)
1064 {
1065 LOG_USER("No target has been configured");
1066 return ERROR_OK;
1067 }
1068
1069 LOG_USER("target state: %s",
1070 Jim_Nvp_value2name_simple(nvp_target_state,target->state)->name);
1071
1072 if (target->state!=TARGET_HALTED)
1073 return ERROR_OK;
1074
1075 retval=target->type->arch_state(target);
1076 return retval;
1077 }
1078
1079 /* Single aligned words are guaranteed to use 16 or 32 bit access
1080 * mode respectively, otherwise data is handled as quickly as
1081 * possible
1082 */
1083 int target_write_buffer(struct target_s *target, u32 address, u32 size, u8 *buffer)
1084 {
1085 int retval;
1086 LOG_DEBUG("writing buffer of %i byte at 0x%8.8x", size, address);
1087
1088 if (!target_was_examined(target))
1089 {
1090 LOG_ERROR("Target not examined yet");
1091 return ERROR_FAIL;
1092 }
1093
1094 if (size == 0) {
1095 return ERROR_OK;
1096 }
1097
1098 if ((address + size - 1) < address)
1099 {
1100 /* GDB can request this when e.g. PC is 0xfffffffc*/
1101 LOG_ERROR("address+size wrapped(0x%08x, 0x%08x)", address, size);
1102 return ERROR_FAIL;
1103 }
1104
1105 if (((address % 2) == 0) && (size == 2))
1106 {
1107 return target_write_memory(target, address, 2, 1, buffer);
1108 }
1109
1110 /* handle unaligned head bytes */
1111 if (address % 4)
1112 {
1113 u32 unaligned = 4 - (address % 4);
1114
1115 if (unaligned > size)
1116 unaligned = size;
1117
1118 if ((retval = target_write_memory(target, address, 1, unaligned, buffer)) != ERROR_OK)
1119 return retval;
1120
1121 buffer += unaligned;
1122 address += unaligned;
1123 size -= unaligned;
1124 }
1125
1126 /* handle aligned words */
1127 if (size >= 4)
1128 {
1129 int aligned = size - (size % 4);
1130
1131 /* use bulk writes above a certain limit. This may have to be changed */
1132 if (aligned > 128)
1133 {
1134 if ((retval = target->type->bulk_write_memory(target, address, aligned / 4, buffer)) != ERROR_OK)
1135 return retval;
1136 }
1137 else
1138 {
1139 if ((retval = target_write_memory(target, address, 4, aligned / 4, buffer)) != ERROR_OK)
1140 return retval;
1141 }
1142
1143 buffer += aligned;
1144 address += aligned;
1145 size -= aligned;
1146 }
1147
1148 /* handle tail writes of less than 4 bytes */
1149 if (size > 0)
1150 {
1151 if ((retval = target_write_memory(target, address, 1, size, buffer)) != ERROR_OK)
1152 return retval;
1153 }
1154
1155 return ERROR_OK;
1156 }
1157
1158 /* Single aligned words are guaranteed to use 16 or 32 bit access
1159 * mode respectively, otherwise data is handled as quickly as
1160 * possible
1161 */
1162 int target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffer)
1163 {
1164 int retval;
1165 LOG_DEBUG("reading buffer of %i byte at 0x%8.8x", size, address);
1166
1167 if (!target_was_examined(target))
1168 {
1169 LOG_ERROR("Target not examined yet");
1170 return ERROR_FAIL;
1171 }
1172
1173 if (size == 0) {
1174 return ERROR_OK;
1175 }
1176
1177 if ((address + size - 1) < address)
1178 {
1179 /* GDB can request this when e.g. PC is 0xfffffffc*/
1180 LOG_ERROR("address+size wrapped(0x%08x, 0x%08x)", address, size);
1181 return ERROR_FAIL;
1182 }
1183
1184 if (((address % 2) == 0) && (size == 2))
1185 {
1186 return target_read_memory(target, address, 2, 1, buffer);
1187 }
1188
1189 /* handle unaligned head bytes */
1190 if (address % 4)
1191 {
1192 u32 unaligned = 4 - (address % 4);
1193
1194 if (unaligned > size)
1195 unaligned = size;
1196
1197 if ((retval = target_read_memory(target, address, 1, unaligned, buffer)) != ERROR_OK)
1198 return retval;
1199
1200 buffer += unaligned;
1201 address += unaligned;
1202 size -= unaligned;
1203 }
1204
1205 /* handle aligned words */
1206 if (size >= 4)
1207 {
1208 int aligned = size - (size % 4);
1209
1210 if ((retval = target_read_memory(target, address, 4, aligned / 4, buffer)) != ERROR_OK)
1211 return retval;
1212
1213 buffer += aligned;
1214 address += aligned;
1215 size -= aligned;
1216 }
1217
1218 /* handle tail writes of less than 4 bytes */
1219 if (size > 0)
1220 {
1221 if ((retval = target_read_memory(target, address, 1, size, buffer)) != ERROR_OK)
1222 return retval;
1223 }
1224
1225 return ERROR_OK;
1226 }
1227
1228 int target_checksum_memory(struct target_s *target, u32 address, u32 size, u32* crc)
1229 {
1230 u8 *buffer;
1231 int retval;
1232 u32 i;
1233 u32 checksum = 0;
1234 if (!target_was_examined(target))
1235 {
1236 LOG_ERROR("Target not examined yet");
1237 return ERROR_FAIL;
1238 }
1239
1240 if ((retval = target->type->checksum_memory(target, address,
1241 size, &checksum)) != ERROR_OK)
1242 {
1243 buffer = malloc(size);
1244 if (buffer == NULL)
1245 {
1246 LOG_ERROR("error allocating buffer for section (%d bytes)", size);
1247 return ERROR_INVALID_ARGUMENTS;
1248 }
1249 retval = target_read_buffer(target, address, size, buffer);
1250 if (retval != ERROR_OK)
1251 {
1252 free(buffer);
1253 return retval;
1254 }
1255
1256 /* convert to target endianess */
1257 for (i = 0; i < (size/sizeof(u32)); i++)
1258 {
1259 u32 target_data;
1260 target_data = target_buffer_get_u32(target, &buffer[i*sizeof(u32)]);
1261 target_buffer_set_u32(target, &buffer[i*sizeof(u32)], target_data);
1262 }
1263
1264 retval = image_calculate_checksum( buffer, size, &checksum );
1265 free(buffer);
1266 }
1267
1268 *crc = checksum;
1269
1270 return retval;
1271 }
1272
1273 int target_blank_check_memory(struct target_s *target, u32 address, u32 size, u32* blank)
1274 {
1275 int retval;
1276 if (!target_was_examined(target))
1277 {
1278 LOG_ERROR("Target not examined yet");
1279 return ERROR_FAIL;
1280 }
1281
1282 if (target->type->blank_check_memory == 0)
1283 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1284
1285 retval = target->type->blank_check_memory(target, address, size, blank);
1286
1287 return retval;
1288 }
1289
1290 int target_read_u32(struct target_s *target, u32 address, u32 *value)
1291 {
1292 u8 value_buf[4];
1293 if (!target_was_examined(target))
1294 {
1295 LOG_ERROR("Target not examined yet");
1296 return ERROR_FAIL;
1297 }
1298
1299 int retval = target_read_memory(target, address, 4, 1, value_buf);
1300
1301 if (retval == ERROR_OK)
1302 {
1303 *value = target_buffer_get_u32(target, value_buf);
1304 LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address, *value);
1305 }
1306 else
1307 {
1308 *value = 0x0;
1309 LOG_DEBUG("address: 0x%8.8x failed", address);
1310 }
1311
1312 return retval;
1313 }
1314
1315 int target_read_u16(struct target_s *target, u32 address, u16 *value)
1316 {
1317 u8 value_buf[2];
1318 if (!target_was_examined(target))
1319 {
1320 LOG_ERROR("Target not examined yet");
1321 return ERROR_FAIL;
1322 }
1323
1324 int retval = target_read_memory(target, address, 2, 1, value_buf);
1325
1326 if (retval == ERROR_OK)
1327 {
1328 *value = target_buffer_get_u16(target, value_buf);
1329 LOG_DEBUG("address: 0x%8.8x, value: 0x%4.4x", address, *value);
1330 }
1331 else
1332 {
1333 *value = 0x0;
1334 LOG_DEBUG("address: 0x%8.8x failed", address);
1335 }
1336
1337 return retval;
1338 }
1339
1340 int target_read_u8(struct target_s *target, u32 address, u8 *value)
1341 {
1342 int retval = target_read_memory(target, address, 1, 1, value);
1343 if (!target_was_examined(target))
1344 {
1345 LOG_ERROR("Target not examined yet");
1346 return ERROR_FAIL;
1347 }
1348
1349 if (retval == ERROR_OK)
1350 {
1351 LOG_DEBUG("address: 0x%8.8x, value: 0x%2.2x", address, *value);
1352 }
1353 else
1354 {
1355 *value = 0x0;
1356 LOG_DEBUG("address: 0x%8.8x failed", address);
1357 }
1358
1359 return retval;
1360 }
1361
1362 int target_write_u32(struct target_s *target, u32 address, u32 value)
1363 {
1364 int retval;
1365 u8 value_buf[4];
1366 if (!target_was_examined(target))
1367 {
1368 LOG_ERROR("Target not examined yet");
1369 return ERROR_FAIL;
1370 }
1371
1372 LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address, value);
1373
1374 target_buffer_set_u32(target, value_buf, value);
1375 if ((retval = target_write_memory(target, address, 4, 1, value_buf)) != ERROR_OK)
1376 {
1377 LOG_DEBUG("failed: %i", retval);
1378 }
1379
1380 return retval;
1381 }
1382
1383 int target_write_u16(struct target_s *target, u32 address, u16 value)
1384 {
1385 int retval;
1386 u8 value_buf[2];
1387 if (!target_was_examined(target))
1388 {
1389 LOG_ERROR("Target not examined yet");
1390 return ERROR_FAIL;
1391 }
1392
1393 LOG_DEBUG("address: 0x%8.8x, value: 0x%8.8x", address, value);
1394
1395 target_buffer_set_u16(target, value_buf, value);
1396 if ((retval = target_write_memory(target, address, 2, 1, value_buf)) != ERROR_OK)
1397 {
1398 LOG_DEBUG("failed: %i", retval);
1399 }
1400
1401 return retval;
1402 }
1403
1404 int target_write_u8(struct target_s *target, u32 address, u8 value)
1405 {
1406 int retval;
1407 if (!target_was_examined(target))
1408 {
1409 LOG_ERROR("Target not examined yet");
1410 return ERROR_FAIL;
1411 }
1412
1413 LOG_DEBUG("address: 0x%8.8x, value: 0x%2.2x", address, value);
1414
1415 if ((retval = target_write_memory(target, address, 1, 1, &value)) != ERROR_OK)
1416 {
1417 LOG_DEBUG("failed: %i", retval);
1418 }
1419
1420 return retval;
1421 }
1422
1423 int target_register_user_commands(struct command_context_s *cmd_ctx)
1424 {
1425 int retval = ERROR_OK;
1426
1427
1428 /* script procedures */
1429 register_command(cmd_ctx, NULL, "profile", handle_profile_command, COMMAND_EXEC, "profiling samples the CPU PC");
1430 register_jim(cmd_ctx, "ocd_mem2array", jim_mem2array, "read memory and return as a TCL array for script processing <ARRAYNAME> <WIDTH=32/16/8> <ADDRESS> <COUNT>");
1431 register_jim(cmd_ctx, "ocd_array2mem", jim_array2mem, "convert a TCL array to memory locations and write the values <ARRAYNAME> <WIDTH=32/16/8> <ADDRESS> <COUNT>");
1432
1433 register_command(cmd_ctx, NULL, "fast_load_image", handle_fast_load_image_command, COMMAND_ANY,
1434 "same args as load_image, image stored in memory - mainly for profiling purposes");
1435
1436 register_command(cmd_ctx, NULL, "fast_load", handle_fast_load_command, COMMAND_ANY,
1437 "loads active fast load image to current target - mainly for profiling purposes");
1438
1439
1440 register_command(cmd_ctx, NULL, "virt2phys", handle_virt2phys_command, COMMAND_ANY, "translate a virtual address into a physical address");
1441 register_command(cmd_ctx, NULL, "reg", handle_reg_command, COMMAND_EXEC, "display or set a register");
1442 register_command(cmd_ctx, NULL, "poll", handle_poll_command, COMMAND_EXEC, "poll target state");
1443 register_command(cmd_ctx, NULL, "wait_halt", handle_wait_halt_command, COMMAND_EXEC, "wait for target halt [time (s)]");
1444 register_command(cmd_ctx, NULL, "halt", handle_halt_command, COMMAND_EXEC, "halt target");
1445 register_command(cmd_ctx, NULL, "resume", handle_resume_command, COMMAND_EXEC, "resume target [addr]");
1446 register_command(cmd_ctx, NULL, "step", handle_step_command, COMMAND_EXEC, "step one instruction from current PC or [addr]");
1447 register_command(cmd_ctx, NULL, "reset", handle_reset_command, COMMAND_EXEC, "reset target [run|halt|init] - default is run");
1448 register_command(cmd_ctx, NULL, "soft_reset_halt", handle_soft_reset_halt_command, COMMAND_EXEC, "halt the target and do a soft reset");
1449
1450 register_command(cmd_ctx, NULL, "mdw", handle_md_command, COMMAND_EXEC, "display memory words <addr> [count]");
1451 register_command(cmd_ctx, NULL, "mdh", handle_md_command, COMMAND_EXEC, "display memory half-words <addr> [count]");
1452 register_command(cmd_ctx, NULL, "mdb", handle_md_command, COMMAND_EXEC, "display memory bytes <addr> [count]");
1453
1454 register_command(cmd_ctx, NULL, "mww", handle_mw_command, COMMAND_EXEC, "write memory word <addr> <value> [count]");
1455 register_command(cmd_ctx, NULL, "mwh", handle_mw_command, COMMAND_EXEC, "write memory half-word <addr> <value> [count]");
1456 register_command(cmd_ctx, NULL, "mwb", handle_mw_command, COMMAND_EXEC, "write memory byte <addr> <value> [count]");
1457
1458 register_command(cmd_ctx, NULL, "bp", handle_bp_command, COMMAND_EXEC, "set breakpoint <address> <length> [hw]");
1459 register_command(cmd_ctx, NULL, "rbp", handle_rbp_command, COMMAND_EXEC, "remove breakpoint <adress>");
1460 register_command(cmd_ctx, NULL, "wp", handle_wp_command, COMMAND_EXEC, "set watchpoint <address> <length> <r/w/a> [value] [mask]");
1461 register_command(cmd_ctx, NULL, "rwp", handle_rwp_command, COMMAND_EXEC, "remove watchpoint <adress>");
1462
1463 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]");
1464 register_command(cmd_ctx, NULL, "dump_image", handle_dump_image_command, COMMAND_EXEC, "dump_image <file> <address> <size>");
1465 register_command(cmd_ctx, NULL, "verify_image", handle_verify_image_command, COMMAND_EXEC, "verify_image <file> [offset] [type]");
1466 register_command(cmd_ctx, NULL, "test_image", handle_test_image_command, COMMAND_EXEC, "test_image <file> [offset] [type]");
1467
1468 if((retval = target_request_register_commands(cmd_ctx)) != ERROR_OK)
1469 return retval;
1470 if((retval = trace_register_commands(cmd_ctx)) != ERROR_OK)
1471 return retval;
1472
1473 return retval;
1474 }
1475
1476 static int handle_targets_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1477 {
1478 target_t *target = all_targets;
1479
1480 if (argc == 1)
1481 {
1482 target = get_target(args[0]);
1483 if (target == NULL) {
1484 command_print(cmd_ctx,"Target: %s is unknown, try one of:\n", args[0] );
1485 goto DumpTargets;
1486 }
1487 if (!target->tap->enabled) {
1488 command_print(cmd_ctx,"Target: TAP %s is disabled, "
1489 "can't be the current target\n",
1490 target->tap->dotted_name);
1491 return ERROR_FAIL;
1492 }
1493
1494 cmd_ctx->current_target = target->target_number;
1495 return ERROR_OK;
1496 }
1497 DumpTargets:
1498
1499 target = all_targets;
1500 command_print(cmd_ctx, " TargetName Type Endian TapName State ");
1501 command_print(cmd_ctx, "-- ------------------ ---------- ------ ------------------ ------------");
1502 while (target)
1503 {
1504 const char *state;
1505 char marker = ' ';
1506
1507 if (target->tap->enabled)
1508 state = Jim_Nvp_value2name_simple(nvp_target_state,
1509 target->state)->name;
1510 else
1511 state = "tap-disabled";
1512
1513 if (cmd_ctx->current_target == target->target_number)
1514 marker = '*';
1515
1516 /* keep columns lined up to match the headers above */
1517 command_print(cmd_ctx, "%2d%c %-18s %-10s %-6s %-18s %s",
1518 target->target_number,
1519 marker,
1520 target->cmd_name,
1521 target_get_name(target),
1522 Jim_Nvp_value2name_simple(nvp_target_endian,
1523 target->endianness)->name,
1524 target->tap->dotted_name,
1525 state);
1526 target = target->next;
1527 }
1528
1529 return ERROR_OK;
1530 }
1531
1532 /* every 300ms we check for reset & powerdropout and issue a "reset halt" if so. */
1533
1534 static int powerDropout;
1535 static int srstAsserted;
1536
1537 static int runPowerRestore;
1538 static int runPowerDropout;
1539 static int runSrstAsserted;
1540 static int runSrstDeasserted;
1541
1542 static int sense_handler(void)
1543 {
1544 static int prevSrstAsserted = 0;
1545 static int prevPowerdropout = 0;
1546
1547 int retval;
1548 if ((retval=jtag_power_dropout(&powerDropout))!=ERROR_OK)
1549 return retval;
1550
1551 int powerRestored;
1552 powerRestored = prevPowerdropout && !powerDropout;
1553 if (powerRestored)
1554 {
1555 runPowerRestore = 1;
1556 }
1557
1558 long long current = timeval_ms();
1559 static long long lastPower = 0;
1560 int waitMore = lastPower + 2000 > current;
1561 if (powerDropout && !waitMore)
1562 {
1563 runPowerDropout = 1;
1564 lastPower = current;
1565 }
1566
1567 if ((retval=jtag_srst_asserted(&srstAsserted))!=ERROR_OK)
1568 return retval;
1569
1570 int srstDeasserted;
1571 srstDeasserted = prevSrstAsserted && !srstAsserted;
1572
1573 static long long lastSrst = 0;
1574 waitMore = lastSrst + 2000 > current;
1575 if (srstDeasserted && !waitMore)
1576 {
1577 runSrstDeasserted = 1;
1578 lastSrst = current;
1579 }
1580
1581 if (!prevSrstAsserted && srstAsserted)
1582 {
1583 runSrstAsserted = 1;
1584 }
1585
1586 prevSrstAsserted = srstAsserted;
1587 prevPowerdropout = powerDropout;
1588
1589 if (srstDeasserted || powerRestored)
1590 {
1591 /* Other than logging the event we can't do anything here.
1592 * Issuing a reset is a particularly bad idea as we might
1593 * be inside a reset already.
1594 */
1595 }
1596
1597 return ERROR_OK;
1598 }
1599
1600 /* process target state changes */
1601 int handle_target(void *priv)
1602 {
1603 int retval = ERROR_OK;
1604
1605 /* we do not want to recurse here... */
1606 static int recursive = 0;
1607 if (! recursive)
1608 {
1609 recursive = 1;
1610 sense_handler();
1611 /* danger! running these procedures can trigger srst assertions and power dropouts.
1612 * We need to avoid an infinite loop/recursion here and we do that by
1613 * clearing the flags after running these events.
1614 */
1615 int did_something = 0;
1616 if (runSrstAsserted)
1617 {
1618 Jim_Eval( interp, "srst_asserted");
1619 did_something = 1;
1620 }
1621 if (runSrstDeasserted)
1622 {
1623 Jim_Eval( interp, "srst_deasserted");
1624 did_something = 1;
1625 }
1626 if (runPowerDropout)
1627 {
1628 Jim_Eval( interp, "power_dropout");
1629 did_something = 1;
1630 }
1631 if (runPowerRestore)
1632 {
1633 Jim_Eval( interp, "power_restore");
1634 did_something = 1;
1635 }
1636
1637 if (did_something)
1638 {
1639 /* clear detect flags */
1640 sense_handler();
1641 }
1642
1643 /* clear action flags */
1644
1645 runSrstAsserted=0;
1646 runSrstDeasserted=0;
1647 runPowerRestore=0;
1648 runPowerDropout=0;
1649
1650 recursive = 0;
1651 }
1652
1653 target_t *target = all_targets;
1654
1655 while (target)
1656 {
1657
1658 /* only poll target if we've got power and srst isn't asserted */
1659 if (target_continous_poll&&!powerDropout&&!srstAsserted)
1660 {
1661 /* polling may fail silently until the target has been examined */
1662 if((retval = target_poll(target)) != ERROR_OK)
1663 return retval;
1664 }
1665
1666 target = target->next;
1667 }
1668
1669 return retval;
1670 }
1671
1672 static int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1673 {
1674 target_t *target;
1675 reg_t *reg = NULL;
1676 int count = 0;
1677 char *value;
1678
1679 LOG_DEBUG("-");
1680
1681 target = get_current_target(cmd_ctx);
1682
1683 /* list all available registers for the current target */
1684 if (argc == 0)
1685 {
1686 reg_cache_t *cache = target->reg_cache;
1687
1688 count = 0;
1689 while(cache)
1690 {
1691 int i;
1692 for (i = 0; i < cache->num_regs; i++)
1693 {
1694 value = buf_to_str(cache->reg_list[i].value, cache->reg_list[i].size, 16);
1695 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);
1696 free(value);
1697 }
1698 cache = cache->next;
1699 }
1700
1701 return ERROR_OK;
1702 }
1703
1704 /* access a single register by its ordinal number */
1705 if ((args[0][0] >= '0') && (args[0][0] <= '9'))
1706 {
1707 unsigned num;
1708 int retval = parse_uint(args[0], &num);
1709 if (ERROR_OK != retval)
1710 return ERROR_COMMAND_SYNTAX_ERROR;
1711
1712 reg_cache_t *cache = target->reg_cache;
1713 count = 0;
1714 while(cache)
1715 {
1716 int i;
1717 for (i = 0; i < cache->num_regs; i++)
1718 {
1719 if (count++ == (int)num)
1720 {
1721 reg = &cache->reg_list[i];
1722 break;
1723 }
1724 }
1725 if (reg)
1726 break;
1727 cache = cache->next;
1728 }
1729
1730 if (!reg)
1731 {
1732 command_print(cmd_ctx, "%i is out of bounds, the current target has only %i registers (0 - %i)", num, count, count - 1);
1733 return ERROR_OK;
1734 }
1735 } else /* access a single register by its name */
1736 {
1737 reg = register_get_by_name(target->reg_cache, args[0], 1);
1738
1739 if (!reg)
1740 {
1741 command_print(cmd_ctx, "register %s not found in current target", args[0]);
1742 return ERROR_OK;
1743 }
1744 }
1745
1746 /* display a register */
1747 if ((argc == 1) || ((argc == 2) && !((args[1][0] >= '0') && (args[1][0] <= '9'))))
1748 {
1749 if ((argc == 2) && (strcmp(args[1], "force") == 0))
1750 reg->valid = 0;
1751
1752 if (reg->valid == 0)
1753 {
1754 reg_arch_type_t *arch_type = register_get_arch_type(reg->arch_type);
1755 arch_type->get(reg);
1756 }
1757 value = buf_to_str(reg->value, reg->size, 16);
1758 command_print(cmd_ctx, "%s (/%i): 0x%s", reg->name, reg->size, value);
1759 free(value);
1760 return ERROR_OK;
1761 }
1762
1763 /* set register value */
1764 if (argc == 2)
1765 {
1766 u8 *buf = malloc(CEIL(reg->size, 8));
1767 str_to_buf(args[1], strlen(args[1]), buf, reg->size, 0);
1768
1769 reg_arch_type_t *arch_type = register_get_arch_type(reg->arch_type);
1770 arch_type->set(reg, buf);
1771
1772 value = buf_to_str(reg->value, reg->size, 16);
1773 command_print(cmd_ctx, "%s (/%i): 0x%s", reg->name, reg->size, value);
1774 free(value);
1775
1776 free(buf);
1777
1778 return ERROR_OK;
1779 }
1780
1781 command_print(cmd_ctx, "usage: reg <#|name> [value]");
1782
1783 return ERROR_OK;
1784 }
1785
1786 static int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1787 {
1788 int retval = ERROR_OK;
1789 target_t *target = get_current_target(cmd_ctx);
1790
1791 if (argc == 0)
1792 {
1793 command_print(cmd_ctx, "background polling: %s",
1794 target_continous_poll ? "on" : "off");
1795 if ((retval = target_poll(target)) != ERROR_OK)
1796 return retval;
1797 if ((retval = target_arch_state(target)) != ERROR_OK)
1798 return retval;
1799
1800 }
1801 else if (argc==1)
1802 {
1803 if (strcmp(args[0], "on") == 0)
1804 {
1805 target_continous_poll = 1;
1806 }
1807 else if (strcmp(args[0], "off") == 0)
1808 {
1809 target_continous_poll = 0;
1810 }
1811 else
1812 {
1813 command_print(cmd_ctx, "arg is \"on\" or \"off\"");
1814 }
1815 } else
1816 {
1817 return ERROR_COMMAND_SYNTAX_ERROR;
1818 }
1819
1820 return retval;
1821 }
1822
1823 static int handle_wait_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1824 {
1825 if (argc > 1)
1826 return ERROR_COMMAND_SYNTAX_ERROR;
1827
1828 unsigned ms = 5000;
1829 if (1 == argc)
1830 {
1831 int retval = parse_uint(args[0], &ms);
1832 if (ERROR_OK != retval)
1833 {
1834 command_print(cmd_ctx, "usage: %s [seconds]", cmd);
1835 return ERROR_COMMAND_SYNTAX_ERROR;
1836 }
1837 // convert seconds (given) to milliseconds (needed)
1838 ms *= 1000;
1839 }
1840
1841 target_t *target = get_current_target(cmd_ctx);
1842 return target_wait_state(target, TARGET_HALTED, ms);
1843 }
1844
1845 /* wait for target state to change. The trick here is to have a low
1846 * latency for short waits and not to suck up all the CPU time
1847 * on longer waits.
1848 *
1849 * After 500ms, keep_alive() is invoked
1850 */
1851 int target_wait_state(target_t *target, enum target_state state, int ms)
1852 {
1853 int retval;
1854 long long then=0, cur;
1855 int once=1;
1856
1857 for (;;)
1858 {
1859 if ((retval=target_poll(target))!=ERROR_OK)
1860 return retval;
1861 if (target->state == state)
1862 {
1863 break;
1864 }
1865 cur = timeval_ms();
1866 if (once)
1867 {
1868 once=0;
1869 then = timeval_ms();
1870 LOG_DEBUG("waiting for target %s...",
1871 Jim_Nvp_value2name_simple(nvp_target_state,state)->name);
1872 }
1873
1874 if (cur-then>500)
1875 {
1876 keep_alive();
1877 }
1878
1879 if ((cur-then)>ms)
1880 {
1881 LOG_ERROR("timed out while waiting for target %s",
1882 Jim_Nvp_value2name_simple(nvp_target_state,state)->name);
1883 return ERROR_FAIL;
1884 }
1885 }
1886
1887 return ERROR_OK;
1888 }
1889
1890 static int handle_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1891 {
1892 LOG_DEBUG("-");
1893
1894 target_t *target = get_current_target(cmd_ctx);
1895 int retval = target_halt(target);
1896 if (ERROR_OK != retval)
1897 return retval;
1898
1899 if (argc == 1)
1900 {
1901 unsigned wait;
1902 retval = parse_uint(args[0], &wait);
1903 if (ERROR_OK != retval)
1904 return ERROR_COMMAND_SYNTAX_ERROR;
1905 if (!wait)
1906 return ERROR_OK;
1907 }
1908
1909 return handle_wait_halt_command(cmd_ctx, cmd, args, argc);
1910 }
1911
1912 static int handle_soft_reset_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1913 {
1914 target_t *target = get_current_target(cmd_ctx);
1915
1916 LOG_USER("requesting target halt and executing a soft reset");
1917
1918 target->type->soft_reset_halt(target);
1919
1920 return ERROR_OK;
1921 }
1922
1923 static int handle_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1924 {
1925 if (argc > 1)
1926 return ERROR_COMMAND_SYNTAX_ERROR;
1927
1928 enum target_reset_mode reset_mode = RESET_RUN;
1929 if (argc == 1)
1930 {
1931 const Jim_Nvp *n;
1932 n = Jim_Nvp_name2value_simple( nvp_reset_modes, args[0] );
1933 if( (n->name == NULL) || (n->value == RESET_UNKNOWN) ){
1934 return ERROR_COMMAND_SYNTAX_ERROR;
1935 }
1936 reset_mode = n->value;
1937 }
1938
1939 /* reset *all* targets */
1940 return target_process_reset(cmd_ctx, reset_mode);
1941 }
1942
1943
1944 static int handle_resume_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1945 {
1946 if (argc > 1)
1947 return ERROR_COMMAND_SYNTAX_ERROR;
1948
1949 target_t *target = get_current_target(cmd_ctx);
1950 target_handle_event(target, TARGET_EVENT_OLD_pre_resume);
1951
1952 /* with no args, resume from current pc, addr = 0,
1953 * with one arguments, addr = args[0],
1954 * handle breakpoints, not debugging */
1955 u32 addr = 0;
1956 if (argc == 1)
1957 {
1958 int retval = parse_u32(args[0], &addr);
1959 if (ERROR_OK != retval)
1960 return retval;
1961 }
1962
1963 return target_resume(target, 0, addr, 1, 0);
1964 }
1965
1966 static int handle_step_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1967 {
1968 if (argc > 1)
1969 return ERROR_COMMAND_SYNTAX_ERROR;
1970
1971 LOG_DEBUG("-");
1972
1973 /* with no args, step from current pc, addr = 0,
1974 * with one argument addr = args[0],
1975 * handle breakpoints, debugging */
1976 u32 addr = 0;
1977 if (argc == 1)
1978 {
1979 int retval = parse_u32(args[0], &addr);
1980 if (ERROR_OK != retval)
1981 return retval;
1982 }
1983
1984 target_t *target = get_current_target(cmd_ctx);
1985 return target->type->step(target, 0, addr, 1);
1986 }
1987
1988 static void handle_md_output(struct command_context_s *cmd_ctx,
1989 struct target_s *target, u32 address, unsigned size,
1990 unsigned count, const u8 *buffer)
1991 {
1992 const unsigned line_bytecnt = 32;
1993 unsigned line_modulo = line_bytecnt / size;
1994
1995 char output[line_bytecnt * 4 + 1];
1996 unsigned output_len = 0;
1997
1998 const char *value_fmt;
1999 switch (size) {
2000 case 4: value_fmt = "%8.8x "; break;
2001 case 2: value_fmt = "%4.2x "; break;
2002 case 1: value_fmt = "%2.2x "; break;
2003 default:
2004 LOG_ERROR("invalid memory read size: %u", size);
2005 exit(-1);
2006 }
2007
2008 for (unsigned i = 0; i < count; i++)
2009 {
2010 if (i % line_modulo == 0)
2011 {
2012 output_len += snprintf(output + output_len,
2013 sizeof(output) - output_len,
2014 "0x%8.8x: ", address + (i*size));
2015 }
2016
2017 u32 value=0;
2018 const u8 *value_ptr = buffer + i * size;
2019 switch (size) {
2020 case 4: value = target_buffer_get_u32(target, value_ptr); break;
2021 case 2: value = target_buffer_get_u16(target, value_ptr); break;
2022 case 1: value = *value_ptr;
2023 }
2024 output_len += snprintf(output + output_len,
2025 sizeof(output) - output_len,
2026 value_fmt, value);
2027
2028 if ((i % line_modulo == line_modulo - 1) || (i == count - 1))
2029 {
2030 command_print(cmd_ctx, "%s", output);
2031 output_len = 0;
2032 }
2033 }
2034 }
2035
2036 static int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2037 {
2038 if (argc < 1)
2039 return ERROR_COMMAND_SYNTAX_ERROR;
2040
2041 unsigned size = 0;
2042 switch (cmd[2]) {
2043 case 'w': size = 4; break;
2044 case 'h': size = 2; break;
2045 case 'b': size = 1; break;
2046 default: return ERROR_COMMAND_SYNTAX_ERROR;
2047 }
2048
2049 u32 address;
2050 int retval = parse_u32(args[0], &address);
2051 if (ERROR_OK != retval)
2052 return retval;
2053
2054 unsigned count = 1;
2055 if (argc == 2)
2056 {
2057 retval = parse_uint(args[1], &count);
2058 if (ERROR_OK != retval)
2059 return retval;
2060 }
2061
2062 u8 *buffer = calloc(count, size);
2063
2064 target_t *target = get_current_target(cmd_ctx);
2065 retval = target_read_memory(target,
2066 address, size, count, buffer);
2067 if (ERROR_OK == retval)
2068 handle_md_output(cmd_ctx, target, address, size, count, buffer);
2069
2070 free(buffer);
2071
2072 return retval;
2073 }
2074
2075 static int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2076 {
2077 u32 address = 0;
2078 u32 value = 0;
2079 int count = 1;
2080 int i;
2081 int wordsize;
2082 target_t *target = get_current_target(cmd_ctx);
2083 u8 value_buf[4];
2084
2085 if ((argc < 2) || (argc > 3))
2086 return ERROR_COMMAND_SYNTAX_ERROR;
2087
2088 address = strtoul(args[0], NULL, 0);
2089 value = strtoul(args[1], NULL, 0);
2090 if (argc == 3)
2091 count = strtoul(args[2], NULL, 0);
2092
2093 switch (cmd[2])
2094 {
2095 case 'w':
2096 wordsize = 4;
2097 target_buffer_set_u32(target, value_buf, value);
2098 break;
2099 case 'h':
2100 wordsize = 2;
2101 target_buffer_set_u16(target, value_buf, value);
2102 break;
2103 case 'b':
2104 wordsize = 1;
2105 value_buf[0] = value;
2106 break;
2107 default:
2108 return ERROR_COMMAND_SYNTAX_ERROR;
2109 }
2110 for (i=0; i<count; i++)
2111 {
2112 int retval = target_write_memory(target,
2113 address + i * wordsize, wordsize, 1, value_buf);
2114 if (ERROR_OK != retval)
2115 return retval;
2116 keep_alive();
2117 }
2118
2119 return ERROR_OK;
2120
2121 }
2122
2123 static int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2124 {
2125 u8 *buffer;
2126 u32 buf_cnt;
2127 u32 image_size;
2128 u32 min_address=0;
2129 u32 max_address=0xffffffff;
2130 int i;
2131 int retval, retvaltemp;
2132
2133 image_t image;
2134
2135 duration_t duration;
2136 char *duration_text;
2137
2138 target_t *target = get_current_target(cmd_ctx);
2139
2140 if ((argc < 1)||(argc > 5))
2141 {
2142 return ERROR_COMMAND_SYNTAX_ERROR;
2143 }
2144
2145 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
2146 if (argc >= 2)
2147 {
2148 image.base_address_set = 1;
2149 image.base_address = strtoul(args[1], NULL, 0);
2150 }
2151 else
2152 {
2153 image.base_address_set = 0;
2154 }
2155
2156
2157 image.start_address_set = 0;
2158
2159 if (argc>=4)
2160 {
2161 min_address=strtoul(args[3], NULL, 0);
2162 }
2163 if (argc>=5)
2164 {
2165 max_address=strtoul(args[4], NULL, 0)+min_address;
2166 }
2167
2168 if (min_address>max_address)
2169 {
2170 return ERROR_COMMAND_SYNTAX_ERROR;
2171 }
2172
2173 duration_start_measure(&duration);
2174
2175 if (image_open(&image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
2176 {
2177 return ERROR_OK;
2178 }
2179
2180 image_size = 0x0;
2181 retval = ERROR_OK;
2182 for (i = 0; i < image.num_sections; i++)
2183 {
2184 buffer = malloc(image.sections[i].size);
2185 if (buffer == NULL)
2186 {
2187 command_print(cmd_ctx, "error allocating buffer for section (%d bytes)", image.sections[i].size);
2188 break;
2189 }
2190
2191 if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
2192 {
2193 free(buffer);
2194 break;
2195 }
2196
2197 u32 offset=0;
2198 u32 length=buf_cnt;
2199
2200 /* DANGER!!! beware of unsigned comparision here!!! */
2201
2202 if ((image.sections[i].base_address+buf_cnt>=min_address)&&
2203 (image.sections[i].base_address<max_address))
2204 {
2205 if (image.sections[i].base_address<min_address)
2206 {
2207 /* clip addresses below */
2208 offset+=min_address-image.sections[i].base_address;
2209 length-=offset;
2210 }
2211
2212 if (image.sections[i].base_address+buf_cnt>max_address)
2213 {
2214 length-=(image.sections[i].base_address+buf_cnt)-max_address;
2215 }
2216
2217 if ((retval = target_write_buffer(target, image.sections[i].base_address+offset, length, buffer+offset)) != ERROR_OK)
2218 {
2219 free(buffer);
2220 break;
2221 }
2222 image_size += length;
2223 command_print(cmd_ctx, "%u byte written at address 0x%8.8x", length, image.sections[i].base_address+offset);
2224 }
2225
2226 free(buffer);
2227 }
2228
2229 if((retvaltemp = duration_stop_measure(&duration, &duration_text)) != ERROR_OK)
2230 {
2231 image_close(&image);
2232 return retvaltemp;
2233 }
2234
2235 if (retval==ERROR_OK)
2236 {
2237 command_print(cmd_ctx, "downloaded %u byte in %s", image_size, duration_text);
2238 }
2239 free(duration_text);
2240
2241 image_close(&image);
2242
2243 return retval;
2244
2245 }
2246
2247 static int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2248 {
2249 fileio_t fileio;
2250
2251 u32 address;
2252 u32 size;
2253 u8 buffer[560];
2254 int retval=ERROR_OK, retvaltemp;
2255
2256 duration_t duration;
2257 char *duration_text;
2258
2259 target_t *target = get_current_target(cmd_ctx);
2260
2261 if (argc != 3)
2262 {
2263 command_print(cmd_ctx, "usage: dump_image <filename> <address> <size>");
2264 return ERROR_OK;
2265 }
2266
2267 address = strtoul(args[1], NULL, 0);
2268 size = strtoul(args[2], NULL, 0);
2269
2270 if (fileio_open(&fileio, args[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)
2271 {
2272 return ERROR_OK;
2273 }
2274
2275 duration_start_measure(&duration);
2276
2277 while (size > 0)
2278 {
2279 u32 size_written;
2280 u32 this_run_size = (size > 560) ? 560 : size;
2281
2282 retval = target_read_buffer(target, address, this_run_size, buffer);
2283 if (retval != ERROR_OK)
2284 {
2285 break;
2286 }
2287
2288 retval = fileio_write(&fileio, this_run_size, buffer, &size_written);
2289 if (retval != ERROR_OK)
2290 {
2291 break;
2292 }
2293
2294 size -= this_run_size;
2295 address += this_run_size;
2296 }
2297
2298 if((retvaltemp = fileio_close(&fileio)) != ERROR_OK)
2299 return retvaltemp;
2300
2301 if((retvaltemp = duration_stop_measure(&duration, &duration_text)) != ERROR_OK)
2302 return retvaltemp;
2303
2304 if (retval==ERROR_OK)
2305 {
2306 command_print(cmd_ctx, "dumped %lld byte in %s",
2307 fileio.size, duration_text);
2308 free(duration_text);
2309 }
2310
2311 return retval;
2312 }
2313
2314 static int handle_verify_image_command_internal(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, int verify)
2315 {
2316 u8 *buffer;
2317 u32 buf_cnt;
2318 u32 image_size;
2319 int i;
2320 int retval, retvaltemp;
2321 u32 checksum = 0;
2322 u32 mem_checksum = 0;
2323
2324 image_t image;
2325
2326 duration_t duration;
2327 char *duration_text;
2328
2329 target_t *target = get_current_target(cmd_ctx);
2330
2331 if (argc < 1)
2332 {
2333 return ERROR_COMMAND_SYNTAX_ERROR;
2334 }
2335
2336 if (!target)
2337 {
2338 LOG_ERROR("no target selected");
2339 return ERROR_FAIL;
2340 }
2341
2342 duration_start_measure(&duration);
2343
2344 if (argc >= 2)
2345 {
2346 image.base_address_set = 1;
2347 image.base_address = strtoul(args[1], NULL, 0);
2348 }
2349 else
2350 {
2351 image.base_address_set = 0;
2352 image.base_address = 0x0;
2353 }
2354
2355 image.start_address_set = 0;
2356
2357 if ((retval=image_open(&image, args[0], (argc == 3) ? args[2] : NULL)) != ERROR_OK)
2358 {
2359 return retval;
2360 }
2361
2362 image_size = 0x0;
2363 retval=ERROR_OK;
2364 for (i = 0; i < image.num_sections; i++)
2365 {
2366 buffer = malloc(image.sections[i].size);
2367 if (buffer == NULL)
2368 {
2369 command_print(cmd_ctx, "error allocating buffer for section (%d bytes)", image.sections[i].size);
2370 break;
2371 }
2372 if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
2373 {
2374 free(buffer);
2375 break;
2376 }
2377
2378 if (verify)
2379 {
2380 /* calculate checksum of image */
2381 image_calculate_checksum( buffer, buf_cnt, &checksum );
2382
2383 retval = target_checksum_memory(target, image.sections[i].base_address, buf_cnt, &mem_checksum);
2384 if( retval != ERROR_OK )
2385 {
2386 free(buffer);
2387 break;
2388 }
2389
2390 if( checksum != mem_checksum )
2391 {
2392 /* failed crc checksum, fall back to a binary compare */
2393 u8 *data;
2394
2395 command_print(cmd_ctx, "checksum mismatch - attempting binary compare");
2396
2397 data = (u8*)malloc(buf_cnt);
2398
2399 /* Can we use 32bit word accesses? */
2400 int size = 1;
2401 int count = buf_cnt;
2402 if ((count % 4) == 0)
2403 {
2404 size *= 4;
2405 count /= 4;
2406 }
2407 retval = target_read_memory(target, image.sections[i].base_address, size, count, data);
2408 if (retval == ERROR_OK)
2409 {
2410 u32 t;
2411 for (t = 0; t < buf_cnt; t++)
2412 {
2413 if (data[t] != buffer[t])
2414 {
2415 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]);
2416 free(data);
2417 free(buffer);
2418 retval=ERROR_FAIL;
2419 goto done;
2420 }
2421 if ((t%16384)==0)
2422 {
2423 keep_alive();
2424 }
2425 }
2426 }
2427
2428 free(data);
2429 }
2430 } else
2431 {
2432 command_print(cmd_ctx, "address 0x%08x length 0x%08x", image.sections[i].base_address, buf_cnt);
2433 }
2434
2435 free(buffer);
2436 image_size += buf_cnt;
2437 }
2438 done:
2439
2440 if((retvaltemp = duration_stop_measure(&duration, &duration_text)) != ERROR_OK)
2441 {
2442 image_close(&image);
2443 return retvaltemp;
2444 }
2445
2446 if (retval==ERROR_OK)
2447 {
2448 command_print(cmd_ctx, "verified %u bytes in %s", image_size, duration_text);
2449 }
2450 free(duration_text);
2451
2452 image_close(&image);
2453
2454 return retval;
2455 }
2456
2457 static int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2458 {
2459 return handle_verify_image_command_internal(cmd_ctx, cmd, args, argc, 1);
2460 }
2461
2462 static int handle_test_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2463 {
2464 return handle_verify_image_command_internal(cmd_ctx, cmd, args, argc, 0);
2465 }
2466
2467 static int handle_bp_command_list(struct command_context_s *cmd_ctx)
2468 {
2469 target_t *target = get_current_target(cmd_ctx);
2470 breakpoint_t *breakpoint = target->breakpoints;
2471 while (breakpoint)
2472 {
2473 if (breakpoint->type == BKPT_SOFT)
2474 {
2475 char* buf = buf_to_str(breakpoint->orig_instr,
2476 breakpoint->length, 16);
2477 command_print(cmd_ctx, "0x%8.8x, 0x%x, %i, 0x%s",
2478 breakpoint->address, breakpoint->length,
2479 breakpoint->set, buf);
2480 free(buf);
2481 }
2482 else
2483 {
2484 command_print(cmd_ctx, "0x%8.8x, 0x%x, %i",
2485 breakpoint->address, breakpoint->length, breakpoint->set);
2486 }
2487
2488 breakpoint = breakpoint->next;
2489 }
2490 return ERROR_OK;
2491 }
2492
2493 static int handle_bp_command_set(struct command_context_s *cmd_ctx,
2494 u32 addr, u32 length, int hw)
2495 {
2496 target_t *target = get_current_target(cmd_ctx);
2497 int retval = breakpoint_add(target, addr, length, hw);
2498 if (ERROR_OK == retval)
2499 command_print(cmd_ctx, "breakpoint set at 0x%8.8x", addr);
2500 else
2501 LOG_ERROR("Failure setting breakpoint");
2502 return retval;
2503 }
2504
2505 static int handle_bp_command(struct command_context_s *cmd_ctx,
2506 char *cmd, char **args, int argc)
2507 {
2508 if (argc == 0)
2509 return handle_bp_command_list(cmd_ctx);
2510
2511 if (argc < 2 || argc > 3)
2512 {
2513 command_print(cmd_ctx, "usage: bp <address> <length> ['hw']");
2514 return ERROR_COMMAND_SYNTAX_ERROR;
2515 }
2516
2517 u32 addr = strtoul(args[0], NULL, 0);
2518 u32 length = strtoul(args[1], NULL, 0);
2519
2520 int hw = BKPT_SOFT;
2521 if (argc == 3)
2522 {
2523 if (strcmp(args[2], "hw") == 0)
2524 hw = BKPT_HARD;
2525 else
2526 return ERROR_COMMAND_SYNTAX_ERROR;
2527 }
2528
2529 return handle_bp_command_set(cmd_ctx, addr, length, hw);
2530 }
2531
2532 static int handle_rbp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2533 {
2534 target_t *target = get_current_target(cmd_ctx);
2535
2536 if (argc > 0)
2537 breakpoint_remove(target, strtoul(args[0], NULL, 0));
2538
2539 return ERROR_OK;
2540 }
2541
2542 static int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2543 {
2544 target_t *target = get_current_target(cmd_ctx);
2545 int retval;
2546
2547 if (argc == 0)
2548 {
2549 watchpoint_t *watchpoint = target->watchpoints;
2550
2551 while (watchpoint)
2552 {
2553 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);
2554 watchpoint = watchpoint->next;
2555 }
2556 }
2557 else if (argc >= 2)
2558 {
2559 enum watchpoint_rw type = WPT_ACCESS;
2560 u32 data_value = 0x0;
2561 u32 data_mask = 0xffffffff;
2562
2563 if (argc >= 3)
2564 {
2565 switch(args[2][0])
2566 {
2567 case 'r':
2568 type = WPT_READ;
2569 break;
2570 case 'w':
2571 type = WPT_WRITE;
2572 break;
2573 case 'a':
2574 type = WPT_ACCESS;
2575 break;
2576 default:
2577 command_print(cmd_ctx, "usage: wp <address> <length> [r/w/a] [value] [mask]");
2578 return ERROR_OK;
2579 }
2580 }
2581 if (argc >= 4)
2582 {
2583 data_value = strtoul(args[3], NULL, 0);
2584 }
2585 if (argc >= 5)
2586 {
2587 data_mask = strtoul(args[4], NULL, 0);
2588 }
2589
2590 if ((retval = watchpoint_add(target, strtoul(args[0], NULL, 0),
2591 strtoul(args[1], NULL, 0), type, data_value, data_mask)) != ERROR_OK)
2592 {
2593 LOG_ERROR("Failure setting breakpoints");
2594 }
2595 }
2596 else
2597 {
2598 command_print(cmd_ctx, "usage: wp <address> <length> [r/w/a] [value] [mask]");
2599 }
2600
2601 return ERROR_OK;
2602 }
2603
2604 static int handle_rwp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2605 {
2606 if (argc != 1)
2607 return ERROR_COMMAND_SYNTAX_ERROR;
2608
2609 target_t *target = get_current_target(cmd_ctx);
2610 watchpoint_remove(target, strtoul(args[0], NULL, 0));
2611
2612 return ERROR_OK;
2613 }
2614
2615
2616 /**
2617 * Translate a virtual address to a physical address.
2618 *
2619 * The low-level target implementation must have logged a detailed error
2620 * which is forwarded to telnet/GDB session.
2621 */
2622 static int handle_virt2phys_command(command_context_t *cmd_ctx,
2623 char *cmd, char **args, int argc)
2624 {
2625 if (argc != 1)
2626 return ERROR_COMMAND_SYNTAX_ERROR;
2627
2628 target_t *target = get_current_target(cmd_ctx);
2629 u32 va = strtoul(args[0], NULL, 0);
2630 u32 pa;
2631
2632 int retval = target->type->virt2phys(target, va, &pa);
2633 if (retval == ERROR_OK)
2634 command_print(cmd_ctx, "Physical address 0x%08x", pa);
2635
2636 return retval;
2637 }
2638
2639 static void writeData(FILE *f, const void *data, size_t len)
2640 {
2641 size_t written = fwrite(data, 1, len, f);
2642 if (written != len)
2643 LOG_ERROR("failed to write %zu bytes: %s", len, strerror(errno));
2644 }
2645
2646 static void writeLong(FILE *f, int l)
2647 {
2648 int i;
2649 for (i=0; i<4; i++)
2650 {
2651 char c=(l>>(i*8))&0xff;
2652 writeData(f, &c, 1);
2653 }
2654
2655 }
2656
2657 static void writeString(FILE *f, char *s)
2658 {
2659 writeData(f, s, strlen(s));
2660 }
2661
2662 /* Dump a gmon.out histogram file. */
2663 static void writeGmon(u32 *samples, u32 sampleNum, char *filename)
2664 {
2665 u32 i;
2666 FILE *f=fopen(filename, "w");
2667 if (f==NULL)
2668 return;
2669 writeString(f, "gmon");
2670 writeLong(f, 0x00000001); /* Version */
2671 writeLong(f, 0); /* padding */
2672 writeLong(f, 0); /* padding */
2673 writeLong(f, 0); /* padding */
2674
2675 u8 zero = 0; /* GMON_TAG_TIME_HIST */
2676 writeData(f, &zero, 1);
2677
2678 /* figure out bucket size */
2679 u32 min=samples[0];
2680 u32 max=samples[0];
2681 for (i=0; i<sampleNum; i++)
2682 {
2683 if (min>samples[i])
2684 {
2685 min=samples[i];
2686 }
2687 if (max<samples[i])
2688 {
2689 max=samples[i];
2690 }
2691 }
2692
2693 int addressSpace=(max-min+1);
2694
2695 static const u32 maxBuckets = 256 * 1024; /* maximum buckets. */
2696 u32 length = addressSpace;
2697 if (length > maxBuckets)
2698 {
2699 length=maxBuckets;
2700 }
2701 int *buckets=malloc(sizeof(int)*length);
2702 if (buckets==NULL)
2703 {
2704 fclose(f);
2705 return;
2706 }
2707 memset(buckets, 0, sizeof(int)*length);
2708 for (i=0; i<sampleNum;i++)
2709 {
2710 u32 address=samples[i];
2711 long long a=address-min;
2712 long long b=length-1;
2713 long long c=addressSpace-1;
2714 int index=(a*b)/c; /* danger!!!! int32 overflows */
2715 buckets[index]++;
2716 }
2717
2718 /* append binary memory gmon.out &profile_hist_hdr ((char*)&profile_hist_hdr + sizeof(struct gmon_hist_hdr)) */
2719 writeLong(f, min); /* low_pc */
2720 writeLong(f, max); /* high_pc */
2721 writeLong(f, length); /* # of samples */
2722 writeLong(f, 64000000); /* 64MHz */
2723 writeString(f, "seconds");
2724 for (i=0; i<(15-strlen("seconds")); i++)
2725 writeData(f, &zero, 1);
2726 writeString(f, "s");
2727
2728 /*append binary memory gmon.out profile_hist_data (profile_hist_data + profile_hist_hdr.hist_size) */
2729
2730 char *data=malloc(2*length);
2731 if (data!=NULL)
2732 {
2733 for (i=0; i<length;i++)
2734 {
2735 int val;
2736 val=buckets[i];
2737 if (val>65535)
2738 {
2739 val=65535;
2740 }
2741 data[i*2]=val&0xff;
2742 data[i*2+1]=(val>>8)&0xff;
2743 }
2744 free(buckets);
2745 writeData(f, data, length * 2);
2746 free(data);
2747 } else
2748 {
2749 free(buckets);
2750 }
2751
2752 fclose(f);
2753 }
2754
2755 /* profiling samples the CPU PC as quickly as OpenOCD is able, which will be used as a random sampling of PC */
2756 static int handle_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2757 {
2758 target_t *target = get_current_target(cmd_ctx);
2759 struct timeval timeout, now;
2760
2761 gettimeofday(&timeout, NULL);
2762 if (argc!=2)
2763 {
2764 return ERROR_COMMAND_SYNTAX_ERROR;
2765 }
2766 char *end;
2767 timeval_add_time(&timeout, strtoul(args[0], &end, 0), 0);
2768 if (*end)
2769 {
2770 return ERROR_OK;
2771 }
2772
2773 command_print(cmd_ctx, "Starting profiling. Halting and resuming the target as often as we can...");
2774
2775 static const int maxSample=10000;
2776 u32 *samples=malloc(sizeof(u32)*maxSample);
2777 if (samples==NULL)
2778 return ERROR_OK;
2779
2780 int numSamples=0;
2781 int retval=ERROR_OK;
2782 /* hopefully it is safe to cache! We want to stop/restart as quickly as possible. */
2783 reg_t *reg = register_get_by_name(target->reg_cache, "pc", 1);
2784
2785 for (;;)
2786 {
2787 target_poll(target);
2788 if (target->state == TARGET_HALTED)
2789 {
2790 u32 t=*((u32 *)reg->value);
2791 samples[numSamples++]=t;
2792 retval = target_resume(target, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */
2793 target_poll(target);
2794 alive_sleep(10); /* sleep 10ms, i.e. <100 samples/second. */
2795 } else if (target->state == TARGET_RUNNING)
2796 {
2797 /* We want to quickly sample the PC. */
2798 if((retval = target_halt(target)) != ERROR_OK)
2799 {
2800 free(samples);
2801 return retval;
2802 }
2803 } else
2804 {
2805 command_print(cmd_ctx, "Target not halted or running");
2806 retval=ERROR_OK;
2807 break;
2808 }
2809 if (retval!=ERROR_OK)
2810 {
2811 break;
2812 }
2813
2814 gettimeofday(&now, NULL);
2815 if ((numSamples>=maxSample) || ((now.tv_sec >= timeout.tv_sec) && (now.tv_usec >= timeout.tv_usec)))
2816 {
2817 command_print(cmd_ctx, "Profiling completed. %d samples.", numSamples);
2818 if((retval = target_poll(target)) != ERROR_OK)
2819 {
2820 free(samples);
2821 return retval;
2822 }
2823 if (target->state == TARGET_HALTED)
2824 {
2825 target_resume(target, 1, 0, 0, 0); /* current pc, addr = 0, do not handle breakpoints, not debugging */
2826 }
2827 if((retval = target_poll(target)) != ERROR_OK)
2828 {
2829 free(samples);
2830 return retval;
2831 }
2832 writeGmon(samples, numSamples, args[1]);
2833 command_print(cmd_ctx, "Wrote %s", args[1]);
2834 break;
2835 }
2836 }
2837 free(samples);
2838
2839 return ERROR_OK;
2840 }
2841
2842 static int new_int_array_element(Jim_Interp * interp, const char *varname, int idx, u32 val)
2843 {
2844 char *namebuf;
2845 Jim_Obj *nameObjPtr, *valObjPtr;
2846 int result;
2847
2848 namebuf = alloc_printf("%s(%d)", varname, idx);
2849 if (!namebuf)
2850 return JIM_ERR;
2851
2852 nameObjPtr = Jim_NewStringObj(interp, namebuf, -1);
2853 valObjPtr = Jim_NewIntObj(interp, val);
2854 if (!nameObjPtr || !valObjPtr)
2855 {
2856 free(namebuf);
2857 return JIM_ERR;
2858 }
2859
2860 Jim_IncrRefCount(nameObjPtr);
2861 Jim_IncrRefCount(valObjPtr);
2862 result = Jim_SetVariable(interp, nameObjPtr, valObjPtr);
2863 Jim_DecrRefCount(interp, nameObjPtr);
2864 Jim_DecrRefCount(interp, valObjPtr);
2865 free(namebuf);
2866 /* printf("%s(%d) <= 0%08x\n", varname, idx, val); */
2867 return result;
2868 }
2869
2870 static int jim_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
2871 {
2872 command_context_t *context;
2873 target_t *target;
2874
2875 context = Jim_GetAssocData(interp, "context");
2876 if (context == NULL)
2877 {
2878 LOG_ERROR("mem2array: no command context");
2879 return JIM_ERR;
2880 }
2881 target = get_current_target(context);
2882 if (target == NULL)
2883 {
2884 LOG_ERROR("mem2array: no current target");
2885 return JIM_ERR;
2886 }
2887
2888 return target_mem2array(interp, target, argc-1, argv+1);
2889 }
2890
2891 static int target_mem2array(Jim_Interp *interp, target_t *target, int argc, Jim_Obj *const *argv)
2892 {
2893 long l;
2894 u32 width;
2895 int len;
2896 u32 addr;
2897 u32 count;
2898 u32 v;
2899 const char *varname;
2900 u8 buffer[4096];
2901 int n, e, retval;
2902 u32 i;
2903
2904 /* argv[1] = name of array to receive the data
2905 * argv[2] = desired width
2906 * argv[3] = memory address
2907 * argv[4] = count of times to read
2908 */
2909 if (argc != 4) {
2910 Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems");
2911 return JIM_ERR;
2912 }
2913 varname = Jim_GetString(argv[0], &len);
2914 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
2915
2916 e = Jim_GetLong(interp, argv[1], &l);
2917 width = l;
2918 if (e != JIM_OK) {
2919 return e;
2920 }
2921
2922 e = Jim_GetLong(interp, argv[2], &l);
2923 addr = l;
2924 if (e != JIM_OK) {
2925 return e;
2926 }
2927 e = Jim_GetLong(interp, argv[3], &l);
2928 len = l;
2929 if (e != JIM_OK) {
2930 return e;
2931 }
2932 switch (width) {
2933 case 8:
2934 width = 1;
2935 break;
2936 case 16:
2937 width = 2;
2938 break;
2939 case 32:
2940 width = 4;
2941 break;
2942 default:
2943 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2944 Jim_AppendStrings( interp, Jim_GetResult(interp), "Invalid width param, must be 8/16/32", NULL );
2945 return JIM_ERR;
2946 }
2947 if (len == 0) {
2948 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2949 Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: zero width read?", NULL);
2950 return JIM_ERR;
2951 }
2952 if ((addr + (len * width)) < addr) {
2953 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2954 Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: addr + len - wraps to zero?", NULL);
2955 return JIM_ERR;
2956 }
2957 /* absurd transfer size? */
2958 if (len > 65536) {
2959 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2960 Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: absurd > 64K item request", NULL);
2961 return JIM_ERR;
2962 }
2963
2964 if ((width == 1) ||
2965 ((width == 2) && ((addr & 1) == 0)) ||
2966 ((width == 4) && ((addr & 3) == 0))) {
2967 /* all is well */
2968 } else {
2969 char buf[100];
2970 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2971 sprintf(buf, "mem2array address: 0x%08x is not aligned for %d byte reads", addr, width);
2972 Jim_AppendStrings(interp, Jim_GetResult(interp), buf , NULL);
2973 return JIM_ERR;
2974 }
2975
2976 /* Transfer loop */
2977
2978 /* index counter */
2979 n = 0;
2980 /* assume ok */
2981 e = JIM_OK;
2982 while (len) {
2983 /* Slurp... in buffer size chunks */
2984
2985 count = len; /* in objects.. */
2986 if (count > (sizeof(buffer)/width)) {
2987 count = (sizeof(buffer)/width);
2988 }
2989
2990 retval = target_read_memory( target, addr, width, count, buffer );
2991 if (retval != ERROR_OK) {
2992 /* BOO !*/
2993 LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed", addr, width, count);
2994 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
2995 Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: cannot read memory", NULL);
2996 e = JIM_ERR;
2997 len = 0;
2998 } else {
2999 v = 0; /* shut up gcc */
3000 for (i = 0 ;i < count ;i++, n++) {
3001 switch (width) {
3002 case 4:
3003 v = target_buffer_get_u32(target, &buffer[i*width]);
3004 break;
3005 case 2:
3006 v = target_buffer_get_u16(target, &buffer[i*width]);
3007 break;
3008 case 1:
3009 v = buffer[i] & 0x0ff;
3010 break;
3011 }
3012 new_int_array_element(interp, varname, n, v);
3013 }
3014 len -= count;
3015 }
3016 }
3017
3018 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
3019
3020 return JIM_OK;
3021 }
3022
3023 static int get_int_array_element(Jim_Interp * interp, const char *varname, int idx, u32 *val)
3024 {
3025 char *namebuf;
3026 Jim_Obj *nameObjPtr, *valObjPtr;
3027 int result;
3028 long l;
3029
3030 namebuf = alloc_printf("%s(%d)", varname, idx);
3031 if (!namebuf)
3032 return JIM_ERR;
3033
3034 nameObjPtr = Jim_NewStringObj(interp, namebuf, -1);
3035 if (!nameObjPtr)
3036 {
3037 free(namebuf);
3038 return JIM_ERR;
3039 }
3040
3041 Jim_IncrRefCount(nameObjPtr);
3042 valObjPtr = Jim_GetVariable(interp, nameObjPtr, JIM_ERRMSG);
3043 Jim_DecrRefCount(interp, nameObjPtr);
3044 free(namebuf);
3045 if (valObjPtr == NULL)
3046 return JIM_ERR;
3047
3048 result = Jim_GetLong(interp, valObjPtr, &l);
3049 /* printf("%s(%d) => 0%08x\n", varname, idx, val); */
3050 *val = l;
3051 return result;
3052 }
3053
3054 static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
3055 {
3056 command_context_t *context;
3057 target_t *target;
3058
3059 context = Jim_GetAssocData(interp, "context");
3060 if (context == NULL){
3061 LOG_ERROR("array2mem: no command context");
3062 return JIM_ERR;
3063 }
3064 target = get_current_target(context);
3065 if (target == NULL){
3066 LOG_ERROR("array2mem: no current target");
3067 return JIM_ERR;
3068 }
3069
3070 return target_array2mem( interp,target, argc-1, argv+1 );
3071 }
3072
3073 static int target_array2mem(Jim_Interp *interp, target_t *target, int argc, Jim_Obj *const *argv)
3074 {
3075 long l;
3076 u32 width;
3077 int len;
3078 u32 addr;
3079 u32 count;
3080 u32 v;
3081 const char *varname;
3082 u8 buffer[4096];
3083 int n, e, retval;
3084 u32 i;
3085
3086 /* argv[1] = name of array to get the data
3087 * argv[2] = desired width
3088 * argv[3] = memory address
3089 * argv[4] = count to write
3090 */
3091 if (argc != 4) {
3092 Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems");
3093 return JIM_ERR;
3094 }
3095 varname = Jim_GetString(argv[0], &len);
3096 /* given "foo" get space for worse case "foo(%d)" .. add 20 */
3097
3098 e = Jim_GetLong(interp, argv[1], &l);
3099 width = l;
3100 if (e != JIM_OK) {
3101 return e;
3102 }
3103
3104 e = Jim_GetLong(interp, argv[2], &l);
3105 addr = l;
3106 if (e != JIM_OK) {
3107 return e;
3108 }
3109 e = Jim_GetLong(interp, argv[3], &l);
3110 len = l;
3111 if (e != JIM_OK) {
3112 return e;
3113 }
3114 switch (width) {
3115 case 8:
3116 width = 1;
3117 break;
3118 case 16:
3119 width = 2;
3120 break;
3121 case 32:
3122 width = 4;
3123 break;
3124 default:
3125 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
3126 Jim_AppendStrings( interp, Jim_GetResult(interp), "Invalid width param, must be 8/16/32", NULL );
3127 return JIM_ERR;
3128 }
3129 if (len == 0) {
3130 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
3131 Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: zero width read?", NULL);
3132 return JIM_ERR;
3133 }
3134 if ((addr + (len * width)) < addr) {
3135 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
3136 Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: addr + len - wraps to zero?", NULL);
3137 return JIM_ERR;
3138 }
3139 /* absurd transfer size? */
3140 if (len > 65536) {
3141 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
3142 Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: absurd > 64K item request", NULL);
3143 return JIM_ERR;
3144 }
3145
3146 if ((width == 1) ||
3147 ((width == 2) && ((addr & 1) == 0)) ||
3148 ((width == 4) && ((addr & 3) == 0))) {
3149 /* all is well */
3150 } else {
3151 char buf[100];
3152 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
3153 sprintf(buf, "array2mem address: 0x%08x is not aligned for %d byte reads", addr, width);
3154 Jim_AppendStrings(interp, Jim_GetResult(interp), buf , NULL);
3155 return JIM_ERR;
3156 }
3157
3158 /* Transfer loop */
3159
3160 /* index counter */
3161 n = 0;
3162 /* assume ok */
3163 e = JIM_OK;
3164 while (len) {
3165 /* Slurp... in buffer size chunks */
3166
3167 count = len; /* in objects.. */
3168 if (count > (sizeof(buffer)/width)) {
3169 count = (sizeof(buffer)/width);
3170 }
3171
3172 v = 0; /* shut up gcc */
3173 for (i = 0 ;i < count ;i++, n++) {
3174 get_int_array_element(interp, varname, n, &v);
3175 switch (width) {
3176 case 4:
3177 target_buffer_set_u32(target, &buffer[i*width], v);
3178 break;
3179 case 2:
3180 target_buffer_set_u16(target, &buffer[i*width], v);
3181 break;
3182 case 1:
3183 buffer[i] = v & 0x0ff;
3184 break;
3185 }
3186 }
3187 len -= count;
3188
3189 retval = target_write_memory(target, addr, width, count, buffer);
3190 if (retval != ERROR_OK) {
3191 /* BOO !*/
3192 LOG_ERROR("array2mem: Write @ 0x%08x, w=%d, cnt=%d, failed", addr, width, count);
3193 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
3194 Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: cannot read memory", NULL);
3195 e = JIM_ERR;
3196 len = 0;
3197 }
3198 }
3199
3200 Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
3201
3202 return JIM_OK;
3203 }
3204
3205 void target_all_handle_event( enum target_event e )
3206 {
3207 target_t *target;
3208
3209 LOG_DEBUG( "**all*targets: event: %d, %s",
3210 e,
3211 Jim_Nvp_value2name_simple( nvp_target_event, e )->name );
3212
3213 target = all_targets;
3214 while (target){
3215 target_handle_event( target, e );
3216 target = target->next;
3217 }
3218 }
3219
3220 void target_handle_event( target_t *target, enum target_event e )
3221 {
3222 target_event_action_t *teap;
3223 int done;
3224
3225 teap = target->event_action;
3226
3227 done = 0;
3228 while( teap ){
3229 if( teap->event == e ){
3230 done = 1;
3231 LOG_DEBUG( "target: (%d) %s (%s) event: %d (%s) action: %s\n",
3232 target->target_number,
3233 target->cmd_name,
3234 target_get_name(target),
3235 e,
3236 Jim_Nvp_value2name_simple( nvp_target_event, e )->name,
3237 Jim_GetString( teap->body, NULL ) );
3238 if (Jim_EvalObj( interp, teap->body )!=JIM_OK)
3239 {
3240 Jim_PrintErrorMessage(interp);
3241 }
3242 }
3243 teap = teap->next;
3244 }
3245 if( !done ){
3246 LOG_DEBUG( "event: %d %s - no action",
3247 e,
3248 Jim_Nvp_value2name_simple( nvp_target_event, e )->name );
3249 }
3250 }
3251
3252 enum target_cfg_param {
3253 TCFG_TYPE,
3254 TCFG_EVENT,
3255 TCFG_WORK_AREA_VIRT,
3256 TCFG_WORK_AREA_PHYS,
3257 TCFG_WORK_AREA_SIZE,
3258 TCFG_WORK_AREA_BACKUP,
3259 TCFG_ENDIAN,
3260 TCFG_VARIANT,
3261 TCFG_CHAIN_POSITION,
3262 };
3263
3264 static Jim_Nvp nvp_config_opts[] = {
3265 { .name = "-type", .value = TCFG_TYPE },
3266 { .name = "-event", .value = TCFG_EVENT },
3267 { .name = "-work-area-virt", .value = TCFG_WORK_AREA_VIRT },
3268 { .name = "-work-area-phys", .value = TCFG_WORK_AREA_PHYS },
3269 { .name = "-work-area-size", .value = TCFG_WORK_AREA_SIZE },
3270 { .name = "-work-area-backup", .value = TCFG_WORK_AREA_BACKUP },
3271 { .name = "-endian" , .value = TCFG_ENDIAN },
3272 { .name = "-variant", .value = TCFG_VARIANT },
3273 { .name = "-chain-position", .value = TCFG_CHAIN_POSITION },
3274
3275 { .name = NULL, .value = -1 }
3276 };
3277
3278 static int target_configure( Jim_GetOptInfo *goi, target_t *target )
3279 {
3280 Jim_Nvp *n;
3281 Jim_Obj *o;
3282 jim_wide w;
3283 char *cp;
3284 int e;
3285
3286 /* parse config or cget options ... */
3287 while( goi->argc > 0 ){
3288 Jim_SetEmptyResult( goi->interp );
3289 /* Jim_GetOpt_Debug( goi ); */
3290
3291 if( target->type->target_jim_configure ){
3292 /* target defines a configure function */
3293 /* target gets first dibs on parameters */
3294 e = (*(target->type->target_jim_configure))( target, goi );
3295 if( e == JIM_OK ){
3296 /* more? */
3297 continue;
3298 }
3299 if( e == JIM_ERR ){
3300 /* An error */
3301 return e;
3302 }
3303 /* otherwise we 'continue' below */
3304 }
3305 e = Jim_GetOpt_Nvp( goi, nvp_config_opts, &n );
3306 if( e != JIM_OK ){
3307 Jim_GetOpt_NvpUnknown( goi, nvp_config_opts, 0 );
3308 return e;
3309 }
3310 switch( n->value ){
3311 case TCFG_TYPE:
3312 /* not setable */
3313 if( goi->isconfigure ){
3314 Jim_SetResult_sprintf( goi->interp, "not setable: %s", n->name );
3315 return JIM_ERR;
3316 } else {
3317 no_params:
3318 if( goi->argc != 0 ){
3319 Jim_WrongNumArgs( goi->interp, goi->argc, goi->argv, "NO PARAMS");
3320 return JIM_ERR;
3321 }
3322 }
3323 Jim_SetResultString( goi->interp, target_get_name(target), -1 );
3324 /* loop for more */
3325 break;
3326 case TCFG_EVENT:
3327 if( goi->argc == 0 ){
3328 Jim_WrongNumArgs( goi->interp, goi->argc, goi->argv, "-event ?event-name? ...");
3329 return JIM_ERR;
3330 }
3331
3332 e = Jim_GetOpt_Nvp( goi, nvp_target_event, &n );
3333 if( e != JIM_OK ){
3334 Jim_GetOpt_NvpUnknown( goi, nvp_target_event, 1 );
3335 return e;
3336 }
3337
3338 if( goi->isconfigure ){
3339 if( goi->argc != 1 ){
3340 Jim_WrongNumArgs( goi->interp, goi->argc, goi->argv, "-event ?event-name? ?EVENT-BODY?");
3341 return JIM_ERR;
3342 }
3343 } else {
3344 if( goi->argc != 0 ){
3345 Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ?event-name?");
3346 return JIM_ERR;
3347 }
3348 }
3349
3350 {
3351 target_event_action_t *teap;
3352
3353 teap = target->event_action;
3354 /* replace existing? */
3355 while( teap ){
3356 if( teap->event == (enum target_event)n->value ){
3357 break;
3358 }
3359 teap = teap->next;
3360 }
3361
3362 if( goi->isconfigure ){
3363 if( teap == NULL ){
3364 /* create new */
3365 teap = calloc( 1, sizeof(*teap) );
3366 }
3367 teap->event = n->value;
3368 Jim_GetOpt_Obj( goi, &o );
3369 if( teap->body ){
3370 Jim_DecrRefCount( interp, teap->body );
3371 }
3372 teap->body = Jim_DuplicateObj( goi->interp, o );
3373 /*
3374 * FIXME:
3375 * Tcl/TK - "tk events" have a nice feature.
3376 * See the "BIND" command.
3377 * We should support that here.
3378 * You can specify %X and %Y in the event code.
3379 * The idea is: %T - target name.
3380 * The idea is: %N - target number
3381 * The idea is: %E - event name.
3382 */
3383 Jim_IncrRefCount( teap->body );
3384
3385 /* add to head of event list */
3386 teap->next = target->event_action;
3387 target->event_action = teap;
3388 Jim_SetEmptyResult(goi->interp);
3389 } else {
3390 /* get */
3391 if( teap == NULL ){
3392 Jim_SetEmptyResult( goi->interp );
3393 } else {
3394 Jim_SetResult( goi->interp, Jim_DuplicateObj( goi->interp, teap->body ) );
3395 }
3396 }
3397 }
3398 /* loop for more */
3399 break;
3400
3401 case TCFG_WORK_AREA_VIRT:
3402 if( goi->isconfigure ){
3403 target_free_all_working_areas(target);
3404 e = Jim_GetOpt_Wide( goi, &w );
3405 if( e != JIM_OK ){
3406 return e;
3407 }
3408 target->working_area_virt = w;
3409 } else {
3410 if( goi->argc != 0 ){
3411 goto no_params;
3412 }
3413 }
3414 Jim_SetResult( interp, Jim_NewIntObj( goi->interp, target->working_area_virt ) );
3415 /* loop for more */
3416 break;
3417
3418 case TCFG_WORK_AREA_PHYS:
3419 if( goi->isconfigure ){
3420 target_free_all_working_areas(target);
3421 e = Jim_GetOpt_Wide( goi, &w );
3422 if( e != JIM_OK ){
3423 return e;
3424 }
3425 target->working_area_phys = w;
3426 } else {
3427 if( goi->argc != 0 ){
3428 goto no_params;
3429 }
3430 }
3431 Jim_SetResult( interp, Jim_NewIntObj( goi->interp, target->working_area_phys ) );
3432 /* loop for more */
3433 break;
3434
3435 case TCFG_WORK_AREA_SIZE:
3436 if( goi->isconfigure ){
3437 target_free_all_working_areas(target);
3438 e = Jim_GetOpt_Wide( goi, &w );
3439 if( e != JIM_OK ){
3440 return e;
3441 }
3442 target->working_area_size = w;
3443 } else {
3444 if( goi->argc != 0 ){
3445 goto no_params;
3446 }
3447 }
3448 Jim_SetResult( interp, Jim_NewIntObj( goi->interp, target->working_area_size ) );
3449 /* loop for more */
3450 break;
3451
3452 case TCFG_WORK_AREA_BACKUP:
3453 if( goi->isconfigure ){
3454 target_free_all_working_areas(target);
3455 e = Jim_GetOpt_Wide( goi, &w );
3456 if( e != JIM_OK ){
3457 return e;
3458 }
3459 /* make this exactly 1 or 0 */
3460 target->backup_working_area = (!!w);
3461 } else {
3462 if( goi->argc != 0 ){
3463 goto no_params;
3464 }
3465 }
3466 Jim_SetResult(interp, Jim_NewIntObj(goi->interp, target->backup_working_area));
3467 /* loop for more e*/
3468 break;
3469
3470 case TCFG_ENDIAN:
3471 if( goi->isconfigure ){
3472 e = Jim_GetOpt_Nvp( goi, nvp_target_endian, &n );
3473 if( e != JIM_OK ){
3474 Jim_GetOpt_NvpUnknown( goi, nvp_target_endian, 1 );
3475 return e;
3476 }
3477 target->endianness = n->value;
3478 } else {
3479 if( goi->argc != 0 ){
3480 goto no_params;
3481 }
3482 }
3483 n = Jim_Nvp_value2name_simple( nvp_target_endian, target->endianness );
3484 if( n->name == NULL ){
3485 target->endianness = TARGET_LITTLE_ENDIAN;
3486 n = Jim_Nvp_value2name_simple( nvp_target_endian, target->endianness );
3487 }
3488 Jim_SetResultString( goi->interp, n->name, -1 );
3489 /* loop for more */
3490 break;
3491
3492 case TCFG_VARIANT:
3493 if( goi->isconfigure ){
3494 if( goi->argc < 1 ){
3495 Jim_SetResult_sprintf( goi->interp,
3496 "%s ?STRING?",
3497 n->name );
3498 return JIM_ERR;
3499 }
3500 if( target->variant ){
3501 free((void *)(target->variant));
3502 }
3503 e = Jim_GetOpt_String( goi, &cp, NULL );
3504 target->variant = strdup(cp);
3505 } else {
3506 if( goi->argc != 0 ){
3507 goto no_params;
3508 }
3509 }
3510 Jim_SetResultString( goi->interp, target->variant,-1 );
3511 /* loop for more */
3512 break;
3513 case TCFG_CHAIN_POSITION:
3514 if( goi->isconfigure ){
3515 Jim_Obj *o;
3516 jtag_tap_t *tap;
3517 target_free_all_working_areas(target);
3518 e = Jim_GetOpt_Obj( goi, &o );
3519 if( e != JIM_OK ){
3520 return e;
3521 }
3522 tap = jtag_tap_by_jim_obj( goi->interp, o );
3523 if( tap == NULL ){
3524 return JIM_ERR;
3525 }
3526 /* make this exactly 1 or 0 */
3527 target->tap = tap;
3528 } else {
3529 if( goi->argc != 0 ){
3530 goto no_params;
3531 }
3532 }
3533 Jim_SetResultString( interp, target->tap->dotted_name, -1 );
3534 /* loop for more e*/
3535 break;
3536 }
3537 } /* while( goi->argc ) */
3538
3539
3540 /* done - we return */
3541 return JIM_OK;
3542 }
3543
3544 /** this is the 'tcl' handler for the target specific command */
3545 static int tcl_target_func( Jim_Interp *interp, int argc, Jim_Obj *const *argv )
3546 {
3547 Jim_GetOptInfo goi;
3548 jim_wide a,b,c;
3549 int x,y,z;
3550 u8 target_buf[32];
3551 Jim_Nvp *n;
3552 target_t *target;
3553 struct command_context_s *cmd_ctx;
3554 int e;
3555
3556 enum {
3557 TS_CMD_CONFIGURE,
3558 TS_CMD_CGET,
3559
3560 TS_CMD_MWW, TS_CMD_MWH, TS_CMD_MWB,
3561 TS_CMD_MDW, TS_CMD_MDH, TS_CMD_MDB,
3562 TS_CMD_MRW, TS_CMD_MRH, TS_CMD_MRB,
3563 TS_CMD_MEM2ARRAY, TS_CMD_ARRAY2MEM,
3564 TS_CMD_EXAMINE,
3565 TS_CMD_POLL,
3566 TS_CMD_RESET,
3567 TS_CMD_HALT,
3568 TS_CMD_WAITSTATE,
3569 TS_CMD_EVENTLIST,
3570 TS_CMD_CURSTATE,
3571 TS_CMD_INVOKE_EVENT,
3572 };
3573
3574 static const Jim_Nvp target_options[] = {
3575 { .name = "configure", .value = TS_CMD_CONFIGURE },
3576 { .name = "cget", .value = TS_CMD_CGET },
3577 { .name = "mww", .value = TS_CMD_MWW },
3578 { .name = "mwh", .value = TS_CMD_MWH },
3579 { .name = "mwb", .value = TS_CMD_MWB },
3580 { .name = "mdw", .value = TS_CMD_MDW },
3581 { .name = "mdh", .value = TS_CMD_MDH },
3582 { .name = "mdb", .value = TS_CMD_MDB },
3583 { .name = "mem2array", .value = TS_CMD_MEM2ARRAY },
3584 { .name = "array2mem", .value = TS_CMD_ARRAY2MEM },
3585 { .name = "eventlist", .value = TS_CMD_EVENTLIST },
3586 { .name = "curstate", .value = TS_CMD_CURSTATE },
3587
3588 { .name = "arp_examine", .value = TS_CMD_EXAMINE },
3589 { .name = "arp_poll", .value = TS_CMD_POLL },
3590 { .name = "arp_reset", .value = TS_CMD_RESET },
3591 { .name = "arp_halt", .value = TS_CMD_HALT },
3592 { .name = "arp_waitstate", .value = TS_CMD_WAITSTATE },
3593 { .name = "invoke-event", .value = TS_CMD_INVOKE_EVENT },
3594
3595 { .name = NULL, .value = -1 },
3596 };
3597
3598 /* go past the "command" */
3599 Jim_GetOpt_Setup( &goi, interp, argc-1, argv+1 );
3600
3601 target = Jim_CmdPrivData( goi.interp );
3602 cmd_ctx = Jim_GetAssocData(goi.interp, "context");
3603
3604 /* commands here are in an NVP table */
3605 e = Jim_GetOpt_Nvp( &goi, target_options, &n );
3606 if( e != JIM_OK ){
3607 Jim_GetOpt_NvpUnknown( &goi, target_options, 0 );
3608 return e;
3609 }
3610 /* Assume blank result */
3611 Jim_SetEmptyResult( goi.interp );
3612
3613 switch( n->value ){
3614 case TS_CMD_CONFIGURE:
3615 if( goi.argc < 2 ){
3616 Jim_WrongNumArgs( goi.interp, goi.argc, goi.argv, "missing: -option VALUE ...");
3617 return JIM_ERR;
3618 }
3619 goi.isconfigure = 1;
3620 return target_configure( &goi, target );
3621 case TS_CMD_CGET:
3622 // some things take params
3623 if( goi.argc < 1 ){
3624 Jim_WrongNumArgs( goi.interp, 0, goi.argv, "missing: ?-option?");
3625 return JIM_ERR;
3626 }
3627 goi.isconfigure = 0;
3628 return target_configure( &goi, target );
3629 break;
3630 case TS_CMD_MWW:
3631 case TS_CMD_MWH:
3632 case TS_CMD_MWB:
3633 /* argv[0] = cmd
3634 * argv[1] = address
3635 * argv[2] = data
3636 * argv[3] = optional count.
3637 */
3638
3639 if( (goi.argc == 3) || (goi.argc == 4) ){
3640 /* all is well */
3641 } else {
3642 mwx_error:
3643 Jim_SetResult_sprintf( goi.interp, "expected: %s ADDR DATA [COUNT]", n->name );
3644 return JIM_ERR;
3645 }
3646
3647 e = Jim_GetOpt_Wide( &goi, &a );
3648 if( e != JIM_OK ){
3649 goto mwx_error;
3650 }
3651
3652 e = Jim_GetOpt_Wide( &goi, &b );
3653 if( e != JIM_OK ){
3654 goto mwx_error;
3655 }
3656 if( goi.argc ){
3657 e = Jim_GetOpt_Wide( &goi, &c );
3658 if( e != JIM_OK ){
3659 goto mwx_error;
3660 }
3661 } else {
3662 c = 1;
3663 }
3664
3665 switch( n->value ){
3666 case TS_CMD_MWW:
3667 target_buffer_set_u32( target, target_buf, b );
3668 b = 4;
3669 break;
3670 case TS_CMD_MWH:
3671 target_buffer_set_u16( target, target_buf, b );
3672 b = 2;
3673 break;
3674 case TS_CMD_MWB:
3675 target_buffer_set_u8( target, target_buf, b );
3676 b = 1;
3677 break;
3678 }
3679 for( x = 0 ; x < c ; x++ ){
3680 e = target_write_memory( target, a, b, 1, target_buf );
3681 if( e != ERROR_OK ){
3682 Jim_SetResult_sprintf( interp, "Error writing @ 0x%08x: %d\n", (int)(a), e );
3683 return JIM_ERR;
3684 }
3685 /* b = width */
3686 a = a + b;
3687 }
3688 return JIM_OK;
3689 break;
3690
3691 /* display */
3692 case TS_CMD_MDW:
3693 case TS_CMD_MDH:
3694 case TS_CMD_MDB:
3695 /* argv[0] = command
3696 * argv[1] = address
3697 * argv[2] = optional count
3698 */
3699 if( (goi.argc == 2) || (goi.argc == 3) ){
3700 Jim_SetResult_sprintf( goi.interp, "expected: %s ADDR [COUNT]", n->name );
3701 return JIM_ERR;
3702 }
3703 e = Jim_GetOpt_Wide( &goi, &a );
3704 if( e != JIM_OK ){
3705 return JIM_ERR;
3706 }
3707 if( goi.argc ){
3708 e = Jim_GetOpt_Wide( &goi, &c );
3709 if( e != JIM_OK ){
3710 return JIM_ERR;
3711 }
3712 } else {
3713 c = 1;
3714 }
3715 b = 1; /* shut up gcc */
3716 switch( n->value ){
3717 case TS_CMD_MDW:
3718 b = 4;
3719 break;
3720 case TS_CMD_MDH:
3721 b = 2;
3722 break;
3723 case TS_CMD_MDB:
3724 b = 1;
3725 break;
3726 }
3727
3728 /* convert to "bytes" */
3729 c = c * b;
3730 /* count is now in 'BYTES' */
3731 while( c > 0 ){
3732 y = c;
3733 if( y > 16 ){
3734 y = 16;
3735 }
3736 e = target_read_memory( target, a, b, y / b, target_buf );
3737 if( e != ERROR_OK ){
3738 Jim_SetResult_sprintf( interp, "error reading target @ 0x%08lx", (int)(a) );
3739 return JIM_ERR;
3740 }
3741
3742 Jim_fprintf( interp, interp->cookie_stdout, "0x%08x ", (int)(a) );
3743 switch( b ){
3744 case 4:
3745 for( x = 0 ; (x < 16) && (x < y) ; x += 4 ){
3746 z = target_buffer_get_u32( target, &(target_buf[ x * 4 ]) );
3747 Jim_fprintf( interp, interp->cookie_stdout, "%08x ", (int)(z) );
3748 }
3749 for( ; (x < 16) ; x += 4 ){
3750 Jim_fprintf( interp, interp->cookie_stdout, " " );
3751 }
3752 break;
3753 case 2:
3754 for( x = 0 ; (x < 16) && (x < y) ; x += 2 ){
3755 z = target_buffer_get_u16( target, &(target_buf[ x * 2 ]) );
3756 Jim_fprintf( interp, interp->cookie_stdout, "%04x ", (int)(z) );
3757 }
3758 for( ; (x < 16) ; x += 2 ){
3759 Jim_fprintf( interp, interp->cookie_stdout, " " );
3760 }
3761 break;
3762 case 1:
3763 default:
3764 for( x = 0 ; (x < 16) && (x < y) ; x += 1 ){
3765 z = target_buffer_get_u8( target, &(target_buf[ x * 4 ]) );
3766 Jim_fprintf( interp, interp->cookie_stdout, "%02x ", (int)(z) );
3767 }
3768 for( ; (x < 16) ; x += 1 ){
3769 Jim_fprintf( interp, interp->cookie_stdout, " " );
3770 }
3771 break;
3772 }
3773 /* ascii-ify the bytes */
3774 for( x = 0 ; x < y ; x++ ){
3775 if( (target_buf[x] >= 0x20) &&
3776 (target_buf[x] <= 0x7e) ){
3777 /* good */
3778 } else {
3779 /* smack it */
3780 target_buf[x] = '.';
3781 }
3782 }
3783 /* space pad */
3784 while( x < 16 ){
3785 target_buf[x] = ' ';
3786 x++;
3787 }
3788 /* terminate */
3789 target_buf[16] = 0;
3790 /* print - with a newline */
3791 Jim_fprintf( interp, interp->cookie_stdout, "%s\n", target_buf );
3792 /* NEXT... */
3793 c -= 16;
3794 a += 16;
3795 }
3796 return JIM_OK;
3797 case TS_CMD_MEM2ARRAY:
3798 return target_mem2array( goi.interp, target, goi.argc, goi.argv );
3799 break;
3800 case TS_CMD_ARRAY2MEM:
3801 return target_array2mem( goi.interp, target, goi.argc, goi.argv );
3802 break;
3803 case TS_CMD_EXAMINE:
3804 if( goi.argc ){
3805 Jim_WrongNumArgs( goi.interp, 2, argv, "[no parameters]");
3806 return JIM_ERR;
3807 }
3808 if (!target->tap->enabled)
3809 goto err_tap_disabled;
3810 e = target->type->examine( target );
3811 if( e != ERROR_OK ){
3812 Jim_SetResult_sprintf( interp, "examine-fails: %d", e );
3813 return JIM_ERR;
3814 }
3815 return JIM_OK;
3816 case TS_CMD_POLL:
3817 if( goi.argc ){
3818 Jim_WrongNumArgs( goi.interp, 2, argv, "[no parameters]");
3819 return JIM_ERR;
3820 }
3821 if (!target->tap->enabled)
3822 goto err_tap_disabled;
3823 if( !(target_was_examined(target)) ){
3824 e = ERROR_TARGET_NOT_EXAMINED;
3825 } else {
3826 e = target->type->poll( target );
3827 }
3828 if( e != ERROR_OK ){
3829 Jim_SetResult_sprintf( interp, "poll-fails: %d", e );
3830 return JIM_ERR;
3831 } else {
3832 return JIM_OK;
3833 }
3834 break;
3835 case TS_CMD_RESET:
3836 if( goi.argc != 2 ){
3837 Jim_WrongNumArgs( interp, 2, argv, "t|f|assert|deassert BOOL");
3838 return JIM_ERR;
3839 }
3840 e = Jim_GetOpt_Nvp( &goi, nvp_assert, &n );
3841 if( e != JIM_OK ){
3842 Jim_GetOpt_NvpUnknown( &goi, nvp_assert, 1 );
3843 return e;
3844 }
3845 /* the halt or not param */
3846 e = Jim_GetOpt_Wide( &goi, &a);
3847 if( e != JIM_OK ){
3848 return e;
3849 }
3850 if (!target->tap->enabled)
3851 goto err_tap_disabled;
3852 /* determine if we should halt or not. */
3853 target->reset_halt = !!a;
3854 /* When this happens - all workareas are invalid. */
3855 target_free_all_working_areas_restore(target, 0);
3856
3857 /* do the assert */
3858 if( n->value == NVP_ASSERT ){
3859 target->type->assert_reset( target );
3860 } else {
3861 target->type->deassert_reset( target );
3862 }
3863 return JIM_OK;
3864 case TS_CMD_HALT:
3865 if( goi.argc ){
3866 Jim_WrongNumArgs( goi.interp, 0, argv, "halt [no parameters]");
3867 return JIM_ERR;
3868 }
3869 if (!target->tap->enabled)
3870 goto err_tap_disabled;
3871 target->type->halt( target );
3872 return JIM_OK;
3873 case TS_CMD_WAITSTATE:
3874 /* params: <name> statename timeoutmsecs */
3875 if( goi.argc != 2 ){
3876 Jim_SetResult_sprintf( goi.interp, "%s STATENAME TIMEOUTMSECS", n->name );
3877 return JIM_ERR;
3878 }
3879 e = Jim_GetOpt_Nvp( &goi, nvp_target_state, &n );
3880 if( e != JIM_OK ){
3881 Jim_GetOpt_NvpUnknown( &goi, nvp_target_state,1 );
3882 return e;
3883 }
3884 e = Jim_GetOpt_Wide( &goi, &a );
3885 if( e != JIM_OK ){
3886 return e;
3887 }
3888 if (!target->tap->enabled)
3889 goto err_tap_disabled;
3890 e = target_wait_state( target, n->value, a );
3891 if( e != ERROR_OK ){
3892 Jim_SetResult_sprintf( goi.interp,
3893 "target: %s wait %s fails (%d) %s",
3894 target->cmd_name,
3895 n->name,
3896 e, target_strerror_safe(e) );
3897 return JIM_ERR;
3898 } else {
3899 return JIM_OK;
3900 }
3901 case TS_CMD_EVENTLIST:
3902 /* List for human, Events defined for this target.
3903 * scripts/programs should use 'name cget -event NAME'
3904 */
3905 {
3906 target_event_action_t *teap;
3907 teap = target->event_action;
3908 command_print( cmd_ctx, "Event actions for target (%d) %s\n",
3909 target->target_number,
3910 target->cmd_name );
3911 command_print( cmd_ctx, "%-25s | Body", "Event");
3912 command_print( cmd_ctx, "------------------------- | ----------------------------------------");
3913 while( teap ){
3914 command_print( cmd_ctx,
3915 "%-25s | %s",
3916 Jim_Nvp_value2name_simple( nvp_target_event, teap->event )->name,
3917 Jim_GetString( teap->body, NULL ) );
3918 teap = teap->next;
3919 }
3920 command_print( cmd_ctx, "***END***");
3921 return JIM_OK;
3922 }
3923 case TS_CMD_CURSTATE:
3924 if( goi.argc != 0 ){
3925 Jim_WrongNumArgs( goi.interp, 0, argv, "[no parameters]");
3926 return JIM_ERR;
3927 }
3928 Jim_SetResultString( goi.interp,
3929 Jim_Nvp_value2name_simple(nvp_target_state,target->state)->name,-1);
3930 return JIM_OK;
3931 case TS_CMD_INVOKE_EVENT:
3932 if( goi.argc != 1 ){
3933 Jim_SetResult_sprintf( goi.interp, "%s ?EVENTNAME?",n->name);
3934 return JIM_ERR;
3935 }
3936 e = Jim_GetOpt_Nvp( &goi, nvp_target_event, &n );
3937 if( e != JIM_OK ){
3938 Jim_GetOpt_NvpUnknown( &goi, nvp_target_event, 1 );
3939 return e;
3940 }
3941 target_handle_event( target, n->value );
3942 return JIM_OK;
3943 }
3944 return JIM_ERR;
3945
3946 err_tap_disabled:
3947 Jim_SetResult_sprintf(interp, "[TAP is disabled]");
3948 return JIM_ERR;
3949 }
3950
3951 static int target_create( Jim_GetOptInfo *goi )
3952 {
3953 Jim_Obj *new_cmd;
3954 Jim_Cmd *cmd;
3955 const char *cp;
3956 char *cp2;
3957 int e;
3958 int x;
3959 target_t *target;
3960 struct command_context_s *cmd_ctx;
3961
3962 cmd_ctx = Jim_GetAssocData(goi->interp, "context");
3963 if( goi->argc < 3 ){
3964 Jim_WrongNumArgs( goi->interp, 1, goi->argv, "?name? ?type? ..options...");
3965 return JIM_ERR;
3966 }
3967
3968 /* COMMAND */
3969 Jim_GetOpt_Obj( goi, &new_cmd );
3970 /* does this command exist? */
3971 cmd = Jim_GetCommand( goi->interp, new_cmd, JIM_ERRMSG );
3972 if( cmd ){
3973 cp = Jim_GetString( new_cmd, NULL );
3974 Jim_SetResult_sprintf(goi->interp, "Command/target: %s Exists", cp);
3975 return JIM_ERR;
3976 }
3977
3978 /* TYPE */
3979 e = Jim_GetOpt_String( goi, &cp2, NULL );
3980 cp = cp2;
3981 /* now does target type exist */
3982 for( x = 0 ; target_types[x] ; x++ ){
3983 if( 0 == strcmp( cp, target_types[x]->name ) ){
3984 /* found */
3985 break;
3986 }
3987 }
3988 if( target_types[x] == NULL ){
3989 Jim_SetResult_sprintf( goi->interp, "Unknown target type %s, try one of ", cp );
3990 for( x = 0 ; target_types[x] ; x++ ){
3991 if( target_types[x+1] ){
3992 Jim_AppendStrings( goi->interp,
3993 Jim_GetResult(goi->interp),
3994 target_types[x]->name,
3995 ", ", NULL);
3996 } else {
3997 Jim_AppendStrings( goi->interp,
3998 Jim_GetResult(goi->interp),
3999 " or ",
4000 target_types[x]->name,NULL );
4001 }
4002 }
4003 return JIM_ERR;
4004 }
4005
4006 /* Create it */
4007 target = calloc(1,sizeof(target_t));
4008 /* set target number */
4009 target->target_number = new_target_number();
4010
4011 /* allocate memory for each unique target type */
4012 target->type = (target_type_t*)calloc(1,sizeof(target_type_t));
4013
4014 memcpy( target->type, target_types[x], sizeof(target_type_t));
4015
4016 /* will be set by "-endian" */
4017 target->endianness = TARGET_ENDIAN_UNKNOWN;
4018
4019 target->working_area = 0x0;
4020 target->working_area_size = 0x0;
4021 target->working_areas = NULL;
4022 target->backup_working_area = 0;
4023
4024 target->state = TARGET_UNKNOWN;
4025 target->debug_reason = DBG_REASON_UNDEFINED;
4026 target->reg_cache = NULL;
4027 target->breakpoints = NULL;
4028 target->watchpoints = NULL;
4029 target->next = NULL;
4030 target->arch_info = NULL;
4031
4032 target->display = 1;
4033
4034 /* initialize trace information */
4035 target->trace_info = malloc(sizeof(trace_t));
4036 target->trace_info->num_trace_points = 0;
4037 target->trace_info->trace_points_size = 0;
4038 target->trace_info->trace_points = NULL;
4039 target->trace_info->trace_history_size = 0;
4040 target->trace_info->trace_history = NULL;
4041 target->trace_info->trace_history_pos = 0;
4042 target->trace_info->trace_history_overflowed = 0;
4043
4044 target->dbgmsg = NULL;
4045 target->dbg_msg_enabled = 0;
4046
4047 target->endianness = TARGET_ENDIAN_UNKNOWN;
4048
4049 /* Do the rest as "configure" options */
4050 goi->isconfigure = 1;
4051 e = target_configure( goi, target);
4052
4053 if (target->tap == NULL)
4054 {
4055 Jim_SetResultString( interp, "-chain-position required when creating target", -1);
4056 e=JIM_ERR;
4057 }
4058
4059 if( e != JIM_OK ){
4060 free( target->type );
4061 free( target );
4062 return e;
4063 }
4064
4065 if( target->endianness == TARGET_ENDIAN_UNKNOWN ){
4066 /* default endian to little if not specified */
4067 target->endianness = TARGET_LITTLE_ENDIAN;
4068 }
4069
4070 /* incase variant is not set */
4071 if (!target->variant)
4072 target->variant = strdup("");
4073
4074 /* create the target specific commands */
4075 if( target->type->register_commands ){
4076 (*(target->type->register_commands))( cmd_ctx );
4077 }
4078 if( target->type->target_create ){
4079 (*(target->type->target_create))( target, goi->interp );
4080 }
4081
4082 /* append to end of list */
4083 {
4084 target_t **tpp;
4085 tpp = &(all_targets);
4086 while( *tpp ){
4087 tpp = &( (*tpp)->next );
4088 }
4089 *tpp = target;
4090 }
4091
4092 cp = Jim_GetString( new_cmd, NULL );
4093 target->cmd_name = strdup(cp);
4094
4095 /* now - create the new target name command */
4096 e = Jim_CreateCommand( goi->interp,
4097 /* name */
4098 cp,
4099 tcl_target_func, /* C function */
4100 target, /* private data */
4101 NULL ); /* no del proc */
4102
4103 return e;
4104 }
4105
4106 static int jim_target( Jim_Interp *interp, int argc, Jim_Obj *const *argv )
4107 {
4108 int x,r,e;
4109 jim_wide w;
4110 struct command_context_s *cmd_ctx;
4111 target_t *target;
4112 Jim_GetOptInfo goi;
4113 enum tcmd {
4114 /* TG = target generic */
4115 TG_CMD_CREATE,
4116 TG_CMD_TYPES,
4117 TG_CMD_NAMES,
4118 TG_CMD_CURRENT,
4119 TG_CMD_NUMBER,
4120 TG_CMD_COUNT,
4121 };
4122 const char *target_cmds[] = {
4123 "create", "types", "names", "current", "number",
4124 "count",
4125 NULL /* terminate */
4126 };
4127
4128 LOG_DEBUG("Target command params:");
4129 LOG_DEBUG("%s", Jim_Debug_ArgvString(interp, argc, argv));
4130
4131 cmd_ctx = Jim_GetAssocData( interp, "context" );
4132
4133 Jim_GetOpt_Setup( &goi, interp, argc-1, argv+1 );
4134
4135 if( goi.argc == 0 ){
4136 Jim_WrongNumArgs(interp, 1, argv, "missing: command ...");
4137 return JIM_ERR;
4138 }
4139
4140 /* Jim_GetOpt_Debug( &goi ); */
4141 r = Jim_GetOpt_Enum( &goi, target_cmds, &x );
4142 if( r != JIM_OK ){
4143 return r;
4144 }
4145
4146 switch(x){
4147 default:
4148 Jim_Panic(goi.interp,"Why am I here?");
4149 return JIM_ERR;
4150 case TG_CMD_CURRENT:
4151 if( goi.argc != 0 ){
4152 Jim_WrongNumArgs( goi.interp, 1, goi.argv, "Too many parameters");
4153 return JIM_ERR;
4154 }
4155 Jim_SetResultString( goi.interp, get_current_target( cmd_ctx )->cmd_name, -1 );
4156 return JIM_OK;
4157 case TG_CMD_TYPES:
4158 if( goi.argc != 0 ){
4159 Jim_WrongNumArgs( goi.interp, 1, goi.argv, "Too many parameters" );
4160 return JIM_ERR;
4161 }
4162 Jim_SetResult( goi.interp, Jim_NewListObj( goi.interp, NULL, 0 ) );
4163 for( x = 0 ; target_types[x] ; x++ ){
4164 Jim_ListAppendElement( goi.interp,
4165 Jim_GetResult(goi.interp),
4166 Jim_NewStringObj( goi.interp, target_types[x]->name, -1 ) );
4167 }
4168 return JIM_OK;
4169 case TG_CMD_NAMES:
4170 if( goi.argc != 0 ){
4171 Jim_WrongNumArgs( goi.interp, 1, goi.argv, "Too many parameters" );
4172 return JIM_ERR;
4173 }
4174 Jim_SetResult( goi.interp, Jim_NewListObj( goi.interp, NULL, 0 ) );
4175 target = all_targets;
4176 while( target ){
4177 Jim_ListAppendElement( goi.interp,
4178 Jim_GetResult(goi.interp),
4179 Jim_NewStringObj( goi.interp, target->cmd_name, -1 ) );
4180 target = target->next;
4181 }
4182 return JIM_OK;
4183 case TG_CMD_CREATE:
4184 if( goi.argc < 3 ){
4185 Jim_WrongNumArgs( goi.interp, goi.argc, goi.argv, "?name ... config options ...");
4186 return JIM_ERR;
4187 }
4188 return target_create( &goi );
4189 break;
4190 case TG_CMD_NUMBER:
4191 if( goi.argc != 1 ){
4192 Jim_SetResult_sprintf( goi.interp, "expected: target number ?NUMBER?");
4193 return JIM_ERR;
4194 }
4195 e = Jim_GetOpt_Wide( &goi, &w );
4196 if( e != JIM_OK ){
4197 return JIM_ERR;
4198 }
4199 {
4200 target_t *t;
4201 t = get_target_by_num(w);
4202 if( t == NULL ){
4203 Jim_SetResult_sprintf( goi.interp,"Target: number %d does not exist", (int)(w));
4204 return JIM_ERR;
4205 }
4206 Jim_SetResultString( goi.interp, t->cmd_name, -1 );
4207 return JIM_OK;
4208 }
4209 case TG_CMD_COUNT:
4210 if( goi.argc != 0 ){
4211 Jim_WrongNumArgs( goi.interp, 0, goi.argv, "<no parameters>");
4212 return JIM_ERR;
4213 }
4214 Jim_SetResult( goi.interp,
4215 Jim_NewIntObj( goi.interp, max_target_number()));
4216 return JIM_OK;
4217 }
4218
4219 return JIM_ERR;
4220 }
4221
4222
4223 struct FastLoad
4224 {
4225 u32 address;
4226 u8 *data;
4227 int length;
4228
4229 };
4230
4231 static int fastload_num;
4232 static struct FastLoad *fastload;
4233
4234 static void free_fastload(void)
4235 {
4236 if (fastload!=NULL)
4237 {
4238 int i;
4239 for (i=0; i<fastload_num; i++)
4240 {
4241 if (fastload[i].data)
4242 free(fastload[i].data);
4243 }
4244 free(fastload);
4245 fastload=NULL;
4246 }
4247 }
4248
4249
4250
4251
4252 static int handle_fast_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
4253 {
4254 u8 *buffer;
4255 u32 buf_cnt;
4256 u32 image_size;
4257 u32 min_address=0;
4258 u32 max_address=0xffffffff;
4259 int i;
4260 int retval;
4261
4262 image_t image;
4263
4264 duration_t duration;
4265 char *duration_text;
4266
4267 if ((argc < 1)||(argc > 5))
4268 {
4269 return ERROR_COMMAND_SYNTAX_ERROR;
4270 }
4271
4272 /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
4273 if (argc >= 2)
4274 {
4275 image.base_address_set = 1;
4276 image.base_address = strtoul(args[1], NULL, 0);
4277 }
4278 else
4279 {
4280 image.base_address_set = 0;
4281 }
4282
4283
4284 image.start_address_set = 0;
4285
4286 if (argc>=4)
4287 {
4288 min_address=strtoul(args[3], NULL, 0);
4289 }
4290 if (argc>=5)
4291 {
4292 max_address=strtoul(args[4], NULL, 0)+min_address;
4293 }
4294
4295 if (min_address>max_address)
4296 {
4297 return ERROR_COMMAND_SYNTAX_ERROR;
4298 }
4299
4300 duration_start_measure(&duration);
4301
4302 if (image_open(&image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
4303 {
4304 return ERROR_OK;
4305 }
4306
4307 image_size = 0x0;
4308 retval = ERROR_OK;
4309 fastload_num=image.num_sections;
4310 fastload=(struct FastLoad *)malloc(sizeof(struct FastLoad)*image.num_sections);
4311 if (fastload==NULL)
4312 {
4313 image_close(&image);
4314 return ERROR_FAIL;
4315 }
4316 memset(fastload, 0, sizeof(struct FastLoad)*image.num_sections);
4317 for (i = 0; i < image.num_sections; i++)
4318 {
4319 buffer = malloc(image.sections[i].size);
4320 if (buffer == NULL)
4321 {
4322 command_print(cmd_ctx, "error allocating buffer for section (%d bytes)", image.sections[i].size);
4323 break;
4324 }
4325
4326 if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
4327 {
4328 free(buffer);
4329 break;
4330 }
4331
4332 u32 offset=0;
4333 u32 length=buf_cnt;
4334
4335
4336 /* DANGER!!! beware of unsigned comparision here!!! */
4337
4338 if ((image.sections[i].base_address+buf_cnt>=min_address)&&
4339 (image.sections[i].base_address<max_address))
4340 {
4341 if (image.sections[i].base_address<min_address)
4342 {
4343 /* clip addresses below */
4344 offset+=min_address-image.sections[i].base_address;
4345 length-=offset;
4346 }
4347
4348 if (image.sections[i].base_address+buf_cnt>max_address)
4349 {
4350 length-=(image.sections[i].base_address+buf_cnt)-max_address;
4351 }
4352
4353 fastload[i].address=image.sections[i].base_address+offset;
4354 fastload[i].data=malloc(length);
4355 if (fastload[i].data==NULL)
4356 {
4357 free(buffer);
4358 break;
4359 }
4360 memcpy(fastload[i].data, buffer+offset, length);
4361 fastload[i].length=length;
4362
4363 image_size += length;
4364 command_print(cmd_ctx, "%u byte written at address 0x%8.8x", length, image.sections[i].base_address+offset);
4365 }
4366
4367 free(buffer);
4368 }
4369
4370 duration_stop_measure(&duration, &duration_text);
4371 if (retval==ERROR_OK)
4372 {
4373 command_print(cmd_ctx, "Loaded %u bytes in %s", image_size, duration_text);
4374 command_print(cmd_ctx, "NB!!! image has not been loaded to target, issue a subsequent 'fast_load' to do so.");
4375 }
4376 free(duration_text);
4377
4378 image_close(&image);
4379
4380 if (retval!=ERROR_OK)
4381 {
4382 free_fastload();
4383 }
4384
4385 return retval;
4386 }
4387
4388 static int handle_fast_load_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
4389 {
4390 if (argc>0)
4391 return ERROR_COMMAND_SYNTAX_ERROR;
4392 if (fastload==NULL)
4393 {
4394 LOG_ERROR("No image in memory");
4395 return ERROR_FAIL;
4396 }
4397 int i;
4398 int ms=timeval_ms();
4399 int size=0;
4400 int retval=ERROR_OK;
4401 for (i=0; i<fastload_num;i++)
4402 {
4403 target_t *target = get_current_target(cmd_ctx);
4404 command_print(cmd_ctx, "Write to 0x%08x, length 0x%08x", fastload[i].address, fastload[i].length);
4405 if (retval==ERROR_OK)
4406 {
4407 retval = target_write_buffer(target, fastload[i].address, fastload[i].length, fastload[i].data);
4408 }
4409 size+=fastload[i].length;
4410 }
4411 int after=timeval_ms();
4412 command_print(cmd_ctx, "Loaded image %f kBytes/s", (float)(size/1024.0)/((float)(after-ms)/1000.0));
4413 return retval;
4414 }

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)