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) 51uint8_t 52nsc_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) 86void 87nsc_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) 113caddr_t 114nsc_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) 141caddr_t 142nsc_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) 170void * 171nsc_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 */ 190