From ecd5e5de7f34f4255f4482c66c7c3ddfca0f4804 Mon Sep 17 00:00:00 2001 From: Luca Ellero Date: Wed, 13 Apr 2011 18:55:19 +0000 Subject: Replace byte-access to memory with faster word-access Freescale iMX53 doesn't seem to like unaligned accesses to his memory mapped registers. Anyway this patch makes dump_image/load_image 4X faster for every access through APB. Signed-off-by: Luca Ellero --- src/target/cortex_a.c | 90 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 69 insertions(+), 21 deletions(-) mode change 100644 => 100755 src/target/cortex_a.c (limited to 'src') diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c old mode 100644 new mode 100755 index 86706cc6..934f75aa --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -1450,42 +1450,76 @@ static int cortex_a8_deassert_reset(struct target *target) return ERROR_OK; } + static int cortex_a8_write_apb_ab_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer) { + + /* write memory through APB-AP */ + int retval = ERROR_INVALID_ARGUMENTS; struct armv7a_common *armv7a = target_to_armv7a(target); struct arm *armv4_5 = &armv7a->armv4_5_common; - int nbytes = count * size; - uint32_t data; + int total_bytes = count * size; + int start_byte, nbytes_to_write, i; struct reg *reg; + union _data { + uint8_t uc_a[4]; + uint32_t ui; + } data; if (target->state != TARGET_HALTED) { LOG_WARNING("target not halted"); return ERROR_TARGET_NOT_HALTED; } + reg = arm_reg_current(armv4_5, 0); reg->dirty = 1; reg = arm_reg_current(armv4_5, 1); reg->dirty = 1; - retval = cortex_a8_dap_write_coreregister_u32(target, address, 0); + + retval = cortex_a8_dap_write_coreregister_u32(target, address & 0xFFFFFFFC, 0); if (retval != ERROR_OK) return retval; - while (nbytes > 0) { - data = *buffer++; - retval = cortex_a8_dap_write_coreregister_u32(target, data, 1); + start_byte = address & 0x3; + + while (total_bytes > 0) { + + nbytes_to_write = 4 - start_byte; + if (total_bytes < nbytes_to_write) + nbytes_to_write = total_bytes; + + if ( nbytes_to_write != 4 ) { + + /* execute instruction LDR r1, [r0] */ + retval = cortex_a8_exec_opcode(target, ARMV4_5_LDR(1, 0), NULL); + if (retval != ERROR_OK) + return retval; + + retval = cortex_a8_dap_read_coreregister_u32(target, &data.ui, 1); + if (retval != ERROR_OK) + return retval; + } + + for (i = 0; i < nbytes_to_write; ++i) + data.uc_a[i + start_byte] = *buffer++; + + retval = cortex_a8_dap_write_coreregister_u32(target, data.ui, 1); if (retval != ERROR_OK) return retval; - /* execute instruction STRB r1, [r0], 1 (0xe4c01001) */ - retval = cortex_a8_exec_opcode(target, ARMV4_5_STRB_IP(1, 0) , NULL); + /* execute instruction STRW r1, [r0], 1 (0xe4801004) */ + retval = cortex_a8_exec_opcode(target, ARMV4_5_STRW_IP(1, 0) , NULL); if (retval != ERROR_OK) - return retval; - --nbytes; + return retval; + + total_bytes -= nbytes_to_write; + start_byte = 0; } + return retval; } @@ -1494,13 +1528,19 @@ static int cortex_a8_read_apb_ab_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) { + + /* read memory through APB-AP */ + int retval = ERROR_INVALID_ARGUMENTS; struct armv7a_common *armv7a = target_to_armv7a(target); struct arm *armv4_5 = &armv7a->armv4_5_common; - /* read memory through APB-AP */ - int nbytes = count * size; - uint32_t data; + int total_bytes = count * size; + int start_byte, nbytes_to_read, i; struct reg *reg; + union _data { + uint8_t uc_a[4]; + uint32_t ui; + } data; if (target->state != TARGET_HALTED) { @@ -1513,26 +1553,34 @@ static int cortex_a8_read_apb_ab_memory(struct target *target, reg = arm_reg_current(armv4_5, 1); reg->dirty = 1; - retval = cortex_a8_dap_write_coreregister_u32(target, address, 0); + retval = cortex_a8_dap_write_coreregister_u32(target, address & 0xFFFFFFFC, 0); if (retval != ERROR_OK) return retval; - while (nbytes > 0) { + start_byte = address & 0x3; + while (total_bytes > 0) { - /* execute instruction LDRB r1, [r0], 1 (0xe4d01001) */ - retval = cortex_a8_exec_opcode(target, ARMV4_5_LDRB_IP(1, 0) , NULL); + /* execute instruction LDRW r1, [r0], 4 (0xe4901004) */ + retval = cortex_a8_exec_opcode(target, ARMV4_5_LDRW_IP(1, 0), NULL); if (retval != ERROR_OK) return retval; - retval = cortex_a8_dap_read_coreregister_u32(target, &data, 1); + retval = cortex_a8_dap_read_coreregister_u32(target, &data.ui, 1); if (retval != ERROR_OK) return retval; - *buffer++ = data; - --nbytes; - + nbytes_to_read = 4 - start_byte; + if (total_bytes < nbytes_to_read) + nbytes_to_read = total_bytes; + + for (i = 0; i < nbytes_to_read; ++i) + *buffer++ = data.uc_a[i + start_byte]; + + total_bytes -= nbytes_to_read; + start_byte = 0; } + return retval; } -- cgit v1.2.3