Subject: Re: Problems flushing cache with KUSEG addresses
To: Jeff Smith <jeffs@geocast.com>
From: Wayne Knowles <w.knowles@niwa.cri.nz>
List: port-mips
Date: 07/27/2000 17:41:51
On Wed, 26 Jul 2000, Jeff Smith wrote:

> Wayne Knowles wrote:
> 
> > The problem is that a kuseg virtual address is being passed to
> > MachFlushICache in the setregs() function.   Under stressful conditions
> > the cache flushing routines can produce a TLB miss exception which has to
> > be handled by the high level TLB Exception functions.  Since the processor
> > is isolated from main memory at that stage weird things start to happen.
> 
> What do you mean "isolated from memory"?  Unfortunately I don't
> understand your reasoning here.

Hi Jeff,

Sorry for the confusion.  This is when the IsC bit is set in the Status
register.  On the R3000 this isolates the cache from the main memory which
is how you invalidate the cache.   The cache handling routines disable
interrupts while the processor is in this mode, but at the same time you
have to ensure there are no TLB misses that will require memory acceses
outside the cache.

> 
> > All memory addresses passed to MachFlush{I,D}Cache should be kseg0 or
> > kseg1 addresses to ensure no TLB miss exceptions are generated during the
> > cache invalidation.
> 
> Is this true with other parts of the mips code?  I would like it not
> to be true so we can do hit ops more on two (or more) way caches, if
> we ever get around to optimizing that.  My port spends a lot of time
> in the cache routines, although I have not profiled after folding in
> some of the improvements from -current.

This is true for any R3000 processor.  In fact it is documented at the
start of the mips1_FlushDCache function:


/*----------------------------------------------------------------------------
 *
 * mips1_FlushDCache --
 *
 *	void mips1_FlushDCache(addr, len)
 *		vaddr_t addr; vsize_t len;
 *
 *	Flush data cache for range of addr to addr + len - 1.
 *	The address can be any valid address so long as no TLB misses occur.
 *	(Be sure to use cached K0SEG kernel addresses)
 * Results:
 *	None.
 *
 * Side effects:
 *	The contents of the cache is flushed.
 *
 *----------------------------------------------------------------------------


> > What I have done is force a dummy read of the address which will cause the
> > TLB entry to be loaded if it isn't available:
> 
> This sounds hackey, and you'd be better off w/o the cache flush at all
> as it rarely affects real programs.

Agreed.  The hack however takes requires only a few instruction for the
common case.

> Another option is to let the mips3 1 way code flushing code
> make a K0 address with the virtual index.  The _2way code does
> this to properly handle index ops on KUSEG adresses.  This would
> be easy to prototype in the C code, but should be best to be
> changed in the assembly code as _2way already does it.
> 
> Use MIPS_PHYS_TO_KSEG0(addr & (cachesize-1))

I think the MIPS3 is more forgiving when it comes to TLB misses during
cache invalidation.   Given the process runs with interrupts enabled and
the special cache opcodes I'm willing to speculate it is able to safely
handle a KUSEG address 

> MIPS1 probably needs some work too.

You have to be a lot more careful with the MIPS1 cache, hence the
requirement for addresses to be KSEG0 based.  

> Also, what processors are going to be supported by the mipsco
> port?  I'd anticipate R4000SC and maybe R4000PC.

Actually it is based on the R3000  There are R4000 models out there but
I don't have access to any.

> Thanks, and sorry for tripping you up.  It's hard to get all
> the cases.

Not problems.  I was saved by the firmware recording the value 'pc' and
'ra' when you hit the rest button!

Wayne
--
  _____	   	Wayne Knowles,  Systems Manager
 / o   \/   	National Institute of Water & Atmospheric Research Ltd
 \/  v /\   	P.O. Box 14-901 Kilbirnie, Wellington, NEW ZEALAND
  `---'     	Email:   w.knowles@niwa.cri.nz