gcl-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gcl-devel] Re: gcl/acl2 and cacheflush


From: Michael Schmitz
Subject: [Gcl-devel] Re: gcl/acl2 and cacheflush
Date: Tue, 19 Nov 2002 18:32:37 +0100 (CET)

> Here is what we use currently use:
>
> #include <asm/cachectl.h>
> int cacheflush(void *,int,int,int);
> #define CLEAR_CACHE do {void 
> *v=memory->cfd.cfd_start,*ve=v+memory->cfd.cfd_size; \
>                         cacheflush(v,FLUSH_SCOPE_LINE,FLUSH_CACHE_BOTH,ve-v);\
>                     } while(0)
>
> The only thing I can think of trying is FLUSH_SCOPE_PAGE.

I imagine a problem might arise if start and end address aren't properly
aligned. This should only matter on the 030, since 040 and 060 cache flush
routines take care of this internally. What type of machine does this
happen on?

Won't hurt to try FLUSH_SCOPE_PAGE - if that works, we might just miss the
last cache line of a range if it wasn't aligned ...

Business end of cache flush syscall:

        if (CPU_IS_020_OR_030) {
                if (scope == FLUSH_SCOPE_LINE && len < 256) {
                        unsigned long cacr;
                        __asm__ ("movec %%cacr, %0" : "=r" (cacr));
                        if (cache & FLUSH_CACHE_INSN)
                                cacr |= 4;
                        if (cache & FLUSH_CACHE_DATA)
                                cacr |= 0x400;
                        len >>= 2;
                        while (len--) {
                                __asm__ __volatile__ ("movec %1, %%caar\n\t"
                                                      "movec %0, %%cacr"
                                                      : /* no outputs */
                                                      : "r" (cacr), "r" (addr));
                                addr += 4;
                        }
                } else {
                        /* Flush the whole cache, even if page granularity 
requested. */
                        unsigned long cacr;
                        __asm__ ("movec %%cacr, %0" : "=r" (cacr));
                        if (cache & FLUSH_CACHE_INSN)
                                cacr |= 8;
                        if (cache & FLUSH_CACHE_DATA)
                                cacr |= 0x800;
                        __asm__ __volatile__ ("movec %0, %%cacr" : : "r" 
(cacr));
                }
                ret = 0;
                goto out;
        } else {
            /*
             * 040 or 060: don't blindly trust 'scope', someone could
             * try to flush a few megs of memory.
             */

            if (len>=3*PAGE_SIZE && scope<FLUSH_SCOPE_PAGE)
                scope=FLUSH_SCOPE_PAGE;
            if (len>=10*PAGE_SIZE && scope<FLUSH_SCOPE_ALL)
                scope=FLUSH_SCOPE_ALL;
            if (CPU_IS_040) {
                ret = cache_flush_040 (addr, scope, cache, len);
            } else if (CPU_IS_060) {
                ret = cache_flush_060 (addr, scope, cache, len);
            }
        }

with 040/060 routines separate. Look at arch/m68k/kernel/sys_m68k.c for
more...

        Michael





reply via email to

[Prev in Thread] Current Thread [Next in Thread]