Hi all,
I did some more research on this subject. I had to dig deeper into
EJTAG specification. I came basck to the story about busy-waiting
PrAcc to be "1" before initiating FASTDATA access, like I did it
before, in the first implementation - which was a performance killer.

Here are some of the most important points :
6.5.6 Fastdata Register (TAP Instruction FASTDATA)
Compliance Level: Required with EJTAG TAP feature for EJTAG version
02.60 and higher.
The width of the Fastdata register is 1 bit.

--> During a Fastdata access, the Fastdata register is *written and
read*, i.e., a bit is
shifted in and a bit is shifted out. (See Section 6.4.3 on page 91 for
how the Data + Fastdata registers are selected by the
FASTDATA instruction.) During a Fastdata access, the Fastdata register
value shifted in specifies whether the Fastdata
access should be completed or not. The value shifted out is a flag
that indicates whether the Fastdata access was
successful or not (if completion was requested).

Shifting in a zero value requests completion of the
Fastdata access. The PrAcc bit in the EJTAG Control
register is overwritten with zero when the access
succeeds.
--> (The access succeeds if *PrAcc is one* and <-- important : PrAcc
must be "1" => we must wait !
the operation address is in the legal dmseg segment
Fastdata area.) When successful, a one is shifted out. <-- important :
we must check the shift out bit !
Shifting out a zero indicates a Fastdata access failure.

During Fastdata uploads and downloads, the processor will stall on
accesses to the Fastdata area. The PrAcc (processor
access pending bit) will be 1 indicating the probe is required to
complete the access. Both upload and download accesses
are attempted by shifting in a zero SPrAcc value (to request access
completion) and shifting out SPrAcc to see if the
attempt will be successful (i.e., there was an access pending and a
legal Fastdata area address was used). Downloads will
also shift in the data to be used to satisfy the load from the dmseg
segment Fastdata area, while uploads will shift out the
data being stored to the dmseg segment Fastdata area.
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).


So, based on this I have several explanations. FASTDATA will fail if
we go into the transfer when PrAcc is "0". So far we are never
checking neither if PrAcc was "1" nor if FASTDATA failed.

CASE 1 - Why it works for Andy and Spen :
-------------------------------------------------------------
By accident (maybe you are using slower probes ?), between FASTDATA
accesses in the loop :
for (i = 0; i < count; i++)
{
        if ((retval = mips_ejtag_fastdata_scan(ejtag_info, write_t,
buf++)) != ERROR_OK)
                return retval;
}
there is enough time between commands shifted out towards TAP for
PrAcc to become "1". FASTDATA acces thus does not fail. You are not
checking it, but anyway it suceeds.

For bigger images, maybe at some point FASTDATA is tryed without PrAcc
== "1", so it fails - but it is never checked.

I am using probably faster Amontec probe, that shifts out FATSDATA
initiation in this loop before PrAcc became "1". So it fails even for
the small images.

I proved that by inserting :
        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;
        }
then it starts working for me also, although I did not change
mips_ejtag_fastdata_scan() by adding jtag_execute_queue();


CASE 2 - Why is it working for me with jtag_execute_queue() and not
added wait_for_pracc_rw() :
------------------------------------------------------------------------------------------------------------------------------------------
Probably because, as Laurent noted before, this inserts enough delay
between two succeeding  mips_ejtag_fastdata_scan() called in the loop,
so that PrAcc actually becomes "1"



Based on this I think correct handling would be :
1) To assure that PrAcc is "1" before each call to mips_ejtag_fastdata_scan()
2) To check SPrAcc shifted out bit. But for this jtag_execute_queue()
has to be executed within mips_ejtag_fastdata_scan().

I am adding a patch that correct these issues.

Off course, it has catastrofic performance issues :

> load_image /home/ddraskovic/test/fred.elf
476 bytes written at address 0x80000000
361064 bytes written at address 0x80080000
downloaded 361540 bytes in 363.814789s (0.970 KiB/s)


It would be great if Andy can set-up some tests on big images again
tonight with code patched with this patch. If the image is loaded
correctly that would say that we are getting closer !

BR,
Drasko
From 3f4882c153ca15dc7689639eca52928cc4583e4b Mon Sep 17 00:00:00 2001
From: Drasko DRASKOVIC <drasko.drasko...@gmail.com>
Date: Tue, 5 Apr 2011 18:05:19 +0200
Subject: [PATCH] mips: FASTDATA needs PrAcc to be "1"

Added waiting for PrAcc to be "1" before initiating FASTDATA access.
Added error checking by verifying that shifted out SPrAcc is "1".
---
 src/target/mips32_pracc.c |   17 +++++++++++------
 src/target/mips_ejtag.c   |   21 ++++++++++++++++++---
 2 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c
index 178f68e..85ef48e 100644
--- a/src/target/mips32_pracc.c
+++ b/src/target/mips32_pracc.c
@@ -1056,20 +1056,25 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are
 	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);
 	mips_ejtag_fastdata_scan(ejtag_info, 1, &val);
 
 	for (i = 0; i < count; i++)
 	{
-		if ((retval = mips_ejtag_fastdata_scan(ejtag_info, write_t, buf++)) != ERROR_OK)
+		/* wait PrAcc pending bit for FASTDATA write */
+		if ((retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl)) != ERROR_OK)
 			return retval;
-	}
 
-	if ((retval = jtag_execute_queue()) != ERROR_OK)
-	{
-		LOG_ERROR("fastdata load failed");
-		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;
 	}
 
 	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 6229055..869b874 100644
--- a/src/target/mips_ejtag.c
+++ b/src/target/mips_ejtag.c
@@ -335,13 +335,14 @@ int mips_ejtag_fastdata_scan(struct mips_ejtag *ejtag_info, int write_t, uint32_
 	assert(tap != NULL);
 
 	struct scan_field fields[2];
-	uint8_t spracc = 0;
+	uint8_t spracc_in = 0;
+	uint8_t spracc_out = 0;
 	uint8_t t[4] = {0, 0, 0, 0};
 
 	/* fastdata 1-bit register */
 	fields[0].num_bits = 1;
-	fields[0].out_value = &spracc;
-	fields[0].in_value = NULL;
+	fields[0].out_value = &spracc_out;
+	fields[0].in_value = &spracc_in;
 
 	/* processor access data register 32 bit */
 	fields[1].num_bits = 32;
@@ -358,6 +359,20 @@ int mips_ejtag_fastdata_scan(struct mips_ejtag *ejtag_info, int write_t, uint32_
 	}
 
 	jtag_add_dr_scan(tap, 2, fields, TAP_IDLE);
+
+	int retval;
+	if ((retval = jtag_execute_queue()) != ERROR_OK)
+	{
+		LOG_ERROR("fastdata load failed");
+		return retval;
+	}
+
+	if (spracc_in != 1)
+	{
+		LOG_ERROR("fastdata load failed");
+		return ERROR_FAIL;
+	}
+
 	keep_alive();
 
 	return ERROR_OK;
-- 
1.5.6.5

_______________________________________________
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to