Annotation of src/sys/arch/amd64/amd64/cpufunc.S, Revision 1.1.6.2
1.1.6.2 ! ad 1: /* $NetBSD$ */
! 2:
! 3: /*-
! 4: * Copyright (c) 1998, 2007 The NetBSD Foundation, Inc.
! 5: * All rights reserved.
! 6: *
! 7: * This code is derived from software contributed to The NetBSD Foundation
! 8: * by Charles M. Hannum, and by Andrew Doran.
! 9: *
! 10: * Redistribution and use in source and binary forms, with or without
! 11: * modification, are permitted provided that the following conditions
! 12: * are met:
! 13: * 1. Redistributions of source code must retain the above copyright
! 14: * notice, this list of conditions and the following disclaimer.
! 15: * 2. Redistributions in binary form must reproduce the above copyright
! 16: * notice, this list of conditions and the following disclaimer in the
! 17: * documentation and/or other materials provided with the distribution.
! 18: * 3. All advertising materials mentioning features or use of this software
! 19: * must display the following acknowledgement:
! 20: * This product includes software developed by the NetBSD
! 21: * Foundation, Inc. and its contributors.
! 22: * 4. Neither the name of The NetBSD Foundation nor the names of its
! 23: * contributors may be used to endorse or promote products derived
! 24: * from this software without specific prior written permission.
! 25: *
! 26: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
! 27: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! 28: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! 29: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
! 30: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! 31: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! 32: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! 33: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! 34: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! 35: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 36: * POSSIBILITY OF SUCH DAMAGE.
! 37: */
! 38:
! 39: /*
! 40: * Functions to provide access to i386-specific instructions.
! 41: */
! 42:
! 43: #include <machine/asm.h>
! 44: #include <machine/specialreg.h>
! 45: #include <machine/segments.h>
! 46:
! 47: #include "assym.h"
! 48:
! 49: /* Small and slow, so align less. */
! 50: #undef _ALIGN_TEXT
! 51: #define _ALIGN_TEXT .align 8
! 52:
! 53: NENTRY(x86_lfence)
! 54: lfence
! 55: ret
! 56:
! 57: NENTRY(x86_sfence)
! 58: sfence
! 59: ret
! 60:
! 61: NENTRY(x86_mfence)
! 62: mfence
! 63: ret
! 64:
! 65: NENTRY(invlpg)
! 66: invlpg (%rdi)
! 67: ret
! 68:
! 69: NENTRY(lidt)
! 70: lidt (%rdi)
! 71: ret
! 72:
! 73: NENTRY(lldt)
! 74: lldt %di
! 75: ret
! 76:
! 77: NENTRY(ltr)
! 78: ltr %di
! 79: ret
! 80:
! 81: NENTRY(lcr0)
! 82: movq %rdi, %cr0
! 83: ret
! 84:
! 85: NENTRY(rcr0)
! 86: movq %cr0, %rax
! 87: ret
! 88:
! 89: NENTRY(rcr2)
! 90: movq %cr2, %rax
! 91: ret
! 92:
! 93: NENTRY(lcr3)
! 94: movq %rdi, %cr3
! 95: ret
! 96:
! 97: NENTRY(rcr3)
! 98: movq %cr3, %rax
! 99: ret
! 100:
! 101: NENTRY(lcr4)
! 102: movq %rdi, %cr4
! 103: ret
! 104:
! 105: NENTRY(rcr4)
! 106: movq %cr4, %rax
! 107: ret
! 108:
! 109: NENTRY(lcr8)
! 110: movq %rdi, %cr8
! 111: ret
! 112:
! 113: NENTRY(rcr8)
! 114: movq %cr8, %rax
! 115: ret
! 116:
! 117: /*
! 118: * Big hammer: flush all TLB entries, including ones from PTE's
! 119: * with the G bit set. This should only be necessary if TLB
! 120: * shootdown falls far behind.
! 121: *
! 122: * Intel Architecture Software Developer's Manual, Volume 3,
! 123: * System Programming, section 9.10, "Invalidating the
! 124: * Translation Lookaside Buffers (TLBS)":
! 125: * "The following operations invalidate all TLB entries, irrespective
! 126: * of the setting of the G flag:
! 127: * ...
! 128: * "(P6 family processors only): Writing to control register CR4 to
! 129: * modify the PSE, PGE, or PAE flag."
! 130: *
! 131: * (the alternatives not quoted above are not an option here.)
! 132: */
! 133: NENTRY(tlbflushg)
! 134: movq %cr4, %rax
! 135: movq %rax, %rdx
! 136: andq $~CR4_PGE, %rdx
! 137: movq %rdx, %cr4
! 138: movq %rax, %cr4
! 139: ret
! 140:
! 141: NENTRY(tlbflush)
! 142: movq %cr3, %rax
! 143: movq %rax, %cr3
! 144: ret
! 145:
! 146: NENTRY(ldr6)
! 147: movq %rdi, %dr6
! 148: ret
! 149:
! 150: NENTRY(rdr6)
! 151: movq %dr6, %rdi
! 152: ret
! 153:
! 154: NENTRY(x86_disable_intr)
! 155: cli
! 156: ret
! 157:
! 158: NENTRY(x86_enable_intr)
! 159: sti
! 160: ret
! 161:
! 162: NENTRY(x86_read_flags)
! 163: pushfq
! 164: popq %rax
! 165: ret
! 166:
! 167: STRONG_ALIAS(x86_read_psl,x86_read_flags)
! 168:
! 169: NENTRY(x86_write_flags)
! 170: pushq %rdi
! 171: popfq
! 172: ret
! 173:
! 174: STRONG_ALIAS(x86_write_psl,x86_write_flags)
! 175:
! 176: NENTRY(rdmsr)
! 177: movq %rdi, %rcx
! 178: xorq %rax, %rax
! 179: rdmsr
! 180: shlq $32, %rdx
! 181: orq %rdx, %rax
! 182: ret
! 183:
! 184: NENTRY(wrmsr)
! 185: movq %rdi, %rcx
! 186: movq %rsi, %rax
! 187: movq %rsi, %rdx
! 188: shrq $32, %rdx
! 189: wrmsr
! 190: ret
! 191:
! 192: NENTRY(rdmsr_locked)
! 193: movq %rdi, %rcx
! 194: xorq %rax, %rax
! 195: movl $OPTERON_MSR_PASSCODE, %edi
! 196: rdmsr
! 197: shlq $32, %rdx
! 198: orq %rdx, %rax
! 199: ret
! 200:
! 201: NENTRY(wrmsr_locked)
! 202: movq %rdi, %rcx
! 203: movq %rsi, %rax
! 204: movq %rsi, %rdx
! 205: shrq $32, %rdx
! 206: movl $OPTERON_MSR_PASSCODE, %edi
! 207: wrmsr
! 208: ret
! 209:
! 210: NENTRY(wbinvd)
! 211: wbinvd
! 212: ret
! 213:
! 214: NENTRY(rdtsc)
! 215: xorq %rax, %rax
! 216: rdtsc
! 217: shlq $32, %rdx
! 218: orq %rdx, %rax
! 219: ret
! 220:
! 221: NENTRY(rdpmc)
! 222: movq %rdi, %rcx
! 223: xorq %rax, %rax
! 224: rdpmc
! 225: shlq $32, %rdx
! 226: orq %rdx, %rax
! 227: ret
! 228:
! 229: NENTRY(breakpoint)
! 230: int $0x03 /* paranoid, not 'int3' */
! 231: ret
! 232:
! 233: NENTRY(x86_atomic_testset_ul)
! 234: movq %rsi, %rax
! 235: xchgq %rax, (%rdi)
! 236: ret
! 237:
! 238: NENTRY(x86_atomic_testset_i)
! 239: movl %esi, %eax
! 240: xchgl %eax, (%rdi)
! 241: ret
! 242:
! 243: NENTRY(x86_atomic_testset_b)
! 244: movl %esi, %eax
! 245: xchgb %al, (%rdi)
! 246: andl $0xff, %eax
! 247: ret
! 248:
! 249: NENTRY(x86_atomic_setbits_l)
! 250: lock
! 251: orq %rsi, (%rdi)
! 252: ret
! 253:
! 254: NENTRY(x86_atomic_clearbits_l)
! 255: notq %rsi
! 256: lock
! 257: andq %rsi, (%rdi)
! 258: ret
! 259:
! 260: NENTRY(x86_curcpu)
! 261: movq %gs:(CPU_INFO_SELF), %rax
! 262: ret
! 263:
! 264: NENTRY(x86_curlwp)
! 265: movq %gs:(CPU_INFO_CURLWP), %rax
! 266: ret
! 267:
! 268: NENTRY(__byte_swap_u32_variable)
! 269: movl %edi, %eax
! 270: bswapl %eax
! 271: ret
! 272:
! 273: NENTRY(__byte_swap_u16_variable)
! 274: movl %edi, %eax
! 275: xchgb %al, %ah
! 276: ret
! 277:
! 278: /*
! 279: * void lgdt(struct region_descriptor *rdp);
! 280: *
! 281: * Load a new GDT pointer (and do any necessary cleanup).
! 282: * XXX It's somewhat questionable whether reloading all the segment registers
! 283: * is necessary, since the actual descriptor data is not changed except by
! 284: * process creation and exit, both of which clean up via task switches. OTOH,
! 285: * this only happens at run time when the GDT is resized.
! 286: */
! 287: NENTRY(lgdt)
! 288: /* Reload the descriptor table. */
! 289: movq %rdi,%rax
! 290: lgdt (%rax)
! 291: /* Flush the prefetch q. */
! 292: jmp 1f
! 293: nop
! 294: 1: /* Reload "stale" selectors. */
! 295: movl $GSEL(GDATA_SEL, SEL_KPL),%eax
! 296: movl %eax,%ds
! 297: movl %eax,%es
! 298: movl %eax,%ss
! 299: /* FALLTHROUGH */
! 300:
! 301: /*
! 302: * void x86_flush()
! 303: *
! 304: * Flush instruction pipelines by doing an intersegment (far) return.
! 305: */
! 306: NENTRY(x86_flush)
! 307: popq %rax
! 308: pushq $GSEL(GCODE_SEL, SEL_KPL)
! 309: pushq %rax
! 310: lretq
! 311:
! 312: /* Waits - set up stack frame. */
! 313: NENTRY(x86_hlt)
! 314: pushq %rbp
! 315: movq %rsp, %rbp
! 316: hlt
! 317: leave
! 318: ret
! 319:
! 320: /* Waits - set up stack frame. */
! 321: NENTRY(x86_stihlt)
! 322: pushq %rbp
! 323: movq %rsp, %rbp
! 324: sti
! 325: hlt
! 326: leave
! 327: ret
! 328:
! 329: NENTRY(x86_monitor)
! 330: movq %rdi, %rax
! 331: movq %rsi, %rcx
! 332: monitor %eax, %ecx, %edx /* XXXgas %rax */
! 333: ret
! 334:
! 335: /* Waits - set up stack frame. */
! 336: NENTRY(x86_mwait)
! 337: pushq %rbp
! 338: movq %rsp, %rbp
! 339: movq %rdi, %rax
! 340: movq %rsi, %rcx
! 341: mwait %eax, %ecx
! 342: leave
! 343: ret
! 344:
! 345: NENTRY(x86_pause)
! 346: pause
! 347: ret
! 348:
! 349: NENTRY(x86_cpuid)
! 350: movq %rbx, %r8
! 351: movq %rdi, %rax
! 352: cpuid
! 353: movl %eax, 0(%rsi)
! 354: movl %ebx, 4(%rsi)
! 355: movl %ecx, 8(%rsi)
! 356: movl %edx, 12(%rsi)
! 357: movq %r8, %rbx
! 358: ret
! 359:
! 360: NENTRY(getss)
! 361: movl %ss, %eax
! 362: ret
! 363:
! 364: NENTRY(fldcw)
! 365: fldcw (%rdi)
! 366: ret
! 367:
! 368: NENTRY(fnclex)
! 369: fnclex
! 370: ret
! 371:
! 372: NENTRY(fninit)
! 373: fninit
! 374: ret
! 375:
! 376: NENTRY(fnsave)
! 377: fnsave (%rdi)
! 378: ret
! 379:
! 380: NENTRY(fnstcw)
! 381: fnstcw (%rdi)
! 382: ret
! 383:
! 384: NENTRY(fnstsw)
! 385: fnstsw (%rdi)
! 386: ret
! 387:
! 388: NENTRY(fp_divide_by_0)
! 389: fldz
! 390: fld1
! 391: fdiv %st, %st(1)
! 392: fwait
! 393: ret
! 394:
! 395: NENTRY(frstor)
! 396: frstor (%rdi)
! 397: ret
! 398:
! 399: ENTRY(fwait)
! 400: fwait
! 401: ret
! 402:
! 403: ENTRY(clts)
! 404: clts
! 405: ret
! 406:
! 407: ENTRY(stts)
! 408: movq %cr0, %rax
! 409: orq $CR0_TS, %rax
! 410: movq %rax, %cr0
! 411: ret
! 412:
! 413: NENTRY(fxsave)
! 414: fxsave (%rdi)
! 415: ret
! 416:
! 417: NENTRY(fxrstor)
! 418: fxrstor (%rdi)
! 419: ret
! 420:
! 421: NENTRY(fldummy)
! 422: ffree %st(7)
! 423: fld (%rdi)
! 424: ret
! 425:
! 426: NENTRY(x86_ldmxcsr)
! 427: ldmxcsr (%rdi)
! 428: ret
! 429:
! 430: NENTRY(inb)
! 431: movq %rdi, %rdx
! 432: xorq %rax, %rax
! 433: inb %dx, %al
! 434: ret
! 435:
! 436: NENTRY(insb)
! 437: movq %rdi, %rdx
! 438: movq %rsi, %rdi
! 439: movq %rdx, %rcx
! 440: cld
! 441: rep
! 442: insb
! 443: ret
! 444:
! 445: NENTRY(inw)
! 446: movq %rdi, %rdx
! 447: xorq %rax, %rax
! 448: inw %dx, %ax
! 449: ret
! 450:
! 451: NENTRY(insw)
! 452: movq %rdi, %rdx
! 453: movq %rsi, %rdi
! 454: movq %rdx, %rcx
! 455: cld
! 456: rep
! 457: insw
! 458: ret
! 459:
! 460: NENTRY(inl)
! 461: movq %rdi, %rdx
! 462: xorq %rax, %rax
! 463: inl %dx, %eax
! 464: ret
! 465:
! 466: NENTRY(insl)
! 467: movq %rdi, %rdx
! 468: movq %rsi, %rdi
! 469: movq %rdx, %rcx
! 470: cld
! 471: rep
! 472: insl
! 473: ret
! 474:
! 475: NENTRY(outb)
! 476: movq %rdi, %rdx
! 477: movq %rsi, %rax
! 478: outb %al, %dx
! 479: ret
! 480:
! 481: NENTRY(outsb)
! 482: movq %rdi, %rdx
! 483: movq %rdx, %rcx
! 484: cld
! 485: rep
! 486: outsb
! 487: ret
! 488:
! 489: NENTRY(outw)
! 490: movq %rdi, %rdx
! 491: movq %rsi, %rax
! 492: outw %ax, %dx
! 493: ret
! 494:
! 495: NENTRY(outsw)
! 496: movq %rdi, %rdx
! 497: movq %rdx, %rcx
! 498: cld
! 499: rep
! 500: outsw
! 501: ret
! 502:
! 503: NENTRY(outl)
! 504: movq %rdi, %rdx
! 505: movq %rsi, %rax
! 506: outl %eax, %dx
! 507: ret
! 508:
! 509: NENTRY(outsl)
! 510: movq %rdi, %rdx
! 511: movq %rdx, %rcx
! 512: cld
! 513: rep
! 514: outsl
! 515: ret
CVSweb <webmaster@jp.NetBSD.org>