xref: /freebsd/sys/amd64/include/cpufunc.h (revision 5b81b6b301437eb9a6df491c829475bd29ae5d6c)
15b81b6b3SRodney W. Grimes /*
25b81b6b3SRodney W. Grimes  * Functions to provide access to special i386 instructions.
35b81b6b3SRodney W. Grimes  * XXX - bezillions more are defined in locore.s but are not declared anywhere.
45b81b6b3SRodney W. Grimes  */
55b81b6b3SRodney W. Grimes 
65b81b6b3SRodney W. Grimes #include <sys/cdefs.h>
75b81b6b3SRodney W. Grimes #include <sys/types.h>
85b81b6b3SRodney W. Grimes 
95b81b6b3SRodney W. Grimes #ifdef	__GNUC__
105b81b6b3SRodney W. Grimes 
115b81b6b3SRodney W. Grimes static __inline int bdb(void)
125b81b6b3SRodney W. Grimes {
135b81b6b3SRodney W. Grimes 	extern int bdb_exists;
145b81b6b3SRodney W. Grimes 
155b81b6b3SRodney W. Grimes 	if (!bdb_exists)
165b81b6b3SRodney W. Grimes 		return (0);
175b81b6b3SRodney W. Grimes 	__asm("int $3");
185b81b6b3SRodney W. Grimes 	return (1);
195b81b6b3SRodney W. Grimes }
205b81b6b3SRodney W. Grimes 
215b81b6b3SRodney W. Grimes static __inline void
225b81b6b3SRodney W. Grimes disable_intr(void)
235b81b6b3SRodney W. Grimes {
245b81b6b3SRodney W. Grimes 	__asm __volatile("cli");
255b81b6b3SRodney W. Grimes }
265b81b6b3SRodney W. Grimes 
275b81b6b3SRodney W. Grimes static __inline void
285b81b6b3SRodney W. Grimes enable_intr(void)
295b81b6b3SRodney W. Grimes {
305b81b6b3SRodney W. Grimes 	__asm __volatile("sti");
315b81b6b3SRodney W. Grimes }
325b81b6b3SRodney W. Grimes 
335b81b6b3SRodney W. Grimes /*
345b81b6b3SRodney W. Grimes  * This roundabout method of returning a u_char helps stop gcc-1.40 from
355b81b6b3SRodney W. Grimes  * generating unnecessary movzbl's.
365b81b6b3SRodney W. Grimes  */
375b81b6b3SRodney W. Grimes #define	inb(port)	((u_char) u_int_inb(port))
385b81b6b3SRodney W. Grimes 
395b81b6b3SRodney W. Grimes static __inline u_int
405b81b6b3SRodney W. Grimes u_int_inb(u_int port)
415b81b6b3SRodney W. Grimes {
425b81b6b3SRodney W. Grimes 	u_char	data;
435b81b6b3SRodney W. Grimes 	/*
445b81b6b3SRodney W. Grimes 	 * We use %%dx and not %1 here because i/o is done at %dx and not at
455b81b6b3SRodney W. Grimes 	 * %edx, while gcc-2.2.2 generates inferior code (movw instead of movl)
465b81b6b3SRodney W. Grimes 	 * if we tell it to load (u_short) port.
475b81b6b3SRodney W. Grimes 	 */
485b81b6b3SRodney W. Grimes 	__asm __volatile("inb %%dx,%0" : "=a" (data) : "d" (port));
495b81b6b3SRodney W. Grimes 	return data;
505b81b6b3SRodney W. Grimes }
515b81b6b3SRodney W. Grimes 
525b81b6b3SRodney W. Grimes static __inline void
535b81b6b3SRodney W. Grimes outb(u_int port, u_char data)
545b81b6b3SRodney W. Grimes {
555b81b6b3SRodney W. Grimes 	register u_char	al asm("ax");
565b81b6b3SRodney W. Grimes 
575b81b6b3SRodney W. Grimes 	al = data;		/* help gcc-1.40's register allocator */
585b81b6b3SRodney W. Grimes 	__asm __volatile("outb %0,%%dx" : : "a" (al), "d" (port));
595b81b6b3SRodney W. Grimes }
605b81b6b3SRodney W. Grimes 
615b81b6b3SRodney W. Grimes #else /* not __GNUC__ */
625b81b6b3SRodney W. Grimes 
635b81b6b3SRodney W. Grimes int	bdb		__P((void));
645b81b6b3SRodney W. Grimes void	disable_intr	__P((void));
655b81b6b3SRodney W. Grimes void	enable_intr	__P((void));
665b81b6b3SRodney W. Grimes u_char	inb		__P((u_int port));
675b81b6b3SRodney W. Grimes void	outb		__P((u_int port, u_int data));	/* XXX - incompat */
685b81b6b3SRodney W. Grimes 
695b81b6b3SRodney W. Grimes #endif	/* __GNUC__ */
705b81b6b3SRodney W. Grimes 
715b81b6b3SRodney W. Grimes #define	really_u_int	int	/* XXX */
725b81b6b3SRodney W. Grimes #define	really_void	int	/* XXX */
735b81b6b3SRodney W. Grimes 
745b81b6b3SRodney W. Grimes void	load_cr0	__P((u_int cr0));
755b81b6b3SRodney W. Grimes really_u_int	rcr0	__P((void));
765b81b6b3SRodney W. Grimes 
775b81b6b3SRodney W. Grimes #ifdef notyet
785b81b6b3SRodney W. Grimes really_void	setidt	__P((int idx, /*XXX*/caddr_t func, int typ, int dpl));
795b81b6b3SRodney W. Grimes #endif
805b81b6b3SRodney W. Grimes 
815b81b6b3SRodney W. Grimes #undef	really_u_int
825b81b6b3SRodney W. Grimes #undef	really_void
83