* Copyright (c) 1992 The Regents of the University of California.
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
* %sccs.include.redist.c%
* @(#)cache.c 7.1 (Berkeley) %G%
* from: $Header: cache.c,v 1.5 92/06/17 05:21:56 torek Exp $ (LBL)
* We need to clear out the valid bits first.
for (i
= AC_CACHETAGS
; i
< AC_CACHETAGS
+ 4096 * 4; i
+= 4)
vactype
= VAC_WRITETHROUGH
; /* XXX must be set per cpu */
stba(AC_SYSENABLE
, ASI_CONTROL
,
lduba(AC_SYSENABLE
, ASI_CONTROL
) | SYSEN_CACHE
);
printf("cache enabled\n");
* Flush the current context from the cache.
* This is done by writing to each cache line in the `flush context'
* address space. Cache lines are 16 bytes, hence the declaration of `p'.
for (i
= 0x1000; --i
>= 0; p
++)
* Flush the given virtual segment from the cache.
* This is also done by writing to each cache line, except that
* now the addresses must include the virtual segment number, and
* we use the `flush segment' space.
cache_flush_segment(vseg
)
p
= (char (*)[16])VSTOVA(vseg
);
for (i
= 0x1000; --i
>= 0; p
++)
* Flush the given virtual page from the cache.
* (va is the actual address, and must be aligned on a page boundary.)
* Again we write to each cache line.
for (i
= NBPG
>> 4; --i
>= 0; p
++)
* Flush a range of virtual addresses (in the current context).
* The first byte is at (base&~PGOFSET) and the last one is just
* before byte (base+len).
* We choose the best of (context,segment,page) here.
* Figure out how much must be flushed.
* If we need to do 16 pages, we can do a segment in the same
* number of loop iterations. We can also do the context. If
* we would need to do two segments, do the whole context.
* This might not be ideal (e.g., fsck likes to do 65536-byte
* reads, which might not necessarily be aligned).
* We could try to be sneaky here and use the direct mapping
* to avoid flushing things `below' the start and `above' the
* ending address (rather than rounding to whole pages and
* segments), but I did not want to debug that now and it is
* not clear it would help much.
baseoff
= (int)base
& PGOFSET
;
i
= (baseoff
+ len
+ PGOFSET
) >> PGSHIFT
;
/* cache_flush_page, for i pages */
p
= (char (*)[16])((int)base
& ~baseoff
);
for (i
<<= PGSHIFT
- 4; --i
>= 0; p
++)
baseoff
= (u_int
)base
& SGOFSET
;
i
= (baseoff
+ len
+ SGOFSET
) >> SGSHIFT
;
/* cache_flush_segment */
p
= (char (*)[16])((int)base
& ~baseoff
);
for (i
= 0x1000; --i
>= 0; p
++)
/* cache_flush_context */
for (i
= 0x1000; --i
>= 0; p
++)