Forum Discussion
Altera_Forum
Honored Contributor
14 years agoI think I've found the solution. In arch/nios2/mm/memory.c, change the icache_push function to flush the data cache before invalidating the instruction cache. This can be done by inserting the line: cache_invalidate_data(vaddr, len); so the whole function is as follows:
void icache_push(unsigned long vaddr, int len)
{
cache_invalidate_data(vaddr, len);
cache_invalidate_inst(vaddr, len);
}
(Note that cache_invalidate_data() is a bit of a misnomer as it actually writes dirty cache lines to memory before invalidating them. Also, I'm using the 'test-nios2' branch of Thomas Chou's git repository.) The reason this is needed is that load_flat_file() in fs/binfmt_flat.c (which is responsible for loading executables in FLAT or ZFLAT format) calls flush_icache_range() after loading the executable into memory. The NiosII implementation of flush_icache_range() in include/asm-nios2/cacheflush.h) just calls the icache_push() function described above. However, with the old version of icache_push() there may still be dirty data cache lines that have not yet been written to memory. If the CPU reads instructions from these memory addresses before the data cache lines have been flushed, it will be reading invalid (stale) instructions. flush_icache_range() is also called when loading kernel modules. Presumably with an 8K or less data cache it's only been working by chance so far!