cpufunc.h revision 1056
1117610Sdes/*
2117610Sdes * Functions to provide access to special i386 instructions.
3255376Sdes * XXX - bezillions more are defined in locore.s but are not declared anywhere.
4117610Sdes *
5255376Sdes *	$Id: cpufunc.h,v 1.8 1994/01/31 04:18:45 davidg Exp $
6117610Sdes */
7117610Sdes
8117610Sdes#ifndef _MACHINE_CPUFUNC_H_
9255376Sdes#define _MACHINE_CPUFUNC_H_ 1
10117610Sdes
11117610Sdes#include <sys/cdefs.h>
12117610Sdes#include <sys/types.h>
13117610Sdes
14117610Sdes#ifdef	__GNUC__
15117610Sdes
16117610Sdesstatic inline int bdb(void)
17117610Sdes{
18255376Sdes	extern int bdb_exists;
19117610Sdes
20117610Sdes	if (!bdb_exists)
21117610Sdes		return (0);
22117610Sdes	__asm("int $3");
23255376Sdes	return (1);
24255376Sdes}
25255376Sdes
26117610Sdesstatic inline void
27255376Sdesdisable_intr(void)
28117610Sdes{
29255376Sdes	__asm __volatile("cli");
30255376Sdes}
31255376Sdes
32255376Sdesstatic inline void
33117610Sdesenable_intr(void)
34255376Sdes{
35117610Sdes	__asm __volatile("sti");
36117610Sdes}
37117610Sdes
38117610Sdes/*
39117610Sdes * This roundabout method of returning a u_char helps stop gcc-1.40 from
40117610Sdes * generating unnecessary movzbl's.
41117610Sdes */
42117610Sdes#define	inb(port)	((u_char) u_int_inb(port))
43117610Sdes
44117610Sdesstatic inline u_int
45117610Sdesu_int_inb(u_int port)
46117610Sdes{
47117610Sdes	u_char	data;
48117610Sdes	/*
49117610Sdes	 * We use %%dx and not %1 here because i/o is done at %dx and not at
50117610Sdes	 * %edx, while gcc-2.2.2 generates inferior code (movw instead of movl)
51117610Sdes	 * if we tell it to load (u_short) port.
52117610Sdes	 */
53255376Sdes	__asm __volatile("inb %%dx,%0" : "=a" (data) : "d" (port));
54117610Sdes	return data;
55117610Sdes}
56117610Sdes
57117610Sdesstatic inline void
58117610Sdesoutb(u_int port, u_char data)
59117610Sdes{
60117610Sdes	register u_char	al asm("ax");
61117610Sdes
62117610Sdes	al = data;		/* help gcc-1.40's register allocator */
63117610Sdes	__asm __volatile("outb %0,%%dx" : : "a" (al), "d" (port));
64117610Sdes}
65255376Sdes
66117610Sdesstatic inline void
67255376Sdestlbflush()
68117610Sdes{
69255376Sdes	__asm __volatile("movl %%cr3, %%eax; movl %%eax, %%cr3" : : : "ax");
70117610Sdes}
71117610Sdes
72117610Sdesstatic inline
73117610Sdesint
74117610Sdesimin(a, b)
75117610Sdes	int a, b;
76117610Sdes{
77117610Sdes
78117610Sdes	return (a < b ? a : b);
79117610Sdes}
80117610Sdes
81117610Sdesstatic inline
82117610Sdesint
83117610Sdesimax(a, b)
84117610Sdes	int a, b;
85117610Sdes{
86117610Sdes
87117610Sdes	return (a > b ? a : b);
88117610Sdes}
89117610Sdes
90117610Sdesstatic inline
91117610Sdesunsigned int
92117610Sdesmin(a, b)
93117610Sdes	unsigned int a, b;
94117610Sdes{
95117610Sdes
96117610Sdes	return (a < b ? a : b);
97117610Sdes}
98117610Sdes
99117610Sdesstatic inline
100117610Sdesunsigned int
101117610Sdesmax(a, b)
102117610Sdes	unsigned int a, b;
103255376Sdes{
104117610Sdes
105117610Sdes	return (a > b ? a : b);
106117610Sdes}
107117610Sdes
108117610Sdesstatic inline
109117610Sdeslong
110117610Sdeslmin(a, b)
111117610Sdes	long a, b;
112117610Sdes{
113117610Sdes
114117610Sdes	return (a < b ? a : b);
115117610Sdes}
116117610Sdes
117117610Sdesstatic inline
118117610Sdeslong
119117610Sdeslmax(a, b)
120117610Sdes	long a, b;
121117610Sdes{
122255376Sdes
123117610Sdes	return (a > b ? a : b);
124117610Sdes}
125117610Sdes
126117610Sdesstatic inline
127117610Sdesunsigned long
128117610Sdesulmin(a, b)
129117610Sdes	unsigned long a, b;
130117610Sdes{
131117610Sdes
132117610Sdes	return (a < b ? a : b);
133117610Sdes}
134117610Sdes
135255376Sdesstatic inline
136255376Sdesunsigned long
137255376Sdesulmax(a, b)
138255376Sdes	unsigned long a, b;
139255376Sdes{
140255376Sdes
141255376Sdes	return (a > b ? a : b);
142255376Sdes}
143255376Sdes
144255376Sdesstatic inline
145255376Sdesint
146255376Sdesffs(mask)
147255376Sdes	register long mask;
148255376Sdes{
149255376Sdes	register int bit;
150255376Sdes
151255376Sdes	if (!mask)
152255376Sdes		return(0);
153255376Sdes	for (bit = 1;; ++bit) {
154255376Sdes		if (mask&0x01)
155255376Sdes			return(bit);
156117610Sdes		mask >>= 1;
157117610Sdes	}
158117610Sdes}
159117610Sdes
160117610Sdesstatic inline
161255376Sdesint
162117610Sdesbcmp(v1, v2, len)
163117610Sdes	void *v1, *v2;
164117610Sdes	register unsigned len;
165117610Sdes{
166117610Sdes	register u_char *s1 = v1, *s2 = v2;
167117610Sdes
168117610Sdes	while (len--)
169117610Sdes		if (*s1++ != *s2++)
170117610Sdes			return (1);
171117610Sdes	return (0);
172117610Sdes}
173117610Sdes
174117610Sdesstatic inline
175117610Sdessize_t
176117610Sdesstrlen(s1)
177117610Sdes	register const char *s1;
178255376Sdes{
179117610Sdes	register size_t len;
180117610Sdes
181117610Sdes	for (len = 0; *s1++ != '\0'; len++)
182117610Sdes		;
183117610Sdes	return (len);
184117610Sdes}
185117610Sdes
186117610Sdesstruct quehead {
187255376Sdes	struct quehead *qh_link;
188117610Sdes	struct quehead *qh_rlink;
189117610Sdes};
190117610Sdes
191117610Sdesstatic inline void
192117610Sdesinsque(void *a, void *b)
193117610Sdes{
194117610Sdes	register struct quehead *element = a, *head = b;
195117610Sdes	element->qh_link = head->qh_link;
196117610Sdes	head->qh_link = (struct quehead *)element;
197255376Sdes	element->qh_rlink = (struct quehead *)head;
198117610Sdes	((struct quehead *)(element->qh_link))->qh_rlink
199117610Sdes	  = (struct quehead *)element;
200117610Sdes}
201117610Sdes
202117610Sdesstatic inline void
203117610Sdesremque(void *a)
204117610Sdes{
205117610Sdes	register struct quehead *element = a;
206117610Sdes	((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink;
207117610Sdes	((struct quehead *)(element->qh_rlink))->qh_link = element->qh_link;
208117610Sdes	element->qh_rlink = 0;
209117610Sdes}
210117610Sdes
211117610Sdes#else /* not __GNUC__ */
212117610Sdesextern	void insque __P((void *, void *));
213117610Sdesextern	void remque __P((void *));
214117610Sdes
215117610Sdesint	bdb		__P((void));
216117610Sdesvoid	disable_intr	__P((void));
217255376Sdesvoid	enable_intr	__P((void));
218255376Sdesu_char	inb		__P((u_int port));
219255376Sdesvoid	outb		__P((u_int port, u_int data));	/* XXX - incompat */
220255376Sdes
221255376Sdes#endif	/* __GNUC__ */
222117610Sdes
223255376Sdesvoid	load_cr0	__P((u_int cr0));
224255376Sdesu_int	rcr0	__P((void));
225255376Sdesvoid load_cr3(u_long);
226255376Sdesu_long rcr3(void);
227255376Sdesu_long rcr2(void);
228255376Sdes
229255376Sdesvoid	setidt	__P((int, void (*)(), int, int));
230255376Sdesextern u_long kvtop(void *);
231255376Sdesextern void outw(int /*u_short*/, int /*u_short*/); /* XXX inline!*/
232255376Sdesextern void outsb(int /*u_short*/, void *, size_t);
233255376Sdesextern void outsw(int /*u_short*/, void *, size_t);
234255376Sdesextern void insw(int /*u_short*/, void *, size_t);
235255376Sdesextern void fillw(int /*u_short*/, void *, size_t);
236255376Sdesextern void filli(int, void *, size_t);
237255376Sdes
238117610Sdes#endif /* _MACHINE_CPUFUNC_H_ */
239255376Sdes