V10/lsys/ml/access.s
.text
#
# badaddr(addr, len)
# see if access addr with a len type instruction causes a machine check
# len is length of access (1=byte, 2=short, 4=long)
#
.globl _badaddr
_badaddr:
.word 0
movl $1,r0
mfpr $IPL,r1
mtpr $0x16,$IPL # low enough for very urgent interrupts
movl 4(ap),r3
movl 8(ap),r4
movl _nofault,r2
movab 2f,_nofault
bbc $0,r4,1f; tstb (r3)
1: bbc $1,r4,1f; tstw (r3)
1: bbc $2,r4,1f; tstl (r3)
1:
movl $10,r3
0: sobgtr r3,0b # pause to allow error interrupt
clrl r0 # made it w/o machine checks
2: movl r2,_nofault
mtpr r1,$IPL
ret
#
# Check address.
# Given virtual address, byte count, and rw flag
# returns 0 on no access.
#
_useracc: .globl _useracc
.word 0x0
movl 4(ap),r0 # get va
movl 8(ap),r1 # count
tstl 12(ap) # test for read access ?
bneq userar # yes
cmpl $NBPG,r1 # can we do it in one probe ?
bgeq uaw2 # yes
uaw1:
probew $3,$NBPG,(r0)
beql uaerr # no access
addl2 $NBPG,r0
acbl $NBPG+1,$-NBPG,r1,uaw1
uaw2:
probew $3,r1,(r0)
beql uaerr
movl $1,r0
ret
userar:
cmpl $NBPG,r1
bgeq uar2
uar1:
prober $3,$NBPG,(r0)
beql uaerr
addl2 $NBPG,r0
acbl $NBPG+1,$-NBPG,r1,uar1
uar2:
prober $3,r1,(r0)
beql uaerr
movl $1,r0
ret
uaerr:
clrl r0
ret
#
# kernacc - check for kernel access privileges
#
# We can't use the probe instruction directly because
# it ors together current and previous mode.
#
.globl _kernacc
_kernacc:
.word 0x0
movl 4(ap),r0 # virtual address
bbcc $31,r0,kacc1
bbs $30,r0,kacerr
mfpr $SBR,r2 # address and length of page table (system)
bbss $31,r2,0f; 0:
mfpr $SLR,r3
brb kacc2
kacc1:
bbsc $30,r0,kacc3
mfpr $P0BR,r2 # user P0
mfpr $P0LR,r3
brb kacc2
kacc3:
mfpr $P1BR,r2 # user P1 (stack)
mfpr $P1LR,r3
kacc2:
addl3 8(ap),r0,r1 # ending virtual address
addl2 $NBPG-1,r1
ashl $-PGSHIFT,r0,r0
ashl $-PGSHIFT,r1,r1
bbs $31,4(ap),kacc6
bbc $30,4(ap),kacc6
cmpl r0,r3 # user stack
blss kacerr # address too low
brb kacc4
kacc6:
cmpl r1,r3 # compare last page to P0LR or SLR
bgtr kacerr # address too high
kacc4:
movl (r2)[r0],r3
bbc $31,4(ap),kacc4a
bbc $31,r3,kacerr # valid bit is off
kacc4a:
cmpzv $27,$4,r3,$1 # check protection code
bleq kacerr # no access allowed
tstb 12(ap)
bneq kacc5 # only check read access
cmpzv $27,$2,r3,$3 # check low 2 bits of prot code
beql kacerr # no write access
kacc5:
aoblss r1,r0,kacc4 # next page
movl $1,r0 # no errors
ret
kacerr:
clrl r0 # error
ret