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

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)