summaryrefslogtreecommitdiff
path: root/src/target
diff options
context:
space:
mode:
authoroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2008-10-12 17:28:12 +0000
committeroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2008-10-12 17:28:12 +0000
commit809a796209b5660bd4b968a48794211871f686b9 (patch)
tree9ccf35549566969f2e587a3edd26456b37dcc1f2 /src/target
parent0689815716ca7dbc1955b48390f502556ebb181a (diff)
downloadopenocd+libswd-809a796209b5660bd4b968a48794211871f686b9.tar.gz
openocd+libswd-809a796209b5660bd4b968a48794211871f686b9.tar.bz2
openocd+libswd-809a796209b5660bd4b968a48794211871f686b9.tar.xz
openocd+libswd-809a796209b5660bd4b968a48794211871f686b9.zip
Fix problems with DCC downloads routine crashing silently.
git-svn-id: svn://svn.berlios.de/openocd/trunk@1040 b42882b7-edfa-0310-969c-e2dbd0fdcd60
Diffstat (limited to 'src/target')
-rw-r--r--src/target/arm7_9_common.c128
-rw-r--r--src/target/armv4_5.c54
2 files changed, 101 insertions, 81 deletions
diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c
index cd4eba1a..225dd9ec 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(&reg_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(&reg_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 6848bf76..93dfa8ad 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;