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