xref: /onnv-gate/usr/src/lib/libc/sparc/sys/door.s (revision 0:68f95e015346)
1*0Sstevel@tonic-gate/*
2*0Sstevel@tonic-gate * CDDL HEADER START
3*0Sstevel@tonic-gate *
4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate * with the License.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate * and limitations under the License.
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate *
20*0Sstevel@tonic-gate * CDDL HEADER END
21*0Sstevel@tonic-gate */
22*0Sstevel@tonic-gate/*
23*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate * Use is subject to license terms.
25*0Sstevel@tonic-gate */
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gate#pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate
29*0Sstevel@tonic-gate	.file	"%M%"
30*0Sstevel@tonic-gate
31*0Sstevel@tonic-gate#include <sys/asm_linkage.h>
32*0Sstevel@tonic-gate
33*0Sstevel@tonic-gate	/*
34*0Sstevel@tonic-gate	 * weak aliases for public interfaces
35*0Sstevel@tonic-gate	 */
36*0Sstevel@tonic-gate	ANSI_PRAGMA_WEAK(_door_bind,function)
37*0Sstevel@tonic-gate	ANSI_PRAGMA_WEAK(_door_call,function)
38*0Sstevel@tonic-gate	ANSI_PRAGMA_WEAK(_door_getparam,function)
39*0Sstevel@tonic-gate	ANSI_PRAGMA_WEAK(_door_info,function)
40*0Sstevel@tonic-gate	ANSI_PRAGMA_WEAK(_door_revoke,function)
41*0Sstevel@tonic-gate	ANSI_PRAGMA_WEAK(_door_setparam,function)
42*0Sstevel@tonic-gate	ANSI_PRAGMA_WEAK(_door_unbind,function)
43*0Sstevel@tonic-gate
44*0Sstevel@tonic-gate	ANSI_PRAGMA_WEAK(door_bind,function)
45*0Sstevel@tonic-gate	ANSI_PRAGMA_WEAK(door_call,function)
46*0Sstevel@tonic-gate	ANSI_PRAGMA_WEAK(door_getparam,function)
47*0Sstevel@tonic-gate	ANSI_PRAGMA_WEAK(door_info,function)
48*0Sstevel@tonic-gate	ANSI_PRAGMA_WEAK(door_revoke,function)
49*0Sstevel@tonic-gate	ANSI_PRAGMA_WEAK(door_setparam,function)
50*0Sstevel@tonic-gate	ANSI_PRAGMA_WEAK(door_unbind,function)
51*0Sstevel@tonic-gate
52*0Sstevel@tonic-gate#include <sys/door.h>
53*0Sstevel@tonic-gate#include "SYS.h"
54*0Sstevel@tonic-gate
55*0Sstevel@tonic-gate/*
56*0Sstevel@tonic-gate * Offsets within struct door_results
57*0Sstevel@tonic-gate */
58*0Sstevel@tonic-gate#define	DOOR_COOKIE	(SA(MINFRAME) + STACK_BIAS + 0*CLONGSIZE)
59*0Sstevel@tonic-gate#define	DOOR_DATA_PTR	(SA(MINFRAME) + STACK_BIAS + 1*CLONGSIZE)
60*0Sstevel@tonic-gate#define	DOOR_DATA_SIZE	(SA(MINFRAME) + STACK_BIAS + 2*CLONGSIZE)
61*0Sstevel@tonic-gate#define	DOOR_DESC_PTR	(SA(MINFRAME) + STACK_BIAS + 3*CLONGSIZE)
62*0Sstevel@tonic-gate#define	DOOR_DESC_SIZE	(SA(MINFRAME) + STACK_BIAS + 4*CLONGSIZE)
63*0Sstevel@tonic-gate#define	DOOR_PC		(SA(MINFRAME) + STACK_BIAS + 5*CLONGSIZE)
64*0Sstevel@tonic-gate#define	DOOR_SERVERS	(SA(MINFRAME) + STACK_BIAS + 6*CLONGSIZE)
65*0Sstevel@tonic-gate#define	DOOR_INFO_PTR	(SA(MINFRAME) + STACK_BIAS + 7*CLONGSIZE)
66*0Sstevel@tonic-gate
67*0Sstevel@tonic-gate/*
68*0Sstevel@tonic-gate * All of the syscalls except door_return() follow the same pattern.  The
69*0Sstevel@tonic-gate * subcode goes in %o5, after all of the other arguments.
70*0Sstevel@tonic-gate */
71*0Sstevel@tonic-gate#define	DOOR_SYSCALL(name, code)					\
72*0Sstevel@tonic-gate	ENTRY(name);							\
73*0Sstevel@tonic-gate	mov	code, %o5;		/* subcode */			\
74*0Sstevel@tonic-gate	SYSTRAP_RVAL1(door);						\
75*0Sstevel@tonic-gate	SYSCERROR;							\
76*0Sstevel@tonic-gate	RET;								\
77*0Sstevel@tonic-gate	SET_SIZE(name)
78*0Sstevel@tonic-gate
79*0Sstevel@tonic-gate	DOOR_SYSCALL(__door_bind,	DOOR_BIND)
80*0Sstevel@tonic-gate	DOOR_SYSCALL(__door_call,	DOOR_CALL)
81*0Sstevel@tonic-gate	DOOR_SYSCALL(__door_create,	DOOR_CREATE)
82*0Sstevel@tonic-gate	DOOR_SYSCALL(__door_getparam,	DOOR_GETPARAM)
83*0Sstevel@tonic-gate	DOOR_SYSCALL(__door_info,	DOOR_INFO)
84*0Sstevel@tonic-gate	DOOR_SYSCALL(__door_revoke,	DOOR_REVOKE)
85*0Sstevel@tonic-gate	DOOR_SYSCALL(__door_setparam,	DOOR_SETPARAM)
86*0Sstevel@tonic-gate	DOOR_SYSCALL(__door_ucred,	DOOR_UCRED)
87*0Sstevel@tonic-gate	DOOR_SYSCALL(__door_unbind,	DOOR_UNBIND)
88*0Sstevel@tonic-gate	DOOR_SYSCALL(__door_unref,	DOOR_UNREFSYS)
89*0Sstevel@tonic-gate
90*0Sstevel@tonic-gate/*
91*0Sstevel@tonic-gate * int
92*0Sstevel@tonic-gate * __door_return(
93*0Sstevel@tonic-gate *	void 			*data_ptr,
94*0Sstevel@tonic-gate *	size_t			data_size,	(in bytes)
95*0Sstevel@tonic-gate *	door_return_desc_t	*door_ptr,	(holds returned desc info)
96*0Sstevel@tonic-gate *	caddr_t			stack_base,
97*0Sstevel@tonic-gate *	size_t			stack_size)
98*0Sstevel@tonic-gate */
99*0Sstevel@tonic-gate	ENTRY(__door_return)
100*0Sstevel@tonic-gatedoor_restart:
101*0Sstevel@tonic-gate	mov	DOOR_RETURN, %o5	/* subcode */
102*0Sstevel@tonic-gate	SYSTRAP_RVAL1(door)
103*0Sstevel@tonic-gate	bcs,pn	%icc, 2f			/* errno is set */
104*0Sstevel@tonic-gate	ld	[%sp + DOOR_SERVERS], %g1	/* (delay) load nservers */
105*0Sstevel@tonic-gate	/*
106*0Sstevel@tonic-gate	 * On return, we're serving a door_call.  Our stack looks like this:
107*0Sstevel@tonic-gate	 *
108*0Sstevel@tonic-gate	 *		descriptors (if any)
109*0Sstevel@tonic-gate	 *		data (if any)
110*0Sstevel@tonic-gate	 *		struct door_results
111*0Sstevel@tonic-gate	 *		MINFRAME
112*0Sstevel@tonic-gate	 *	sp ->
113*0Sstevel@tonic-gate	 */
114*0Sstevel@tonic-gate	tst	%g1				/* test nservers */
115*0Sstevel@tonic-gate	bg	1f				/* everything looks o.k. */
116*0Sstevel@tonic-gate	ldn	[%sp + DOOR_COOKIE], %o0	/* (delay) load cookie */
117*0Sstevel@tonic-gate	/*
118*0Sstevel@tonic-gate	 * this is the last server thread - call creation func for more
119*0Sstevel@tonic-gate	 */
120*0Sstevel@tonic-gate	save	%sp, -SA(MINFRAME), %sp
121*0Sstevel@tonic-gate	PIC_SETUP(g1)
122*0Sstevel@tonic-gate#ifdef __sparcv9
123*0Sstevel@tonic-gate	sethi	%hi(door_server_func), %g5
124*0Sstevel@tonic-gate	or	%g5, %lo(door_server_func), %g5
125*0Sstevel@tonic-gate	ldn	[%g5 + %g1], %g1
126*0Sstevel@tonic-gate#else
127*0Sstevel@tonic-gate	ldn	[%g1 + door_server_func], %g1
128*0Sstevel@tonic-gate#endif
129*0Sstevel@tonic-gate	ldn	[%g1], %g1
130*0Sstevel@tonic-gate	jmpl	%g1, %o7			/* call create function */
131*0Sstevel@tonic-gate	ldn	[%fp + DOOR_INFO_PTR], %o0	/* (delay) load door_info ptr */
132*0Sstevel@tonic-gate	restore
133*0Sstevel@tonic-gate1:
134*0Sstevel@tonic-gate	/* Call the door server function now */
135*0Sstevel@tonic-gate	ldn	[%sp + DOOR_DATA_PTR], %o1
136*0Sstevel@tonic-gate	ldn	[%sp + DOOR_DATA_SIZE], %o2
137*0Sstevel@tonic-gate	ldn	[%sp + DOOR_DESC_PTR], %o3
138*0Sstevel@tonic-gate	ldn	[%sp + DOOR_PC], %g1
139*0Sstevel@tonic-gate	jmpl	%g1, %o7
140*0Sstevel@tonic-gate	ldn	[%sp + DOOR_DESC_SIZE], %o4
141*0Sstevel@tonic-gate
142*0Sstevel@tonic-gate	/* Exit the thread if we return here */
143*0Sstevel@tonic-gate	call	_thr_terminate
144*0Sstevel@tonic-gate	mov	%g0, %o0
145*0Sstevel@tonic-gate	/* NOTREACHED */
146*0Sstevel@tonic-gate2:
147*0Sstevel@tonic-gate	/*
148*0Sstevel@tonic-gate	 * Error during door_return call.  Repark the thread in the kernel if
149*0Sstevel@tonic-gate	 * the error code is EINTR (or ERESTART) and this lwp is still part
150*0Sstevel@tonic-gate	 * of the same process.
151*0Sstevel@tonic-gate	 */
152*0Sstevel@tonic-gate	cmp	%o0, ERESTART		/* ERESTART is same as EINTR */
153*0Sstevel@tonic-gate	be,a	3f
154*0Sstevel@tonic-gate	mov	EINTR, %o0
155*0Sstevel@tonic-gate3:
156*0Sstevel@tonic-gate	cmp	%o0, EINTR		/* interrupted while waiting? */
157*0Sstevel@tonic-gate	bne	__cerror		/* if not, return the error */
158*0Sstevel@tonic-gate	nop
159*0Sstevel@tonic-gate
160*0Sstevel@tonic-gate	save	%sp, -SA(MINFRAME), %sp
161*0Sstevel@tonic-gate	call	_private_getpid		/* get current process id */
162*0Sstevel@tonic-gate	nop
163*0Sstevel@tonic-gate	PIC_SETUP(g1)
164*0Sstevel@tonic-gate#ifdef __sparcv9
165*0Sstevel@tonic-gate	sethi	%hi(door_create_pid), %g5
166*0Sstevel@tonic-gate	or	%g5, %lo(door_create_pid), %g5
167*0Sstevel@tonic-gate	ldn	[%g1 + %g5], %g1
168*0Sstevel@tonic-gate#else
169*0Sstevel@tonic-gate	ldn	[%g1 + door_create_pid], %g1
170*0Sstevel@tonic-gate#endif
171*0Sstevel@tonic-gate	ld	[%g1], %g1
172*0Sstevel@tonic-gate	cmp	%o0, %g1		/* same process? */
173*0Sstevel@tonic-gate	mov	EINTR, %o0	/* if no, return EINTR (child of forkall) */
174*0Sstevel@tonic-gate	bne	__cerror
175*0Sstevel@tonic-gate	restore
176*0Sstevel@tonic-gate
177*0Sstevel@tonic-gate	clr	%o0			/* clear arguments and restart */
178*0Sstevel@tonic-gate	clr	%o1
179*0Sstevel@tonic-gate	ba	door_restart
180*0Sstevel@tonic-gate	clr	%o2
181*0Sstevel@tonic-gate	SET_SIZE(__door_return)
182