This is the mail archive of the
ecos-discuss@sources.redhat.com
mailing list for the eCos project.
Re: Question on hal macro: HAL_DCACHE_INVALIDATE_ALL
On architectures with writeback cache, should this do:
writeback + invalidate
or simply
invalidate
If you need the data in the cache to make it to memory, then you need
to flush (writeback).
One normally invalidates the cache when it is assumed that some other
agent has [or is about to] change memory that would make the contents
of the cache incorrect. By invalidating the cache, new [read] accesses
will cause the contents to be refreshed from memory.
I can't think of anything that would be harmed by doing both a
writeback, and an invalidate. Is there a case where that would not be
the desired use. Generally I would expect people would perform a
HAL_DCACHE_SYNC prior to the invalidate, thus there should not be any
writebacks during the invalidate loop (maybe 1 or 2 cache lines from
stack accesses). Besides reset, is there some case where you would
invalidate the cache without first flushing?
I'll give some slightly useless information, for entertainment purposes.
This macro was originally implemented more or less as a loop like such:
(I removed some macros to make it slightly more intelligible, at least
to me)
(on Xtensa the mnemonic "dii" is: data cache index invalidate)
# define HAL_DCACHE_INVALIDATE_ALL() \
CYG_MACRO_START \
cyg_uint32 addr; \
for (addr = 0; \
addr < HAL_DCACHE_SIZE/HAL_DCACHE_WAYS; \
addr += 4 * HAL_DCACHE_LINE_SIZE) \
asm ("dii %0, 0\n\r" \
"dii %0, 16\n\r" \
"dii %0, 32\n\r" \
"dii %0, 48\n\r" \
: : "r" (addr)); \
asm ("memw; \n\r"); \
CYG_MACRO_END
The crummy compiler spilled the loop variable 'addr' to the stack (-O0
will do that). So when the dii hit the line in the cache where the
'addr' variable was, well... it didn't work out so well. ;)
The easy fix is to change the 'dii' instruction to an instruction that
does does writeback + invalidate. Or compile with -O2, but I personally
dislike code that requires optimizaion on to work correctly. Or I could
rewrite the loop entirely in assembly, which is what I'll end up doing.
Thanks,
-john
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss