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

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)