11817Sdg/*- 21817Sdg * Copyright (c) 1993 The Regents of the University of California. 31817Sdg * All rights reserved. 41817Sdg * 51817Sdg * Redistribution and use in source and binary forms, with or without 61817Sdg * modification, are permitted provided that the following conditions 71817Sdg * are met: 81817Sdg * 1. Redistributions of source code must retain the above copyright 91817Sdg * notice, this list of conditions and the following disclaimer. 101817Sdg * 2. Redistributions in binary form must reproduce the above copyright 111817Sdg * notice, this list of conditions and the following disclaimer in the 121817Sdg * documentation and/or other materials provided with the distribution. 131817Sdg * 4. Neither the name of the University nor the names of its contributors 141817Sdg * may be used to endorse or promote products derived from this software 151817Sdg * without specific prior written permission. 161817Sdg * 171817Sdg * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181817Sdg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191817Sdg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201817Sdg * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211817Sdg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221817Sdg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231817Sdg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241817Sdg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251817Sdg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261817Sdg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271817Sdg * SUCH DAMAGE. 281817Sdg * 2950477Speter * $FreeBSD: stable/10/sys/i386/include/cpufunc.h 313150 2017-02-03 12:20:44Z kib $ 301817Sdg */ 311817Sdg 324Srgrimes/* 334Srgrimes * Functions to provide access to special i386 instructions. 3491497Smarkm * This in included in sys/systm.h, and that file should be 3591497Smarkm * used in preference to this. 364Srgrimes */ 374Srgrimes 38719Swollman#ifndef _MACHINE_CPUFUNC_H_ 394479Sbde#define _MACHINE_CPUFUNC_H_ 40719Swollman 41143063Sjoerg#ifndef _SYS_CDEFS_H_ 42143063Sjoerg#error this file needs sys/cdefs.h as a prerequisite 43143063Sjoerg#endif 44143063Sjoerg 45181775Skmacy#ifdef XEN 46181775Skmacyextern void xen_cli(void); 47181775Skmacyextern void xen_sti(void); 48184040Skmacyextern u_int xen_rcr2(void); 49181775Skmacyextern void xen_load_cr3(u_int data); 50181775Skmacyextern void xen_tlb_flush(void); 51181775Skmacyextern void xen_invlpg(u_int addr); 52197693Skmacyextern void write_eflags(u_int eflags); 53197693Skmacyextern u_int read_eflags(void); 54181775Skmacy#endif 55181775Skmacy 56103778Speterstruct region_descriptor; 5793264Sdillon 58220627Sjkim#define readb(va) (*(volatile uint8_t *) (va)) 59220627Sjkim#define readw(va) (*(volatile uint16_t *) (va)) 60220627Sjkim#define readl(va) (*(volatile uint32_t *) (va)) 6138392Sdfr 62220627Sjkim#define writeb(va, d) (*(volatile uint8_t *) (va) = (d)) 63220627Sjkim#define writew(va, d) (*(volatile uint16_t *) (va) = (d)) 64220627Sjkim#define writel(va, d) (*(volatile uint32_t *) (va) = (d)) 6538392Sdfr 66143063Sjoerg#if defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE) 674Srgrimes 6815122Sbdestatic __inline void 6915122Sbdebreakpoint(void) 703102Sdg{ 714479Sbde __asm __volatile("int $3"); 723102Sdg} 733102Sdg 7455672Sbdestatic __inline u_int 7555672Sbdebsfl(u_int mask) 7655672Sbde{ 7755672Sbde u_int result; 7855672Sbde 79194115Sed __asm("bsfl %1,%0" : "=r" (result) : "rm" (mask) : "cc"); 8055672Sbde return (result); 8155672Sbde} 8255672Sbde 8355672Sbdestatic __inline u_int 8455672Sbdebsrl(u_int mask) 8555672Sbde{ 8655672Sbde u_int result; 8755672Sbde 88194115Sed __asm("bsrl %1,%0" : "=r" (result) : "rm" (mask) : "cc"); 8955672Sbde return (result); 9055672Sbde} 9155672Sbde 923102Sdgstatic __inline void 93195940Skibclflush(u_long addr) 94195940Skib{ 95195940Skib 96195940Skib __asm __volatile("clflush %0" : : "m" (*(char *)addr)); 97195940Skib} 98195940Skib 99195940Skibstatic __inline void 100290189Skibclflushopt(u_long addr) 101290189Skib{ 102290189Skib 103290189Skib __asm __volatile(".byte 0x66;clflush %0" : : "m" (*(char *)addr)); 104290189Skib} 105290189Skib 106290189Skibstatic __inline void 107238311Sjhbclts(void) 108238311Sjhb{ 109238311Sjhb 110238311Sjhb __asm __volatile("clts"); 111238311Sjhb} 112238311Sjhb 113238311Sjhbstatic __inline void 1144479Sbdedisable_intr(void) 1153102Sdg{ 116181775Skmacy#ifdef XEN 117181775Skmacy xen_cli(); 118181775Skmacy#else 119184040Skmacy __asm __volatile("cli" : : : "memory"); 120181775Skmacy#endif 1213102Sdg} 1223102Sdg 1233102Sdgstatic __inline void 12494386Sdwmalonedo_cpuid(u_int ax, u_int *p) 12594386Sdwmalone{ 12694386Sdwmalone __asm __volatile("cpuid" 12794386Sdwmalone : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3]) 12894386Sdwmalone : "0" (ax)); 12994386Sdwmalone} 13094386Sdwmalone 13194386Sdwmalonestatic __inline void 132146170Snectarcpuid_count(u_int ax, u_int cx, u_int *p) 133146170Snectar{ 134146170Snectar __asm __volatile("cpuid" 135146170Snectar : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3]) 136146170Snectar : "0" (ax), "c" (cx)); 137146170Snectar} 138146170Snectar 139146170Snectarstatic __inline void 1404479Sbdeenable_intr(void) 1413102Sdg{ 142181775Skmacy#ifdef XEN 143181775Skmacy xen_sti(); 144184040Skmacy#else 14510342Sbde __asm __volatile("sti"); 146181775Skmacy#endif 1473102Sdg} 1483102Sdg 149197647Savgstatic __inline void 150223796Sjkimcpu_monitor(const void *addr, u_long extensions, u_int hints) 151178299Sjeff{ 152223796Sjkim 153223796Sjkim __asm __volatile("monitor" 154223796Sjkim : : "a" (addr), "c" (extensions), "d" (hints)); 155178299Sjeff} 156178299Sjeff 157197647Savgstatic __inline void 158223796Sjkimcpu_mwait(u_long extensions, u_int hints) 159178299Sjeff{ 160223796Sjkim 161223796Sjkim __asm __volatile("mwait" : : "a" (hints), "c" (extensions)); 162178299Sjeff} 163178299Sjeff 164195940Skibstatic __inline void 165238972Skiblfence(void) 166238972Skib{ 167238972Skib 168238972Skib __asm __volatile("lfence" : : : "memory"); 169238972Skib} 170238972Skib 171238972Skibstatic __inline void 172195940Skibmfence(void) 173195940Skib{ 174195940Skib 175195940Skib __asm __volatile("mfence" : : : "memory"); 176195940Skib} 177195940Skib 178313150Skibstatic __inline void 179313150Skibsfence(void) 180313150Skib{ 181313150Skib 182313150Skib __asm __volatile("sfence" : : : "memory"); 183313150Skib} 184313150Skib 185126846Sbde#ifdef _KERNEL 186126846Sbde 18750054Speter#define HAVE_INLINE_FFS 18850054Speter 18950054Speterstatic __inline int 19050054Speterffs(int mask) 19150054Speter{ 19250054Speter /* 1934479Sbde * Note that gcc-2's builtin ffs would be used if we didn't declare 1944479Sbde * this inline or turn off the builtin. The builtin is faster but 19555672Sbde * broken in gcc-2.4.5 and slower but working in gcc-2.5 and later 19655672Sbde * versions. 1974479Sbde */ 198100078Smarkm return (mask == 0 ? mask : (int)bsfl((u_int)mask) + 1); 19950054Speter} 20050054Speter 201289818Savg#define HAVE_INLINE_FFSL 202289818Savg 203289818Savgstatic __inline int 204289818Savgffsl(long mask) 205289818Savg{ 206289818Savg return (ffs((int)mask)); 207289818Savg} 208289818Savg 20917384Swollman#define HAVE_INLINE_FLS 21017384Swollman 21117384Swollmanstatic __inline int 21217384Swollmanfls(int mask) 21317384Swollman{ 214100078Smarkm return (mask == 0 ? mask : (int)bsrl((u_int)mask) + 1); 21517384Swollman} 21617384Swollman 217289818Savg#define HAVE_INLINE_FLSL 218289818Savg 219289818Savgstatic __inline int 220289818Savgflsl(long mask) 221289818Savg{ 222289818Savg return (fls((int)mask)); 223289818Savg} 224289818Savg 225126846Sbde#endif /* _KERNEL */ 226126846Sbde 227103749Smarkmstatic __inline void 228103749Smarkmhalt(void) 229103749Smarkm{ 230103749Smarkm __asm __volatile("hlt"); 231103749Smarkm} 232103749Smarkm 2334479Sbdestatic __inline u_char 234190919Sedinb(u_int port) 2353102Sdg{ 2364479Sbde u_char data; 2374479Sbde 238220629Sjkim __asm __volatile("inb %w1, %0" : "=a" (data) : "Nd" (port)); 2394479Sbde return (data); 2403102Sdg} 2413102Sdg 24237552Sbdestatic __inline u_int 2434479Sbdeinl(u_int port) 2442826Sdg{ 24537552Sbde u_int data; 2462826Sdg 247220629Sjkim __asm __volatile("inl %w1, %0" : "=a" (data) : "Nd" (port)); 2484479Sbde return (data); 2492826Sdg} 2502826Sdg 2514479Sbdestatic __inline void 252201369Sobrieninsb(u_int port, void *addr, size_t count) 2532826Sdg{ 2544479Sbde __asm __volatile("cld; rep; insb" 255201369Sobrien : "+D" (addr), "+c" (count) 25688118Sjhb : "d" (port) 25742427Sbde : "memory"); 2584479Sbde} 2592826Sdg 2604479Sbdestatic __inline void 261201369Sobrieninsw(u_int port, void *addr, size_t count) 2624479Sbde{ 2634479Sbde __asm __volatile("cld; rep; insw" 264201369Sobrien : "+D" (addr), "+c" (count) 26588118Sjhb : "d" (port) 26642427Sbde : "memory"); 2672826Sdg} 2682826Sdg 2694479Sbdestatic __inline void 270201369Sobrieninsl(u_int port, void *addr, size_t count) 2712826Sdg{ 2724479Sbde __asm __volatile("cld; rep; insl" 273201369Sobrien : "+D" (addr), "+c" (count) 27488118Sjhb : "d" (port) 27542427Sbde : "memory"); 2762826Sdg} 2772826Sdg 27818567Sbdestatic __inline void 27924112Skatoinvd(void) 28024112Skato{ 28124112Skato __asm __volatile("invd"); 28224112Skato} 28324112Skato 2844479Sbdestatic __inline u_short 2854479Sbdeinw(u_int port) 2862826Sdg{ 2874479Sbde u_short data; 2884479Sbde 289220629Sjkim __asm __volatile("inw %w1, %0" : "=a" (data) : "Nd" (port)); 2904479Sbde return (data); 2912826Sdg} 2922826Sdg 2934479Sbdestatic __inline void 294190919Sedoutb(u_int port, u_char data) 2952826Sdg{ 296190919Sed __asm __volatile("outb %0, %w1" : : "a" (data), "Nd" (port)); 2972826Sdg} 2982826Sdg 2994479Sbdestatic __inline void 30037552Sbdeoutl(u_int port, u_int data) 3014Srgrimes{ 302220629Sjkim __asm __volatile("outl %0, %w1" : : "a" (data), "Nd" (port)); 3034Srgrimes} 3044Srgrimes 3054479Sbdestatic __inline void 306201369Sobrienoutsb(u_int port, const void *addr, size_t count) 3074Srgrimes{ 3084479Sbde __asm __volatile("cld; rep; outsb" 309201369Sobrien : "+S" (addr), "+c" (count) 31088118Sjhb : "d" (port)); 3114Srgrimes} 3124Srgrimes 3134479Sbdestatic __inline void 314201369Sobrienoutsw(u_int port, const void *addr, size_t count) 3154Srgrimes{ 3164479Sbde __asm __volatile("cld; rep; outsw" 317201369Sobrien : "+S" (addr), "+c" (count) 31888118Sjhb : "d" (port)); 3194Srgrimes} 3204Srgrimes 3214479Sbdestatic __inline void 322201369Sobrienoutsl(u_int port, const void *addr, size_t count) 3234Srgrimes{ 3244479Sbde __asm __volatile("cld; rep; outsl" 325201369Sobrien : "+S" (addr), "+c" (count) 32688118Sjhb : "d" (port)); 3274Srgrimes} 3284Srgrimes 3294479Sbdestatic __inline void 3304479Sbdeoutw(u_int port, u_short data) 3314Srgrimes{ 332220629Sjkim __asm __volatile("outw %0, %w1" : : "a" (data), "Nd" (port)); 3334Srgrimes} 3344Srgrimes 33597114Sjhbstatic __inline void 33697139Sjhbia32_pause(void) 33797114Sjhb{ 33897114Sjhb __asm __volatile("pause"); 33997114Sjhb} 34097114Sjhb 34137552Sbdestatic __inline u_int 342197693Skmacy#ifdef XEN 343197693Skmacy_read_eflags(void) 344197693Skmacy#else 3454479Sbderead_eflags(void) 346197693Skmacy#endif 3474479Sbde{ 34837552Sbde u_int ef; 3494479Sbde 3508876Srgrimes __asm __volatile("pushfl; popl %0" : "=r" (ef)); 3514479Sbde return (ef); 3524479Sbde} 3534479Sbde 354171797Snjlstatic __inline uint64_t 35515122Sbderdmsr(u_int msr) 3564479Sbde{ 357171797Snjl uint64_t rv; 35815122Sbde 35969006Smarkm __asm __volatile("rdmsr" : "=A" (rv) : "c" (msr)); 36015122Sbde return (rv); 3614479Sbde} 3624479Sbde 363171797Snjlstatic __inline uint64_t 36415122Sbderdpmc(u_int pmc) 36514825Swollman{ 366171797Snjl uint64_t rv; 36715122Sbde 36869006Smarkm __asm __volatile("rdpmc" : "=A" (rv) : "c" (pmc)); 36915122Sbde return (rv); 37014825Swollman} 37114825Swollman 372171797Snjlstatic __inline uint64_t 37314825Swollmanrdtsc(void) 37414825Swollman{ 375171797Snjl uint64_t rv; 37615122Sbde 37769006Smarkm __asm __volatile("rdtsc" : "=A" (rv)); 37815122Sbde return (rv); 37914825Swollman} 38014825Swollman 381220631Sjkimstatic __inline uint32_t 382220631Sjkimrdtsc32(void) 383220631Sjkim{ 384220631Sjkim uint32_t rv; 385220631Sjkim 386220631Sjkim __asm __volatile("rdtsc" : "=a" (rv) : : "edx"); 387220631Sjkim return (rv); 388220631Sjkim} 389220631Sjkim 39015122Sbdestatic __inline void 39124112Skatowbinvd(void) 39224112Skato{ 39324112Skato __asm __volatile("wbinvd"); 39424112Skato} 39524112Skato 39624112Skatostatic __inline void 397197693Skmacy#ifdef XEN 398197693Skmacy_write_eflags(u_int ef) 399197693Skmacy#else 40037552Sbdewrite_eflags(u_int ef) 401197693Skmacy#endif 40214825Swollman{ 40315122Sbde __asm __volatile("pushl %0; popfl" : : "r" (ef)); 40414825Swollman} 40514825Swollman 40614825Swollmanstatic __inline void 407171797Snjlwrmsr(u_int msr, uint64_t newval) 40814825Swollman{ 40969006Smarkm __asm __volatile("wrmsr" : : "A" (newval), "c" (msr)); 41014825Swollman} 41114825Swollman 41299862Speterstatic __inline void 41399862Speterload_cr0(u_int data) 41499862Speter{ 41599862Speter 41699862Speter __asm __volatile("movl %0,%%cr0" : : "r" (data)); 41799862Speter} 41899862Speter 41946129Sluoqistatic __inline u_int 42099862Speterrcr0(void) 42199862Speter{ 42299862Speter u_int data; 42399862Speter 42499862Speter __asm __volatile("movl %%cr0,%0" : "=r" (data)); 42599862Speter return (data); 42699862Speter} 42799862Speter 42899862Speterstatic __inline u_int 42999862Speterrcr2(void) 43099862Speter{ 43199862Speter u_int data; 43299862Speter 433184040Skmacy#ifdef XEN 434184040Skmacy return (xen_rcr2()); 435184040Skmacy#endif 43699862Speter __asm __volatile("movl %%cr2,%0" : "=r" (data)); 43799862Speter return (data); 43899862Speter} 43999862Speter 44099862Speterstatic __inline void 44199862Speterload_cr3(u_int data) 44299862Speter{ 443181775Skmacy#ifdef XEN 444181775Skmacy xen_load_cr3(data); 445181775Skmacy#else 44699862Speter __asm __volatile("movl %0,%%cr3" : : "r" (data) : "memory"); 447181775Skmacy#endif 44899862Speter} 44999862Speter 45099862Speterstatic __inline u_int 45199862Speterrcr3(void) 45299862Speter{ 45399862Speter u_int data; 45499862Speter 45599862Speter __asm __volatile("movl %%cr3,%0" : "=r" (data)); 45699862Speter return (data); 45799862Speter} 45899862Speter 45999862Speterstatic __inline void 46099862Speterload_cr4(u_int data) 46199862Speter{ 46299862Speter __asm __volatile("movl %0,%%cr4" : : "r" (data)); 46399862Speter} 46499862Speter 46599862Speterstatic __inline u_int 46699862Speterrcr4(void) 46799862Speter{ 46899862Speter u_int data; 46999862Speter 47099862Speter __asm __volatile("movl %%cr4,%0" : "=r" (data)); 47199862Speter return (data); 47299862Speter} 47399862Speter 474276084Sjhbstatic __inline uint64_t 475276084Sjhbrxcr(u_int reg) 476276084Sjhb{ 477276084Sjhb u_int low, high; 478276084Sjhb 479276084Sjhb __asm __volatile("xgetbv" : "=a" (low), "=d" (high) : "c" (reg)); 480276084Sjhb return (low | ((uint64_t)high << 32)); 481276084Sjhb} 482276084Sjhb 483276084Sjhbstatic __inline void 484276084Sjhbload_xcr(u_int reg, uint64_t val) 485276084Sjhb{ 486276084Sjhb u_int low, high; 487276084Sjhb 488276084Sjhb low = val; 489276084Sjhb high = val >> 32; 490276084Sjhb __asm __volatile("xsetbv" : : "c" (reg), "a" (low), "d" (high)); 491276084Sjhb} 492276084Sjhb 49399862Speter/* 49499862Speter * Global TLB flush (except for thise for pages marked PG_G) 49599862Speter */ 49699862Speterstatic __inline void 49799862Speterinvltlb(void) 49899862Speter{ 499181775Skmacy#ifdef XEN 500181775Skmacy xen_tlb_flush(); 501181775Skmacy#else 50299862Speter load_cr3(rcr3()); 503181775Skmacy#endif 50499862Speter} 50599862Speter 50699862Speter/* 50799862Speter * TLB flush for an individual page (even if it has PG_G). 50899862Speter * Only works on 486+ CPUs (i386 does not have PG_G). 50999862Speter */ 51099862Speterstatic __inline void 51199862Speterinvlpg(u_int addr) 51299862Speter{ 51399862Speter 514181775Skmacy#ifdef XEN 515181775Skmacy xen_invlpg(addr); 516181775Skmacy#else 51799862Speter __asm __volatile("invlpg %0" : : "m" (*(char *)addr) : "memory"); 518181775Skmacy#endif 51999862Speter} 52099862Speter 521212177Srdivackystatic __inline u_short 52246129Sluoqirfs(void) 52346129Sluoqi{ 524212177Srdivacky u_short sel; 525212177Srdivacky __asm __volatile("movw %%fs,%0" : "=rm" (sel)); 52646129Sluoqi return (sel); 52746129Sluoqi} 52846129Sluoqi 529171797Snjlstatic __inline uint64_t 530171797Snjlrgdt(void) 531171797Snjl{ 532171797Snjl uint64_t gdtr; 533171797Snjl __asm __volatile("sgdt %0" : "=m" (gdtr)); 534171797Snjl return (gdtr); 535171797Snjl} 536171797Snjl 537212177Srdivackystatic __inline u_short 53846129Sluoqirgs(void) 53946129Sluoqi{ 540212177Srdivacky u_short sel; 541212177Srdivacky __asm __volatile("movw %%gs,%0" : "=rm" (sel)); 54246129Sluoqi return (sel); 54346129Sluoqi} 54446129Sluoqi 545171797Snjlstatic __inline uint64_t 546171797Snjlridt(void) 547171797Snjl{ 548171797Snjl uint64_t idtr; 549171797Snjl __asm __volatile("sidt %0" : "=m" (idtr)); 550171797Snjl return (idtr); 551171797Snjl} 552171797Snjl 553171797Snjlstatic __inline u_short 554171797Snjlrldt(void) 555171797Snjl{ 556171797Snjl u_short ldtr; 557171797Snjl __asm __volatile("sldt %0" : "=g" (ldtr)); 558171797Snjl return (ldtr); 559171797Snjl} 560171797Snjl 561212177Srdivackystatic __inline u_short 562127813Smarcelrss(void) 563127813Smarcel{ 564212177Srdivacky u_short sel; 565212177Srdivacky __asm __volatile("movw %%ss,%0" : "=rm" (sel)); 566127813Smarcel return (sel); 567127813Smarcel} 568127813Smarcel 569171797Snjlstatic __inline u_short 570171797Snjlrtr(void) 571171797Snjl{ 572171797Snjl u_short tr; 573171797Snjl __asm __volatile("str %0" : "=g" (tr)); 574171797Snjl return (tr); 575171797Snjl} 576171797Snjl 57746129Sluoqistatic __inline void 578212177Srdivackyload_fs(u_short sel) 57946129Sluoqi{ 580212177Srdivacky __asm __volatile("movw %0,%%fs" : : "rm" (sel)); 58146129Sluoqi} 58246129Sluoqi 58346129Sluoqistatic __inline void 584212177Srdivackyload_gs(u_short sel) 58546129Sluoqi{ 586212177Srdivacky __asm __volatile("movw %0,%%gs" : : "rm" (sel)); 58746129Sluoqi} 58846129Sluoqi 589103778Speterstatic __inline void 590103778Speterlidt(struct region_descriptor *addr) 591103778Speter{ 592103778Speter __asm __volatile("lidt (%0)" : : "r" (addr)); 593103778Speter} 594103778Speter 595103778Speterstatic __inline void 596103778Speterlldt(u_short sel) 597103778Speter{ 598103778Speter __asm __volatile("lldt %0" : : "r" (sel)); 599103778Speter} 600103778Speter 601103778Speterstatic __inline void 602103778Speterltr(u_short sel) 603103778Speter{ 604103778Speter __asm __volatile("ltr %0" : : "r" (sel)); 605103778Speter} 606103778Speter 60757362Sbsdstatic __inline u_int 60857362Sbsdrdr0(void) 60957362Sbsd{ 61057362Sbsd u_int data; 61157376Sbsd __asm __volatile("movl %%dr0,%0" : "=r" (data)); 61257362Sbsd return (data); 61357362Sbsd} 61457362Sbsd 61578903Sbsdstatic __inline void 61697115Sjhbload_dr0(u_int dr0) 61778903Sbsd{ 61897115Sjhb __asm __volatile("movl %0,%%dr0" : : "r" (dr0)); 61978903Sbsd} 62078903Sbsd 62157362Sbsdstatic __inline u_int 62257362Sbsdrdr1(void) 62357362Sbsd{ 62457362Sbsd u_int data; 62557376Sbsd __asm __volatile("movl %%dr1,%0" : "=r" (data)); 62657362Sbsd return (data); 62757362Sbsd} 62857362Sbsd 62978903Sbsdstatic __inline void 63097115Sjhbload_dr1(u_int dr1) 63178903Sbsd{ 63297115Sjhb __asm __volatile("movl %0,%%dr1" : : "r" (dr1)); 63378903Sbsd} 63478903Sbsd 63557362Sbsdstatic __inline u_int 63657362Sbsdrdr2(void) 63757362Sbsd{ 63857362Sbsd u_int data; 63957376Sbsd __asm __volatile("movl %%dr2,%0" : "=r" (data)); 64057362Sbsd return (data); 64157362Sbsd} 64257362Sbsd 64378903Sbsdstatic __inline void 64497115Sjhbload_dr2(u_int dr2) 64578903Sbsd{ 64697115Sjhb __asm __volatile("movl %0,%%dr2" : : "r" (dr2)); 64778903Sbsd} 64878903Sbsd 64957362Sbsdstatic __inline u_int 65057362Sbsdrdr3(void) 65157362Sbsd{ 65257362Sbsd u_int data; 65357376Sbsd __asm __volatile("movl %%dr3,%0" : "=r" (data)); 65457362Sbsd return (data); 65557362Sbsd} 65657362Sbsd 65778903Sbsdstatic __inline void 65897115Sjhbload_dr3(u_int dr3) 65978903Sbsd{ 66097115Sjhb __asm __volatile("movl %0,%%dr3" : : "r" (dr3)); 66178903Sbsd} 66278903Sbsd 66357362Sbsdstatic __inline u_int 66478903Sbsdrdr4(void) 66578903Sbsd{ 66678903Sbsd u_int data; 66778903Sbsd __asm __volatile("movl %%dr4,%0" : "=r" (data)); 66878903Sbsd return (data); 66978903Sbsd} 67078903Sbsd 67178903Sbsdstatic __inline void 67297115Sjhbload_dr4(u_int dr4) 67378903Sbsd{ 67497115Sjhb __asm __volatile("movl %0,%%dr4" : : "r" (dr4)); 67578903Sbsd} 67678903Sbsd 67778903Sbsdstatic __inline u_int 67878903Sbsdrdr5(void) 67978903Sbsd{ 68078903Sbsd u_int data; 68178903Sbsd __asm __volatile("movl %%dr5,%0" : "=r" (data)); 68278903Sbsd return (data); 68378903Sbsd} 68478903Sbsd 68578903Sbsdstatic __inline void 68697115Sjhbload_dr5(u_int dr5) 68778903Sbsd{ 68897115Sjhb __asm __volatile("movl %0,%%dr5" : : "r" (dr5)); 68978903Sbsd} 69078903Sbsd 69178903Sbsdstatic __inline u_int 69257362Sbsdrdr6(void) 69357362Sbsd{ 69457362Sbsd u_int data; 69557376Sbsd __asm __volatile("movl %%dr6,%0" : "=r" (data)); 69657362Sbsd return (data); 69757362Sbsd} 69857362Sbsd 69978903Sbsdstatic __inline void 70097115Sjhbload_dr6(u_int dr6) 70178903Sbsd{ 70297115Sjhb __asm __volatile("movl %0,%%dr6" : : "r" (dr6)); 70378903Sbsd} 70478903Sbsd 70557362Sbsdstatic __inline u_int 70657362Sbsdrdr7(void) 70757362Sbsd{ 70857362Sbsd u_int data; 70957376Sbsd __asm __volatile("movl %%dr7,%0" : "=r" (data)); 71057362Sbsd return (data); 71157362Sbsd} 71257362Sbsd 71378903Sbsdstatic __inline void 71497115Sjhbload_dr7(u_int dr7) 71578903Sbsd{ 71697115Sjhb __asm __volatile("movl %0,%%dr7" : : "r" (dr7)); 71778903Sbsd} 71878903Sbsd 719194295Sjhbstatic __inline u_char 720194295Sjhbread_cyrix_reg(u_char reg) 721194295Sjhb{ 722194295Sjhb outb(0x22, reg); 723194295Sjhb return inb(0x23); 724194295Sjhb} 725194295Sjhb 726194295Sjhbstatic __inline void 727194295Sjhbwrite_cyrix_reg(u_char reg, u_char data) 728194295Sjhb{ 729194295Sjhb outb(0x22, reg); 730194295Sjhb outb(0x23, data); 731194295Sjhb} 732194295Sjhb 73392860Simpstatic __inline register_t 73492860Simpintr_disable(void) 73592860Simp{ 736181911Skmacy register_t eflags; 73792860Simp 73892860Simp eflags = read_eflags(); 73992860Simp disable_intr(); 74092860Simp return (eflags); 74192860Simp} 74292860Simp 74392860Simpstatic __inline void 74492860Simpintr_restore(register_t eflags) 74592860Simp{ 74692860Simp write_eflags(eflags); 74792860Simp} 74892860Simp 749143063Sjoerg#else /* !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */ 7504Srgrimes 75192819Simpint breakpoint(void); 75292819Simpu_int bsfl(u_int mask); 75392819Simpu_int bsrl(u_int mask); 754238311Sjhbvoid clflush(u_long addr); 755238311Sjhbvoid clts(void); 756238311Sjhbvoid cpuid_count(u_int ax, u_int cx, u_int *p); 75792819Simpvoid disable_intr(void); 75892819Simpvoid do_cpuid(u_int ax, u_int *p); 75992819Simpvoid enable_intr(void); 760103749Smarkmvoid halt(void); 761126656Sbdevoid ia32_pause(void); 76292819Simpu_char inb(u_int port); 76392819Simpu_int inl(u_int port); 764201369Sobrienvoid insb(u_int port, void *addr, size_t count); 765201369Sobrienvoid insl(u_int port, void *addr, size_t count); 766201369Sobrienvoid insw(u_int port, void *addr, size_t count); 767126656Sbderegister_t intr_disable(void); 768126656Sbdevoid intr_restore(register_t ef); 76992819Simpvoid invd(void); 77092819Simpvoid invlpg(u_int addr); 77192819Simpvoid invltlb(void); 77292819Simpu_short inw(u_int port); 773126656Sbdevoid lidt(struct region_descriptor *addr); 774126656Sbdevoid lldt(u_short sel); 77599862Spetervoid load_cr0(u_int cr0); 77699862Spetervoid load_cr3(u_int cr3); 77799862Spetervoid load_cr4(u_int cr4); 778126656Sbdevoid load_dr0(u_int dr0); 779126656Sbdevoid load_dr1(u_int dr1); 780126656Sbdevoid load_dr2(u_int dr2); 781126656Sbdevoid load_dr3(u_int dr3); 782126656Sbdevoid load_dr4(u_int dr4); 783126656Sbdevoid load_dr5(u_int dr5); 784126656Sbdevoid load_dr6(u_int dr6); 785126656Sbdevoid load_dr7(u_int dr7); 786212177Srdivackyvoid load_fs(u_short sel); 787212177Srdivackyvoid load_gs(u_short sel); 788103778Spetervoid ltr(u_short sel); 78992819Simpvoid outb(u_int port, u_char data); 79092819Simpvoid outl(u_int port, u_int data); 791201369Sobrienvoid outsb(u_int port, const void *addr, size_t count); 792201369Sobrienvoid outsl(u_int port, const void *addr, size_t count); 793201369Sobrienvoid outsw(u_int port, const void *addr, size_t count); 79492819Simpvoid outw(u_int port, u_short data); 79599862Speteru_int rcr0(void); 79692819Simpu_int rcr2(void); 79799862Speteru_int rcr3(void); 79899862Speteru_int rcr4(void); 799171797Snjluint64_t rdmsr(u_int msr); 800171797Snjluint64_t rdpmc(u_int pmc); 80197114Sjhbu_int rdr0(void); 80297114Sjhbu_int rdr1(void); 80397114Sjhbu_int rdr2(void); 80497114Sjhbu_int rdr3(void); 80597114Sjhbu_int rdr4(void); 80697114Sjhbu_int rdr5(void); 80797114Sjhbu_int rdr6(void); 80897114Sjhbu_int rdr7(void); 809171797Snjluint64_t rdtsc(void); 810194295Sjhbu_char read_cyrix_reg(u_char reg); 811126656Sbdeu_int read_eflags(void); 812126656Sbdeu_int rfs(void); 813171797Snjluint64_t rgdt(void); 814126656Sbdeu_int rgs(void); 815171797Snjluint64_t ridt(void); 816171797Snjlu_short rldt(void); 817171797Snjlu_short rtr(void); 818126656Sbdevoid wbinvd(void); 819194295Sjhbvoid write_cyrix_reg(u_char reg, u_char data); 820126656Sbdevoid write_eflags(u_int ef); 821171797Snjlvoid wrmsr(u_int msr, uint64_t newval); 8224Srgrimes 823143063Sjoerg#endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */ 8244Srgrimes 82592761Salfredvoid reset_dbregs(void); 82693264Sdillon 827181430Sstas#ifdef _KERNEL 828181430Sstasint rdmsr_safe(u_int msr, uint64_t *val); 829181430Sstasint wrmsr_safe(u_int msr, uint64_t newval); 830181430Sstas#endif 831181430Sstas 8324479Sbde#endif /* !_MACHINE_CPUFUNC_H_ */ 833