Files
Arquivotheca.SunOS-4.1.3/sys/sun4m/module_srmmu_asm.s
seta75D 2e8a93c394 Init
2021-10-11 18:20:23 -03:00

296 lines
7.4 KiB
ArmAsm

/*
* @(#)module_srmmu_asm.s 1.1 92/07/30 SMI
* Copyright (c) 1990 by Sun Microsystems, Inc.
*
* assembly code interface to flexible module routines
*/
#include <sys/param.h>
#include <machine/asm_linkage.h>
#include <machine/mmu.h>
#include <machine/pte.h>
#include <machine/cpu.h>
#include <machine/psl.h>
#include <machine/trap.h>
#include <machine/devaddr.h>
#ifdef MULTIPROCESSOR
#include <percpu_def.h>
#endif MULTIPROCESSOR
#include "assym.s"
.seg "text"
.align 4
ALTENTRY(srmmu_mmu_getcr) ! int mmu_getcr(void);
set RMMU_CTL_REG, %o1 ! get srmmu control register
retl
lda [%o1]ASI_MOD, %o0
ALTENTRY(srmmu_mmu_getctp) ! int mmu_getctp(void);
set RMMU_CTP_REG, %o1 ! get srmmu context table ptr
retl
lda [%o1]ASI_MOD, %o0
ALTENTRY(srmmu_mmu_getctx) ! int mmu_getctx(void);
set RMMU_CTX_REG, %o1 ! get srmmu context number
retl
lda [%o1]ASI_MOD, %o0
ALTENTRY(srmmu_mmu_probe)
and %o0, MMU_PAGEMASK, %o0 ! virtual page number
or %o0, FT_ALL<<8, %o0 ! match criteria
retl
lda [%o0]ASI_FLPR, %o0
ALTENTRY(srmmu_mmu_setcr) ! void srmmu_mmu_setcr(int v);
set RMMU_CTL_REG, %o1 ! set srmmu control register
retl
sta %o0, [%o1]ASI_MOD
ALTENTRY(srmmu_mmu_setctp) ! void srmmu_mmu_setctp(int v);
set RMMU_CTP_REG, %o1 ! set srmmu context table pointer
retl
sta %o0, [%o1]ASI_MOD
ALTENTRY(srmmu_mmu_setctx) ! void srmmu_mmu_setctx(int v);
set RMMU_CTX_REG, %o5 ! set srmmu context number
retl
sta %o0, [%o5]ASI_MOD
ALTENTRY(srmmu_mmu_flushall) ! void srmmu_mmu_flushall(void)
or %g0, FT_ALL<<8, %o0 ! flush entire mmu
set RMMU_CTX_REG, %o4 ! flush mapping from context in mmu
retl
sta %g0, [%o0]ASI_FLPR ! do the flush
/*
* BORROW_CONTEXT: temporarily set the context number
* to that given in %o1.
*
* NOTE: if the kernel does not appear to be mapped into the requested
* context, then the operation is done in the current context instead.
* This may or may not be the most efficient thing to do, but it is
* the safest.
*
* NOTE: traps are disabled while we are in a borrowed context. It is
* not possible to prove that the only traps that can happen while the
* context is borrowed are safe to activate while we are in a borrowed
* context (this includes random level-15 interrupts!).
*
* %o0 flush/probe address [don't touch!]
* %o1 context number to borrow
* %o2 saved context number
* %o3 [[appears to be free]]
* %o4 psr temp / probe temp / RMMU_CTX_REG
* %o5 saved psr
*
* The probe sequence (middle block) is documented more clearly in
* the routine "mmu_flushctx".
*/
#define BORROW_CONTEXT \
mov %psr, %o5; \
andn %o5, PSR_ET, %o4; \
mov %o4, %psr; \
nop ; nop; \
\
set RMMU_CTP_REG, %o4; \
lda [%o4]ASI_MOD, %o4; \
sll %o1, 2, %o2; \
sll %o4, 4, %o4; \
add %o4, %o2, %o4; \
lda [%o4]ASI_MEM, %o4; \
and %o4, 3, %o4; \
subcc %o4, MMU_ET_PTP, %g0; \
\
set RMMU_CTX_REG, %o4; \
bne 1f; \
lda [%o4]ASI_MOD, %o2; \
sta %o1, [%o4]ASI_MOD; \
1:
/*
* RESTORE_CONTEXT: back out from whatever BORROW_CONTEXT did.
* Assumes that two cycles of PSR DELAY follow.
*/
#define RESTORE_CONTEXT \
sta %o2, [%o4]ASI_MOD; \
mov %o5, %psr; \
nop
ALTENTRY(srmmu_mmu_flushctx) ! void srmmu_mmu_flushctx(int ctx);
set FT_CTX<<8, %o0
BORROW_CONTEXT
sta %g0, [%o0]ASI_FLPR ! do the flush
RESTORE_CONTEXT
retl
nop ! psr delay
ALTENTRY(srmmu_mmu_flushrgn) ! void srmmu_mmu_flushrgn(caddr_t base);
b srmmu_flushcommon ! flush region in context from mmu
or %o0, FT_RGN<<8, %o0
ALTENTRY(srmmu_mmu_flushseg) ! void srmmu_mmu_flushseg(caddr_t base);
b srmmu_flushcommon ! flush segment in context from mmu
or %o0, FT_SEG<<8, %o0
ALTENTRY(srmmu_mmu_flushpage) ! void srmmu_mmu_flushpage(caddr_t base)
or %o0, FT_PAGE<<8, %o0
srmmu_flushcommon:
#ifdef MULTIPROCESSOR
BORROW_CONTEXT
#endif MULTIPROCESSOR
sta %g0, [%o0]ASI_FLPR ! do the flush
#ifdef MULTIPROCESSOR
RESTORE_CONTEXT
#endif MULTIPROCESSOR
retl
nop ! PSR or MMU delay.
ALTENTRY(srmmu_mmu_flushpagectx) ! void srmmu_mmu_flushpagectx(caddr_t base, int ctx)
or %o0, FT_PAGE<<8, %o0
BORROW_CONTEXT
sta %g0, [%o0]ASI_FLPR ! do the flush
RESTORE_CONTEXT
retl
nop ! PSR or MMU delay.
!
! BE CAREFUL - register useage must correspond to code
! in locore.s that calls this routine!
! See comments for "mmu_getsyncflt" for allocation information.
ALTENTRY(srmmu_mmu_getsyncflt)
set RMMU_FAV_REG, %g7
lda [%g7]ASI_MOD, %g7
set RMMU_FSR_REG, %g6
retl
lda [%g6]ASI_MOD, %g6
ALTENTRY(srmmu_mmu_getasyncflt)
set RMMU_AFA_REG, %o1
lda [%o1]ASI_MOD, %o1
st %o1, [%o0+4]
set RMMU_AFS_REG, %o1
lda [%o1]ASI_MOD, %o1
st %o1, [%o0]
set -1, %o1
retl
st %o1, [%o0+8]
ALTENTRY(srmmu_mmu_chk_wdreset)
set RMMU_RST_REG, %o1 ! D-side reset reg.
lda [%o1]ASI_MOD, %o0
retl
and %o0, RSTREG_WD, %o0 ! mask WD reset bit
! see "mmu_sys_ovf" for constraints.
ALTENTRY(srmmu_mmu_sys_ovf)
set RMMU_FSR_REG, %g1 ! clear any old faults out
lda [%g1]ASI_MOD, %g0 ! of the SFSR.
set RMMU_CTL_REG, %g2
lda [%g2]ASI_MOD, %g1 ! turn on no-fault bit in
or %g1, MCR_NF, %g1 ! mmu control register to
sta %g1, [%g2]ASI_MOD ! prevent taking a fault.
SAVE_WINDOW(%sp) ! try to save reg window
andn %g1, MCR_NF, %g1 ! turn off no-fault bit
sta %g1, [%g2]ASI_MOD
set RMMU_FAV_REG, %g2
lda [%g2]ASI_MOD, %g2 ! read SFAR
set RMMU_FSR_REG, %g1
lda [%g1]ASI_MOD, %g1 ! read SFSR
b,a st_chk_flt ! continue caller
! see "mmu_sys_unf" for constraints.
ALTENTRY(srmmu_mmu_sys_unf)
set RMMU_FSR_REG, %g1 ! clear any old faults out
lda [%g1]ASI_MOD, %g0 ! of the SFSR.
set RMMU_CTL_REG, %g2
lda [%g2]ASI_MOD, %g1 ! turn on no-fault bit in
or %g1, MCR_NF, %g1 ! mmu control register to
sta %g1, [%g2]ASI_MOD ! prevent taking a fault
restore
RESTORE_WINDOW(%sp) ! try to restore reg window
save
andn %g1, MCR_NF, %g1 ! turn off no-fault bit
sta %g1, [%g2]ASI_MOD
set RMMU_FAV_REG, %g2
lda [%g2]ASI_MOD, %g2 ! read SFAR
set RMMU_FSR_REG, %g1
lda [%g1]ASI_MOD, %g1 ! read SFSR
b,a sr_chk_flt ! continue caller
! see mmu_wo for constraints
ALTENTRY(srmmu_mmu_wo)
set RMMU_FSR_REG, %g1 ! clear any old faults out
lda [%g1]ASI_MOD, %g0 ! of the SFSR.
set RMMU_CTL_REG, %g2
lda [%g2]ASI_MOD, %g1 ! turn on no-fault bit in
or %g1, MCR_NF, %g1 ! mmu control register to
sta %g1, [%g2]ASI_MOD ! prevent taking a fault.
SAVE_WINDOW(%sp) ! try to save reg window
andn %g1, MCR_NF, %g1 ! turn off no-fault bit
sta %g1, [%g2]ASI_MOD
set RMMU_FAV_REG, %g2
lda [%g2]ASI_MOD, %g2 ! read SFAR
set RMMU_FSR_REG, %g1
lda [%g1]ASI_MOD, %g1 ! read SFSR
b,a wo_chk_flt ! continue caller
ALTENTRY(srmmu_mmu_wu)
! GENERIC SRMMU mmu module specific part of the code
! used by underflow.s to handle a register window
! underflow.
! NOTE that this routine is jumped to, and that it jumps
! back to a fixed location.
! BE CAREFUL WITH REGISTER USEAGE -- REGISTERS MUST
! CORRESPOND TO underflow.s CODE THAT JUMPS
! HERE.
!
set RMMU_FSR_REG, %l5
lda [%l5]ASI_MOD, %g0 ! clear SFSR
set RMMU_CTL_REG, %l5
lda [%l5]ASI_MOD, %l4
or %l4, MCR_NF, %l4 ! set no-fault bit in
sta %l4, [%l5]ASI_MOD ! control register
RESTORE_WINDOW(%sp)
save
save
set RMMU_CTL_REG, %l5
lda [%l5]ASI_MOD, %l4
andn %l4, MCR_NF, %l4 ! clear no-fault bit
sta %l4, [%l5]ASI_MOD ! in control register
set RMMU_FAV_REG, %l5
lda [%l5]ASI_MOD, %l5 ! read SFAR
set RMMU_FSR_REG, %l4
lda [%l4]ASI_MOD, %l4 ! read SFSR
b wu_chk_flt ! proceed with underflow
nop