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 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26#pragma ident "%Z%%M% %I% %E% SMI" 27 28 .file "%M%" 29 30#include <sys/asm_linkage.h> 31 32 /* 33 * weak aliases for public interfaces 34 */ 35 ANSI_PRAGMA_WEAK(_door_bind,function) 36 ANSI_PRAGMA_WEAK(_door_call,function) 37 ANSI_PRAGMA_WEAK(_door_getparam,function) 38 ANSI_PRAGMA_WEAK(_door_info,function) 39 ANSI_PRAGMA_WEAK(_door_revoke,function) 40 ANSI_PRAGMA_WEAK(_door_setparam,function) 41 ANSI_PRAGMA_WEAK(_door_unbind,function) 42 43 ANSI_PRAGMA_WEAK(door_bind,function) 44 ANSI_PRAGMA_WEAK(door_call,function) 45 ANSI_PRAGMA_WEAK(door_getparam,function) 46 ANSI_PRAGMA_WEAK(door_info,function) 47 ANSI_PRAGMA_WEAK(door_revoke,function) 48 ANSI_PRAGMA_WEAK(door_setparam,function) 49 ANSI_PRAGMA_WEAK(door_unbind,function) 50 51#include <sys/door.h> 52#include "SYS.h" 53 54/* 55 * Offsets within struct door_results 56 */ 57#define DOOR_COOKIE _MUL(0, CLONGSIZE) 58#define DOOR_DATA_PTR _MUL(1, CLONGSIZE) 59#define DOOR_DATA_SIZE _MUL(2, CLONGSIZE) 60#define DOOR_DESC_PTR _MUL(3, CLONGSIZE) 61#define DOOR_DESC_SIZE _MUL(4, CLONGSIZE) 62#define DOOR_PC _MUL(5, CLONGSIZE) 63#define DOOR_SERVERS _MUL(6, CLONGSIZE) 64#define DOOR_INFO_PTR _MUL(7, CLONGSIZE) 65 66/* 67 * All of the syscalls except door_return() follow the same pattern. The 68 * subcode goes in %r9, after all of the other arguments. 69 */ 70#define DOOR_SYSCALL(name, code) \ 71 ENTRY(name); \ 72 movq $code, %r9; /* subcode */ \ 73 SYSTRAP_RVAL1(door); \ 74 SYSCERROR; \ 75 RET; \ 76 SET_SIZE(name) 77 78 DOOR_SYSCALL(__door_bind, DOOR_BIND) 79 DOOR_SYSCALL(__door_call, DOOR_CALL) 80 DOOR_SYSCALL(__door_create, DOOR_CREATE) 81 DOOR_SYSCALL(__door_getparam, DOOR_GETPARAM) 82 DOOR_SYSCALL(__door_info, DOOR_INFO) 83 DOOR_SYSCALL(__door_revoke, DOOR_REVOKE) 84 DOOR_SYSCALL(__door_setparam, DOOR_SETPARAM) 85 DOOR_SYSCALL(__door_ucred, DOOR_UCRED) 86 DOOR_SYSCALL(__door_unbind, DOOR_UNBIND) 87 DOOR_SYSCALL(__door_unref, DOOR_UNREFSYS) 88 89/* 90 * int 91 * __door_return( 92 * void *data_ptr, 93 * size_t data_size, (in bytes) 94 * door_return_desc_t *door_ptr, (holds returned desc info) 95 * caddr_t stack_base, 96 * size_t stack_size) 97 */ 98 ENTRY(__door_return) 99door_restart: 100 movq $DOOR_RETURN, %r9 /* subcode */ 101 SYSTRAP_RVAL1(door) 102 jb 3f /* errno is set */ 103 /* 104 * On return, we're serving a door_call. Our stack looks like this: 105 * 106 * descriptors (if any) 107 * data (if any) 108 * sp-> struct door_results 109 */ 110 movl DOOR_SERVERS(%rsp), %eax 111 andl %eax, %eax /* test nservers */ 112 jg 1f 113 /* 114 * this is the last server thread - call creation func for more 115 */ 116 movq _daref_(door_server_func), %rax 117 movq 0(%rax), %rax 118 movq DOOR_INFO_PTR(%rsp), %rdi 119 call *%rax /* call create function */ 1201: 121 /* Call the door server function now */ 122 movq DOOR_COOKIE(%rsp), %rdi 123 movq DOOR_DATA_PTR(%rsp), %rsi 124 movq DOOR_DATA_SIZE(%rsp), %rdx 125 movq DOOR_DESC_PTR(%rsp), %rcx 126 movq DOOR_DESC_SIZE(%rsp), %r8 127 movq DOOR_PC(%rsp), %rax 128 call *%rax 1292: 130 /* Exit the thread if we return here */ 131 movq $0, %rdi 132 call _thr_terminate 133 /* NOTREACHED */ 1343: 135 /* 136 * Error during door_return call. Repark the thread in the kernel if 137 * the error code is EINTR (or ERESTART) and this lwp is still part 138 * of the same process. 139 */ 140 cmpl $EEXIST, %eax /* exit if EEXIST is returned */ 141 je 2b 142 cmpl $ERESTART, %eax /* ERESTART is same as EINTR */ 143 jne 3f 144 movl $EINTR, %eax 1453: 146 cmpl $EINTR, %eax /* interrupted while waiting? */ 147 jne __cerror /* if not, return the error */ 148 149 call _private_getpid /* get current process id */ 150 movq _daref_(door_create_pid), %rdx 151 movl 0(%rdx), %edx 152 cmpl %eax, %edx /* same process? */ 153 movl $EINTR, %eax /* if no, return EINTR (child of forkall) */ 154 jne __cerror 155 156 movq $0, %rdi /* clear arguments and restart */ 157 movq $0, %rsi 158 movq $0, %rdx 159 jmp door_restart 160 SET_SIZE(__door_return) 161