X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Ftarget%2Ftarget.c;h=531d632e698384ddec9dd321be8e12c84a0afe1d;hb=a582e9a8d183c56d1aa8ae18afc1c11e2cbd6d2d;hp=98407afb79839d66f2e68ecd4684ffbee31ec47f;hpb=8b4e882a1630d63bbc9840fa3f968e36b6ac3702;p=openocd.git diff --git a/src/target/target.c b/src/target/target.c index 98407afb79..531d632e69 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -17,7 +17,11 @@ * 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 "log.h" @@ -71,6 +75,7 @@ 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; target_type_t *target_types[] = { @@ -78,6 +83,7 @@ target_type_t *target_types[] = &arm9tdmi_target, &arm920t_target, &arm720t_target, + &arm966e_target, NULL, }; @@ -111,6 +117,42 @@ 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) { @@ -653,6 +695,7 @@ int target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffe if ((retval = target->type->read_memory(target, address, 1, unaligned, buffer)) != ERROR_OK) return retval; + buffer += unaligned; address += unaligned; size -= unaligned; } @@ -665,6 +708,7 @@ int target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffe if ((retval = target->type->read_memory(target, address, 4, aligned / 4, buffer)) != ERROR_OK) return retval; + buffer += aligned; address += aligned; size -= aligned; } @@ -679,6 +723,50 @@ int target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffe return ERROR_OK; } +void target_read_u32(struct target_s *target, u32 address, u32 *value) +{ + u8 value_buf[4]; + + target->type->read_memory(target, address, 4, 1, value_buf); + + *value = target_buffer_get_u32(target, value_buf); +} + +void target_read_u16(struct target_s *target, u32 address, u16 *value) +{ + u8 value_buf[2]; + + target->type->read_memory(target, address, 2, 1, value_buf); + + *value = target_buffer_get_u16(target, value_buf); +} + +void target_read_u8(struct target_s *target, u32 address, u8 *value) +{ + target->type->read_memory(target, address, 1, 1, value); +} + +void target_write_u32(struct target_s *target, u32 address, u32 value) +{ + u8 value_buf[4]; + + target_buffer_set_u32(target, value_buf, value); + target->type->write_memory(target, address, 4, 1, value_buf); +} + +void target_write_u16(struct target_s *target, u32 address, u16 value) +{ + u8 value_buf[2]; + + target_buffer_set_u16(target, value_buf, value); + target->type->write_memory(target, address, 2, 1, value_buf); +} + +void target_write_u8(struct target_s *target, u32 address, u8 value) +{ + target->type->read_memory(target, address, 1, 1, &value); +} + int target_register_user_commands(struct command_context_s *cmd_ctx) { register_command(cmd_ctx, NULL, "reg", handle_reg_command, COMMAND_EXEC, NULL); @@ -997,7 +1085,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); } @@ -1062,7 +1150,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; @@ -1071,7 +1159,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) { @@ -1079,11 +1169,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; } @@ -1377,6 +1470,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; @@ -1389,13 +1483,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; } @@ -1417,6 +1511,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; @@ -1427,13 +1522,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; @@ -1471,7 +1569,7 @@ int handle_load_binary_command(struct command_context_s *cmd_ctx, char *cmd, cha u8 *buffer; u32 buf_cnt; - struct timeval start, end; + struct timeval start, end, duration; target_t *target = get_current_target(cmd_ctx); @@ -1490,7 +1588,7 @@ int handle_load_binary_command(struct command_context_s *cmd_ctx, char *cmd, cha return ERROR_OK; } - if (!(binary = fopen(args[0], "r"))) + if (!(binary = fopen(args[0], "rb"))) { ERROR("couldn't open %s: %s", args[0], strerror(errno)); command_print(cmd_ctx, "error accessing file %s", args[0]); @@ -1514,7 +1612,8 @@ int handle_load_binary_command(struct command_context_s *cmd_ctx, char *cmd, cha free(buffer); - command_print(cmd_ctx, "downloaded %lli byte in %is %ius", (long long) binary_stat.st_size, end.tv_sec - start.tv_sec, end.tv_usec - start.tv_usec); + 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); @@ -1529,6 +1628,8 @@ int handle_dump_binary_command(struct command_context_s *cmd_ctx, char *cmd, cha u32 size; u8 buffer[560]; + struct timeval start, end, duration; + target_t *target = get_current_target(cmd_ctx); if (argc != 3) @@ -1540,7 +1641,7 @@ int handle_dump_binary_command(struct command_context_s *cmd_ctx, char *cmd, cha address = strtoul(args[1], NULL, 0); size = strtoul(args[2], NULL, 0); - if (!(binary = fopen(args[0], "w"))) + if (!(binary = fopen(args[0], "wb"))) { ERROR("couldn't open %s for writing: %s", args[0], strerror(errno)); command_print(cmd_ctx, "error accessing file %s", args[0]); @@ -1553,6 +1654,8 @@ int handle_dump_binary_command(struct command_context_s *cmd_ctx, char *cmd, cha return ERROR_OK; } + gettimeofday(&start, NULL); + while (size > 0) { u32 this_run_size = (size > 560) ? 560 : size; @@ -1564,6 +1667,11 @@ int handle_dump_binary_command(struct command_context_s *cmd_ctx, char *cmd, cha fclose(binary); + gettimeofday(&end, NULL); + + timeval_subtract(&duration, &end, &start); + command_print(cmd_ctx, "dumped %i byte in %is %ius", strtoul(args[2], NULL, 0), duration.tv_sec, duration.tv_usec); + return ERROR_OK; } @@ -1581,7 +1689,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); } @@ -1618,6 +1726,14 @@ int handle_bp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, 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
['hw']"); } return ERROR_OK;