xref: /freebsd/sys/i386/include/cpufunc.h (revision afe61c15161c324a7af299a9b8457aba5afc92db)
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.9 1994/01/31 23:48:23 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 #include "machine/spl.h"
15 
16 #ifdef	__GNUC__
17 
18 static inline int bdb(void)
19 {
20 	extern int bdb_exists;
21 
22 	if (!bdb_exists)
23 		return (0);
24 	__asm("int $3");
25 	return (1);
26 }
27 
28 static inline void
29 disable_intr(void)
30 {
31 	__asm __volatile("cli");
32 }
33 
34 static inline void
35 enable_intr(void)
36 {
37 	__asm __volatile("sti");
38 }
39 
40 /*
41  * This roundabout method of returning a u_char helps stop gcc-1.40 from
42  * generating unnecessary movzbl's.
43  */
44 #define	inb(port)	((u_char) u_int_inb(port))
45 
46 static inline u_int
47 u_int_inb(u_int port)
48 {
49 	u_char	data;
50 	/*
51 	 * We use %%dx and not %1 here because i/o is done at %dx and not at
52 	 * %edx, while gcc-2.2.2 generates inferior code (movw instead of movl)
53 	 * if we tell it to load (u_short) port.
54 	 */
55 	__asm __volatile("inb %%dx,%0" : "=a" (data) : "d" (port));
56 	return data;
57 }
58 
59 static inline void
60 outb(u_int port, u_char data)
61 {
62 	register u_char	al asm("ax");
63 
64 	al = data;		/* help gcc-1.40's register allocator */
65 	__asm __volatile("outb %0,%%dx" : : "a" (al), "d" (port));
66 }
67 
68 static inline void
69 tlbflush()
70 {
71 	__asm __volatile("movl %%cr3, %%eax; movl %%eax, %%cr3" : : : "ax");
72 }
73 
74 #else /* not __GNUC__ */
75 extern	void insque __P((void *, void *));
76 extern	void remque __P((void *));
77 
78 int	bdb		__P((void));
79 void	disable_intr	__P((void));
80 void	enable_intr	__P((void));
81 u_char	inb		__P((u_int port));
82 void	outb		__P((u_int port, u_int data));	/* XXX - incompat */
83 
84 #endif	/* __GNUC__ */
85 
86 void	load_cr0	__P((u_int cr0));
87 u_int	rcr0	__P((void));
88 void load_cr3(u_long);
89 u_long rcr3(void);
90 u_long rcr2(void);
91 
92 void	setidt	__P((int, void (*)(), int, int));
93 extern u_long kvtop(void *);
94 extern void outw(int /*u_short*/, int /*u_short*/); /* XXX inline!*/
95 extern void outsb(int /*u_short*/, void *, size_t);
96 extern void outsw(int /*u_short*/, void *, size_t);
97 extern void insw(int /*u_short*/, void *, size_t);
98 extern void fillw(int /*u_short*/, void *, size_t);
99 extern void filli(int, void *, size_t);
100 
101 #endif /* _MACHINE_CPUFUNC_H_ */
102