V10/sys/ml/copy.s

Compare this file to the similar file:
Show the results in this format:

	.text

	.set	MOVCMAX,0xffff		# largest single movc
#
# copyin and copyout
#
_Copyin:	.globl	_Copyin		# <<<massaged for jsb by asm.sed>>>
	movl	12(sp),r0		# copy length
	blss	ersb
	movl	4(sp),r1		# copy user address
	cmpl	$NBPG,r0		# probing one page or less ?
	blss	ciloop			# no
cishort:
	prober	$3,r0,(r1)		# bytes accessible ?
	beql	ersb			# no
docp:
	pushl	_nofault
	movab	ersbp,_nofault
cpagain:
	cmpl	16(sp),$MOVCMAX
	bgtr	cpbig
	movc3	16(sp),*8(sp),*12(sp)
	movl	(sp)+,_nofault	
#	clrl	r0		# movc leaves 0 in r0
	rsb
ersbp:
	movl	(sp)+,_nofault	
ersb:
	mnegl	$1,r0
	rsb

cpbig:
	movc3	$MOVCMAX,*8(sp),*12(sp)
	subl2	$MOVCMAX,16(sp)	# new len
	movl	r1,8(sp)	# new source, from movc
	movl	r3,12(sp)	# new dest, from movc
	brb	cpagain
ciloop:
	prober	$3,$NBPG,(r1)		# bytes accessible ?
	beql	ersb			# no
	addl2	$NBPG,r1		# incr user address ptr
	acbl	$NBPG+1,$-NBPG,r0,ciloop	# reduce count and loop
	brb	cishort

_Copyout: 	.globl	_Copyout	# <<<massaged for jsb by asm.sed >>>
	movl	12(sp),r0		# get count
	blss	ersb
	movl	8(sp),r1		# get user address
	cmpl	$NBPG,r0		# can do in one probew?
	blss	coloop			# yes
coshort:
	probew	$3,r0,(r1)		# bytes accessible?
	beql	ersb			# no
	brw	docp
coloop:
	probew	$3,$NBPG,(r1)		# bytes accessible?
	beql	ersb			# no 
	addl2	$NBPG,r1		# increment user address
	acbl	$NBPG+1,$-NBPG,r0,coloop	# reduce count and loop
	brb	coshort

/*
 * {fu,su},{byte,word}, all massaged by asm.sed to jsb's
 */
	.globl	_Fuword
_Fuword:
	prober	$3,$4,(r0)
	beql	fserr
	movl	(r0),r0
	rsb
fserr:
	mnegl	$1,r0
	rsb

	.globl	_Fubyte
_Fubyte:
	prober	$3,$1,(r0)
	beql	fserr
	movzbl	(r0),r0
	rsb

	.globl	_Suword
_Suword:
	probew	$3,$4,(r0)
	beql	fserr
	movl	r1,(r0)
	clrl	r0
	rsb

	.globl	_Subyte
_Subyte:
	probew	$3,$1,(r0)
	beql	fserr
	movb	r1,(r0)
	clrl	r0
	rsb

/*
 * find length of a NUL-terminated string in user space;
 * check access along the way
 * returns -1 if access is bad,
 * otherwise length of string including NUL
 * NB not the same number strlen returns
 */

	.globl	_fustrlen
_fustrlen:			# fustrlen(ustr)
	.word	0x0000
	movl	4(ap),r2
	bsbb	Fustrlen
	ret

/*
 * the real work, split off so can jsb here for speed
 * address of string in r2
 */

Fustrlen:
	movl	r2,r1
	bicl3	$~(NBPG-1),r1,r0	# bytes within page
	subl3	r0,$NBPG,r0	# bytes remaining in page
0:
	prober	$3,r0,(r1)
	beql	fsfault		# sic - if error, ret from whoever called us
	locc	$0,r0,(r1)
	bneq	1f
	movl	$NBPG,r0	# next page
	brb	0b
1:				# r1 contains address of NUL
	subl3	r2,r1,r0
	incl	r0		# byte count
	rsb

/*
 * strncpy, but from user space; returns -1 if error
 * it is an error if the string is too long
 *	fustrncpy(to, from, tolen)
 */
	.globl	_fustrncpy
_fustrncpy:
	.word	0
	movl	8(ap),r2
	bsbb	Fustrlen	# check access and find length
#	tstl	r0		# Fustrlen does ret if error
#	blss	fsfault
	cmpl	r0,12(ap)
	bgtr	fsfault
0:	cmpl	r0,$MOVCMAX
	bgtr	1f		# hard case: too big for one movc
	movc3	r0,*8(ap),*4(ap)
#	clrl	r0		# movc leaves 0 in r0
	ret

1:
	subl3	$MOVCMAX,r0,-(sp)
	movc3	$MOVCMAX,*8(ap),*4(ap)
	movl	r1,8(ap)	# movc leaves new source here
	movl	r3,4(ap)	# movc leaves new dest here
	movl	(sp)+,r0
	jbr	0b

fsfault:
	mnegl	$1,r0
	ret

/*
 * Copy 1 relocation unit (NBPG bytes)
 * from user virtual address to physical address
 */
_copyseg: 	.globl	_copyseg
	.word	0x0
	bisl3	$PG_V|PG_KW,8(ap),*_CMAP2
	mtpr	_CADDR2,$TBIS	# invalidate entry for copy 
	movc3	$NBPG,*4(ap),*_CADDR2
	ret

/*
 * zero out physical memory
 * specified in relocation units (NBPG bytes)
 */
_clearseg: 	.globl	_clearseg
	.word	0x0
	bisl3	$PG_V|PG_KW,4(ap),*_CMAP1
	mtpr	_CADDR1,$TBIS
	movc5	$0,(sp),$0,$NBPG,*_CADDR1
	ret

	.comm	_CMAP1,4
	.comm	_CADDR1,4
	.comm	_CMAP2,4
	.comm	_CADDR2,4

#
# get/put one byte in physical memory
# the original excuse is I/O ECC correction
#
#	phgetc(addr)
#	phputc(addr, byte)
#	both return -1 for error
#
	.comm	_CMAP3,4
	.comm	_CADDR3,4
_phgetc:	.globl	_phgetc
	.word	0
	bsbb	phcomm
	movzbl	(r1),r0
	brb	2f

_phputc:	.globl	_phputc
	.word	0
	bsbb	phcomm
	clrl	r0		# return 0 if ok
	cvtlb	8(ap),(r1)
	brb	2f
1:	 mnegl	$1,r0		# error
2:	movl	r3,_nofault
	mtpr	r2,$IPL
	ret

# r2 -> old IPL, new IPL high
# r3 -> old nofault, new nofault ours
# *CMAP3 -> pte
# r1 -> virtual address of the interesting byte

phcomm:
	mfpr	$IPL,r2
	mtpr	$HIGH,$IPL
	divl3	$NBPG,4(ap),r0	# page number
	bisl3	$PG_V|PG_KW,r0,*_CMAP3
	bicl3	$~(NBPG-1),4(ap),r1	# offset within page
	addl2	_CADDR3,r1
	mtpr	r1,$TBIS
	movl	_nofault,r3
	movab	1b,_nofault
	rsb