pio.h revision 1.16 1 /* $NetBSD: pio.h,v 1.16 2001/04/26 17:55:54 thorpej 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 _I386_PIO_H_
40 #define _I386_PIO_H_
41
42 /*
43 * Functions to provide access to i386 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 (__use_immediate_port(port) ? __inbc(port) : __inb(port))
65
66 static __inline u_int8_t
67 __inbc(int port)
68 {
69 u_int8_t data;
70 __asm __volatile("inb %1,%0" : "=a" (data) : "id" (port));
71 return data;
72 }
73
74 static __inline u_int8_t
75 __inb(int port)
76 {
77 u_int8_t data;
78 __asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
79 return data;
80 }
81
82 static __inline void
83 insb(int port, void *addr, int cnt)
84 {
85 void *dummy1;
86 int dummy2;
87 __asm __volatile("cld\n\trepne\n\tinsb" :
88 "=D" (dummy1), "=c" (dummy2) :
89 "d" (port), "0" (addr), "1" (cnt) :
90 "memory");
91 }
92
93 #define inw(port) \
94 (__use_immediate_port(port) ? __inwc(port) : __inw(port))
95
96 static __inline u_int16_t
97 __inwc(int port)
98 {
99 u_int16_t data;
100 __asm __volatile("inw %1,%0" : "=a" (data) : "id" (port));
101 return data;
102 }
103
104 static __inline u_int16_t
105 __inw(int port)
106 {
107 u_int16_t data;
108 __asm __volatile("inw %w1,%0" : "=a" (data) : "d" (port));
109 return data;
110 }
111
112 static __inline void
113 insw(int port, void *addr, int cnt)
114 {
115 void *dummy1;
116 int dummy2;
117 __asm __volatile("cld\n\trepne\n\tinsw" :
118 "=D" (dummy1), "=c" (dummy2) :
119 "d" (port), "0" (addr), "1" (cnt) :
120 "memory");
121 }
122
123 #define inl(port) \
124 (__use_immediate_port(port) ? __inlc(port) : __inl(port))
125
126 static __inline u_int32_t
127 __inlc(int port)
128 {
129 u_int32_t data;
130 __asm __volatile("inl %1,%0" : "=a" (data) : "id" (port));
131 return data;
132 }
133
134 static __inline u_int32_t
135 __inl(int port)
136 {
137 u_int32_t data;
138 __asm __volatile("inl %w1,%0" : "=a" (data) : "d" (port));
139 return data;
140 }
141
142 static __inline void
143 insl(int port, void *addr, int cnt)
144 {
145 void *dummy1;
146 int dummy2;
147 __asm __volatile("cld\n\trepne\n\tinsl" :
148 "=D" (dummy1), "=c" (dummy2) :
149 "d" (port), "0" (addr), "1" (cnt) :
150 "memory");
151 }
152
153 #define outb(port, data) \
154 (__use_immediate_port(port) ? __outbc(port, data) : __outb(port, data))
155
156 static __inline void
157 __outbc(int port, u_int8_t data)
158 {
159 __asm __volatile("outb %0,%1" : : "a" (data), "id" (port));
160 }
161
162 static __inline void
163 __outb(int port, u_int8_t data)
164 {
165 __asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
166 }
167
168 static __inline void
169 outsb(int port, const void *addr, int cnt)
170 {
171 void *dummy1;
172 int dummy2;
173 __asm __volatile("cld\n\trepne\n\toutsb" :
174 "=S" (dummy1), "=c" (dummy2) :
175 "d" (port), "0" (addr), "1" (cnt));
176 }
177
178 #define outw(port, data) \
179 (__use_immediate_port(port) ? __outwc(port, data) : __outw(port, data))
180
181 static __inline void
182 __outwc(int port, u_int16_t data)
183 {
184 __asm __volatile("outw %0,%1" : : "a" (data), "id" (port));
185 }
186
187 static __inline void
188 __outw(int port, u_int16_t data)
189 {
190 __asm __volatile("outw %0,%w1" : : "a" (data), "d" (port));
191 }
192
193 static __inline void
194 outsw(int port, const void *addr, int cnt)
195 {
196 void *dummy1;
197 int dummy2;
198 __asm __volatile("cld\n\trepne\n\toutsw" :
199 "=S" (dummy1), "=c" (dummy2) :
200 "d" (port), "0" (addr), "1" (cnt));
201 }
202
203 #define outl(port, data) \
204 (__use_immediate_port(port) ? __outlc(port, data) : __outl(port, data))
205
206 static __inline void
207 __outlc(int port, u_int32_t data)
208 {
209 __asm __volatile("outl %0,%1" : : "a" (data), "id" (port));
210 }
211
212 static __inline void
213 __outl(int port, u_int32_t data)
214 {
215 __asm __volatile("outl %0,%w1" : : "a" (data), "d" (port));
216 }
217
218 static __inline void
219 outsl(int port, const void *addr, int cnt)
220 {
221 void *dummy1;
222 int dummy2;
223 __asm __volatile("cld\n\trepne\n\toutsl" :
224 "=S" (dummy1), "=c" (dummy2) :
225 "d" (port), "0" (addr), "1" (cnt));
226 }
227
228 #endif /* _I386_PIO_H_ */
229