Files
Arquivotheca.SunOS-4.1.4/sys/boot/lib/sun4c/cache.s
seta75D ff309bfe1c Init
2021-10-11 18:37:13 -03:00

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