[ECOS] Question on hal macro: HAL_DCACHE_INVALIDATE_ALL

Gary Thomas gary@mlbassoc.com
Thu May 6 12:06:00 GMT 2004


On Wed, 2004-05-05 at 22:39, John Newlin wrote:
> >>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?

For performance reasons only, and then only when the area being 
invalidated is known to lie on cache line boundaries.  e.g. in the
ethernet drivers, I use this for read buffers.  One does have to
be careful using this macro alone as you point out.

> 
> 
> 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. 

Actually, this is what the HAL_DCACHE_FLUSH() macro is supposed to do,
flush any modified data to memory and then scrub the cache.  I can't
imagine any reason to use HAL_DCACHE_INVALIDATE_ALL() other than system
startup, when you want to initialize the state of the cache (and
especially then, you would probably want to invalidate only as the cache
tags might indicate sending data to strange and unwanted places)


-- 
Gary Thomas <gary@mlbassoc.com>
MLB Associates


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss



More information about the Ecos-discuss mailing list