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

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)