summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2007-10-22 08:44:34 +0000
committerntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2007-10-22 08:44:34 +0000
commite27696f6b04459e935a0a5f65f7f668cb02970dd (patch)
tree24ec25797d6cc0f97336553b44b0eee920634859 /src
parentce8768f46345e3f88ca6f8f0b88603d79e22d89a (diff)
downloadopenocd+libswd-e27696f6b04459e935a0a5f65f7f668cb02970dd.tar.gz
openocd+libswd-e27696f6b04459e935a0a5f65f7f668cb02970dd.tar.bz2
openocd+libswd-e27696f6b04459e935a0a5f65f7f668cb02970dd.tar.xz
openocd+libswd-e27696f6b04459e935a0a5f65f7f668cb02970dd.zip
- add verify_image command
- add support for gdb qCRC packet (compare-sections command) git-svn-id: svn://svn.berlios.de/openocd/trunk@210 b42882b7-edfa-0310-969c-e2dbd0fdcd60
Diffstat (limited to 'src')
-rw-r--r--src/server/gdb_server.c48
-rw-r--r--src/target/arm720t.c3
-rw-r--r--src/target/arm7_9_common.c76
-rw-r--r--src/target/arm7_9_common.h1
-rw-r--r--src/target/arm7tdmi.c3
-rw-r--r--src/target/arm920t.c3
-rw-r--r--src/target/arm926ejs.c3
-rw-r--r--src/target/arm966e.c3
-rw-r--r--src/target/arm9tdmi.c3
-rw-r--r--src/target/armv7m.c80
-rw-r--r--src/target/armv7m.h2
-rw-r--r--src/target/cortex_m3.c3
-rw-r--r--src/target/image.c31
-rw-r--r--src/target/image.h2
-rw-r--r--src/target/target.c127
-rw-r--r--src/target/target.h3
-rw-r--r--src/target/trace.h3
-rw-r--r--src/target/xscale.c9
18 files changed, 392 insertions, 11 deletions
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index 74928c87..175e0674 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -1167,7 +1167,7 @@ int gdb_breakpoint_watchpoint_packet(connection_t *connection, target_t *target,
return ERROR_OK;
}
-void gdb_query_packet(connection_t *connection, char *packet, int packet_size)
+int gdb_query_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
{
command_context_t *cmd_ctx = connection->cmd_ctx;
@@ -1189,10 +1189,52 @@ void gdb_query_packet(connection_t *connection, char *packet, int packet_size)
free(cmd);
}
gdb_put_packet(connection, "OK", 2);
- return;
+ return ERROR_OK;
}
+ if (strstr(packet, "qCRC:"))
+ {
+ if (packet_size > 5)
+ {
+ int retval;
+ u8 gdb_reply[9];
+ char *separator;
+ u32 checksum;
+ u32 addr = 0;
+ u32 len = 0;
+
+ /* skip command character */
+ packet += 5;
+
+ addr = strtoul(packet, &separator, 16);
+
+ if (*separator != ',')
+ {
+ ERROR("incomplete read memory packet received, dropping connection");
+ return ERROR_SERVER_REMOTE_CLOSED;
+ }
+
+ len = strtoul(separator+1, NULL, 16);
+
+ retval = target_checksum_memory(target, addr, len, &checksum);
+
+ if (retval == ERROR_OK)
+ {
+ snprintf(gdb_reply, 9, "C%2.2x", checksum);
+ gdb_put_packet(connection, gdb_reply, 9);
+ }
+ else
+ {
+ if ((retval = gdb_memory_packet_error(connection, retval)) != ERROR_OK)
+ return retval;
+ }
+
+ return ERROR_OK;
+ }
+ }
+
gdb_put_packet(connection, "", 0);
+ return ERROR_OK;
}
int gdb_v_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
@@ -1382,7 +1424,7 @@ int gdb_input(connection_t *connection)
gdb_put_packet(connection, NULL, 0);
break;
case 'q':
- gdb_query_packet(connection, packet, packet_size);
+ retval = gdb_query_packet(connection, target, packet, packet_size);
break;
case 'g':
retval = gdb_get_registers_packet(connection, target, packet, packet_size);
diff --git a/src/target/arm720t.c b/src/target/arm720t.c
index b5c9752b..05cc30f4 100644
--- a/src/target/arm720t.c
+++ b/src/target/arm720t.c
@@ -70,7 +70,8 @@ target_type_t arm720t_target =
.read_memory = arm720t_read_memory,
.write_memory = arm720t_write_memory,
.bulk_write_memory = arm7_9_bulk_write_memory,
-
+ .checksum_memory = arm7_9_checksum_memory,
+
.run_algorithm = armv4_5_run_algorithm,
.add_breakpoint = arm7_9_add_breakpoint,
diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c
index 35cbe6e5..e596d057 100644
--- a/src/target/arm7_9_common.c
+++ b/src/target/arm7_9_common.c
@@ -2147,6 +2147,82 @@ int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffe
return ERROR_OK;
}
+int arm7_9_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum)
+{
+ working_area_t *crc_algorithm;
+ armv4_5_algorithm_t armv4_5_info;
+ reg_param_t reg_params[2];
+ int retval;
+
+ u32 arm7_9_crc_code[] = {
+ 0xE1A02000, /* mov r2, r0 */
+ 0xE3E00000, /* mov r0, #0xffffffff */
+ 0xE1A03001, /* mov r3, r1 */
+ 0xE3A04000, /* mov r4, #0 */
+ 0xEA00000B, /* b ncomp */
+ /* nbyte: */
+ 0xE7D21004, /* ldrb r1, [r2, r4] */
+ 0xE59F7030, /* ldr r7, CRC32XOR */
+ 0xE0200C01, /* eor r0, r0, r1, asl 24 */
+ 0xE3A05000, /* mov r5, #0 */
+ /* loop: */
+ 0xE3500000, /* cmp r0, #0 */
+ 0xE1A06080, /* mov r6, r0, asl #1 */
+ 0xE2855001, /* add r5, r5, #1 */
+ 0xE1A00006, /* mov r0, r6 */
+ 0xB0260007, /* eorlt r0, r6, r7 */
+ 0xE3550008, /* cmp r5, #8 */
+ 0x1AFFFFF8, /* bne loop */
+ 0xE2844001, /* add r4, r4, #1 */
+ /* ncomp: */
+ 0xE1540003, /* cmp r4, r3 */
+ 0x1AFFFFF1, /* bne nbyte */
+ /* end: */
+ 0xEAFFFFFE, /* b end */
+ 0x04C11DB7 /* CRC32XOR: .word 0x04C11DB7 */
+ };
+
+ int i;
+
+ if (target_alloc_working_area(target, sizeof(arm7_9_crc_code), &crc_algorithm) != ERROR_OK)
+ {
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
+
+ /* convert flash writing code into a buffer in target endianness */
+ for (i = 0; i < (sizeof(arm7_9_crc_code)/sizeof(u32)); i++)
+ target_write_u32(target, crc_algorithm->address + i*sizeof(u32), arm7_9_crc_code[i]);
+
+ armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
+ armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
+ armv4_5_info.core_state = ARMV4_5_STATE_ARM;
+
+ init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
+ init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
+
+ buf_set_u32(reg_params[0].value, 0, 32, address);
+ buf_set_u32(reg_params[1].value, 0, 32, count);
+
+ if ((retval = target->type->run_algorithm(target, 0, NULL, 2, reg_params,
+ crc_algorithm->address, crc_algorithm->address + (sizeof(arm7_9_crc_code) - 8), 20000, &armv4_5_info)) != ERROR_OK)
+ {
+ ERROR("error executing arm7_9 crc algorithm");
+ destroy_reg_param(&reg_params[0]);
+ destroy_reg_param(&reg_params[1]);
+ target_free_working_area(target, crc_algorithm);
+ return retval;
+ }
+
+ *checksum = buf_get_u32(reg_params[0].value, 0, 32);
+
+ destroy_reg_param(&reg_params[0]);
+ destroy_reg_param(&reg_params[1]);
+
+ target_free_working_area(target, crc_algorithm);
+
+ return ERROR_OK;
+}
+
int arm7_9_register_commands(struct command_context_s *cmd_ctx)
{
command_t *arm7_9_cmd;
diff --git a/src/target/arm7_9_common.h b/src/target/arm7_9_common.h
index 53a0ce9f..9d11dc2a 100644
--- a/src/target/arm7_9_common.h
+++ b/src/target/arm7_9_common.h
@@ -121,6 +121,7 @@ int arm7_9_read_core_reg(struct target_s *target, int num, enum armv4_5_mode mod
int arm7_9_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
int arm7_9_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer);
+int arm7_9_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum);
int arm7_9_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t *mem_params, int num_reg_prams, reg_param_t *reg_param, u32 entry_point, void *arch_info);
diff --git a/src/target/arm7tdmi.c b/src/target/arm7tdmi.c
index ae51e3ae..9a9a2450 100644
--- a/src/target/arm7tdmi.c
+++ b/src/target/arm7tdmi.c
@@ -75,7 +75,8 @@ target_type_t arm7tdmi_target =
.read_memory = arm7_9_read_memory,
.write_memory = arm7_9_write_memory,
.bulk_write_memory = arm7_9_bulk_write_memory,
-
+ .checksum_memory = arm7_9_checksum_memory,
+
.run_algorithm = armv4_5_run_algorithm,
.add_breakpoint = arm7_9_add_breakpoint,
diff --git a/src/target/arm920t.c b/src/target/arm920t.c
index 0dff2506..882fec2f 100644
--- a/src/target/arm920t.c
+++ b/src/target/arm920t.c
@@ -79,7 +79,8 @@ target_type_t arm920t_target =
.read_memory = arm920t_read_memory,
.write_memory = arm920t_write_memory,
.bulk_write_memory = arm7_9_bulk_write_memory,
-
+ .checksum_memory = arm7_9_checksum_memory,
+
.run_algorithm = armv4_5_run_algorithm,
.add_breakpoint = arm7_9_add_breakpoint,
diff --git a/src/target/arm926ejs.c b/src/target/arm926ejs.c
index 7d8f371b..ef225145 100644
--- a/src/target/arm926ejs.c
+++ b/src/target/arm926ejs.c
@@ -79,7 +79,8 @@ target_type_t arm926ejs_target =
.read_memory = arm7_9_read_memory,
.write_memory = arm926ejs_write_memory,
.bulk_write_memory = arm7_9_bulk_write_memory,
-
+ .checksum_memory = arm7_9_checksum_memory,
+
.run_algorithm = armv4_5_run_algorithm,
.add_breakpoint = arm7_9_add_breakpoint,
diff --git a/src/target/arm966e.c b/src/target/arm966e.c
index 53627a5f..2885e3df 100644
--- a/src/target/arm966e.c
+++ b/src/target/arm966e.c
@@ -70,7 +70,8 @@ target_type_t arm966e_target =
.read_memory = arm7_9_read_memory,
.write_memory = arm7_9_write_memory,
.bulk_write_memory = arm7_9_bulk_write_memory,
-
+ .checksum_memory = arm7_9_checksum_memory,
+
.run_algorithm = armv4_5_run_algorithm,
.add_breakpoint = arm7_9_add_breakpoint,
diff --git a/src/target/arm9tdmi.c b/src/target/arm9tdmi.c
index b9b1f953..5bb7e399 100644
--- a/src/target/arm9tdmi.c
+++ b/src/target/arm9tdmi.c
@@ -73,7 +73,8 @@ target_type_t arm9tdmi_target =
.read_memory = arm7_9_read_memory,
.write_memory = arm7_9_write_memory,
.bulk_write_memory = arm7_9_bulk_write_memory,
-
+ .checksum_memory = arm7_9_checksum_memory,
+
.run_algorithm = armv4_5_run_algorithm,
.add_breakpoint = arm7_9_add_breakpoint,
diff --git a/src/target/armv7m.c b/src/target/armv7m.c
index 7010b5c0..22ffb5e7 100644
--- a/src/target/armv7m.c
+++ b/src/target/armv7m.c
@@ -578,3 +578,83 @@ int armv7m_register_commands(struct command_context_s *cmd_ctx)
{
return ERROR_OK;
}
+
+int armv7m_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum)
+{
+ working_area_t *crc_algorithm;
+ armv7m_algorithm_t armv7m_info;
+ reg_param_t reg_params[2];
+ int retval;
+
+ u16 cortex_m3_crc_code[] = {
+ 0x4602, /* mov r2, r0 */
+ 0xF04F, 0x30FF, /* mov r0, #0xffffffff */
+ 0x460B, /* mov r3, r1 */
+ 0xF04F, 0x0400, /* mov r4, #0 */
+ 0xE013, /* b ncomp */
+ /* nbyte: */
+ 0x5D11, /* ldrb r1, [r2, r4] */
+ 0xF8DF, 0x7028, /* ldr r7, CRC32XOR */
+ 0xEA80, 0x6001, /* eor r0, r0, r1, asl #24 */
+
+ 0xF04F, 0x0500, /* mov r5, #0 */
+ /* loop: */
+ 0x2800, /* cmp r0, #0 */
+ 0xEA4F, 0x0640, /* mov r6, r0, asl #1 */
+ 0xF105, 0x0501, /* add r5, r5, #1 */
+ 0x4630, /* mov r0, r6 */
+ 0xBFB8, /* it lt */
+ 0xEA86, 0x0007, /* eor r0, r6, r7 */
+ 0x2D08, /* cmp r5, #8 */
+ 0xD1F4, /* bne loop */
+
+ 0xF104, 0x0401, /* add r4, r4, #1 */
+ /* ncomp: */
+ 0x429C, /* cmp r4, r3 */
+ 0xD1E9, /* bne nbyte */
+ /* end: */
+ 0xE7FE, /* b end */
+ 0x1DB7, 0x04C1 /* CRC32XOR: .word 0x04C11DB7 */
+ };
+
+ int i;
+
+ if (target_alloc_working_area(target, sizeof(cortex_m3_crc_code), &crc_algorithm) != ERROR_OK)
+ {
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
+
+ /* convert flash writing code into a buffer in target endianness */
+ for (i = 0; i < (sizeof(cortex_m3_crc_code)/sizeof(u16)); i++)
+ target_write_u16(target, crc_algorithm->address + i*sizeof(u16), cortex_m3_crc_code[i]);
+
+ armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
+ armv7m_info.core_mode = ARMV7M_MODE_ANY;
+ armv7m_info.core_state = ARMV7M_STATE_THUMB;
+
+ init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
+ init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
+
+ buf_set_u32(reg_params[0].value, 0, 32, address);
+ buf_set_u32(reg_params[1].value, 0, 32, count);
+
+ if ((retval = target->type->run_algorithm(target, 0, NULL, 2, reg_params,
+ crc_algorithm->address, crc_algorithm->address + (sizeof(cortex_m3_crc_code)-6), 20000, &armv7m_info)) != ERROR_OK)
+ {
+ ERROR("error executing cortex_m3 crc algorithm");
+ destroy_reg_param(&reg_params[0]);
+ destroy_reg_param(&reg_params[1]);
+ target_free_working_area(target, crc_algorithm);
+ return retval;
+ }
+
+ *checksum = buf_get_u32(reg_params[0].value, 0, 32);
+
+ destroy_reg_param(&reg_params[0]);
+ destroy_reg_param(&reg_params[1]);
+
+ target_free_working_area(target, crc_algorithm);
+
+ return ERROR_OK;
+}
+
diff --git a/src/target/armv7m.h b/src/target/armv7m.h
index 8d06cc65..64689f0b 100644
--- a/src/target/armv7m.h
+++ b/src/target/armv7m.h
@@ -168,6 +168,8 @@ extern int armv7m_use_context(target_t *target, enum armv7m_runcontext new_ctx);
extern enum armv7m_runcontext armv7m_get_context(target_t *target);
extern int armv7m_restore_context(target_t *target);
+extern int armv7m_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum);
+
/* Thumb mode instructions
*/
diff --git a/src/target/cortex_m3.c b/src/target/cortex_m3.c
index c47fbbf8..f1513c7a 100644
--- a/src/target/cortex_m3.c
+++ b/src/target/cortex_m3.c
@@ -74,7 +74,8 @@ target_type_t cortexm3_target =
.read_memory = cortex_m3_read_memory,
.write_memory = cortex_m3_write_memory,
.bulk_write_memory = cortex_m3_bulk_write_memory,
-
+ .checksum_memory = armv7m_checksum_memory,
+
.run_algorithm = armv7m_run_algorithm,
.add_breakpoint = cortex_m3_add_breakpoint,
diff --git a/src/target/image.c b/src/target/image.c
index dbb1c2ab..d20f9df2 100644
--- a/src/target/image.c
+++ b/src/target/image.c
@@ -949,3 +949,34 @@ int image_close(image_t *image)
return ERROR_OK;
}
+
+static u32 crc32_table[256] = {0, 0};
+
+int image_calculate_checksum(u8* buffer, u32 nbytes, u32* checksum)
+{
+ u32 crc = 0xffffffff;
+
+ if (!crc32_table[1])
+ {
+ /* Initialize the CRC table and the decoding table. */
+ int i, j;
+ unsigned int c;
+ for (i = 0; i < 256; i++)
+ {
+ /* as per gdb */
+ for (c = i << 24, j = 8; j > 0; --j)
+ c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
+ crc32_table[i] = c;
+ }
+ }
+
+ while (nbytes--)
+ {
+ /* as per gdb */
+ crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buffer++) & 255];
+ }
+
+ *checksum = crc;
+ return ERROR_OK;
+}
+
diff --git a/src/target/image.h b/src/target/image.h
index e8f585bb..47f0215f 100644
--- a/src/target/image.h
+++ b/src/target/image.h
@@ -105,6 +105,8 @@ extern int image_read_section(image_t *image, int section, u32 offset, u32 size,
extern int image_close(image_t *image);
extern int image_add_section(image_t *image, u32 base, u32 size, int flags, u8 *data);
+extern int image_calculate_checksum(u8* buffer, u32 nbytes, u32* checksum);
+
#define ERROR_IMAGE_FORMAT_ERROR (-1400)
#define ERROR_IMAGE_TYPE_UNKNOWN (-1401)
#define ERROR_IMAGE_TEMPORARILY_UNAVAILABLE (-1402)
diff --git a/src/target/target.c b/src/target/target.c
index f471167b..f9d957d6 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -69,6 +69,7 @@ int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char **args,
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);
@@ -752,6 +753,36 @@ int target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffe
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);
+ target_read_buffer(target, address, size, buffer);
+
+ /* 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];
@@ -881,6 +912,7 @@ int target_register_user_commands(struct command_context_s *cmd_ctx)
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>");
@@ -1802,6 +1834,101 @@ int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char
}
+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 ((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 );
+ free(buffer);
+
+ retval = target_checksum_memory(target, image.sections[i].base_address, buf_cnt, &mem_checksum);
+
+ if( retval != ERROR_OK )
+ {
+ command_print(cmd_ctx, "image verify failed, verify aborted");
+ image_close(&image);
+ return ERROR_OK;
+ }
+
+ if( checksum != mem_checksum )
+ {
+ command_print(cmd_ctx, "image verify failed, verify aborted");
+ image_close(&image);
+ return ERROR_OK;
+ }
+
+ 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;
diff --git a/src/target/target.h b/src/target/target.h
index ae5fbc43..1900351e 100644
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -129,6 +129,8 @@ typedef struct target_type_s
/* write target memory in multiples of 4 byte, optimized for writing large quantities of data */
int (*bulk_write_memory)(struct target_s *target, u32 address, u32 count, u8 *buffer);
+ int (*checksum_memory)(struct target_s *target, u32 address, u32 count, u32* checksum);
+
/* target break-/watchpoint control
* rw: 0 = write, 1 = read, 2 = access
*/
@@ -217,6 +219,7 @@ extern target_t* get_target_by_num(int num);
extern int target_write_buffer(struct target_s *target, u32 address, u32 size, u8 *buffer);
extern int target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffer);
+extern int target_checksum_memory(struct target_s *target, u32 address, u32 size, u32* crc);
extern int target_alloc_working_area(struct target_s *target, u32 size, working_area_t **area);
extern int target_free_working_area(struct target_s *target, working_area_t *area);
diff --git a/src/target/trace.h b/src/target/trace.h
index 0279d51f..f7d9e5b1 100644
--- a/src/target/trace.h
+++ b/src/target/trace.h
@@ -21,6 +21,8 @@
#define TRACE_H
#include "target.h"
+#include "command.h"
+#include "types.h"
typedef struct trace_point_s
{
@@ -49,6 +51,7 @@ typedef enum trace_status
} trace_status_t;
extern int trace_point(struct target_s *target, int number);
+extern int trace_register_commands(struct command_context_s *cmd_ctx);
#define ERROR_TRACE_IMAGE_UNAVAILABLE -(1500)
#define ERROR_TRACE_INSTRUCTION_UNAVAILABLE -(1501)
diff --git a/src/target/xscale.c b/src/target/xscale.c
index b207dbb2..baef5fe9 100644
--- a/src/target/xscale.c
+++ b/src/target/xscale.c
@@ -74,6 +74,7 @@ int xscale_write_core_reg(struct target_s *target, int num, enum armv4_5_mode mo
int xscale_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
int xscale_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
int xscale_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer);
+int xscale_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum);
int xscale_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
int xscale_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
@@ -109,7 +110,8 @@ target_type_t xscale_target =
.read_memory = xscale_read_memory,
.write_memory = xscale_write_memory,
.bulk_write_memory = xscale_bulk_write_memory,
-
+ .checksum_memory = xscale_checksum_memory,
+
.run_algorithm = armv4_5_run_algorithm,
.add_breakpoint = xscale_add_breakpoint,
@@ -2035,6 +2037,11 @@ int xscale_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffe
return ERROR_OK;
}
+int xscale_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum)
+{
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+}
+
u32 xscale_get_ttb(target_t *target)
{
armv4_5_common_t *armv4_5 = target->arch_info;