xref: /titanic_52/usr/src/lib/libc/i386/sys/door.s (revision 49b225e1cfa7bbf7738d4df0a03f18e3283426eb)
17c478bd9Sstevel@tonic-gate/*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5a574db85Sraf * Common Development and Distribution License (the "License").
6a574db85Sraf * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
21a574db85Sraf
227c478bd9Sstevel@tonic-gate/*
23*49b225e1SGavin Maltby * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
279a70fc3bSMark J. Nelson	.file	"door.s"
287c478bd9Sstevel@tonic-gate
297257d1b4Sraf#include "SYS.h"
307257d1b4Sraf#include <sys/door.h>
317c478bd9Sstevel@tonic-gate
327c478bd9Sstevel@tonic-gate	/*
337c478bd9Sstevel@tonic-gate	 * weak aliases for public interfaces
347c478bd9Sstevel@tonic-gate	 */
357257d1b4Sraf	ANSI_PRAGMA_WEAK2(door_bind,__door_bind,function)
367257d1b4Sraf	ANSI_PRAGMA_WEAK2(door_getparam,__door_getparam,function)
377257d1b4Sraf	ANSI_PRAGMA_WEAK2(door_info,__door_info,function)
387257d1b4Sraf	ANSI_PRAGMA_WEAK2(door_revoke,__door_revoke,function)
397257d1b4Sraf	ANSI_PRAGMA_WEAK2(door_setparam,__door_setparam,function)
407c478bd9Sstevel@tonic-gate
417c478bd9Sstevel@tonic-gate/*
427c478bd9Sstevel@tonic-gate * Offsets within struct door_results
437c478bd9Sstevel@tonic-gate */
447c478bd9Sstevel@tonic-gate#define	DOOR_COOKIE	_MUL(0, CLONGSIZE)
457c478bd9Sstevel@tonic-gate#define	DOOR_DATA_PTR	_MUL(1, CLONGSIZE)
467c478bd9Sstevel@tonic-gate#define	DOOR_DATA_SIZE	_MUL(2, CLONGSIZE)
477c478bd9Sstevel@tonic-gate#define	DOOR_DESC_PTR	_MUL(3, CLONGSIZE)
487c478bd9Sstevel@tonic-gate#define	DOOR_DESC_SIZE	_MUL(4, CLONGSIZE)
497c478bd9Sstevel@tonic-gate#define	DOOR_PC		_MUL(5, CLONGSIZE)
507c478bd9Sstevel@tonic-gate#define	DOOR_SERVERS	_MUL(6, CLONGSIZE)
517c478bd9Sstevel@tonic-gate#define	DOOR_INFO_PTR	_MUL(7, CLONGSIZE)
527c478bd9Sstevel@tonic-gate
537c478bd9Sstevel@tonic-gate/*
547c478bd9Sstevel@tonic-gate * All of the syscalls except door_return() follow the same pattern.
557c478bd9Sstevel@tonic-gate * The subcode goes in argument 6, which means we have to copy our
567c478bd9Sstevel@tonic-gate * arguments into a new bit of stack, large enough to include the
577c478bd9Sstevel@tonic-gate * subcode.  We fill the unused positions with zeros.
587c478bd9Sstevel@tonic-gate */
597c478bd9Sstevel@tonic-gate#define	DOOR_SYSCALL(name, code, copy_args)				\
607c478bd9Sstevel@tonic-gate	ENTRY(name);							\
617c478bd9Sstevel@tonic-gate	pushl	%ebp;							\
627c478bd9Sstevel@tonic-gate	movl	%esp, %ebp;						\
637c478bd9Sstevel@tonic-gate	pushl	$code;		/* syscall subcode, arg 6 */		\
647c478bd9Sstevel@tonic-gate	pushl	$0;		/* dummy arg 5 */			\
657c478bd9Sstevel@tonic-gate	pushl	$0;		/* dummy arg 4 */			\
667c478bd9Sstevel@tonic-gate	copy_args;		/* args 1, 2, 3 */			\
677c478bd9Sstevel@tonic-gate	pushl	$0;		/* dummy return PC */			\
687c478bd9Sstevel@tonic-gate	SYSTRAP_RVAL1(door);						\
697c478bd9Sstevel@tonic-gate	jae	1f;							\
707c478bd9Sstevel@tonic-gate	addl	$28, %esp;						\
717c478bd9Sstevel@tonic-gate	leave;								\
727c478bd9Sstevel@tonic-gate	jmp	__cerror;						\
737c478bd9Sstevel@tonic-gate1:									\
747c478bd9Sstevel@tonic-gate	addl	$28, %esp;						\
757c478bd9Sstevel@tonic-gate	leave;								\
767c478bd9Sstevel@tonic-gate	ret;								\
777c478bd9Sstevel@tonic-gate	SET_SIZE(name)
787c478bd9Sstevel@tonic-gate
797c478bd9Sstevel@tonic-gate#define	COPY_0								\
807c478bd9Sstevel@tonic-gate	pushl	$0;		/* dummy */				\
817c478bd9Sstevel@tonic-gate	pushl	$0;		/* dummy */				\
827c478bd9Sstevel@tonic-gate	pushl	$0		/* dummy */
837c478bd9Sstevel@tonic-gate
847c478bd9Sstevel@tonic-gate#define	COPY_1								\
857c478bd9Sstevel@tonic-gate	pushl	$0;		/* dummy */				\
867c478bd9Sstevel@tonic-gate	pushl	$0;		/* dummy */				\
877c478bd9Sstevel@tonic-gate	pushl	8(%ebp)		/* 1 */
887c478bd9Sstevel@tonic-gate
897c478bd9Sstevel@tonic-gate#define	COPY_2								\
907c478bd9Sstevel@tonic-gate	pushl	$0;		/* dummy */				\
917c478bd9Sstevel@tonic-gate	pushl	12(%ebp);	/* 2 */					\
927c478bd9Sstevel@tonic-gate	pushl	8(%ebp)		/* 1 */
937c478bd9Sstevel@tonic-gate
947c478bd9Sstevel@tonic-gate#define	COPY_3								\
957c478bd9Sstevel@tonic-gate	pushl	16(%ebp);	/* 3 */					\
967c478bd9Sstevel@tonic-gate	pushl	12(%ebp);	/* 2 */					\
977c478bd9Sstevel@tonic-gate	pushl	8(%ebp)		/* 1 */
987c478bd9Sstevel@tonic-gate
997c478bd9Sstevel@tonic-gate	DOOR_SYSCALL(__door_bind,	DOOR_BIND,	COPY_1)
1007c478bd9Sstevel@tonic-gate	DOOR_SYSCALL(__door_call,	DOOR_CALL,	COPY_2)
1017c478bd9Sstevel@tonic-gate	DOOR_SYSCALL(__door_create,	DOOR_CREATE,	COPY_3)
1027c478bd9Sstevel@tonic-gate	DOOR_SYSCALL(__door_getparam,	DOOR_GETPARAM,	COPY_3)
1037c478bd9Sstevel@tonic-gate	DOOR_SYSCALL(__door_info,	DOOR_INFO,	COPY_2)
1047c478bd9Sstevel@tonic-gate	DOOR_SYSCALL(__door_revoke,	DOOR_REVOKE,	COPY_1)
1057c478bd9Sstevel@tonic-gate	DOOR_SYSCALL(__door_setparam,	DOOR_SETPARAM,	COPY_3)
1067c478bd9Sstevel@tonic-gate	DOOR_SYSCALL(__door_ucred,	DOOR_UCRED,	COPY_1)
1077c478bd9Sstevel@tonic-gate	DOOR_SYSCALL(__door_unbind,	DOOR_UNBIND,	COPY_0)
1087c478bd9Sstevel@tonic-gate	DOOR_SYSCALL(__door_unref,	DOOR_UNREFSYS,	COPY_0)
1097c478bd9Sstevel@tonic-gate
1107c478bd9Sstevel@tonic-gate/*
1117c478bd9Sstevel@tonic-gate * int
1127c478bd9Sstevel@tonic-gate * __door_return(
1137c478bd9Sstevel@tonic-gate *	void 			*data_ptr,
1147c478bd9Sstevel@tonic-gate *	size_t			data_size,	(in bytes)
1157c478bd9Sstevel@tonic-gate *	door_return_desc_t	*door_ptr,	(holds returned desc info)
1167c478bd9Sstevel@tonic-gate *	caddr_t			stack_base,
1177c478bd9Sstevel@tonic-gate *	size_t			stack_size)
1187c478bd9Sstevel@tonic-gate */
1197c478bd9Sstevel@tonic-gate	ENTRY(__door_return)
1207c478bd9Sstevel@tonic-gate	movl	%esp, %edx		/ Save pointer to args
1217c478bd9Sstevel@tonic-gate
1227c478bd9Sstevel@tonic-gate	pushl	%edi			/ save old %edi and %esi
1237c478bd9Sstevel@tonic-gate	pushl	%esi			/ and use them to hold the
1247c478bd9Sstevel@tonic-gate	movl	16(%edx), %esi		/ stack pointer and
1257c478bd9Sstevel@tonic-gate	movl	20(%edx), %edi		/ size.
1267c478bd9Sstevel@tonic-gate
1277c478bd9Sstevel@tonic-gate	pushl	$DOOR_RETURN		/ syscall subcode
1287c478bd9Sstevel@tonic-gate	pushl	%edi			/ size of user stack
1297c478bd9Sstevel@tonic-gate	pushl	%esi			/ base of user stack
1307c478bd9Sstevel@tonic-gate	pushl	12(%edx)		/ desc arguments ptr
1317c478bd9Sstevel@tonic-gate	pushl	8(%edx)			/ data size
1327c478bd9Sstevel@tonic-gate	pushl	4(%edx)			/ data ptr
1337c478bd9Sstevel@tonic-gate	pushl	0(%edx)			/ dummy return PC
1347c478bd9Sstevel@tonic-gate
1357c478bd9Sstevel@tonic-gatedoor_restart:
1367c478bd9Sstevel@tonic-gate	SYSTRAP_RVAL1(door)
137c4ace179Sdm120769	jb	2f			/* errno is set */
1387c478bd9Sstevel@tonic-gate	/*
1397c478bd9Sstevel@tonic-gate	 * On return, we're serving a door_call.  Our stack looks like this:
1407c478bd9Sstevel@tonic-gate	 *
1417c478bd9Sstevel@tonic-gate	 *		descriptors (if any)
1427c478bd9Sstevel@tonic-gate	 *		data (if any)
1437c478bd9Sstevel@tonic-gate	 *	 sp->	struct door_results
1447c478bd9Sstevel@tonic-gate	 *
1457c478bd9Sstevel@tonic-gate	 * struct door_results has the arguments in place for the server proc,
1467c478bd9Sstevel@tonic-gate	 * so we just call it directly.
1477c478bd9Sstevel@tonic-gate	 */
1487c478bd9Sstevel@tonic-gate	movl	DOOR_SERVERS(%esp), %eax
1497c478bd9Sstevel@tonic-gate	andl	%eax, %eax	/* test nservers */
1507c478bd9Sstevel@tonic-gate	jg	1f
1517c478bd9Sstevel@tonic-gate	/*
1527c478bd9Sstevel@tonic-gate	 * this is the last server thread - call creation func for more
1537c478bd9Sstevel@tonic-gate	 */
1547c478bd9Sstevel@tonic-gate	movl	DOOR_INFO_PTR(%esp), %eax
1557c478bd9Sstevel@tonic-gate	pushl	%eax		/* door_info_t * */
156*49b225e1SGavin Maltby	call	door_depletion_cb@PLT
1577c478bd9Sstevel@tonic-gate	addl	$4, %esp
1587c478bd9Sstevel@tonic-gate1:
1597c478bd9Sstevel@tonic-gate	/* Call the door server function now */
1607c478bd9Sstevel@tonic-gate	movl	DOOR_PC(%esp), %eax
1617c478bd9Sstevel@tonic-gate	call	*%eax
1627c478bd9Sstevel@tonic-gate	/* Exit the thread if we return here */
1637c478bd9Sstevel@tonic-gate	pushl	$0
1647257d1b4Sraf	call	_thrp_terminate
1657c478bd9Sstevel@tonic-gate	/* NOTREACHED */
166c4ace179Sdm1207692:
1677c478bd9Sstevel@tonic-gate	/*
1687c478bd9Sstevel@tonic-gate	 * Error during door_return call.  Repark the thread in the kernel if
1697c478bd9Sstevel@tonic-gate	 * the error code is EINTR (or ERESTART) and this lwp is still part
1707c478bd9Sstevel@tonic-gate	 * of the same process.
1717c478bd9Sstevel@tonic-gate	 *
1727c478bd9Sstevel@tonic-gate	 * If the error code is EINTR or ERESTART, our stack may have been
1737c478bd9Sstevel@tonic-gate	 * corrupted by a partial door call, so we refresh the system call
1747c478bd9Sstevel@tonic-gate	 * arguments.
1757c478bd9Sstevel@tonic-gate	 */
1767c478bd9Sstevel@tonic-gate	cmpl	$ERESTART, %eax		/* ERESTART is same as EINTR */
177c4ace179Sdm120769	jne	3f
1787c478bd9Sstevel@tonic-gate	movl	$EINTR, %eax
179c4ace179Sdm1207693:
1807c478bd9Sstevel@tonic-gate	cmpl	$EINTR, %eax		/* interrupted while waiting? */
181c4ace179Sdm120769	jne	4f			/* if not, return the error */
1827c478bd9Sstevel@tonic-gate	_prologue_
1838cd45542Sraf	call	getpid
1847c478bd9Sstevel@tonic-gate	movl	_daref_(door_create_pid), %edx
1857c478bd9Sstevel@tonic-gate	movl	0(%edx), %edx
1867c478bd9Sstevel@tonic-gate	_epilogue_
1877c478bd9Sstevel@tonic-gate	cmpl	%eax, %edx		/* same process? */
1887c478bd9Sstevel@tonic-gate	movl	$EINTR, %eax	/* if no, return EINTR (child of forkall) */
189c4ace179Sdm120769	jne	4f
1907c478bd9Sstevel@tonic-gate	movl	$0, 4(%esp)		/* clear arguments and restart */
1917c478bd9Sstevel@tonic-gate	movl	$0, 8(%esp)
1927c478bd9Sstevel@tonic-gate	movl	$0, 12(%esp)
1937c478bd9Sstevel@tonic-gate	movl	%esi, 16(%esp)		/* refresh sp */
1947c478bd9Sstevel@tonic-gate	movl	%edi, 20(%esp)		/* refresh ssize */
1957c478bd9Sstevel@tonic-gate	movl	$DOOR_RETURN, 24(%esp)	/* refresh syscall subcode */
1967c478bd9Sstevel@tonic-gate	jmp	door_restart
197c4ace179Sdm1207694:
1987c478bd9Sstevel@tonic-gate	/* Something bad happened during the door_return */
1997c478bd9Sstevel@tonic-gate	addl	$28, %esp
2007c478bd9Sstevel@tonic-gate	popl	%esi
2017c478bd9Sstevel@tonic-gate	popl	%edi
2027c478bd9Sstevel@tonic-gate	jmp	__cerror
2037c478bd9Sstevel@tonic-gate	SET_SIZE(__door_return)
204