HI all,
here are patches that correct endianess treatment for MIPS-M14Kc Big
Endian targets, as it has been discussed lately here :
http://www.mail-archive.com/[email protected]/msg15770.html,
here : 
http://www.mail-archive.com/[email protected]/msg15769.html
or here : 
http://www.mail-archive.com/[email protected]/msg15815.html
or on some other similar topics.

First patch corrects endianess, but this *might break* behaviour for
targets which do not have little endian TAP. I do am not sure that
targets like this exists, because all miniprograms (ROM monitors) are
written in LE and anyway at the current implementation when you go to
bulk access you will get bytes switched. I added this logic to simple
read and write.

Second patch corrects meaningless while (1) loop in
wait_for_pracc_rw() and also adds some checking that PrAcc is "1"
before FASTDATA access. Since all of this has not been done before, I
am very suprised that it works at all in the current state. EJTAG
specification is explicit on this (chapter 6.5.6 Fastdata Register
(TAP Instruction FASTDATA)) :

As noted above, two conditions must be true for the Fastdata access to
succeed. These are:
• PrAcc must be 1, i.e., there must be a pending processor access.
• The Fastdata operation must use a valid Fastdata area address in the
dmseg segment (0xF..F20.0000 to
0xF..F20.000F).

I guess we have been falling to the case that PrAcc was "1" by chance,
maybe because of obscure jtag_add_clocks(5) which I removed.

One thing I am not quite sure about, but is purely empiric, is
re-sending FASTDATA instruction to TAP before each FASTDATA acces.
Since this is done in a loop, this can potentially slow down the
communication. But not putting this instruction makes bulk write fail
systematically with error : "miniprogram did not return to start".
Again, this is M14Kc, and it seems to be working on M4k. Anyway, if
both versions work on 4K that I think that we can use the changes I
commited.

It would be a great thing if somebody who has M4K board (Andy, Spencer
?) could test these changed before they are commited, so that we can
assure that there is no regression.

Best regards,
Drasko
From 9ba1c3953250cb892a0ca29cd1107786ab8d5fbf Mon Sep 17 00:00:00 2001
From: Drasko DRASKOVIC <[email protected]>
Date: Thu, 31 Mar 2011 17:18:07 +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 |   58 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c
index 3a79273..02f23d7 100644
--- a/src/target/mips_m4k.c
+++ b/src/target/mips_m4k.c
@@ -859,6 +859,28 @@ static int mips_m4k_read_memory(struct target *target, uint32_t address,
 	if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
 		return ERROR_TARGET_UNALIGNED_ACCESS;
 
+	/* 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;
+			}
+		}
+	}
+
 	/* if noDMA off, use DMAACC mode for memory read */
 	int retval;
 	if (ejtag_info->impcode & EJTAG_IMP_NODMA)
@@ -893,6 +915,28 @@ 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;
 
+	/* 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 = be_to_h_u32(&buffer[i]);
+					h_u32_to_le(&buffer[i], t32);
+					break;
+				case 2:
+					t16 = be_to_h_u16(&buffer[i]);
+					h_u16_to_le(&buffer[i], t16);
+					break;
+			}
+		}
+	}
+
 	/* if noDMA off, use DMAACC mode for memory write */
 	if (ejtag_info->impcode & EJTAG_IMP_NODMA)
 		return mips32_pracc_write_mem(ejtag_info, address, size, count, (void *)buffer);
@@ -1019,6 +1063,20 @@ static int mips_m4k_bulk_write_memory(struct target *target, uint32_t address,
 	{
 		/* FASTDATA access failed, try normal memory write */
 		LOG_DEBUG("Fastdata access Failed, falling back to non-bulk write");
+
+		/* In unlikely case of error, re-shuffle back bytes to keep endianess.
+		 * It will be treated again by mips_m4k_write_memory() which expect that bytes were not shuffled before */
+		if (target->endianness == TARGET_BIG_ENDIAN)
+		{
+			uint32_t i, t32;
+
+			for(i = 0; i < (count * 4); i += 4)
+			{
+				t32 = le_to_h_u32((uint8_t *) &buffer[i]);
+				h_u32_to_be(&buffer[i], t32);
+			}
+		}
+
 		retval = mips_m4k_write_memory(target, address, 4, count, buffer);
 	}
 
-- 
1.5.6.5

From 0f81ffd88809ae5470aaef14a6b59313a07228ac Mon Sep 17 00:00:00 2001
From: Drasko DRASKOVIC <[email protected]>
Date: Thu, 31 Mar 2011 17:21:33 +0200
Subject: [PATCH] Corrected waiting on PrAcc in wait_for_pracc_rw().
 Added necessary check that PrAcc is "1" before FASTDATA access.
 Added TAP instruction re-sending before every FASTDATAaccess (seems to
 be necessary for 14Kc).

---
 src/target/mips32_pracc.c |   31 +++++++++++++++++++++++++++----
 1 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c
index 9a9b427..ec04d0b 100644
--- a/src/target/mips32_pracc.c
+++ b/src/target/mips32_pracc.c
@@ -111,16 +111,24 @@ 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;
 
 	while (1)
 	{
+		/* wait for the PrAcc to become "1" */
 		mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
 		ejtag_ctrl = ejtag_info->ejtag_ctrl;
 		mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
+
 		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 +183,7 @@ 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);
+	//jtag_add_clocks(5);
 	jtag_execute_queue();
 
 	return ERROR_OK;
@@ -195,7 +203,7 @@ static int mips32_pracc_exec_write(struct mips32_pracc_context *ctx, uint32_t ad
 	mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL);
 	mips_ejtag_drscan_32(ctx->ejtag_info, &ejtag_ctrl);
 
-	jtag_add_clocks(5);
+	//jtag_add_clocks(5);
 	jtag_execute_queue();
 
 	if ((address >= MIPS32_PRACC_PARAM_IN)
@@ -920,6 +928,7 @@ int mips32_pracc_read_regs(struct mips_ejtag *ejtag_info, uint32_t *regs)
 	return retval;
 }
 
+
 /* fastdata upload/download requires an initialized working area
  * to load the download code; it should not be called otherwise
  * fetch order from the fastdata area
@@ -1022,11 +1031,19 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are
 	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);
 	mips_ejtag_fastdata_scan(ejtag_info, 1, &val);
 
+	/* wait PrAcc pending bit for FASTDATA write */
+	if ((retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl)) != ERROR_OK)
+		return retval;
+
 	/* Send the load end address */
 	val = addr + (count - 1) * 4;
 	mips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA);
@@ -1034,7 +1051,12 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are
 
 	for (i = 0; i < count; i++)
 	{
+		/* wait PrAcc pending bit for FASTDATA write */
+		if ((retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl)) != ERROR_OK)
+			return retval;
+
 		/* Send the data out using fastdata (clears the access pending bit) */
+		mips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA);
 		if ((retval = mips_ejtag_fastdata_scan(ejtag_info, write_t, buf++)) != ERROR_OK)
 			return retval;
 	}
@@ -1057,3 +1079,4 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are
 
 	return retval;
 }
+
-- 
1.5.6.5

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

Reply via email to