Home | History | Annotate | Download | only in sys
      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 2009 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 	.file	"door.s"
     28 
     29 #include "SYS.h"
     30 #include <sys/door.h>
     31 
     32 	/*
     33 	 * weak aliases for public interfaces
     34 	 */
     35 	ANSI_PRAGMA_WEAK2(door_bind,__door_bind,function)
     36 	ANSI_PRAGMA_WEAK2(door_getparam,__door_getparam,function)
     37 	ANSI_PRAGMA_WEAK2(door_info,__door_info,function)
     38 	ANSI_PRAGMA_WEAK2(door_revoke,__door_revoke,function)
     39 	ANSI_PRAGMA_WEAK2(door_setparam,__door_setparam,function)
     40 
     41 /*
     42  * Offsets within struct door_results
     43  */
     44 #define	DOOR_COOKIE	(SA(MINFRAME) + STACK_BIAS + 0*CLONGSIZE)
     45 #define	DOOR_DATA_PTR	(SA(MINFRAME) + STACK_BIAS + 1*CLONGSIZE)
     46 #define	DOOR_DATA_SIZE	(SA(MINFRAME) + STACK_BIAS + 2*CLONGSIZE)
     47 #define	DOOR_DESC_PTR	(SA(MINFRAME) + STACK_BIAS + 3*CLONGSIZE)
     48 #define	DOOR_DESC_SIZE	(SA(MINFRAME) + STACK_BIAS + 4*CLONGSIZE)
     49 #define	DOOR_PC		(SA(MINFRAME) + STACK_BIAS + 5*CLONGSIZE)
     50 #define	DOOR_SERVERS	(SA(MINFRAME) + STACK_BIAS + 6*CLONGSIZE)
     51 #define	DOOR_INFO_PTR	(SA(MINFRAME) + STACK_BIAS + 7*CLONGSIZE)
     52 
     53 /*
     54  * All of the syscalls except door_return() follow the same pattern.  The
     55  * subcode goes in %o5, after all of the other arguments.
     56  */
     57 #define	DOOR_SYSCALL(name, code)					\
     58 	ENTRY(name);							\
     59 	mov	code, %o5;		/* subcode */			\
     60 	SYSTRAP_RVAL1(door);						\
     61 	SYSCERROR;							\
     62 	RET;								\
     63 	SET_SIZE(name)
     64 
     65 	DOOR_SYSCALL(__door_bind,	DOOR_BIND)
     66 	DOOR_SYSCALL(__door_call,	DOOR_CALL)
     67 	DOOR_SYSCALL(__door_create,	DOOR_CREATE)
     68 	DOOR_SYSCALL(__door_getparam,	DOOR_GETPARAM)
     69 	DOOR_SYSCALL(__door_info,	DOOR_INFO)
     70 	DOOR_SYSCALL(__door_revoke,	DOOR_REVOKE)
     71 	DOOR_SYSCALL(__door_setparam,	DOOR_SETPARAM)
     72 	DOOR_SYSCALL(__door_ucred,	DOOR_UCRED)
     73 	DOOR_SYSCALL(__door_unbind,	DOOR_UNBIND)
     74 	DOOR_SYSCALL(__door_unref,	DOOR_UNREFSYS)
     75 
     76 /*
     77  * int
     78  * __door_return(
     79  *	void 			*data_ptr,
     80  *	size_t			data_size,	(in bytes)
     81  *	door_return_desc_t	*door_ptr,	(holds returned desc info)
     82  *	caddr_t			stack_base,
     83  *	size_t			stack_size)
     84  */
     85 	ENTRY(__door_return)
     86 door_restart:
     87 	mov	DOOR_RETURN, %o5	/* subcode */
     88 	SYSTRAP_RVAL1(door)
     89 	bcs,pn	%icc, 2f			/* errno is set */
     90 	ld	[%sp + DOOR_SERVERS], %g1	/* (delay) load nservers */
     91 	/*
     92 	 * On return, we're serving a door_call.  Our stack looks like this:
     93 	 *
     94 	 *		descriptors (if any)
     95 	 *		data (if any)
     96 	 *		struct door_results
     97 	 *		MINFRAME
     98 	 *	sp ->
     99 	 */
    100 	tst	%g1				/* test nservers */
    101 	bg	1f				/* everything looks o.k. */
    102 	ldn	[%sp + DOOR_COOKIE], %o0	/* (delay) load cookie */
    103 	/*
    104 	 * this is the last server thread - call creation func for more
    105 	 */
    106 	save	%sp, -SA(MINFRAME), %sp
    107 	call	door_depletion_cb
    108 	ldn	[%fp + DOOR_INFO_PTR], %o0	/* (delay) load door_info ptr */
    109 	restore
    110 1:
    111 	/* Call the door server function now */
    112 	ldn	[%sp + DOOR_DATA_PTR], %o1
    113 	ldn	[%sp + DOOR_DATA_SIZE], %o2
    114 	ldn	[%sp + DOOR_DESC_PTR], %o3
    115 	ldn	[%sp + DOOR_PC], %g1
    116 	jmpl	%g1, %o7
    117 	ldn	[%sp + DOOR_DESC_SIZE], %o4
    118 
    119 	/* Exit the thread if we return here */
    120 	call	_thrp_terminate
    121 	mov	%g0, %o0
    122 	/* NOTREACHED */
    123 2:
    124 	/*
    125 	 * Error during door_return call.  Repark the thread in the kernel if
    126 	 * the error code is EINTR (or ERESTART) and this lwp is still part
    127 	 * of the same process.
    128 	 */
    129 	cmp	%o0, ERESTART		/* ERESTART is same as EINTR */
    130 	be,a	3f
    131 	mov	EINTR, %o0
    132 3:
    133 	cmp	%o0, EINTR		/* interrupted while waiting? */
    134 	bne	__cerror		/* if not, return the error */
    135 	nop
    136 
    137 	save	%sp, -SA(MINFRAME), %sp
    138 	call	getpid
    139 	nop
    140 	PIC_SETUP(g1)
    141 #ifdef __sparcv9
    142 	sethi	%hi(door_create_pid), %g5
    143 	or	%g5, %lo(door_create_pid), %g5
    144 	ldn	[%g1 + %g5], %g1
    145 #else
    146 	ldn	[%g1 + door_create_pid], %g1
    147 #endif
    148 	ld	[%g1], %g1
    149 	cmp	%o0, %g1		/* same process? */
    150 	mov	EINTR, %o0	/* if no, return EINTR (child of forkall) */
    151 	bne	__cerror
    152 	restore
    153 
    154 	clr	%o0			/* clear arguments and restart */
    155 	clr	%o1
    156 	ba	door_restart
    157 	clr	%o2
    158 	SET_SIZE(__door_return)
    159