⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 big_copy.s

📁 操作系统SunOS 4.1.3版本的源码
💻 S
📖 第 1 页 / 共 2 页
字号:
 * kzero(addr, count) *	caddr_t addr; *	u_int count; */	ENTRY(kzero)	sethi	%hi(zeroerr), %o2	b	do_zero	or	%o2, %lo(zeroerr), %o2/* * We got here because of a fault during kzero. */zeroerr:	st	%o5, [_u+U_LOFAULT]	! restore old u.u_lofault	retl	restore	%g0, EIO, %o0		! return (EIO)/* * Zero a block of storage. * * bzero(addr, length) *	caddr_t addr; *	u_int count; */	ENTRY2(bzero,blkclr)	mov	0, %o2do_zero:	ld	[_u+U_LOFAULT], %o5	! save u.u_lofault	cmp	%o1, 15			! check for small counts	bl	byteclr			! just clear bytes	st	%o2, [_u+U_LOFAULT]	! install new vector	!	! Check for word alignment.	!	btst	3, %o0	bz	_bzero_probe	mov	0x100, %o3		! constant size of main loop	!	!	! clear bytes until word aligned	!1:	clrb	[%o0]	add	%o0, 1, %o0	btst	3, %o0	bnz	1b	sub	%o1, 1, %o1	!	! Word aligned.	! Probe to see if word access is allowed (i.e. not VME_D16)	! This assumes that the source will not change to VME_D16	! during the bzero. This will get a data fault with	! be_vmeserr set if unsuccessful. Trap will	! then return to bzero_vme16. This is gross but fast.	!	.global _bzero_probe, _ebzero_probe_bzero_probe:	clr	[%o0]			! clear word to probe_ebzero_probe:	!	! If needed move a word to become double-word aligned.	!	btst	7, %o0			! align to double-word boundary	bz	2f	clr	%g1			! clr g1 for second half of double %g0	sub	%o1, 4, %o1	b	2f	add	%o0, 4, %o0	!std	%g0, [%o0+0xf8]zeroblock:	std	%g0, [%o0+0xf0]	std	%g0, [%o0+0xe8]	std	%g0, [%o0+0xe0]	std	%g0, [%o0+0xd8]	std	%g0, [%o0+0xd0]	std	%g0, [%o0+0xc8]	std	%g0, [%o0+0xc0]	std	%g0, [%o0+0xb8]	std	%g0, [%o0+0xb0]	std	%g0, [%o0+0xa8]	std	%g0, [%o0+0xa0]	std	%g0, [%o0+0x98]	std	%g0, [%o0+0x90]	std	%g0, [%o0+0x88]	std	%g0, [%o0+0x80]	std	%g0, [%o0+0x78]	std	%g0, [%o0+0x70]	std	%g0, [%o0+0x68]	std	%g0, [%o0+0x60]	std	%g0, [%o0+0x58]	std	%g0, [%o0+0x50]	std	%g0, [%o0+0x48]	std	%g0, [%o0+0x40]	std	%g0, [%o0+0x38]	std	%g0, [%o0+0x30]	std	%g0, [%o0+0x28]	std	%g0, [%o0+0x20]	std	%g0, [%o0+0x18]	std	%g0, [%o0+0x10]	std	%g0, [%o0+0x08]	std	%g0, [%o0]zinst:	add	%o0, %o3, %o0		! increment source address	sub	%o1, %o3, %o1		! decrement count2:	cmp	%o1, 0x100		! can we do whole chunk?	bge,a	zeroblock	std	%g0, [%o0+0xf8]		! do first double of chunk	cmp	%o1, 7			! can we zero any more double words	ble	byteclr			! too small go zero bytes	andn	%o1, 7, %o3		! %o3 bytes left, double-word aligned	srl	%o3, 1, %o2		! using doubles, need 1 instr / 2 words	set	zinst, %o4		! address of clr instructions	sub	%o4, %o2, %o4		! jmp address relative to instr	jmp	%o4	nop	!	! do leftover bytes	!3:	add	%o0, 1, %o0		! increment addressbyteclr:	subcc	%o1, 1, %o1		! decrement count	bge,a	3b	clrb	[%o0]			! zero a byte	st	%o5, [_u+U_LOFAULT]	! restore old u.u_lofault	retl	mov	0, %o0			! return (0)/* * bcopy_vme16(from, to, count) * Block copy to/from a 16 bit vme device. * There is little optimization because the VME is so slow. * We are only entered after a VME size error trap from within bcopy. * We get here with more than 3 bytes to copy. */	ENTRY(bcopy_vme16)	xor	%i0, %i1, %i4		! test for mutually half word aligned	btst	1, %i4	bnz	bytecp			! misaligned, copy bytes	.empty	btst	1, %i0			! test for initial byte	bz,a	1f	andn	%i2, 1, %i3		! count of aligned bytes to clear	ldub	[%i0], %i4		! copy initial byte	add	%i0, 1, %i0	stb	%i4, [%i1]	add	%i1, 1, %i1	sub	%i2, 1, %i2	andn	%i2, 1, %i3		! count of aligned bytes to clear1:	and	%i2, 1, %i2		! unaligned leftover count2:	lduh	[%i0], %i4		! read from address	add	%i0, 2, %i0		! inc from address	sth	%i4, [%i1]		! write at destination address	subcc	%i3, 2, %i3		! dec count	bg	2b	add	%i1, 2, %i1		! delay slot, inc to address	b,a	bytecp			! copy remaining bytes, if any/* * bzero_vme16(addr, length) * Zero a block of VME_D16 memory. * There is little optimization because the VME is so slow. * We get here with more than 3 bytes to clear. */	ENTRY(bzero_vme16)	!	! clear memory until halfword aligned	!1:	btst	1, %o0			! test for half word aligned	bz,a	2f	andn	%o1, 1, %o3		! count of aligned bytes to clear	clrb	[%o0]			! clear 1 byte	sub	%o1, 1, %o1	add	%o0, 1, %o0	andn	%o1, 1, %o3		! count of aligned bytes to clear	!	! now half word aligned	!2:	and	%o1, 1, %o1		! unaligned leftover count3:	clrh	[%o0]			! zero word	subcc	%o3, 2, %o3		! decrement count	bg	3b	add	%o0, 2, %o0		! increment address	b,a	byteclr			! zero remaining bytes, if any#endif never/* * Copy a null terminated string from one point to another in * the kernel address space. * NOTE - don't use %o5 in this routine as copy{in,out}str uses it. * * copystr(from, to, maxlength, lencopied) *	caddr_t from, to; *	u_int maxlength, *lencopied; */	ENTRY(copystr)	tst	%o2	bg	1f	mov	%o2, %o4		! save original count	!	! maxlength <= 0	!	bz	cs_out			! maxlength = 0	mov	ENAMETOOLONG, %o0	retl				! maxlength < 0	mov	EFAULT, %o0		! return (EFAULT)	!	! Do a byte by byte loop.	! We do this instead of a word by word copy because most strings	! are small and this takes a small number of cache lines.	!0:	add	%o0, 1, %o0		! interlock slot, inc src addr	stb	%g1, [%o1]		! store byte	tst	%g1			! null byte?	bnz	1f	add	%o1, 1, %o1		! incr dst addr	b	cs_out			! last byte in string	mov	0, %o0			! ret code = 01:	subcc	%o2, 1, %o2		! test count	bge,a	0b	ldub	[%o0], %g1		! delay slot, get source byte	mov	0, %o2			! max number of bytes moved	mov	ENAMETOOLONG, %o0	! ret code = ENAMETOOLONGcs_out:	tst	%o3			! want length?	bz	2f	.empty	sub	%o4, %o2, %o4		! compute length and store it	st	%o4, [%o3]2:	retl	nop				! return (ret code)#ifdef never/* * Transfer data to and from user space - * Note that these routines can cause faults * It is assumed that the kernel has nothing at * less than KERNELBASE in the virtual address space. *//* * Copy kernel data to user space. * * int * copyout(kaddr, uaddr, count) *	caddr_t kaddr, uaddr; *	u_int count; */	ENTRY(copyout)	sethi	%hi(KERNELBASE), %g1	! test uaddr < KERNELBASE	cmp	%o1, %g1	sethi	%hi(copyioerr), %o3	! copyioerr is lofault value	bleu	do_copy			! common code	or	%o3, %lo(copyioerr), %o3	retl				! return (EFAULT)	mov	EFAULT, %o0/* * Copy user data to kernel space. * * int * copyin(uaddr, kaddr, count) *	caddr_t uaddr, kaddr; *	u_int count; */	ENTRY(copyin)	sethi	%hi(KERNELBASE), %g1	! test uaddr < KERNELBASE	cmp	%o0, %g1	sethi	%hi(copyioerr), %o3	! copyioerr is lofault value	bleu	do_copy			! common code	or	%o3, %lo(copyioerr), %o3	retl				! return (EFAULT)	mov	EFAULT, %o0/* * We got here because of a fault during copy{in,out}. */copyioerr:	st	%l6, [_u+U_LOFAULT]	! restore old u.u_lofault	ret	restore	%g0, EFAULT, %o0	! return (EFAULT)/* * Copy a null terminated string from the user address space into * the kernel address space. * * copyinstr(uaddr, kaddr, maxlength, lencopied) *	caddr_t uaddr, kaddr; *	u_int maxlength, *lencopied; */	ENTRY(copyinstr)	sethi	%hi(KERNELBASE), %g1	! test uaddr < KERNELBASE	cmp	%o0, %g1	bgeu	copystrerr	mov	%o7, %o5		! save return addresscs_common:	set	copystrerr, %g1	call	_copystr	st	%g1, [_u+U_LOFAULT]	! catch faults	jmp	%o5 + 8			! return (results of copystr)	clr	[_u+U_LOFAULT]		! clear fault catcher/* * Copy a null terminated string from the kernel * address space to the user address space. * * copyoutstr(kaddr, uaddr, maxlength, lencopied) *	caddr_t kaddr, uaddr; *	u_int maxlength, *lencopied; */	ENTRY(copyoutstr)	sethi	%hi(KERNELBASE), %g1	! test uaddr < KERNELBASE	cmp	%o1, %g1	blu	cs_common	mov	%o7, %o5		! save return address	! fall through/* * Fault while trying to move from or to user space. * Set and return error code. */copystrerr:	mov	EFAULT, %o0	jmp	%o5 + 8			! return (EFAULT)	clr	[_u+U_LOFAULT]/* * Fetch user (long) word. * * int * fuword(addr) *	caddr_t addr; */	ENTRY2(fuword,fuiword)	sethi	%hi(KERNELBASE), %o3	! compare access addr to KERNELBASE	cmp	%o0, %o3		! if (KERNELBASE >= addr) error	bgeu	fsuerr	btst	0x3, %o0		! test alignment	bne	fsuerr	.empty	set	fsuerr, %o3		! set u.u_lofault to catch any fault	st	%o3, [_u+U_LOFAULT]	ld	[%o0], %o0		! get the word	retl	clr	[_u+U_LOFAULT]		! clear u.u_lofault/* * Fetch user byte. * * int * fubyte(addr) *	caddr_t addr; */	ENTRY2(fubyte,fuibyte)	sethi	%hi(KERNELBASE), %o3	! compare access addr to KERNELBASE	cmp	%o0, %o3		! if (KERNELBASE >= addr) error	bgeu	fsuerr	.empty	set	fsuerr, %o3		! set u.u_lofault to catch any fault	st	%o3, [_u+U_LOFAULT]	ldub	[%o0], %o0		! get the byte	retl	clr	[_u+U_LOFAULT]		! clear u.u_lofault/* * Set user (long) word. * * int * suword(addr, value) *	caddr_t addr; *	int value; */	ENTRY2(suword,suiword)	sethi	%hi(KERNELBASE), %o3	! compare access addr to KERNELBASE	cmp	%o0, %o3		! if (KERNELBASE >= addr) error	bgeu	fsuerr	btst	0x3, %o0		! test alignment	bne	fsuerr	.empty	set	fsuerr, %o3		! set u.u_lofault to catch any fault	st	%o3, [_u+U_LOFAULT]	st	%o1, [%o0]		! set the word	b,a	suret/* * Set user byte. * * int * subyte(addr, value) *	caddr_t addr; *	int value; */	ENTRY2(subyte,suibyte)	sethi	%hi(KERNELBASE), %o3	! compare access addr to KERNELBASE	cmp	%o0, %o3		! if (KERNELBASE >= addr) error	bgeu	fsuerr	.empty	set	fsuerr, %o3		! set u.u_lofault to catch any fault	st	%o3, [_u+U_LOFAULT]	stb	%o1, [%o0]		! set the bytesuret:	mov	0, %o0			! indicate success	retl	clr	[_u+U_LOFAULT]		! clear u.u_lofault/* * Fetch user short (half) word. * * int * fusword(addr) *	caddr_t addr; */	ENTRY(fusword)	sethi	%hi(KERNELBASE), %o3	! compare access addr to KERNELBASE	cmp	%o0, %o3		! if (KERNELBASE >= addr) error	bgeu	fsuerr	btst	0x1, %o0		! test alignment	bne	fsuerr	.empty	set	fsuerr, %o3		! set u.u_lofault to catch any fault	st	%o3, [_u+U_LOFAULT]	lduh	[%o0], %o0		! get the half word	retl	clr	[_u+U_LOFAULT]		! clear u.u_lofault/* * Set user short word. * * int * susword(addr, value) *	caddr_t addr; *	int value; */	ENTRY(susword)	sethi	%hi(KERNELBASE), %o3	! compare access addr to KERNELBASE	cmp	%o0, %o3		! if (KERNELBASE >= addr) error	bgeu	fsuerr	btst	0x1, %o0		! test alignment	bne	fsuerr	.empty	set	fsuerr, %o3		! set u.u_lofault to catch any fault	st	%o3, [_u+U_LOFAULT]	sth	%o1, [%o0]		! set the half word	b,a	suretfsuerr:	mov	-1, %o0			! return error	retl	clr	[_u+U_LOFAULT]		! clear u.u_lofault#endif never

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -