pio.h revision 1.1
11.1Sfvdl/*	$NetBSD: pio.h,v 1.1 2003/02/26 21:26:11 fvdl Exp $	*/
21.1Sfvdl
31.1Sfvdl/*-
41.1Sfvdl * Copyright (c) 1998 The NetBSD Foundation, Inc.
51.1Sfvdl * All rights reserved.
61.1Sfvdl *
71.1Sfvdl * This code is derived from software contributed to The NetBSD Foundation
81.1Sfvdl * by Charles M. Hannum.
91.1Sfvdl *
101.1Sfvdl * Redistribution and use in source and binary forms, with or without
111.1Sfvdl * modification, are permitted provided that the following conditions
121.1Sfvdl * are met:
131.1Sfvdl * 1. Redistributions of source code must retain the above copyright
141.1Sfvdl *    notice, this list of conditions and the following disclaimer.
151.1Sfvdl * 2. Redistributions in binary form must reproduce the above copyright
161.1Sfvdl *    notice, this list of conditions and the following disclaimer in the
171.1Sfvdl *    documentation and/or other materials provided with the distribution.
181.1Sfvdl * 3. All advertising materials mentioning features or use of this software
191.1Sfvdl *    must display the following acknowledgement:
201.1Sfvdl *        This product includes software developed by the NetBSD
211.1Sfvdl *        Foundation, Inc. and its contributors.
221.1Sfvdl * 4. Neither the name of The NetBSD Foundation nor the names of its
231.1Sfvdl *    contributors may be used to endorse or promote products derived
241.1Sfvdl *    from this software without specific prior written permission.
251.1Sfvdl *
261.1Sfvdl * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
271.1Sfvdl * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
281.1Sfvdl * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
291.1Sfvdl * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
301.1Sfvdl * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
311.1Sfvdl * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
321.1Sfvdl * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
331.1Sfvdl * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
341.1Sfvdl * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
351.1Sfvdl * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
361.1Sfvdl * POSSIBILITY OF SUCH DAMAGE.
371.1Sfvdl */
381.1Sfvdl
391.1Sfvdl#ifndef _X86_PIO_H_
401.1Sfvdl#define _X86_PIO_H_
411.1Sfvdl
421.1Sfvdl/*
431.1Sfvdl * Functions to provide access to x86 programmed I/O instructions.
441.1Sfvdl *
451.1Sfvdl * The in[bwl]() and out[bwl]() functions are split into two varieties: one to
461.1Sfvdl * use a small, constant, 8-bit port number, and another to use a large or
471.1Sfvdl * variable port number.  The former can be compiled as a smaller instruction.
481.1Sfvdl */
491.1Sfvdl
501.1Sfvdl
511.1Sfvdl#ifdef __OPTIMIZE__
521.1Sfvdl
531.1Sfvdl#define	__use_immediate_port(port) \
541.1Sfvdl	(__builtin_constant_p((port)) && (port) < 0x100)
551.1Sfvdl
561.1Sfvdl#else
571.1Sfvdl
581.1Sfvdl#define	__use_immediate_port(port)	0
591.1Sfvdl
601.1Sfvdl#endif
611.1Sfvdl
621.1Sfvdl
631.1Sfvdl#define	inb(port) \
641.1Sfvdl    (/* CONSTCOND */ __use_immediate_port(port) ? __inbc(port) : __inb(port))
651.1Sfvdl
661.1Sfvdlstatic __inline u_int8_t
671.1Sfvdl__inbc(int port)
681.1Sfvdl{
691.1Sfvdl	u_int8_t data;
701.1Sfvdl	__asm __volatile("inb %w1,%0" : "=a" (data) : "id" (port));
711.1Sfvdl	return data;
721.1Sfvdl}
731.1Sfvdl
741.1Sfvdlstatic __inline u_int8_t
751.1Sfvdl__inb(int port)
761.1Sfvdl{
771.1Sfvdl	u_int8_t data;
781.1Sfvdl	__asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
791.1Sfvdl	return data;
801.1Sfvdl}
811.1Sfvdl
821.1Sfvdlstatic __inline void
831.1Sfvdlinsb(int port, void *addr, int cnt)
841.1Sfvdl{
851.1Sfvdl	void *dummy1;
861.1Sfvdl	int dummy2;
871.1Sfvdl	__asm __volatile("cld\n\trepne\n\tinsb"			:
881.1Sfvdl			 "=D" (dummy1), "=c" (dummy2) 		:
891.1Sfvdl			 "d" (port), "0" (addr), "1" (cnt)	:
901.1Sfvdl			 "memory");
911.1Sfvdl}
921.1Sfvdl
931.1Sfvdl#define	inw(port) \
941.1Sfvdl    (/* CONSTCOND */ __use_immediate_port(port) ? __inwc(port) : __inw(port))
951.1Sfvdl
961.1Sfvdlstatic __inline u_int16_t
971.1Sfvdl__inwc(int port)
981.1Sfvdl{
991.1Sfvdl	u_int16_t data;
1001.1Sfvdl	__asm __volatile("inw %w1,%0" : "=a" (data) : "id" (port));
1011.1Sfvdl	return data;
1021.1Sfvdl}
1031.1Sfvdl
1041.1Sfvdlstatic __inline u_int16_t
1051.1Sfvdl__inw(int port)
1061.1Sfvdl{
1071.1Sfvdl	u_int16_t data;
1081.1Sfvdl	__asm __volatile("inw %w1,%0" : "=a" (data) : "d" (port));
1091.1Sfvdl	return data;
1101.1Sfvdl}
1111.1Sfvdl
1121.1Sfvdlstatic __inline void
1131.1Sfvdlinsw(int port, void *addr, int cnt)
1141.1Sfvdl{
1151.1Sfvdl	void *dummy1;
1161.1Sfvdl	int dummy2;
1171.1Sfvdl	__asm __volatile("cld\n\trepne\n\tinsw"			:
1181.1Sfvdl			 "=D" (dummy1), "=c" (dummy2)		:
1191.1Sfvdl			 "d" (port), "0" (addr), "1" (cnt)	:
1201.1Sfvdl			 "memory");
1211.1Sfvdl}
1221.1Sfvdl
1231.1Sfvdl#define	inl(port) \
1241.1Sfvdl    (/* CONSTCOND */ __use_immediate_port(port) ? __inlc(port) : __inl(port))
1251.1Sfvdl
1261.1Sfvdlstatic __inline u_int32_t
1271.1Sfvdl__inlc(int port)
1281.1Sfvdl{
1291.1Sfvdl	u_int32_t data;
1301.1Sfvdl	__asm __volatile("inl %w1,%0" : "=a" (data) : "id" (port));
1311.1Sfvdl	return data;
1321.1Sfvdl}
1331.1Sfvdl
1341.1Sfvdlstatic __inline u_int32_t
1351.1Sfvdl__inl(int port)
1361.1Sfvdl{
1371.1Sfvdl	u_int32_t data;
1381.1Sfvdl	__asm __volatile("inl %w1,%0" : "=a" (data) : "d" (port));
1391.1Sfvdl	return data;
1401.1Sfvdl}
1411.1Sfvdl
1421.1Sfvdlstatic __inline void
1431.1Sfvdlinsl(int port, void *addr, int cnt)
1441.1Sfvdl{
1451.1Sfvdl	void *dummy1;
1461.1Sfvdl	int dummy2;
1471.1Sfvdl	__asm __volatile("cld\n\trepne\n\tinsl"			:
1481.1Sfvdl			 "=D" (dummy1), "=c" (dummy2)		:
1491.1Sfvdl			 "d" (port), "0" (addr), "1" (cnt)	:
1501.1Sfvdl			 "memory");
1511.1Sfvdl}
1521.1Sfvdl
1531.1Sfvdl#define	outb(port, data) \
1541.1Sfvdl    (/* CONSTCOND */__use_immediate_port(port) ? __outbc(port, data) : __outb(port, data))
1551.1Sfvdl
1561.1Sfvdlstatic __inline void
1571.1Sfvdl__outbc(int port, u_int8_t data)
1581.1Sfvdl{
1591.1Sfvdl	__asm __volatile("outb %0,%w1" : : "a" (data), "id" (port));
1601.1Sfvdl}
1611.1Sfvdl
1621.1Sfvdlstatic __inline void
1631.1Sfvdl__outb(int port, u_int8_t data)
1641.1Sfvdl{
1651.1Sfvdl	__asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
1661.1Sfvdl}
1671.1Sfvdl
1681.1Sfvdlstatic __inline void
1691.1Sfvdloutsb(int port, void *addr, int cnt)
1701.1Sfvdl{
1711.1Sfvdl	void *dummy1;
1721.1Sfvdl	int dummy2;
1731.1Sfvdl	__asm __volatile("cld\n\trepne\n\toutsb"		:
1741.1Sfvdl			 "=S" (dummy1), "=c" (dummy2)		:
1751.1Sfvdl			 "d" (port), "0" (addr), "1" (cnt));
1761.1Sfvdl}
1771.1Sfvdl
1781.1Sfvdl#define	outw(port, data) \
1791.1Sfvdl    (/* CONSTCOND */ __use_immediate_port(port) ? __outwc(port, data) : __outw(port, data))
1801.1Sfvdl
1811.1Sfvdlstatic __inline void
1821.1Sfvdl__outwc(int port, u_int16_t data)
1831.1Sfvdl{
1841.1Sfvdl	__asm __volatile("outw %0,%w1" : : "a" (data), "id" (port));
1851.1Sfvdl}
1861.1Sfvdl
1871.1Sfvdlstatic __inline void
1881.1Sfvdl__outw(int port, u_int16_t data)
1891.1Sfvdl{
1901.1Sfvdl	__asm __volatile("outw %0,%w1" : : "a" (data), "d" (port));
1911.1Sfvdl}
1921.1Sfvdl
1931.1Sfvdlstatic __inline void
1941.1Sfvdloutsw(int port, void *addr, int cnt)
1951.1Sfvdl{
1961.1Sfvdl	void *dummy1;
1971.1Sfvdl	int dummy2;
1981.1Sfvdl	__asm __volatile("cld\n\trepne\n\toutsw"		:
1991.1Sfvdl			 "=S" (dummy1), "=c" (dummy2)		:
2001.1Sfvdl			 "d" (port), "0" (addr), "1" (cnt));
2011.1Sfvdl}
2021.1Sfvdl
2031.1Sfvdl#define	outl(port, data) \
2041.1Sfvdl    (/* CONSTCOND */ __use_immediate_port(port) ? __outlc(port, data) : __outl(port, data))
2051.1Sfvdl
2061.1Sfvdlstatic __inline void
2071.1Sfvdl__outlc(int port, u_int32_t data)
2081.1Sfvdl{
2091.1Sfvdl	__asm __volatile("outl %0,%w1" : : "a" (data), "id" (port));
2101.1Sfvdl}
2111.1Sfvdl
2121.1Sfvdlstatic __inline void
2131.1Sfvdl__outl(int port, u_int32_t data)
2141.1Sfvdl{
2151.1Sfvdl	__asm __volatile("outl %0,%w1" : : "a" (data), "d" (port));
2161.1Sfvdl}
2171.1Sfvdl
2181.1Sfvdlstatic __inline void
2191.1Sfvdloutsl(int port, void *addr, int cnt)
2201.1Sfvdl{
2211.1Sfvdl	void *dummy1;
2221.1Sfvdl	int dummy2;
2231.1Sfvdl	__asm __volatile("cld\n\trepne\n\toutsl"		:
2241.1Sfvdl			 "=S" (dummy1), "=c" (dummy2)		:
2251.1Sfvdl			 "d" (port), "0" (addr), "1" (cnt));
2261.1Sfvdl}
2271.1Sfvdl
2281.1Sfvdl#endif /* _X86_PIO_H_ */
229