This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]