2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
27 * Mach RPC Subsystem Interfaces
33 #include <mach/boolean.h>
34 #include <mach/kern_return.h>
35 #include <mach/port.h>
36 #include <mach/vm_types.h>
39 #include <mach/mig_errors.h>
40 #include <mach/machine/rpc.h>
41 #include <mach/thread_status.h>
43 #ifdef MACH_KERNEL_PRIVATE
44 #include <ipc/ipc_object.h>
45 #endif /* MACH_KERNEL_PRIVATE */
48 * The various bits of the type field of the routine_arg_descriptor
54 #define MACH_RPC_PORT (1 << TYPE_SHIFT)
55 #define MACH_RPC_ARRAY (1 << (TYPE_SHIFT + 1))
56 #define MACH_RPC_VARIABLE (1 << (TYPE_SHIFT + 2))
57 #define LAST_TYPE_BIT (TYPE_SHIFT+3)
59 /* XXX Port arrays need not be variable arrays, as assumed below. Fixme. */
60 #define MACH_RPC_ARRAY_FIX (MACH_RPC_ARRAY)
61 #define MACH_RPC_ARRAY_FIXED (MACH_RPC_ARRAY)
62 #define MACH_RPC_ARRAY_VAR (MACH_RPC_ARRAY | MACH_RPC_VARIABLE)
63 #define MACH_RPC_ARRAY_VARIABLE (MACH_RPC_ARRAY | MACH_RPC_VARIABLE)
64 #define MACH_RPC_PORT_ARRAY (MACH_RPC_PORT | MACH_RPC_ARRAY_VAR)
66 /* Argument direction bits */
68 #define DIRECT_SHIFT LAST_TYPE_BIT
69 #define DIRECTION_SHIFT LAST_TYPE_BIT
70 #define MACH_RPC_IN (1 << DIRECTION_SHIFT)
71 #define MACH_RPC_OUT (1 << (DIRECTION_SHIFT + 1))
72 #define LAST_DIRECT_BIT (DIRECTION_SHIFT + 2)
73 #define LAST_DIRECTION_BIT (DIRECTION_SHIFT + 2)
75 #define MACH_RPC_INOUT (MACH_RPC_IN | MACH_RPC_OUT)
77 /* Persist and pointer bit */
79 #define POINTER_SHIFT LAST_DIRECTION_BIT
80 #define MACH_RPC_POINTER (1 << POINTER_SHIFT)
81 #define LAST_POINTER_BIT (POINTER_SHIFT + 1)
83 /* Port disposition bits */
85 #define NAME_SHIFT LAST_POINTER_BIT
86 #define MACH_RPC_RECEIVE (1 << NAME_SHIFT)
87 #define MACH_RPC_SEND (2 << NAME_SHIFT)
88 #define MACH_RPC_SEND_ONCE (3 << NAME_SHIFT)
89 #define LAST_NAME_BIT (NAME_SHIFT + 2)
91 #define ACTION_SHIFT LAST_NAME_BIT
92 #define MACH_RPC_MOVE (1 << ACTION_SHIFT)
93 #define MACH_RPC_COPY (2 << ACTION_SHIFT)
94 #define MACH_RPC_MAKE (3 << ACTION_SHIFT)
95 #define LAST_ACTION_BIT (ACTION_SHIFT + 2)
97 #define MACH_RPC_MOVE_RECEIVE (MACH_RPC_MOVE | MACH_RPC_RECEIVE)
98 #define MACH_RPC_MOVE_SEND (MACH_RPC_MOVE | MACH_RPC_SEND)
99 #define MACH_RPC_COPY_SEND (MACH_RPC_COPY | MACH_RPC_SEND)
100 #define MACH_RPC_MAKE_SEND (MACH_RPC_MAKE | MACH_RPC_SEND)
101 #define MACH_RPC_MOVE_SEND_ONCE (MACH_RPC_MOVE | MACH_RPC_SEND_ONCE)
102 #define MACH_RPC_MAKE_SEND_ONCE (MACH_RPC_MAKE | MACH_RPC_SEND_ONCE)
104 /* Hint for virtual vs. physical copy */
106 #define OPTION_SHIFT LAST_ACTION_BIT
107 #define MACH_RPC_PHYSICAL_COPY (1 << OPTION_SHIFT)
108 #define MACH_RPC_VIRTUAL_COPY (1 << (OPTION_SHIFT + 1))
109 #define LAST_OPTION_BIT (OPTION_SHIFT + 2)
113 #define DEALLOCATE_SHIFT LAST_OPTION_BIT
114 #define MACH_RPC_DEALLOCATE (1 << DEALLOCATE_SHIFT)
115 #define LAST_DEALLOCATE_BIT (DEALLOCATE_SHIFT + 1)
117 /* Argument is already on the stack */
119 #define ONSTACK_SHIFT LAST_DEALLOCATE_BIT
120 #define MACH_RPC_ONSTACK (1 << ONSTACK_SHIFT)
121 #define LAST_ONSTACK_BIT (ONSTACK_SHIFT + 1)
123 /* Is variable array bounded? Derived from type and arg.size */
125 #define BOUND_SHIFT LAST_ONSTACK_BIT
126 #define MACH_RPC_BOUND (1 << BOUND_SHIFT)
127 #define MACH_RPC_UNBOUND (0)
128 #define BOUND MACH_RPC_BOUND
129 #define UNBND MACH_RPC_UNBOUND
130 #define LAST_BOUND_BIT (BOUND_SHIFT + 1)
133 * Basic mach rpc types.
135 typedef unsigned int routine_arg_type
;
136 typedef unsigned int routine_arg_offset
;
137 typedef unsigned int routine_arg_size
;
140 * Definitions for a signature's argument and routine descriptor's.
142 struct routine_arg_descriptor
{
143 routine_arg_type type
; /* Port, Array, etc. */
144 routine_arg_size size
; /* element size in bytes */
145 routine_arg_size count
; /* number of elements */
146 routine_arg_offset offset
; /* Offset in list of routine args */
148 typedef struct routine_arg_descriptor
*routine_arg_descriptor_t
;
150 struct routine_descriptor
{
151 mig_impl_routine_t impl_routine
; /* Server work func pointer */
152 mig_stub_routine_t stub_routine
; /* Unmarshalling func pointer */
153 unsigned int argc
; /* Number of argument words */
154 unsigned int descr_count
; /* Number of complex argument */
156 struct routine_arg_descriptor
*
157 arg_descr
; /* Pointer to beginning of */
158 /* the arg_descr array */
159 unsigned int max_reply_msg
; /* Max size for reply msg */
161 typedef struct routine_descriptor
*routine_descriptor_t
;
163 #define DESCR_SIZE(x) ((x)->descr_count * sizeof(struct routine_arg_descriptor))
165 struct rpc_signature
{
166 struct routine_descriptor rd
;
167 struct routine_arg_descriptor rad
[1];
170 #ifdef MACH_KERNEL_PRIVATE
172 typedef struct rpc_signature
*rpc_signature_t
;
176 #define RPC_SIGBUF_SIZE 8
178 * A subsystem describes a set of server routines that can be invoked by
179 * mach_rpc() on the ports that are registered with the subsystem. For
180 * each routine, the routine number is given, along with the
181 * address of the implementation function in the server and a
182 * description of the arguments of the routine (it's "signature").
184 * This structure definition is only a template for what is really a
185 * variable-length structure (generated by MIG for each subsystem).
186 * The actual structures do not always have one entry in the routine
187 * array, and also have a varying number of entries in the arg_descr
188 * array. Each routine has an array of zero or more arg descriptors
189 * one for each complex arg. These arrays are all catenated together
190 * to form the arg_descr field of the subsystem struct. The
191 * arg_descr field of each routine entry points to a unique sub-sequence
192 * within this catenated array. The goal is to keep everything
195 struct rpc_subsystem
{
196 struct subsystem
*subsystem
; /* Reserved for system use */
198 mach_msg_id_t start
; /* Min routine number */
199 mach_msg_id_t end
; /* Max routine number + 1 */
200 unsigned int maxsize
; /* Max mach_msg size */
201 vm_address_t base_addr
; /* Address of this struct in user */
203 struct routine_descriptor
/* Array of routine descriptors */
204 routine
[1 /* Actually, (start-end+1) */
207 struct routine_arg_descriptor
208 arg_descriptor
[1 /* Actually, the sum of the descr_ */
209 ]; /* count fields for all routines */
211 typedef struct rpc_subsystem
*rpc_subsystem_t
;
213 #define RPC_SUBSYSTEM_NULL ((rpc_subsystem_t) 0)
216 * New RPC declarations
218 * First pass at definitions and types for the new rpc service.
219 * This is subject to revision.
226 #define RPC_MASK(shift,last) \
227 ( ((1 << ((last)-(shift)))-1) << (shift) )
229 #define RPC_FIELD(field,shift,last) \
230 ( (field) & (((1 << ((last)-(shift)))-1) << (shift)) )
232 #define RPC_BOUND(dsc) \
233 (((RPC_FIELD((dsc).type,TYPE_SHIFT+1,TYPE_SHIFT+3) == \
234 MACH_RPC_ARRAY_VARIABLE) && (dsc).count != 0) ? MACH_RPC_BOUND : 0)
236 #define ROUNDUP2(x,n) ((((unsigned)(x)) + (n) - 1) & ~((n)-1))
237 #define ROUNDWORD(x) ROUNDUP2(x,sizeof(int))
242 * Display and process errors of different severity, from just for
243 * information only to fatal (panic). Error code colors indicate how
244 * difficult it is for the subsystem to handle the error correctly.
245 * The implication is that, for example, early versions of the code may
246 * not be handling code red errors properly. The code should use this
247 * facility instead of regular printf's.
250 #define MACH_RPC_DEBUG 1
252 #define ERR_INFO 1 /* purely informational */
253 #define ERR_GREEN 2 /* easily handled error */
254 #define ERR_YELLOW 3 /* medium difficult error */
255 #define ERR_RED 4 /* difficult to handle error */
256 #define ERR_FATAL 5 /* unrecoverable error, panic */
258 #if MACH_RPC_DEBUG > 1
259 #define rpc_error(E,S) \
260 printf("RPC error "); \
261 rpc_error_show_severity(S); \
262 printf("in file \"%s\", line %d: ", __FILE__, __LINE__); \
265 rpc_error_severity(S)
267 #define rpc_error(E,S) \
268 if ((S) == ERR_FATAL || (S) == ERR_RED) { \
269 printf("RPC error "); \
270 rpc_error_show_severity(S); \
271 printf("in file \"%s\", line %d: ", __FILE__, __LINE__); \
274 rpc_error_severity(S); \
276 #endif /* MACH_RPC_DEBUG */
279 * RPC buffer size and break points
281 * These values define the rpc buffer size on the kernel stack,
282 * and break point values for switching to virtual copy (cow).
283 * This should be in a machine dependent include file. All sizes
284 * are in word (sizeof(int)) units.
287 #define RPC_KBUF_SIZE 16 /* kernel stack buffer size (ints) */
288 #define RPC_COW_SIZE 1024 /* size where COW is a win (ints) */
289 #define RPC_DESC_COUNT 4 /* default descriptor count */
295 * Record the rpc copy state for arrays, so we can unwind our state
296 * during error processing. There is one entry per complex (signatured)
297 * argument. The first entry is marked COPY_TYPE_ALLOC_KRN if this record
298 * itself was kalloc'd because the number of complex arg descriptors
299 * exceeded the default value (RPC_DESC_COUNT). This is not a conflict
300 * since the first argument is always the destination port, never an array.
303 #define COPY_TYPE_NO_COPY 0 /* nothing special */
304 #define COPY_TYPE_ON_KSTACK 1 /* array is on kernel stack */
305 #define COPY_TYPE_ON_SSTACK 2 /* array is on server stack */
306 #define COPY_TYPE_VIRTUAL_IN 3 /* vm_map_copyin part of cow */
307 #define COPY_TYPE_VIRTUAL_OUT_SVR 4 /* map cpyout svr part of cow */
308 #define COPY_TYPE_VIRTUAL_OUT_CLN 5 /* map cpyout cln part of cow */
309 #define COPY_TYPE_ALLOC_KRN 6 /* kernel kalloc'd for array */
310 #define COPY_TYPE_ALLOC_SVR 7 /* vm_alloc'd in server space */
311 #define COPY_TYPE_ALLOC_CLN 8 /* vm_alloc'd in client space */
312 #define COPY_TYPE_PORT 9 /* plain port translated */
313 #define COPY_TYPE_PORT_ARRAY 10 /* port array translated */
319 typedef int rpc_id_t
;
320 typedef int rpc_return_t
;
321 typedef unsigned int rpc_size_t
;
322 typedef unsigned int rpc_offset_t
;
324 struct rpc_copy_state
{
325 unsigned copy_type
; /* what kind of copy */
326 vm_offset_t alloc_addr
; /* address to free */
328 typedef struct rpc_copy_state
*rpc_copy_state_t
;
329 typedef struct rpc_copy_state rpc_copy_state_data_t
;
331 typedef boolean_t (*copyfunc_t
)(const char *, char *, vm_size_t
);
335 * RPC function declarations
338 #ifdef CALLOUT_RPC_MODEL
341 void rpc_bootstrap( void );
344 void rpc_remote_bootstrap( void );
347 rpc_return_t
mach_rpc_trap(
348 mach_port_name_t dest_port
,
349 rpc_id_t routine_num
,
350 rpc_signature_t signature_ptr
,
351 rpc_size_t signature_size
);
354 rpc_return_t
mach_rpc_return_trap( void );
357 rpc_return_t
mach_rpc_return_error( void );
359 void mach_rpc_return_wrapper( void );
363 vm_offset_t new_stack
,
364 vm_offset_t server_func
,
367 void rpc_error_severity( int severity
);
368 void rpc_error_show_severity( int severity
);
369 unsigned int name_rpc_to_ipc( unsigned int action
);
371 void clean_port_array(
372 ipc_object_t
* array
,
377 void unwind_rpc_state(
378 routine_descriptor_t routine
,
379 rpc_copy_state_t state
,
382 kern_return_t
unwind_invoke_state(
383 thread_act_t thr_act
);
385 kern_return_t
rpc_invke_args_in(
386 routine_descriptor_t routine
,
387 rpc_copy_state_t state
,
391 kern_return_t
rpc_invke_args_out(
392 routine_descriptor_t routine
,
393 rpc_copy_state_t state
,
396 copyfunc_t outfunc
);
398 kern_return_t
rpc_reply_args_in(
399 routine_descriptor_t routine
,
400 rpc_copy_state_t state
,
404 kern_return_t
rpc_reply_args_out(
405 routine_descriptor_t routine
,
406 rpc_copy_state_t state
,
409 copyfunc_t outfunc
);
411 #endif /* CALLOUT_RPC_MODEL */
414 * libmach helper functions:
416 extern rpc_subsystem_t
mach_subsystem_join(
422 #endif /* _MACH_RPC_H_ */