Hi all,
Currently for MIPS32 target we do mem writes using
mips32_pracc_write_mem() function. And this works fine, but only
untill kseg0 memory segment is uncached (i.e. K0 field of the Config
Register (CP0 Register 16, Select 0) are set to 0x2, which is a reset
value). However, this memory region is cachable, and it is it's
primary use (in difference to kseg1, which is always uncached).

The moment I tried to turn on cache, using "Cacheable, noncoherent,
write-back, write allocate" set-up (0x3 in the K0 field), I saw that
all data writes are left in cache. Linux turns on these caches by
default - and this is quite normal, and a proper way to do. From this
point on OpenOCD debugging via GDB is unusable : writing breakpoint
instruction will happily live in your D$ and will never be seen by
CPU, who will keep executing instructions from I$ (not coherent from
this moment on).

As done for all architectures before, proper way to handle write on a
cached reginos is folowing :
1) do your write
2) clean and drain D$, so that data and instructions you wrote will
end up in RAM (you do not necessarily have to invalidate it - it will
be coherent from this point on)
3) invalidate I$, so that CPU will pick up newly written instructions
from RAM, and not continue executing it's I$ (which is btw. no longer
coherent)

Now, in case of EJTAG communication implementation in mips32_pracc.c
this is not a simple thing to implement. I am currently adding missing
opcodes and trying to craft a miniprogram based on bytecode, similar
to existing stuff. It is quite a headache to debug, but I previously
spent a lot of time on demistfying this implementation and wrote one
draft doc to this list (more complete doc is on the way, and will be
contributed as a separate patch).

In the MIPS official doc MD00086  (MIPS32™ Architecture For
Programmers Volume II: The MIPS32™ Instruction Set), we can find
interesting procedure to synchronize caches using synci (Synchronize
Caches to Make Instruction Writes Effective) instruction. I am
referencing here Programming Notes given in the chapter describing
this instruction (page 287). Based on this, I re-implemented this
procedure to the detail in bytecode minirpogram and I have first
working draft.

Here is what I tested :
1) I put a soft breakpoint on start_kernel() just after image
download. It is after-reset state, and kseg0 is uncached (by default)
2) I do "continue" in GDB and program hits this breakpoint. It should,
it is well in the memory (and copied to I$)
3) On further resume, OpenOCD will replace this breakpoint with
original instruction that lived on this addr. That will, however, be
put in D$ and never reflected in I$ upon resume
4) CPU keeps hitting soft breakpoint, because it is what it really
sees in I$ - original instruction has never been really brought back !

I think that synci is a good candidate for this fix, rather than
explicitly using "cache" instructions. I give a reference to similar
discussion : http://comments.gmane.org/gmane.linux.ports.mips.general/4267.
Some nice information can also be found in "See Mips Run" book
(http://www.scribd.com/doc/39654922/161/Synci-Cache-Management-for-Instruction-Writers).
Normally, it should do exactly what is needed - clean D$ and
invalidate I$ at the same time. As I said, I did some fixes and
OpenOCD started to work correctly even on cached regions, so I can
proceeded debugging Linux kernel with it).

I will post the patch soon, just after I clean the code and test it a
little bit more.

In the meantime, I would like to hear some observations like : Did
anyone else experienced this problem ? Would "synci" be better than
"cache" instruction ? What happens with FASTDATA - should we clean
after these bulk loads too ?

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

Reply via email to