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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22/* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29/ 30/ In-line functions for i86 kernels. 31/ 32 33/ 34/ return current thread pointer 35/ 36/ NOTE: the "0x10" should be replaced by the computed value of the 37/ offset of "cpu_thread" from the beginning of the struct cpu. 38/ Including "assym.h" does not work, however, since that stuff 39/ is PSM-specific and is only visible to the 'unix' build anyway. 40/ Same with current cpu pointer, where "0xc" should be replaced 41/ by the computed value of the offset of "cpu_self". 42/ Ugh -- what a disaster. 43/ 44 .inline threadp,0 45 movl %gs:0x10, %eax 46 .end 47 48/ 49/ return current cpu pointer 50/ 51 .inline curcpup,0 52 movl %gs:0xc, %eax 53 .end 54 55/ 56/ return caller 57/ 58 .inline caller,0 59 movl 4(%ebp), %eax 60 .end 61 62/ 63/ return value of cr3 register 64/ 65 .inline getcr3,0 66 movl %cr3, %eax 67 .end 68 69/ 70/ reload cr3 register with its current value 71/ 72 .inline reload_cr3,0 73 movl %cr3, %eax 74 movl %eax, %cr3 75 .end 76 77/* 78 * Put a new value into cr3 (page table base register 79 * void setcr3(void *value) 80 */ 81 .inline setcr3,4 82 movl (%esp), %eax 83 movl %eax, %cr3 84 .end 85 86/ 87/ invalidate and flush cache. 88/ 89 .inline cache_bug,0 90 wbinvd 91 .end 92 93/ 94/ convert ipl to spl. This is the identity function for i86 95/ 96 .inline ipltospl,0 97 movl (%esp), %eax 98 .end 99 100/ 101/ enable interrupts 102/ 103 .inline sti,0 104 sti 105 .end 106 107/ 108/ disable interrupts 109/ 110 .inline cli,0 111 cli 112 .end 113 114/ 115/ find the low order bit in a word 116/ 117 .inline lowbit,4 118 movl $-1, %eax 119 bsfl (%esp), %eax 120 incl %eax 121 .end 122/ 123/ find the high order bit in a word 124/ 125 .inline highbit,4 126 movl $-1, %eax 127 bsrl (%esp), %eax 128 incl %eax 129 .end 130 131/ 132/ disable interrupts and return value describing if interrupts were enabled 133/ 134 .inline clear_int_flag,0 135 pushfl 136 cli 137 popl %eax 138 .end 139 140 .inline intr_clear,0 141 pushfl 142 cli 143 popl %eax 144 .end 145 146/ 147/ restore interrupt enable flag to value returned from 'clear_int_flag' above 148/ 149 .inline restore_int_flag,4 150 pushl (%esp) 151 popfl 152 .end 153 154 .inline intr_restore,4 155 pushl (%esp) 156 popfl 157 .end 158 159/ 160/ in and out 161/ 162 .inline inb,4 163 movl (%esp), %edx 164 xorl %eax, %eax 165 inb (%dx) 166 .end 167 168 .inline inw,4 169 movl (%esp), %edx 170 xorl %eax, %eax 171 inw (%dx) 172 .end 173 174 .inline inl,4 175 movl (%esp), %edx 176 xorl %eax, %eax 177 inl (%dx) 178 .end 179 180 .inline outb,8 181 movl (%esp), %edx 182 movl 4(%esp), %eax 183 outb (%dx) 184 .end 185 186 .inline outw,8 187 movl (%esp), %edx 188 movl 4(%esp), %eax 189 outw (%dx) 190 .end 191 192 .inline outl,8 193 movl (%esp), %edx 194 movl 4(%esp), %eax 195 outl (%dx) 196 .end 197 198/ 199/ Networking byte order functions (too bad, Intel has the wrong byte order) 200/ 201 202 .inline htonl,4 203 movl (%esp), %eax 204 bswap %eax 205 .end 206 207 .inline ntohl,4 208 movl (%esp), %eax 209 bswap %eax 210 .end 211 212 .inline htons,4 213 movl (%esp), %eax 214 bswap %eax 215 shrl $16, %eax 216 .end 217 218 .inline ntohs,4 219 movl (%esp), %eax 220 bswap %eax 221 shrl $16, %eax 222 .end 223 224/* 225 * multiply two long numbers and yield a u_lonlong_t result 226 * Provided to manipulate hrtime_t values. 227 */ 228 .inline mul32, 8 229 movl 4(%esp), %eax 230 movl (%esp), %ecx 231 mull %ecx 232 .end 233 234/* 235 * Unlock hres_lock and increment the count value. (See clock.h) 236 */ 237 .inline unlock_hres_lock, 0 238 lock 239 incl hres_lock 240 .end 241 242 .inline atomic_orb,8 243 movl (%esp), %eax 244 movl 4(%esp), %edx 245 lock 246 orb %dl,(%eax) 247 .end 248 249 .inline atomic_andb,8 250 movl (%esp), %eax 251 movl 4(%esp), %edx 252 lock 253 andb %dl,(%eax) 254 .end 255 256 257/* 258 * atomic inc/dec operations. 259 * void atomic_inc16(uint16_t *addr) { ++*addr; } 260 * void atomic_dec16(uint16_t *addr) { --*addr; } 261 */ 262 .inline atomic_inc16,4 263 movl (%esp), %eax 264 lock 265 incw (%eax) 266 .end 267 268 .inline atomic_dec16,4 269 movl (%esp), %eax 270 lock 271 decw (%eax) 272 .end 273 274/* 275 * Invalidate TLB translation to 1 page. 276 * void mmu_tlbflush_entry(void *addr) 277 */ 278 .inline mmu_tlbflush_entry,4 279 movl (%esp), %eax 280 invlpg (%eax) 281 .end 282 283/* 284 * Read Time Stamp Counter 285 * uint64_t tsc_read(); 286 * 287 * usage: 288 * uint64_t cycles = tsc_read(); 289 * 290 * PPro & PII take no less than 34 cycles to execute rdtsc + stores. 291 * Pentium takes about 16 cycles. 292 */ 293 .inline tsc_read, 0 294 rdtsc / %edx:%eax = RDTSC 295 .end 296 297/* 298 * void tsc_clear(register) 299 * Clear the local Time Stamp Counter via write-MSR instruction. 300 * Note that while this is a 64-bit write, the top 32-bits are 301 * ignored, so it isn't massively useful to write anything other 302 * than zero. 303 */ 304 .inline tsc_reset, 4 305 movl (%esp), %ecx 306 xorl %eax, %eax 307 movl %eax, %edx 308 wrmsr 309 ret 310 .end 311 312/* 313 * Call the pause instruction. To the Pentium 4 Xeon processor, it acts as 314 * a hint that the code sequence is a busy spin-wait loop. Without a pause 315 * instruction in these loops, the P4 Xeon processor may suffer a severe 316 * penalty when exiting the loop because the processor detects a possible 317 * memory violation. Inserting the pause instruction significantly reduces 318 * the likelihood of a memory order violation, improving performance. 319 * The pause instruction is a NOP on all other IA-32 processors. 320 */ 321 .inline ht_pause, 0 322 rep / our compiler doesn't support "pause" yet, 323 nop / so we're using "F3 90" opcode directly 324 .end 325 326/* 327 * Call the halt instruction. This will put the CPU to sleep until 328 * it is again awoken via an interrupt. 329 * This function should be called with interrupts already disabled 330 * for the CPU. 331 * Note that "sti" will only enable interrupts at the end of the 332 * subsequent instruction...in this case: "hlt". 333 */ 334 .inline i86_halt,0 335 sti 336 hlt 337 .end 338