xref: /onnv-gate/usr/src/lib/libc/sparc/sys/door.s (revision 11102:b91faef0c984)
10Sstevel@tonic-gate/*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
55891Sraf * Common Development and Distribution License (the "License").
65891Sraf * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
215891Sraf
220Sstevel@tonic-gate/*
23*11102SGavin.Maltby@Sun.COM * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
277298SMark.J.Nelson@Sun.COM	.file	"door.s"
280Sstevel@tonic-gate
296812Sraf#include "SYS.h"
306812Sraf#include <sys/door.h>
310Sstevel@tonic-gate
320Sstevel@tonic-gate	/*
330Sstevel@tonic-gate	 * weak aliases for public interfaces
340Sstevel@tonic-gate	 */
356812Sraf	ANSI_PRAGMA_WEAK2(door_bind,__door_bind,function)
366812Sraf	ANSI_PRAGMA_WEAK2(door_getparam,__door_getparam,function)
376812Sraf	ANSI_PRAGMA_WEAK2(door_info,__door_info,function)
386812Sraf	ANSI_PRAGMA_WEAK2(door_revoke,__door_revoke,function)
396812Sraf	ANSI_PRAGMA_WEAK2(door_setparam,__door_setparam,function)
400Sstevel@tonic-gate
410Sstevel@tonic-gate/*
420Sstevel@tonic-gate * Offsets within struct door_results
430Sstevel@tonic-gate */
440Sstevel@tonic-gate#define	DOOR_COOKIE	(SA(MINFRAME) + STACK_BIAS + 0*CLONGSIZE)
450Sstevel@tonic-gate#define	DOOR_DATA_PTR	(SA(MINFRAME) + STACK_BIAS + 1*CLONGSIZE)
460Sstevel@tonic-gate#define	DOOR_DATA_SIZE	(SA(MINFRAME) + STACK_BIAS + 2*CLONGSIZE)
470Sstevel@tonic-gate#define	DOOR_DESC_PTR	(SA(MINFRAME) + STACK_BIAS + 3*CLONGSIZE)
480Sstevel@tonic-gate#define	DOOR_DESC_SIZE	(SA(MINFRAME) + STACK_BIAS + 4*CLONGSIZE)
490Sstevel@tonic-gate#define	DOOR_PC		(SA(MINFRAME) + STACK_BIAS + 5*CLONGSIZE)
500Sstevel@tonic-gate#define	DOOR_SERVERS	(SA(MINFRAME) + STACK_BIAS + 6*CLONGSIZE)
510Sstevel@tonic-gate#define	DOOR_INFO_PTR	(SA(MINFRAME) + STACK_BIAS + 7*CLONGSIZE)
520Sstevel@tonic-gate
530Sstevel@tonic-gate/*
540Sstevel@tonic-gate * All of the syscalls except door_return() follow the same pattern.  The
550Sstevel@tonic-gate * subcode goes in %o5, after all of the other arguments.
560Sstevel@tonic-gate */
570Sstevel@tonic-gate#define	DOOR_SYSCALL(name, code)					\
580Sstevel@tonic-gate	ENTRY(name);							\
590Sstevel@tonic-gate	mov	code, %o5;		/* subcode */			\
600Sstevel@tonic-gate	SYSTRAP_RVAL1(door);						\
610Sstevel@tonic-gate	SYSCERROR;							\
620Sstevel@tonic-gate	RET;								\
630Sstevel@tonic-gate	SET_SIZE(name)
640Sstevel@tonic-gate
650Sstevel@tonic-gate	DOOR_SYSCALL(__door_bind,	DOOR_BIND)
660Sstevel@tonic-gate	DOOR_SYSCALL(__door_call,	DOOR_CALL)
670Sstevel@tonic-gate	DOOR_SYSCALL(__door_create,	DOOR_CREATE)
680Sstevel@tonic-gate	DOOR_SYSCALL(__door_getparam,	DOOR_GETPARAM)
690Sstevel@tonic-gate	DOOR_SYSCALL(__door_info,	DOOR_INFO)
700Sstevel@tonic-gate	DOOR_SYSCALL(__door_revoke,	DOOR_REVOKE)
710Sstevel@tonic-gate	DOOR_SYSCALL(__door_setparam,	DOOR_SETPARAM)
720Sstevel@tonic-gate	DOOR_SYSCALL(__door_ucred,	DOOR_UCRED)
730Sstevel@tonic-gate	DOOR_SYSCALL(__door_unbind,	DOOR_UNBIND)
740Sstevel@tonic-gate	DOOR_SYSCALL(__door_unref,	DOOR_UNREFSYS)
750Sstevel@tonic-gate
760Sstevel@tonic-gate/*
770Sstevel@tonic-gate * int
780Sstevel@tonic-gate * __door_return(
790Sstevel@tonic-gate *	void 			*data_ptr,
800Sstevel@tonic-gate *	size_t			data_size,	(in bytes)
810Sstevel@tonic-gate *	door_return_desc_t	*door_ptr,	(holds returned desc info)
820Sstevel@tonic-gate *	caddr_t			stack_base,
830Sstevel@tonic-gate *	size_t			stack_size)
840Sstevel@tonic-gate */
850Sstevel@tonic-gate	ENTRY(__door_return)
860Sstevel@tonic-gatedoor_restart:
870Sstevel@tonic-gate	mov	DOOR_RETURN, %o5	/* subcode */
880Sstevel@tonic-gate	SYSTRAP_RVAL1(door)
895540Sdm120769	bcs,pn	%icc, 2f			/* errno is set */
900Sstevel@tonic-gate	ld	[%sp + DOOR_SERVERS], %g1	/* (delay) load nservers */
910Sstevel@tonic-gate	/*
920Sstevel@tonic-gate	 * On return, we're serving a door_call.  Our stack looks like this:
930Sstevel@tonic-gate	 *
940Sstevel@tonic-gate	 *		descriptors (if any)
950Sstevel@tonic-gate	 *		data (if any)
960Sstevel@tonic-gate	 *		struct door_results
970Sstevel@tonic-gate	 *		MINFRAME
980Sstevel@tonic-gate	 *	sp ->
990Sstevel@tonic-gate	 */
1000Sstevel@tonic-gate	tst	%g1				/* test nservers */
1010Sstevel@tonic-gate	bg	1f				/* everything looks o.k. */
1020Sstevel@tonic-gate	ldn	[%sp + DOOR_COOKIE], %o0	/* (delay) load cookie */
1030Sstevel@tonic-gate	/*
1040Sstevel@tonic-gate	 * this is the last server thread - call creation func for more
1050Sstevel@tonic-gate	 */
1060Sstevel@tonic-gate	save	%sp, -SA(MINFRAME), %sp
107*11102SGavin.Maltby@Sun.COM	call	door_depletion_cb
1080Sstevel@tonic-gate	ldn	[%fp + DOOR_INFO_PTR], %o0	/* (delay) load door_info ptr */
1090Sstevel@tonic-gate	restore
1100Sstevel@tonic-gate1:
1110Sstevel@tonic-gate	/* Call the door server function now */
1120Sstevel@tonic-gate	ldn	[%sp + DOOR_DATA_PTR], %o1
1130Sstevel@tonic-gate	ldn	[%sp + DOOR_DATA_SIZE], %o2
1140Sstevel@tonic-gate	ldn	[%sp + DOOR_DESC_PTR], %o3
1150Sstevel@tonic-gate	ldn	[%sp + DOOR_PC], %g1
1160Sstevel@tonic-gate	jmpl	%g1, %o7
1170Sstevel@tonic-gate	ldn	[%sp + DOOR_DESC_SIZE], %o4
1180Sstevel@tonic-gate
1190Sstevel@tonic-gate	/* Exit the thread if we return here */
1206812Sraf	call	_thrp_terminate
1210Sstevel@tonic-gate	mov	%g0, %o0
1220Sstevel@tonic-gate	/* NOTREACHED */
1235540Sdm1207692:
1240Sstevel@tonic-gate	/*
1250Sstevel@tonic-gate	 * Error during door_return call.  Repark the thread in the kernel if
1260Sstevel@tonic-gate	 * the error code is EINTR (or ERESTART) and this lwp is still part
1275540Sdm120769	 * of the same process.
1280Sstevel@tonic-gate	 */
1290Sstevel@tonic-gate	cmp	%o0, ERESTART		/* ERESTART is same as EINTR */
1305540Sdm120769	be,a	3f
1310Sstevel@tonic-gate	mov	EINTR, %o0
1325540Sdm1207693:
1330Sstevel@tonic-gate	cmp	%o0, EINTR		/* interrupted while waiting? */
1340Sstevel@tonic-gate	bne	__cerror		/* if not, return the error */
1350Sstevel@tonic-gate	nop
1360Sstevel@tonic-gate
1370Sstevel@tonic-gate	save	%sp, -SA(MINFRAME), %sp
1386515Sraf	call	getpid
1390Sstevel@tonic-gate	nop
1400Sstevel@tonic-gate	PIC_SETUP(g1)
1410Sstevel@tonic-gate#ifdef __sparcv9
1420Sstevel@tonic-gate	sethi	%hi(door_create_pid), %g5
1430Sstevel@tonic-gate	or	%g5, %lo(door_create_pid), %g5
1440Sstevel@tonic-gate	ldn	[%g1 + %g5], %g1
1450Sstevel@tonic-gate#else
1460Sstevel@tonic-gate	ldn	[%g1 + door_create_pid], %g1
1470Sstevel@tonic-gate#endif
1480Sstevel@tonic-gate	ld	[%g1], %g1
1490Sstevel@tonic-gate	cmp	%o0, %g1		/* same process? */
1500Sstevel@tonic-gate	mov	EINTR, %o0	/* if no, return EINTR (child of forkall) */
1510Sstevel@tonic-gate	bne	__cerror
1520Sstevel@tonic-gate	restore
1530Sstevel@tonic-gate
1540Sstevel@tonic-gate	clr	%o0			/* clear arguments and restart */
1550Sstevel@tonic-gate	clr	%o1
1560Sstevel@tonic-gate	ba	door_restart
1570Sstevel@tonic-gate	clr	%o2
1580Sstevel@tonic-gate	SET_SIZE(__door_return)
159