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$ 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 100239914Sjhbclts(void) 101239914Sjhb{ 102239914Sjhb 103239914Sjhb __asm __volatile("clts"); 104239914Sjhb} 105239914Sjhb 106239914Sjhbstatic __inline void 1074479Sbdedisable_intr(void) 1083102Sdg{ 109181775Skmacy#ifdef XEN 110181775Skmacy xen_cli(); 111181775Skmacy#else 112184040Skmacy __asm __volatile("cli" : : : "memory"); 113181775Skmacy#endif 1143102Sdg} 1153102Sdg 1163102Sdgstatic __inline void 11794386Sdwmalonedo_cpuid(u_int ax, u_int *p) 11894386Sdwmalone{ 11994386Sdwmalone __asm __volatile("cpuid" 12094386Sdwmalone : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3]) 12194386Sdwmalone : "0" (ax)); 12294386Sdwmalone} 12394386Sdwmalone 12494386Sdwmalonestatic __inline void 125146170Snectarcpuid_count(u_int ax, u_int cx, u_int *p) 126146170Snectar{ 127146170Snectar __asm __volatile("cpuid" 128146170Snectar : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3]) 129146170Snectar : "0" (ax), "c" (cx)); 130146170Snectar} 131146170Snectar 132146170Snectarstatic __inline void 1334479Sbdeenable_intr(void) 1343102Sdg{ 135181775Skmacy#ifdef XEN 136181775Skmacy xen_sti(); 137184040Skmacy#else 13810342Sbde __asm __volatile("sti"); 139181775Skmacy#endif 1403102Sdg} 1413102Sdg 142197647Savgstatic __inline void 143223796Sjkimcpu_monitor(const void *addr, u_long extensions, u_int hints) 144178299Sjeff{ 145223796Sjkim 146223796Sjkim __asm __volatile("monitor" 147223796Sjkim : : "a" (addr), "c" (extensions), "d" (hints)); 148178299Sjeff} 149178299Sjeff 150197647Savgstatic __inline void 151223796Sjkimcpu_mwait(u_long extensions, u_int hints) 152178299Sjeff{ 153223796Sjkim 154223796Sjkim __asm __volatile("mwait" : : "a" (hints), "c" (extensions)); 155178299Sjeff} 156178299Sjeff 157195940Skibstatic __inline void 158239902Skiblfence(void) 159239902Skib{ 160239902Skib 161239902Skib __asm __volatile("lfence" : : : "memory"); 162239902Skib} 163239902Skib 164239902Skibstatic __inline void 165195940Skibmfence(void) 166195940Skib{ 167195940Skib 168195940Skib __asm __volatile("mfence" : : : "memory"); 169195940Skib} 170195940Skib 171126846Sbde#ifdef _KERNEL 172126846Sbde 17350054Speter#define HAVE_INLINE_FFS 17450054Speter 17550054Speterstatic __inline int 17650054Speterffs(int mask) 17750054Speter{ 17850054Speter /* 1794479Sbde * Note that gcc-2's builtin ffs would be used if we didn't declare 1804479Sbde * this inline or turn off the builtin. The builtin is faster but 18155672Sbde * broken in gcc-2.4.5 and slower but working in gcc-2.5 and later 18255672Sbde * versions. 1834479Sbde */ 184100078Smarkm return (mask == 0 ? mask : (int)bsfl((u_int)mask) + 1); 18550054Speter} 18650054Speter 18717384Swollman#define HAVE_INLINE_FLS 18817384Swollman 18917384Swollmanstatic __inline int 19017384Swollmanfls(int mask) 19117384Swollman{ 192100078Smarkm return (mask == 0 ? mask : (int)bsrl((u_int)mask) + 1); 19317384Swollman} 19417384Swollman 195126846Sbde#endif /* _KERNEL */ 196126846Sbde 197103749Smarkmstatic __inline void 198103749Smarkmhalt(void) 199103749Smarkm{ 200103749Smarkm __asm __volatile("hlt"); 201103749Smarkm} 202103749Smarkm 2034479Sbdestatic __inline u_char 204190919Sedinb(u_int port) 2053102Sdg{ 2064479Sbde u_char data; 2074479Sbde 208220629Sjkim __asm __volatile("inb %w1, %0" : "=a" (data) : "Nd" (port)); 2094479Sbde return (data); 2103102Sdg} 2113102Sdg 21237552Sbdestatic __inline u_int 2134479Sbdeinl(u_int port) 2142826Sdg{ 21537552Sbde u_int data; 2162826Sdg 217220629Sjkim __asm __volatile("inl %w1, %0" : "=a" (data) : "Nd" (port)); 2184479Sbde return (data); 2192826Sdg} 2202826Sdg 2214479Sbdestatic __inline void 222201369Sobrieninsb(u_int port, void *addr, size_t count) 2232826Sdg{ 2244479Sbde __asm __volatile("cld; rep; insb" 225201369Sobrien : "+D" (addr), "+c" (count) 22688118Sjhb : "d" (port) 22742427Sbde : "memory"); 2284479Sbde} 2292826Sdg 2304479Sbdestatic __inline void 231201369Sobrieninsw(u_int port, void *addr, size_t count) 2324479Sbde{ 2334479Sbde __asm __volatile("cld; rep; insw" 234201369Sobrien : "+D" (addr), "+c" (count) 23588118Sjhb : "d" (port) 23642427Sbde : "memory"); 2372826Sdg} 2382826Sdg 2394479Sbdestatic __inline void 240201369Sobrieninsl(u_int port, void *addr, size_t count) 2412826Sdg{ 2424479Sbde __asm __volatile("cld; rep; insl" 243201369Sobrien : "+D" (addr), "+c" (count) 24488118Sjhb : "d" (port) 24542427Sbde : "memory"); 2462826Sdg} 2472826Sdg 24818567Sbdestatic __inline void 24924112Skatoinvd(void) 25024112Skato{ 25124112Skato __asm __volatile("invd"); 25224112Skato} 25324112Skato 2544479Sbdestatic __inline u_short 2554479Sbdeinw(u_int port) 2562826Sdg{ 2574479Sbde u_short data; 2584479Sbde 259220629Sjkim __asm __volatile("inw %w1, %0" : "=a" (data) : "Nd" (port)); 2604479Sbde return (data); 2612826Sdg} 2622826Sdg 2634479Sbdestatic __inline void 264190919Sedoutb(u_int port, u_char data) 2652826Sdg{ 266190919Sed __asm __volatile("outb %0, %w1" : : "a" (data), "Nd" (port)); 2672826Sdg} 2682826Sdg 2694479Sbdestatic __inline void 27037552Sbdeoutl(u_int port, u_int data) 2714Srgrimes{ 272220629Sjkim __asm __volatile("outl %0, %w1" : : "a" (data), "Nd" (port)); 2734Srgrimes} 2744Srgrimes 2754479Sbdestatic __inline void 276201369Sobrienoutsb(u_int port, const void *addr, size_t count) 2774Srgrimes{ 2784479Sbde __asm __volatile("cld; rep; outsb" 279201369Sobrien : "+S" (addr), "+c" (count) 28088118Sjhb : "d" (port)); 2814Srgrimes} 2824Srgrimes 2834479Sbdestatic __inline void 284201369Sobrienoutsw(u_int port, const void *addr, size_t count) 2854Srgrimes{ 2864479Sbde __asm __volatile("cld; rep; outsw" 287201369Sobrien : "+S" (addr), "+c" (count) 28888118Sjhb : "d" (port)); 2894Srgrimes} 2904Srgrimes 2914479Sbdestatic __inline void 292201369Sobrienoutsl(u_int port, const void *addr, size_t count) 2934Srgrimes{ 2944479Sbde __asm __volatile("cld; rep; outsl" 295201369Sobrien : "+S" (addr), "+c" (count) 29688118Sjhb : "d" (port)); 2974Srgrimes} 2984Srgrimes 2994479Sbdestatic __inline void 3004479Sbdeoutw(u_int port, u_short data) 3014Srgrimes{ 302220629Sjkim __asm __volatile("outw %0, %w1" : : "a" (data), "Nd" (port)); 3034Srgrimes} 3044Srgrimes 30597114Sjhbstatic __inline void 30697139Sjhbia32_pause(void) 30797114Sjhb{ 30897114Sjhb __asm __volatile("pause"); 30997114Sjhb} 31097114Sjhb 31137552Sbdestatic __inline u_int 312197693Skmacy#ifdef XEN 313197693Skmacy_read_eflags(void) 314197693Skmacy#else 3154479Sbderead_eflags(void) 316197693Skmacy#endif 3174479Sbde{ 31837552Sbde u_int ef; 3194479Sbde 3208876Srgrimes __asm __volatile("pushfl; popl %0" : "=r" (ef)); 3214479Sbde return (ef); 3224479Sbde} 3234479Sbde 324171797Snjlstatic __inline uint64_t 32515122Sbderdmsr(u_int msr) 3264479Sbde{ 327171797Snjl uint64_t rv; 32815122Sbde 32969006Smarkm __asm __volatile("rdmsr" : "=A" (rv) : "c" (msr)); 33015122Sbde return (rv); 3314479Sbde} 3324479Sbde 333171797Snjlstatic __inline uint64_t 33415122Sbderdpmc(u_int pmc) 33514825Swollman{ 336171797Snjl uint64_t rv; 33715122Sbde 33869006Smarkm __asm __volatile("rdpmc" : "=A" (rv) : "c" (pmc)); 33915122Sbde return (rv); 34014825Swollman} 34114825Swollman 342171797Snjlstatic __inline uint64_t 34314825Swollmanrdtsc(void) 34414825Swollman{ 345171797Snjl uint64_t rv; 34615122Sbde 34769006Smarkm __asm __volatile("rdtsc" : "=A" (rv)); 34815122Sbde return (rv); 34914825Swollman} 35014825Swollman 351220631Sjkimstatic __inline uint32_t 352220631Sjkimrdtsc32(void) 353220631Sjkim{ 354220631Sjkim uint32_t rv; 355220631Sjkim 356220631Sjkim __asm __volatile("rdtsc" : "=a" (rv) : : "edx"); 357220631Sjkim return (rv); 358220631Sjkim} 359220631Sjkim 36015122Sbdestatic __inline void 36124112Skatowbinvd(void) 36224112Skato{ 36324112Skato __asm __volatile("wbinvd"); 36424112Skato} 36524112Skato 36624112Skatostatic __inline void 367197693Skmacy#ifdef XEN 368197693Skmacy_write_eflags(u_int ef) 369197693Skmacy#else 37037552Sbdewrite_eflags(u_int ef) 371197693Skmacy#endif 37214825Swollman{ 37315122Sbde __asm __volatile("pushl %0; popfl" : : "r" (ef)); 37414825Swollman} 37514825Swollman 37614825Swollmanstatic __inline void 377171797Snjlwrmsr(u_int msr, uint64_t newval) 37814825Swollman{ 37969006Smarkm __asm __volatile("wrmsr" : : "A" (newval), "c" (msr)); 38014825Swollman} 38114825Swollman 38299862Speterstatic __inline void 38399862Speterload_cr0(u_int data) 38499862Speter{ 38599862Speter 38699862Speter __asm __volatile("movl %0,%%cr0" : : "r" (data)); 38799862Speter} 38899862Speter 38946129Sluoqistatic __inline u_int 39099862Speterrcr0(void) 39199862Speter{ 39299862Speter u_int data; 39399862Speter 39499862Speter __asm __volatile("movl %%cr0,%0" : "=r" (data)); 39599862Speter return (data); 39699862Speter} 39799862Speter 39899862Speterstatic __inline u_int 39999862Speterrcr2(void) 40099862Speter{ 40199862Speter u_int data; 40299862Speter 403184040Skmacy#ifdef XEN 404184040Skmacy return (xen_rcr2()); 405184040Skmacy#endif 40699862Speter __asm __volatile("movl %%cr2,%0" : "=r" (data)); 40799862Speter return (data); 40899862Speter} 40999862Speter 41099862Speterstatic __inline void 41199862Speterload_cr3(u_int data) 41299862Speter{ 413181775Skmacy#ifdef XEN 414181775Skmacy xen_load_cr3(data); 415181775Skmacy#else 41699862Speter __asm __volatile("movl %0,%%cr3" : : "r" (data) : "memory"); 417181775Skmacy#endif 41899862Speter} 41999862Speter 42099862Speterstatic __inline u_int 42199862Speterrcr3(void) 42299862Speter{ 42399862Speter u_int data; 42499862Speter 42599862Speter __asm __volatile("movl %%cr3,%0" : "=r" (data)); 42699862Speter return (data); 42799862Speter} 42899862Speter 42999862Speterstatic __inline void 43099862Speterload_cr4(u_int data) 43199862Speter{ 43299862Speter __asm __volatile("movl %0,%%cr4" : : "r" (data)); 43399862Speter} 43499862Speter 43599862Speterstatic __inline u_int 43699862Speterrcr4(void) 43799862Speter{ 43899862Speter u_int data; 43999862Speter 44099862Speter __asm __volatile("movl %%cr4,%0" : "=r" (data)); 44199862Speter return (data); 44299862Speter} 44399862Speter 44499862Speter/* 44599862Speter * Global TLB flush (except for thise for pages marked PG_G) 44699862Speter */ 44799862Speterstatic __inline void 44899862Speterinvltlb(void) 44999862Speter{ 450181775Skmacy#ifdef XEN 451181775Skmacy xen_tlb_flush(); 452181775Skmacy#else 45399862Speter load_cr3(rcr3()); 454181775Skmacy#endif 45599862Speter} 45699862Speter 45799862Speter/* 45899862Speter * TLB flush for an individual page (even if it has PG_G). 45999862Speter * Only works on 486+ CPUs (i386 does not have PG_G). 46099862Speter */ 46199862Speterstatic __inline void 46299862Speterinvlpg(u_int addr) 46399862Speter{ 46499862Speter 465181775Skmacy#ifdef XEN 466181775Skmacy xen_invlpg(addr); 467181775Skmacy#else 46899862Speter __asm __volatile("invlpg %0" : : "m" (*(char *)addr) : "memory"); 469181775Skmacy#endif 47099862Speter} 47199862Speter 472212177Srdivackystatic __inline u_short 47346129Sluoqirfs(void) 47446129Sluoqi{ 475212177Srdivacky u_short sel; 476212177Srdivacky __asm __volatile("movw %%fs,%0" : "=rm" (sel)); 47746129Sluoqi return (sel); 47846129Sluoqi} 47946129Sluoqi 480171797Snjlstatic __inline uint64_t 481171797Snjlrgdt(void) 482171797Snjl{ 483171797Snjl uint64_t gdtr; 484171797Snjl __asm __volatile("sgdt %0" : "=m" (gdtr)); 485171797Snjl return (gdtr); 486171797Snjl} 487171797Snjl 488212177Srdivackystatic __inline u_short 48946129Sluoqirgs(void) 49046129Sluoqi{ 491212177Srdivacky u_short sel; 492212177Srdivacky __asm __volatile("movw %%gs,%0" : "=rm" (sel)); 49346129Sluoqi return (sel); 49446129Sluoqi} 49546129Sluoqi 496171797Snjlstatic __inline uint64_t 497171797Snjlridt(void) 498171797Snjl{ 499171797Snjl uint64_t idtr; 500171797Snjl __asm __volatile("sidt %0" : "=m" (idtr)); 501171797Snjl return (idtr); 502171797Snjl} 503171797Snjl 504171797Snjlstatic __inline u_short 505171797Snjlrldt(void) 506171797Snjl{ 507171797Snjl u_short ldtr; 508171797Snjl __asm __volatile("sldt %0" : "=g" (ldtr)); 509171797Snjl return (ldtr); 510171797Snjl} 511171797Snjl 512212177Srdivackystatic __inline u_short 513127813Smarcelrss(void) 514127813Smarcel{ 515212177Srdivacky u_short sel; 516212177Srdivacky __asm __volatile("movw %%ss,%0" : "=rm" (sel)); 517127813Smarcel return (sel); 518127813Smarcel} 519127813Smarcel 520171797Snjlstatic __inline u_short 521171797Snjlrtr(void) 522171797Snjl{ 523171797Snjl u_short tr; 524171797Snjl __asm __volatile("str %0" : "=g" (tr)); 525171797Snjl return (tr); 526171797Snjl} 527171797Snjl 52846129Sluoqistatic __inline void 529212177Srdivackyload_fs(u_short sel) 53046129Sluoqi{ 531212177Srdivacky __asm __volatile("movw %0,%%fs" : : "rm" (sel)); 53246129Sluoqi} 53346129Sluoqi 53446129Sluoqistatic __inline void 535212177Srdivackyload_gs(u_short sel) 53646129Sluoqi{ 537212177Srdivacky __asm __volatile("movw %0,%%gs" : : "rm" (sel)); 53846129Sluoqi} 53946129Sluoqi 540103778Speterstatic __inline void 541103778Speterlidt(struct region_descriptor *addr) 542103778Speter{ 543103778Speter __asm __volatile("lidt (%0)" : : "r" (addr)); 544103778Speter} 545103778Speter 546103778Speterstatic __inline void 547103778Speterlldt(u_short sel) 548103778Speter{ 549103778Speter __asm __volatile("lldt %0" : : "r" (sel)); 550103778Speter} 551103778Speter 552103778Speterstatic __inline void 553103778Speterltr(u_short sel) 554103778Speter{ 555103778Speter __asm __volatile("ltr %0" : : "r" (sel)); 556103778Speter} 557103778Speter 55857362Sbsdstatic __inline u_int 55957362Sbsdrdr0(void) 56057362Sbsd{ 56157362Sbsd u_int data; 56257376Sbsd __asm __volatile("movl %%dr0,%0" : "=r" (data)); 56357362Sbsd return (data); 56457362Sbsd} 56557362Sbsd 56678903Sbsdstatic __inline void 56797115Sjhbload_dr0(u_int dr0) 56878903Sbsd{ 56997115Sjhb __asm __volatile("movl %0,%%dr0" : : "r" (dr0)); 57078903Sbsd} 57178903Sbsd 57257362Sbsdstatic __inline u_int 57357362Sbsdrdr1(void) 57457362Sbsd{ 57557362Sbsd u_int data; 57657376Sbsd __asm __volatile("movl %%dr1,%0" : "=r" (data)); 57757362Sbsd return (data); 57857362Sbsd} 57957362Sbsd 58078903Sbsdstatic __inline void 58197115Sjhbload_dr1(u_int dr1) 58278903Sbsd{ 58397115Sjhb __asm __volatile("movl %0,%%dr1" : : "r" (dr1)); 58478903Sbsd} 58578903Sbsd 58657362Sbsdstatic __inline u_int 58757362Sbsdrdr2(void) 58857362Sbsd{ 58957362Sbsd u_int data; 59057376Sbsd __asm __volatile("movl %%dr2,%0" : "=r" (data)); 59157362Sbsd return (data); 59257362Sbsd} 59357362Sbsd 59478903Sbsdstatic __inline void 59597115Sjhbload_dr2(u_int dr2) 59678903Sbsd{ 59797115Sjhb __asm __volatile("movl %0,%%dr2" : : "r" (dr2)); 59878903Sbsd} 59978903Sbsd 60057362Sbsdstatic __inline u_int 60157362Sbsdrdr3(void) 60257362Sbsd{ 60357362Sbsd u_int data; 60457376Sbsd __asm __volatile("movl %%dr3,%0" : "=r" (data)); 60557362Sbsd return (data); 60657362Sbsd} 60757362Sbsd 60878903Sbsdstatic __inline void 60997115Sjhbload_dr3(u_int dr3) 61078903Sbsd{ 61197115Sjhb __asm __volatile("movl %0,%%dr3" : : "r" (dr3)); 61278903Sbsd} 61378903Sbsd 61457362Sbsdstatic __inline u_int 61578903Sbsdrdr4(void) 61678903Sbsd{ 61778903Sbsd u_int data; 61878903Sbsd __asm __volatile("movl %%dr4,%0" : "=r" (data)); 61978903Sbsd return (data); 62078903Sbsd} 62178903Sbsd 62278903Sbsdstatic __inline void 62397115Sjhbload_dr4(u_int dr4) 62478903Sbsd{ 62597115Sjhb __asm __volatile("movl %0,%%dr4" : : "r" (dr4)); 62678903Sbsd} 62778903Sbsd 62878903Sbsdstatic __inline u_int 62978903Sbsdrdr5(void) 63078903Sbsd{ 63178903Sbsd u_int data; 63278903Sbsd __asm __volatile("movl %%dr5,%0" : "=r" (data)); 63378903Sbsd return (data); 63478903Sbsd} 63578903Sbsd 63678903Sbsdstatic __inline void 63797115Sjhbload_dr5(u_int dr5) 63878903Sbsd{ 63997115Sjhb __asm __volatile("movl %0,%%dr5" : : "r" (dr5)); 64078903Sbsd} 64178903Sbsd 64278903Sbsdstatic __inline u_int 64357362Sbsdrdr6(void) 64457362Sbsd{ 64557362Sbsd u_int data; 64657376Sbsd __asm __volatile("movl %%dr6,%0" : "=r" (data)); 64757362Sbsd return (data); 64857362Sbsd} 64957362Sbsd 65078903Sbsdstatic __inline void 65197115Sjhbload_dr6(u_int dr6) 65278903Sbsd{ 65397115Sjhb __asm __volatile("movl %0,%%dr6" : : "r" (dr6)); 65478903Sbsd} 65578903Sbsd 65657362Sbsdstatic __inline u_int 65757362Sbsdrdr7(void) 65857362Sbsd{ 65957362Sbsd u_int data; 66057376Sbsd __asm __volatile("movl %%dr7,%0" : "=r" (data)); 66157362Sbsd return (data); 66257362Sbsd} 66357362Sbsd 66478903Sbsdstatic __inline void 66597115Sjhbload_dr7(u_int dr7) 66678903Sbsd{ 66797115Sjhb __asm __volatile("movl %0,%%dr7" : : "r" (dr7)); 66878903Sbsd} 66978903Sbsd 670194295Sjhbstatic __inline u_char 671194295Sjhbread_cyrix_reg(u_char reg) 672194295Sjhb{ 673194295Sjhb outb(0x22, reg); 674194295Sjhb return inb(0x23); 675194295Sjhb} 676194295Sjhb 677194295Sjhbstatic __inline void 678194295Sjhbwrite_cyrix_reg(u_char reg, u_char data) 679194295Sjhb{ 680194295Sjhb outb(0x22, reg); 681194295Sjhb outb(0x23, data); 682194295Sjhb} 683194295Sjhb 68492860Simpstatic __inline register_t 68592860Simpintr_disable(void) 68692860Simp{ 687181911Skmacy register_t eflags; 68892860Simp 68992860Simp eflags = read_eflags(); 69092860Simp disable_intr(); 69192860Simp return (eflags); 69292860Simp} 69392860Simp 69492860Simpstatic __inline void 69592860Simpintr_restore(register_t eflags) 69692860Simp{ 69792860Simp write_eflags(eflags); 69892860Simp} 69992860Simp 700143063Sjoerg#else /* !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */ 7014Srgrimes 70292819Simpint breakpoint(void); 70392819Simpu_int bsfl(u_int mask); 70492819Simpu_int bsrl(u_int mask); 705239914Sjhbvoid clflush(u_long addr); 706239914Sjhbvoid clts(void); 707239914Sjhbvoid cpuid_count(u_int ax, u_int cx, u_int *p); 70892819Simpvoid disable_intr(void); 70992819Simpvoid do_cpuid(u_int ax, u_int *p); 71092819Simpvoid enable_intr(void); 711103749Smarkmvoid halt(void); 712126656Sbdevoid ia32_pause(void); 71392819Simpu_char inb(u_int port); 71492819Simpu_int inl(u_int port); 715201369Sobrienvoid insb(u_int port, void *addr, size_t count); 716201369Sobrienvoid insl(u_int port, void *addr, size_t count); 717201369Sobrienvoid insw(u_int port, void *addr, size_t count); 718126656Sbderegister_t intr_disable(void); 719126656Sbdevoid intr_restore(register_t ef); 72092819Simpvoid invd(void); 72192819Simpvoid invlpg(u_int addr); 72292819Simpvoid invltlb(void); 72392819Simpu_short inw(u_int port); 724126656Sbdevoid lidt(struct region_descriptor *addr); 725126656Sbdevoid lldt(u_short sel); 72699862Spetervoid load_cr0(u_int cr0); 72799862Spetervoid load_cr3(u_int cr3); 72899862Spetervoid load_cr4(u_int cr4); 729126656Sbdevoid load_dr0(u_int dr0); 730126656Sbdevoid load_dr1(u_int dr1); 731126656Sbdevoid load_dr2(u_int dr2); 732126656Sbdevoid load_dr3(u_int dr3); 733126656Sbdevoid load_dr4(u_int dr4); 734126656Sbdevoid load_dr5(u_int dr5); 735126656Sbdevoid load_dr6(u_int dr6); 736126656Sbdevoid load_dr7(u_int dr7); 737212177Srdivackyvoid load_fs(u_short sel); 738212177Srdivackyvoid load_gs(u_short sel); 739103778Spetervoid ltr(u_short sel); 74092819Simpvoid outb(u_int port, u_char data); 74192819Simpvoid outl(u_int port, u_int data); 742201369Sobrienvoid outsb(u_int port, const void *addr, size_t count); 743201369Sobrienvoid outsl(u_int port, const void *addr, size_t count); 744201369Sobrienvoid outsw(u_int port, const void *addr, size_t count); 74592819Simpvoid outw(u_int port, u_short data); 74699862Speteru_int rcr0(void); 74792819Simpu_int rcr2(void); 74899862Speteru_int rcr3(void); 74999862Speteru_int rcr4(void); 750171797Snjluint64_t rdmsr(u_int msr); 751171797Snjluint64_t rdpmc(u_int pmc); 75297114Sjhbu_int rdr0(void); 75397114Sjhbu_int rdr1(void); 75497114Sjhbu_int rdr2(void); 75597114Sjhbu_int rdr3(void); 75697114Sjhbu_int rdr4(void); 75797114Sjhbu_int rdr5(void); 75897114Sjhbu_int rdr6(void); 75997114Sjhbu_int rdr7(void); 760171797Snjluint64_t rdtsc(void); 761194295Sjhbu_char read_cyrix_reg(u_char reg); 762126656Sbdeu_int read_eflags(void); 763126656Sbdeu_int rfs(void); 764171797Snjluint64_t rgdt(void); 765126656Sbdeu_int rgs(void); 766171797Snjluint64_t ridt(void); 767171797Snjlu_short rldt(void); 768171797Snjlu_short rtr(void); 769126656Sbdevoid wbinvd(void); 770194295Sjhbvoid write_cyrix_reg(u_char reg, u_char data); 771126656Sbdevoid write_eflags(u_int ef); 772171797Snjlvoid wrmsr(u_int msr, uint64_t newval); 7734Srgrimes 774143063Sjoerg#endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */ 7754Srgrimes 77692761Salfredvoid reset_dbregs(void); 77793264Sdillon 778181430Sstas#ifdef _KERNEL 779181430Sstasint rdmsr_safe(u_int msr, uint64_t *val); 780181430Sstasint wrmsr_safe(u_int msr, uint64_t newval); 781181430Sstas#endif 782181430Sstas 7834479Sbde#endif /* !_MACHINE_CPUFUNC_H_ */ 784