import less(1)
[unleashed/tickless.git] / usr / src / lib / libc / i386 / sys / door.s
blob1e5561c3870ba6aa4b8419e21a08ca2f9c46af18
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 .file "door.s"
29 #include "SYS.h"
30 #include <sys/door.h>
33 * weak aliases for public interfaces
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)
42 * Offsets within struct door_results
44 #define DOOR_COOKIE _MUL(0, CLONGSIZE)
45 #define DOOR_DATA_PTR _MUL(1, CLONGSIZE)
46 #define DOOR_DATA_SIZE _MUL(2, CLONGSIZE)
47 #define DOOR_DESC_PTR _MUL(3, CLONGSIZE)
48 #define DOOR_DESC_SIZE _MUL(4, CLONGSIZE)
49 #define DOOR_PC _MUL(5, CLONGSIZE)
50 #define DOOR_SERVERS _MUL(6, CLONGSIZE)
51 #define DOOR_INFO_PTR _MUL(7, CLONGSIZE)
54 * All of the syscalls except door_return() follow the same pattern.
55 * The subcode goes in argument 6, which means we have to copy our
56 * arguments into a new bit of stack, large enough to include the
57 * subcode. We fill the unused positions with zeros.
59 #define DOOR_SYSCALL(name, code, copy_args) \
60 ENTRY(name); \
61 pushl %ebp; \
62 movl %esp, %ebp; \
63 pushl $code; /* syscall subcode, arg 6 */ \
64 pushl $0; /* dummy arg 5 */ \
65 pushl $0; /* dummy arg 4 */ \
66 copy_args; /* args 1, 2, 3 */ \
67 pushl $0; /* dummy return PC */ \
68 SYSTRAP_RVAL1(door); \
69 jae 1f; \
70 addl $28, %esp; \
71 leave; \
72 jmp __cerror; \
73 1: \
74 addl $28, %esp; \
75 leave; \
76 ret; \
77 SET_SIZE(name)
79 #define COPY_0 \
80 pushl $0; /* dummy */ \
81 pushl $0; /* dummy */ \
82 pushl $0 /* dummy */
84 #define COPY_1 \
85 pushl $0; /* dummy */ \
86 pushl $0; /* dummy */ \
87 pushl 8(%ebp) /* 1 */
89 #define COPY_2 \
90 pushl $0; /* dummy */ \
91 pushl 12(%ebp); /* 2 */ \
92 pushl 8(%ebp) /* 1 */
94 #define COPY_3 \
95 pushl 16(%ebp); /* 3 */ \
96 pushl 12(%ebp); /* 2 */ \
97 pushl 8(%ebp) /* 1 */
99 DOOR_SYSCALL(__door_bind, DOOR_BIND, COPY_1)
100 DOOR_SYSCALL(__door_call, DOOR_CALL, COPY_2)
101 DOOR_SYSCALL(__door_create, DOOR_CREATE, COPY_3)
102 DOOR_SYSCALL(__door_getparam, DOOR_GETPARAM, COPY_3)
103 DOOR_SYSCALL(__door_info, DOOR_INFO, COPY_2)
104 DOOR_SYSCALL(__door_revoke, DOOR_REVOKE, COPY_1)
105 DOOR_SYSCALL(__door_setparam, DOOR_SETPARAM, COPY_3)
106 DOOR_SYSCALL(__door_ucred, DOOR_UCRED, COPY_1)
107 DOOR_SYSCALL(__door_unbind, DOOR_UNBIND, COPY_0)
108 DOOR_SYSCALL(__door_unref, DOOR_UNREFSYS, COPY_0)
111 * int
112 * __door_return(
113 * void *data_ptr,
114 * size_t data_size, (in bytes)
115 * door_return_desc_t *door_ptr, (holds returned desc info)
116 * caddr_t stack_base,
117 * size_t stack_size)
119 ENTRY(__door_return)
120 movl %esp, %edx / Save pointer to args
122 pushl %edi / save old %edi and %esi
123 pushl %esi / and use them to hold the
124 movl 16(%edx), %esi / stack pointer and
125 movl 20(%edx), %edi / size.
127 pushl $DOOR_RETURN / syscall subcode
128 pushl %edi / size of user stack
129 pushl %esi / base of user stack
130 pushl 12(%edx) / desc arguments ptr
131 pushl 8(%edx) / data size
132 pushl 4(%edx) / data ptr
133 pushl 0(%edx) / dummy return PC
135 door_restart:
136 SYSTRAP_RVAL1(door)
137 jb 2f /* errno is set */
139 * On return, we're serving a door_call. Our stack looks like this:
141 * descriptors (if any)
142 * data (if any)
143 * sp-> struct door_results
145 * struct door_results has the arguments in place for the server proc,
146 * so we just call it directly.
148 movl DOOR_SERVERS(%esp), %eax
149 andl %eax, %eax /* test nservers */
150 jg 1f
152 * this is the last server thread - call creation func for more
154 movl DOOR_INFO_PTR(%esp), %eax
155 pushl %eax /* door_info_t * */
156 call door_depletion_cb@PLT
157 addl $4, %esp
159 /* Call the door server function now */
160 movl DOOR_PC(%esp), %eax
161 call *%eax
162 /* Exit the thread if we return here */
163 pushl $0
164 call _thrp_terminate
165 /* NOTREACHED */
168 * Error during door_return call. Repark the thread in the kernel if
169 * the error code is EINTR (or ERESTART) and this lwp is still part
170 * of the same process.
172 * If the error code is EINTR or ERESTART, our stack may have been
173 * corrupted by a partial door call, so we refresh the system call
174 * arguments.
176 cmpl $ERESTART, %eax /* ERESTART is same as EINTR */
177 jne 3f
178 movl $EINTR, %eax
180 cmpl $EINTR, %eax /* interrupted while waiting? */
181 jne 4f /* if not, return the error */
182 _prologue_
183 call getpid
184 movl _daref_(door_create_pid), %edx
185 movl 0(%edx), %edx
186 _epilogue_
187 cmpl %eax, %edx /* same process? */
188 movl $EINTR, %eax /* if no, return EINTR (child of forkall) */
189 jne 4f
190 movl $0, 4(%esp) /* clear arguments and restart */
191 movl $0, 8(%esp)
192 movl $0, 12(%esp)
193 movl %esi, 16(%esp) /* refresh sp */
194 movl %edi, 20(%esp) /* refresh ssize */
195 movl $DOOR_RETURN, 24(%esp) /* refresh syscall subcode */
196 jmp door_restart
198 /* Something bad happened during the door_return */
199 addl $28, %esp
200 popl %esi
201 popl %edi
202 jmp __cerror
203 SET_SIZE(__door_return)