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 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _LIBC_SPARCV9_INC_SYS_H 28 #define _LIBC_SPARCV9_INC_SYS_H 29 30 /* 31 * This file defines common code sequences for system calls. Note that 32 * it is assumed that __cerror is within the short branch distance from 33 * all the traps (so that a simple bcs can follow the trap, rather than 34 * a position independent code sequence.) 35 */ 36 37 #include <sys/asm_linkage.h> 38 #include <sys/syscall.h> 39 #include <sys/errno.h> 40 41 /* 42 * While it's tempting to imagine we could use 'rd %pc' here, 43 * in fact it's a rather slow operation that consumes many 44 * cycles, so we use the usual side-effect of 'call' instead. 45 */ 46 #define PIC_SETUP(r) \ 47 mov %o7, %g1; \ 48 9: call 8f; \ 49 sethi %hi(_GLOBAL_OFFSET_TABLE_ - (9b - .)), %r; \ 50 8: or %r, %lo(_GLOBAL_OFFSET_TABLE_ - (9b - .)), %r; \ 51 add %r, %o7, %r; \ 52 mov %g1, %o7 53 54 /* 55 * Trap number for system calls 56 */ 57 #define SYSCALL_TRAPNUM 64 58 59 /* 60 * Define the external symbol __cerror for all files. 61 */ 62 .global __cerror 63 64 /* 65 * __SYSTRAP provides the basic trap sequence. It assumes that an entry 66 * of the form SYS_name exists (probably from sys/syscall.h). 67 */ 68 #define __SYSTRAP(name) \ 69 /* CSTYLED */ \ 70 mov SYS_##name, %g1; \ 71 ta SYSCALL_TRAPNUM 72 73 #define SYSTRAP_RVAL1(name) __SYSTRAP(name) 74 #define SYSTRAP_RVAL2(name) __SYSTRAP(name) 75 #define SYSTRAP_2RVALS(name) __SYSTRAP(name) 76 #define SYSTRAP_64RVAL(name) __SYSTRAP(name) 77 78 /* 79 * SYSFASTTRAP provides the fast system call trap sequence. It assumes 80 * that an entry of the form ST_name exists (probably from sys/trap.h). 81 */ 82 #define SYSFASTTRAP(name) \ 83 /* CSTYLED */ \ 84 ta ST_##name 85 86 /* 87 * SYSCERROR provides the sequence to branch to __cerror if an error is 88 * indicated by the carry-bit being set upon return from a trap. 89 */ 90 #define SYSCERROR \ 91 /* CSTYLED */ \ 92 bcs __cerror; \ 93 nop 94 95 /* 96 * SYSLWPERR provides the sequence to return 0 on a successful trap 97 * and the error code if unsuccessful. 98 * Error is indicated by the carry-bit being set upon return from a trap. 99 */ 100 #define SYSLWPERR \ 101 /* CSTYLED */ \ 102 bcc,a,pt %icc, 1f; \ 103 clr %o0; \ 104 cmp %o0, ERESTART; \ 105 move %icc, EINTR, %o0; \ 106 1: 107 108 #define SAVE_OFFSET (STACK_BIAS + 8 * 16) 109 110 /* 111 * SYSREENTRY provides the entry sequence for restartable system calls. 112 */ 113 #define SYSREENTRY(name) \ 114 ENTRY(name); \ 115 stn %o0, [%sp + SAVE_OFFSET]; \ 116 /* CSTYLED */ \ 117 .restart_##name: 118 119 /* 120 * SYSRESTART provides the error handling sequence for restartable 121 * system calls. 122 */ 123 #define SYSRESTART(name) \ 124 /* CSTYLED */ \ 125 bcc,pt %icc, 1f; \ 126 cmp %o0, ERESTART; \ 127 /* CSTYLED */ \ 128 be,a,pn %icc, name; \ 129 ldn [%sp + SAVE_OFFSET], %o0; \ 130 /* CSTYLED */ \ 131 ba,a __cerror; \ 132 1: 133 134 /* 135 * SYSINTR_RESTART provides the error handling sequence for restartable 136 * system calls in case of EINTR or ERESTART. 137 */ 138 #define SYSINTR_RESTART(name) \ 139 /* CSTYLED */ \ 140 bcc,a,pt %icc, 1f; \ 141 clr %o0; \ 142 cmp %o0, ERESTART; \ 143 /* CSTYLED */ \ 144 be,a,pn %icc, name; \ 145 ldn [%sp + SAVE_OFFSET], %o0; \ 146 cmp %o0, EINTR; \ 147 /* CSTYLED */ \ 148 be,a,pn %icc, name; \ 149 ldn [%sp + SAVE_OFFSET], %o0; \ 150 1: 151 152 /* 153 * SYSCALL provides the standard (i.e.: most common) system call sequence. 154 */ 155 #define SYSCALL(name) \ 156 ENTRY(name); \ 157 SYSTRAP_2RVALS(name); \ 158 SYSCERROR 159 160 #define SYSCALL_RVAL1(name) \ 161 ENTRY(name); \ 162 SYSTRAP_RVAL1(name); \ 163 SYSCERROR 164 165 /* 166 * SYSCALL_RESTART provides the most common restartable system call sequence. 167 */ 168 #define SYSCALL_RESTART(name) \ 169 SYSREENTRY(name); \ 170 SYSTRAP_2RVALS(name); \ 171 /* CSTYLED */ \ 172 SYSRESTART(.restart_##name) 173 174 #define SYSCALL_RESTART_RVAL1(name) \ 175 SYSREENTRY(name); \ 176 SYSTRAP_RVAL1(name); \ 177 /* CSTYLED */ \ 178 SYSRESTART(.restart_##name) 179 180 /* 181 * SYSCALL2 provides a common system call sequence when the entry name 182 * is different than the trap name. 183 */ 184 #define SYSCALL2(entryname, trapname) \ 185 ENTRY(entryname); \ 186 SYSTRAP_2RVALS(trapname); \ 187 SYSCERROR 188 189 #define SYSCALL2_RVAL1(entryname, trapname) \ 190 ENTRY(entryname); \ 191 SYSTRAP_RVAL1(trapname); \ 192 SYSCERROR 193 194 /* 195 * SYSCALL2_RESTART provides a common restartable system call sequence when the 196 * entry name is different than the trap name. 197 */ 198 #define SYSCALL2_RESTART(entryname, trapname) \ 199 SYSREENTRY(entryname); \ 200 SYSTRAP_2RVALS(trapname); \ 201 /* CSTYLED */ \ 202 SYSRESTART(.restart_##entryname) 203 204 #define SYSCALL2_RESTART_RVAL1(entryname, trapname) \ 205 SYSREENTRY(entryname); \ 206 SYSTRAP_RVAL1(trapname); \ 207 /* CSTYLED */ \ 208 SYSRESTART(.restart_##entryname) 209 210 /* 211 * SYSCALL_NOERROR provides the most common system call sequence for those 212 * system calls which don't check the error return (carry bit). 213 */ 214 #define SYSCALL_NOERROR(name) \ 215 ENTRY(name); \ 216 SYSTRAP_2RVALS(name) 217 218 #define SYSCALL_NOERROR_RVAL1(name) \ 219 ENTRY(name); \ 220 SYSTRAP_RVAL1(name) 221 222 /* 223 * Standard syscall return sequence, return code equal to rval1. 224 */ 225 #define RET \ 226 retl; \ 227 nop 228 229 /* 230 * Syscall return sequence, return code equal to rval2. 231 */ 232 #define RET2 \ 233 retl; \ 234 mov %o1, %o0 235 236 /* 237 * Syscall return sequence with return code forced to zero. 238 */ 239 #define RETC \ 240 retl; \ 241 clr %o0 242 243 #endif /* _LIBC_SPARCV9_INC_SYS_H */ 244