.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