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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #if defined(lint) || defined(DS_DDICT) 27 #include <sys/types.h> 28 #include <sys/param.h> 29 #else 30 #include "assym.h" /* Determine value of CPU_THREAD */ 31 #include <sys/asm_linkage.h> 32 #endif 33 34 #ifdef DS_DDICT 35 #define uint8_t uchar_t 36 #endif 37 38 39 /* 40 * Special support routines that can't be done with C 41 * x86 variant 42 */ 43 44 /* 45 * uint8_t nsc_ldstub(uint8_t *cp) 46 * 47 * Store 0xFF at the specified location, and return its previous content. 48 */ 49 50 #if defined(lint) || defined(DS_DDICT) 51 uint8_t 52 nsc_ldstub(uint8_t *cp) 53 { 54 uint8_t rv; 55 rv = *cp; 56 *cp = 0xFF; 57 return (rv); 58 } 59 #else 60 ENTRY(nsc_ldstub) 61 #if defined(__amd64) 62 movl $0xff,%eax 63 lock 64 xchgb %al, (%rdi) /* rdi = lock addr */ 65 ret 66 #elif defined(__i386) 67 movl 4(%esp), %ecx /* ecx = lock addr */ 68 movl $0xff, %eax /* eax = 0xff */ 69 lock 70 xchgb %al, (%ecx) /* atomic swap eax <-> *ecx */ 71 ret 72 #else 73 #error "port this routine" 74 #endif 75 SET_SIZE(nsc_ldstub) 76 #endif 77 78 /* 79 * nsc_membar_stld(void) 80 * 81 * On SPARC this is a C callable interface to SPARC asm membar instruction. 82 * For x86 we brute force it with a #LOCK instruction. 83 */ 84 85 #if defined(lint) || defined(DS_DDICT) 86 void 87 nsc_membar_stld(void) 88 {} 89 #else 90 91 ENTRY(nsc_membar_stld) 92 #if defined(__amd64) 93 mfence 94 ret 95 #elif defined(__i386) 96 lock 97 xorl $0, (%esp) 98 ret 99 #else 100 #error "port this routine" 101 #endif 102 SET_SIZE(nsc_membar_stld) 103 104 #endif /* lint || DS_DDICT */ 105 106 107 /* 108 * if a() calls b() calls nsc_caller(), 109 * nsc_caller() returns return address in a(). 110 */ 111 112 #if defined(lint) || defined(DS_DDICT) 113 caddr_t 114 nsc_caller(void) 115 { 116 return (0); 117 } 118 #else 119 120 ENTRY(nsc_caller) 121 #if defined(__amd64) 122 movq 8(%rbp), %rax /* b()'s return pc, in a() */ 123 ret 124 #elif defined(__i386) 125 movl 4(%ebp), %eax /* b()'s return pc, in a() */ 126 ret 127 #else 128 #error "port this routine" 129 #endif 130 SET_SIZE(nsc_caller) 131 132 #endif /* lint || DS_DDICT */ 133 134 135 /* 136 * if a() calls nsc_callee(), nsc_callee() returns the 137 * return address in a(); 138 */ 139 140 #if defined(lint) || defined(DS_DDICT) 141 caddr_t 142 nsc_callee(void) 143 { 144 return (0); 145 } 146 #else 147 148 ENTRY(nsc_callee) 149 #if defined(__amd64) 150 movq (%rsp), %rax /* callee()'s return pc, in a() */ 151 ret 152 #elif defined(__i386) 153 movl (%esp), %eax /* callee()'s return pc, in a() */ 154 ret 155 #else 156 #error "port this routine" 157 #endif 158 SET_SIZE(nsc_callee) 159 160 #endif /* lint || DS_DDICT */ 161 162 163 /* 164 * nsc_threadp(void) 165 * 166 * C callable interface to get the current thread pointer. 167 */ 168 169 #if defined(lint) || defined(DS_DDICT) 170 void * 171 nsc_threadp(void) 172 { 173 return (NULL); 174 } 175 #else 176 177 ENTRY(nsc_threadp) 178 #if defined(__amd64) 179 movq %gs:CPU_THREAD, %rax 180 ret 181 #elif defined(__i386) 182 movl %gs:CPU_THREAD,%eax 183 ret 184 #else 185 #error "port this routine" 186 #endif 187 SET_SIZE(nsc_threadp) 188 189 #endif /* lint || DS_DDICT */