pio.h revision 1.15.8.1 1 /* $NetBSD: pio.h,v 1.15.8.1 2001/06/21 19:25:53 nathanw 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 (/* CONSTCOND */ __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 (/* CONSTCOND */ __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 (/* CONSTCOND */ __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 (/* CONSTCOND */ __use_immediate_port(port) ? __outbc(port, data) : \
155 __outb(port, data))
156
157 static __inline void
158 __outbc(int port, u_int8_t data)
159 {
160 __asm __volatile("outb %0,%1" : : "a" (data), "id" (port));
161 }
162
163 static __inline void
164 __outb(int port, u_int8_t data)
165 {
166 __asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
167 }
168
169 static __inline void
170 outsb(int port, const void *addr, int cnt)
171 {
172 void *dummy1;
173 int dummy2;
174 __asm __volatile("cld\n\trepne\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
183 static __inline void
184 __outwc(int port, u_int16_t data)
185 {
186 __asm __volatile("outw %0,%1" : : "a" (data), "id" (port));
187 }
188
189 static __inline void
190 __outw(int port, u_int16_t data)
191 {
192 __asm __volatile("outw %0,%w1" : : "a" (data), "d" (port));
193 }
194
195 static __inline void
196 outsw(int port, const void *addr, int cnt)
197 {
198 void *dummy1;
199 int dummy2;
200 __asm __volatile("cld\n\trepne\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
209 static __inline void
210 __outlc(int port, u_int32_t data)
211 {
212 __asm __volatile("outl %0,%1" : : "a" (data), "id" (port));
213 }
214
215 static __inline void
216 __outl(int port, u_int32_t data)
217 {
218 __asm __volatile("outl %0,%w1" : : "a" (data), "d" (port));
219 }
220
221 static __inline void
222 outsl(int port, const void *addr, int cnt)
223 {
224 void *dummy1;
225 int dummy2;
226 __asm __volatile("cld\n\trepne\n\toutsl" :
227 "=S" (dummy1), "=c" (dummy2) :
228 "d" (port), "0" (addr), "1" (cnt));
229 }
230
231 #endif /* _I386_PIO_H_ */
232