syscall.s revision 2
2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A
2N/A/*
2N/A * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A/* Copyright (c) 1988 AT&T */
2N/A/* All Rights Reserved */
2N/A
2N/A/*
2N/A * C library -- int syscall(int sysnum, ...);
2N/A * C library -- int __systemcall(sysret_t *, int sysnum, ...);
2N/A *
2N/A * Interpret a given system call
2N/A *
2N/A * This version handles up to 8 'long' arguments to a system call.
2N/A *
2N/A * Even though indirect system call support exists in the SPARC
2N/A * 32-bit kernel, we want to eliminate it in a future release,
2N/A * so the real trap for the desired system call is issued right here.
2N/A *
2N/A * Even though %g5 can be used as a scratch register for sparcv9, we don't
2N/A * use it here because this code is shared between sparcv8 and sparcv9.
2N/A */
2N/A
2N/A .file "syscall.s"
2N/A
2N/A#include "SYS.h"
2N/A
2N/A ANSI_PRAGMA_WEAK(syscall,function)
2N/A
2N/A ENTRY(syscall)
2N/A save %sp, -SA(MINFRAME + 2*CLONGSIZE), %sp
2N/A ldn [%fp + STACK_BIAS + MINFRAME], %o5 ! arg 5
2N/A mov %i3, %o2 ! arg 2
2N/A ldn [%fp + STACK_BIAS + MINFRAME + CLONGSIZE], %g1
2N/A mov %i4, %o3 ! arg 3
2N/A stn %g1, [%sp + STACK_BIAS + MINFRAME] ! arg 6
2N/A mov %i5, %o4 ! arg 4
2N/A ldn [%fp + STACK_BIAS + MINFRAME + 2*CLONGSIZE], %g1
2N/A mov %i1, %o0 ! arg 0
2N/A stn %g1, [%sp + STACK_BIAS + MINFRAME + CLONGSIZE] ! arg 7
2N/A mov %i2, %o1 ! arg 1
2N/A mov %i0, %g1 ! sysnum
2N/A ta SYSCALL_TRAPNUM
2N/A bcc,a,pt %icc, 1f
2N/A sra %o0, 0, %i0 ! (int) cast
2N/A restore %o0, 0, %o0
2N/A ba __cerror
2N/A nop
2N/A1:
2N/A ret
2N/A restore
2N/A SET_SIZE(syscall)
2N/A
2N/A/*
2N/A * Same as _syscall(), but restricted to 6 syscall arguments
2N/A * so it doesn't need to incur the overhead of a register window.
2N/A * Implemented for use only within libc; symbol is not exported.
2N/A */
2N/A ENTRY(_syscall6)
2N/A mov %o0, %g1 /* sysnum */
2N/A mov %o1, %o0 /* syscall args */
2N/A mov %o2, %o1
2N/A mov %o3, %o2
2N/A mov %o4, %o3
2N/A mov %o5, %o4
2N/A ldn [%sp + STACK_BIAS + MINFRAME], %o5
2N/A ta SYSCALL_TRAPNUM
2N/A SYSCERROR
2N/A retl
2N/A sra %o0, 0, %o0 /* (int) cast */
2N/A SET_SIZE(_syscall6)
2N/A
2N/A ENTRY(__systemcall)
2N/A save %sp, -SA(MINFRAME + 2*CLONGSIZE), %sp
2N/A ldn [%fp + STACK_BIAS + MINFRAME], %o4 ! arg 4
2N/A mov %i3, %o1 ! arg 1
2N/A ldn [%fp + STACK_BIAS + MINFRAME + CLONGSIZE], %o5 ! arg5
2N/A mov %i4, %o2 ! arg 2
2N/A ldn [%fp + STACK_BIAS + MINFRAME + 2*CLONGSIZE], %g1
2N/A mov %i5, %o3 ! arg 3
2N/A stn %g1, [%sp + STACK_BIAS + MINFRAME] ! arg 6
2N/A mov %i2, %o0 ! arg 0
2N/A ldn [%fp + STACK_BIAS + MINFRAME + 3*CLONGSIZE], %g1
2N/A stn %g1, [%sp + STACK_BIAS + MINFRAME + CLONGSIZE] ! arg7
2N/A mov %i1, %g1 ! sysnum
2N/A ta SYSCALL_TRAPNUM
2N/A bcc,pt %icc, 1f
2N/A mov -1, %g1
2N/A stn %g1, [%i0] /* error */
2N/A ba 2f
2N/A stn %g1, [%i0 + CLONGSIZE]
2N/A1:
2N/A stn %o0, [%i0] /* no error */
2N/A clr %o0
2N/A stn %o1, [%i0 + CLONGSIZE]
2N/A2:
2N/A ret
2N/A restore %o0, 0, %o0
2N/A SET_SIZE(__systemcall)
2N/A
2N/A/*
2N/A * Same as __systemcall(), but restricted to 6 syscall arguments
2N/A * so it doesn't need to incur the overhead of a register window.
2N/A * Implemented for use only within libc; symbol is not exported.
2N/A */
2N/A ENTRY(__systemcall6)
2N/A stn %o0, [%sp + SAVE_OFFSET] /* sysret address */
2N/A mov %o1, %g1 /* sysnum */
2N/A mov %o2, %o0 /* syscall args */
2N/A mov %o3, %o1
2N/A mov %o4, %o2
2N/A mov %o5, %o3
2N/A ldn [%sp + STACK_BIAS + MINFRAME], %o4
2N/A ldn [%sp + STACK_BIAS + MINFRAME + CLONGSIZE], %o5
2N/A ta SYSCALL_TRAPNUM
2N/A bcs,pn %icc, 1f
2N/A ldn [%sp + SAVE_OFFSET], %g1
2N/A stn %o0, [%g1] /* no error */
2N/A stn %o1, [%g1 + CLONGSIZE]
2N/A retl
2N/A clr %o0
2N/A1:
2N/A mov -1, %o1 /* error */
2N/A stn %o1, [%g1]
2N/A retl
2N/A stn %o1, [%g1 + CLONGSIZE]
2N/A SET_SIZE(__systemcall6)
2N/A