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