I was asked to post this conversation in the list, so it is quoted below (I
removed greetings and other parts that are not important to the subject),
and at the end is my answer, that has been send only to the mailing list
(thus moving the discussion here).
The problem has been partially solved, but it is open for further comments.

Drasko DRASKOVIC <(address removed)>:

> 2011/12/15 Kazimierz Król <(address removed)>:
> (...)
>
> > The problem is this: I am using MIPS32 24KEc cpu, that is built into the
> > VSC7428 chip (by Vitesse), and trying to load my program into the RAM for
> > fast debugging (flashing it every time is several times slower). I'm
> using
> > the load_image function of OOCD.
> >
> > Now on one of the devices (prototype) the loading and running works fine,
> > without any troubles, but on 3 other devices (1 other prototype, and 2
> > production) the load_image fails to go to fastdata mode and loads the
> > program in "non-bulk", which is around 100 bytes per second (compared to
> > over 100kB/s for fastdata).
> >
> > I have performed many tests and a lot of debugging, and found out that
> the
> > function mips32_pracc_fastdata_xfer (in mips32_pracc.c file) fails at
> this
> > block:
> >
> > /* next fetch to dmseg should be in FASTDATA_AREA, check */
> > address = 0;
> > mips_ejtag_set_instr(ejtag_
> info, EJTAG_INST_ADDRESS);
> > retval = mips_ejtag_drscan_32(ejtag_info, &address);
> > if (retval != ERROR_OK) {
> >   return retval;
> > }
> >
> > if (address != MIPS32_PRACC_FASTDATA_AREA) {
> >   return ERROR_FAIL;
> > }
> >
> > The address returned from drscan is 0xFF200200 (always the same), while
> the
> > code expects it to be 0xFF200000 (fastdata area). I tried to find out why
> > that would be, but didn't came to anything. I have even written some
> code to
> > enable PC sampling to check what the processor is doing before it comes
> > here. All I found is that everything before that check is identical in
> both
> > 'good' and 'bad' devices, and at that block it is, out of sudden, wrong.
> The
> > jump block that moves execution to the mini-program is loaded correctly
> (PC
> > increases, values seem good), but the mini-program never executes (I have
> > extended it with some instructions to write values to memory, that I
> check
> > manually later). It seems that the processor does not 'like' the JR
> > instruction and returns to the debug exception vector on it. Do you have
> any
> > idea what may be causing that?
> >
> > The address 0xFF200200 is the address that the CPU jumps to after going
> to
> > debug mode (debug vector). Working area is properly aligned (0x80030000,
> RAM
> > starts at 0x80000000)
>
>
As a first hint that cross my mind - is maybe cache getting in your
> way ? Can you please try putting the work area to the 0xA0030000 (or
> whatever that starts with 0xAxx..x rather than 0x8xx..x).
>
> As an other hint - is the RAM properly configured ? Are you sure that
> miniprogram was correctly loaded to RAM ?
>
> Based on the doc, I can see that you well understood how the things
> work, but just to clear this out : main miniprog is contained in the
> handler_code[] byte array. It is copied into you work_area using
> mips32_pracc_write_mem32(
> ejtag_info, source->address,
> ARRAY_SIZE(handler_code), handler_code); instruction. if your RAM is
> well configured, and your work_area is not in the cachable region
> (i.e. there is no cache between CPU and RAM that intercepts writes),
> everything should go OK.
>
> Now all you have to do is to execute small jmp_code, which is executed
> instruction by instruction via EJTAG. Once last instruction of
> jmp_code[], MIPS32_JR(15), is executed CPU will start reading
> handler_code[] from RAM. EJATG now does not send any instructions -
> they are just read from RAM, and when CPU hits MIPS32_LW(11,0,0)
> instruction of the handler_code[] it stalls on EJTAG access (bacause
> it understood that it should read some data that should be provided by
> EJTAG's FASTDATA_AREA).
>
> That's why when you read now "address" from dmseg, you should read
> FASTDATA_AREA. If you are not reading this that means that your
> handler_code[] was not properly executed and come to the
> MIPS32_LW(11,0,0) instruction. As I pointed out - there can be many
> reasons :
> 1) Code ended up in cache, but some coherency problems came out
> 2) RAM was not properly configured in the first place. jmp_code[] was
> executed (as it is executed via EJTAG and not from RAM), but after
> jump to RAM there is not valid handler_code[]
> 3) Doom and destiny united to prevent you finish your project
> 4) Many other stupid things
>
> I hope that this helps you.
>

-------------------------------------------------------
Kazimierz Król <(address removed)>:

I asked you the question with a really bad timing, because I'm on vacation
starting today, and I will be back on the project several days after the
new year, so only then I will be able to check your suggestions.

As a first hint that cross my mind - is maybe cache getting in your
> way ? Can you please try putting the work area to the 0xA0030000 (or
> whatever that starts with 0xAxx..x rather than 0x8xx..x).
>

This seems to be the only possible reason. I will try that.

As an other hint - is the RAM properly configured ? Are you sure that
> miniprogram was correctly loaded to RAM ?
>

Yes, I checked that using mdw commands after loading the image.
Also before, I was using 0x80040000 as the work area position, which is
also the place where the target code is downloaded. The behaviour was
exactly the same for both 'good' and 'bad' devices. Since all devices are
working properly when the code is loaded to that address by RedBoot, I
assume the memory is fine. But now, when I think of it, the work area at
0x80040000 should not work properly for OOCD, because the mini-program
would get overwritten when the first bytes were downloaded. I guess the
fact that it actually worked properly (for one device) means that some kind
of caching is in effect, or I am missing something obvious.


> Based on the doc, I can see that you well understood how the things
> work, but just to clear this out : main miniprog is contained in the
> handler_code[] byte array. It is copied into you work_area using
> mips32_pracc_write_mem32(ejtag_info, source->address,
> ARRAY_SIZE(handler_code), handler_code); instruction. if your RAM is
> well configured, and your work_area is not in the cachable region
> (i.e. there is no cache between CPU and RAM that intercepts writes),
> everything should go OK.


> Now all you have to do is to execute small jmp_code, which is executed
> instruction by instruction via EJTAG. Once last instruction of
> jmp_code[], MIPS32_JR(15), is executed CPU will start reading
> handler_code[] from RAM. EJATG now does not send any instructions -
> they are just read from RAM, and when CPU hits MIPS32_LW(11,0,0)
> instruction of the handler_code[] it stalls on EJTAG access (bacause
> it understood that it should read some data that should be provided by
> EJTAG's FASTDATA_AREA).
>

Yes, this is how I understood that. I have made many checks and tests to
verify the exact place of failure in that scheme.
1. The jmp_code[] is loaded perfectly, the assembly commands are correct
(at least identical in both 'good' and 'bad' cases), the address and PC
increases during loading. And after the NOP is loaded the address becomes
0xFF200000 for good device, and 0xFF200200 for bad device. Of course the
latter address would be correct if the handler_code executed, but not
stalled on fastdata access for some reason, so:
2. To verify whether it is executing or not, I have added three commands to
it after the initial register saving (don't remember the exact syntax now,
and I have no access to the code right now), that store a sequence of bytes
in the memory right after the handler. Then I loaded the target code to the
good device, and the sequence was there (again read with mdw), but after
loading to a bad device, it was not. So this means that the handler is not
executed at all.


> That's why when you read now "address" from dmseg, you should read
> FASTDATA_AREA. If you are not reading this that means that your
> handler_code[] was not properly executed and come to the
> MIPS32_LW(11,0,0) instruction. As I pointed out - there can be many
> reasons :
> 1) Code ended up in cache, but some coherency problems came out
> 2) RAM was not properly configured in the first place. jmp_code[] was
> executed (as it is executed via EJTAG and not from RAM), but after
> jump to RAM there is not valid handler_code[]
> 3) Doom and destiny united to prevent you finish your project
> 4) Many other stupid things
>
> I hope that this helps you.


The points 1, 3 and 4 are the most probable causes :)

-------------------------------------------------------
Kazimierz Król <(address removed)>:

Hi, I finally could get to the project again, and the problem was indeed in
the caching.

My colleauge was also searching for the solution when I was on vacation,
and he found it out independently. He added a call to sync_cache after
loading the mini-program. This solved the problem - everything now loads
fine on all devices.

The modified code is following (with context):

jmp_code[1] |= UPPER16(source->address);
jmp_code[2] |= LOWER16(source->address);

mips32_pracc_sync_cache(ejtag_
info, source->address, source->address + sizeof(handler_code));

for (i = 0; i < (int) ARRAY_SIZE(jmp_code); i++)
{

Also, he came up with a solution to buffer overflows in
ft2232_execute_scan() ("buffer size reached" debug messages), that slightly
increases loading speed (original: 27 seconds (5.46MB file), modified: 23
seconds).

The modification is by adding buffer limiting code in the fastdata_scan
loop:

uint32_t buf_siz = 0;

for (i = 0; i < count; i++)
    {
        if ((retval = mips_ejtag_fastdata_scan(ejtag_info, write_t, buf++))
!= ERROR_OK)
            return retval;

        if(buf_siz < 0x2000)
            buf_siz++;
        else {
            if ((retval = jtag_execute_queue()) != ERROR_OK)
            {
                LOG_ERROR("fastdata load failed");
                return retval;
            }
            buf_siz = 0;
        }
    }

  if (buf_siz > 0x0)
      if ((retval = jtag_execute_queue()) != ERROR_OK)
        {
            LOG_ERROR("fastdata load failed");
          return retval;
        }
  jtag_execute_queue_noclear();

    if ((retval = jtag_execute_queue()) != ERROR_OK)
    {

But I'm not sure if it should be done this way, since it's jtag-specific.

---------------------------------------------------------------
Drasko DRASKOVIC <(address removed)>:

> Hi, I finally could get to the project again, and the problem was indeed
in
> the caching.

Hi Kazimierz,
Nice to hear that I could help...

>
> My colleauge was also searching for the solution when I was on vacation,
and
> he found it out independently. He added a call to sync_cache after loading
> the mini-program. This solved the problem - everything now loads fine on
all
> devices.
>
> The modified code is following (with context):
>
> jmp_code[1] |= UPPER16(source->address);
> jmp_code[2] |= LOWER16(source->address);
>
> mips32_pracc_sync_cache(ejtag_info, source->address, source->address +
> sizeof(handler_code));
>
> for (i = 0; i < (int) ARRAY_SIZE(jmp_code); i++)
> {

Oh, yes - the good ol' sync_cache(). It's me who wrote it ;).

However - did he really understand what he was doing ? Syncing caches
on the uncachable area should tell you exactly this : your workarea is
wrong ! It is obviously put in the cachable region, which should be
avoided.

So, instead of workarounding your problems by bloating OpenOCDcode
with unnecessary trash and dumping your cache (so, slowing your
execution), try to do what I suggested in the first place - set the
correct, uncachable address fro your work area in the init script
(0xAxxxxxxx).

Why I am demanding you this ? Because I want to check if there is
indeed a bug in OpenOCD. As you see, sync_cache() is already called in
mips32_pracc_write_mem(), i.e. everytime you write something to the
mem during your debugging - ordinary write, not the one that uses
mips32_pracc_fastdata_xfer(). Why ? Because if you use
mips32_pracc_fastdata_xfer() you have to use your work area (this kind
of transfer demands temporary mem) and you __must__ guaranteee that it
is not in the cachable region.

I am starting to wonder now, maybe I should insert some asserts for
work area addresses...

Can you please do this experiment (change work area address and remove
mips32_pracc_sync_cache()) and tell me if this works.

>
> Also, he came up with a solution to buffer overflows in
> ft2232_execute_scan() ("buffer size reached" debug messages), that
slightly
> increases loading speed (original: 27 seconds (5.46MB file), modified: 23
> seconds).
>
> The modification is by adding buffer limiting code in the fastdata_scan
> loop:
>
> uint32_t buf_siz = 0;
>
> for (i = 0; i < count; i++)
>     {
>         if ((retval = mips_ejtag_fastdata_scan(
ejtag_info, write_t, buf++))
> != ERROR_OK)
>             return retval;
>
>         if(buf_siz < 0x2000)
>             buf_siz++;
>         else {
>             if ((retval = jtag_execute_queue()) != ERROR_OK)
>             {
>                 LOG_ERROR("fastdata load failed");
>                 return retval;
>             }
>             buf_siz = 0;
>         }
>     }
>
>   if (buf_siz > 0x0)
>       if ((retval = jtag_execute_queue()) != ERROR_OK)
>         {
>             LOG_ERROR("fastdata load failed");
>           return retval;
>         }
>   jtag_execute_queue_noclear();
>
>     if ((retval = jtag_execute_queue()) != ERROR_OK)
>     {
>
> But I'm not sure if it should be done this way, since it's jtag-specific.

Me neither... I never saw these kind of messages. This also might tell
that your JTAG freq is set up too high in your init sript (which might
lead to other problems).
This might be smart question to ask on the lists, there will be some
experts on the subject.

--------------------------------------------------------
Below is my answer:

However - did he really understand what he was doing ? Syncing caches
> on the uncachable area should tell you exactly this : your workarea is
> wrong ! It is obviously put in the cachable region, which should be
> avoided.
>
> So, instead of workarounding your problems by bloating OpenOCDcode
> with unnecessary trash and dumping your cache (so, slowing your
> execution), try to do what I suggested in the first place - set the
> correct, uncachable address fro your work area in the init script
> (0xAxxxxxxx).
>

>
Can you please do this experiment (change work area address and remove
> mips32_pracc_sync_cache()) and tell me if this works.
>

Address 0xA0040000 is working fine (without cache syncing), but I had to
decrease the JTAG speed to 5000kHz (was 6000), because the written program
was getting corrupted. So using the cached area was actually speeding up
the execution :).

Me neither... I never saw these kind of messages. This also might tell
> that your JTAG freq is set up too high in your init sript (which might
> lead to other problems).
>

I tried as low as 100kHz and the messages were still there (not sure, but I
think there were more of them).

Best Regards
Kazik
------------------------------------------------------------------------------
RSA(R) Conference 2012
Mar 27 - Feb 2
Save $400 by Jan. 27
Register now!
http://p.sf.net/sfu/rsa-sfdev2dev2
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to