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 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 / 28 / Inline functions for i386 kernels. 29 / Shared between all x86 platform variants. 30 / 31 32 / 33 / return current thread pointer 34 / 35 / NOTE: the "0x10" 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 movl %gs:0x10, %eax 45 .end 46 47 / 48 / return current cpu pointer 49 / 50 .inline curcpup,0 51 movl %gs:0xc, %eax 52 .end 53 54 / 55 / return caller 56 / 57 .inline caller,0 58 movl 4(%ebp), %eax 59 .end 60 61 / 62 / convert ipl to spl. This is the identity function for i86 63 / 64 .inline ipltospl,0 65 movl (%esp), %eax 66 .end 67 68 / 69 / Networking byte order functions (too bad, Intel has the wrong byte order) 70 / 71 .inline htonll,4 72 movl (%esp), %edx 73 movl 4(%esp), %eax 74 bswap %edx 75 bswap %eax 76 .end 77 78 .inline ntohll,4 79 movl (%esp), %edx 80 movl 4(%esp), %eax 81 bswap %edx 82 bswap %eax 83 .end 84 85 .inline htonl,4 86 movl (%esp), %eax 87 bswap %eax 88 .end 89 90 .inline ntohl,4 91 movl (%esp), %eax 92 bswap %eax 93 .end 94 95 .inline htons,4 96 movl (%esp), %eax 97 bswap %eax 98 shrl $16, %eax 99 .end 100 101 .inline ntohs,4 102 movl (%esp), %eax 103 bswap %eax 104 shrl $16, %eax 105 .end 106 107 /* 108 * multiply two long numbers and yield a u_longlong_t result 109 * Provided to manipulate hrtime_t values. 110 */ 111 .inline mul32, 8 112 movl 4(%esp), %eax 113 movl (%esp), %ecx 114 mull %ecx 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 (%esp), %eax 127 movl 4(%esp), %edx 128 lock 129 orb %dl,(%eax) 130 .end 131 132 .inline atomic_andb,8 133 movl (%esp), %eax 134 movl 4(%esp), %edx 135 lock 136 andb %dl,(%eax) 137 .end 138 139 /* 140 * atomic inc/dec operations. 141 * void atomic_inc16(uint16_t *addr) { ++*addr; } 142 * void atomic_dec16(uint16_t *addr) { --*addr; } 143 */ 144 .inline atomic_inc16,4 145 movl (%esp), %eax 146 lock 147 incw (%eax) 148 .end 149 150 .inline atomic_dec16,4 151 movl (%esp), %eax 152 lock 153 decw (%eax) 154 .end 155 156 /* 157 * Call the pause instruction. To the Pentium 4 Xeon processor, it acts as 158 * a hint that the code sequence is a busy spin-wait loop. Without a pause 159 * instruction in these loops, the P4 Xeon processor may suffer a severe 160 * penalty when exiting the loop because the processor detects a possible 161 * memory violation. Inserting the pause instruction significantly reduces 162 * the likelihood of a memory order violation, improving performance. 163 * The pause instruction is a NOP on all other IA-32 processors. 164 */ 165 .inline ht_pause, 0 166 rep / our compiler doesn't support "pause" yet, 167 nop / so we're using "F3 90" opcode directly 168 .end 169 170 /* 171 * prefetch 64 bytes 172 * 173 * prefetch is an SSE extension which is not supported on older 32-bit processors 174 * so define this as a no-op for now 175 */ 176 177 .inline prefetch_read_many,4 178 / movl (%esp), %eax 179 / prefetcht0 (%eax) 180 / prefetcht0 32(%eax) 181 .end 182 183 .inline prefetch_read_once,4 184 / movl (%esp), %eax 185 / prefetchnta (%eax) 186 / prefetchnta 32(%eax) 187 .end 188 189 .inline prefetch_write_many,4 190 / movl (%esp), %eax 191 / prefetcht0 (%eax) 192 / prefetcht0 32(%eax) 193 .end 194 195 .inline prefetch_write_once,4 196 / movl (%esp), %eax 197 / prefetcht0 (%eax) 198 / prefetcht0 32(%eax) 199 .end 200