Subject: Re: more on cache ops... What are they actually supposed to do?
To: Noriyuki Soda <soda@sra.co.jp>
From: Chris G. Demetriou <cgd@sibyte.com>
List: port-mips
Date: 06/20/2000 14:11:54
soda@sra.co.jp (Noriyuki Soda) writes:
> If I understand correctly, his proposal basically means having
> following cache primitives:
> 
> 	- invalidate instruction cache
> 	- invalidate data cache
> 	- writeback and invalidate data cache
> 		This is what our current FlushDCache() does.
> 		On MIPS1, this should be just same function with 
> 		invalidation, since MIPS1's cache is write-through,
> 	- writeback data cache
> 		On MIPS1, this should be just no operation,
> 		since MIPS1's cache is write-through,

Even just looking at the ops which we currently support (iinv/iwbinv,
for the index ops), i'd break it down further.

Assuming we're going to stick with using index, rather than hit, ops
for most operations for the time being:

provide primitives that do:

	index inv. (I caches)
	index wb inv. (D caches)

for each of:

	primary I
	primary D
	secondary
	tertiary (note, see mips run says rm7k supports tertiary cache!)

and then, provide implementations with line sizes and associativity as
necessary.


The current necessary ops for mips3 processors that are currently
supported or that I know of people having a desire to support "soon"
are:

	iinv primary i 16-byte lines direct-mapped v-indx	*
	iwbinv primary d 16-byte lines direct-mapped v-indx	*
	iwbinv secondary 32-byte lines direct-mapped v-indx	*, **
	iinv primary i 32-byte-lines 2-way v-indx		**
	iwbinv primary d 32-byte-lines 2-way v-indx		**
	iwbinv secondary 32-byte lines 2-way v-indx		***

* == in current scheme, done by mips3_Flush{,I,D}Cache
** == in current scheme, done by mips3_Flush{,I,D}Cache_2way
*** == not provided/done in current scheme, needed for e.g. r10k.

(other line sizes may be desirable, too, for max. efficiency, but I
don't know more on that front.)

Is that is that correct?

(additionally, i'd figure that a no-op stub (which just returns)
should probably be provided, for the case where you just don't have a
cache of a given type, e.g. no l2.)


I'd say that the way this "should work" for the general case is that
there should be a set of parameters:

	l1 i cache: size, line size, associativity, index type
	l1 d cache: size, line size, associativity, index type
	l2 cache: size, line size, associativity, index type
	(others, e.g. that info for l3)

(presence should be implied by size).

board-specific code would set board-specific parameters (e.g. L2
information; see the #ifdef's in mips3_vector_init()) before calling
mips_vector_init().

the cpu-detection code in mips_vector_init() would set the parameters
as appropriate for the CPU.

Code at the end of mips_vector_init() would fill in fn ptrs for the
ops as appropriate (doing best-fit based on what fns are available and
the parameters), filling in NULL (or maybe a function prointer which
won't crash but is known to be special) for functions which can't be
supported with the current kernel config. 

finally, code in cpu_identify() could punt on unsupported cache
configurations, by checking for the special pointer values.


You would then combine the appropriately set functions to implement
the higher-level operations (FlushI, FlushD, Flush).  (There are
various ways to do this, e.g. simple calls through function pointers,
copying & concatenating the code, etc.)  

pared-down configs which support only certain cache ops could be
optimized in various ways, but I'd like to see the general case solved
first.


comments?  I'm planning to post the first set of diffs which move in
this general direction RSN.


chris