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 6126931201SDavid Greenman static __inline__ 6226931201SDavid Greenman imin(a, b) 6326931201SDavid Greenman int a, b; 6426931201SDavid Greenman { 6526931201SDavid Greenman 6626931201SDavid Greenman return (a < b ? a : b); 6726931201SDavid Greenman } 6826931201SDavid Greenman 6926931201SDavid Greenman static __inline__ 7026931201SDavid Greenman imax(a, b) 7126931201SDavid Greenman int a, b; 7226931201SDavid Greenman { 7326931201SDavid Greenman 7426931201SDavid Greenman return (a > b ? a : b); 7526931201SDavid Greenman } 7626931201SDavid Greenman 7726931201SDavid Greenman static __inline__ 7826931201SDavid Greenman unsigned int 7926931201SDavid Greenman min(a, b) 8026931201SDavid Greenman unsigned int a, b; 8126931201SDavid Greenman { 8226931201SDavid Greenman 8326931201SDavid Greenman return (a < b ? a : b); 8426931201SDavid Greenman } 8526931201SDavid Greenman 8626931201SDavid Greenman static __inline__ 8726931201SDavid Greenman unsigned int 8826931201SDavid Greenman max(a, b) 8926931201SDavid Greenman unsigned int a, b; 9026931201SDavid Greenman { 9126931201SDavid Greenman 9226931201SDavid Greenman return (a > b ? a : b); 9326931201SDavid Greenman } 9426931201SDavid Greenman 9526931201SDavid Greenman static __inline__ 9626931201SDavid Greenman long 9726931201SDavid Greenman lmin(a, b) 9826931201SDavid Greenman long a, b; 9926931201SDavid Greenman { 10026931201SDavid Greenman 10126931201SDavid Greenman return (a < b ? a : b); 10226931201SDavid Greenman } 10326931201SDavid Greenman 10426931201SDavid Greenman static __inline__ 10526931201SDavid Greenman long 10626931201SDavid Greenman lmax(a, b) 10726931201SDavid Greenman long a, b; 10826931201SDavid Greenman { 10926931201SDavid Greenman 11026931201SDavid Greenman return (a > b ? a : b); 11126931201SDavid Greenman } 11226931201SDavid Greenman 11326931201SDavid Greenman static __inline__ 11426931201SDavid Greenman unsigned long 11526931201SDavid Greenman ulmin(a, b) 11626931201SDavid Greenman unsigned long a, b; 11726931201SDavid Greenman { 11826931201SDavid Greenman 11926931201SDavid Greenman return (a < b ? a : b); 12026931201SDavid Greenman } 12126931201SDavid Greenman 12226931201SDavid Greenman static __inline__ 12326931201SDavid Greenman unsigned long 12426931201SDavid Greenman ulmax(a, b) 12526931201SDavid Greenman unsigned long a, b; 12626931201SDavid Greenman { 12726931201SDavid Greenman 12826931201SDavid Greenman return (a > b ? a : b); 12926931201SDavid Greenman } 13026931201SDavid Greenman 13126931201SDavid Greenman static __inline__ 13226931201SDavid Greenman ffs(mask) 13326931201SDavid Greenman register long mask; 13426931201SDavid Greenman { 13526931201SDavid Greenman register int bit; 13626931201SDavid Greenman 13726931201SDavid Greenman if (!mask) 13826931201SDavid Greenman return(0); 13926931201SDavid Greenman for (bit = 1;; ++bit) { 14026931201SDavid Greenman if (mask&0x01) 14126931201SDavid Greenman return(bit); 14226931201SDavid Greenman mask >>= 1; 14326931201SDavid Greenman } 14426931201SDavid Greenman } 14526931201SDavid Greenman 14626931201SDavid Greenman static __inline__ 14726931201SDavid Greenman bcmp(v1, v2, len) 14826931201SDavid Greenman void *v1, *v2; 14926931201SDavid Greenman register unsigned len; 15026931201SDavid Greenman { 15126931201SDavid Greenman register u_char *s1 = v1, *s2 = v2; 15226931201SDavid Greenman 15326931201SDavid Greenman while (len--) 15426931201SDavid Greenman if (*s1++ != *s2++) 15526931201SDavid Greenman return (1); 15626931201SDavid Greenman return (0); 15726931201SDavid Greenman } 15826931201SDavid Greenman 15926931201SDavid Greenman static __inline__ 16026931201SDavid Greenman size_t 16126931201SDavid Greenman strlen(s1) 16226931201SDavid Greenman register __const__ char *s1; 16326931201SDavid Greenman { 16426931201SDavid Greenman register size_t len; 16526931201SDavid Greenman 16626931201SDavid Greenman for (len = 0; *s1++ != '\0'; len++) 16726931201SDavid Greenman ; 16826931201SDavid Greenman return (len); 16926931201SDavid Greenman } 17026931201SDavid Greenman 1715b81b6b3SRodney W. Grimes #else /* not __GNUC__ */ 1725b81b6b3SRodney W. Grimes 1735b81b6b3SRodney W. Grimes int bdb __P((void)); 1745b81b6b3SRodney W. Grimes void disable_intr __P((void)); 1755b81b6b3SRodney W. Grimes void enable_intr __P((void)); 1765b81b6b3SRodney W. Grimes u_char inb __P((u_int port)); 1775b81b6b3SRodney W. Grimes void outb __P((u_int port, u_int data)); /* XXX - incompat */ 1785b81b6b3SRodney W. Grimes 1795b81b6b3SRodney W. Grimes #endif /* __GNUC__ */ 1805b81b6b3SRodney W. Grimes 1815b81b6b3SRodney W. Grimes #define really_u_int int /* XXX */ 1825b81b6b3SRodney W. Grimes #define really_void int /* XXX */ 1835b81b6b3SRodney W. Grimes 1845b81b6b3SRodney W. Grimes void load_cr0 __P((u_int cr0)); 1855b81b6b3SRodney W. Grimes really_u_int rcr0 __P((void)); 1865b81b6b3SRodney W. Grimes 1875b81b6b3SRodney W. Grimes #ifdef notyet 1885b81b6b3SRodney W. Grimes really_void setidt __P((int idx, /*XXX*/caddr_t func, int typ, int dpl)); 1895b81b6b3SRodney W. Grimes #endif 1905b81b6b3SRodney W. Grimes 1915b81b6b3SRodney W. Grimes #undef really_u_int 1925b81b6b3SRodney W. Grimes #undef really_void 19326931201SDavid Greenman 194