From Michael Bruck
[openocd.git] / src / target / target.c
index 27df12fc33f42d34466c6f5ea6ad300ce90f822a..a9f7c1034b893b2e9f557b120e0fcb2ee3eed643 100644 (file)
-/***************************************************************************
- *   Copyright (C) 2005 by Dominic Rath                                    *
- *   Dominic.Rath@gmx.de                                                   *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "replacements.h"
-#include "target.h"
-#include "target_request.h"
-
-#include "log.h"
-#include "configuration.h"
-#include "binarybuffer.h"
-#include "jtag.h"
-
-#include <string.h>
-#include <stdlib.h>
-#include <inttypes.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <sys/time.h>
-#include <time.h>
-
-#include <time_support.h>
-
-#include <fileio.h>
-#include <image.h>
-
-int cli_target_callback_event_handler(struct target_s *target, enum target_event event, void *priv);
-
-
-int handle_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_daemon_startup_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_targets_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-
-int handle_target_script_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_run_and_halt_time_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_working_area_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-
-int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_wait_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_soft_reset_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_resume_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_step_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_bp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_rbp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_rwp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc);
-
-/* targets
- */
-extern target_type_t arm7tdmi_target;
-extern target_type_t arm720t_target;
-extern target_type_t arm9tdmi_target;
-extern target_type_t arm920t_target;
-extern target_type_t arm966e_target;
-extern target_type_t arm926ejs_target;
-extern target_type_t feroceon_target;
-extern target_type_t xscale_target;
-extern target_type_t cortexm3_target;
-
-target_type_t *target_types[] =
-{
-       &arm7tdmi_target,
-       &arm9tdmi_target,
-       &arm920t_target,
-       &arm720t_target,
-       &arm966e_target,
-       &arm926ejs_target,
-       &feroceon_target,
-       &xscale_target,
-       &cortexm3_target,
-       NULL,
-};
-
-target_t *targets = NULL;
-target_event_callback_t *target_event_callbacks = NULL;
-target_timer_callback_t *target_timer_callbacks = NULL;
-
-char *target_state_strings[] =
-{
-       "unknown",
-       "running",
-       "halted",
-       "reset",
-       "debug_running",
-};
-
-char *target_debug_reason_strings[] =
-{
-       "debug request", "breakpoint", "watchpoint",
-       "watchpoint and breakpoint", "single step",
-       "target not halted"
-};
-
-char *target_endianess_strings[] =
-{
-       "big endian",
-       "little endian",
-};
-
-enum daemon_startup_mode startup_mode = DAEMON_ATTACH;
-
-static int target_continous_poll = 1;
-
-/* read a u32 from a buffer in target memory endianness */
-u32 target_buffer_get_u32(target_t *target, u8 *buffer)
-{
-       if (target->endianness == TARGET_LITTLE_ENDIAN)
-               return le_to_h_u32(buffer);
-       else
-               return be_to_h_u32(buffer);
-}
-
-/* read a u16 from a buffer in target memory endianness */
-u16 target_buffer_get_u16(target_t *target, u8 *buffer)
-{
-       if (target->endianness == TARGET_LITTLE_ENDIAN)
-               return le_to_h_u16(buffer);
-       else
-               return be_to_h_u16(buffer);
-}
-
-/* write a u32 to a buffer in target memory endianness */
-void target_buffer_set_u32(target_t *target, u8 *buffer, u32 value)
-{
-       if (target->endianness == TARGET_LITTLE_ENDIAN)
-               h_u32_to_le(buffer, value);
-       else
-               h_u32_to_be(buffer, value);
-}
-
-/* write a u16 to a buffer in target memory endianness */
-void target_buffer_set_u16(target_t *target, u8 *buffer, u16 value)
-{
-       if (target->endianness == TARGET_LITTLE_ENDIAN)
-               h_u16_to_le(buffer, value);
-       else
-               h_u16_to_be(buffer, value);
-}
-
-/* returns a pointer to the n-th configured target */
-target_t* get_target_by_num(int num)
-{
-       target_t *target = targets;
-       int i = 0;
-
-       while (target)
-       {
-               if (num == i)
-                       return target;
-               target = target->next;
-               i++;
-       }
-
-       return NULL;
-}
-
-int get_num_by_target(target_t *query_target)
-{
-       target_t *target = targets;
-       int i = 0;      
-       
-       while (target)
-       {
-               if (target == query_target)
-                       return i;
-               target = target->next;
-               i++;
-       }
-       
-       return -1;
-}
-
-target_t* get_current_target(command_context_t *cmd_ctx)
-{
-       target_t *target = get_target_by_num(cmd_ctx->current_target);
-       
-       if (target == NULL)
-       {
-               ERROR("BUG: current_target out of bounds");
-               exit(-1);
-       }
-       
-       return target;
-}
-
-/* Process target initialization, when target entered debug out of reset
- * the handler is unregistered at the end of this function, so it's only called once
- */
-int target_init_handler(struct target_s *target, enum target_event event, void *priv)
-{
-       FILE *script;
-       struct command_context_s *cmd_ctx = priv;
-       
-       if ((event == TARGET_EVENT_HALTED) && (target->reset_script))
-       {
-               target_unregister_event_callback(target_init_handler, priv);
-
-               script = open_file_from_path(cmd_ctx, target->reset_script, "r");
-               if (!script)
-               {
-                       ERROR("couldn't open script file %s", target->reset_script);
-                               return ERROR_OK;
-               }
-
-               INFO("executing reset script '%s'", target->reset_script);
-               command_run_file(cmd_ctx, script, COMMAND_EXEC);
-               fclose(script);
-
-               jtag_execute_queue();
-       }
-       
-       return ERROR_OK;
-}
-
-int target_run_and_halt_handler(void *priv)
-{
-       target_t *target = priv;
-       
-       target->type->halt(target);
-       
-       return ERROR_OK;
-}
-
-int target_process_reset(struct command_context_s *cmd_ctx)
-{
-       int retval = ERROR_OK;
-       target_t *target;
-       struct timeval timeout, now;
-       
-       /* prepare reset_halt where necessary */
-       target = targets;
-       while (target)
-       {
-               if (jtag_reset_config & RESET_SRST_PULLS_TRST)
-               {
-                       switch (target->reset_mode)
-                       {
-                               case RESET_HALT:
-                                       command_print(cmd_ctx, "nSRST pulls nTRST, falling back to RESET_RUN_AND_HALT");
-                                       target->reset_mode = RESET_RUN_AND_HALT;
-                                       break;
-                               case RESET_INIT:
-                                       command_print(cmd_ctx, "nSRST pulls nTRST, falling back to RESET_RUN_AND_INIT");
-                                       target->reset_mode = RESET_RUN_AND_INIT;
-                                       break;
-                               default:
-                                       break;
-                       } 
-               }
-               switch (target->reset_mode)
-               {
-                       case RESET_HALT:
-                       case RESET_INIT:
-                               target->type->prepare_reset_halt(target);
-                               break;
-                       default:
-                               break;
-               }
-               target = target->next;
-       }
-       
-       target = targets;
-       while (target)
-       {
-               target->type->assert_reset(target);
-               target = target->next;
-       }
-       jtag_execute_queue();
-       
-       /* request target halt if necessary, and schedule further action */
-       target = targets;
-       while (target)
-       {
-               switch (target->reset_mode)
-               {
-                       case RESET_RUN:
-                               /* nothing to do if target just wants to be run */
-                               break;
-                       case RESET_RUN_AND_HALT:
-                               /* schedule halt */
-                               target_register_timer_callback(target_run_and_halt_handler, target->run_and_halt_time, 0, target);
-                               break;
-                       case RESET_RUN_AND_INIT:
-                               /* schedule halt */
-                               target_register_timer_callback(target_run_and_halt_handler, target->run_and_halt_time, 0, target);
-                               target_register_event_callback(target_init_handler, cmd_ctx);
-                               break;
-                       case RESET_HALT:
-                               target->type->halt(target);
-                               break;
-                       case RESET_INIT:
-                               target->type->halt(target);
-                               target_register_event_callback(target_init_handler, cmd_ctx);
-                               break;
-                       default:
-                               ERROR("BUG: unknown target->reset_mode");
-               }
-               target = target->next;
-       }
-       
-       target = targets;
-       while (target)
-       {
-               target->type->deassert_reset(target);
-               target = target->next;
-       }
-       jtag_execute_queue();
-
-       /* Wait for reset to complete, maximum 5 seconds. */    
-       gettimeofday(&timeout, NULL);
-       timeval_add_time(&timeout, 5, 0);
-       for(;;)
-       {
-               gettimeofday(&now, NULL);
-               
-               target_call_timer_callbacks();
-               
-               target = targets;
-               while (target)
-               {
-                       target->type->poll(target);
-                       if ((target->reset_mode == RESET_RUN_AND_INIT) || (target->reset_mode == RESET_RUN_AND_HALT))
-                       {
-                               if (target->state != TARGET_HALTED)
-                               {
-                                       if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec) && (now.tv_usec >= timeout.tv_usec)))
-                                       {
-                                               command_print(cmd_ctx, "Timed out waiting for reset");
-                                               goto done;
-                                       }
-                                       usleep(100*1000); /* Do not eat all cpu */
-                                       goto again;
-                               }
-                       }
-                       target = target->next;
-               }
-               /* All targets we're waiting for are halted */
-               break;
-               
-               again:;
-       }
-       done:
-       
-       
-       /* We want any events to be processed before the prompt */
-       target_call_timer_callbacks();
-       
-       return retval;
-}
-
-static int default_virt2phys(struct target_s *target, u32 virtual, u32 *physical)
-{
-       *physical = virtual;
-       return ERROR_OK;
-}
-
-static int default_mmu(struct target_s *target, int *enabled)
-{
-       *enabled = 0;
-       return ERROR_OK;
-}
-
-int target_init(struct command_context_s *cmd_ctx)
-{
-       target_t *target = targets;
-       
-       while (target)
-       {
-               if (target->type->init_target(cmd_ctx, target) != ERROR_OK)
-               {
-                       ERROR("target '%s' init failed", target->type->name);
-                       exit(-1);
-               }
-               
-               /* Set up default functions if none are provided by target */
-               if (target->type->virt2phys == NULL)
-               {
-                       target->type->virt2phys = default_virt2phys;
-               }
-               if (target->type->mmu == NULL)
-               {
-                       target->type->mmu = default_mmu;
-               }
-               target = target->next;
-       }
-       
-       if (targets)
-       {
-               target_register_user_commands(cmd_ctx);
-               target_register_timer_callback(handle_target, 100, 1, NULL);
-       }
-               
-       return ERROR_OK;
-}
-
-int target_init_reset(struct command_context_s *cmd_ctx)
-{
-       if (startup_mode == DAEMON_RESET)
-               target_process_reset(cmd_ctx);
-       
-       return ERROR_OK;
-}
-
-int target_register_event_callback(int (*callback)(struct target_s *target, enum target_event event, void *priv), void *priv)
-{
-       target_event_callback_t **callbacks_p = &target_event_callbacks;
-       
-       if (callback == NULL)
-       {
-               return ERROR_INVALID_ARGUMENTS;
-       }
-       
-       if (*callbacks_p)
-       {
-               while ((*callbacks_p)->next)
-                       callbacks_p = &((*callbacks_p)->next);
-               callbacks_p = &((*callbacks_p)->next);
-       }
-       
-       (*callbacks_p) = malloc(sizeof(target_event_callback_t));
-       (*callbacks_p)->callback = callback;
-       (*callbacks_p)->priv = priv;
-       (*callbacks_p)->next = NULL;
-       
-       return ERROR_OK;
-}
-
-int target_register_timer_callback(int (*callback)(void *priv), int time_ms, int periodic, void *priv)
-{
-       target_timer_callback_t **callbacks_p = &target_timer_callbacks;
-       struct timeval now;
-       
-       if (callback == NULL)
-       {
-               return ERROR_INVALID_ARGUMENTS;
-       }
-       
-       if (*callbacks_p)
-       {
-               while ((*callbacks_p)->next)
-                       callbacks_p = &((*callbacks_p)->next);
-               callbacks_p = &((*callbacks_p)->next);
-       }
-       
-       (*callbacks_p) = malloc(sizeof(target_timer_callback_t));
-       (*callbacks_p)->callback = callback;
-       (*callbacks_p)->periodic = periodic;
-       (*callbacks_p)->time_ms = time_ms;
-       
-       gettimeofday(&now, NULL);
-       (*callbacks_p)->when.tv_usec = now.tv_usec + (time_ms % 1000) * 1000;
-       time_ms -= (time_ms % 1000);
-       (*callbacks_p)->when.tv_sec = now.tv_sec + (time_ms / 1000);
-       if ((*callbacks_p)->when.tv_usec > 1000000)
-       {
-               (*callbacks_p)->when.tv_usec = (*callbacks_p)->when.tv_usec - 1000000;
-               (*callbacks_p)->when.tv_sec += 1;
-       }
-       
-       (*callbacks_p)->priv = priv;
-       (*callbacks_p)->next = NULL;
-       
-       return ERROR_OK;
-}
-
-int target_unregister_event_callback(int (*callback)(struct target_s *target, enum target_event event, void *priv), void *priv)
-{
-       target_event_callback_t **p = &target_event_callbacks;
-       target_event_callback_t *c = target_event_callbacks;
-       
-       if (callback == NULL)
-       {
-               return ERROR_INVALID_ARGUMENTS;
-       }
-               
-       while (c)
-       {
-               target_event_callback_t *next = c->next;
-               if ((c->callback == callback) && (c->priv == priv))
-               {
-                       *p = next;
-                       free(c);
-                       return ERROR_OK;
-               }
-               else
-                       p = &(c->next);
-               c = next;
-       }
-       
-       return ERROR_OK;
-}
-
-int target_unregister_timer_callback(int (*callback)(void *priv), void *priv)
-{
-       target_timer_callback_t **p = &target_timer_callbacks;
-       target_timer_callback_t *c = target_timer_callbacks;
-       
-       if (callback == NULL)
-       {
-               return ERROR_INVALID_ARGUMENTS;
-       }
-               
-       while (c)
-       {
-               target_timer_callback_t *next = c->next;
-               if ((c->callback == callback) && (c->priv == priv))
-               {
-                       *p = next;
-                       free(c);
-                       return ERROR_OK;
-               }
-               else
-                       p = &(c->next);
-               c = next;
-       }
-       
-       return ERROR_OK;
-}
-
-int target_call_event_callbacks(target_t *target, enum target_event event)
-{
-       target_event_callback_t *callback = target_event_callbacks;
-       target_event_callback_t *next_callback;
-       
-       DEBUG("target event %i", event);
-       
-       while (callback)
-       {
-               next_callback = callback->next;
-               callback->callback(target, event, callback->priv);
-               callback = next_callback;
-       }
-       
-       return ERROR_OK;
-}
-
-int target_call_timer_callbacks()
-{
-       target_timer_callback_t *callback = target_timer_callbacks;
-       target_timer_callback_t *next_callback;
-       struct timeval now;
-
-       gettimeofday(&now, NULL);
-       
-       while (callback)
-       {
-               next_callback = callback->next;
-               
-               if (((now.tv_sec >= callback->when.tv_sec) && (now.tv_usec >= callback->when.tv_usec))
-                       || (now.tv_sec > callback->when.tv_sec))
-               {
-                       callback->callback(callback->priv);
-                       if (callback->periodic)
-                       {
-                               int time_ms = callback->time_ms;
-                               callback->when.tv_usec = now.tv_usec + (time_ms % 1000) * 1000;
-                               time_ms -= (time_ms % 1000);
-                               callback->when.tv_sec = now.tv_sec + time_ms / 1000;
-                               if (callback->when.tv_usec > 1000000)
-                               {
-                                       callback->when.tv_usec = callback->when.tv_usec - 1000000;
-                                       callback->when.tv_sec += 1;
-                               }
-                       }
-                       else
-                               target_unregister_timer_callback(callback->callback, callback->priv);
-               }
-                       
-               callback = next_callback;
-       }
-       
-       return ERROR_OK;
-}
-
-int target_alloc_working_area(struct target_s *target, u32 size, working_area_t **area)
-{
-       working_area_t *c = target->working_areas;
-       working_area_t *new_wa = NULL;
-       
-       /* Reevaluate working area address based on MMU state*/
-       if (target->working_areas == NULL)
-       {
-               int retval;
-               int enabled;
-               retval = target->type->mmu(target, &enabled);
-               if (retval != ERROR_OK)
-               {
-                       return retval;
-               }
-               if (enabled)
-               {
-                       target->working_area = target->working_area_virt;
-               }
-               else
-               {
-                       target->working_area = target->working_area_phys;
-               }
-       }
-       
-       /* only allocate multiples of 4 byte */
-       if (size % 4)
-       {
-               ERROR("BUG: code tried to allocate unaligned number of bytes, padding");
-               size = CEIL(size, 4);
-       }
-       
-       /* see if there's already a matching working area */
-       while (c)
-       {
-               if ((c->free) && (c->size == size))
-               {
-                       new_wa = c;
-                       break;
-               }
-               c = c->next;
-       }
-       
-       /* if not, allocate a new one */
-       if (!new_wa)
-       {
-               working_area_t **p = &target->working_areas;
-               u32 first_free = target->working_area;
-               u32 free_size = target->working_area_size;
-               
-               DEBUG("allocating new working area");
-               
-               c = target->working_areas;
-               while (c)
-               {
-                       first_free += c->size;
-                       free_size -= c->size;
-                       p = &c->next;
-                       c = c->next;
-               }
-               
-               if (free_size < size)
-               {
-                       WARNING("not enough working area available(requested %d, free %d)", size, free_size);
-                       return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
-               }
-               
-               new_wa = malloc(sizeof(working_area_t));
-               new_wa->next = NULL;
-               new_wa->size = size;
-               new_wa->address = first_free;
-               
-               if (target->backup_working_area)
-               {
-                       new_wa->backup = malloc(new_wa->size);
-                       target->type->read_memory(target, new_wa->address, 4, new_wa->size / 4, new_wa->backup);
-               }
-               else
-               {
-                       new_wa->backup = NULL;
-               }
-               
-               /* put new entry in list */
-               *p = new_wa;
-       }
-       
-       /* mark as used, and return the new (reused) area */
-       new_wa->free = 0;
-       *area = new_wa;
-       
-       /* user pointer */
-       new_wa->user = area;
-       
-       return ERROR_OK;
-}
-
-int target_free_working_area(struct target_s *target, working_area_t *area)
-{
-       if (area->free)
-               return ERROR_OK;
-       
-       if (target->backup_working_area)
-               target->type->write_memory(target, area->address, 4, area->size / 4, area->backup);
-       
-       area->free = 1;
-       
-       /* mark user pointer invalid */
-       *area->user = NULL;
-       area->user = NULL;
-       
-       return ERROR_OK;
-}
-
-int target_free_all_working_areas(struct target_s *target)
-{
-       working_area_t *c = target->working_areas;
-
-       while (c)
-       {
-               working_area_t *next = c->next;
-               target_free_working_area(target, c);
-               
-               if (c->backup)
-                       free(c->backup);
-               
-               free(c);
-               
-               c = next;
-       }
-       
-       target->working_areas = NULL;
-       
-       return ERROR_OK;
-}
-
-int target_register_commands(struct command_context_s *cmd_ctx)
-{
-       register_command(cmd_ctx, NULL, "target", handle_target_command, COMMAND_CONFIG, NULL);
-       register_command(cmd_ctx, NULL, "targets", handle_targets_command, COMMAND_EXEC, NULL);
-       register_command(cmd_ctx, NULL, "daemon_startup", handle_daemon_startup_command, COMMAND_CONFIG, NULL);
-       register_command(cmd_ctx, NULL, "target_script", handle_target_script_command, COMMAND_CONFIG, NULL);
-       register_command(cmd_ctx, NULL, "run_and_halt_time", handle_run_and_halt_time_command, COMMAND_CONFIG, NULL);
-       register_command(cmd_ctx, NULL, "working_area", handle_working_area_command, COMMAND_ANY, "working_area <target#> <address> <size> <'backup'|'nobackup'> [virtual address]");
-       register_command(cmd_ctx, NULL, "virt2phys", handle_virt2phys_command, COMMAND_ANY, "virt2phys <virtual address>");
-
-       return ERROR_OK;
-}
-
-int target_arch_state(struct target_s *target)
-{
-       int retval;
-       if (target==NULL)
-       {
-               USER("No target has been configured");
-               return ERROR_OK;
-       }
-       
-       USER("target state: %s", target_state_strings[target->state]);
-       
-       if (target->state!=TARGET_HALTED)
-               return ERROR_OK;
-       
-       retval=target->type->arch_state(target);
-       return retval;
-}
-
-/* Single aligned words are guaranteed to use 16 or 32 bit access 
- * mode respectively, otherwise data is handled as quickly as 
- * possible
- */
-int target_write_buffer(struct target_s *target, u32 address, u32 size, u8 *buffer)
-{
-       int retval;
-       
-       DEBUG("writing buffer of %i byte at 0x%8.8x", size, address);
-       
-       if (((address % 2) == 0) && (size == 2))
-       {
-               return target->type->write_memory(target, address, 2, 1, buffer);
-       }
-       
-       /* handle unaligned head bytes */
-       if (address % 4)
-       {
-               int unaligned = 4 - (address % 4);
-               
-               if (unaligned > size)
-                       unaligned = size;
-
-               if ((retval = target->type->write_memory(target, address, 1, unaligned, buffer)) != ERROR_OK)
-                       return retval;
-               
-               buffer += unaligned;
-               address += unaligned;
-               size -= unaligned;
-       }
-               
-       /* handle aligned words */
-       if (size >= 4)
-       {
-               int aligned = size - (size % 4);
-       
-               /* use bulk writes above a certain limit. This may have to be changed */
-               if (aligned > 128)
-               {
-                       if ((retval = target->type->bulk_write_memory(target, address, aligned / 4, buffer)) != ERROR_OK)
-                               return retval;
-               }
-               else
-               {
-                       if ((retval = target->type->write_memory(target, address, 4, aligned / 4, buffer)) != ERROR_OK)
-                               return retval;
-               }
-               
-               buffer += aligned;
-               address += aligned;
-               size -= aligned;
-       }
-       
-       /* handle tail writes of less than 4 bytes */
-       if (size > 0)
-       {
-               if ((retval = target->type->write_memory(target, address, 1, size, buffer)) != ERROR_OK)
-                       return retval;
-       }
-       
-       return ERROR_OK;
-}
-
-
-/* Single aligned words are guaranteed to use 16 or 32 bit access 
- * mode respectively, otherwise data is handled as quickly as 
- * possible
- */
-int target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffer)
-{
-       int retval;
-       
-       DEBUG("reading buffer of %i byte at 0x%8.8x", size, address);
-       
-       if (((address % 2) == 0) && (size == 2))
-       {
-               return target->type->read_memory(target, address, 2, 1, buffer);
-       }
-       
-       /* handle unaligned head bytes */
-       if (address % 4)
-       {
-               int unaligned = 4 - (address % 4);
-               
-               if (unaligned > size)
-                       unaligned = size;
-
-               if ((retval = target->type->read_memory(target, address, 1, unaligned, buffer)) != ERROR_OK)
-                       return retval;
-               
-               buffer += unaligned;
-               address += unaligned;
-               size -= unaligned;
-       }
-               
-       /* handle aligned words */
-       if (size >= 4)
-       {
-               int aligned = size - (size % 4);
-       
-               if ((retval = target->type->read_memory(target, address, 4, aligned / 4, buffer)) != ERROR_OK)
-                       return retval;
-               
-               buffer += aligned;
-               address += aligned;
-               size -= aligned;
-       }
-       
-       /* handle tail writes of less than 4 bytes */
-       if (size > 0)
-       {
-               if ((retval = target->type->read_memory(target, address, 1, size, buffer)) != ERROR_OK)
-                       return retval;
-       }
-       
-       return ERROR_OK;
-}
-
-int target_checksum_memory(struct target_s *target, u32 address, u32 size, u32* crc)
-{
-       u8 *buffer;
-       int retval;
-       int i;
-       u32 checksum = 0;
-       
-       if ((retval = target->type->checksum_memory(target, address,
-               size, &checksum)) == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
-       {
-               buffer = malloc(size);
-               if (buffer == NULL)
-               {
-                       ERROR("error allocating buffer for section (%d bytes)", size);
-                       return ERROR_INVALID_ARGUMENTS;
-               }
-               retval = target_read_buffer(target, address, size, buffer);
-               if (retval != ERROR_OK)
-               {
-                       free(buffer);
-                       return retval;
-               }
-
-               /* convert to target endianess */
-               for (i = 0; i < (size/sizeof(u32)); i++)
-               {
-                       u32 target_data;
-                       target_data = target_buffer_get_u32(target, &buffer[i*sizeof(u32)]);
-                       target_buffer_set_u32(target, &buffer[i*sizeof(u32)], target_data);
-               }
-
-               retval = image_calculate_checksum( buffer, size, &checksum );
-               free(buffer);
-       }
-       
-       *crc = checksum;
-       
-       return retval;
-}
-
-int target_read_u32(struct target_s *target, u32 address, u32 *value)
-{
-       u8 value_buf[4];
-
-       int retval = target->type->read_memory(target, address, 4, 1, value_buf);
-       
-       if (retval == ERROR_OK)
-       {
-               *value = target_buffer_get_u32(target, value_buf);
-               DEBUG("address: 0x%8.8x, value: 0x%8.8x", address, *value);
-       }
-       else
-       {
-               *value = 0x0;
-               DEBUG("address: 0x%8.8x failed", address);
-       }
-       
-       return retval;
-}
-
-int target_read_u16(struct target_s *target, u32 address, u16 *value)
-{
-       u8 value_buf[2];
-       
-       int retval = target->type->read_memory(target, address, 2, 1, value_buf);
-       
-       if (retval == ERROR_OK)
-       {
-               *value = target_buffer_get_u16(target, value_buf);
-               DEBUG("address: 0x%8.8x, value: 0x%4.4x", address, *value);
-       }
-       else
-       {
-               *value = 0x0;
-               DEBUG("address: 0x%8.8x failed", address);
-       }
-       
-       return retval;
-}
-
-int target_read_u8(struct target_s *target, u32 address, u8 *value)
-{
-       int retval = target->type->read_memory(target, address, 1, 1, value);
-
-       if (retval == ERROR_OK)
-       {
-               DEBUG("address: 0x%8.8x, value: 0x%2.2x", address, *value);
-       }
-       else
-       {
-               *value = 0x0;
-               DEBUG("address: 0x%8.8x failed", address);
-       }
-       
-       return retval;
-}
-
-int target_write_u32(struct target_s *target, u32 address, u32 value)
-{
-       int retval;
-       u8 value_buf[4];
-
-       DEBUG("address: 0x%8.8x, value: 0x%8.8x", address, value);
-
-       target_buffer_set_u32(target, value_buf, value);        
-       if ((retval = target->type->write_memory(target, address, 4, 1, value_buf)) != ERROR_OK)
-       {
-               DEBUG("failed: %i", retval);
-       }
-       
-       return retval;
-}
-
-int target_write_u16(struct target_s *target, u32 address, u16 value)
-{
-       int retval;
-       u8 value_buf[2];
-       
-       DEBUG("address: 0x%8.8x, value: 0x%8.8x", address, value);
-
-       target_buffer_set_u16(target, value_buf, value);        
-       if ((retval = target->type->write_memory(target, address, 2, 1, value_buf)) != ERROR_OK)
-       {
-               DEBUG("failed: %i", retval);
-       }
-       
-       return retval;
-}
-
-int target_write_u8(struct target_s *target, u32 address, u8 value)
-{
-       int retval;
-       
-       DEBUG("address: 0x%8.8x, value: 0x%2.2x", address, value);
-
-       if ((retval = target->type->read_memory(target, address, 1, 1, &value)) != ERROR_OK)
-       {
-               DEBUG("failed: %i", retval);
-       }
-       
-       return retval;
-}
-
-int target_register_user_commands(struct command_context_s *cmd_ctx)
-{
-       register_command(cmd_ctx,  NULL, "reg", handle_reg_command, COMMAND_EXEC, NULL);
-       register_command(cmd_ctx,  NULL, "poll", handle_poll_command, COMMAND_EXEC, "poll target state");
-       register_command(cmd_ctx,  NULL, "wait_halt", handle_wait_halt_command, COMMAND_EXEC, "wait for target halt [time (s)]");
-       register_command(cmd_ctx,  NULL, "halt", handle_halt_command, COMMAND_EXEC, "halt target");
-       register_command(cmd_ctx,  NULL, "resume", handle_resume_command, COMMAND_EXEC, "resume target [addr]");
-       register_command(cmd_ctx,  NULL, "step", handle_step_command, COMMAND_EXEC, "step one instruction from current PC or [addr]");
-       register_command(cmd_ctx,  NULL, "reset", handle_reset_command, COMMAND_EXEC, "reset target [run|halt|init|run_and_halt|run_and_init]");
-       register_command(cmd_ctx,  NULL, "soft_reset_halt", handle_soft_reset_halt_command, COMMAND_EXEC, "halt the target and do a soft reset");
-
-       register_command(cmd_ctx,  NULL, "mdw", handle_md_command, COMMAND_EXEC, "display memory words <addr> [count]");
-       register_command(cmd_ctx,  NULL, "mdh", handle_md_command, COMMAND_EXEC, "display memory half-words <addr> [count]");
-       register_command(cmd_ctx,  NULL, "mdb", handle_md_command, COMMAND_EXEC, "display memory bytes <addr> [count]");
-       
-       register_command(cmd_ctx,  NULL, "mww", handle_mw_command, COMMAND_EXEC, "write memory word <addr> <value>");
-       register_command(cmd_ctx,  NULL, "mwh", handle_mw_command, COMMAND_EXEC, "write memory half-word <addr> <value>");
-       register_command(cmd_ctx,  NULL, "mwb", handle_mw_command, COMMAND_EXEC, "write memory byte <addr> <value>");
-       
-       register_command(cmd_ctx,  NULL, "bp", handle_bp_command, COMMAND_EXEC, "set breakpoint <address> <length> [hw]");      
-       register_command(cmd_ctx,  NULL, "rbp", handle_rbp_command, COMMAND_EXEC, "remove breakpoint <adress>");
-       register_command(cmd_ctx,  NULL, "wp", handle_wp_command, COMMAND_EXEC, "set watchpoint <address> <length> <r/w/a> [value] [mask]");    
-       register_command(cmd_ctx,  NULL, "rwp", handle_rwp_command, COMMAND_EXEC, "remove watchpoint <adress>");
-       
-       register_command(cmd_ctx,  NULL, "load_image", handle_load_image_command, COMMAND_EXEC, "load_image <file> <address> ['bin'|'ihex'|'elf'|'s19']");
-       register_command(cmd_ctx,  NULL, "dump_image", handle_dump_image_command, COMMAND_EXEC, "dump_image <file> <address> <size>");
-       register_command(cmd_ctx,  NULL, "verify_image", handle_verify_image_command, COMMAND_EXEC, "verify_image <file> [offset] [type]");
-       register_command(cmd_ctx,  NULL, "load_binary", handle_load_image_command, COMMAND_EXEC, "[DEPRECATED] load_binary <file> <address>");
-       register_command(cmd_ctx,  NULL, "dump_binary", handle_dump_image_command, COMMAND_EXEC, "[DEPRECATED] dump_binary <file> <address> <size>");
-       
-       target_request_register_commands(cmd_ctx);
-       trace_register_commands(cmd_ctx);
-       
-       return ERROR_OK;
-}
-
-int handle_targets_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       target_t *target = targets;
-       int count = 0;
-       
-       if (argc == 1)
-       {
-               int num = strtoul(args[0], NULL, 0);
-               
-               while (target)
-               {
-                       count++;
-                       target = target->next;
-               }
-               
-               if (num < count)
-                       cmd_ctx->current_target = num;
-               else
-                       command_print(cmd_ctx, "%i is out of bounds, only %i targets are configured", num, count);
-                       
-               return ERROR_OK;
-       }
-               
-       while (target)
-       {
-               command_print(cmd_ctx, "%i: %s (%s), state: %s", count++, target->type->name, target_endianess_strings[target->endianness], target_state_strings[target->state]);
-               target = target->next;
-       }
-       
-       return ERROR_OK;
-}
-
-int handle_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       int i;
-       int found = 0;
-       
-       if (argc < 3)
-       {
-               ERROR("target command requires at least three arguments: <type> <endianess> <reset_mode>");
-               exit(-1);
-       }
-       
-       /* search for the specified target */
-       if (args[0] && (args[0][0] != 0))
-       {
-               for (i = 0; target_types[i]; i++)
-               {
-                       if (strcmp(args[0], target_types[i]->name) == 0)
-                       {
-                               target_t **last_target_p = &targets;
-                               
-                               /* register target specific commands */
-                               if (target_types[i]->register_commands(cmd_ctx) != ERROR_OK)
-                               {
-                                       ERROR("couldn't register '%s' commands", args[0]);
-                                       exit(-1);
-                               }
-
-                               if (*last_target_p)
-                               {
-                                       while ((*last_target_p)->next)
-                                               last_target_p = &((*last_target_p)->next);
-                                       last_target_p = &((*last_target_p)->next);
-                               }
-
-                               *last_target_p = malloc(sizeof(target_t));
-                               
-                               (*last_target_p)->type = target_types[i];
-                               
-                               if (strcmp(args[1], "big") == 0)
-                                       (*last_target_p)->endianness = TARGET_BIG_ENDIAN;
-                               else if (strcmp(args[1], "little") == 0)
-                                       (*last_target_p)->endianness = TARGET_LITTLE_ENDIAN;
-                               else
-                               {
-                                       ERROR("endianness must be either 'little' or 'big', not '%s'", args[1]);
-                                       exit(-1);
-                               }
-                               
-                               /* what to do on a target reset */
-                               if (strcmp(args[2], "reset_halt") == 0)
-                                       (*last_target_p)->reset_mode = RESET_HALT;
-                               else if (strcmp(args[2], "reset_run") == 0)
-                                       (*last_target_p)->reset_mode = RESET_RUN;
-                               else if (strcmp(args[2], "reset_init") == 0)
-                                       (*last_target_p)->reset_mode = RESET_INIT;
-                               else if (strcmp(args[2], "run_and_halt") == 0)
-                                       (*last_target_p)->reset_mode = RESET_RUN_AND_HALT;
-                               else if (strcmp(args[2], "run_and_init") == 0)
-                                       (*last_target_p)->reset_mode = RESET_RUN_AND_INIT;
-                               else
-                               {
-                                       ERROR("unknown target startup mode %s", args[2]);
-                                       exit(-1);
-                               }
-                               (*last_target_p)->run_and_halt_time = 1000; /* default 1s */
-                               
-                               (*last_target_p)->reset_script = NULL;
-                               (*last_target_p)->post_halt_script = NULL;
-                               (*last_target_p)->pre_resume_script = NULL;
-                               (*last_target_p)->gdb_program_script = NULL;
-                               
-                               (*last_target_p)->working_area = 0x0;
-                               (*last_target_p)->working_area_size = 0x0;
-                               (*last_target_p)->working_areas = NULL;
-                               (*last_target_p)->backup_working_area = 0;
-                               
-                               (*last_target_p)->state = TARGET_UNKNOWN;
-                               (*last_target_p)->reg_cache = NULL;
-                               (*last_target_p)->breakpoints = NULL;
-                               (*last_target_p)->watchpoints = NULL;
-                               (*last_target_p)->next = NULL;
-                               (*last_target_p)->arch_info = NULL;
-                               
-                               /* initialize trace information */
-                               (*last_target_p)->trace_info = malloc(sizeof(trace_t));
-                               (*last_target_p)->trace_info->num_trace_points = 0;
-                               (*last_target_p)->trace_info->trace_points_size = 0;
-                               (*last_target_p)->trace_info->trace_points = NULL;
-                               (*last_target_p)->trace_info->trace_history_size = 0;
-                               (*last_target_p)->trace_info->trace_history = NULL;
-                               (*last_target_p)->trace_info->trace_history_pos = 0;
-                               (*last_target_p)->trace_info->trace_history_overflowed = 0;
-                               
-                               (*last_target_p)->dbgmsg = NULL;
-                               (*last_target_p)->dbg_msg_enabled = 0;
-                                                               
-                               (*last_target_p)->type->target_command(cmd_ctx, cmd, args, argc, *last_target_p);
-                               
-                               found = 1;
-                               break;
-                       }
-               }
-       }
-       
-       /* no matching target found */
-       if (!found)
-       {
-               ERROR("target '%s' not found", args[0]);
-               exit(-1);
-       }
-
-       return ERROR_OK;
-}
-
-/* usage: target_script <target#> <event> <script_file> */
-int handle_target_script_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       target_t *target = NULL;
-       
-       if (argc < 3)
-       {
-               ERROR("incomplete target_script command");
-               exit(-1);
-       }
-       
-       target = get_target_by_num(strtoul(args[0], NULL, 0));
-       
-       if (!target)
-       {
-               ERROR("target number '%s' not defined", args[0]);
-               exit(-1);
-       }
-       
-       if (strcmp(args[1], "reset") == 0)
-       {
-               if (target->reset_script)
-                       free(target->reset_script);
-               target->reset_script = strdup(args[2]);
-       }
-       else if (strcmp(args[1], "post_halt") == 0)
-       {
-               if (target->post_halt_script)
-                       free(target->post_halt_script);
-               target->post_halt_script = strdup(args[2]);
-       }
-       else if (strcmp(args[1], "pre_resume") == 0)
-       {
-               if (target->pre_resume_script)
-                       free(target->pre_resume_script);
-               target->pre_resume_script = strdup(args[2]);
-       }
-       else if (strcmp(args[1], "gdb_program_config") == 0)
-       {
-               if (target->gdb_program_script)
-                       free(target->gdb_program_script);
-               target->gdb_program_script = strdup(args[2]);
-       }
-       else
-       {
-               ERROR("unknown event type: '%s", args[1]);
-               exit(-1);       
-       }
-       
-       return ERROR_OK;
-}
-
-int handle_run_and_halt_time_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       target_t *target = NULL;
-       
-       if (argc < 2)
-       {
-               ERROR("incomplete run_and_halt_time command");
-               exit(-1);
-       }
-       
-       target = get_target_by_num(strtoul(args[0], NULL, 0));
-       
-       if (!target)
-       {
-               ERROR("target number '%s' not defined", args[0]);
-               exit(-1);
-       }
-       
-       target->run_and_halt_time = strtoul(args[1], NULL, 0);
-       
-       return ERROR_OK;
-}
-
-int handle_working_area_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       target_t *target = NULL;
-       
-       if ((argc < 4) || (argc > 5))
-       {
-               return ERROR_COMMAND_SYNTAX_ERROR;
-       }
-       
-       target = get_target_by_num(strtoul(args[0], NULL, 0));
-       
-       if (!target)
-       {
-               ERROR("target number '%s' not defined", args[0]);
-               exit(-1);
-       }
-       target_free_all_working_areas(target);
-       
-       target->working_area_phys = target->working_area_virt = strtoul(args[1], NULL, 0);
-       if (argc == 5)
-       {
-               target->working_area_virt = strtoul(args[4], NULL, 0);
-       }
-       target->working_area_size = strtoul(args[2], NULL, 0);
-       
-       if (strcmp(args[3], "backup") == 0)
-       {
-               target->backup_working_area = 1;
-       }
-       else if (strcmp(args[3], "nobackup") == 0)
-       {
-               target->backup_working_area = 0;
-       }
-       else
-       {
-               ERROR("unrecognized <backup|nobackup> argument (%s)", args[3]);
-               return ERROR_COMMAND_SYNTAX_ERROR;
-       }
-       
-       return ERROR_OK;
-}
-
-
-/* process target state changes */
-int handle_target(void *priv)
-{
-       int retval;
-       target_t *target = targets;
-       
-       while (target)
-       {
-               /* only poll if target isn't already halted */
-               if (target->state != TARGET_HALTED)
-               {
-                       if (target_continous_poll)
-                               if ((retval = target->type->poll(target)) != ERROR_OK)
-                               {
-                                       ERROR("couldn't poll target(%d). It's due for a reset.", retval);
-                               }
-               }
-       
-               target = target->next;
-       }
-       
-       return ERROR_OK;
-}
-
-int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       target_t *target;
-       reg_t *reg = NULL;
-       int count = 0;
-       char *value;
-       
-       DEBUG("-");
-       
-       target = get_current_target(cmd_ctx);
-       
-       /* list all available registers for the current target */
-       if (argc == 0)
-       {
-               reg_cache_t *cache = target->reg_cache;
-               
-               count = 0;
-               while(cache)
-               {
-                       int i;
-                       for (i = 0; i < cache->num_regs; i++)
-                       {
-                               value = buf_to_str(cache->reg_list[i].value, cache->reg_list[i].size, 16);
-                               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);
-                               free(value);
-                       }
-                       cache = cache->next;
-               }
-               
-               return ERROR_OK;
-       }
-       
-       /* access a single register by its ordinal number */
-       if ((args[0][0] >= '0') && (args[0][0] <= '9'))
-       {
-               int num = strtoul(args[0], NULL, 0);
-               reg_cache_t *cache = target->reg_cache;
-               
-               count = 0;
-               while(cache)
-               {
-                       int i;
-                       for (i = 0; i < cache->num_regs; i++)
-                       {
-                               if (count++ == num)
-                               {
-                                       reg = &cache->reg_list[i];
-                                       break;
-                               }
-                       }
-                       if (reg)
-                               break;
-                       cache = cache->next;
-               }
-               
-               if (!reg)
-               {
-                       command_print(cmd_ctx, "%i is out of bounds, the current target has only %i registers (0 - %i)", num, count, count - 1);
-                       return ERROR_OK;
-               }
-       } else /* access a single register by its name */
-       {
-               reg = register_get_by_name(target->reg_cache, args[0], 1);
-               
-               if (!reg)
-               {
-                       command_print(cmd_ctx, "register %s not found in current target", args[0]);
-                       return ERROR_OK;
-               }
-       }
-
-       /* display a register */
-       if ((argc == 1) || ((argc == 2) && !((args[1][0] >= '0') && (args[1][0] <= '9'))))
-       {
-               if ((argc == 2) && (strcmp(args[1], "force") == 0))
-                       reg->valid = 0;
-               
-               if (reg->valid == 0)
-               {
-                       reg_arch_type_t *arch_type = register_get_arch_type(reg->arch_type);
-                       if (arch_type == NULL)
-                       {
-                               ERROR("BUG: encountered unregistered arch type");
-                               return ERROR_OK;
-                       }
-                       arch_type->get(reg);
-               }
-               value = buf_to_str(reg->value, reg->size, 16);
-               command_print(cmd_ctx, "%s (/%i): 0x%s", reg->name, reg->size, value);
-               free(value);
-               return ERROR_OK;
-       }
-       
-       /* set register value */
-       if (argc == 2)
-       {
-               u8 *buf = malloc(CEIL(reg->size, 8));
-               str_to_buf(args[1], strlen(args[1]), buf, reg->size, 0);
-
-               reg_arch_type_t *arch_type = register_get_arch_type(reg->arch_type);
-               if (arch_type == NULL)
-               {
-                       ERROR("BUG: encountered unregistered arch type");
-                       return ERROR_OK;
-               }
-               
-               arch_type->set(reg, buf);
-               
-               value = buf_to_str(reg->value, reg->size, 16);
-               command_print(cmd_ctx, "%s (/%i): 0x%s", reg->name, reg->size, value);
-               free(value);
-               
-               free(buf);
-               
-               return ERROR_OK;
-       }
-       
-       command_print(cmd_ctx, "usage: reg <#|name> [value]");
-       
-       return ERROR_OK;
-}
-
-static int wait_state(struct command_context_s *cmd_ctx, char *cmd, enum target_state state, int ms);
-
-int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       target_t *target = get_current_target(cmd_ctx);
-
-       if (argc == 0)
-       {
-               target->type->poll(target);
-                       target_arch_state(target);
-       }
-       else
-       {
-               if (strcmp(args[0], "on") == 0)
-               {
-                       target_continous_poll = 1;
-               }
-               else if (strcmp(args[0], "off") == 0)
-               {
-                       target_continous_poll = 0;
-               }
-               else
-               {
-                       command_print(cmd_ctx, "arg is \"on\" or \"off\"");
-               }
-       }
-       
-       
-       return ERROR_OK;
-}
-
-int handle_wait_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       int ms = 5000;
-       
-       if (argc > 0)
-       {
-               char *end;
-
-               ms = strtoul(args[0], &end, 0) * 1000;
-               if (*end)
-               {
-                       command_print(cmd_ctx, "usage: %s [seconds]", cmd);
-                       return ERROR_OK;
-               }
-       }
-
-       return wait_state(cmd_ctx, cmd, TARGET_HALTED, ms); 
-}
-
-static void target_process_events(struct command_context_s *cmd_ctx)
-{
-       target_t *target = get_current_target(cmd_ctx);
-       target->type->poll(target);
-       target_call_timer_callbacks();
-}
-
-static int wait_state(struct command_context_s *cmd_ctx, char *cmd, enum target_state state, int ms)
-{
-       int retval;
-       struct timeval timeout, now;
-       
-       gettimeofday(&timeout, NULL);
-       timeval_add_time(&timeout, 0, ms * 1000);
-       
-       target_t *target = get_current_target(cmd_ctx);
-       for (;;)
-       {
-               if ((retval=target->type->poll(target))!=ERROR_OK)
-                       return retval;
-               target_call_timer_callbacks();
-               if (target->state == state)
-               {
-                       break;
-               }
-               command_print(cmd_ctx, "waiting for target %s...", target_state_strings[state]);
-               
-               gettimeofday(&now, NULL);
-               if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec) && (now.tv_usec >= timeout.tv_usec)))
-               {
-                       command_print(cmd_ctx, "timed out while waiting for target %s", target_state_strings[state]);
-                       ERROR("timed out while waiting for target %s", target_state_strings[state]);
-                       break;
-               }
-       }
-       
-       return ERROR_OK;
-}
-
-int handle_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       int retval;
-       target_t *target = get_current_target(cmd_ctx);
-
-       DEBUG("-");
-       
-       command_print(cmd_ctx, "requesting target halt...");
-
-       if ((retval = target->type->halt(target)) != ERROR_OK)
-       {       
-               switch (retval)
-               {
-                       case ERROR_TARGET_ALREADY_HALTED:
-                               command_print(cmd_ctx, "target already halted");
-                               break;
-                       case ERROR_TARGET_TIMEOUT:
-                               command_print(cmd_ctx, "target timed out... shutting down");
-                               return retval;
-                       default:
-                               command_print(cmd_ctx, "unknown error... shutting down");
-                               return retval;
-               }
-       }
-       
-       return handle_wait_halt_command(cmd_ctx, cmd, args, argc);
-}
-
-/* what to do on daemon startup */
-int handle_daemon_startup_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       if (argc == 1)
-       {
-               if (strcmp(args[0], "attach") == 0)
-               {
-                       startup_mode = DAEMON_ATTACH;
-                       return ERROR_OK;
-               }
-               else if (strcmp(args[0], "reset") == 0)
-               {
-                       startup_mode = DAEMON_RESET;
-                       return ERROR_OK;
-               }
-       }
-       
-       WARNING("invalid daemon_startup configuration directive: %s", args[0]);
-       return ERROR_OK;
-
-}
-               
-int handle_soft_reset_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       target_t *target = get_current_target(cmd_ctx);
-       int retval;
-       
-       command_print(cmd_ctx, "requesting target halt and executing a soft reset");
-       
-       if ((retval = target->type->soft_reset_halt(target)) != ERROR_OK)
-       {       
-               switch (retval)
-               {
-                       case ERROR_TARGET_TIMEOUT:
-                               command_print(cmd_ctx, "target timed out... shutting down");
-                               exit(-1);
-                       default:
-                               command_print(cmd_ctx, "unknown error... shutting down");
-                               exit(-1);
-               }
-       }
-       
-       return ERROR_OK;
-}
-
-int handle_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       target_t *target = get_current_target(cmd_ctx);
-       enum target_reset_mode reset_mode = target->reset_mode;
-       enum target_reset_mode save = target->reset_mode;
-       
-       DEBUG("-");
-       
-       if (argc >= 1)
-       {
-               if (strcmp("run", args[0]) == 0)
-                       reset_mode = RESET_RUN;
-               else if (strcmp("halt", args[0]) == 0)
-                       reset_mode = RESET_HALT;
-               else if (strcmp("init", args[0]) == 0)
-                       reset_mode = RESET_INIT;
-               else if (strcmp("run_and_halt", args[0]) == 0)
-               {
-                       reset_mode = RESET_RUN_AND_HALT;
-                       if (argc >= 2)
-                       {
-                               target->run_and_halt_time = strtoul(args[1], NULL, 0);
-                       }
-               }
-               else if (strcmp("run_and_init", args[0]) == 0)
-               {
-                       reset_mode = RESET_RUN_AND_INIT;
-                       if (argc >= 2)
-                       {
-                               target->run_and_halt_time = strtoul(args[1], NULL, 0);
-                       }
-               }
-               else
-               {
-                       command_print(cmd_ctx, "usage: reset ['run', 'halt', 'init', 'run_and_halt', 'run_and_init]");
-                       return ERROR_OK;
-               }
-       }
-       
-       /* temporarily modify mode of current reset target */
-       target->reset_mode = reset_mode;
-
-       /* reset *all* targets */
-       target_process_reset(cmd_ctx);
-       
-       /* Restore default reset mode for this target */
-    target->reset_mode = save;
-       
-       return ERROR_OK;
-}
-
-int handle_resume_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       int retval;
-       target_t *target = get_current_target(cmd_ctx);
-       
-       if (argc == 0)
-               retval = target->type->resume(target, 1, 0, 1, 0); /* current pc, addr = 0, handle breakpoints, not debugging */
-       else if (argc == 1)
-               retval = target->type->resume(target, 0, strtoul(args[0], NULL, 0), 1, 0); /* addr = args[0], handle breakpoints, not debugging */
-       else
-       {
-               return ERROR_COMMAND_SYNTAX_ERROR;
-       }
-
-       target_process_events(cmd_ctx);
-       
-       target_arch_state(target);
-       
-       return retval;
-}
-
-int handle_step_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       target_t *target = get_current_target(cmd_ctx);
-       
-       DEBUG("-");
-       
-       if (argc == 0)
-               target->type->step(target, 1, 0, 1); /* current pc, addr = 0, handle breakpoints */
-
-       if (argc == 1)
-               target->type->step(target, 0, strtoul(args[0], NULL, 0), 1); /* addr = args[0], handle breakpoints */
-       
-       return ERROR_OK;
-}
-
-int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       const int line_bytecnt = 32;
-       int count = 1;
-       int size = 4;
-       u32 address = 0;
-       int line_modulo;
-       int i;
-
-       char output[128];
-       int output_len;
-
-       int retval;
-
-       u8 *buffer;
-       target_t *target = get_current_target(cmd_ctx);
-
-       if (argc < 1)
-               return ERROR_OK;
-
-       if (argc == 2)
-               count = strtoul(args[1], NULL, 0);
-
-       address = strtoul(args[0], NULL, 0);
-       
-
-       switch (cmd[2])
-       {
-               case 'w':
-                       size = 4; line_modulo = line_bytecnt / 4;
-                       break;
-               case 'h':
-                       size = 2; line_modulo = line_bytecnt / 2;
-                       break;
-               case 'b':
-                       size = 1; line_modulo = line_bytecnt / 1;
-                       break;
-               default:
-                       return ERROR_OK;
-       }
-
-       buffer = calloc(count, size);
-       retval  = target->type->read_memory(target, address, size, count, buffer);
-       if (retval != ERROR_OK)
-       {
-               switch (retval)
-               {
-                       case ERROR_TARGET_UNALIGNED_ACCESS:
-                               command_print(cmd_ctx, "error: address not aligned");
-                               break;
-                       case ERROR_TARGET_NOT_HALTED:
-                               command_print(cmd_ctx, "error: target must be halted for memory accesses");
-                               break;                  
-                       case ERROR_TARGET_DATA_ABORT:
-                               command_print(cmd_ctx, "error: access caused data abort, system possibly corrupted");
-                               break;
-                       default:
-                               command_print(cmd_ctx, "error: unknown error");
-                               break;
-               }
-               return ERROR_OK;
-       }
-
-       output_len = 0;
-
-       for (i = 0; i < count; i++)
-       {
-               if (i%line_modulo == 0)
-                       output_len += snprintf(output + output_len, 128 - output_len, "0x%8.8x: ", address + (i*size));
-               
-               switch (size)
-               {
-                       case 4:
-                               output_len += snprintf(output + output_len, 128 - output_len, "%8.8x ", target_buffer_get_u32(target, &buffer[i*4]));
-                               break;
-                       case 2:
-                               output_len += snprintf(output + output_len, 128 - output_len, "%4.4x ", target_buffer_get_u16(target, &buffer[i*2]));
-                               break;
-                       case 1:
-                               output_len += snprintf(output + output_len, 128 - output_len, "%2.2x ", buffer[i*1]);
-                               break;
-               }
-
-               if ((i%line_modulo == line_modulo-1) || (i == count - 1))
-               {
-                       command_print(cmd_ctx, output);
-                       output_len = 0;
-               }
-       }
-
-       free(buffer);
-       
-       return ERROR_OK;
-}
-
-int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       u32 address = 0;
-       u32 value = 0;
-       int retval;
-       target_t *target = get_current_target(cmd_ctx);
-       u8 value_buf[4];
-
-       if (argc < 2)
-               return ERROR_OK;
-
-       address = strtoul(args[0], NULL, 0);
-       value = strtoul(args[1], NULL, 0);
-
-       switch (cmd[2])
-       {
-               case 'w':
-                       target_buffer_set_u32(target, value_buf, value);
-                       retval = target->type->write_memory(target, address, 4, 1, value_buf);
-                       break;
-               case 'h':
-                       target_buffer_set_u16(target, value_buf, value);
-                       retval = target->type->write_memory(target, address, 2, 1, value_buf);
-                       break;
-               case 'b':
-                       value_buf[0] = value;
-                       retval = target->type->write_memory(target, address, 1, 1, value_buf);
-                       break;
-               default:
-                       return ERROR_OK;
-       }
-
-       switch (retval)
-       {
-               case ERROR_TARGET_UNALIGNED_ACCESS:
-                       command_print(cmd_ctx, "error: address not aligned");
-                       break;
-               case ERROR_TARGET_DATA_ABORT:
-                       command_print(cmd_ctx, "error: access caused data abort, system possibly corrupted");
-                       break;
-               case ERROR_TARGET_NOT_HALTED:
-                       command_print(cmd_ctx, "error: target must be halted for memory accesses");
-                       break;
-               case ERROR_OK:
-                       break;
-               default:
-                       command_print(cmd_ctx, "error: unknown error");
-                       break;
-       }
-
-       return ERROR_OK;
-
-}
-
-int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       u8 *buffer;
-       u32 buf_cnt;
-       u32 image_size;
-       int i;
-       int retval;
-
-       image_t image;  
-       
-       duration_t duration;
-       char *duration_text;
-       
-       target_t *target = get_current_target(cmd_ctx);
-
-       if (argc < 1)
-       {
-               command_print(cmd_ctx, "usage: load_image <filename> [address] [type]");
-               return ERROR_OK;
-       }
-       
-       /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
-       if (argc >= 2)
-       {
-               image.base_address_set = 1;
-               image.base_address = strtoul(args[1], NULL, 0);
-       }
-       else
-       {
-               image.base_address_set = 0;
-       }
-       
-       image.start_address_set = 0;
-
-       duration_start_measure(&duration);
-       
-       if (image_open(&image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
-       {
-               command_print(cmd_ctx, "load_image error: %s", image.error_str);
-               return ERROR_OK;
-       }
-       
-       image_size = 0x0;
-       for (i = 0; i < image.num_sections; i++)
-       {
-               buffer = malloc(image.sections[i].size);
-               if (buffer == NULL)
-               {
-                       command_print(cmd_ctx, "error allocating buffer for section (%d bytes)", image.sections[i].size);
-                       break;
-               }
-               
-               if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
-               {
-                       ERROR("image_read_section failed with error code: %i", retval);
-                       command_print(cmd_ctx, "image reading failed, download aborted");
-                       free(buffer);
-                       image_close(&image);
-                       return ERROR_OK;
-               }
-               target_write_buffer(target, image.sections[i].base_address, buf_cnt, buffer);
-               image_size += buf_cnt;
-               command_print(cmd_ctx, "%u byte written at address 0x%8.8x", buf_cnt, image.sections[i].base_address);
-               
-               free(buffer);
-       }
-
-       duration_stop_measure(&duration, &duration_text);
-       command_print(cmd_ctx, "downloaded %u byte in %s", image_size, duration_text);
-       free(duration_text);
-       
-       image_close(&image);
-
-       return ERROR_OK;
-
-}
-
-int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       fileio_t fileio;
-       
-       u32 address;
-       u32 size;
-       u8 buffer[560];
-       int retval;
-       
-       duration_t duration;
-       char *duration_text;
-       
-       target_t *target = get_current_target(cmd_ctx);
-
-       if (argc != 3)
-       {
-               command_print(cmd_ctx, "usage: dump_image <filename> <address> <size>");
-               return ERROR_OK;
-       }
-
-       address = strtoul(args[1], NULL, 0);
-       size = strtoul(args[2], NULL, 0);
-
-       if ((address & 3) || (size & 3))
-       {
-               command_print(cmd_ctx, "only 32-bit aligned address and size are supported");
-               return ERROR_OK;
-       }
-       
-       if (fileio_open(&fileio, args[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)
-       {
-               command_print(cmd_ctx, "dump_image error: %s", fileio.error_str);
-               return ERROR_OK;
-       }
-       
-       duration_start_measure(&duration);
-       
-       while (size > 0)
-       {
-               u32 size_written;
-               u32 this_run_size = (size > 560) ? 560 : size;
-               
-               retval = target->type->read_memory(target, address, 4, this_run_size / 4, buffer);
-               if (retval != ERROR_OK)
-               {
-                       command_print(cmd_ctx, "Reading memory failed %d", retval);
-                       break;
-               }
-               
-               fileio_write(&fileio, this_run_size, buffer, &size_written);
-               
-               size -= this_run_size;
-               address += this_run_size;
-       }
-
-       fileio_close(&fileio);
-
-       duration_stop_measure(&duration, &duration_text);
-       command_print(cmd_ctx, "dumped %"PRIi64" byte in %s", fileio.size, duration_text);
-       free(duration_text);
-       
-       return ERROR_OK;
-}
-
-int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       u8 *buffer;
-       u32 buf_cnt;
-       u32 image_size;
-       int i;
-       int retval;
-       u32 checksum = 0;
-       u32 mem_checksum = 0;
-
-       image_t image;  
-       
-       duration_t duration;
-       char *duration_text;
-       
-       target_t *target = get_current_target(cmd_ctx);
-       
-       if (argc < 1)
-       {
-               command_print(cmd_ctx, "usage: verify_image <file> [offset] [type]");
-               return ERROR_OK;
-       }
-       
-       if (!target)
-       {
-               ERROR("no target selected");
-               return ERROR_OK;
-       }
-       
-       duration_start_measure(&duration);
-       
-       if (argc >= 2)
-       {
-               image.base_address_set = 1;
-               image.base_address = strtoul(args[1], NULL, 0);
-       }
-       else
-       {
-               image.base_address_set = 0;
-               image.base_address = 0x0;
-       }
-
-       image.start_address_set = 0;
-
-       if (image_open(&image, args[0], (argc == 3) ? args[2] : NULL) != ERROR_OK)
-       {
-               command_print(cmd_ctx, "verify_image error: %s", image.error_str);
-               return ERROR_OK;
-       }
-       
-       image_size = 0x0;
-       for (i = 0; i < image.num_sections; i++)
-       {
-               buffer = malloc(image.sections[i].size);
-               if (buffer == NULL)
-               {
-                       command_print(cmd_ctx, "error allocating buffer for section (%d bytes)", image.sections[i].size);
-                       break;
-               }
-               if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
-               {
-                       ERROR("image_read_section failed with error code: %i", retval);
-                       command_print(cmd_ctx, "image reading failed, verify aborted");
-                       free(buffer);
-                       image_close(&image);
-                       return ERROR_OK;
-               }
-               
-               /* calculate checksum of image */
-               image_calculate_checksum( buffer, buf_cnt, &checksum );
-               
-               retval = target_checksum_memory(target, image.sections[i].base_address, buf_cnt, &mem_checksum);
-               
-               if( retval != ERROR_OK )
-               {
-                       command_print(cmd_ctx, "could not calculate checksum, verify aborted");
-                       free(buffer);
-                       image_close(&image);
-                       return ERROR_OK;
-               }
-               
-               if( checksum != mem_checksum )
-               {
-                       /* failed crc checksum, fall back to a binary compare */
-                       u8 *data;
-                       
-                       command_print(cmd_ctx, "checksum mismatch - attempting binary compare");
-                       
-                       data = (u8*)malloc(buf_cnt);
-                       
-                       /* Can we use 32bit word accesses? */
-                       int size = 1;
-                       int count = buf_cnt;
-                       if ((count % 4) == 0)
-                       {
-                               size *= 4;
-                               count /= 4;
-                       }
-                       retval = target->type->read_memory(target, image.sections[i].base_address, size, count, data);
-       
-                       if (retval == ERROR_OK)
-                       {
-                               int t;
-                               for (t = 0; t < buf_cnt; t++)
-                               {
-                                       if (data[t] != buffer[t])
-                                       {
-                                               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]);
-                                               free(data);
-                                               free(buffer);
-                                               image_close(&image);
-                                               return ERROR_OK;
-                                       }
-                               }
-                       }
-                       
-                       free(data);
-               }
-               
-               free(buffer);
-               image_size += buf_cnt;
-       }
-       
-       duration_stop_measure(&duration, &duration_text);
-       command_print(cmd_ctx, "verified %u bytes in %s", image_size, duration_text);
-       free(duration_text);
-       
-       image_close(&image);
-       
-       return ERROR_OK;
-}
-
-int handle_bp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       int retval;
-       target_t *target = get_current_target(cmd_ctx);
-
-       if (argc == 0)
-       {
-               breakpoint_t *breakpoint = target->breakpoints;
-
-               while (breakpoint)
-               {
-                       if (breakpoint->type == BKPT_SOFT)
-                       {
-                               char* buf = buf_to_str(breakpoint->orig_instr, breakpoint->length, 16);
-                               command_print(cmd_ctx, "0x%8.8x, 0x%x, %i, 0x%s", breakpoint->address, breakpoint->length, breakpoint->set, buf);
-                               free(buf);
-                       }
-                       else
-                       {
-                               command_print(cmd_ctx, "0x%8.8x, 0x%x, %i", breakpoint->address, breakpoint->length, breakpoint->set);
-                       }
-                       breakpoint = breakpoint->next;
-               }
-       }
-       else if (argc >= 2)
-       {
-               int hw = BKPT_SOFT;
-               u32 length = 0;
-
-               length = strtoul(args[1], NULL, 0);
-               
-               if (argc >= 3)
-                       if (strcmp(args[2], "hw") == 0)
-                               hw = BKPT_HARD;
-
-               if ((retval = breakpoint_add(target, strtoul(args[0], NULL, 0), length, hw)) != ERROR_OK)
-               {
-                       switch (retval)
-                       {
-                               case ERROR_TARGET_NOT_HALTED:
-                                       command_print(cmd_ctx, "target must be halted to set breakpoints");
-                                       break;
-                               case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:
-                                       command_print(cmd_ctx, "no more breakpoints available");
-                                       break;
-                               default:
-                                       command_print(cmd_ctx, "unknown error, breakpoint not set");
-                                       break;
-                       }
-               }
-               else
-               {
-                       command_print(cmd_ctx, "breakpoint added at address 0x%8.8x", strtoul(args[0], NULL, 0));
-               }
-       }
-       else
-       {
-               command_print(cmd_ctx, "usage: bp <address> <length> ['hw']");
-       }
-
-       return ERROR_OK;
-}
-
-int handle_rbp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       target_t *target = get_current_target(cmd_ctx);
-
-       if (argc > 0)
-               breakpoint_remove(target, strtoul(args[0], NULL, 0));
-
-       return ERROR_OK;
-}
-
-int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       target_t *target = get_current_target(cmd_ctx);
-       int retval;
-
-       if (argc == 0)
-       {
-               watchpoint_t *watchpoint = target->watchpoints;
-
-               while (watchpoint)
-               {
-                       command_print(cmd_ctx, "address: 0x%8.8x, mask: 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);
-                       watchpoint = watchpoint->next;
-               }
-       } 
-       else if (argc >= 2)
-       {
-               enum watchpoint_rw type = WPT_ACCESS;
-               u32 data_value = 0x0;
-               u32 data_mask = 0xffffffff;
-               
-               if (argc >= 3)
-               {
-                       switch(args[2][0])
-                       {
-                               case 'r':
-                                       type = WPT_READ;
-                                       break;
-                               case 'w':
-                                       type = WPT_WRITE;
-                                       break;
-                               case 'a':
-                                       type = WPT_ACCESS;
-                                       break;
-                               default:
-                                       command_print(cmd_ctx, "usage: wp <address> <length> [r/w/a] [value] [mask]");
-                                       return ERROR_OK;
-                       }
-               }
-               if (argc >= 4)
-               {
-                       data_value = strtoul(args[3], NULL, 0);
-               }
-               if (argc >= 5)
-               {
-                       data_mask = strtoul(args[4], NULL, 0);
-               }
-               
-               if ((retval = watchpoint_add(target, strtoul(args[0], NULL, 0),
-                               strtoul(args[1], NULL, 0), type, data_value, data_mask)) != ERROR_OK)
-               {
-                       switch (retval)
-                       {
-                               case ERROR_TARGET_NOT_HALTED:
-                                       command_print(cmd_ctx, "target must be halted to set watchpoints");
-                                       break;
-                               case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:
-                                       command_print(cmd_ctx, "no more watchpoints available");
-                                       break;
-                               default:
-                                       command_print(cmd_ctx, "unknown error, watchpoint not set");
-                                       break;
-                       }       
-               }
-       }
-       else
-       {
-               command_print(cmd_ctx, "usage: wp <address> <length> [r/w/a] [value] [mask]");
-       }
-               
-       return ERROR_OK;
-}
-
-int handle_rwp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       target_t *target = get_current_target(cmd_ctx);
-
-       if (argc > 0)
-               watchpoint_remove(target, strtoul(args[0], NULL, 0));
-       
-       return ERROR_OK;
-}
-
-int handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
-{
-       int retval;
-       target_t *target = get_current_target(cmd_ctx);
-       u32 va;
-       u32 pa;
-
-       if (argc != 1)
-       {
-               return ERROR_COMMAND_SYNTAX_ERROR;
-       }
-       va = strtoul(args[0], NULL, 0);
-
-       retval = target->type->virt2phys(target, va, &pa);
-       if (retval == ERROR_OK)
-       {
-               command_print(cmd_ctx, "Physical address 0x%08x", pa);
-       }
-       else
-       {
-               /* lower levels will have logged a detailed error which is 
-                * forwarded to telnet/GDB session.  
-                */
-       }
-       return retval;
-}
+/***************************************************************************\r
+ *   Copyright (C) 2005 by Dominic Rath                                    *\r
+ *   Dominic.Rath@gmx.de                                                   *\r
+ *                                                                         *\r
+ *   This program is free software; you can redistribute it and/or modify  *\r
+ *   it under the terms of the GNU General Public License as published by  *\r
+ *   the Free Software Foundation; either version 2 of the License, or     *\r
+ *   (at your option) any later version.                                   *\r
+ *                                                                         *\r
+ *   This program is distributed in the hope that it will be useful,       *\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\r
+ *   GNU General Public License for more details.                          *\r
+ *                                                                         *\r
+ *   You should have received a copy of the GNU General Public License     *\r
+ *   along with this program; if not, write to the                         *\r
+ *   Free Software Foundation, Inc.,                                       *\r
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *\r
+ ***************************************************************************/\r
+#ifdef HAVE_CONFIG_H\r
+#include "config.h"\r
+#endif\r
+\r
+#include "replacements.h"\r
+#include "target.h"\r
+#include "target_request.h"\r
+\r
+#include "log.h"\r
+#include "configuration.h"\r
+#include "binarybuffer.h"\r
+#include "jtag.h"\r
+\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <inttypes.h>\r
+\r
+#include <sys/types.h>\r
+#include <sys/stat.h>\r
+#include <unistd.h>\r
+#include <errno.h>\r
+\r
+#include <sys/time.h>\r
+#include <time.h>\r
+\r
+#include <time_support.h>\r
+\r
+#include <fileio.h>\r
+#include <image.h>\r
+\r
+int cli_target_callback_event_handler(struct target_s *target, enum target_event event, void *priv);\r
+\r
+\r
+int handle_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int handle_daemon_startup_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int handle_targets_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+\r
+int handle_target_script_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int handle_run_and_halt_time_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int handle_working_area_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+\r
+int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int handle_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int handle_wait_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int handle_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int handle_soft_reset_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int handle_resume_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int handle_step_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int handle_bp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int handle_rbp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int handle_rwp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc);\r
+\r
+/* targets\r
+ */\r
+extern target_type_t arm7tdmi_target;\r
+extern target_type_t arm720t_target;\r
+extern target_type_t arm9tdmi_target;\r
+extern target_type_t arm920t_target;\r
+extern target_type_t arm966e_target;\r
+extern target_type_t arm926ejs_target;\r
+extern target_type_t feroceon_target;\r
+extern target_type_t xscale_target;\r
+extern target_type_t cortexm3_target;\r
+\r
+target_type_t *target_types[] =\r
+{\r
+       &arm7tdmi_target,\r
+       &arm9tdmi_target,\r
+       &arm920t_target,\r
+       &arm720t_target,\r
+       &arm966e_target,\r
+       &arm926ejs_target,\r
+       &feroceon_target,\r
+       &xscale_target,\r
+       &cortexm3_target,\r
+       NULL,\r
+};\r
+\r
+target_t *targets = NULL;\r
+target_event_callback_t *target_event_callbacks = NULL;\r
+target_timer_callback_t *target_timer_callbacks = NULL;\r
+\r
+char *target_state_strings[] =\r
+{\r
+       "unknown",\r
+       "running",\r
+       "halted",\r
+       "reset",\r
+       "debug_running",\r
+};\r
+\r
+char *target_debug_reason_strings[] =\r
+{\r
+       "debug request", "breakpoint", "watchpoint",\r
+       "watchpoint and breakpoint", "single step",\r
+       "target not halted"\r
+};\r
+\r
+char *target_endianess_strings[] =\r
+{\r
+       "big endian",\r
+       "little endian",\r
+};\r
+\r
+enum daemon_startup_mode startup_mode = DAEMON_ATTACH;\r
+\r
+static int target_continous_poll = 1;\r
+\r
+/* read a u32 from a buffer in target memory endianness */\r
+u32 target_buffer_get_u32(target_t *target, u8 *buffer)\r
+{\r
+       if (target->endianness == TARGET_LITTLE_ENDIAN)\r
+               return le_to_h_u32(buffer);\r
+       else\r
+               return be_to_h_u32(buffer);\r
+}\r
+\r
+/* read a u16 from a buffer in target memory endianness */\r
+u16 target_buffer_get_u16(target_t *target, u8 *buffer)\r
+{\r
+       if (target->endianness == TARGET_LITTLE_ENDIAN)\r
+               return le_to_h_u16(buffer);\r
+       else\r
+               return be_to_h_u16(buffer);\r
+}\r
+\r
+/* write a u32 to a buffer in target memory endianness */\r
+void target_buffer_set_u32(target_t *target, u8 *buffer, u32 value)\r
+{\r
+       if (target->endianness == TARGET_LITTLE_ENDIAN)\r
+               h_u32_to_le(buffer, value);\r
+       else\r
+               h_u32_to_be(buffer, value);\r
+}\r
+\r
+/* write a u16 to a buffer in target memory endianness */\r
+void target_buffer_set_u16(target_t *target, u8 *buffer, u16 value)\r
+{\r
+       if (target->endianness == TARGET_LITTLE_ENDIAN)\r
+               h_u16_to_le(buffer, value);\r
+       else\r
+               h_u16_to_be(buffer, value);\r
+}\r
+\r
+/* returns a pointer to the n-th configured target */\r
+target_t* get_target_by_num(int num)\r
+{\r
+       target_t *target = targets;\r
+       int i = 0;\r
+\r
+       while (target)\r
+       {\r
+               if (num == i)\r
+                       return target;\r
+               target = target->next;\r
+               i++;\r
+       }\r
+\r
+       return NULL;\r
+}\r
+\r
+int get_num_by_target(target_t *query_target)\r
+{\r
+       target_t *target = targets;\r
+       int i = 0;      \r
+       \r
+       while (target)\r
+       {\r
+               if (target == query_target)\r
+                       return i;\r
+               target = target->next;\r
+               i++;\r
+       }\r
+       \r
+       return -1;\r
+}\r
+\r
+target_t* get_current_target(command_context_t *cmd_ctx)\r
+{\r
+       target_t *target = get_target_by_num(cmd_ctx->current_target);\r
+       \r
+       if (target == NULL)\r
+       {\r
+               ERROR("BUG: current_target out of bounds");\r
+               exit(-1);\r
+       }\r
+       \r
+       return target;\r
+}\r
+\r
+/* Process target initialization, when target entered debug out of reset\r
+ * the handler is unregistered at the end of this function, so it's only called once\r
+ */\r
+int target_init_handler(struct target_s *target, enum target_event event, void *priv)\r
+{\r
+       FILE *script;\r
+       struct command_context_s *cmd_ctx = priv;\r
+       \r
+       if ((event == TARGET_EVENT_HALTED) && (target->reset_script))\r
+       {\r
+               target_unregister_event_callback(target_init_handler, priv);\r
+\r
+               script = open_file_from_path(cmd_ctx, target->reset_script, "r");\r
+               if (!script)\r
+               {\r
+                       ERROR("couldn't open script file %s", target->reset_script);\r
+                               return ERROR_OK;\r
+               }\r
+\r
+               INFO("executing reset script '%s'", target->reset_script);\r
+               command_run_file(cmd_ctx, script, COMMAND_EXEC);\r
+               fclose(script);\r
+\r
+               jtag_execute_queue();\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int target_run_and_halt_handler(void *priv)\r
+{\r
+       target_t *target = priv;\r
+       \r
+       target->type->halt(target);\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int target_process_reset(struct command_context_s *cmd_ctx)\r
+{\r
+       int retval = ERROR_OK;\r
+       target_t *target;\r
+       struct timeval timeout, now;\r
+       \r
+       /* prepare reset_halt where necessary */\r
+       target = targets;\r
+       while (target)\r
+       {\r
+               if (jtag_reset_config & RESET_SRST_PULLS_TRST)\r
+               {\r
+                       switch (target->reset_mode)\r
+                       {\r
+                               case RESET_HALT:\r
+                                       command_print(cmd_ctx, "nSRST pulls nTRST, falling back to RESET_RUN_AND_HALT");\r
+                                       target->reset_mode = RESET_RUN_AND_HALT;\r
+                                       break;\r
+                               case RESET_INIT:\r
+                                       command_print(cmd_ctx, "nSRST pulls nTRST, falling back to RESET_RUN_AND_INIT");\r
+                                       target->reset_mode = RESET_RUN_AND_INIT;\r
+                                       break;\r
+                               default:\r
+                                       break;\r
+                       } \r
+               }\r
+               switch (target->reset_mode)\r
+               {\r
+                       case RESET_HALT:\r
+                       case RESET_INIT:\r
+                               target->type->prepare_reset_halt(target);\r
+                               break;\r
+                       default:\r
+                               break;\r
+               }\r
+               target = target->next;\r
+       }\r
+       \r
+       target = targets;\r
+       while (target)\r
+       {\r
+               target->type->assert_reset(target);\r
+               target = target->next;\r
+       }\r
+       jtag_execute_queue();\r
+       \r
+       /* request target halt if necessary, and schedule further action */\r
+       target = targets;\r
+       while (target)\r
+       {\r
+               switch (target->reset_mode)\r
+               {\r
+                       case RESET_RUN:\r
+                               /* nothing to do if target just wants to be run */\r
+                               break;\r
+                       case RESET_RUN_AND_HALT:\r
+                               /* schedule halt */\r
+                               target_register_timer_callback(target_run_and_halt_handler, target->run_and_halt_time, 0, target);\r
+                               break;\r
+                       case RESET_RUN_AND_INIT:\r
+                               /* schedule halt */\r
+                               target_register_timer_callback(target_run_and_halt_handler, target->run_and_halt_time, 0, target);\r
+                               target_register_event_callback(target_init_handler, cmd_ctx);\r
+                               break;\r
+                       case RESET_HALT:\r
+                               target->type->halt(target);\r
+                               break;\r
+                       case RESET_INIT:\r
+                               target->type->halt(target);\r
+                               target_register_event_callback(target_init_handler, cmd_ctx);\r
+                               break;\r
+                       default:\r
+                               ERROR("BUG: unknown target->reset_mode");\r
+               }\r
+               target = target->next;\r
+       }\r
+       \r
+       target = targets;\r
+       while (target)\r
+       {\r
+               target->type->deassert_reset(target);\r
+               target = target->next;\r
+       }\r
+       jtag_execute_queue();\r
+\r
+       /* Wait for reset to complete, maximum 5 seconds. */    \r
+       gettimeofday(&timeout, NULL);\r
+       timeval_add_time(&timeout, 5, 0);\r
+       for(;;)\r
+       {\r
+               gettimeofday(&now, NULL);\r
+               \r
+               target_call_timer_callbacks();\r
+               \r
+               target = targets;\r
+               while (target)\r
+               {\r
+                       target->type->poll(target);\r
+                       if ((target->reset_mode == RESET_RUN_AND_INIT) || (target->reset_mode == RESET_RUN_AND_HALT))\r
+                       {\r
+                               if (target->state != TARGET_HALTED)\r
+                               {\r
+                                       if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec) && (now.tv_usec >= timeout.tv_usec)))\r
+                                       {\r
+                                               command_print(cmd_ctx, "Timed out waiting for reset");\r
+                                               goto done;\r
+                                       }\r
+                                       usleep(100*1000); /* Do not eat all cpu */\r
+                                       goto again;\r
+                               }\r
+                       }\r
+                       target = target->next;\r
+               }\r
+               /* All targets we're waiting for are halted */\r
+               break;\r
+               \r
+               again:;\r
+       }\r
+       done:\r
+       \r
+       \r
+       /* We want any events to be processed before the prompt */\r
+       target_call_timer_callbacks();\r
+       \r
+       return retval;\r
+}\r
+\r
+static int default_virt2phys(struct target_s *target, u32 virtual, u32 *physical)\r
+{\r
+       *physical = virtual;\r
+       return ERROR_OK;\r
+}\r
+\r
+static int default_mmu(struct target_s *target, int *enabled)\r
+{\r
+       *enabled = 0;\r
+       return ERROR_OK;\r
+}\r
+\r
+int target_init(struct command_context_s *cmd_ctx)\r
+{\r
+       target_t *target = targets;\r
+       \r
+       while (target)\r
+       {\r
+               if (target->type->init_target(cmd_ctx, target) != ERROR_OK)\r
+               {\r
+                       ERROR("target '%s' init failed", target->type->name);\r
+                       exit(-1);\r
+               }\r
+               \r
+               /* Set up default functions if none are provided by target */\r
+               if (target->type->virt2phys == NULL)\r
+               {\r
+                       target->type->virt2phys = default_virt2phys;\r
+               }\r
+               if (target->type->mmu == NULL)\r
+               {\r
+                       target->type->mmu = default_mmu;\r
+               }\r
+               target = target->next;\r
+       }\r
+       \r
+       if (targets)\r
+       {\r
+               target_register_user_commands(cmd_ctx);\r
+               target_register_timer_callback(handle_target, 100, 1, NULL);\r
+       }\r
+               \r
+       return ERROR_OK;\r
+}\r
+\r
+int target_init_reset(struct command_context_s *cmd_ctx)\r
+{\r
+       if (startup_mode == DAEMON_RESET)\r
+               target_process_reset(cmd_ctx);\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int target_register_event_callback(int (*callback)(struct target_s *target, enum target_event event, void *priv), void *priv)\r
+{\r
+       target_event_callback_t **callbacks_p = &target_event_callbacks;\r
+       \r
+       if (callback == NULL)\r
+       {\r
+               return ERROR_INVALID_ARGUMENTS;\r
+       }\r
+       \r
+       if (*callbacks_p)\r
+       {\r
+               while ((*callbacks_p)->next)\r
+                       callbacks_p = &((*callbacks_p)->next);\r
+               callbacks_p = &((*callbacks_p)->next);\r
+       }\r
+       \r
+       (*callbacks_p) = malloc(sizeof(target_event_callback_t));\r
+       (*callbacks_p)->callback = callback;\r
+       (*callbacks_p)->priv = priv;\r
+       (*callbacks_p)->next = NULL;\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int target_register_timer_callback(int (*callback)(void *priv), int time_ms, int periodic, void *priv)\r
+{\r
+       target_timer_callback_t **callbacks_p = &target_timer_callbacks;\r
+       struct timeval now;\r
+       \r
+       if (callback == NULL)\r
+       {\r
+               return ERROR_INVALID_ARGUMENTS;\r
+       }\r
+       \r
+       if (*callbacks_p)\r
+       {\r
+               while ((*callbacks_p)->next)\r
+                       callbacks_p = &((*callbacks_p)->next);\r
+               callbacks_p = &((*callbacks_p)->next);\r
+       }\r
+       \r
+       (*callbacks_p) = malloc(sizeof(target_timer_callback_t));\r
+       (*callbacks_p)->callback = callback;\r
+       (*callbacks_p)->periodic = periodic;\r
+       (*callbacks_p)->time_ms = time_ms;\r
+       \r
+       gettimeofday(&now, NULL);\r
+       (*callbacks_p)->when.tv_usec = now.tv_usec + (time_ms % 1000) * 1000;\r
+       time_ms -= (time_ms % 1000);\r
+       (*callbacks_p)->when.tv_sec = now.tv_sec + (time_ms / 1000);\r
+       if ((*callbacks_p)->when.tv_usec > 1000000)\r
+       {\r
+               (*callbacks_p)->when.tv_usec = (*callbacks_p)->when.tv_usec - 1000000;\r
+               (*callbacks_p)->when.tv_sec += 1;\r
+       }\r
+       \r
+       (*callbacks_p)->priv = priv;\r
+       (*callbacks_p)->next = NULL;\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int target_unregister_event_callback(int (*callback)(struct target_s *target, enum target_event event, void *priv), void *priv)\r
+{\r
+       target_event_callback_t **p = &target_event_callbacks;\r
+       target_event_callback_t *c = target_event_callbacks;\r
+       \r
+       if (callback == NULL)\r
+       {\r
+               return ERROR_INVALID_ARGUMENTS;\r
+       }\r
+               \r
+       while (c)\r
+       {\r
+               target_event_callback_t *next = c->next;\r
+               if ((c->callback == callback) && (c->priv == priv))\r
+               {\r
+                       *p = next;\r
+                       free(c);\r
+                       return ERROR_OK;\r
+               }\r
+               else\r
+                       p = &(c->next);\r
+               c = next;\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int target_unregister_timer_callback(int (*callback)(void *priv), void *priv)\r
+{\r
+       target_timer_callback_t **p = &target_timer_callbacks;\r
+       target_timer_callback_t *c = target_timer_callbacks;\r
+       \r
+       if (callback == NULL)\r
+       {\r
+               return ERROR_INVALID_ARGUMENTS;\r
+       }\r
+               \r
+       while (c)\r
+       {\r
+               target_timer_callback_t *next = c->next;\r
+               if ((c->callback == callback) && (c->priv == priv))\r
+               {\r
+                       *p = next;\r
+                       free(c);\r
+                       return ERROR_OK;\r
+               }\r
+               else\r
+                       p = &(c->next);\r
+               c = next;\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int target_call_event_callbacks(target_t *target, enum target_event event)\r
+{\r
+       target_event_callback_t *callback = target_event_callbacks;\r
+       target_event_callback_t *next_callback;\r
+       \r
+       DEBUG("target event %i", event);\r
+       \r
+       while (callback)\r
+       {\r
+               next_callback = callback->next;\r
+               callback->callback(target, event, callback->priv);\r
+               callback = next_callback;\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int target_call_timer_callbacks()\r
+{\r
+       target_timer_callback_t *callback = target_timer_callbacks;\r
+       target_timer_callback_t *next_callback;\r
+       struct timeval now;\r
+\r
+       gettimeofday(&now, NULL);\r
+       \r
+       while (callback)\r
+       {\r
+               next_callback = callback->next;\r
+               \r
+               if (((now.tv_sec >= callback->when.tv_sec) && (now.tv_usec >= callback->when.tv_usec))\r
+                       || (now.tv_sec > callback->when.tv_sec))\r
+               {\r
+                       callback->callback(callback->priv);\r
+                       if (callback->periodic)\r
+                       {\r
+                               int time_ms = callback->time_ms;\r
+                               callback->when.tv_usec = now.tv_usec + (time_ms % 1000) * 1000;\r
+                               time_ms -= (time_ms % 1000);\r
+                               callback->when.tv_sec = now.tv_sec + time_ms / 1000;\r
+                               if (callback->when.tv_usec > 1000000)\r
+                               {\r
+                                       callback->when.tv_usec = callback->when.tv_usec - 1000000;\r
+                                       callback->when.tv_sec += 1;\r
+                               }\r
+                       }\r
+                       else\r
+                               target_unregister_timer_callback(callback->callback, callback->priv);\r
+               }\r
+                       \r
+               callback = next_callback;\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int target_alloc_working_area(struct target_s *target, u32 size, working_area_t **area)\r
+{\r
+       working_area_t *c = target->working_areas;\r
+       working_area_t *new_wa = NULL;\r
+       \r
+       /* Reevaluate working area address based on MMU state*/\r
+       if (target->working_areas == NULL)\r
+       {\r
+               int retval;\r
+               int enabled;\r
+               retval = target->type->mmu(target, &enabled);\r
+               if (retval != ERROR_OK)\r
+               {\r
+                       return retval;\r
+               }\r
+               if (enabled)\r
+               {\r
+                       target->working_area = target->working_area_virt;\r
+               }\r
+               else\r
+               {\r
+                       target->working_area = target->working_area_phys;\r
+               }\r
+       }\r
+       \r
+       /* only allocate multiples of 4 byte */\r
+       if (size % 4)\r
+       {\r
+               ERROR("BUG: code tried to allocate unaligned number of bytes, padding");\r
+               size = CEIL(size, 4);\r
+       }\r
+       \r
+       /* see if there's already a matching working area */\r
+       while (c)\r
+       {\r
+               if ((c->free) && (c->size == size))\r
+               {\r
+                       new_wa = c;\r
+                       break;\r
+               }\r
+               c = c->next;\r
+       }\r
+       \r
+       /* if not, allocate a new one */\r
+       if (!new_wa)\r
+       {\r
+               working_area_t **p = &target->working_areas;\r
+               u32 first_free = target->working_area;\r
+               u32 free_size = target->working_area_size;\r
+               \r
+               DEBUG("allocating new working area");\r
+               \r
+               c = target->working_areas;\r
+               while (c)\r
+               {\r
+                       first_free += c->size;\r
+                       free_size -= c->size;\r
+                       p = &c->next;\r
+                       c = c->next;\r
+               }\r
+               \r
+               if (free_size < size)\r
+               {\r
+                       WARNING("not enough working area available(requested %d, free %d)", size, free_size);\r
+                       return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\r
+               }\r
+               \r
+               new_wa = malloc(sizeof(working_area_t));\r
+               new_wa->next = NULL;\r
+               new_wa->size = size;\r
+               new_wa->address = first_free;\r
+               \r
+               if (target->backup_working_area)\r
+               {\r
+                       new_wa->backup = malloc(new_wa->size);\r
+                       target->type->read_memory(target, new_wa->address, 4, new_wa->size / 4, new_wa->backup);\r
+               }\r
+               else\r
+               {\r
+                       new_wa->backup = NULL;\r
+               }\r
+               \r
+               /* put new entry in list */\r
+               *p = new_wa;\r
+       }\r
+       \r
+       /* mark as used, and return the new (reused) area */\r
+       new_wa->free = 0;\r
+       *area = new_wa;\r
+       \r
+       /* user pointer */\r
+       new_wa->user = area;\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int target_free_working_area(struct target_s *target, working_area_t *area)\r
+{\r
+       if (area->free)\r
+               return ERROR_OK;\r
+       \r
+       if (target->backup_working_area)\r
+               target->type->write_memory(target, area->address, 4, area->size / 4, area->backup);\r
+       \r
+       area->free = 1;\r
+       \r
+       /* mark user pointer invalid */\r
+       *area->user = NULL;\r
+       area->user = NULL;\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int target_free_all_working_areas(struct target_s *target)\r
+{\r
+       working_area_t *c = target->working_areas;\r
+\r
+       while (c)\r
+       {\r
+               working_area_t *next = c->next;\r
+               target_free_working_area(target, c);\r
+               \r
+               if (c->backup)\r
+                       free(c->backup);\r
+               \r
+               free(c);\r
+               \r
+               c = next;\r
+       }\r
+       \r
+       target->working_areas = NULL;\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int target_register_commands(struct command_context_s *cmd_ctx)\r
+{\r
+       register_command(cmd_ctx, NULL, "target", handle_target_command, COMMAND_CONFIG, NULL);\r
+       register_command(cmd_ctx, NULL, "targets", handle_targets_command, COMMAND_EXEC, NULL);\r
+       register_command(cmd_ctx, NULL, "daemon_startup", handle_daemon_startup_command, COMMAND_CONFIG, NULL);\r
+       register_command(cmd_ctx, NULL, "target_script", handle_target_script_command, COMMAND_CONFIG, NULL);\r
+       register_command(cmd_ctx, NULL, "run_and_halt_time", handle_run_and_halt_time_command, COMMAND_CONFIG, NULL);\r
+       register_command(cmd_ctx, NULL, "working_area", handle_working_area_command, COMMAND_ANY, "working_area <target#> <address> <size> <'backup'|'nobackup'> [virtual address]");\r
+       register_command(cmd_ctx, NULL, "virt2phys", handle_virt2phys_command, COMMAND_ANY, "virt2phys <virtual address>");\r
+\r
+       return ERROR_OK;\r
+}\r
+\r
+int target_arch_state(struct target_s *target)\r
+{\r
+       int retval;\r
+       if (target==NULL)\r
+       {\r
+               USER("No target has been configured");\r
+               return ERROR_OK;\r
+       }\r
+       \r
+       USER("target state: %s", target_state_strings[target->state]);\r
+       \r
+       if (target->state!=TARGET_HALTED)\r
+               return ERROR_OK;\r
+       \r
+       retval=target->type->arch_state(target);\r
+       return retval;\r
+}\r
+\r
+/* Single aligned words are guaranteed to use 16 or 32 bit access \r
+ * mode respectively, otherwise data is handled as quickly as \r
+ * possible\r
+ */\r
+int target_write_buffer(struct target_s *target, u32 address, u32 size, u8 *buffer)\r
+{\r
+       int retval;\r
+       \r
+       DEBUG("writing buffer of %i byte at 0x%8.8x", size, address);\r
+       \r
+       if (((address % 2) == 0) && (size == 2))\r
+       {\r
+               return target->type->write_memory(target, address, 2, 1, buffer);\r
+       }\r
+       \r
+       /* handle unaligned head bytes */\r
+       if (address % 4)\r
+       {\r
+               int unaligned = 4 - (address % 4);\r
+               \r
+               if (unaligned > size)\r
+                       unaligned = size;\r
+\r
+               if ((retval = target->type->write_memory(target, address, 1, unaligned, buffer)) != ERROR_OK)\r
+                       return retval;\r
+               \r
+               buffer += unaligned;\r
+               address += unaligned;\r
+               size -= unaligned;\r
+       }\r
+               \r
+       /* handle aligned words */\r
+       if (size >= 4)\r
+       {\r
+               int aligned = size - (size % 4);\r
+       \r
+               /* use bulk writes above a certain limit. This may have to be changed */\r
+               if (aligned > 128)\r
+               {\r
+                       if ((retval = target->type->bulk_write_memory(target, address, aligned / 4, buffer)) != ERROR_OK)\r
+                               return retval;\r
+               }\r
+               else\r
+               {\r
+                       if ((retval = target->type->write_memory(target, address, 4, aligned / 4, buffer)) != ERROR_OK)\r
+                               return retval;\r
+               }\r
+               \r
+               buffer += aligned;\r
+               address += aligned;\r
+               size -= aligned;\r
+       }\r
+       \r
+       /* handle tail writes of less than 4 bytes */\r
+       if (size > 0)\r
+       {\r
+               if ((retval = target->type->write_memory(target, address, 1, size, buffer)) != ERROR_OK)\r
+                       return retval;\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+\r
+/* Single aligned words are guaranteed to use 16 or 32 bit access \r
+ * mode respectively, otherwise data is handled as quickly as \r
+ * possible\r
+ */\r
+int target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffer)\r
+{\r
+       int retval;\r
+       \r
+       DEBUG("reading buffer of %i byte at 0x%8.8x", size, address);\r
+       \r
+       if (((address % 2) == 0) && (size == 2))\r
+       {\r
+               return target->type->read_memory(target, address, 2, 1, buffer);\r
+       }\r
+       \r
+       /* handle unaligned head bytes */\r
+       if (address % 4)\r
+       {\r
+               int unaligned = 4 - (address % 4);\r
+               \r
+               if (unaligned > size)\r
+                       unaligned = size;\r
+\r
+               if ((retval = target->type->read_memory(target, address, 1, unaligned, buffer)) != ERROR_OK)\r
+                       return retval;\r
+               \r
+               buffer += unaligned;\r
+               address += unaligned;\r
+               size -= unaligned;\r
+       }\r
+               \r
+       /* handle aligned words */\r
+       if (size >= 4)\r
+       {\r
+               int aligned = size - (size % 4);\r
+       \r
+               if ((retval = target->type->read_memory(target, address, 4, aligned / 4, buffer)) != ERROR_OK)\r
+                       return retval;\r
+               \r
+               buffer += aligned;\r
+               address += aligned;\r
+               size -= aligned;\r
+       }\r
+       \r
+       /* handle tail writes of less than 4 bytes */\r
+       if (size > 0)\r
+       {\r
+               if ((retval = target->type->read_memory(target, address, 1, size, buffer)) != ERROR_OK)\r
+                       return retval;\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int target_checksum_memory(struct target_s *target, u32 address, u32 size, u32* crc)\r
+{\r
+       u8 *buffer;\r
+       int retval;\r
+       int i;\r
+       u32 checksum = 0;\r
+       \r
+       if ((retval = target->type->checksum_memory(target, address,\r
+               size, &checksum)) == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)\r
+       {\r
+               buffer = malloc(size);\r
+               if (buffer == NULL)\r
+               {\r
+                       ERROR("error allocating buffer for section (%d bytes)", size);\r
+                       return ERROR_INVALID_ARGUMENTS;\r
+               }\r
+               retval = target_read_buffer(target, address, size, buffer);\r
+               if (retval != ERROR_OK)\r
+               {\r
+                       free(buffer);\r
+                       return retval;\r
+               }\r
+\r
+               /* convert to target endianess */\r
+               for (i = 0; i < (size/sizeof(u32)); i++)\r
+               {\r
+                       u32 target_data;\r
+                       target_data = target_buffer_get_u32(target, &buffer[i*sizeof(u32)]);\r
+                       target_buffer_set_u32(target, &buffer[i*sizeof(u32)], target_data);\r
+               }\r
+\r
+               retval = image_calculate_checksum( buffer, size, &checksum );\r
+               free(buffer);\r
+       }\r
+       \r
+       *crc = checksum;\r
+       \r
+       return retval;\r
+}\r
+\r
+int target_read_u32(struct target_s *target, u32 address, u32 *value)\r
+{\r
+       u8 value_buf[4];\r
+\r
+       int retval = target->type->read_memory(target, address, 4, 1, value_buf);\r
+       \r
+       if (retval == ERROR_OK)\r
+       {\r
+               *value = target_buffer_get_u32(target, value_buf);\r
+               DEBUG("address: 0x%8.8x, value: 0x%8.8x", address, *value);\r
+       }\r
+       else\r
+       {\r
+               *value = 0x0;\r
+               DEBUG("address: 0x%8.8x failed", address);\r
+       }\r
+       \r
+       return retval;\r
+}\r
+\r
+int target_read_u16(struct target_s *target, u32 address, u16 *value)\r
+{\r
+       u8 value_buf[2];\r
+       \r
+       int retval = target->type->read_memory(target, address, 2, 1, value_buf);\r
+       \r
+       if (retval == ERROR_OK)\r
+       {\r
+               *value = target_buffer_get_u16(target, value_buf);\r
+               DEBUG("address: 0x%8.8x, value: 0x%4.4x", address, *value);\r
+       }\r
+       else\r
+       {\r
+               *value = 0x0;\r
+               DEBUG("address: 0x%8.8x failed", address);\r
+       }\r
+       \r
+       return retval;\r
+}\r
+\r
+int target_read_u8(struct target_s *target, u32 address, u8 *value)\r
+{\r
+       int retval = target->type->read_memory(target, address, 1, 1, value);\r
+\r
+       if (retval == ERROR_OK)\r
+       {\r
+               DEBUG("address: 0x%8.8x, value: 0x%2.2x", address, *value);\r
+       }\r
+       else\r
+       {\r
+               *value = 0x0;\r
+               DEBUG("address: 0x%8.8x failed", address);\r
+       }\r
+       \r
+       return retval;\r
+}\r
+\r
+int target_write_u32(struct target_s *target, u32 address, u32 value)\r
+{\r
+       int retval;\r
+       u8 value_buf[4];\r
+\r
+       DEBUG("address: 0x%8.8x, value: 0x%8.8x", address, value);\r
+\r
+       target_buffer_set_u32(target, value_buf, value);        \r
+       if ((retval = target->type->write_memory(target, address, 4, 1, value_buf)) != ERROR_OK)\r
+       {\r
+               DEBUG("failed: %i", retval);\r
+       }\r
+       \r
+       return retval;\r
+}\r
+\r
+int target_write_u16(struct target_s *target, u32 address, u16 value)\r
+{\r
+       int retval;\r
+       u8 value_buf[2];\r
+       \r
+       DEBUG("address: 0x%8.8x, value: 0x%8.8x", address, value);\r
+\r
+       target_buffer_set_u16(target, value_buf, value);        \r
+       if ((retval = target->type->write_memory(target, address, 2, 1, value_buf)) != ERROR_OK)\r
+       {\r
+               DEBUG("failed: %i", retval);\r
+       }\r
+       \r
+       return retval;\r
+}\r
+\r
+int target_write_u8(struct target_s *target, u32 address, u8 value)\r
+{\r
+       int retval;\r
+       \r
+       DEBUG("address: 0x%8.8x, value: 0x%2.2x", address, value);\r
+\r
+       if ((retval = target->type->read_memory(target, address, 1, 1, &value)) != ERROR_OK)\r
+       {\r
+               DEBUG("failed: %i", retval);\r
+       }\r
+       \r
+       return retval;\r
+}\r
+\r
+int target_register_user_commands(struct command_context_s *cmd_ctx)\r
+{\r
+       register_command(cmd_ctx,  NULL, "reg", handle_reg_command, COMMAND_EXEC, NULL);\r
+       register_command(cmd_ctx,  NULL, "poll", handle_poll_command, COMMAND_EXEC, "poll target state");\r
+       register_command(cmd_ctx,  NULL, "wait_halt", handle_wait_halt_command, COMMAND_EXEC, "wait for target halt [time (s)]");\r
+       register_command(cmd_ctx,  NULL, "halt", handle_halt_command, COMMAND_EXEC, "halt target");\r
+       register_command(cmd_ctx,  NULL, "resume", handle_resume_command, COMMAND_EXEC, "resume target [addr]");\r
+       register_command(cmd_ctx,  NULL, "step", handle_step_command, COMMAND_EXEC, "step one instruction from current PC or [addr]");\r
+       register_command(cmd_ctx,  NULL, "reset", handle_reset_command, COMMAND_EXEC, "reset target [run|halt|init|run_and_halt|run_and_init]");\r
+       register_command(cmd_ctx,  NULL, "soft_reset_halt", handle_soft_reset_halt_command, COMMAND_EXEC, "halt the target and do a soft reset");\r
+\r
+       register_command(cmd_ctx,  NULL, "mdw", handle_md_command, COMMAND_EXEC, "display memory words <addr> [count]");\r
+       register_command(cmd_ctx,  NULL, "mdh", handle_md_command, COMMAND_EXEC, "display memory half-words <addr> [count]");\r
+       register_command(cmd_ctx,  NULL, "mdb", handle_md_command, COMMAND_EXEC, "display memory bytes <addr> [count]");\r
+       \r
+       register_command(cmd_ctx,  NULL, "mww", handle_mw_command, COMMAND_EXEC, "write memory word <addr> <value>");\r
+       register_command(cmd_ctx,  NULL, "mwh", handle_mw_command, COMMAND_EXEC, "write memory half-word <addr> <value>");\r
+       register_command(cmd_ctx,  NULL, "mwb", handle_mw_command, COMMAND_EXEC, "write memory byte <addr> <value>");\r
+       \r
+       register_command(cmd_ctx,  NULL, "bp", handle_bp_command, COMMAND_EXEC, "set breakpoint <address> <length> [hw]");      \r
+       register_command(cmd_ctx,  NULL, "rbp", handle_rbp_command, COMMAND_EXEC, "remove breakpoint <adress>");\r
+       register_command(cmd_ctx,  NULL, "wp", handle_wp_command, COMMAND_EXEC, "set watchpoint <address> <length> <r/w/a> [value] [mask]");    \r
+       register_command(cmd_ctx,  NULL, "rwp", handle_rwp_command, COMMAND_EXEC, "remove watchpoint <adress>");\r
+       \r
+       register_command(cmd_ctx,  NULL, "load_image", handle_load_image_command, COMMAND_EXEC, "load_image <file> <address> ['bin'|'ihex'|'elf'|'s19']");\r
+       register_command(cmd_ctx,  NULL, "dump_image", handle_dump_image_command, COMMAND_EXEC, "dump_image <file> <address> <size>");\r
+       register_command(cmd_ctx,  NULL, "verify_image", handle_verify_image_command, COMMAND_EXEC, "verify_image <file> [offset] [type]");\r
+       register_command(cmd_ctx,  NULL, "load_binary", handle_load_image_command, COMMAND_EXEC, "[DEPRECATED] load_binary <file> <address>");\r
+       register_command(cmd_ctx,  NULL, "dump_binary", handle_dump_image_command, COMMAND_EXEC, "[DEPRECATED] dump_binary <file> <address> <size>");\r
+       \r
+       target_request_register_commands(cmd_ctx);\r
+       trace_register_commands(cmd_ctx);\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int handle_targets_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       target_t *target = targets;\r
+       int count = 0;\r
+       \r
+       if (argc == 1)\r
+       {\r
+               int num = strtoul(args[0], NULL, 0);\r
+               \r
+               while (target)\r
+               {\r
+                       count++;\r
+                       target = target->next;\r
+               }\r
+               \r
+               if (num < count)\r
+                       cmd_ctx->current_target = num;\r
+               else\r
+                       command_print(cmd_ctx, "%i is out of bounds, only %i targets are configured", num, count);\r
+                       \r
+               return ERROR_OK;\r
+       }\r
+               \r
+       while (target)\r
+       {\r
+               command_print(cmd_ctx, "%i: %s (%s), state: %s", count++, target->type->name, target_endianess_strings[target->endianness], target_state_strings[target->state]);\r
+               target = target->next;\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int handle_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       int i;\r
+       int found = 0;\r
+       \r
+       if (argc < 3)\r
+       {\r
+               ERROR("target command requires at least three arguments: <type> <endianess> <reset_mode>");\r
+               exit(-1);\r
+       }\r
+       \r
+       /* search for the specified target */\r
+       if (args[0] && (args[0][0] != 0))\r
+       {\r
+               for (i = 0; target_types[i]; i++)\r
+               {\r
+                       if (strcmp(args[0], target_types[i]->name) == 0)\r
+                       {\r
+                               target_t **last_target_p = &targets;\r
+                               \r
+                               /* register target specific commands */\r
+                               if (target_types[i]->register_commands(cmd_ctx) != ERROR_OK)\r
+                               {\r
+                                       ERROR("couldn't register '%s' commands", args[0]);\r
+                                       exit(-1);\r
+                               }\r
+\r
+                               if (*last_target_p)\r
+                               {\r
+                                       while ((*last_target_p)->next)\r
+                                               last_target_p = &((*last_target_p)->next);\r
+                                       last_target_p = &((*last_target_p)->next);\r
+                               }\r
+\r
+                               *last_target_p = malloc(sizeof(target_t));\r
+                               \r
+                               (*last_target_p)->type = target_types[i];\r
+                               \r
+                               if (strcmp(args[1], "big") == 0)\r
+                                       (*last_target_p)->endianness = TARGET_BIG_ENDIAN;\r
+                               else if (strcmp(args[1], "little") == 0)\r
+                                       (*last_target_p)->endianness = TARGET_LITTLE_ENDIAN;\r
+                               else\r
+                               {\r
+                                       ERROR("endianness must be either 'little' or 'big', not '%s'", args[1]);\r
+                                       exit(-1);\r
+                               }\r
+                               \r
+                               /* what to do on a target reset */\r
+                               if (strcmp(args[2], "reset_halt") == 0)\r
+                                       (*last_target_p)->reset_mode = RESET_HALT;\r
+                               else if (strcmp(args[2], "reset_run") == 0)\r
+                                       (*last_target_p)->reset_mode = RESET_RUN;\r
+                               else if (strcmp(args[2], "reset_init") == 0)\r
+                                       (*last_target_p)->reset_mode = RESET_INIT;\r
+                               else if (strcmp(args[2], "run_and_halt") == 0)\r
+                                       (*last_target_p)->reset_mode = RESET_RUN_AND_HALT;\r
+                               else if (strcmp(args[2], "run_and_init") == 0)\r
+                                       (*last_target_p)->reset_mode = RESET_RUN_AND_INIT;\r
+                               else\r
+                               {\r
+                                       ERROR("unknown target startup mode %s", args[2]);\r
+                                       exit(-1);\r
+                               }\r
+                               (*last_target_p)->run_and_halt_time = 1000; /* default 1s */\r
+                               \r
+                               (*last_target_p)->reset_script = NULL;\r
+                               (*last_target_p)->post_halt_script = NULL;\r
+                               (*last_target_p)->pre_resume_script = NULL;\r
+                               (*last_target_p)->gdb_program_script = NULL;\r
+                               \r
+                               (*last_target_p)->working_area = 0x0;\r
+                               (*last_target_p)->working_area_size = 0x0;\r
+                               (*last_target_p)->working_areas = NULL;\r
+                               (*last_target_p)->backup_working_area = 0;\r
+                               \r
+                               (*last_target_p)->state = TARGET_UNKNOWN;\r
+                               (*last_target_p)->reg_cache = NULL;\r
+                               (*last_target_p)->breakpoints = NULL;\r
+                               (*last_target_p)->watchpoints = NULL;\r
+                               (*last_target_p)->next = NULL;\r
+                               (*last_target_p)->arch_info = NULL;\r
+                               \r
+                               /* initialize trace information */\r
+                               (*last_target_p)->trace_info = malloc(sizeof(trace_t));\r
+                               (*last_target_p)->trace_info->num_trace_points = 0;\r
+                               (*last_target_p)->trace_info->trace_points_size = 0;\r
+                               (*last_target_p)->trace_info->trace_points = NULL;\r
+                               (*last_target_p)->trace_info->trace_history_size = 0;\r
+                               (*last_target_p)->trace_info->trace_history = NULL;\r
+                               (*last_target_p)->trace_info->trace_history_pos = 0;\r
+                               (*last_target_p)->trace_info->trace_history_overflowed = 0;\r
+                               \r
+                               (*last_target_p)->dbgmsg = NULL;\r
+                               (*last_target_p)->dbg_msg_enabled = 0;\r
+                                                               \r
+                               (*last_target_p)->type->target_command(cmd_ctx, cmd, args, argc, *last_target_p);\r
+                               \r
+                               found = 1;\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
+       \r
+       /* no matching target found */\r
+       if (!found)\r
+       {\r
+               ERROR("target '%s' not found", args[0]);\r
+               exit(-1);\r
+       }\r
+\r
+       return ERROR_OK;\r
+}\r
+\r
+/* usage: target_script <target#> <event> <script_file> */\r
+int handle_target_script_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       target_t *target = NULL;\r
+       \r
+       if (argc < 3)\r
+       {\r
+               ERROR("incomplete target_script command");\r
+               exit(-1);\r
+       }\r
+       \r
+       target = get_target_by_num(strtoul(args[0], NULL, 0));\r
+       \r
+       if (!target)\r
+       {\r
+               ERROR("target number '%s' not defined", args[0]);\r
+               exit(-1);\r
+       }\r
+       \r
+       if (strcmp(args[1], "reset") == 0)\r
+       {\r
+               if (target->reset_script)\r
+                       free(target->reset_script);\r
+               target->reset_script = strdup(args[2]);\r
+       }\r
+       else if (strcmp(args[1], "post_halt") == 0)\r
+       {\r
+               if (target->post_halt_script)\r
+                       free(target->post_halt_script);\r
+               target->post_halt_script = strdup(args[2]);\r
+       }\r
+       else if (strcmp(args[1], "pre_resume") == 0)\r
+       {\r
+               if (target->pre_resume_script)\r
+                       free(target->pre_resume_script);\r
+               target->pre_resume_script = strdup(args[2]);\r
+       }\r
+       else if (strcmp(args[1], "gdb_program_config") == 0)\r
+       {\r
+               if (target->gdb_program_script)\r
+                       free(target->gdb_program_script);\r
+               target->gdb_program_script = strdup(args[2]);\r
+       }\r
+       else\r
+       {\r
+               ERROR("unknown event type: '%s", args[1]);\r
+               exit(-1);       \r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int handle_run_and_halt_time_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       target_t *target = NULL;\r
+       \r
+       if (argc < 2)\r
+       {\r
+               ERROR("incomplete run_and_halt_time command");\r
+               exit(-1);\r
+       }\r
+       \r
+       target = get_target_by_num(strtoul(args[0], NULL, 0));\r
+       \r
+       if (!target)\r
+       {\r
+               ERROR("target number '%s' not defined", args[0]);\r
+               exit(-1);\r
+       }\r
+       \r
+       target->run_and_halt_time = strtoul(args[1], NULL, 0);\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int handle_working_area_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       target_t *target = NULL;\r
+       \r
+       if ((argc < 4) || (argc > 5))\r
+       {\r
+               return ERROR_COMMAND_SYNTAX_ERROR;\r
+       }\r
+       \r
+       target = get_target_by_num(strtoul(args[0], NULL, 0));\r
+       \r
+       if (!target)\r
+       {\r
+               ERROR("target number '%s' not defined", args[0]);\r
+               exit(-1);\r
+       }\r
+       target_free_all_working_areas(target);\r
+       \r
+       target->working_area_phys = target->working_area_virt = strtoul(args[1], NULL, 0);\r
+       if (argc == 5)\r
+       {\r
+               target->working_area_virt = strtoul(args[4], NULL, 0);\r
+       }\r
+       target->working_area_size = strtoul(args[2], NULL, 0);\r
+       \r
+       if (strcmp(args[3], "backup") == 0)\r
+       {\r
+               target->backup_working_area = 1;\r
+       }\r
+       else if (strcmp(args[3], "nobackup") == 0)\r
+       {\r
+               target->backup_working_area = 0;\r
+       }\r
+       else\r
+       {\r
+               ERROR("unrecognized <backup|nobackup> argument (%s)", args[3]);\r
+               return ERROR_COMMAND_SYNTAX_ERROR;\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+\r
+/* process target state changes */\r
+int handle_target(void *priv)\r
+{\r
+       int retval;\r
+       target_t *target = targets;\r
+       \r
+       while (target)\r
+       {\r
+               /* only poll if target isn't already halted */\r
+               if (target->state != TARGET_HALTED)\r
+               {\r
+                       if (target_continous_poll)\r
+                               if ((retval = target->type->poll(target)) != ERROR_OK)\r
+                               {\r
+                                       ERROR("couldn't poll target(%d). It's due for a reset.", retval);\r
+                               }\r
+               }\r
+       \r
+               target = target->next;\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       target_t *target;\r
+       reg_t *reg = NULL;\r
+       int count = 0;\r
+       char *value;\r
+       \r
+       DEBUG("-");\r
+       \r
+       target = get_current_target(cmd_ctx);\r
+       \r
+       /* list all available registers for the current target */\r
+       if (argc == 0)\r
+       {\r
+               reg_cache_t *cache = target->reg_cache;\r
+               \r
+               count = 0;\r
+               while(cache)\r
+               {\r
+                       int i;\r
+                       for (i = 0; i < cache->num_regs; i++)\r
+                       {\r
+                               value = buf_to_str(cache->reg_list[i].value, cache->reg_list[i].size, 16);\r
+                               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);\r
+                               free(value);\r
+                       }\r
+                       cache = cache->next;\r
+               }\r
+               \r
+               return ERROR_OK;\r
+       }\r
+       \r
+       /* access a single register by its ordinal number */\r
+       if ((args[0][0] >= '0') && (args[0][0] <= '9'))\r
+       {\r
+               int num = strtoul(args[0], NULL, 0);\r
+               reg_cache_t *cache = target->reg_cache;\r
+               \r
+               count = 0;\r
+               while(cache)\r
+               {\r
+                       int i;\r
+                       for (i = 0; i < cache->num_regs; i++)\r
+                       {\r
+                               if (count++ == num)\r
+                               {\r
+                                       reg = &cache->reg_list[i];\r
+                                       break;\r
+                               }\r
+                       }\r
+                       if (reg)\r
+                               break;\r
+                       cache = cache->next;\r
+               }\r
+               \r
+               if (!reg)\r
+               {\r
+                       command_print(cmd_ctx, "%i is out of bounds, the current target has only %i registers (0 - %i)", num, count, count - 1);\r
+                       return ERROR_OK;\r
+               }\r
+       } else /* access a single register by its name */\r
+       {\r
+               reg = register_get_by_name(target->reg_cache, args[0], 1);\r
+               \r
+               if (!reg)\r
+               {\r
+                       command_print(cmd_ctx, "register %s not found in current target", args[0]);\r
+                       return ERROR_OK;\r
+               }\r
+       }\r
+\r
+       /* display a register */\r
+       if ((argc == 1) || ((argc == 2) && !((args[1][0] >= '0') && (args[1][0] <= '9'))))\r
+       {\r
+               if ((argc == 2) && (strcmp(args[1], "force") == 0))\r
+                       reg->valid = 0;\r
+               \r
+               if (reg->valid == 0)\r
+               {\r
+                       reg_arch_type_t *arch_type = register_get_arch_type(reg->arch_type);\r
+                       if (arch_type == NULL)\r
+                       {\r
+                               ERROR("BUG: encountered unregistered arch type");\r
+                               return ERROR_OK;\r
+                       }\r
+                       arch_type->get(reg);\r
+               }\r
+               value = buf_to_str(reg->value, reg->size, 16);\r
+               command_print(cmd_ctx, "%s (/%i): 0x%s", reg->name, reg->size, value);\r
+               free(value);\r
+               return ERROR_OK;\r
+       }\r
+       \r
+       /* set register value */\r
+       if (argc == 2)\r
+       {\r
+               u8 *buf = malloc(CEIL(reg->size, 8));\r
+               str_to_buf(args[1], strlen(args[1]), buf, reg->size, 0);\r
+\r
+               reg_arch_type_t *arch_type = register_get_arch_type(reg->arch_type);\r
+               if (arch_type == NULL)\r
+               {\r
+                       ERROR("BUG: encountered unregistered arch type");\r
+                       return ERROR_OK;\r
+               }\r
+               \r
+               arch_type->set(reg, buf);\r
+               \r
+               value = buf_to_str(reg->value, reg->size, 16);\r
+               command_print(cmd_ctx, "%s (/%i): 0x%s", reg->name, reg->size, value);\r
+               free(value);\r
+               \r
+               free(buf);\r
+               \r
+               return ERROR_OK;\r
+       }\r
+       \r
+       command_print(cmd_ctx, "usage: reg <#|name> [value]");\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+static int wait_state(struct command_context_s *cmd_ctx, char *cmd, enum target_state state, int ms);\r
+\r
+int handle_poll_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       target_t *target = get_current_target(cmd_ctx);\r
+\r
+       if (argc == 0)\r
+       {\r
+               target->type->poll(target);\r
+                       target_arch_state(target);\r
+       }\r
+       else\r
+       {\r
+               if (strcmp(args[0], "on") == 0)\r
+               {\r
+                       target_continous_poll = 1;\r
+               }\r
+               else if (strcmp(args[0], "off") == 0)\r
+               {\r
+                       target_continous_poll = 0;\r
+               }\r
+               else\r
+               {\r
+                       command_print(cmd_ctx, "arg is \"on\" or \"off\"");\r
+               }\r
+       }\r
+       \r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int handle_wait_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       int ms = 5000;\r
+       \r
+       if (argc > 0)\r
+       {\r
+               char *end;\r
+\r
+               ms = strtoul(args[0], &end, 0) * 1000;\r
+               if (*end)\r
+               {\r
+                       command_print(cmd_ctx, "usage: %s [seconds]", cmd);\r
+                       return ERROR_OK;\r
+               }\r
+       }\r
+\r
+       return wait_state(cmd_ctx, cmd, TARGET_HALTED, ms); \r
+}\r
+\r
+static void target_process_events(struct command_context_s *cmd_ctx)\r
+{\r
+       target_t *target = get_current_target(cmd_ctx);\r
+       target->type->poll(target);\r
+       target_call_timer_callbacks();\r
+}\r
+\r
+static int wait_state(struct command_context_s *cmd_ctx, char *cmd, enum target_state state, int ms)\r
+{\r
+       int retval;\r
+       struct timeval timeout, now;\r
+       \r
+       gettimeofday(&timeout, NULL);\r
+       timeval_add_time(&timeout, 0, ms * 1000);\r
+       \r
+       target_t *target = get_current_target(cmd_ctx);\r
+       for (;;)\r
+       {\r
+               if ((retval=target->type->poll(target))!=ERROR_OK)\r
+                       return retval;\r
+               target_call_timer_callbacks();\r
+               if (target->state == state)\r
+               {\r
+                       break;\r
+               }\r
+               command_print(cmd_ctx, "waiting for target %s...", target_state_strings[state]);\r
+               \r
+               gettimeofday(&now, NULL);\r
+               if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec) && (now.tv_usec >= timeout.tv_usec)))\r
+               {\r
+                       command_print(cmd_ctx, "timed out while waiting for target %s", target_state_strings[state]);\r
+                       ERROR("timed out while waiting for target %s", target_state_strings[state]);\r
+                       break;\r
+               }\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int handle_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       int retval;\r
+       target_t *target = get_current_target(cmd_ctx);\r
+\r
+       DEBUG("-");\r
+       \r
+       command_print(cmd_ctx, "requesting target halt...");\r
+\r
+       if ((retval = target->type->halt(target)) != ERROR_OK)\r
+       {       \r
+               switch (retval)\r
+               {\r
+                       case ERROR_TARGET_ALREADY_HALTED:\r
+                               command_print(cmd_ctx, "target already halted");\r
+                               break;\r
+                       case ERROR_TARGET_TIMEOUT:\r
+                               command_print(cmd_ctx, "target timed out... shutting down");\r
+                               return retval;\r
+                       default:\r
+                               command_print(cmd_ctx, "unknown error... shutting down");\r
+                               return retval;\r
+               }\r
+       }\r
+       \r
+       return handle_wait_halt_command(cmd_ctx, cmd, args, argc);\r
+}\r
+\r
+/* what to do on daemon startup */\r
+int handle_daemon_startup_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       if (argc == 1)\r
+       {\r
+               if (strcmp(args[0], "attach") == 0)\r
+               {\r
+                       startup_mode = DAEMON_ATTACH;\r
+                       return ERROR_OK;\r
+               }\r
+               else if (strcmp(args[0], "reset") == 0)\r
+               {\r
+                       startup_mode = DAEMON_RESET;\r
+                       return ERROR_OK;\r
+               }\r
+       }\r
+       \r
+       WARNING("invalid daemon_startup configuration directive: %s", args[0]);\r
+       return ERROR_OK;\r
+\r
+}\r
+               \r
+int handle_soft_reset_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       target_t *target = get_current_target(cmd_ctx);\r
+       int retval;\r
+       \r
+       command_print(cmd_ctx, "requesting target halt and executing a soft reset");\r
+       \r
+       if ((retval = target->type->soft_reset_halt(target)) != ERROR_OK)\r
+       {       \r
+               switch (retval)\r
+               {\r
+                       case ERROR_TARGET_TIMEOUT:\r
+                               command_print(cmd_ctx, "target timed out... shutting down");\r
+                               exit(-1);\r
+                       default:\r
+                               command_print(cmd_ctx, "unknown error... shutting down");\r
+                               exit(-1);\r
+               }\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int handle_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       target_t *target = get_current_target(cmd_ctx);\r
+       enum target_reset_mode reset_mode = target->reset_mode;\r
+       enum target_reset_mode save = target->reset_mode;\r
+       \r
+       DEBUG("-");\r
+       \r
+       if (argc >= 1)\r
+       {\r
+               if (strcmp("run", args[0]) == 0)\r
+                       reset_mode = RESET_RUN;\r
+               else if (strcmp("halt", args[0]) == 0)\r
+                       reset_mode = RESET_HALT;\r
+               else if (strcmp("init", args[0]) == 0)\r
+                       reset_mode = RESET_INIT;\r
+               else if (strcmp("run_and_halt", args[0]) == 0)\r
+               {\r
+                       reset_mode = RESET_RUN_AND_HALT;\r
+                       if (argc >= 2)\r
+                       {\r
+                               target->run_and_halt_time = strtoul(args[1], NULL, 0);\r
+                       }\r
+               }\r
+               else if (strcmp("run_and_init", args[0]) == 0)\r
+               {\r
+                       reset_mode = RESET_RUN_AND_INIT;\r
+                       if (argc >= 2)\r
+                       {\r
+                               target->run_and_halt_time = strtoul(args[1], NULL, 0);\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       command_print(cmd_ctx, "usage: reset ['run', 'halt', 'init', 'run_and_halt', 'run_and_init]");\r
+                       return ERROR_OK;\r
+               }\r
+       }\r
+       \r
+       /* temporarily modify mode of current reset target */\r
+       target->reset_mode = reset_mode;\r
+\r
+       /* reset *all* targets */\r
+       target_process_reset(cmd_ctx);\r
+       \r
+       /* Restore default reset mode for this target */\r
+    target->reset_mode = save;\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int handle_resume_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       int retval;\r
+       target_t *target = get_current_target(cmd_ctx);\r
+       \r
+       if (argc == 0)\r
+               retval = target->type->resume(target, 1, 0, 1, 0); /* current pc, addr = 0, handle breakpoints, not debugging */\r
+       else if (argc == 1)\r
+               retval = target->type->resume(target, 0, strtoul(args[0], NULL, 0), 1, 0); /* addr = args[0], handle breakpoints, not debugging */\r
+       else\r
+       {\r
+               return ERROR_COMMAND_SYNTAX_ERROR;\r
+       }\r
+\r
+       target_process_events(cmd_ctx);\r
+       \r
+       target_arch_state(target);\r
+       \r
+       return retval;\r
+}\r
+\r
+int handle_step_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       target_t *target = get_current_target(cmd_ctx);\r
+       \r
+       DEBUG("-");\r
+       \r
+       if (argc == 0)\r
+               target->type->step(target, 1, 0, 1); /* current pc, addr = 0, handle breakpoints */\r
+\r
+       if (argc == 1)\r
+               target->type->step(target, 0, strtoul(args[0], NULL, 0), 1); /* addr = args[0], handle breakpoints */\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       const int line_bytecnt = 32;\r
+       int count = 1;\r
+       int size = 4;\r
+       u32 address = 0;\r
+       int line_modulo;\r
+       int i;\r
+\r
+       char output[128];\r
+       int output_len;\r
+\r
+       int retval;\r
+\r
+       u8 *buffer;\r
+       target_t *target = get_current_target(cmd_ctx);\r
+\r
+       if (argc < 1)\r
+               return ERROR_OK;\r
+\r
+       if (argc == 2)\r
+               count = strtoul(args[1], NULL, 0);\r
+\r
+       address = strtoul(args[0], NULL, 0);\r
+       \r
+\r
+       switch (cmd[2])\r
+       {\r
+               case 'w':\r
+                       size = 4; line_modulo = line_bytecnt / 4;\r
+                       break;\r
+               case 'h':\r
+                       size = 2; line_modulo = line_bytecnt / 2;\r
+                       break;\r
+               case 'b':\r
+                       size = 1; line_modulo = line_bytecnt / 1;\r
+                       break;\r
+               default:\r
+                       return ERROR_OK;\r
+       }\r
+\r
+       buffer = calloc(count, size);\r
+       retval  = target->type->read_memory(target, address, size, count, buffer);\r
+       if (retval != ERROR_OK)\r
+       {\r
+               switch (retval)\r
+               {\r
+                       case ERROR_TARGET_UNALIGNED_ACCESS:\r
+                               command_print(cmd_ctx, "error: address not aligned");\r
+                               break;\r
+                       case ERROR_TARGET_NOT_HALTED:\r
+                               command_print(cmd_ctx, "error: target must be halted for memory accesses");\r
+                               break;                  \r
+                       case ERROR_TARGET_DATA_ABORT:\r
+                               command_print(cmd_ctx, "error: access caused data abort, system possibly corrupted");\r
+                               break;\r
+                       default:\r
+                               command_print(cmd_ctx, "error: unknown error");\r
+                               break;\r
+               }\r
+               return ERROR_OK;\r
+       }\r
+\r
+       output_len = 0;\r
+\r
+       for (i = 0; i < count; i++)\r
+       {\r
+               if (i%line_modulo == 0)\r
+                       output_len += snprintf(output + output_len, 128 - output_len, "0x%8.8x: ", address + (i*size));\r
+               \r
+               switch (size)\r
+               {\r
+                       case 4:\r
+                               output_len += snprintf(output + output_len, 128 - output_len, "%8.8x ", target_buffer_get_u32(target, &buffer[i*4]));\r
+                               break;\r
+                       case 2:\r
+                               output_len += snprintf(output + output_len, 128 - output_len, "%4.4x ", target_buffer_get_u16(target, &buffer[i*2]));\r
+                               break;\r
+                       case 1:\r
+                               output_len += snprintf(output + output_len, 128 - output_len, "%2.2x ", buffer[i*1]);\r
+                               break;\r
+               }\r
+\r
+               if ((i%line_modulo == line_modulo-1) || (i == count - 1))\r
+               {\r
+                       command_print(cmd_ctx, output);\r
+                       output_len = 0;\r
+               }\r
+       }\r
+\r
+       free(buffer);\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       u32 address = 0;\r
+       u32 value = 0;\r
+       int retval;\r
+       target_t *target = get_current_target(cmd_ctx);\r
+       u8 value_buf[4];\r
+\r
+       if (argc < 2)\r
+               return ERROR_OK;\r
+\r
+       address = strtoul(args[0], NULL, 0);\r
+       value = strtoul(args[1], NULL, 0);\r
+\r
+       switch (cmd[2])\r
+       {\r
+               case 'w':\r
+                       target_buffer_set_u32(target, value_buf, value);\r
+                       retval = target->type->write_memory(target, address, 4, 1, value_buf);\r
+                       break;\r
+               case 'h':\r
+                       target_buffer_set_u16(target, value_buf, value);\r
+                       retval = target->type->write_memory(target, address, 2, 1, value_buf);\r
+                       break;\r
+               case 'b':\r
+                       value_buf[0] = value;\r
+                       retval = target->type->write_memory(target, address, 1, 1, value_buf);\r
+                       break;\r
+               default:\r
+                       return ERROR_OK;\r
+       }\r
+\r
+       switch (retval)\r
+       {\r
+               case ERROR_TARGET_UNALIGNED_ACCESS:\r
+                       command_print(cmd_ctx, "error: address not aligned");\r
+                       break;\r
+               case ERROR_TARGET_DATA_ABORT:\r
+                       command_print(cmd_ctx, "error: access caused data abort, system possibly corrupted");\r
+                       break;\r
+               case ERROR_TARGET_NOT_HALTED:\r
+                       command_print(cmd_ctx, "error: target must be halted for memory accesses");\r
+                       break;\r
+               case ERROR_OK:\r
+                       break;\r
+               default:\r
+                       command_print(cmd_ctx, "error: unknown error");\r
+                       break;\r
+       }\r
+\r
+       return ERROR_OK;\r
+\r
+}\r
+\r
+int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       u8 *buffer;\r
+       u32 buf_cnt;\r
+       u32 image_size;\r
+       int i;\r
+       int retval;\r
+\r
+       image_t image;  \r
+       \r
+       duration_t duration;\r
+       char *duration_text;\r
+       \r
+       target_t *target = get_current_target(cmd_ctx);\r
+\r
+       if (argc < 1)\r
+       {\r
+               command_print(cmd_ctx, "usage: load_image <filename> [address] [type]");\r
+               return ERROR_OK;\r
+       }\r
+       \r
+       /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */\r
+       if (argc >= 2)\r
+       {\r
+               image.base_address_set = 1;\r
+               image.base_address = strtoul(args[1], NULL, 0);\r
+       }\r
+       else\r
+       {\r
+               image.base_address_set = 0;\r
+       }\r
+       \r
+       image.start_address_set = 0;\r
+\r
+       duration_start_measure(&duration);\r
+       \r
+       if (image_open(&image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)\r
+       {\r
+               command_print(cmd_ctx, "load_image error: %s", image.error_str);\r
+               return ERROR_OK;\r
+       }\r
+       \r
+       image_size = 0x0;\r
+       for (i = 0; i < image.num_sections; i++)\r
+       {\r
+               buffer = malloc(image.sections[i].size);\r
+               if (buffer == NULL)\r
+               {\r
+                       command_print(cmd_ctx, "error allocating buffer for section (%d bytes)", image.sections[i].size);\r
+                       break;\r
+               }\r
+               \r
+               if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)\r
+               {\r
+                       ERROR("image_read_section failed with error code: %i", retval);\r
+                       command_print(cmd_ctx, "image reading failed, download aborted");\r
+                       free(buffer);\r
+                       image_close(&image);\r
+                       return ERROR_OK;\r
+               }\r
+               target_write_buffer(target, image.sections[i].base_address, buf_cnt, buffer);\r
+               image_size += buf_cnt;\r
+               command_print(cmd_ctx, "%u byte written at address 0x%8.8x", buf_cnt, image.sections[i].base_address);\r
+               \r
+               free(buffer);\r
+       }\r
+\r
+       duration_stop_measure(&duration, &duration_text);\r
+       command_print(cmd_ctx, "downloaded %u byte in %s", image_size, duration_text);\r
+       free(duration_text);\r
+       \r
+       image_close(&image);\r
+\r
+       return ERROR_OK;\r
+\r
+}\r
+\r
+int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       fileio_t fileio;\r
+       \r
+       u32 address;\r
+       u32 size;\r
+       u8 buffer[560];\r
+       int retval;\r
+       \r
+       duration_t duration;\r
+       char *duration_text;\r
+       \r
+       target_t *target = get_current_target(cmd_ctx);\r
+\r
+       if (argc != 3)\r
+       {\r
+               command_print(cmd_ctx, "usage: dump_image <filename> <address> <size>");\r
+               return ERROR_OK;\r
+       }\r
+\r
+       address = strtoul(args[1], NULL, 0);\r
+       size = strtoul(args[2], NULL, 0);\r
+\r
+       if ((address & 3) || (size & 3))\r
+       {\r
+               command_print(cmd_ctx, "only 32-bit aligned address and size are supported");\r
+               return ERROR_OK;\r
+       }\r
+       \r
+       if (fileio_open(&fileio, args[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)\r
+       {\r
+               command_print(cmd_ctx, "dump_image error: %s", fileio.error_str);\r
+               return ERROR_OK;\r
+       }\r
+       \r
+       duration_start_measure(&duration);\r
+       \r
+       while (size > 0)\r
+       {\r
+               u32 size_written;\r
+               u32 this_run_size = (size > 560) ? 560 : size;\r
+               \r
+               retval = target->type->read_memory(target, address, 4, this_run_size / 4, buffer);\r
+               if (retval != ERROR_OK)\r
+               {\r
+                       command_print(cmd_ctx, "Reading memory failed %d", retval);\r
+                       break;\r
+               }\r
+               \r
+               fileio_write(&fileio, this_run_size, buffer, &size_written);\r
+               \r
+               size -= this_run_size;\r
+               address += this_run_size;\r
+       }\r
+\r
+       fileio_close(&fileio);\r
+\r
+       duration_stop_measure(&duration, &duration_text);\r
+       command_print(cmd_ctx, "dumped %"PRIi64" byte in %s", fileio.size, duration_text);\r
+       free(duration_text);\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       u8 *buffer;\r
+       u32 buf_cnt;\r
+       u32 image_size;\r
+       int i;\r
+       int retval;\r
+       u32 checksum = 0;\r
+       u32 mem_checksum = 0;\r
+\r
+       image_t image;  \r
+       \r
+       duration_t duration;\r
+       char *duration_text;\r
+       \r
+       target_t *target = get_current_target(cmd_ctx);\r
+       \r
+       if (argc < 1)\r
+       {\r
+               command_print(cmd_ctx, "usage: verify_image <file> [offset] [type]");\r
+               return ERROR_OK;\r
+       }\r
+       \r
+       if (!target)\r
+       {\r
+               ERROR("no target selected");\r
+               return ERROR_OK;\r
+       }\r
+       \r
+       duration_start_measure(&duration);\r
+       \r
+       if (argc >= 2)\r
+       {\r
+               image.base_address_set = 1;\r
+               image.base_address = strtoul(args[1], NULL, 0);\r
+       }\r
+       else\r
+       {\r
+               image.base_address_set = 0;\r
+               image.base_address = 0x0;\r
+       }\r
+\r
+       image.start_address_set = 0;\r
+\r
+       if (image_open(&image, args[0], (argc == 3) ? args[2] : NULL) != ERROR_OK)\r
+       {\r
+               command_print(cmd_ctx, "verify_image error: %s", image.error_str);\r
+               return ERROR_OK;\r
+       }\r
+       \r
+       image_size = 0x0;\r
+       for (i = 0; i < image.num_sections; i++)\r
+       {\r
+               buffer = malloc(image.sections[i].size);\r
+               if (buffer == NULL)\r
+               {\r
+                       command_print(cmd_ctx, "error allocating buffer for section (%d bytes)", image.sections[i].size);\r
+                       break;\r
+               }\r
+               if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)\r
+               {\r
+                       ERROR("image_read_section failed with error code: %i", retval);\r
+                       command_print(cmd_ctx, "image reading failed, verify aborted");\r
+                       free(buffer);\r
+                       image_close(&image);\r
+                       return ERROR_OK;\r
+               }\r
+               \r
+               /* calculate checksum of image */\r
+               image_calculate_checksum( buffer, buf_cnt, &checksum );\r
+               \r
+               retval = target_checksum_memory(target, image.sections[i].base_address, buf_cnt, &mem_checksum);\r
+               \r
+               if( retval != ERROR_OK )\r
+               {\r
+                       command_print(cmd_ctx, "could not calculate checksum, verify aborted");\r
+                       free(buffer);\r
+                       image_close(&image);\r
+                       return ERROR_OK;\r
+               }\r
+               \r
+               if( checksum != mem_checksum )\r
+               {\r
+                       /* failed crc checksum, fall back to a binary compare */\r
+                       u8 *data;\r
+                       \r
+                       command_print(cmd_ctx, "checksum mismatch - attempting binary compare");\r
+                       \r
+                       data = (u8*)malloc(buf_cnt);\r
+                       \r
+                       /* Can we use 32bit word accesses? */\r
+                       int size = 1;\r
+                       int count = buf_cnt;\r
+                       if ((count % 4) == 0)\r
+                       {\r
+                               size *= 4;\r
+                               count /= 4;\r
+                       }\r
+                       retval = target->type->read_memory(target, image.sections[i].base_address, size, count, data);\r
+       \r
+                       if (retval == ERROR_OK)\r
+                       {\r
+                               int t;\r
+                               for (t = 0; t < buf_cnt; t++)\r
+                               {\r
+                                       if (data[t] != buffer[t])\r
+                                       {\r
+                                               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]);\r
+                                               free(data);\r
+                                               free(buffer);\r
+                                               image_close(&image);\r
+                                               return ERROR_OK;\r
+                                       }\r
+                               }\r
+                       }\r
+                       \r
+                       free(data);\r
+               }\r
+               \r
+               free(buffer);\r
+               image_size += buf_cnt;\r
+       }\r
+       \r
+       duration_stop_measure(&duration, &duration_text);\r
+       command_print(cmd_ctx, "verified %u bytes in %s", image_size, duration_text);\r
+       free(duration_text);\r
+       \r
+       image_close(&image);\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int handle_bp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       int retval;\r
+       target_t *target = get_current_target(cmd_ctx);\r
+\r
+       if (argc == 0)\r
+       {\r
+               breakpoint_t *breakpoint = target->breakpoints;\r
+\r
+               while (breakpoint)\r
+               {\r
+                       if (breakpoint->type == BKPT_SOFT)\r
+                       {\r
+                               char* buf = buf_to_str(breakpoint->orig_instr, breakpoint->length, 16);\r
+                               command_print(cmd_ctx, "0x%8.8x, 0x%x, %i, 0x%s", breakpoint->address, breakpoint->length, breakpoint->set, buf);\r
+                               free(buf);\r
+                       }\r
+                       else\r
+                       {\r
+                               command_print(cmd_ctx, "0x%8.8x, 0x%x, %i", breakpoint->address, breakpoint->length, breakpoint->set);\r
+                       }\r
+                       breakpoint = breakpoint->next;\r
+               }\r
+       }\r
+       else if (argc >= 2)\r
+       {\r
+               int hw = BKPT_SOFT;\r
+               u32 length = 0;\r
+\r
+               length = strtoul(args[1], NULL, 0);\r
+               \r
+               if (argc >= 3)\r
+                       if (strcmp(args[2], "hw") == 0)\r
+                               hw = BKPT_HARD;\r
+\r
+               if ((retval = breakpoint_add(target, strtoul(args[0], NULL, 0), length, hw)) != ERROR_OK)\r
+               {\r
+                       switch (retval)\r
+                       {\r
+                               case ERROR_TARGET_NOT_HALTED:\r
+                                       command_print(cmd_ctx, "target must be halted to set breakpoints");\r
+                                       break;\r
+                               case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:\r
+                                       command_print(cmd_ctx, "no more breakpoints available");\r
+                                       break;\r
+                               default:\r
+                                       command_print(cmd_ctx, "unknown error, breakpoint not set");\r
+                                       break;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       command_print(cmd_ctx, "breakpoint added at address 0x%8.8x", strtoul(args[0], NULL, 0));\r
+               }\r
+       }\r
+       else\r
+       {\r
+               command_print(cmd_ctx, "usage: bp <address> <length> ['hw']");\r
+       }\r
+\r
+       return ERROR_OK;\r
+}\r
+\r
+int handle_rbp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       target_t *target = get_current_target(cmd_ctx);\r
+\r
+       if (argc > 0)\r
+               breakpoint_remove(target, strtoul(args[0], NULL, 0));\r
+\r
+       return ERROR_OK;\r
+}\r
+\r
+int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       target_t *target = get_current_target(cmd_ctx);\r
+       int retval;\r
+\r
+       if (argc == 0)\r
+       {\r
+               watchpoint_t *watchpoint = target->watchpoints;\r
+\r
+               while (watchpoint)\r
+               {\r
+                       command_print(cmd_ctx, "address: 0x%8.8x, mask: 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);\r
+                       watchpoint = watchpoint->next;\r
+               }\r
+       } \r
+       else if (argc >= 2)\r
+       {\r
+               enum watchpoint_rw type = WPT_ACCESS;\r
+               u32 data_value = 0x0;\r
+               u32 data_mask = 0xffffffff;\r
+               \r
+               if (argc >= 3)\r
+               {\r
+                       switch(args[2][0])\r
+                       {\r
+                               case 'r':\r
+                                       type = WPT_READ;\r
+                                       break;\r
+                               case 'w':\r
+                                       type = WPT_WRITE;\r
+                                       break;\r
+                               case 'a':\r
+                                       type = WPT_ACCESS;\r
+                                       break;\r
+                               default:\r
+                                       command_print(cmd_ctx, "usage: wp <address> <length> [r/w/a] [value] [mask]");\r
+                                       return ERROR_OK;\r
+                       }\r
+               }\r
+               if (argc >= 4)\r
+               {\r
+                       data_value = strtoul(args[3], NULL, 0);\r
+               }\r
+               if (argc >= 5)\r
+               {\r
+                       data_mask = strtoul(args[4], NULL, 0);\r
+               }\r
+               \r
+               if ((retval = watchpoint_add(target, strtoul(args[0], NULL, 0),\r
+                               strtoul(args[1], NULL, 0), type, data_value, data_mask)) != ERROR_OK)\r
+               {\r
+                       switch (retval)\r
+                       {\r
+                               case ERROR_TARGET_NOT_HALTED:\r
+                                       command_print(cmd_ctx, "target must be halted to set watchpoints");\r
+                                       break;\r
+                               case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:\r
+                                       command_print(cmd_ctx, "no more watchpoints available");\r
+                                       break;\r
+                               default:\r
+                                       command_print(cmd_ctx, "unknown error, watchpoint not set");\r
+                                       break;\r
+                       }       \r
+               }\r
+       }\r
+       else\r
+       {\r
+               command_print(cmd_ctx, "usage: wp <address> <length> [r/w/a] [value] [mask]");\r
+       }\r
+               \r
+       return ERROR_OK;\r
+}\r
+\r
+int handle_rwp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       target_t *target = get_current_target(cmd_ctx);\r
+\r
+       if (argc > 0)\r
+               watchpoint_remove(target, strtoul(args[0], NULL, 0));\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       int retval;\r
+       target_t *target = get_current_target(cmd_ctx);\r
+       u32 va;\r
+       u32 pa;\r
+\r
+       if (argc != 1)\r
+       {\r
+               return ERROR_COMMAND_SYNTAX_ERROR;\r
+       }\r
+       va = strtoul(args[0], NULL, 0);\r
+\r
+       retval = target->type->virt2phys(target, va, &pa);\r
+       if (retval == ERROR_OK)\r
+       {\r
+               command_print(cmd_ctx, "Physical address 0x%08x", pa);\r
+       }\r
+       else\r
+       {\r
+               /* lower levels will have logged a detailed error which is \r
+                * forwarded to telnet/GDB session.  \r
+                */\r
+       }\r
+       return retval;\r
+}\r

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)