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