15b81b6b3SRodney W. Grimes /* 25b81b6b3SRodney W. Grimes * Functions to provide access to special i386 instructions. 35b81b6b3SRodney W. Grimes * XXX - bezillions more are defined in locore.s but are not declared anywhere. 45b81b6b3SRodney W. Grimes */ 55b81b6b3SRodney W. Grimes 65b81b6b3SRodney W. Grimes #include <sys/cdefs.h> 75b81b6b3SRodney W. Grimes #include <sys/types.h> 85b81b6b3SRodney W. Grimes 95b81b6b3SRodney W. Grimes #ifdef __GNUC__ 105b81b6b3SRodney W. Grimes 115b81b6b3SRodney W. Grimes static __inline int bdb(void) 125b81b6b3SRodney W. Grimes { 135b81b6b3SRodney W. Grimes extern int bdb_exists; 145b81b6b3SRodney W. Grimes 155b81b6b3SRodney W. Grimes if (!bdb_exists) 165b81b6b3SRodney W. Grimes return (0); 175b81b6b3SRodney W. Grimes __asm("int $3"); 185b81b6b3SRodney W. Grimes return (1); 195b81b6b3SRodney W. Grimes } 205b81b6b3SRodney W. Grimes 215b81b6b3SRodney W. Grimes static __inline void 225b81b6b3SRodney W. Grimes disable_intr(void) 235b81b6b3SRodney W. Grimes { 245b81b6b3SRodney W. Grimes __asm __volatile("cli"); 255b81b6b3SRodney W. Grimes } 265b81b6b3SRodney W. Grimes 275b81b6b3SRodney W. Grimes static __inline void 285b81b6b3SRodney W. Grimes enable_intr(void) 295b81b6b3SRodney W. Grimes { 305b81b6b3SRodney W. Grimes __asm __volatile("sti"); 315b81b6b3SRodney W. Grimes } 325b81b6b3SRodney W. Grimes 335b81b6b3SRodney W. Grimes /* 345b81b6b3SRodney W. Grimes * This roundabout method of returning a u_char helps stop gcc-1.40 from 355b81b6b3SRodney W. Grimes * generating unnecessary movzbl's. 365b81b6b3SRodney W. Grimes */ 375b81b6b3SRodney W. Grimes #define inb(port) ((u_char) u_int_inb(port)) 385b81b6b3SRodney W. Grimes 395b81b6b3SRodney W. Grimes static __inline u_int 405b81b6b3SRodney W. Grimes u_int_inb(u_int port) 415b81b6b3SRodney W. Grimes { 425b81b6b3SRodney W. Grimes u_char data; 435b81b6b3SRodney W. Grimes /* 445b81b6b3SRodney W. Grimes * We use %%dx and not %1 here because i/o is done at %dx and not at 455b81b6b3SRodney W. Grimes * %edx, while gcc-2.2.2 generates inferior code (movw instead of movl) 465b81b6b3SRodney W. Grimes * if we tell it to load (u_short) port. 475b81b6b3SRodney W. Grimes */ 485b81b6b3SRodney W. Grimes __asm __volatile("inb %%dx,%0" : "=a" (data) : "d" (port)); 495b81b6b3SRodney W. Grimes return data; 505b81b6b3SRodney W. Grimes } 515b81b6b3SRodney W. Grimes 525b81b6b3SRodney W. Grimes static __inline void 535b81b6b3SRodney W. Grimes outb(u_int port, u_char data) 545b81b6b3SRodney W. Grimes { 555b81b6b3SRodney W. Grimes register u_char al asm("ax"); 565b81b6b3SRodney W. Grimes 575b81b6b3SRodney W. Grimes al = data; /* help gcc-1.40's register allocator */ 585b81b6b3SRodney W. Grimes __asm __volatile("outb %0,%%dx" : : "a" (al), "d" (port)); 595b81b6b3SRodney W. Grimes } 605b81b6b3SRodney W. Grimes 615b81b6b3SRodney W. Grimes #else /* not __GNUC__ */ 625b81b6b3SRodney W. Grimes 635b81b6b3SRodney W. Grimes int bdb __P((void)); 645b81b6b3SRodney W. Grimes void disable_intr __P((void)); 655b81b6b3SRodney W. Grimes void enable_intr __P((void)); 665b81b6b3SRodney W. Grimes u_char inb __P((u_int port)); 675b81b6b3SRodney W. Grimes void outb __P((u_int port, u_int data)); /* XXX - incompat */ 685b81b6b3SRodney W. Grimes 695b81b6b3SRodney W. Grimes #endif /* __GNUC__ */ 705b81b6b3SRodney W. Grimes 715b81b6b3SRodney W. Grimes #define really_u_int int /* XXX */ 725b81b6b3SRodney W. Grimes #define really_void int /* XXX */ 735b81b6b3SRodney W. Grimes 745b81b6b3SRodney W. Grimes void load_cr0 __P((u_int cr0)); 755b81b6b3SRodney W. Grimes really_u_int rcr0 __P((void)); 765b81b6b3SRodney W. Grimes 775b81b6b3SRodney W. Grimes #ifdef notyet 785b81b6b3SRodney W. Grimes really_void setidt __P((int idx, /*XXX*/caddr_t func, int typ, int dpl)); 795b81b6b3SRodney W. Grimes #endif 805b81b6b3SRodney W. Grimes 815b81b6b3SRodney W. Grimes #undef really_u_int 825b81b6b3SRodney W. Grimes #undef really_void 83