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