147 lines
3.8 KiB
ArmAsm
147 lines
3.8 KiB
ArmAsm
/*
|
|
* .seg "data"
|
|
* .asciz "@(#)cache.s 1.1 94/10/31 SMI"
|
|
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
|
*/
|
|
.seg "text"
|
|
.align 4
|
|
|
|
#include <machine/asm_linkage.h>
|
|
#include <machine/param.h>
|
|
#include <machine/pte.h>
|
|
#include <machine/mmu.h>
|
|
#include <machine/enable.h>
|
|
#define NSGVA (1<<(32-PMGRPSHIFT))
|
|
|
|
#ifdef VAC
|
|
|
|
/*
|
|
* cache_prog(start, end)
|
|
* change all of the text and data pages
|
|
* that are used by prog to be cacheable
|
|
*/
|
|
ENTRY(cache_prog)
|
|
save %sp, -WINDOWSIZE, %sp
|
|
set PG_NC, %l0 ! the no cache bit
|
|
set NBPG, %l1 ! pagesize increment
|
|
1:
|
|
call _getpgmap ! get pte
|
|
mov %i0, %o0 ! address
|
|
|
|
andn %o0, %l0, %o1 ! clear the nocache bit
|
|
call _setpgmap ! write the new pte
|
|
mov %i0, %o0 ! address
|
|
|
|
add %i0, %l1, %i0 ! add pagesize to get next pte
|
|
cmp %i0, %i1
|
|
bleu 1b ! go do the next page
|
|
nop
|
|
|
|
ret
|
|
restore
|
|
|
|
/*
|
|
* turnon_cache
|
|
* write all the tags to zero
|
|
* turn on the cache via the system enable register
|
|
*/
|
|
ENTRY(turnon_cache)
|
|
set CACHE_TAGS, %o0 ! address of cache tags in CTL space
|
|
set _vac_size, %o1 ! number of lines to initialize
|
|
ld [%o1], %o1
|
|
set _vac_linesize, %o2 ! offsets for by 4 loop unroll
|
|
ld [%o2], %o2
|
|
sll %o2, 1, %o3 ! VAC_LINESIZE * 2
|
|
add %o2, %o3, %o4 ! VAC_LINESIZE * 3
|
|
sll %o2, 2, %o5 ! VAC_LINESIZE * 4
|
|
1:
|
|
sta %g0, [%o0]ASI_CTL ! write tags to zero
|
|
sta %g0, [%o0 + %o2]ASI_CTL ! offset 16
|
|
sta %g0, [%o0 + %o3]ASI_CTL ! offset 32
|
|
sta %g0, [%o0 + %o4]ASI_CTL ! offset 48
|
|
subcc %o1, 4, %o1 ! done yet?
|
|
bg 1b
|
|
add %o0, %o5, %o0 ! next cache tags address
|
|
|
|
set ENABLEREG, %o2 ! address of real version in hardware
|
|
lduba [%o2]ASI_CTL, %g1 ! get current value
|
|
bset ENA_CACHE, %g1 ! enable cache bit
|
|
retl
|
|
stba %g1, [%o2]ASI_CTL ! write new value
|
|
|
|
/*
|
|
* disable the cache, flush the cache completely (all of context 0)
|
|
* We can't flush context 0 with a context flush, (a feature)
|
|
* because we've been using context 0 in supervisor mode,
|
|
* so we loop through segments. Once flushed, turn off the
|
|
* cache via the system enable register
|
|
* NOTE: this assumes that standalones only use one context
|
|
*/
|
|
ENTRY(turnoff_cache)
|
|
save %sp, -WINDOWSIZE, %sp
|
|
mov 0, %l0 ! address of first segment
|
|
set PMGRPSIZE, %l1 ! number of bytes in a segment
|
|
set NPMGRPPERCTX/2, %l2 ! number of segs to flush in 1st half
|
|
set _vac_linesize, %l5 ! offsets for by 4 loop unroll
|
|
ld [%l5], %l5
|
|
sll %l5, 1, %l6 ! VAC_LINESIZE * 2
|
|
add %l5, %l6, %l7 ! VAC_LINESIZE * 3
|
|
sll %l5, 2, %l4 ! VAC_LINESIZE * 4
|
|
set _npmgrps, %l3
|
|
ld [%l3], %l3
|
|
dec %l3 ! PMGRP_INVALID
|
|
set _vac_size, %o2
|
|
ld [%o2], %o2
|
|
mov %l5, %o3 ! compute NLINES=SIZE/LINESIZE...
|
|
0:
|
|
srl %o3, 1, %o3 ! we "know" LINESIZE is a power of 2
|
|
tst %o3 ! so just shift until LINESIZE
|
|
bnz,a 0b ! goes to zero
|
|
srl %o2, 1, %o2
|
|
1:
|
|
lduha [%l0]ASI_SM, %g1 ! get segment map
|
|
cmp %g1, %l3 ! if invalid we don't have to flush
|
|
be 3f
|
|
.empty
|
|
!
|
|
! flush the segment
|
|
!
|
|
mov %l0, %o0
|
|
mov %o2, %o1 ! %o1 = VAC_SEGFLUSH_COUNT
|
|
2:
|
|
sta %g0, [%o0]ASI_FCS
|
|
sta %g0, [%o0 + %l5]ASI_FCS
|
|
sta %g0, [%o0 + %l6]ASI_FCS
|
|
sta %g0, [%o0 + %l7]ASI_FCS
|
|
deccc 4, %o1 ! dec count
|
|
bg 2b ! done?
|
|
add %o0, %l4, %o0 ! next group of lines
|
|
3:
|
|
deccc %l2 ! count down segments
|
|
bnz 1b
|
|
add %l0, %l1, %l0 ! next segment
|
|
|
|
tst %l0 ! at end of 2nd half of addr space?
|
|
set (NSGVA - (NPMGRPPERCTX/2)) * PMGRPSIZE, %l0
|
|
! start of 2nd half
|
|
set NPMGRPPERCTX/2, %l2 ! number of segs to flush in 2nd half
|
|
bnz 1b ! no, do 2nd half
|
|
.empty
|
|
|
|
set ENABLEREG, %o0 ! address of enable reigster
|
|
lduba [%o0]ASI_CTL, %g1 ! get current value
|
|
bclr ENA_CACHE, %g1 ! clear enable cache bit
|
|
stba %g1, [%o0]ASI_CTL ! write new value
|
|
ret ! cache is now off
|
|
restore
|
|
|
|
#else VAC
|
|
|
|
ENTRY(cache_prog)
|
|
ALTENTRY(turnon_cache)
|
|
ALTENTRY(turnoff_cache)
|
|
retl
|
|
nop
|
|
|
|
#endif
|