17836SJohn.Forte@Sun.COM/* 27836SJohn.Forte@Sun.COM * CDDL HEADER START 37836SJohn.Forte@Sun.COM * 47836SJohn.Forte@Sun.COM * The contents of this file are subject to the terms of the 57836SJohn.Forte@Sun.COM * Common Development and Distribution License (the "License"). 67836SJohn.Forte@Sun.COM * You may not use this file except in compliance with the License. 77836SJohn.Forte@Sun.COM * 87836SJohn.Forte@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97836SJohn.Forte@Sun.COM * or http://www.opensolaris.org/os/licensing. 107836SJohn.Forte@Sun.COM * See the License for the specific language governing permissions 117836SJohn.Forte@Sun.COM * and limitations under the License. 127836SJohn.Forte@Sun.COM * 137836SJohn.Forte@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 147836SJohn.Forte@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157836SJohn.Forte@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 167836SJohn.Forte@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 177836SJohn.Forte@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 187836SJohn.Forte@Sun.COM * 197836SJohn.Forte@Sun.COM * CDDL HEADER END 207836SJohn.Forte@Sun.COM */ 217836SJohn.Forte@Sun.COM/* 227836SJohn.Forte@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 237836SJohn.Forte@Sun.COM * Use is subject to license terms. 247836SJohn.Forte@Sun.COM */ 257836SJohn.Forte@Sun.COM 267836SJohn.Forte@Sun.COM#if defined(lint) || defined(DS_DDICT) 277836SJohn.Forte@Sun.COM#include <sys/types.h> 287836SJohn.Forte@Sun.COM#include <sys/param.h> 297836SJohn.Forte@Sun.COM#else 30*7859SJohn.Forte@Sun.COM#include "assym.h" /* Determine value of CPU_THREAD */ 317836SJohn.Forte@Sun.COM#include <sys/asm_linkage.h> 327836SJohn.Forte@Sun.COM#endif 337836SJohn.Forte@Sun.COM 347836SJohn.Forte@Sun.COM#ifdef DS_DDICT 357836SJohn.Forte@Sun.COM#define uint8_t uchar_t 367836SJohn.Forte@Sun.COM#endif 377836SJohn.Forte@Sun.COM 387836SJohn.Forte@Sun.COM 397836SJohn.Forte@Sun.COM/* 407836SJohn.Forte@Sun.COM * Special support routines that can't be done with C 417836SJohn.Forte@Sun.COM * x86 variant 427836SJohn.Forte@Sun.COM */ 437836SJohn.Forte@Sun.COM 447836SJohn.Forte@Sun.COM/* 457836SJohn.Forte@Sun.COM * uint8_t nsc_ldstub(uint8_t *cp) 467836SJohn.Forte@Sun.COM * 477836SJohn.Forte@Sun.COM * Store 0xFF at the specified location, and return its previous content. 487836SJohn.Forte@Sun.COM */ 497836SJohn.Forte@Sun.COM 507836SJohn.Forte@Sun.COM#if defined(lint) || defined(DS_DDICT) 517836SJohn.Forte@Sun.COMuint8_t 527836SJohn.Forte@Sun.COMnsc_ldstub(uint8_t *cp) 537836SJohn.Forte@Sun.COM{ 547836SJohn.Forte@Sun.COM uint8_t rv; 557836SJohn.Forte@Sun.COM rv = *cp; 567836SJohn.Forte@Sun.COM *cp = 0xFF; 577836SJohn.Forte@Sun.COM return (rv); 587836SJohn.Forte@Sun.COM} 597836SJohn.Forte@Sun.COM#else 607836SJohn.Forte@Sun.COM ENTRY(nsc_ldstub) 617836SJohn.Forte@Sun.COM#if defined(__amd64) 627836SJohn.Forte@Sun.COM movl $0xff,%eax 637836SJohn.Forte@Sun.COM lock 647836SJohn.Forte@Sun.COM xchgb %al, (%rdi) /* rdi = lock addr */ 657836SJohn.Forte@Sun.COM ret 667836SJohn.Forte@Sun.COM#elif defined(__i386) 677836SJohn.Forte@Sun.COM movl 4(%esp), %ecx /* ecx = lock addr */ 687836SJohn.Forte@Sun.COM movl $0xff, %eax /* eax = 0xff */ 697836SJohn.Forte@Sun.COM lock 707836SJohn.Forte@Sun.COM xchgb %al, (%ecx) /* atomic swap eax <-> *ecx */ 717836SJohn.Forte@Sun.COM ret 727836SJohn.Forte@Sun.COM#else 737836SJohn.Forte@Sun.COM#error "port this routine" 747836SJohn.Forte@Sun.COM#endif 757836SJohn.Forte@Sun.COM SET_SIZE(nsc_ldstub) 767836SJohn.Forte@Sun.COM#endif 777836SJohn.Forte@Sun.COM 787836SJohn.Forte@Sun.COM/* 797836SJohn.Forte@Sun.COM * nsc_membar_stld(void) 807836SJohn.Forte@Sun.COM * 817836SJohn.Forte@Sun.COM * On SPARC this is a C callable interface to SPARC asm membar instruction. 827836SJohn.Forte@Sun.COM * For x86 we brute force it with a #LOCK instruction. 837836SJohn.Forte@Sun.COM */ 847836SJohn.Forte@Sun.COM 857836SJohn.Forte@Sun.COM#if defined(lint) || defined(DS_DDICT) 867836SJohn.Forte@Sun.COMvoid 877836SJohn.Forte@Sun.COMnsc_membar_stld(void) 887836SJohn.Forte@Sun.COM{} 897836SJohn.Forte@Sun.COM#else 907836SJohn.Forte@Sun.COM 917836SJohn.Forte@Sun.COM ENTRY(nsc_membar_stld) 927836SJohn.Forte@Sun.COM#if defined(__amd64) 937836SJohn.Forte@Sun.COM mfence 947836SJohn.Forte@Sun.COM ret 957836SJohn.Forte@Sun.COM#elif defined(__i386) 967836SJohn.Forte@Sun.COM lock 977836SJohn.Forte@Sun.COM xorl $0, (%esp) 987836SJohn.Forte@Sun.COM ret 997836SJohn.Forte@Sun.COM#else 1007836SJohn.Forte@Sun.COM#error "port this routine" 1017836SJohn.Forte@Sun.COM#endif 1027836SJohn.Forte@Sun.COM SET_SIZE(nsc_membar_stld) 1037836SJohn.Forte@Sun.COM 1047836SJohn.Forte@Sun.COM#endif /* lint || DS_DDICT */ 1057836SJohn.Forte@Sun.COM 1067836SJohn.Forte@Sun.COM 1077836SJohn.Forte@Sun.COM/* 1087836SJohn.Forte@Sun.COM * if a() calls b() calls nsc_caller(), 1097836SJohn.Forte@Sun.COM * nsc_caller() returns return address in a(). 1107836SJohn.Forte@Sun.COM */ 1117836SJohn.Forte@Sun.COM 1127836SJohn.Forte@Sun.COM#if defined(lint) || defined(DS_DDICT) 1137836SJohn.Forte@Sun.COMcaddr_t 1147836SJohn.Forte@Sun.COMnsc_caller(void) 1157836SJohn.Forte@Sun.COM{ 1167836SJohn.Forte@Sun.COM return (0); 1177836SJohn.Forte@Sun.COM} 1187836SJohn.Forte@Sun.COM#else 1197836SJohn.Forte@Sun.COM 1207836SJohn.Forte@Sun.COM ENTRY(nsc_caller) 1217836SJohn.Forte@Sun.COM#if defined(__amd64) 1227836SJohn.Forte@Sun.COM movq 8(%rbp), %rax /* b()'s return pc, in a() */ 1237836SJohn.Forte@Sun.COM ret 1247836SJohn.Forte@Sun.COM#elif defined(__i386) 1257836SJohn.Forte@Sun.COM movl 4(%ebp), %eax /* b()'s return pc, in a() */ 1267836SJohn.Forte@Sun.COM ret 1277836SJohn.Forte@Sun.COM#else 1287836SJohn.Forte@Sun.COM#error "port this routine" 1297836SJohn.Forte@Sun.COM#endif 1307836SJohn.Forte@Sun.COM SET_SIZE(nsc_caller) 1317836SJohn.Forte@Sun.COM 1327836SJohn.Forte@Sun.COM#endif /* lint || DS_DDICT */ 1337836SJohn.Forte@Sun.COM 1347836SJohn.Forte@Sun.COM 1357836SJohn.Forte@Sun.COM/* 1367836SJohn.Forte@Sun.COM * if a() calls nsc_callee(), nsc_callee() returns the 1377836SJohn.Forte@Sun.COM * return address in a(); 1387836SJohn.Forte@Sun.COM */ 1397836SJohn.Forte@Sun.COM 1407836SJohn.Forte@Sun.COM#if defined(lint) || defined(DS_DDICT) 1417836SJohn.Forte@Sun.COMcaddr_t 1427836SJohn.Forte@Sun.COMnsc_callee(void) 1437836SJohn.Forte@Sun.COM{ 1447836SJohn.Forte@Sun.COM return (0); 1457836SJohn.Forte@Sun.COM} 1467836SJohn.Forte@Sun.COM#else 1477836SJohn.Forte@Sun.COM 1487836SJohn.Forte@Sun.COM ENTRY(nsc_callee) 1497836SJohn.Forte@Sun.COM#if defined(__amd64) 1507836SJohn.Forte@Sun.COM movq (%rsp), %rax /* callee()'s return pc, in a() */ 1517836SJohn.Forte@Sun.COM ret 1527836SJohn.Forte@Sun.COM#elif defined(__i386) 1537836SJohn.Forte@Sun.COM movl (%esp), %eax /* callee()'s return pc, in a() */ 1547836SJohn.Forte@Sun.COM ret 1557836SJohn.Forte@Sun.COM#else 1567836SJohn.Forte@Sun.COM#error "port this routine" 1577836SJohn.Forte@Sun.COM#endif 1587836SJohn.Forte@Sun.COM SET_SIZE(nsc_callee) 1597836SJohn.Forte@Sun.COM 1607836SJohn.Forte@Sun.COM#endif /* lint || DS_DDICT */ 1617836SJohn.Forte@Sun.COM 1627836SJohn.Forte@Sun.COM 1637836SJohn.Forte@Sun.COM/* 1647836SJohn.Forte@Sun.COM * nsc_threadp(void) 1657836SJohn.Forte@Sun.COM * 1667836SJohn.Forte@Sun.COM * C callable interface to get the current thread pointer. 1677836SJohn.Forte@Sun.COM */ 1687836SJohn.Forte@Sun.COM 1697836SJohn.Forte@Sun.COM#if defined(lint) || defined(DS_DDICT) 1707836SJohn.Forte@Sun.COMvoid * 1717836SJohn.Forte@Sun.COMnsc_threadp(void) 1727836SJohn.Forte@Sun.COM{ 1737836SJohn.Forte@Sun.COM return (NULL); 1747836SJohn.Forte@Sun.COM} 1757836SJohn.Forte@Sun.COM#else 1767836SJohn.Forte@Sun.COM 1777836SJohn.Forte@Sun.COM ENTRY(nsc_threadp) 1787836SJohn.Forte@Sun.COM#if defined(__amd64) 1797836SJohn.Forte@Sun.COM movq %gs:CPU_THREAD, %rax 1807836SJohn.Forte@Sun.COM ret 1817836SJohn.Forte@Sun.COM#elif defined(__i386) 1827836SJohn.Forte@Sun.COM movl %gs:CPU_THREAD,%eax 1837836SJohn.Forte@Sun.COM ret 1847836SJohn.Forte@Sun.COM#else 1857836SJohn.Forte@Sun.COM#error "port this routine" 1867836SJohn.Forte@Sun.COM#endif 1877836SJohn.Forte@Sun.COM SET_SIZE(nsc_threadp) 1887836SJohn.Forte@Sun.COM 1897836SJohn.Forte@Sun.COM#endif /* lint || DS_DDICT */ 190