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 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26#pragma ident "%Z%%M% %I% %E% SMI" 27 28/ 29/ In-line functions for amd64 kernels. 30/ 31 32/ 33/ return current thread pointer 34/ 35/ NOTE: the "0x18" should be replaced by the computed value of the 36/ offset of "cpu_thread" from the beginning of the struct cpu. 37/ Including "assym.h" does not work, however, since that stuff 38/ is PSM-specific and is only visible to the 'unix' build anyway. 39/ Same with current cpu pointer, where "0xc" should be replaced 40/ by the computed value of the offset of "cpu_self". 41/ Ugh -- what a disaster. 42/ 43 .inline threadp,0 44 movq %gs:0x18, %rax 45 .end 46 47/ 48/ return current cpu pointer 49/ 50 .inline curcpup,0 51 movq %gs:0x10, %rax 52 .end 53 54/ 55/ return caller 56/ 57 .inline caller,0 58 movq 8(%rbp), %rax 59 .end 60 61/ 62/ convert ipl to spl. This is the identity function for i86 63/ 64 .inline ipltospl,0 65 movq %rdi, %rax 66 .end 67 68/ 69/ find the low order bit in a word 70/ 71 .inline lowbit,4 72 movq $-1, %rax 73 bsfq %rdi, %rax 74 incq %rax 75 .end 76 77/ 78/ Networking byte order functions (too bad, Intel has the wrong byte order) 79/ 80 81 .inline htonl,4 82 movl %edi, %eax 83 bswap %eax 84 .end 85 86 .inline ntohl,4 87 movl %edi, %eax 88 bswap %eax 89 .end 90 91 .inline htons,4 92 movl %edi, %eax 93 bswap %eax 94 shrl $16, %eax 95 .end 96 97 .inline ntohs,4 98 movl %edi, %eax 99 bswap %eax 100 shrl $16, %eax 101 .end 102 103/* 104 * multiply two long numbers and yield a u_lonlong_t result 105 * Provided to manipulate hrtime_t values. 106 */ 107 /* XX64 These don't work correctly with SOS9 build 13.0 yet 108 .inline mul32, 8 109 xorl %edx, %edx 110 movl %edi, %eax 111 mull %esi 112 shlq $32, %rdx 113 orq %rdx, %rax 114 ret 115 .end 116 */ 117/* 118 * Unlock hres_lock and increment the count value. (See clock.h) 119 */ 120 .inline unlock_hres_lock, 0 121 lock 122 incl hres_lock 123 .end 124 125 .inline atomic_orb,8 126 movl %esi, %eax 127 lock 128 orb %al,(%rdi) 129 .end 130 131 .inline atomic_andb,8 132 movl %esi, %eax 133 lock 134 andb %al,(%rdi) 135 .end 136 137/* 138 * atomic inc/dec operations. 139 * void atomic_inc16(uint16_t *addr) { ++*addr; } 140 * void atomic_dec16(uint16_t *addr) { --*addr; } 141 */ 142 .inline atomic_inc16,4 143 lock 144 incw (%rdi) 145 .end 146 147 .inline atomic_dec16,4 148 lock 149 decw (%rdi) 150 .end 151 152/* 153 * atomic bit clear 154 */ 155 .inline atomic_btr32,8 156 lock 157 btrl %esi, (%rdi) 158 setc %al 159 .end 160 161/* 162 * Call the pause instruction. To the Pentium 4 Xeon processor, it acts as 163 * a hint that the code sequence is a busy spin-wait loop. Without a pause 164 * instruction in these loops, the P4 Xeon processor may suffer a severe 165 * penalty when exiting the loop because the processor detects a possible 166 * memory violation. Inserting the pause instruction significantly reduces 167 * the likelihood of a memory order violation, improving performance. 168 * The pause instruction is a NOP on all other IA-32 processors. 169 */ 170 .inline ht_pause, 0 171 pause 172 .end 173 174/* 175 * inlines for update_sregs(). 176 */ 177 .inline __set_ds, 0 178 movw %di, %ds 179 .end 180 181 .inline __set_es, 0 182 movw %di, %es 183 .end 184 185 .inline __set_fs, 0 186 movw %di, %fs 187 .end 188 189 .inline __set_gs, 0 190 movw %di, %gs 191 .end 192 193 /* 194 * OPTERON_ERRATUM_88 requires mfence 195 */ 196 .inline __swapgs, 0 197 mfence 198 swapgs 199 .end 200