GP2X Flushing The Processor Cache?


hmw

Still Fresh
Joined
Feb 13, 2006
Messages
42
Website
mobilegraphics.wordpress.com
So I am trying to pick up things where this attempt to port Vincent to the gp2x left off. Looks like that the library was effectively compiled in debug mode, because the GCC configuration in the dev kit defines __arm__, but neither ARM nor _ARM_. Anyway, settings this enables the JIT, which brings up the next question:

On StrongARM-derived implementations as well as the XScale it is necessary to explicitly flush the code cache (which is separate from the data cache) after generating a code fragment before it can be executed. Is the same necessary for the CPU in the GP2X? [Anyone having a link do a good document?] If so, what's the equivalent of
Code:
CacheSync(CACHE_SYNC_INSTRUCTIONS | CACHE_SYNC_WRITEBACK);
on this box?

Thanx,
hm
 
Last edited by a moderator:
There's a SWI call you can use to get Linux to flush (virtual) memory to ram, but I don't think there's anything for flushing the instruction cache. If you need to do that, you'll have to overwrite an entry in the syscall table with your own code, and then call that routine via a SWI to get access to supervisor mode so you can flush the cache yourself.

You can overwrite the sys call table by opening /dev/kmem, and you should find the relevent addresses you need in /proc/ksyms (or something similarly named).

Or, you can just write a module to do it.
 
Or you could make a routine that's essentially a bunch of jump operations to memory spaced out enough to exhaust the processor instruction cache... might be an easier solution, if maybe a little less efficient. Just need to know the cache row size and how many rows it has.
 
For reference, I am answering my own question here:
Code:
#define CLEAR_INSN_CACHE(BEG, END)        	\
{                	\
  register unsigned long _beg __asm ("a1") = (unsigned long) (BEG);	\
  register unsigned long _end __asm ("a2") = (unsigned long) (END);	\
  register unsigned long _flg __asm ("a3") = 0;      \
  register unsigned long _scno __asm ("r7") = 0xf0002;    \
  __asm __volatile ("swi 0x9f0002  @ sys_cacheflush"  	\
      : "=r" (_beg)          	\
      : "0" (_beg), "r" (_end), "r" (_flg), "r" (_scno));  \
}
- hm

PS: Did I really post this in "talk"??? This should go to dev.
 
Back
Top