cpufunc.h revision 907
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.6 1993/12/19 00:50:14 wollman 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
67int
68imin(a, b)
69	int a, b;
70{
71
72	return (a < b ? a : b);
73}
74
75static inline
76int
77imax(a, b)
78	int a, b;
79{
80
81	return (a > b ? a : b);
82}
83
84static inline
85unsigned int
86min(a, b)
87	unsigned int a, b;
88{
89
90	return (a < b ? a : b);
91}
92
93static inline
94unsigned int
95max(a, b)
96	unsigned int a, b;
97{
98
99	return (a > b ? a : b);
100}
101
102static inline
103long
104lmin(a, b)
105	long a, b;
106{
107
108	return (a < b ? a : b);
109}
110
111static inline
112long
113lmax(a, b)
114	long a, b;
115{
116
117	return (a > b ? a : b);
118}
119
120static inline
121unsigned long
122ulmin(a, b)
123	unsigned long a, b;
124{
125
126	return (a < b ? a : b);
127}
128
129static inline
130unsigned long
131ulmax(a, b)
132	unsigned long a, b;
133{
134
135	return (a > b ? a : b);
136}
137
138static inline
139int
140ffs(mask)
141	register long mask;
142{
143	register int bit;
144
145	if (!mask)
146		return(0);
147	for (bit = 1;; ++bit) {
148		if (mask&0x01)
149			return(bit);
150		mask >>= 1;
151	}
152}
153
154static inline
155int
156bcmp(v1, v2, len)
157	void *v1, *v2;
158	register unsigned len;
159{
160	register u_char *s1 = v1, *s2 = v2;
161
162	while (len--)
163		if (*s1++ != *s2++)
164			return (1);
165	return (0);
166}
167
168static inline
169size_t
170strlen(s1)
171	register const char *s1;
172{
173	register size_t len;
174
175	for (len = 0; *s1++ != '\0'; len++)
176		;
177	return (len);
178}
179
180struct quehead {
181	struct quehead *qh_link;
182	struct quehead *qh_rlink;
183};
184
185static inline void
186insque(void *a, void *b)
187{
188	register struct quehead *element = a, *head = b;
189	element->qh_link = head->qh_link;
190	head->qh_link = (struct quehead *)element;
191	element->qh_rlink = (struct quehead *)head;
192	((struct quehead *)(element->qh_link))->qh_rlink
193	  = (struct quehead *)element;
194}
195
196static inline void
197remque(void *a)
198{
199	register struct quehead *element = a;
200	((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink;
201	((struct quehead *)(element->qh_rlink))->qh_link = element->qh_link;
202	element->qh_rlink = 0;
203}
204
205#else /* not __GNUC__ */
206extern	void insque __P((void *, void *));
207extern	void remque __P((void *));
208
209int	bdb		__P((void));
210void	disable_intr	__P((void));
211void	enable_intr	__P((void));
212u_char	inb		__P((u_int port));
213void	outb		__P((u_int port, u_int data));	/* XXX - incompat */
214
215#endif	/* __GNUC__ */
216
217void	load_cr0	__P((u_int cr0));
218u_int	rcr0	__P((void));
219void load_cr3(u_long);
220u_long rcr3(void);
221u_long rcr2(void);
222
223void	setidt	__P((int, void (*)(), int, int));
224extern u_long kvtop(void *);
225extern void tlbflush(void);
226extern void outw(int /*u_short*/, int /*u_short*/); /* XXX inline!*/
227extern void outsb(int /*u_short*/, void *, size_t);
228extern void outsw(int /*u_short*/, void *, size_t);
229extern void insw(int /*u_short*/, void *, size_t);
230extern void fillw(int /*u_short*/, void *, size_t);
231
232#endif /* _MACHINE_CPUFUNC_H_ */
233