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