1 /*****************************************************************************/
2 /**
3 * \file
4 * \brief x86 port I/O
5 *
6 * \date 06/2003
7 * \author Frank Mehnert <fm3@os.inf.tu-dresden.de>
8 */
9 /*****************************************************************************/
10
11 /*
12 * (c) 2003-2009 Author(s)
13 * economic rights: Technische Universität Dresden (Germany)
14 * This file is part of TUD:OS and distributed under the terms of the
15 * GNU Lesser General Public License 2.1.
16 * Please see the COPYING-LGPL-2.1 file for details.
17 */
18
19 #ifndef _L4UTIL_PORT_IO_H
20 #define _L4UTIL_PORT_IO_H
21
22 /**
23 * \defgroup l4util_portio IA32 Port I/O API
24 * \ingroup l4util_api
25 */
26
27 /* L4 includes */
28 #include <l4/sys/l4int.h>
29 #include <l4/sys/compiler.h>
30
31 /*****************************************************************************
32 *** Prototypes
33 *****************************************************************************/
34
35 EXTERN_C_BEGIN
36 /**
37 * \addtogroup l4util_portio
38 */
39 /*@{*/
40 /**
41 * \brief Read byte from I/O port
42 *
43 * \param port I/O port address
44 * \return value
45 */
46 L4_INLINE l4_uint8_t
47 l4util_in8(l4_uint16_t port);
48
49 /**
50 * \brief Read 16-bit-value from I/O port
51 *
52 * \param port I/O port address
53 * \return value
54 */
55 L4_INLINE l4_uint16_t
56 l4util_in16(l4_uint16_t port);
57
58 /**
59 * \brief Read 32-bit-value from I/O port
60 *
61 * \param port I/O port address
62 * \return value
63 */
64 L4_INLINE l4_uint32_t
65 l4util_in32(l4_uint16_t port);
66
67 /**
68 * \brief Read a block of 8-bit-values from I/O ports
69 *
70 * \param port I/O port address
71 * \param addr address of buffer
72 * \param count number of I/O operations
73 */
74 L4_INLINE void
75 l4util_ins8(l4_uint16_t port, l4_umword_t addr, l4_umword_t count);
76
77 /**
78 * \brief Read a block of 16-bit-values from I/O ports
79 *
80 * \param port I/O port address
81 * \param addr address of buffer
82 * \param count number of I/O operations
83 */
84 L4_INLINE void
85 l4util_ins16(l4_uint16_t port, l4_umword_t addr, l4_umword_t count);
86
87 /**
88 * \brief Read a block of 32-bit-values from I/O ports
89 *
90 * \param port I/O port address
91 * \param addr address of buffer
92 * \param count number of I/O operations
93 */
94 L4_INLINE void
95 l4util_ins32(l4_uint16_t port, l4_umword_t addr, l4_umword_t count);
96
97 /**
98 * \brief Write byte to I/O port
99 *
100 * \param port I/O port address
101 * \param value value to write
102 */
103 L4_INLINE void
104 l4util_out8(l4_uint8_t value, l4_uint16_t port);
105
106 /**
107 * \brief Write 16-bit-value to I/O port
108 * \ingroup port_io
109 *
110 * \param port I/O port address
111 * \param value value to write
112 */
113 L4_INLINE void
114 l4util_out16(l4_uint16_t value, l4_uint16_t port);
115
116 /**
117 * \brief Write 32-bit-value to I/O port
118 *
119 * \param port I/O port address
120 * \param value value to write
121 */
122 L4_INLINE void
123 l4util_out32(l4_uint32_t value, l4_uint16_t port);
124
125 /**
126 * \brief Write a block of bytes to I/O port
127 *
128 * \param port I/O port address
129 * \param addr address of buffer
130 * \param count number of I/O operations
131 */
132 L4_INLINE void
133 l4util_outs8(l4_uint16_t port, l4_umword_t addr, l4_umword_t count);
134
135 /**
136 * \brief Write a block of 16-bit-values to I/O port
137 * \ingroup port_io
138 *
139 * \param port I/O port address
140 * \param addr address of buffer
141 * \param count number of I/O operations
142 */
143 L4_INLINE void
144 l4util_outs16(l4_uint16_t port, l4_umword_t addr, l4_umword_t count);
145
146 /**
147 * \brief Write block of 32-bit-values to I/O port
148 *
149 * \param port I/O port address
150 * \param addr address of buffer
151 * \param count number of I/O operations
152 */
153 L4_INLINE void
154 l4util_outs32(l4_uint16_t port, l4_umword_t addr, l4_umword_t count);
155
156 /**
157 * \brief delay I/O port access by writing to port 0x80
158 */
159 L4_INLINE void
160 l4util_iodelay(void);
161
162 /*@}*/
163
164 EXTERN_C_END
165
166
167 /*****************************************************************************
168 *** Implementation
169 *****************************************************************************/
170
171 L4_INLINE l4_uint8_t
l4util_in8(l4_uint16_t port)172 l4util_in8(l4_uint16_t port)
173 {
174 l4_uint8_t value;
175 asm volatile ("inb %w1, %b0" : "=a" (value) : "Nd" (port));
176 return value;
177 }
178
179 L4_INLINE l4_uint16_t
l4util_in16(l4_uint16_t port)180 l4util_in16(l4_uint16_t port)
181 {
182 l4_uint16_t value;
183 asm volatile ("inw %w1, %w0" : "=a" (value) : "Nd" (port));
184 return value;
185 }
186
187 L4_INLINE l4_uint32_t
l4util_in32(l4_uint16_t port)188 l4util_in32(l4_uint16_t port)
189 {
190 l4_uint32_t value;
191 asm volatile ("inl %w1, %0" : "=a" (value) : "Nd" (port));
192 return value;
193 }
194
195 L4_INLINE void
l4util_ins8(l4_uint16_t port,l4_umword_t addr,l4_umword_t count)196 l4util_ins8(l4_uint16_t port, l4_umword_t addr, l4_umword_t count)
197 {
198 l4_umword_t dummy1, dummy2;
199 asm volatile ("rep insb" : "=D"(dummy1), "=c"(dummy2)
200 : "d" (port), "D" (addr), "c"(count)
201 : "memory");
202 }
203
204 L4_INLINE void
l4util_ins16(l4_uint16_t port,l4_umword_t addr,l4_umword_t count)205 l4util_ins16(l4_uint16_t port, l4_umword_t addr, l4_umword_t count)
206 {
207 l4_umword_t dummy1, dummy2;
208 asm volatile ("rep insw" : "=D"(dummy1), "=c"(dummy2)
209 : "d" (port), "D" (addr), "c"(count)
210 : "memory");
211 }
212
213 L4_INLINE void
l4util_ins32(l4_uint16_t port,l4_umword_t addr,l4_umword_t count)214 l4util_ins32(l4_uint16_t port, l4_umword_t addr, l4_umword_t count)
215 {
216 l4_umword_t dummy1, dummy2;
217 asm volatile ("rep insl" : "=D"(dummy1), "=c"(dummy2)
218 : "d" (port), "D" (addr), "c"(count)
219 : "memory");
220 }
221
222 L4_INLINE void
l4util_out8(l4_uint8_t value,l4_uint16_t port)223 l4util_out8(l4_uint8_t value, l4_uint16_t port)
224 {
225 asm volatile ("outb %b0, %w1" : : "a" (value), "Nd" (port));
226 }
227
228 L4_INLINE void
l4util_out16(l4_uint16_t value,l4_uint16_t port)229 l4util_out16(l4_uint16_t value, l4_uint16_t port)
230 {
231 asm volatile ("outw %w0, %w1" : : "a" (value), "Nd" (port));
232 }
233
234 L4_INLINE void
l4util_out32(l4_uint32_t value,l4_uint16_t port)235 l4util_out32(l4_uint32_t value, l4_uint16_t port)
236 {
237 asm volatile ("outl %0, %w1" : : "a" (value), "Nd" (port));
238 }
239
240 L4_INLINE void
l4util_outs8(l4_uint16_t port,l4_umword_t addr,l4_umword_t count)241 l4util_outs8(l4_uint16_t port, l4_umword_t addr, l4_umword_t count)
242 {
243 l4_umword_t dummy1, dummy2;
244 asm volatile ("rep outsb" : "=S"(dummy1), "=c"(dummy2)
245 : "d" (port), "S" (addr), "c"(count)
246 : "memory");
247 }
248
249 L4_INLINE void
l4util_outs16(l4_uint16_t port,l4_umword_t addr,l4_umword_t count)250 l4util_outs16(l4_uint16_t port, l4_umword_t addr, l4_umword_t count)
251 {
252 l4_umword_t dummy1, dummy2;
253 asm volatile ("rep outsw" : "=S"(dummy1), "=c"(dummy2)
254 : "d" (port), "S" (addr), "c"(count)
255 : "memory");
256 }
257
258 L4_INLINE void
l4util_outs32(l4_uint16_t port,l4_umword_t addr,l4_umword_t count)259 l4util_outs32(l4_uint16_t port, l4_umword_t addr, l4_umword_t count)
260 {
261 l4_umword_t dummy1, dummy2;
262 asm volatile ("rep outsl" : "=S"(dummy1), "=c"(dummy2)
263 : "d" (port), "S" (addr), "c"(count)
264 : "memory");
265 }
266
267 L4_INLINE void
l4util_iodelay(void)268 l4util_iodelay(void)
269 {
270 asm volatile ("outb %al,$0x80");
271 }
272
273 #endif
274