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