Home | History | Annotate | Download | only in sys
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 /*	Copyright (c) 1988 AT&T	*/
     28 /*	  All Rights Reserved	*/
     29 
     30 /*
     31  * C library -- int syscall(int sysnum, ...);
     32  * C library -- int __systemcall(sysret_t *, int sysnum, ...);
     33  *
     34  * Interpret a given system call
     35  *
     36  * This version handles up to 8 'long' arguments to a system call.
     37  *
     38  * Even though indirect system call support exists in the SPARC
     39  * 32-bit kernel, we want to eliminate it in a future release,
     40  * so the real trap for the desired system call is issued right here.
     41  *
     42  * Even though %g5 can be used as a scratch register for sparcv9, we don't
     43  * use it here because this code is shared between sparcv8 and sparcv9.
     44  */
     45 
     46 	.file	"syscall.s"
     47 
     48 #include "SYS.h"
     49 
     50 	ANSI_PRAGMA_WEAK(syscall,function)
     51 
     52 	ENTRY(syscall)
     53 	save	%sp, -SA(MINFRAME + 2*CLONGSIZE), %sp
     54 	ldn	[%fp + STACK_BIAS + MINFRAME], %o5	! arg 5
     55 	mov	%i3, %o2				! arg 2
     56 	ldn	[%fp + STACK_BIAS + MINFRAME + CLONGSIZE], %g1
     57 	mov	%i4, %o3				! arg 3
     58 	stn	%g1, [%sp + STACK_BIAS + MINFRAME]	! arg 6
     59 	mov	%i5, %o4				! arg 4
     60 	ldn	[%fp + STACK_BIAS + MINFRAME + 2*CLONGSIZE], %g1
     61 	mov	%i1, %o0				! arg 0
     62 	stn	%g1, [%sp + STACK_BIAS + MINFRAME + CLONGSIZE] ! arg 7
     63 	mov	%i2, %o1				! arg 1
     64 	mov	%i0, %g1				! sysnum
     65 	ta	SYSCALL_TRAPNUM
     66 	bcc,a,pt %icc, 1f
     67 	  sra	%o0, 0, %i0				! (int) cast
     68 	restore	%o0, 0, %o0
     69 	ba	__cerror
     70 	  nop
     71 1:
     72 	ret
     73 	  restore
     74 	SET_SIZE(syscall)
     75 
     76 /*
     77  * Same as _syscall(), but restricted to 6 syscall arguments
     78  * so it doesn't need to incur the overhead of a register window.
     79  * Implemented for use only within libc; symbol is not exported.
     80  */
     81 	ENTRY(_syscall6)
     82 	mov	%o0, %g1			/* sysnum */
     83 	mov	%o1, %o0			/* syscall args */
     84 	mov	%o2, %o1
     85 	mov	%o3, %o2
     86 	mov	%o4, %o3
     87 	mov	%o5, %o4
     88 	ldn	[%sp + STACK_BIAS + MINFRAME], %o5
     89 	ta	SYSCALL_TRAPNUM
     90 	SYSCERROR
     91 	retl
     92 	  sra	%o0, 0, %o0			/* (int) cast */
     93 	SET_SIZE(_syscall6)
     94 
     95 	ENTRY(__systemcall)
     96 	save	%sp, -SA(MINFRAME + 2*CLONGSIZE), %sp
     97 	ldn	[%fp + STACK_BIAS + MINFRAME], %o4	! arg 4
     98 	mov	%i3, %o1				! arg 1
     99 	ldn	[%fp + STACK_BIAS + MINFRAME + CLONGSIZE], %o5 ! arg5
    100 	mov	%i4, %o2				! arg 2
    101 	ldn	[%fp + STACK_BIAS + MINFRAME + 2*CLONGSIZE], %g1
    102 	mov	%i5, %o3				! arg 3
    103 	stn	%g1, [%sp + STACK_BIAS + MINFRAME]	! arg 6
    104 	mov	%i2, %o0				! arg 0
    105 	ldn	[%fp + STACK_BIAS + MINFRAME + 3*CLONGSIZE], %g1
    106 	stn	%g1, [%sp + STACK_BIAS + MINFRAME + CLONGSIZE] ! arg7
    107 	mov	%i1, %g1				! sysnum
    108 	ta	SYSCALL_TRAPNUM
    109 	bcc,pt	%icc, 1f
    110 	  mov	-1, %g1
    111 	stn	%g1, [%i0]	/* error */
    112 	ba	2f
    113 	  stn	%g1, [%i0 + CLONGSIZE]
    114 1:
    115 	stn	%o0, [%i0]	/* no error */
    116 	clr	%o0
    117 	stn	%o1, [%i0 + CLONGSIZE]
    118 2:
    119 	ret
    120 	  restore %o0, 0, %o0
    121 	SET_SIZE(__systemcall)
    122 
    123 /*
    124  * Same as __systemcall(), but restricted to 6 syscall arguments
    125  * so it doesn't need to incur the overhead of a register window.
    126  * Implemented for use only within libc; symbol is not exported.
    127  */
    128 	ENTRY(__systemcall6)
    129 	stn	%o0, [%sp + SAVE_OFFSET]	/* sysret address */
    130 	mov	%o1, %g1			/* sysnum */
    131 	mov	%o2, %o0			/* syscall args */
    132 	mov	%o3, %o1
    133 	mov	%o4, %o2
    134 	mov	%o5, %o3
    135 	ldn	[%sp + STACK_BIAS + MINFRAME], %o4
    136 	ldn	[%sp + STACK_BIAS + MINFRAME + CLONGSIZE], %o5
    137 	ta	SYSCALL_TRAPNUM
    138 	bcs,pn	%icc, 1f
    139 	  ldn	[%sp + SAVE_OFFSET], %g1
    140 	stn	%o0, [%g1]	/* no error */
    141 	stn	%o1, [%g1 + CLONGSIZE]
    142 	retl
    143 	  clr	%o0
    144 1:
    145 	mov	-1, %o1		/* error */
    146 	stn	%o1, [%g1]
    147 	retl
    148 	  stn	%o1, [%g1 + CLONGSIZE]
    149 	SET_SIZE(__systemcall6)
    150