- reformat src/jtag/bitq.c (thanks to Pavel Chromy)
[fw/openocd] / src / target / target.c
index 2f5126dfefbbdf0134dfeb429cfa45bfd4e5c813..10d430b9392eb36ea476317f58253285f7804594 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <string.h>
 #include <stdlib.h>
+#include <inttypes.h>
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -42,6 +43,9 @@
 
 #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);
@@ -62,8 +66,8 @@ int handle_resume_command(struct command_context_s *cmd_ctx, char *cmd, char **a
 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_binary_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int handle_dump_binary_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_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);
@@ -76,6 +80,9 @@ 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 xscale_target;
+extern target_type_t cortexm3_target;
 
 target_type_t *target_types[] =
 {
@@ -84,6 +91,9 @@ target_type_t *target_types[] =
        &arm920t_target,
        &arm720t_target,
        &arm966e_target,
+       &arm926ejs_target,
+       &xscale_target,
+       &cortexm3_target,
        NULL,
 };
 
@@ -209,6 +219,8 @@ int target_init_handler(struct target_s *target, enum target_event event, void *
        
        if ((event == TARGET_EVENT_HALTED) && (target->reset_script))
        {
+               target_unregister_event_callback(target_init_handler, priv);
+
                script = fopen(target->reset_script, "r");
                if (!script)
                {
@@ -221,8 +233,6 @@ int target_init_handler(struct target_s *target, enum target_event event, void *
                fclose(script);
 
                jtag_execute_queue();
-
-               target_unregister_event_callback(target_init_handler, priv);
        }
        
        return ERROR_OK;
@@ -241,7 +251,23 @@ int target_process_reset(struct command_context_s *cmd_ctx)
 {
        int retval = ERROR_OK;
        target_t *target;
-        
+       
+       /* prepare reset_halt where necessary */
+       target = targets;
+       while (target)
+       {
+               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)
        {
@@ -627,6 +653,7 @@ int target_write_buffer(struct target_s *target, u32 address, u32 size, u8 *buff
        {
                if ((retval = target->type->write_memory(target, address, 1, size, buffer)) != ERROR_OK)
                        return retval;
+               return ERROR_OK;
        }
        
        /* handle unaligned head bytes */
@@ -685,6 +712,7 @@ int target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffe
        {
                if ((retval = target->type->read_memory(target, address, 1, size, buffer)) != ERROR_OK)
                        return retval;
+               return ERROR_OK;
        }
        
        /* handle unaligned head bytes */
@@ -723,11 +751,114 @@ int target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffe
        return ERROR_OK;
 }
 
+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");
+       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");
@@ -747,8 +878,10 @@ int target_register_user_commands(struct command_context_s *cmd_ctx)
        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_binary", handle_load_binary_command, COMMAND_EXEC, "load binary <file> <address>");
-       register_command(cmd_ctx,  NULL, "dump_binary", handle_dump_binary_command, COMMAND_EXEC, "dump binary <file> <address> <size>");
+       register_command(cmd_ctx,  NULL, "load_image", handle_load_image_command, COMMAND_EXEC, "load_image <file> <address> ['bin'|'ihex'|'elf']");
+       register_command(cmd_ctx,  NULL, "dump_image", handle_dump_image_command, COMMAND_EXEC, "dump_image <file> <address> <size>");
+       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>");
        
        return ERROR_OK;
 }
@@ -860,7 +993,6 @@ int handle_target_command(struct command_context_s *cmd_ctx, char *cmd, char **a
                                (*last_target_p)->working_areas = NULL;
                                (*last_target_p)->backup_working_area = 0;
                                
-                               (*last_target_p)->endianness = TARGET_LITTLE_ENDIAN;
                                (*last_target_p)->state = TARGET_UNKNOWN;
                                (*last_target_p)->reg_cache = NULL;
                                (*last_target_p)->breakpoints = NULL;
@@ -1026,7 +1158,7 @@ int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args
        int count = 0;
        char *value;
        
-       DEBUG("");
+       DEBUG("-");
        
        target = get_current_target(cmd_ctx);
        
@@ -1041,7 +1173,7 @@ int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args
                        int i;
                        for (i = 0; i < cache->num_regs; i++)
                        {
-                               value = buf_to_char(cache->reg_list[i].value, cache->reg_list[i].size);
+                               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);
                        }
@@ -1106,7 +1238,7 @@ int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args
                        }
                        arch_type->get(reg);
                }
-               value = buf_to_char(reg->value, reg->size);
+               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;
@@ -1115,7 +1247,9 @@ int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args
        /* set register value */
        if (argc == 2)
        {
-               u32 new_value = strtoul(args[1], NULL, 0);
+               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)
                {
@@ -1123,11 +1257,14 @@ int handle_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args
                        return ERROR_OK;
                }
                
-               arch_type->set(reg, new_value);
-               value = buf_to_char(reg->value, reg->size);
+               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;
        }
        
@@ -1173,7 +1310,17 @@ int handle_wait_halt_command(struct command_context_s *cmd_ctx, char *cmd, char
        struct timeval timeout, now;
        
        gettimeofday(&timeout, NULL);
-       timeval_add_time(&timeout, 5, 0);
+       if (!argc)
+               timeval_add_time(&timeout, 5, 0);
+       else {
+               char *end;
+
+               timeval_add_time(&timeout, strtoul(args[0], &end, 0), 0);
+               if (*end) {
+                       command_print(cmd_ctx, "usage: wait_halt [seconds]");
+                       return ERROR_OK;
+               }
+       }
 
        command_print(cmd_ctx, "waiting for target halted...");
 
@@ -1203,7 +1350,7 @@ int handle_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **arg
        int retval;
        target_t *target = get_current_target(cmd_ctx);
 
-       DEBUG("");
+       DEBUG("-");
        
        command_print(cmd_ctx, "requesting target halt...");
 
@@ -1277,7 +1424,7 @@ int handle_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **ar
        target_t *target = get_current_target(cmd_ctx);
        enum target_reset_mode reset_mode = RESET_RUN;
        
-       DEBUG("");
+       DEBUG("-");
        
        if (argc >= 1)
        {
@@ -1321,7 +1468,7 @@ int handle_resume_command(struct command_context_s *cmd_ctx, char *cmd, char **a
        int retval;
        target_t *target = get_current_target(cmd_ctx);
        
-       DEBUG("");
+       DEBUG("-");
        
        if (argc == 0)
                retval = target->type->resume(target, 1, 0, 1, 0); /* current pc, addr = 0, handle breakpoints, not debugging */
@@ -1353,7 +1500,7 @@ int handle_step_command(struct command_context_s *cmd_ctx, char *cmd, char **arg
 {
        target_t *target = get_current_target(cmd_ctx);
        
-       DEBUG("");
+       DEBUG("-");
        
        if (argc == 0)
                target->type->step(target, 1, 0, 1); /* current pc, addr = 0, handle breakpoints */
@@ -1421,6 +1568,7 @@ int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char **args,
                                command_print(cmd_ctx, "error: unknown error");
                                break;
                }
+               return ERROR_OK;
        }
 
        output_len = 0;
@@ -1433,13 +1581,13 @@ int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char **args,
                switch (size)
                {
                        case 4:
-                               output_len += snprintf(output + output_len, 128 - output_len, "%8.8x ", ((u32*)buffer)[i]);
+                               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 ", ((u16*)buffer)[i]);
+                               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 ", ((u8*)buffer)[i]);
+                               output_len += snprintf(output + output_len, 128 - output_len, "%2.2x ", buffer[i*1]);
                                break;
                }
 
@@ -1461,6 +1609,7 @@ int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char **args,
        u32 value = 0;
        int retval;
        target_t *target = get_current_target(cmd_ctx);
+       u8 value_buf[4];
 
        if (argc < 2)
                return ERROR_OK;
@@ -1471,13 +1620,16 @@ int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char **args,
        switch (cmd[2])
        {
                case 'w':
-                       retval = target->type->write_memory(target, address, 4, 1, (u8*)&value);
+                       target_buffer_set_u32(target, value_buf, value);
+                       retval = target->type->write_memory(target, address, 4, 1, value_buf);
                        break;
                case 'h':
-                       retval = target->type->write_memory(target, address, 2, 1, (u8*)&value);
+                       target_buffer_set_u16(target, value_buf, value);
+                       retval = target->type->write_memory(target, address, 2, 1, value_buf);
                        break;
                case 'b':
-                       retval = target->type->write_memory(target, address, 1, 1, (u8*)&value);
+                       value_buf[0] = value;
+                       retval = target->type->write_memory(target, address, 1, 1, value_buf);
                        break;
                default:
                        return ERROR_OK;
@@ -1505,110 +1657,131 @@ int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char **args,
 
 }
 
-int handle_load_binary_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)
 {
-       FILE *binary;
-       u32 address;
-       struct stat binary_stat;
-       u32 binary_size;
-
        u8 *buffer;
        u32 buf_cnt;
+       u32 image_size;
+       int i;
+       int retval;
+
+       image_t image;  
+       
+       duration_t duration;
+       char *duration_text;
        
-       struct timeval start, end, duration;
-               
        target_t *target = get_current_target(cmd_ctx);
 
-       if (argc != 2)
+       if (argc < 1)
        {
-               command_print(cmd_ctx, "usage: load_binary <filename> <address>");
+               command_print(cmd_ctx, "usage: load_image <filename> [address] [type]");
                return ERROR_OK;
        }
-
-       address = strtoul(args[1], NULL, 0);
-
-       if (stat(args[0], &binary_stat) == -1)
+       
+       /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
+       if (argc >= 2)
        {
-               ERROR("couldn't stat() %s: %s", args[0], strerror(errno));
-               command_print(cmd_ctx, "error accessing file %s", args[0]);
-               return ERROR_OK;
+               image.base_address_set = 1;
+               image.base_address = strtoul(args[1], NULL, 0);
        }
+       else
+       {
+               image.base_address_set = 0;
+       }
+       
+       image.start_address_set = 0;
 
-       if (!(binary = fopen(args[0], "rb")))
+       duration_start_measure(&duration);
+       
+       if (image_open(&image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
        {
-               ERROR("couldn't open %s: %s", args[0], strerror(errno));
-               command_print(cmd_ctx, "error accessing file %s", args[0]);
+               command_print(cmd_ctx, "load_image error: %s", image.error_str);
                return ERROR_OK;
        }
        
-       buffer = malloc(128 * 1024);
-
-       gettimeofday(&start, NULL);     
-
-       binary_size = binary_stat.st_size;
-       while (binary_size > 0)
+       image_size = 0x0;
+       for (i = 0; i < image.num_sections; i++)
        {
-               buf_cnt = fread(buffer, 1, 128*1024, binary);
-               target_write_buffer(target, address, buf_cnt, buffer);
-               address += buf_cnt;
-               binary_size -= buf_cnt;
+               buffer = malloc(image.sections[i].size);
+               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);
        }
 
-       gettimeofday(&end, NULL);       
-
-       free(buffer);
+       duration_stop_measure(&duration, &duration_text);
+       command_print(cmd_ctx, "downloaded %u byte in %s", image_size, duration_text);
+       free(duration_text);
        
-       timeval_subtract(&duration, &end, &start);
-       command_print(cmd_ctx, "downloaded %lli byte in %is %ius", (long long) binary_stat.st_size, duration.tv_sec, duration.tv_usec);
-       
-       fclose(binary);
+       image_close(&image);
 
        return ERROR_OK;
 
 }
 
-int handle_dump_binary_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)
 {
-       FILE *binary;
+       fileio_t fileio;
+       
        u32 address;
        u32 size;
        u8 buffer[560];
        
+       duration_t duration;
+       char *duration_text;
+       
        target_t *target = get_current_target(cmd_ctx);
 
        if (argc != 3)
        {
-               command_print(cmd_ctx, "usage: dump_binary <filename> <address> <size>");
+               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 (!(binary = fopen(args[0], "wb")))
+       if ((address & 3) || (size & 3))
        {
-               ERROR("couldn't open %s for writing: %s", args[0], strerror(errno));
-               command_print(cmd_ctx, "error accessing file %s", args[0]);
+               command_print(cmd_ctx, "only 32-bit aligned address and size are supported");
                return ERROR_OK;
        }
-
-       if ((address & 3) || (size & 3))
+       
+       if (fileio_open(&fileio, args[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)
        {
-               command_print(cmd_ctx, "only 32-bit aligned address and size are supported");
+               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;
+               
                target->type->read_memory(target, address, 4, this_run_size / 4, buffer);
-               fwrite(buffer, 1, this_run_size, binary);
+               fileio_write(&fileio, this_run_size, buffer, &size_written);
+               
                size -= this_run_size;
                address += this_run_size;
        }
 
-       fclose(binary);
+       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;
 
 }
@@ -1626,7 +1799,7 @@ int handle_bp_command(struct command_context_s *cmd_ctx, char *cmd, char **args,
                {
                        if (breakpoint->type == BKPT_SOFT)
                        {
-                               char* buf = buf_to_char(breakpoint->orig_instr, breakpoint->length);
+                               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);
                        }
@@ -1689,6 +1862,7 @@ int handle_rbp_command(struct command_context_s *cmd_ctx, char *cmd, char **args
 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)
        {
@@ -1732,7 +1906,23 @@ int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char **args,
                {
                        data_mask = strtoul(args[4], NULL, 0);
                }
-               watchpoint_add(target, strtoul(args[0], NULL, 0), strtoul(args[1], NULL, 0), type, data_value, data_mask);
+               
+               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
        {