Subject: Re: MIPS cache rototill progressing!
To: None <port-mips@netbsd.org>
From: Toru Nishimura <nisimura@itc.aist-nara.ac.jp>
List: port-mips
Date: 07/13/2001 09:46:16
>        * Have not yet tested R4600 (SGI Indy).  I want to get the
>          RM52xx working, first, since the R4600 cache is "like" the
>          RM52xx cache, except with hardware bugs :-)
>
> Considering that it works on the R4400 (direct-mapped cache) and not
> the RM52xx (2-way set-associative), I probably have a bug in the 2-way
> cache handling code.

As the homework style solution I have a piece of code for cache
invalidation logics for MIPS processors.

This is what I'm using.
 
                /* direct mapped 32KB/16KB, assuming 16B linesize */
                asm("mtc0 $0, $28");            /* mtc0 zero, CP0_TAGLO */
                size = 32 * 1024;               /* 32KB Icache */
                p = (caddr_t)0x80000000;
                while (size > 0) {
                        asm("cache 8,0(%0)" ::"r"(p)); /* cache (2<<2)|0,(p) */
                        size -= 16;
                        p += 16;
                }
                asm("mtc0 $0, $28");            /* mtc0 zero, CP0_TAGLO */
                size = 16 * 1024;               /* 16KB Dcache */
                p = (caddr_t)0x80000000;
                while (size > 0) {
                        asm("cache 9,0(%0)" ::"r"(p)); /* cache (2<<2)|1,(p) */
                        size -= 16;
                        p += 16;
                }

For the 2way set associative cache, the following should work (I have
never tried);

                /* 2way set associative 16KB/16KB, assuming 16B linesize */
                asm("mtc0 $0, $28");            /* mtc0 zero, CP0_TAGLO */
                size = (16 * 1024) >> 1;        /* 16KB 2way Icache */
                p = (caddr_t)0x80000000;
                while (size > 0) {
                        asm("cache 8,0(%0)"  ::"r"(p)); /* cache (2<<2)|1,(p) */
                        asm("cache 8,%1(%0)" ::"r"(p), "i"((16 * 1024) >> 1));
                        size -= 16;
                        p += 16;
                }
                asm("mtc0 $0, $28");            /* mtc0 zero, CP0_TAGLO */
                size = (16 * 1024) >> 1;        /* 16KB 2way Dcache */
                p = (caddr_t)0x80000000;
                while (size > 0) {
                        asm("cache 9,0(%0)"  ::"r"(p)); /* cache (2<<2)|1,(p) */
                        asm("cache 9,%1(%0)" ::"r"(p), "i"((16 * 1024) >> 1));
                        size -= 16;
                        p += 16;
                }

Hope this helpful to someone.

Tohru Nishimura