pio.h revision 1.5
1/*	$NetBSD: pio.h,v 1.5 2006/02/16 20:17:15 perry Exp $	*/
2
3/*-
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 *    must display the following acknowledgement:
20 *        This product includes software developed by the NetBSD
21 *        Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 *    contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39#ifndef _X86_PIO_H_
40#define _X86_PIO_H_
41
42/*
43 * Functions to provide access to x86 programmed I/O instructions.
44 *
45 * The in[bwl]() and out[bwl]() functions are split into two varieties: one to
46 * use a small, constant, 8-bit port number, and another to use a large or
47 * variable port number.  The former can be compiled as a smaller instruction.
48 */
49
50
51#ifdef __OPTIMIZE__
52
53#define	__use_immediate_port(port) \
54	(__builtin_constant_p((port)) && (port) < 0x100)
55
56#else
57
58#define	__use_immediate_port(port)	0
59
60#endif
61
62
63#define	inb(port) \
64    (/* CONSTCOND */ __use_immediate_port(port) ? __inbc(port) : __inb(port))
65
66static __inline u_int8_t
67__inbc(unsigned port)
68{
69	u_int8_t data;
70	__asm volatile("inb %w1,%0" : "=a" (data) : "id" (port));
71	return data;
72}
73
74static __inline u_int8_t
75__inb(unsigned port)
76{
77	u_int8_t data;
78	__asm volatile("inb %w1,%0" : "=a" (data) : "d" (port));
79	return data;
80}
81
82static __inline void
83insb(unsigned port, void *addr, int cnt)
84{
85	void *dummy1;
86	int dummy2;
87	__asm volatile("cld\n\trep\n\tinsb"			:
88			 "=D" (dummy1), "=c" (dummy2) 		:
89			 "d" (port), "0" (addr), "1" (cnt)	:
90			 "memory");
91}
92
93#define	inw(port) \
94    (/* CONSTCOND */ __use_immediate_port(port) ? __inwc(port) : __inw(port))
95
96static __inline u_int16_t
97__inwc(unsigned port)
98{
99	u_int16_t data;
100	__asm volatile("inw %w1,%0" : "=a" (data) : "id" (port));
101	return data;
102}
103
104static __inline u_int16_t
105__inw(unsigned port)
106{
107	u_int16_t data;
108	__asm volatile("inw %w1,%0" : "=a" (data) : "d" (port));
109	return data;
110}
111
112static __inline void
113insw(unsigned port, void *addr, int cnt)
114{
115	void *dummy1;
116	int dummy2;
117	__asm volatile("cld\n\trep\n\tinsw"			:
118			 "=D" (dummy1), "=c" (dummy2)		:
119			 "d" (port), "0" (addr), "1" (cnt)	:
120			 "memory");
121}
122
123#define	inl(port) \
124    (/* CONSTCOND */ __use_immediate_port(port) ? __inlc(port) : __inl(port))
125
126static __inline u_int32_t
127__inlc(unsigned port)
128{
129	u_int32_t data;
130	__asm volatile("inl %w1,%0" : "=a" (data) : "id" (port));
131	return data;
132}
133
134static __inline u_int32_t
135__inl(unsigned port)
136{
137	u_int32_t data;
138	__asm volatile("inl %w1,%0" : "=a" (data) : "d" (port));
139	return data;
140}
141
142static __inline void
143insl(unsigned port, void *addr, int cnt)
144{
145	void *dummy1;
146	int dummy2;
147	__asm volatile("cld\n\trep\n\tinsl"			:
148			 "=D" (dummy1), "=c" (dummy2)		:
149			 "d" (port), "0" (addr), "1" (cnt)	:
150			 "memory");
151}
152
153#define	outb(port, data) \
154    (/* CONSTCOND */__use_immediate_port(port) ? __outbc(port, data) : \
155						__outb(port, data))
156
157static __inline void
158__outbc(unsigned port, u_int8_t data)
159{
160	__asm volatile("outb %0,%w1" : : "a" (data), "id" (port));
161}
162
163static __inline void
164__outb(unsigned port, u_int8_t data)
165{
166	__asm volatile("outb %0,%w1" : : "a" (data), "d" (port));
167}
168
169static __inline void
170outsb(unsigned port, const void *addr, int cnt)
171{
172	void *dummy1;
173	int dummy2;
174	__asm volatile("cld\n\trep\n\toutsb"		:
175			 "=S" (dummy1), "=c" (dummy2)		:
176			 "d" (port), "0" (addr), "1" (cnt));
177}
178
179#define	outw(port, data) \
180    (/* CONSTCOND */ __use_immediate_port(port) ? __outwc(port, data) : \
181						__outw(port, data))
182
183static __inline void
184__outwc(unsigned port, u_int16_t data)
185{
186	__asm volatile("outw %0,%w1" : : "a" (data), "id" (port));
187}
188
189static __inline void
190__outw(unsigned port, u_int16_t data)
191{
192	__asm volatile("outw %0,%w1" : : "a" (data), "d" (port));
193}
194
195static __inline void
196outsw(unsigned port, const void *addr, int cnt)
197{
198	void *dummy1;
199	int dummy2;
200	__asm volatile("cld\n\trep\n\toutsw"		:
201			 "=S" (dummy1), "=c" (dummy2)		:
202			 "d" (port), "0" (addr), "1" (cnt));
203}
204
205#define	outl(port, data) \
206    (/* CONSTCOND */ __use_immediate_port(port) ? __outlc(port, data) : \
207						__outl(port, data))
208
209static __inline void
210__outlc(unsigned port, u_int32_t data)
211{
212	__asm volatile("outl %0,%w1" : : "a" (data), "id" (port));
213}
214
215static __inline void
216__outl(unsigned port, u_int32_t data)
217{
218	__asm volatile("outl %0,%w1" : : "a" (data), "d" (port));
219}
220
221static __inline void
222outsl(unsigned port, const void *addr, int cnt)
223{
224	void *dummy1;
225	int dummy2;
226	__asm volatile("cld\n\trep\n\toutsl"		:
227			 "=S" (dummy1), "=c" (dummy2)		:
228			 "d" (port), "0" (addr), "1" (cnt));
229}
230
231#endif /* _X86_PIO_H_ */
232