Hi all,
here is a set of patched (separeted by the logical changes they
introduce) that :
1) Correct endianess for big endian targets
2) Correct while(1) loop waiting for PrAcc to be "1"
3) Change FASTDATA operation, forcing the shift out to prevent "ft2232
buffer size reached" errors
4) Add optimizations similar to ones introduced by Øyvind recently

With these patches I was able to obtain decent performances and
correct functioning for my big endian MIPS-M14Kc based target.

I see no more problems with libftdi of type :
Error: couldn't read enough bytes from FT2232 device (0 < 5)
Current stable version of libftdi can be used, no need for closed D2XX
files nor for development branches of libusb-1.0

I also have no more problems with GDB synchronisation - ELF can be
correctly downloaded and executed from GDB.

Best regards,
Drasko
From ea3e13a81d0ca53f69f993448925f4ce85c81afb Mon Sep 17 00:00:00 2001
From: Drasko DRASKOVIC <[email protected]>
Date: Mon, 4 Apr 2011 13:06:18 +0200
Subject: [PATCH] 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).

---
 src/target/mips_m4k.c |   78 +++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 72 insertions(+), 6 deletions(-)

diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c
index 7530cbd..74d0d50 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);
-- 
1.5.6.5

From 760cf073d56d47a4915ff09eb365c98a8f3045a1 Mon Sep 17 00:00:00 2001
From: Drasko DRASKOVIC <[email protected]>
Date: Mon, 4 Apr 2011 15:24:59 +0200
Subject: [PATCH] Corrected waiting on PrAcc in wait_for_pracc_rw().
 Added necessary check that PrAcc is "1" before FASTDATA access.

---
 src/target/mips32_pracc.c |   56 +++++++++++++++++++++++++++++++++-----------
 1 files changed, 42 insertions(+), 14 deletions(-)

diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c
index 816f352..ef132fe 100644
--- a/src/target/mips32_pracc.c
+++ b/src/target/mips32_pracc.c
@@ -74,6 +74,8 @@ Nico Coesel
 #include "config.h"
 #endif
 
+#include <helper/time_support.h>
+
 #include "mips32.h"
 #include "mips32_pracc.h"
 
@@ -111,16 +113,34 @@ static int mips32_pracc_write_u32(struct mips_ejtag *ejtag_info,
 static int wait_for_pracc_rw(struct mips_ejtag *ejtag_info, uint32_t *ctrl)
 {
 	uint32_t ejtag_ctrl;
+	long long then = timeval_ms();
+	int timeout;
+
+	/* wait for the PrAcc to become "1" */
+	mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
+	ejtag_ctrl = ejtag_info->ejtag_ctrl;
+
+	int retval;
+	if ((retval = jtag_execute_queue()) != ERROR_OK)
+	{
+		LOG_ERROR("fastdata load failed");
+		return retval;
+	}
 
 	while (1)
 	{
-		mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
-		ejtag_ctrl = ejtag_info->ejtag_ctrl;
-		mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
+		retval = mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
+		if (retval != ERROR_OK)
+			return retval;
+
 		if (ejtag_ctrl & EJTAG_CTRL_PRACC)
 			break;
-		LOG_DEBUG("DEBUGMODULE: No memory access in progress!");
-		return ERROR_JTAG_DEVICE_ERROR;
+
+		if ( (timeout = timeval_ms()-then) > 1000 )
+		{
+			LOG_DEBUG("DEBUGMODULE: No memory access in progress!");
+			return ERROR_JTAG_DEVICE_ERROR;
+		}
 	}
 
 	*ctrl = ejtag_ctrl;
@@ -175,7 +195,6 @@ static int mips32_pracc_exec_read(struct mips32_pracc_context *ctx, uint32_t add
 	mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL);
 	mips_ejtag_drscan_32(ctx->ejtag_info, &ejtag_ctrl);
 
-	jtag_add_clocks(5);
 	return jtag_execute_queue();
 }
 
@@ -184,17 +203,18 @@ static int mips32_pracc_exec_write(struct mips32_pracc_context *ctx, uint32_t ad
 	uint32_t ejtag_ctrl,data;
 	int offset;
 	struct mips_ejtag *ejtag_info = ctx->ejtag_info;
+	int retval;
 
 	mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA);
-	mips_ejtag_drscan_32(ctx->ejtag_info, &data);
+	retval = mips_ejtag_drscan_32(ctx->ejtag_info, &data);
+	if (retval != ERROR_OK)
+		return retval;
 
 	/* Clear access pending bit */
 	ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;
 	mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL);
 	mips_ejtag_drscan_32(ctx->ejtag_info, &ejtag_ctrl);
 
-	jtag_add_clocks(5);
-	int retval;
 	retval = jtag_execute_queue();
 	if (retval != ERROR_OK)
 		return retval;
@@ -250,7 +270,9 @@ int mips32_pracc_exec(struct mips_ejtag *ejtag_info, int code_len, const uint32_
 
 		address = data = 0;
 		mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
-		mips_ejtag_drscan_32(ejtag_info, &address);
+		retval = mips_ejtag_drscan_32(ejtag_info, &address);
+		if (retval != ERROR_OK)
+			return retval;
 
 		/* Check for read or write */
 		if (ejtag_ctrl & EJTAG_CTRL_PRNW)
@@ -1018,11 +1040,17 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are
 	/* next fetch to dmseg should be in FASTDATA_AREA, check */
 	address = 0;
 	mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
-	mips_ejtag_drscan_32(ejtag_info, &address);
+	retval = mips_ejtag_drscan_32(ejtag_info, &address);
+	if (retval != ERROR_OK)
+		return retval;
 
 	if (address != MIPS32_PRACC_FASTDATA_AREA)
 		return ERROR_FAIL;
 
+	/* wait PrAcc pending bit for FASTDATA write */
+	if ((retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl)) != ERROR_OK)
+		return retval;
+
 	/* Send the load start address */
 	val = addr;
 	mips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA);
@@ -1030,12 +1058,10 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are
 
 	/* Send the load end address */
 	val = addr + (count - 1) * 4;
-	mips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA);
 	mips_ejtag_fastdata_scan(ejtag_info, 1, &val);
 
 	for (i = 0; i < count; i++)
 	{
-		/* Send the data out using fastdata (clears the access pending bit) */
 		if ((retval = mips_ejtag_fastdata_scan(ejtag_info, write_t, buf++)) != ERROR_OK)
 			return retval;
 	}
@@ -1051,7 +1077,9 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are
 
 	address = 0;
 	mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
-	mips_ejtag_drscan_32(ejtag_info, &address);
+	retval = mips_ejtag_drscan_32(ejtag_info, &address);
+	if (retval != ERROR_OK)
+		return retval;
 
 	if (address != MIPS32_PRACC_TEXT)
 		LOG_ERROR("mini program did not return to start");
-- 
1.5.6.5

From 9a165bb144f10b40c420bb1590b6c688cd477426 Mon Sep 17 00:00:00 2001
From: Drasko DRASKOVIC <[email protected]>
Date: Mon, 4 Apr 2011 15:29:15 +0200
Subject: [PATCH] Added jtag_execute_queue() to FASTDATA operations in order to prevent
 "ft2232 buffer size reached" errors.

---
 src/target/mips_ejtag.c |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/src/target/mips_ejtag.c b/src/target/mips_ejtag.c
index 087be07..aa58439 100644
--- a/src/target/mips_ejtag.c
+++ b/src/target/mips_ejtag.c
@@ -343,7 +343,13 @@ int mips_ejtag_fastdata_scan(struct mips_ejtag *ejtag_info, int write_t, uint32_
 	}
 
 	jtag_add_dr_scan(tap, 2, fields, TAP_IDLE);
-	keep_alive();
+
+	int retval;
+	if ((retval = jtag_execute_queue()) != ERROR_OK)
+	{
+		LOG_ERROR("register read failed");
+		return retval;
+	}
 
 	return ERROR_OK;
 }
-- 
1.5.6.5

From 71799828ce32154d1b0a935f74bba4b53a6c95ef Mon Sep 17 00:00:00 2001
From: Drasko DRASKOVIC <[email protected]>
Date: Mon, 4 Apr 2011 15:33:04 +0200
Subject: [PATCH] Added mips_ejtag_drscan_32_out() for optimization.

---
 src/target/mips32_pracc.c |   10 +++++-----
 src/target/mips_ejtag.c   |   15 +++++++++++++++
 src/target/mips_ejtag.h   |    1 +
 src/target/mips_m4k.c     |    2 +-
 4 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c
index ef132fe..178f68e 100644
--- a/src/target/mips32_pracc.c
+++ b/src/target/mips32_pracc.c
@@ -188,12 +188,12 @@ static int mips32_pracc_exec_read(struct mips32_pracc_context *ctx, uint32_t add
 
 	/* Send the data out */
 	mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA);
-	mips_ejtag_drscan_32(ctx->ejtag_info, &data);
+	mips_ejtag_drscan_32_out(ctx->ejtag_info, data);
 
 	/* Clear the access pending bit (let the processor eat!) */
 	ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;
 	mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL);
-	mips_ejtag_drscan_32(ctx->ejtag_info, &ejtag_ctrl);
+	mips_ejtag_drscan_32_out(ctx->ejtag_info, ejtag_ctrl);
 
 	return jtag_execute_queue();
 }
@@ -213,7 +213,7 @@ static int mips32_pracc_exec_write(struct mips32_pracc_context *ctx, uint32_t ad
 	/* Clear access pending bit */
 	ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;
 	mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL);
-	mips_ejtag_drscan_32(ctx->ejtag_info, &ejtag_ctrl);
+	mips_ejtag_drscan_32_out(ctx->ejtag_info, ejtag_ctrl);
 
 	retval = jtag_execute_queue();
 	if (retval != ERROR_OK)
@@ -1026,12 +1026,12 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are
 			return retval;
 
 		mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA);
-		mips_ejtag_drscan_32(ejtag_info, &jmp_code[i]);
+		mips_ejtag_drscan_32_out(ejtag_info, jmp_code[i]);
 
 		/* Clear the access pending bit (let the processor eat!) */
 		ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;
 		mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
-		mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
+		mips_ejtag_drscan_32_out(ejtag_info, ejtag_ctrl);
 	}
 
 	if ((retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl)) != ERROR_OK)
diff --git a/src/target/mips_ejtag.c b/src/target/mips_ejtag.c
index aa58439..58227c7 100644
--- a/src/target/mips_ejtag.c
+++ b/src/target/mips_ejtag.c
@@ -121,6 +121,21 @@ int mips_ejtag_drscan_32(struct mips_ejtag *ejtag_info, uint32_t *data)
 	return ERROR_OK;
 }
 
+void mips_ejtag_drscan_32_out(struct mips_ejtag *ejtag_info, uint32_t data)
+{
+	struct jtag_tap *tap;
+	tap  = ejtag_info->tap;
+	assert(tap != NULL);
+
+	struct scan_field field;
+
+	field.num_bits = 32;
+	field.out_value = (uint8_t *)&data;
+	field.in_value = NULL;
+
+	jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
+}
+
 int mips_ejtag_drscan_8(struct mips_ejtag *ejtag_info, uint32_t *data)
 {
 	struct jtag_tap *tap;
diff --git a/src/target/mips_ejtag.h b/src/target/mips_ejtag.h
index aa890d2..a6ed95a 100644
--- a/src/target/mips_ejtag.h
+++ b/src/target/mips_ejtag.h
@@ -136,6 +136,7 @@ void mips_ejtag_set_instr(struct mips_ejtag *ejtag_info,
 int mips_ejtag_enter_debug(struct mips_ejtag *ejtag_info);
 int mips_ejtag_exit_debug(struct mips_ejtag *ejtag_info);
 int mips_ejtag_get_idcode(struct mips_ejtag *ejtag_info, uint32_t *idcode);
+void mips_ejtag_drscan_32_out(struct mips_ejtag *ejtag_info, uint32_t data);
 int mips_ejtag_drscan_32(struct mips_ejtag *ejtag_info, uint32_t *data);
 void mips_ejtag_drscan_8_out(struct mips_ejtag *ejtag_info, uint8_t data);
 int mips_ejtag_drscan_8(struct mips_ejtag *ejtag_info, uint32_t *data);
diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c
index 74d0d50..1166b87 100644
--- a/src/target/mips_m4k.c
+++ b/src/target/mips_m4k.c
@@ -274,7 +274,7 @@ static int mips_m4k_assert_reset(struct target *target)
 			uint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl | EJTAG_CTRL_PRRST | EJTAG_CTRL_PERRST;
 			LOG_DEBUG("Using EJTAG reset (PRRST) to reset processor...");
 			mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
-			mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
+			mips_ejtag_drscan_32_out(ejtag_info, ejtag_ctrl);
 		}
 	}
 
-- 
1.5.6.5

_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to