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

📄 scall_o32.s

📁 一个2.4.21版本的嵌入式linux内核
💻 S
字号:
/* * This file is subject to the terms and conditions of the GNU General Public * License.  See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 1997, 1998, 1999, 2000, 2001 by Ralf Baechle * Copyright (C) 2001 MIPS Technologies, Inc. */#include <linux/config.h>#include <linux/errno.h>#include <asm/asm.h>#include <asm/current.h>#include <asm/mipsregs.h>#include <asm/regdef.h>#include <asm/stackframe.h>#include <asm/isadep.h>#include <asm/sysmips.h>#include <asm/unistd.h>/* Highest syscall used of any syscall flavour */#define MAX_SYSCALL_NO	__NR_Linux + __NR_Linux_syscalls	.align  5NESTED(handle_sys, PT_SIZE, sp)	.set	noat	SAVE_SOME	STI	.set	at	lw	t1, PT_EPC(sp)		# skip syscall on return	sltiu	t0, v0, MAX_SYSCALL_NO + 1 # check syscall number	addiu	t1, 4			# skip to next instruction	beqz	t0, illegal_syscall	sw	t1, PT_EPC(sp)	/* XXX Put both in one cacheline, should save a bit. */	sll	t0, v0, 2	lw	t2, sys_call_table(t0)	# syscall routine	lbu	t3, sys_narg_table(v0)	# number of arguments	beqz	t2, illegal_syscall	subu	t0, t3, 5		# 5 or more arguments?	sw	a3, PT_R26(sp)		# save a3 for syscall restarting	bgez	t0, stackargsstack_done:        sw      a3, PT_R26(sp)          # save for syscall restart	lw	t0, TASK_PTRACE($28)	# syscall tracing enabled?	andi	t0, _PT_TRACESYS	bnez	t0, trace_a_syscall	jalr	t2			# Do The Real Thing (TM)	li	t0, -EMAXERRNO - 1	# error?	sltu	t0, t0, v0	sw	t0, PT_R7(sp)		# set error flag	beqz	t0, 1f	negu	v0			# error	sw	v0, PT_R0(sp)		# set flag for syscall restarting1:	sw	v0, PT_R2(sp)		# resultfast_ret_from_sys_call:ret_from_schedule:	mfc0	t0, CP0_STATUS		# need_resched and signals atomic test	ori	t0, t0, 1	xori	t0, t0, 1	mtc0	t0, CP0_STATUS	SSNOP; SSNOP; SSNOP	lw	t2, TASK_NEED_RESCHED($28)	lw	v0, TASK_SIGPENDING($28)	bnez	t2, reschedule	bnez	v0, signal_returnrestore_all:	RESTORE_SOME	RESTORE_SP_AND_RET/* ------------------------------------------------------------------------ */FEXPORT(ret_from_fork)	move	a0, v0			# prev	jal	schedule_tail	lw	t0, TASK_PTRACE($28)	# syscall tracing enabled?	andi	t0, _PT_TRACESYS	bnez	t0, tracesys_exitstatic_ret_from_sys_call:	RESTORE_STATIC	j	fast_ret_from_sys_call/* ------------------------------------------------------------------------ *//* ret_from_sys_call should be here but is in entry.S.  *//* ------------------------------------------------------------------------ *//* Put this behind restore_all for the sake of the branch prediction.  */signal_return:	.type	signal_return, @function	mfc0	t0, CP0_STATUS	ori	t0, t0, 1	mtc0	t0, CP0_STATUS	SAVE_STATIC	move	a0, zero	move	a1, sp	jal	do_signal	RESTORE_STATIC	b	restore_all/* ------------------------------------------------------------------------ */reschedule:	jal	schedule	b	ret_from_schedule/* ------------------------------------------------------------------------ */trace_a_syscall:	SAVE_STATIC	sw	t2, PT_R1(sp)	jal	syscall_trace	lw	t2, PT_R1(sp)	lw	a0, PT_R4(sp)		# Restore argument registers	lw	a1, PT_R5(sp)	lw	a2, PT_R6(sp)	lw	a3, PT_R7(sp)	jalr	t2	li	t0, -EMAXERRNO - 1	# error?	sltu	t0, t0, v0	sw	t0, PT_R7(sp)		# set error flag	beqz	t0, 1f	negu	v0			# error	sw	v0, PT_R0(sp)		# set flag for syscall restarting1:	sw	v0, PT_R2(sp)		# resulttracesys_exit:	jal	syscall_trace	j	static_ret_from_sys_call/* ------------------------------------------------------------------------ */	/*	 * More than four arguments.  Try to deal with it by copying the	 * stack arguments from the user stack to the kernel stack.	 * This Sucks (TM).	 */stackargs:	lw	t0, PT_R29(sp)		# get old user stack pointer	subu	t3, 4	sll	t1, t3, 2		# stack valid?	addu	t1, t0			# end address	or	t0, t1	bltz	t0, bad_stack		# -> sp is bad	lw	t0, PT_R29(sp)		# get old user stack pointer	PTR_LA	t1, 3f			# copy 1 to 2 arguments	sll	t3, t3, 4	subu	t1, t3	jr	t1	/* Ok, copy the args from the luser stack to the kernel stack */	/*	 * I know Ralf doesn't like nops but this avoids code	 * duplication for R3000 targets (and this is the	 * only place where ".set reorder" doesn't help).	 * Harald.	 */	.set    push	.set    noreorder	.set	nomacro1:	lw	t1, 20(t0)		# argument #6 from usp	nop	sw	t1, 20(sp)	nop2:	lw	t1, 16(t0)		# argument #5 from usp	nop	sw	t1, 16(sp)	nop3:	.set	pop	j	stack_done		# go back	.section __ex_table,"a"	PTR	1b,bad_stack	PTR	2b,bad_stack	.previous/* ------------------------------------------------------------------------ */	/*	 * The stackpointer for a call with more than 4 arguments is bad.	 * We probably should handle this case a bit more drastic.	 */bad_stack:	negu	v0			# error	sw	v0, PT_R0(sp)	sw	v0, PT_R2(sp)	li	t0, 1			# set error flag	sw	t0, PT_R7(sp)	j	fast_ret_from_sys_call/* ------------------------------------------------------------------------ */	/*	 * The system call does not exist in this kernel	 */illegal_syscall:	lw	t0, TASK_PTRACE($28)	# syscall tracing enabled?	andi	t0, _PT_TRACESYS	beqz	t0, 1f	SAVE_STATIC	jal	syscall_trace	li	t0, _PT_TRACESYS1:	li	v0, ENOSYS		# error	sw	v0, PT_R0(sp)		# set flag for syscall restarting	sw	v0, PT_R2(sp)	li	t1, 1			# set error flag	sw	t1, PT_R7(sp)	bnez	t0, tracesys_exit	j	fast_ret_from_sys_callEND(handle_sys)LEAF(mips_atomic_set)	andi	v0, a1, 3		# must be word aligned	bnez	v0, bad_alignment	lw	v1, THREAD_CURDS($28)	# in legal address range?	addiu	a0, a1, 4	or	a0, a0, a1	and	a0, a0, v1	bltz	a0, bad_address#ifdef CONFIG_CPU_HAS_LLSC	/* Ok, this is the ll/sc case.  World is sane :-)  */1:	ll	v0, (a1)	move	a0, a22:	sc	a0, (a1)	beqz	a0, 1b	.section __ex_table,"a"	PTR	1b, bad_stack	PTR	2b, bad_stack	.previous#else	sw	a1, 16(sp)	sw	a2, 20(sp)	move	a0, sp	move	a2, a1	li	a1, 1	jal	do_page_fault	lw	a1, 16(sp)	lw	a2, 20(sp)	/*	 * At this point the page should be readable and writable unless	 * there was no more memory available.	 */1:	lw	v0, (a1)2:	sw	a2, (a1)	.section __ex_table,"a"	PTR	1b, no_mem	PTR	2b, no_mem	.previous#endif	sw	zero, PT_R7(sp)		# success	sw	v0, PT_R2(sp)		# result	/* Success, so skip usual error handling garbage.  */	lw	t0, TASK_PTRACE($28)	# syscall tracing enabled?	andi	t0, _PT_TRACESYS	beqz	t0, fast_ret_from_sys_call	SAVE_STATIC	jal	syscall_trace	j	static_ret_from_sys_callno_mem:	li	v0, -ENOMEM	jr	rabad_address:	li	v0, -EFAULT	jr	rabad_alignment:	li	v0, -EINVAL	jr	raEND(mips_atomic_set)LEAF(sys_sysmips)	beq	a0, MIPS_ATOMIC_SET, mips_atomic_set	j	_sys_sysmipsEND(sys_sysmips)LEAF(sys_syscall)	lw	t0, PT_R29(sp)		# user sp	sltu	v0, a0, __NR_Linux + __NR_Linux_syscalls + 1	beqz	v0, enosys	sll	v0, a0, 2	la	v1, sys_syscall	lw	t2, sys_call_table(v0)	# function pointer	lbu	t4, sys_narg_table(a0)	# number of arguments	li	v0, -EINVAL	beq	t2, v1, out		# do not recurse	beqz	t2, enosys		# null function pointer?	andi	v0, t0, 0x3		# unaligned stack pointer?	bnez	v0, sigsegv	addu	v0, t0, 16		# v0 = usp + 16	addu	t1, v0, 12		# 3 32-bit arguments	lw	v1, THREAD_CURDS($28)	or	v0, v0, t1	and	v1, v1, v0	bltz	v1, efault	move	a0, a1			# shift argument registers	move	a1, a2	move	a2, a31:	lw	a3, 16(t0)2:	lw	t3, 20(t0)3:	lw	t4, 24(t0)	.section	__ex_table, "a"	.word	1b, efault	.word	2b, efault	.word	3b, efault	.previous	sw	t3, 16(sp)		# put into new stackframe	sw	t4, 20(sp)	bnez	t4, 1f			# zero arguments?	addu	a0, sp, 32		# then pass sp in a01:	sw	t3, 16(sp)	sw	v1, 20(sp)	jr	t2	/* Unreached */enosys:	li	v0, -ENOSYS	b	outsigsegv:	li	a0, _SIGSEGV	move	a1, $28	jal	force_sig	/* Fall through */efault:	li	v0, -EFAULTout:	jr	raEND(sys_syscall)

⌨️ 快捷键说明

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