1fcf3ce44SJohn Forte/* 2fcf3ce44SJohn Forte * CDDL HEADER START 3fcf3ce44SJohn Forte * 4fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7fcf3ce44SJohn Forte * 8fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11fcf3ce44SJohn Forte * and limitations under the License. 12fcf3ce44SJohn Forte * 13fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18fcf3ce44SJohn Forte * 19fcf3ce44SJohn Forte * CDDL HEADER END 20fcf3ce44SJohn Forte */ 21fcf3ce44SJohn Forte/* 22fcf3ce44SJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23fcf3ce44SJohn Forte * Use is subject to license terms. 24fcf3ce44SJohn Forte */ 25fcf3ce44SJohn Forte 26fcf3ce44SJohn Forte#if defined(lint) || defined(DS_DDICT) 27fcf3ce44SJohn Forte#include <sys/types.h> 28fcf3ce44SJohn Forte#include <sys/param.h> 29fcf3ce44SJohn Forte#else 30*fd65ca28SJohn Forte#include "assym.h" /* Determine value of CPU_THREAD */ 31fcf3ce44SJohn Forte#include <sys/asm_linkage.h> 32fcf3ce44SJohn Forte#endif 33fcf3ce44SJohn Forte 34fcf3ce44SJohn Forte#ifdef DS_DDICT 35fcf3ce44SJohn Forte#define uint8_t uchar_t 36fcf3ce44SJohn Forte#endif 37fcf3ce44SJohn Forte 38fcf3ce44SJohn Forte 39fcf3ce44SJohn Forte/* 40fcf3ce44SJohn Forte * Special support routines that can't be done with C 41fcf3ce44SJohn Forte * x86 variant 42fcf3ce44SJohn Forte */ 43fcf3ce44SJohn Forte 44fcf3ce44SJohn Forte/* 45fcf3ce44SJohn Forte * uint8_t nsc_ldstub(uint8_t *cp) 46fcf3ce44SJohn Forte * 47fcf3ce44SJohn Forte * Store 0xFF at the specified location, and return its previous content. 48fcf3ce44SJohn Forte */ 49fcf3ce44SJohn Forte 50fcf3ce44SJohn Forte#if defined(lint) || defined(DS_DDICT) 51fcf3ce44SJohn Forteuint8_t 52fcf3ce44SJohn Fortensc_ldstub(uint8_t *cp) 53fcf3ce44SJohn Forte{ 54fcf3ce44SJohn Forte uint8_t rv; 55fcf3ce44SJohn Forte rv = *cp; 56fcf3ce44SJohn Forte *cp = 0xFF; 57fcf3ce44SJohn Forte return (rv); 58fcf3ce44SJohn Forte} 59fcf3ce44SJohn Forte#else 60fcf3ce44SJohn Forte ENTRY(nsc_ldstub) 61fcf3ce44SJohn Forte#if defined(__amd64) 62fcf3ce44SJohn Forte movl $0xff,%eax 63fcf3ce44SJohn Forte lock 64fcf3ce44SJohn Forte xchgb %al, (%rdi) /* rdi = lock addr */ 65fcf3ce44SJohn Forte ret 66fcf3ce44SJohn Forte#elif defined(__i386) 67fcf3ce44SJohn Forte movl 4(%esp), %ecx /* ecx = lock addr */ 68fcf3ce44SJohn Forte movl $0xff, %eax /* eax = 0xff */ 69fcf3ce44SJohn Forte lock 70fcf3ce44SJohn Forte xchgb %al, (%ecx) /* atomic swap eax <-> *ecx */ 71fcf3ce44SJohn Forte ret 72fcf3ce44SJohn Forte#else 73fcf3ce44SJohn Forte#error "port this routine" 74fcf3ce44SJohn Forte#endif 75fcf3ce44SJohn Forte SET_SIZE(nsc_ldstub) 76fcf3ce44SJohn Forte#endif 77fcf3ce44SJohn Forte 78fcf3ce44SJohn Forte/* 79fcf3ce44SJohn Forte * nsc_membar_stld(void) 80fcf3ce44SJohn Forte * 81fcf3ce44SJohn Forte * On SPARC this is a C callable interface to SPARC asm membar instruction. 82fcf3ce44SJohn Forte * For x86 we brute force it with a #LOCK instruction. 83fcf3ce44SJohn Forte */ 84fcf3ce44SJohn Forte 85fcf3ce44SJohn Forte#if defined(lint) || defined(DS_DDICT) 86fcf3ce44SJohn Fortevoid 87fcf3ce44SJohn Fortensc_membar_stld(void) 88fcf3ce44SJohn Forte{} 89fcf3ce44SJohn Forte#else 90fcf3ce44SJohn Forte 91fcf3ce44SJohn Forte ENTRY(nsc_membar_stld) 92fcf3ce44SJohn Forte#if defined(__amd64) 93fcf3ce44SJohn Forte mfence 94fcf3ce44SJohn Forte ret 95fcf3ce44SJohn Forte#elif defined(__i386) 96fcf3ce44SJohn Forte lock 97fcf3ce44SJohn Forte xorl $0, (%esp) 98fcf3ce44SJohn Forte ret 99fcf3ce44SJohn Forte#else 100fcf3ce44SJohn Forte#error "port this routine" 101fcf3ce44SJohn Forte#endif 102fcf3ce44SJohn Forte SET_SIZE(nsc_membar_stld) 103fcf3ce44SJohn Forte 104fcf3ce44SJohn Forte#endif /* lint || DS_DDICT */ 105fcf3ce44SJohn Forte 106fcf3ce44SJohn Forte 107fcf3ce44SJohn Forte/* 108fcf3ce44SJohn Forte * if a() calls b() calls nsc_caller(), 109fcf3ce44SJohn Forte * nsc_caller() returns return address in a(). 110fcf3ce44SJohn Forte */ 111fcf3ce44SJohn Forte 112fcf3ce44SJohn Forte#if defined(lint) || defined(DS_DDICT) 113fcf3ce44SJohn Fortecaddr_t 114fcf3ce44SJohn Fortensc_caller(void) 115fcf3ce44SJohn Forte{ 116fcf3ce44SJohn Forte return (0); 117fcf3ce44SJohn Forte} 118fcf3ce44SJohn Forte#else 119fcf3ce44SJohn Forte 120fcf3ce44SJohn Forte ENTRY(nsc_caller) 121fcf3ce44SJohn Forte#if defined(__amd64) 122fcf3ce44SJohn Forte movq 8(%rbp), %rax /* b()'s return pc, in a() */ 123fcf3ce44SJohn Forte ret 124fcf3ce44SJohn Forte#elif defined(__i386) 125fcf3ce44SJohn Forte movl 4(%ebp), %eax /* b()'s return pc, in a() */ 126fcf3ce44SJohn Forte ret 127fcf3ce44SJohn Forte#else 128fcf3ce44SJohn Forte#error "port this routine" 129fcf3ce44SJohn Forte#endif 130fcf3ce44SJohn Forte SET_SIZE(nsc_caller) 131fcf3ce44SJohn Forte 132fcf3ce44SJohn Forte#endif /* lint || DS_DDICT */ 133fcf3ce44SJohn Forte 134fcf3ce44SJohn Forte 135fcf3ce44SJohn Forte/* 136fcf3ce44SJohn Forte * if a() calls nsc_callee(), nsc_callee() returns the 137fcf3ce44SJohn Forte * return address in a(); 138fcf3ce44SJohn Forte */ 139fcf3ce44SJohn Forte 140fcf3ce44SJohn Forte#if defined(lint) || defined(DS_DDICT) 141fcf3ce44SJohn Fortecaddr_t 142fcf3ce44SJohn Fortensc_callee(void) 143fcf3ce44SJohn Forte{ 144fcf3ce44SJohn Forte return (0); 145fcf3ce44SJohn Forte} 146fcf3ce44SJohn Forte#else 147fcf3ce44SJohn Forte 148fcf3ce44SJohn Forte ENTRY(nsc_callee) 149fcf3ce44SJohn Forte#if defined(__amd64) 150fcf3ce44SJohn Forte movq (%rsp), %rax /* callee()'s return pc, in a() */ 151fcf3ce44SJohn Forte ret 152fcf3ce44SJohn Forte#elif defined(__i386) 153fcf3ce44SJohn Forte movl (%esp), %eax /* callee()'s return pc, in a() */ 154fcf3ce44SJohn Forte ret 155fcf3ce44SJohn Forte#else 156fcf3ce44SJohn Forte#error "port this routine" 157fcf3ce44SJohn Forte#endif 158fcf3ce44SJohn Forte SET_SIZE(nsc_callee) 159fcf3ce44SJohn Forte 160fcf3ce44SJohn Forte#endif /* lint || DS_DDICT */ 161fcf3ce44SJohn Forte 162fcf3ce44SJohn Forte 163fcf3ce44SJohn Forte/* 164fcf3ce44SJohn Forte * nsc_threadp(void) 165fcf3ce44SJohn Forte * 166fcf3ce44SJohn Forte * C callable interface to get the current thread pointer. 167fcf3ce44SJohn Forte */ 168fcf3ce44SJohn Forte 169fcf3ce44SJohn Forte#if defined(lint) || defined(DS_DDICT) 170fcf3ce44SJohn Fortevoid * 171fcf3ce44SJohn Fortensc_threadp(void) 172fcf3ce44SJohn Forte{ 173fcf3ce44SJohn Forte return (NULL); 174fcf3ce44SJohn Forte} 175fcf3ce44SJohn Forte#else 176fcf3ce44SJohn Forte 177fcf3ce44SJohn Forte ENTRY(nsc_threadp) 178fcf3ce44SJohn Forte#if defined(__amd64) 179fcf3ce44SJohn Forte movq %gs:CPU_THREAD, %rax 180fcf3ce44SJohn Forte ret 181fcf3ce44SJohn Forte#elif defined(__i386) 182fcf3ce44SJohn Forte movl %gs:CPU_THREAD,%eax 183fcf3ce44SJohn Forte ret 184fcf3ce44SJohn Forte#else 185fcf3ce44SJohn Forte#error "port this routine" 186fcf3ce44SJohn Forte#endif 187fcf3ce44SJohn Forte SET_SIZE(nsc_threadp) 188fcf3ce44SJohn Forte 189fcf3ce44SJohn Forte#endif /* lint || DS_DDICT */ 190