cpufunc.h revision 1045
1/* 2 * Functions to provide access to special i386 instructions. 3 * XXX - bezillions more are defined in locore.s but are not declared anywhere. 4 * 5 * $Id: cpufunc.h,v 1.7 1993/12/21 21:27:04 davidg Exp $ 6 */ 7 8#ifndef _MACHINE_CPUFUNC_H_ 9#define _MACHINE_CPUFUNC_H_ 1 10 11#include <sys/cdefs.h> 12#include <sys/types.h> 13 14#ifdef __GNUC__ 15 16static inline int bdb(void) 17{ 18 extern int bdb_exists; 19 20 if (!bdb_exists) 21 return (0); 22 __asm("int $3"); 23 return (1); 24} 25 26static inline void 27disable_intr(void) 28{ 29 __asm __volatile("cli"); 30} 31 32static inline void 33enable_intr(void) 34{ 35 __asm __volatile("sti"); 36} 37 38/* 39 * This roundabout method of returning a u_char helps stop gcc-1.40 from 40 * generating unnecessary movzbl's. 41 */ 42#define inb(port) ((u_char) u_int_inb(port)) 43 44static inline u_int 45u_int_inb(u_int port) 46{ 47 u_char data; 48 /* 49 * We use %%dx and not %1 here because i/o is done at %dx and not at 50 * %edx, while gcc-2.2.2 generates inferior code (movw instead of movl) 51 * if we tell it to load (u_short) port. 52 */ 53 __asm __volatile("inb %%dx,%0" : "=a" (data) : "d" (port)); 54 return data; 55} 56 57static inline void 58outb(u_int port, u_char data) 59{ 60 register u_char al asm("ax"); 61 62 al = data; /* help gcc-1.40's register allocator */ 63 __asm __volatile("outb %0,%%dx" : : "a" (al), "d" (port)); 64} 65 66static inline void 67tlbflush() 68{ 69 __asm __volatile("movl %%cr3, %%eax; movl %%eax, %%cr3" : : : "ax"); 70} 71 72static inline 73int 74imin(a, b) 75 int a, b; 76{ 77 78 return (a < b ? a : b); 79} 80 81static inline 82int 83imax(a, b) 84 int a, b; 85{ 86 87 return (a > b ? a : b); 88} 89 90static inline 91unsigned int 92min(a, b) 93 unsigned int a, b; 94{ 95 96 return (a < b ? a : b); 97} 98 99static inline 100unsigned int 101max(a, b) 102 unsigned int a, b; 103{ 104 105 return (a > b ? a : b); 106} 107 108static inline 109long 110lmin(a, b) 111 long a, b; 112{ 113 114 return (a < b ? a : b); 115} 116 117static inline 118long 119lmax(a, b) 120 long a, b; 121{ 122 123 return (a > b ? a : b); 124} 125 126static inline 127unsigned long 128ulmin(a, b) 129 unsigned long a, b; 130{ 131 132 return (a < b ? a : b); 133} 134 135static inline 136unsigned long 137ulmax(a, b) 138 unsigned long a, b; 139{ 140 141 return (a > b ? a : b); 142} 143 144static inline 145int 146ffs(mask) 147 register long mask; 148{ 149 register int bit; 150 151 if (!mask) 152 return(0); 153 for (bit = 1;; ++bit) { 154 if (mask&0x01) 155 return(bit); 156 mask >>= 1; 157 } 158} 159 160static inline 161int 162bcmp(v1, v2, len) 163 void *v1, *v2; 164 register unsigned len; 165{ 166 register u_char *s1 = v1, *s2 = v2; 167 168 while (len--) 169 if (*s1++ != *s2++) 170 return (1); 171 return (0); 172} 173 174static inline 175size_t 176strlen(s1) 177 register const char *s1; 178{ 179 register size_t len; 180 181 for (len = 0; *s1++ != '\0'; len++) 182 ; 183 return (len); 184} 185 186struct quehead { 187 struct quehead *qh_link; 188 struct quehead *qh_rlink; 189}; 190 191static inline void 192insque(void *a, void *b) 193{ 194 register struct quehead *element = a, *head = b; 195 element->qh_link = head->qh_link; 196 head->qh_link = (struct quehead *)element; 197 element->qh_rlink = (struct quehead *)head; 198 ((struct quehead *)(element->qh_link))->qh_rlink 199 = (struct quehead *)element; 200} 201 202static inline void 203remque(void *a) 204{ 205 register struct quehead *element = a; 206 ((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink; 207 ((struct quehead *)(element->qh_rlink))->qh_link = element->qh_link; 208 element->qh_rlink = 0; 209} 210 211#else /* not __GNUC__ */ 212extern void insque __P((void *, void *)); 213extern void remque __P((void *)); 214 215int bdb __P((void)); 216void disable_intr __P((void)); 217void enable_intr __P((void)); 218u_char inb __P((u_int port)); 219void outb __P((u_int port, u_int data)); /* XXX - incompat */ 220 221#endif /* __GNUC__ */ 222 223void load_cr0 __P((u_int cr0)); 224u_int rcr0 __P((void)); 225void load_cr3(u_long); 226u_long rcr3(void); 227u_long rcr2(void); 228 229void setidt __P((int, void (*)(), int, int)); 230extern u_long kvtop(void *); 231extern void outw(int /*u_short*/, int /*u_short*/); /* XXX inline!*/ 232extern void outsb(int /*u_short*/, void *, size_t); 233extern void outsw(int /*u_short*/, void *, size_t); 234extern void insw(int /*u_short*/, void *, size_t); 235extern void fillw(int /*u_short*/, void *, size_t); 236 237#endif /* _MACHINE_CPUFUNC_H_ */ 238