summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDrasko DRASKOVIC <drasko.draskovic@gmail.com>2011-04-04 13:06:18 +0200
committerØyvind Harboe <oyvind.harboe@zylin.com>2011-04-05 08:21:17 +0200
commitb1256894598296b54a1827e7ac797ad1c60a0b18 (patch)
tree4aeea961e13cd73a672283d997f3acb2187aa0c9
parent3fea99097efc1d1a38e73ba646261c2a7a79bd12 (diff)
downloadopenocd_libswd-b1256894598296b54a1827e7ac797ad1c60a0b18.tar.gz
openocd_libswd-b1256894598296b54a1827e7ac797ad1c60a0b18.tar.bz2
openocd_libswd-b1256894598296b54a1827e7ac797ad1c60a0b18.tar.xz
openocd_libswd-b1256894598296b54a1827e7ac797ad1c60a0b18.zip
Added correct endianess treatment for big endian targets. Now it is possible to use mips_m4k_write_memory() and mips_m4k_read_memory() to correctly set-up SDRAM, as well as bulk data write, which already handled endianess well. Also added correct endianess manipulation in case of fallback from erroneus bulk write to simple write (to avoid byte swapping two times).
-rw-r--r--src/target/mips_m4k.c78
1 files changed, 72 insertions, 6 deletions
diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c
index 7530cbd0..74d0d503 100644
--- a/src/target/mips_m4k.c
+++ b/src/target/mips_m4k.c
@@ -120,7 +120,9 @@ static int mips_m4k_poll(struct target *target)
/* read ejtag control reg */
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
- mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
+ retval = mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
+ if (retval != ERROR_OK)
+ return retval;
/* clear this bit before handling polling
* as after reset registers will read zero */
@@ -131,7 +133,9 @@ static int mips_m4k_poll(struct target *target)
ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_ROCC;
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
- mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
+ retval = mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
+ if (retval != ERROR_OK)
+ return retval;
LOG_DEBUG("Reset Detected");
}
@@ -864,6 +868,28 @@ static int mips_m4k_read_memory(struct target *target, uint32_t address,
if (ERROR_OK != retval)
return retval;
+ /* TAP data register is loaded LSB first (little endian) */
+ if (target->endianness == TARGET_BIG_ENDIAN)
+ {
+ uint32_t i, t32;
+ uint16_t t16;
+
+ for(i = 0; i < (count*size); i += size)
+ {
+ switch(size)
+ {
+ case 4:
+ t32 = le_to_h_u32(&buffer[i]);
+ h_u32_to_be(&buffer[i], t32);
+ break;
+ case 2:
+ t16 = le_to_h_u16(&buffer[i]);
+ h_u16_to_be(&buffer[i], t16);
+ break;
+ }
+ }
+ }
+
return ERROR_OK;
}
@@ -889,11 +915,50 @@ static int mips_m4k_write_memory(struct target *target, uint32_t address,
if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
return ERROR_TARGET_UNALIGNED_ACCESS;
+ uint8_t * t = NULL;
+
+ /* TAP data register is loaded LSB first (little endian) */
+ if (target->endianness == TARGET_BIG_ENDIAN)
+ {
+ t = malloc(count * sizeof(uint32_t));
+ if (t == NULL)
+ {
+ LOG_ERROR("Out of memory");
+ return ERROR_FAIL;
+ }
+
+ uint32_t i, t32, t16;
+ for(i = 0; i < (count*size); i += size)
+ {
+ switch(size)
+ {
+ case 4:
+ t32 = be_to_h_u32((uint8_t *) &buffer[i]);
+ h_u32_to_le(&t[i], t32);
+ break;
+ case 2:
+ t16 = be_to_h_u16((uint8_t *) &buffer[i]);
+ h_u16_to_le(&t[i], t16);
+ break;
+ }
+ }
+
+ buffer = t;
+ }
+
/* if noDMA off, use DMAACC mode for memory write */
+ int retval;
if (ejtag_info->impcode & EJTAG_IMP_NODMA)
- return mips32_pracc_write_mem(ejtag_info, address, size, count, (void *)buffer);
+ retval = mips32_pracc_write_mem(ejtag_info, address, size, count, (void *)buffer);
else
- return mips32_dmaacc_write_mem(ejtag_info, address, size, count, (void *)buffer);
+ retval = mips32_dmaacc_write_mem(ejtag_info, address, size, count, (void *)buffer);
+ if (ERROR_OK != retval)
+ return retval;
+
+ if (t != NULL)
+ free(t);
+
+ return ERROR_OK;
}
static int mips_m4k_init_target(struct command_context *cmd_ctx,
@@ -1001,6 +1066,7 @@ static int mips_m4k_bulk_write_memory(struct target *target, uint32_t address,
}
uint8_t * t = NULL;
+ const uint8_t *ec_buffer = buffer; /* endian-corrected buffer */
/* TAP data register is loaded LSB first (little endian) */
if (target->endianness == TARGET_BIG_ENDIAN)
@@ -1019,11 +1085,11 @@ static int mips_m4k_bulk_write_memory(struct target *target, uint32_t address,
h_u32_to_le(&t[i], t32);
}
- buffer = t;
+ ec_buffer = t;
}
retval = mips32_pracc_fastdata_xfer(ejtag_info, mips32->fast_data_area, write_t, address,
- count, (uint32_t*) (void *)buffer);
+ count, (uint32_t*) (void *)ec_buffer);
if (t != NULL)
free(t);