xref: /netbsd-src/sys/arch/i386/include/cpufunc.h (revision cda4f8f6ee55684e8d311b86c99ea59191e6b74f)
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 
6 #include <sys/cdefs.h>
7 #include <sys/types.h>
8 
9 #ifdef	__GNUC__
10 
11 static __inline int bdb(void)
12 {
13 	extern int bdb_exists;
14 
15 	if (!bdb_exists)
16 		return (0);
17 	__asm("int $3");
18 	return (1);
19 }
20 
21 static __inline void
22 disable_intr(void)
23 {
24 	__asm __volatile("cli");
25 }
26 
27 static __inline void
28 enable_intr(void)
29 {
30 	__asm __volatile("sti");
31 }
32 
33 /*
34  * This roundabout method of returning a u_char helps stop gcc-1.40 from
35  * generating unnecessary movzbl's.
36  */
37 #define	inb(port)	((u_char) u_int_inb(port))
38 
39 static __inline u_int
40 u_int_inb(u_int port)
41 {
42 	u_char	data;
43 	/*
44 	 * We use %%dx and not %1 here because i/o is done at %dx and not at
45 	 * %edx, while gcc-2.2.2 generates inferior code (movw instead of movl)
46 	 * if we tell it to load (u_short) port.
47 	 */
48 	__asm __volatile("inb %%dx,%0" : "=a" (data) : "d" (port));
49 	return data;
50 }
51 
52 static __inline void
53 outb(u_int port, u_char data)
54 {
55 	register u_char	al asm("ax");
56 
57 	al = data;		/* help gcc-1.40's register allocator */
58 	__asm __volatile("outb %0,%%dx" : : "a" (al), "d" (port));
59 }
60 
61 #else /* not __GNUC__ */
62 
63 int	bdb		__P((void));
64 void	disable_intr	__P((void));
65 void	enable_intr	__P((void));
66 u_char	inb		__P((u_int port));
67 void	outb		__P((u_int port, u_int data));	/* XXX - incompat */
68 
69 #endif	/* __GNUC__ */
70 
71 #define	really_u_int	int	/* XXX */
72 #define	really_void	int	/* XXX */
73 
74 void	load_cr0	__P((u_int cr0));
75 really_u_int	rcr0	__P((void));
76 
77 #ifdef notyet
78 really_void	setidt	__P((int idx, /*XXX*/caddr_t func, int typ, int dpl));
79 #endif
80 
81 #undef	really_u_int
82 #undef	really_void
83