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

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)