|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 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. ! 11: * ! 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 ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * @OSF_COPYRIGHT@ ! 24: */ ! 25: ! 26: /* ! 27: * Mach RPC Subsystem Interfaces ! 28: */ ! 29: ! 30: #ifndef _MACH_RPC_H_ ! 31: #define _MACH_RPC_H_ ! 32: ! 33: #include <mach/boolean.h> ! 34: #include <mach/kern_return.h> ! 35: #include <mach/port.h> ! 36: #include <mach/vm_types.h> ! 37: ! 38: #include <mach/mig_errors.h> ! 39: #include <mach/machine/rpc.h> ! 40: #include <mach/thread_status.h> ! 41: ! 42: #ifdef MACH_KERNEL_PRIVATE ! 43: #include <ipc/ipc_object.h> ! 44: #endif /* MACH_KERNEL_PRIVATE */ ! 45: ! 46: /* ! 47: * The various bits of the type field of the routine_arg_descriptor ! 48: */ ! 49: ! 50: /* The basic types */ ! 51: ! 52: #define TYPE_SHIFT 0 ! 53: #define MACH_RPC_PORT (1 << TYPE_SHIFT) ! 54: #define MACH_RPC_ARRAY (1 << (TYPE_SHIFT + 1)) ! 55: #define MACH_RPC_VARIABLE (1 << (TYPE_SHIFT + 2)) ! 56: #define LAST_TYPE_BIT (TYPE_SHIFT+3) ! 57: ! 58: /* XXX Port arrays need not be variable arrays, as assumed below. Fixme. */ ! 59: #define MACH_RPC_ARRAY_FIX (MACH_RPC_ARRAY) ! 60: #define MACH_RPC_ARRAY_FIXED (MACH_RPC_ARRAY) ! 61: #define MACH_RPC_ARRAY_VAR (MACH_RPC_ARRAY | MACH_RPC_VARIABLE) ! 62: #define MACH_RPC_ARRAY_VARIABLE (MACH_RPC_ARRAY | MACH_RPC_VARIABLE) ! 63: #define MACH_RPC_PORT_ARRAY (MACH_RPC_PORT | MACH_RPC_ARRAY_VAR) ! 64: ! 65: /* Argument direction bits */ ! 66: ! 67: #define DIRECT_SHIFT LAST_TYPE_BIT ! 68: #define DIRECTION_SHIFT LAST_TYPE_BIT ! 69: #define MACH_RPC_IN (1 << DIRECTION_SHIFT) ! 70: #define MACH_RPC_OUT (1 << (DIRECTION_SHIFT + 1)) ! 71: #define LAST_DIRECT_BIT (DIRECTION_SHIFT + 2) ! 72: #define LAST_DIRECTION_BIT (DIRECTION_SHIFT + 2) ! 73: ! 74: #define MACH_RPC_INOUT (MACH_RPC_IN | MACH_RPC_OUT) ! 75: ! 76: /* Persist and pointer bit */ ! 77: ! 78: #define POINTER_SHIFT LAST_DIRECTION_BIT ! 79: #define MACH_RPC_POINTER (1 << POINTER_SHIFT) ! 80: #define LAST_POINTER_BIT (POINTER_SHIFT + 1) ! 81: ! 82: /* Port disposition bits */ ! 83: ! 84: #define NAME_SHIFT LAST_POINTER_BIT ! 85: #define MACH_RPC_RECEIVE (1 << NAME_SHIFT) ! 86: #define MACH_RPC_SEND (2 << NAME_SHIFT) ! 87: #define MACH_RPC_SEND_ONCE (3 << NAME_SHIFT) ! 88: #define LAST_NAME_BIT (NAME_SHIFT + 2) ! 89: ! 90: #define ACTION_SHIFT LAST_NAME_BIT ! 91: #define MACH_RPC_MOVE (1 << ACTION_SHIFT) ! 92: #define MACH_RPC_COPY (2 << ACTION_SHIFT) ! 93: #define MACH_RPC_MAKE (3 << ACTION_SHIFT) ! 94: #define LAST_ACTION_BIT (ACTION_SHIFT + 2) ! 95: ! 96: #define MACH_RPC_MOVE_RECEIVE (MACH_RPC_MOVE | MACH_RPC_RECEIVE) ! 97: #define MACH_RPC_MOVE_SEND (MACH_RPC_MOVE | MACH_RPC_SEND) ! 98: #define MACH_RPC_COPY_SEND (MACH_RPC_COPY | MACH_RPC_SEND) ! 99: #define MACH_RPC_MAKE_SEND (MACH_RPC_MAKE | MACH_RPC_SEND) ! 100: #define MACH_RPC_MOVE_SEND_ONCE (MACH_RPC_MOVE | MACH_RPC_SEND_ONCE) ! 101: #define MACH_RPC_MAKE_SEND_ONCE (MACH_RPC_MAKE | MACH_RPC_SEND_ONCE) ! 102: ! 103: /* Hint for virtual vs. physical copy */ ! 104: ! 105: #define OPTION_SHIFT LAST_ACTION_BIT ! 106: #define MACH_RPC_PHYSICAL_COPY (1 << OPTION_SHIFT) ! 107: #define MACH_RPC_VIRTUAL_COPY (1 << (OPTION_SHIFT + 1)) ! 108: #define LAST_OPTION_BIT (OPTION_SHIFT + 2) ! 109: ! 110: /* Deallocate? */ ! 111: ! 112: #define DEALLOCATE_SHIFT LAST_OPTION_BIT ! 113: #define MACH_RPC_DEALLOCATE (1 << DEALLOCATE_SHIFT) ! 114: #define LAST_DEALLOCATE_BIT (DEALLOCATE_SHIFT + 1) ! 115: ! 116: /* Argument is already on the stack */ ! 117: ! 118: #define ONSTACK_SHIFT LAST_DEALLOCATE_BIT ! 119: #define MACH_RPC_ONSTACK (1 << ONSTACK_SHIFT) ! 120: #define LAST_ONSTACK_BIT (ONSTACK_SHIFT + 1) ! 121: ! 122: /* Is variable array bounded? Derived from type and arg.size */ ! 123: ! 124: #define BOUND_SHIFT LAST_ONSTACK_BIT ! 125: #define MACH_RPC_BOUND (1 << BOUND_SHIFT) ! 126: #define MACH_RPC_UNBOUND (0) ! 127: #define BOUND MACH_RPC_BOUND ! 128: #define UNBND MACH_RPC_UNBOUND ! 129: #define LAST_BOUND_BIT (BOUND_SHIFT + 1) ! 130: ! 131: /* ! 132: * Basic mach rpc types. ! 133: */ ! 134: typedef unsigned int routine_arg_type; ! 135: typedef unsigned int routine_arg_offset; ! 136: typedef unsigned int routine_arg_size; ! 137: ! 138: /* ! 139: * Definition for MIG-generated server stub routines. These routines ! 140: * unpack the request message, call the server procedure, and pack the ! 141: * reply message. ! 142: */ ! 143: typedef void (*mig_stub_routine_t) (mach_msg_header_t *InHeadP, ! 144: mach_msg_header_t *OutHeadP); ! 145: ! 146: typedef mig_stub_routine_t mig_routine_t; ! 147: ! 148: /* ! 149: * Definition for server implementation routines. This is the routine ! 150: * called by the MIG-generated server stub routine. ! 151: */ ! 152: typedef kern_return_t (*mig_impl_routine_t)(void); ! 153: ! 154: typedef mig_impl_routine_t entry_function_t; ! 155: ! 156: /* ! 157: * Structure for parameters of new activation. The entry_func field is used ! 158: * as the upcall PC when there is no registered subsystem. The return_func is ! 159: * a pointer to a mach_rpc_return_trap instruction. In addition, optional ! 160: * thread state parameters are provided for architectures that require it. ! 161: */ ! 162: ! 163: struct thread_act_params ! 164: { ! 165: vm_offset_t stack; ! 166: vm_size_t stack_size; ! 167: entry_function_t entry_func; ! 168: int flavor; ! 169: thread_state_t act_state; ! 170: unsigned int act_state_count; ! 171: }; ! 172: ! 173: typedef struct thread_act_params *thread_act_params_t; ! 174: typedef char act_params_t[sizeof(struct thread_act_params)]; ! 175: #define NULL_PARAMS ((thread_act_params_t) 0) ! 176: ! 177: /* ! 178: * Definitions for a signature's argument and routine descriptor's. ! 179: */ ! 180: struct routine_arg_descriptor { ! 181: routine_arg_type type; /* Port, Array, etc. */ ! 182: routine_arg_size size; /* element size in bytes */ ! 183: routine_arg_size count; /* number of elements */ ! 184: routine_arg_offset offset; /* Offset in list of routine args */ ! 185: }; ! 186: typedef struct routine_arg_descriptor *routine_arg_descriptor_t; ! 187: ! 188: struct routine_descriptor { ! 189: mig_impl_routine_t impl_routine; /* Server work func pointer */ ! 190: mig_stub_routine_t stub_routine; /* Unmarshalling func pointer */ ! 191: unsigned int argc; /* Number of argument words */ ! 192: unsigned int descr_count; /* Number of complex argument */ ! 193: /* descriptors */ ! 194: struct routine_arg_descriptor * ! 195: arg_descr; /* Pointer to beginning of */ ! 196: /* the arg_descr array */ ! 197: unsigned int max_reply_msg; /* Max size for reply msg */ ! 198: }; ! 199: typedef struct routine_descriptor *routine_descriptor_t; ! 200: ! 201: #define DESCR_SIZE(x) ((x)->descr_count * sizeof(struct routine_arg_descriptor)) ! 202: ! 203: struct rpc_signature { ! 204: struct routine_descriptor rd; ! 205: struct routine_arg_descriptor rad[1]; ! 206: }; ! 207: ! 208: #ifdef MACH_KERNEL_PRIVATE ! 209: ! 210: typedef struct rpc_signature *rpc_signature_t; ! 211: ! 212: #endif ! 213: ! 214: #define RPC_SIGBUF_SIZE 8 ! 215: /* ! 216: * A subsystem describes a set of server routines that can be invoked by ! 217: * mach_rpc() on the ports that are registered with the subsystem. For ! 218: * each routine, the routine number is given, along with the ! 219: * address of the implementation function in the server and a ! 220: * description of the arguments of the routine (it's "signature"). ! 221: * ! 222: * This structure definition is only a template for what is really a ! 223: * variable-length structure (generated by MIG for each subsystem). ! 224: * The actual structures do not always have one entry in the routine ! 225: * array, and also have a varying number of entries in the arg_descr ! 226: * array. Each routine has an array of zero or more arg descriptors ! 227: * one for each complex arg. These arrays are all catenated together ! 228: * to form the arg_descr field of the subsystem struct. The ! 229: * arg_descr field of each routine entry points to a unique sub-sequence ! 230: * within this catenated array. The goal is to keep everything ! 231: * contiguous. ! 232: */ ! 233: struct rpc_subsystem { ! 234: struct subsystem *subsystem; /* Reserved for system use */ ! 235: ! 236: mach_msg_id_t start; /* Min routine number */ ! 237: mach_msg_id_t end; /* Max routine number + 1 */ ! 238: unsigned int maxsize; /* Max mach_msg size */ ! 239: vm_address_t base_addr; /* Address of this struct in user */ ! 240: ! 241: struct routine_descriptor /* Array of routine descriptors */ ! 242: routine[1 /* Actually, (start-end+1) */ ! 243: ]; ! 244: ! 245: struct routine_arg_descriptor ! 246: arg_descriptor[1 /* Actually, the sum of the descr_ */ ! 247: ]; /* count fields for all routines */ ! 248: }; ! 249: typedef struct rpc_subsystem *rpc_subsystem_t; ! 250: ! 251: #define RPC_SUBSYSTEM_NULL ((rpc_subsystem_t) 0) ! 252: ! 253: /* ! 254: * New RPC declarations ! 255: * ! 256: * First pass at definitions and types for the new rpc service. ! 257: * This is subject to revision. ! 258: */ ! 259: ! 260: /* ! 261: * RPC macros ! 262: */ ! 263: ! 264: #define RPC_MASK(shift,last) \ ! 265: ( ((1 << ((last)-(shift)))-1) << (shift) ) ! 266: ! 267: #define RPC_FIELD(field,shift,last) \ ! 268: ( (field) & (((1 << ((last)-(shift)))-1) << (shift)) ) ! 269: ! 270: #define RPC_BOUND(dsc) \ ! 271: (((RPC_FIELD((dsc).type,TYPE_SHIFT+1,TYPE_SHIFT+3) == \ ! 272: MACH_RPC_ARRAY_VARIABLE) && (dsc).count != 0) ? MACH_RPC_BOUND : 0) ! 273: ! 274: #define ROUNDUP2(x,n) ((((unsigned)(x)) + (n) - 1) & ~((n)-1)) ! 275: #define ROUNDWORD(x) ROUNDUP2(x,sizeof(int)) ! 276: ! 277: /* ! 278: * RPC errors ! 279: * ! 280: * Display and process errors of different severity, from just for ! 281: * information only to fatal (panic). Error code colors indicate how ! 282: * difficult it is for the subsystem to handle the error correctly. ! 283: * The implication is that, for example, early versions of the code may ! 284: * not be handling code red errors properly. The code should use this ! 285: * facility instead of regular printf's. ! 286: */ ! 287: ! 288: #define MACH_RPC_DEBUG 1 ! 289: ! 290: #define ERR_INFO 1 /* purely informational */ ! 291: #define ERR_GREEN 2 /* easily handled error */ ! 292: #define ERR_YELLOW 3 /* medium difficult error */ ! 293: #define ERR_RED 4 /* difficult to handle error */ ! 294: #define ERR_FATAL 5 /* unrecoverable error, panic */ ! 295: ! 296: #if MACH_RPC_DEBUG > 1 ! 297: #define rpc_error(E,S) \ ! 298: printf("RPC error "); \ ! 299: rpc_error_show_severity(S); \ ! 300: printf("in file \"%s\", line %d: ", __FILE__, __LINE__); \ ! 301: printf E ; \ ! 302: printf("\n"); \ ! 303: rpc_error_severity(S) ! 304: #else ! 305: #define rpc_error(E,S) \ ! 306: if ((S) == ERR_FATAL || (S) == ERR_RED) { \ ! 307: printf("RPC error "); \ ! 308: rpc_error_show_severity(S); \ ! 309: printf("in file \"%s\", line %d: ", __FILE__, __LINE__); \ ! 310: printf E ; \ ! 311: printf("\n"); \ ! 312: rpc_error_severity(S); \ ! 313: } ! 314: #endif /* MACH_RPC_DEBUG */ ! 315: ! 316: /* ! 317: * RPC buffer size and break points ! 318: * ! 319: * These values define the rpc buffer size on the kernel stack, ! 320: * and break point values for switching to virtual copy (cow). ! 321: * This should be in a machine dependent include file. All sizes ! 322: * are in word (sizeof(int)) units. ! 323: */ ! 324: ! 325: #define RPC_KBUF_SIZE 16 /* kernel stack buffer size (ints) */ ! 326: #define RPC_COW_SIZE 1024 /* size where COW is a win (ints) */ ! 327: #define RPC_DESC_COUNT 4 /* default descriptor count */ ! 328: ! 329: ! 330: /* ! 331: * RPC copy state ! 332: * ! 333: * Record the rpc copy state for arrays, so we can unwind our state ! 334: * during error processing. There is one entry per complex (signatured) ! 335: * argument. The first entry is marked COPY_TYPE_ALLOC_KRN if this record ! 336: * itself was kalloc'd because the number of complex arg descriptors ! 337: * exceeded the default value (RPC_DESC_COUNT). This is not a conflict ! 338: * since the first argument is always the destination port, never an array. ! 339: */ ! 340: ! 341: #define COPY_TYPE_NO_COPY 0 /* nothing special */ ! 342: #define COPY_TYPE_ON_KSTACK 1 /* array is on kernel stack */ ! 343: #define COPY_TYPE_ON_SSTACK 2 /* array is on server stack */ ! 344: #define COPY_TYPE_VIRTUAL_IN 3 /* vm_map_copyin part of cow */ ! 345: #define COPY_TYPE_VIRTUAL_OUT_SVR 4 /* map cpyout svr part of cow */ ! 346: #define COPY_TYPE_VIRTUAL_OUT_CLN 5 /* map cpyout cln part of cow */ ! 347: #define COPY_TYPE_ALLOC_KRN 6 /* kernel kalloc'd for array */ ! 348: #define COPY_TYPE_ALLOC_SVR 7 /* vm_alloc'd in server space */ ! 349: #define COPY_TYPE_ALLOC_CLN 8 /* vm_alloc'd in client space */ ! 350: #define COPY_TYPE_PORT 9 /* plain port translated */ ! 351: #define COPY_TYPE_PORT_ARRAY 10 /* port array translated */ ! 352: ! 353: ! 354: /* ! 355: * RPC types ! 356: */ ! 357: typedef int rpc_id_t; ! 358: typedef int rpc_return_t; ! 359: typedef unsigned int rpc_size_t; ! 360: typedef unsigned int rpc_offset_t; ! 361: ! 362: struct rpc_copy_state { ! 363: unsigned copy_type; /* what kind of copy */ ! 364: vm_offset_t alloc_addr; /* address to free */ ! 365: }; ! 366: typedef struct rpc_copy_state *rpc_copy_state_t; ! 367: typedef struct rpc_copy_state rpc_copy_state_data_t; ! 368: ! 369: typedef boolean_t (*copyfunc_t)(const char *, char *, vm_size_t); ! 370: ! 371: ! 372: /* ! 373: * RPC function declarations ! 374: */ ! 375: ! 376: #ifdef CALLOUT_RPC_MODEL ! 377: ! 378: extern ! 379: void rpc_bootstrap( void ); ! 380: ! 381: extern ! 382: void rpc_remote_bootstrap( void ); ! 383: ! 384: extern ! 385: rpc_return_t mach_rpc_trap( ! 386: mach_port_name_t dest_port, ! 387: rpc_id_t routine_num, ! 388: rpc_signature_t signature_ptr, ! 389: rpc_size_t signature_size ); ! 390: ! 391: extern ! 392: rpc_return_t mach_rpc_return_trap( void ); ! 393: ! 394: extern ! 395: rpc_return_t mach_rpc_return_error( void ); ! 396: ! 397: void mach_rpc_return_wrapper( void ); ! 398: ! 399: void rpc_upcall( ! 400: vm_offset_t stack, ! 401: vm_offset_t new_stack, ! 402: vm_offset_t server_func, ! 403: int return_code ); ! 404: ! 405: void rpc_error_severity( int severity ); ! 406: void rpc_error_show_severity( int severity ); ! 407: unsigned int name_rpc_to_ipc( unsigned int action ); ! 408: ! 409: void clean_port_array( ! 410: ipc_object_t * array, ! 411: unsigned count, ! 412: unsigned cooked, ! 413: unsigned direct ); ! 414: ! 415: void unwind_rpc_state( ! 416: routine_descriptor_t routine, ! 417: rpc_copy_state_t state, ! 418: int * arg_buf ); ! 419: ! 420: kern_return_t unwind_invoke_state( ! 421: thread_act_t thr_act ); ! 422: ! 423: kern_return_t rpc_invke_args_in( ! 424: routine_descriptor_t routine, ! 425: rpc_copy_state_t state, ! 426: int * arg_buf, ! 427: copyfunc_t infunc ); ! 428: ! 429: kern_return_t rpc_invke_args_out( ! 430: routine_descriptor_t routine, ! 431: rpc_copy_state_t state, ! 432: int * arg_buf, ! 433: int ** new_sp, ! 434: copyfunc_t outfunc ); ! 435: ! 436: kern_return_t rpc_reply_args_in( ! 437: routine_descriptor_t routine, ! 438: rpc_copy_state_t state, ! 439: int * svr_buf, ! 440: copyfunc_t infunc ); ! 441: ! 442: kern_return_t rpc_reply_args_out( ! 443: routine_descriptor_t routine, ! 444: rpc_copy_state_t state, ! 445: int * svr_buf, ! 446: int * cln_buf, ! 447: copyfunc_t outfunc ); ! 448: ! 449: #endif /* CALLOUT_RPC_MODEL */ ! 450: ! 451: /* ! 452: * libmach helper functions: ! 453: */ ! 454: extern rpc_subsystem_t mach_subsystem_join( ! 455: rpc_subsystem_t, ! 456: rpc_subsystem_t, ! 457: unsigned int *, ! 458: void *(* )(int)); ! 459: ! 460: #endif /* _MACH_RPC_H_ */ ! 461: ! 462:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.