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