summaryrefslogtreecommitdiffstats
path: root/sys/i386/include/cpufunc.h
blob: 729a5c06ccf88da5f7d5ba367c2bb137ce2a6ae4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*
 * Functions to provide access to special i386 instructions.
 * XXX - bezillions more are defined in locore.s but are not declared anywhere.
 *
 *	$Id: cpufunc.h,v 1.9 1994/01/31 23:48:23 davidg Exp $
 */

#ifndef _MACHINE_CPUFUNC_H_
#define _MACHINE_CPUFUNC_H_ 1

#include <sys/cdefs.h>
#include <sys/types.h>

#include "machine/spl.h"

#ifdef	__GNUC__

static inline int bdb(void)
{
	extern int bdb_exists;

	if (!bdb_exists)
		return (0);
	__asm("int $3");
	return (1);
}

static inline void
disable_intr(void)
{
	__asm __volatile("cli");
}

static inline void
enable_intr(void)
{
	__asm __volatile("sti");
}

/*
 * This roundabout method of returning a u_char helps stop gcc-1.40 from
 * generating unnecessary movzbl's.
 */
#define	inb(port)	((u_char) u_int_inb(port))

static inline u_int
u_int_inb(u_int port)
{
	u_char	data;
	/*
	 * We use %%dx and not %1 here because i/o is done at %dx and not at
	 * %edx, while gcc-2.2.2 generates inferior code (movw instead of movl)
	 * if we tell it to load (u_short) port.
	 */
	__asm __volatile("inb %%dx,%0" : "=a" (data) : "d" (port));
	return data;
}

static inline void
outb(u_int port, u_char data)
{
	register u_char	al asm("ax");

	al = data;		/* help gcc-1.40's register allocator */
	__asm __volatile("outb %0,%%dx" : : "a" (al), "d" (port));
}

static inline void
tlbflush()
{
	__asm __volatile("movl %%cr3, %%eax; movl %%eax, %%cr3" : : : "ax");
}

#else /* not __GNUC__ */
extern	void insque __P((void *, void *));
extern	void remque __P((void *));

int	bdb		__P((void));
void	disable_intr	__P((void));
void	enable_intr	__P((void));
u_char	inb		__P((u_int port));
void	outb		__P((u_int port, u_int data));	/* XXX - incompat */

#endif	/* __GNUC__ */

void	load_cr0	__P((u_int cr0));
u_int	rcr0	__P((void));
void load_cr3(u_long);
u_long rcr3(void);
u_long rcr2(void);

void	setidt	__P((int, void (*)(), int, int));
extern u_long kvtop(void *);
extern void outw(int /*u_short*/, int /*u_short*/); /* XXX inline!*/
extern void outsb(int /*u_short*/, void *, size_t);
extern void outsw(int /*u_short*/, void *, size_t);
extern void insw(int /*u_short*/, void *, size_t);
extern void fillw(int /*u_short*/, void *, size_t);
extern void filli(int, void *, size_t);

#endif /* _MACHINE_CPUFUNC_H_ */
OpenPOWER on IntegriCloud