xref: /illumos-gate/usr/src/lib/libc/sparc/sys/syscall.S (revision 34bbc83afbf22a6f8e504cb99d76c97c017cb5f4)
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 -- long syscall(int sysnum, ...);
32 * C library -- long __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
711:
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]
1141:
115	stn	%o0, [%i0]	/* no error */
116	clr	%o0
117	stn	%o1, [%i0 + CLONGSIZE]
1182:
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
1441:
145	mov	-1, %o1		/* error */
146	stn	%o1, [%g1]
147	retl
148	  stn	%o1, [%g1 + CLONGSIZE]
149	SET_SIZE(__systemcall6)
150