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

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)