From: oharboe Date: Sun, 12 Oct 2008 17:28:12 +0000 (+0000) Subject: Fix problems with DCC downloads routine crashing silently. X-Git-Tag: v0.1.0~269 X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=commitdiff_plain;h=809a796209b5660bd4b968a48794211871f686b9 Fix problems with DCC downloads routine crashing silently. git-svn-id: svn://svn.berlios.de/openocd/trunk@1040 b42882b7-edfa-0310-969c-e2dbd0fdcd60 --- diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index cd4eba1ad8..225dd9ecb2 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -2124,20 +2124,61 @@ int arm7_9_write_memory(struct target_s *target, u32 address, u32 size, u32 coun return ERROR_OK; } +static int dcc_count; +static u8 *dcc_buffer; + + +static int arm7_9_dcc_completion(struct target_s *target, u32 exit_point, int timeout_ms, void *arch_info) +{ + armv4_5_common_t *armv4_5 = target->arch_info; + arm7_9_common_t *arm7_9 = armv4_5->arch_info; + int little=target->endianness==TARGET_LITTLE_ENDIAN; + int count=dcc_count; + u8 *buffer=dcc_buffer; + if (count>2) + { + /* Handle first & last using standard embeddedice_write_reg and the middle ones w/the + core function repeated. + */ + embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], fast_target_buffer_get_u32(buffer, little)); + buffer+=4; + + embeddedice_reg_t *ice_reg = arm7_9->eice_cache->reg_list[EICE_COMMS_DATA].arch_info; + u8 reg_addr = ice_reg->addr & 0x1f; + int chain_pos = ice_reg->jtag_info->chain_pos; + + embeddedice_write_dcc(chain_pos, reg_addr, buffer, little, count-2); + buffer += (count-2)*4; + + embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], fast_target_buffer_get_u32(buffer, little)); + } else + { + int i; + for (i = 0; i < count; i++) + { + embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], fast_target_buffer_get_u32(buffer, little)); + buffer += 4; + } + } + + target_halt(target); + return target_wait_state(target, TARGET_HALTED, 500); +} + + static const u32 dcc_code[] = { /* MRC TST BNE MRC STR B */ 0xee101e10, 0xe3110001, 0x0afffffc, 0xee111e10, 0xe4801004, 0xeafffff9 }; +int armv4_5_run_algorithm_inner(struct target_s *target, int num_mem_params, mem_param_t *mem_params, int num_reg_params, reg_param_t *reg_params, u32 entry_point, u32 exit_point, int timeout_ms, void *arch_info, int (*run_it)(struct target_s *target, u32 exit_point, int timeout_ms, void *arch_info)); + + int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer) { armv4_5_common_t *armv4_5 = target->arch_info; arm7_9_common_t *arm7_9 = armv4_5->arch_info; - enum armv4_5_state core_state = armv4_5->core_state; - u32 r0 = buf_get_u32(armv4_5->core_cache->reg_list[0].value, 0, 32); - u32 r1 = buf_get_u32(armv4_5->core_cache->reg_list[1].value, 0, 32); - u32 pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32); int i; if (!arm7_9->dcc_downloads) @@ -2165,75 +2206,38 @@ int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffe target->type->write_memory(target, arm7_9->dcc_working_area->address, 4, 6, dcc_code_buf); } - buf_set_u32(armv4_5->core_cache->reg_list[0].value, 0, 32, address); - armv4_5->core_cache->reg_list[0].valid = 1; - armv4_5->core_cache->reg_list[0].dirty = 1; - armv4_5->core_state = ARMV4_5_STATE_ARM; - - arm7_9_resume(target, 0, arm7_9->dcc_working_area->address, 1, 1); - - int little=target->endianness==TARGET_LITTLE_ENDIAN; - if (count>2) - { - /* Handle first & last using standard embeddedice_write_reg and the middle ones w/the - core function repeated. - */ - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], fast_target_buffer_get_u32(buffer, little)); - buffer+=4; + armv4_5_algorithm_t armv4_5_info; + reg_param_t reg_params[1]; - embeddedice_reg_t *ice_reg = arm7_9->eice_cache->reg_list[EICE_COMMS_DATA].arch_info; - u8 reg_addr = ice_reg->addr & 0x1f; - int chain_pos = ice_reg->jtag_info->chain_pos; + 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; - embeddedice_write_dcc(chain_pos, reg_addr, buffer, little, count-2); - buffer += (count-2)*4; + init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], fast_target_buffer_get_u32(buffer, little)); - } else - { - for (i = 0; i < count; i++) - { - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], fast_target_buffer_get_u32(buffer, little)); - buffer += 4; - } - } + buf_set_u32(reg_params[0].value, 0, 32, address); - target_halt(target); + //armv4_5_run_algorithm_inner(struct target_s *target, int num_mem_params, mem_param_t *mem_params, + // int num_reg_params, reg_param_t *reg_params, u32 entry_point, u32 exit_point, int timeout_ms, void *arch_info, int (*run_it)(struct target_s *target, u32 exit_point, int timeout_ms, void *arch_info)) + int retval; + dcc_count=count; + dcc_buffer=buffer; + retval = armv4_5_run_algorithm_inner(target, 0, NULL, 1, reg_params, + arm7_9->dcc_working_area->address, arm7_9->dcc_working_area->address+6*4, 20*1000, &armv4_5_info, arm7_9_dcc_completion); - long long then=timeval_ms(); - int timeout; - while (!(timeout=((timeval_ms()-then)>100))) + if (retval==ERROR_OK) { - target_poll(target); - if (target->state == TARGET_HALTED) - break; - if (debug_level>=3) - { - alive_sleep(100); - } else + u32 endaddress=buf_get_u32(reg_params[0].value, 0, 32); + if (endaddress!=(address+count*4)) { - keep_alive(); + LOG_ERROR("DCC write failed, expected end address 0x%08x got 0x%0x", (address+count*4), endaddress); + retval=ERROR_FAIL; } } - if (timeout) - { - LOG_ERROR("bulk write timed out, target not halted"); - return ERROR_TARGET_TIMEOUT; - } - /* restore target state */ - buf_set_u32(armv4_5->core_cache->reg_list[0].value, 0, 32, r0); - armv4_5->core_cache->reg_list[0].valid = 1; - armv4_5->core_cache->reg_list[0].dirty = 1; - buf_set_u32(armv4_5->core_cache->reg_list[1].value, 0, 32, r1); - armv4_5->core_cache->reg_list[1].valid = 1; - armv4_5->core_cache->reg_list[1].dirty = 1; - buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, pc); - armv4_5->core_cache->reg_list[15].valid = 1; - armv4_5->core_cache->reg_list[15].dirty = 1; - armv4_5->core_state = core_state; + destroy_reg_param(®_params[0]); - return ERROR_OK; + return retval; } int arm7_9_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum) diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index 6848bf7617..93dfa8ad34 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -476,7 +476,34 @@ int armv4_5_get_gdb_reg_list(target_t *target, reg_t **reg_list[], int *reg_list return ERROR_OK; } -int armv4_5_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t *mem_params, int num_reg_params, reg_param_t *reg_params, u32 entry_point, u32 exit_point, int timeout_ms, void *arch_info) +/* wait for execution to complete and check exit point */ +static int armv4_5_run_algorithm_completion(struct target_s *target, u32 exit_point, int timeout_ms, void *arch_info) +{ + int retval; + armv4_5_common_t *armv4_5 = target->arch_info; + + target_wait_state(target, TARGET_HALTED, timeout_ms); + if (target->state != TARGET_HALTED) + { + if ((retval=target_halt(target))!=ERROR_OK) + return retval; + if ((retval=target_wait_state(target, TARGET_HALTED, 500))!=ERROR_OK) + { + return retval; + } + return ERROR_TARGET_TIMEOUT; + } + if (buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) != exit_point) + { + LOG_WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4x", + buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32)); + return ERROR_TARGET_TIMEOUT; + } + + return ERROR_OK; +} + +int armv4_5_run_algorithm_inner(struct target_s *target, int num_mem_params, mem_param_t *mem_params, int num_reg_params, reg_param_t *reg_params, u32 entry_point, u32 exit_point, int timeout_ms, void *arch_info, int (*run_it)(struct target_s *target, u32 exit_point, int timeout_ms, void *arch_info)) { armv4_5_common_t *armv4_5 = target->arch_info; armv4_5_algorithm_t *armv4_5_algorithm_info = arch_info; @@ -562,24 +589,7 @@ int armv4_5_run_algorithm(struct target_s *target, int num_mem_params, mem_param target_resume(target, 0, entry_point, 1, 1); - target_wait_state(target, TARGET_HALTED, timeout_ms); - if (target->state != TARGET_HALTED) - { - if ((retval=target_halt(target))!=ERROR_OK) - return retval; - if ((retval=target_wait_state(target, TARGET_HALTED, 500))!=ERROR_OK) - { - return retval; - } - return ERROR_TARGET_TIMEOUT; - } - - if (buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) != exit_point) - { - LOG_WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4x", - buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32)); - return ERROR_TARGET_TIMEOUT; - } + retval=run_it(target, exit_point, timeout_ms, arch_info); breakpoint_remove(target, exit_point); @@ -628,6 +638,12 @@ int armv4_5_run_algorithm(struct target_s *target, int num_mem_params, mem_param return retval; } + +int armv4_5_run_algorithm(struct target_s *target, int num_mem_params, mem_param_t *mem_params, int num_reg_params, reg_param_t *reg_params, u32 entry_point, u32 exit_point, int timeout_ms, void *arch_info) +{ + return armv4_5_run_algorithm_inner(target, num_mem_params, mem_params, num_reg_params, reg_params, entry_point, exit_point, timeout_ms, arch_info, armv4_5_run_algorithm_completion); +} + int armv4_5_init_arch_info(target_t *target, armv4_5_common_t *armv4_5) { target->arch_info = armv4_5;