Subject: cacheflush() proposal
To: None <tech-userlevel@netbsd.org>
From: Ignatios Souvatzis <is@jocelyn.rhein.de>
List: tech-userlevel
Date: 12/02/1998 23:56:06
$Id: cacheflush.txt,v 1.2 1998/12/02 21:30:36 is Exp $

This is in response to PR 4951.

4951 complains that NetBSD doesn't have an defined (with a name) interface to
icache/dcache synchronization on m68k. If you're a (objc or Pascal) compiler
writer, or a JAVA JIT machine implementor, you need to browse through kernel
code or gcc sources to find out how to do it.

Browsing through stuff, I found that all MIPS OSes (Ultrix, NetBSD, rumours are
also IRIX) provide the interface cited below, which is a bit coarser
than what the badly documented trap #12 on NetBSD/m68k does, but enough for 
people writing self-modifying code. My proposal (shortly discussed with Jason
Thorpe elsewhere) is to declare this interface machine independent, and provide
machine dependent implementations. Ports are allowed to synchronize
more than requested (e.g., the arm32 sysarch() call does this).

As I understand, there are 3 cases:

- the CPU has none or unified caches: the function is a no-op; possibly an
  empty define in the header file, and a return(0) or equivalent in libc.

- the CPU supports user-level instructions for this (e.g., PPC): the
  implementation is just (possibly inline) code to do the job. Look at what
  gcc does for objc purposes.

- the CPU needs supervisor code: implement as trap call, sysarch() call or
  whatever you're already doing... remember, gcc's libgcc already contains 
  code to do this for the benefit of Objective C, so something must exist
  already.

Of course, pre-existing traditional interfaces (e.g., the MIPS and ARM32 one)
are allowed to stay, but, to port, e.g., a JIT machine to NetBSD you just put
the cacheflush(addr, len, BCACHE) calls in place and are done for all
architectures.

This should be implemented for 1.4, IMO.

Find below (mostly) the MIPS definition, with my additions marked with + at the
beginning of the line..

Regards,
	Ignatios Souvatzis

   Name
     cacheflush - flush the instruction cache, data cache, or both

   Syntax
-    #include <mips/cachectl.h>
+    #include <cacheflush.h>

     cacheflush(addr, nbytes, cache)
     char *addr;
     int nbytes, cache;

   Description
     Flushes contents of indicated caches for user addresses in the range of
     addr to (addr+nbytes-1).  The cache parameter is one of the following:

     ICACHE         Flush only the instruction cache.

     DCACHE         Flush only the data cache.

     BCACHE         Flush both the instruction and data caches.

+    An implementation on a particular CPU is allowed to do nothing (if the
+    CPU has no or unified caches) or flush more than requested (if the CPU
+    doesn't provide fine-grained control over its caches), as long as a 
+    BCACHE operation guarantees that all data written to the address range
+    before cacheflush() is guaranteed to be visible as instruction stream 
+    afterwards.

   Return Values
     The cacheflush system call returns 0 when errors are not detected.  If
     errors are detected, the cacheflush system call returns -1 with the
     error cause indicated in errno.

   Diagnostics

     [EFAULT]       Some or all of the address range in the addr to
                    (addr+nbytes-1) are not accessible.

     [EINVAL]       The cache parameter is not ICACHE, DCACHE, or BCACHE.