1 #ifndef _GPXE_IO_H
2 #define _GPXE_IO_H
3
4 /** @file
5 *
6 * gPXE I/O API
7 *
8 * The I/O API provides methods for reading from and writing to
9 * memory-mapped and I/O-mapped devices.
10 *
11 * The standard methods (readl()/writel() etc.) do not strictly check
12 * the type of the address parameter; this is because traditional
13 * usage does not necessarily provide the correct pointer type. For
14 * example, code written for ISA devices at fixed I/O addresses (such
15 * as the keyboard controller) tend to use plain integer constants for
16 * the address parameter.
17 */
18
19 FILE_LICENCE ( GPL2_OR_LATER );
20
21 #include <stdint.h>
22 #include <gpxe/api.h>
23 #include <config/ioapi.h>
24 #include <gpxe/uaccess.h>
25
26 /**
27 * Calculate static inline I/O API function name
28 *
29 * @v _prefix Subsystem prefix
30 * @v _api_func API function
31 * @ret _subsys_func Subsystem API function
32 */
33 #define IOAPI_INLINE( _subsys, _api_func ) \
34 SINGLE_API_INLINE ( IOAPI_PREFIX_ ## _subsys, _api_func )
35
36 /**
37 * Provide an I/O API implementation
38 *
39 * @v _prefix Subsystem prefix
40 * @v _api_func API function
41 * @v _func Implementing function
42 */
43 #define PROVIDE_IOAPI( _subsys, _api_func, _func ) \
44 PROVIDE_SINGLE_API ( IOAPI_PREFIX_ ## _subsys, _api_func, _func )
45
46 /**
47 * Provide a static inline I/O API implementation
48 *
49 * @v _prefix Subsystem prefix
50 * @v _api_func API function
51 */
52 #define PROVIDE_IOAPI_INLINE( _subsys, _api_func ) \
53 PROVIDE_SINGLE_API_INLINE ( IOAPI_PREFIX_ ## _subsys, _api_func )
54
55 /* Include all architecture-independent I/O API headers */
56 #include <gpxe/efi/efi_io.h>
57
58 /* Include all architecture-dependent I/O API headers */
59 #include <bits/io.h>
60
61 /**
62 * Wrap an I/O read
63 *
64 * @v _func I/O API function
65 * @v _type Data type
66 * @v io_addr I/O address
67 * @v _prefix Prefix for address in debug message
68 * @v _ndigits Number of hex digits for this data type
69 */
70 #define IOAPI_READ( _func, _type, io_addr, _prefix, _ndigits ) ( { \
71 volatile _type *_io_addr = \
72 ( ( volatile _type * ) ( intptr_t ) (io_addr) ); \
73 _type _data = _func ( _io_addr ); \
74 DBGIO ( "[" _prefix " %08lx] => %0" #_ndigits "llx\n", \
75 io_to_bus ( _io_addr ), ( unsigned long long ) _data ); \
76 _data; } )
77
78 /**
79 * Wrap an I/O write
80 *
81 * @v _func I/O API function
82 * @v _type Data type
83 * @v data Value to write
84 * @v io_addr I/O address
85 * @v _prefix Prefix for address in debug message
86 * @v _ndigits Number of hex digits for this data type
87 */
88 #define IOAPI_WRITE( _func, _type, data, io_addr, _prefix, _ndigits ) do { \
89 volatile _type *_io_addr = \
90 ( ( volatile _type * ) ( intptr_t ) (io_addr) ); \
91 _type _data = (data); \
92 DBGIO ( "[" _prefix " %08lx] <= %0" #_ndigits "llx\n", \
93 io_to_bus ( _io_addr ), ( unsigned long long ) _data ); \
94 _func ( _data, _io_addr ); \
95 } while ( 0 )
96
97 /**
98 * Wrap an I/O string read
99 *
100 * @v _func I/O API function
101 * @v _type Data type
102 * @v io_addr I/O address
103 * @v data Data buffer
104 * @v count Number of elements to read
105 * @v _prefix Prefix for address in debug message
106 * @v _ndigits Number of hex digits for this data type
107 */
108 #define IOAPI_READS( _func, _type, io_addr, data, count, _prefix, _ndigits ) \
109 do { \
110 volatile _type *_io_addr = \
111 ( ( volatile _type * ) ( intptr_t ) (io_addr) ); \
112 void *_data_void = (data); /* Check data is a pointer */ \
113 _type * _data = ( ( _type * ) _data_void ); \
114 const _type * _dbg_data = _data; \
115 unsigned int _count = (count); \
116 unsigned int _dbg_count = _count; \
117 _func ( _io_addr, _data, _count ); \
118 DBGIO ( "[" _prefix " %08lx] =>", io_to_bus ( _io_addr ) ); \
119 while ( _dbg_count-- ) { \
120 DBGIO ( " %0" #_ndigits "llx", \
121 ( ( unsigned long long ) *(_dbg_data++) ) ); \
122 } \
123 DBGIO ( "\n" ); \
124 } while ( 0 )
125
126 /**
127 * Wrap an I/O string write
128 *
129 * @v _func I/O API function
130 * @v _type Data type
131 * @v io_addr I/O address
132 * @v data Data buffer
133 * @v count Number of elements to write
134 * @v _prefix Prefix for address in debug message
135 * @v _ndigits Number of hex digits for this data type
136 */
137 #define IOAPI_WRITES( _func, _type, io_addr, data, count, _prefix, _ndigits ) \
138 do { \
139 volatile _type *_io_addr = \
140 ( ( volatile _type * ) ( intptr_t ) (io_addr) ); \
141 const void *_data_void = (data); /* Check data is a pointer */ \
142 const _type * _data = ( ( const _type * ) _data_void ); \
143 const _type * _dbg_data = _data; \
144 unsigned int _count = (count); \
145 unsigned int _dbg_count = _count; \
146 DBGIO ( "[" _prefix " %08lx] <=", io_to_bus ( _io_addr ) ); \
147 while ( _dbg_count-- ) { \
148 DBGIO ( " %0" #_ndigits "llx", \
149 ( ( unsigned long long ) *(_dbg_data++) ) ); \
150 } \
151 DBGIO ( "\n" ); \
152 _func ( _io_addr, _data, _count ); \
153 } while ( 0 )
154
155 /**
156 * Convert physical address to a bus address
157 *
158 * @v phys_addr Physical address
159 * @ret bus_addr Bus address
160 */
161 unsigned long phys_to_bus ( unsigned long phys_addr );
162
163 /**
164 * Convert bus address to a physical address
165 *
166 * @v bus_addr Bus address
167 * @ret phys_addr Physical address
168 */
169 unsigned long bus_to_phys ( unsigned long bus_addr );
170
171 /**
172 * Convert virtual address to a bus address
173 *
174 * @v addr Virtual address
175 * @ret bus_addr Bus address
176 */
177 static inline __always_inline unsigned long
virt_to_bus(volatile const void * addr)178 virt_to_bus ( volatile const void *addr ) {
179 return phys_to_bus ( virt_to_phys ( addr ) );
180 }
181
182 /**
183 * Convert bus address to a virtual address
184 *
185 * @v bus_addr Bus address
186 * @ret addr Virtual address
187 *
188 * This operation is not available under all memory models.
189 */
bus_to_virt(unsigned long bus_addr)190 static inline __always_inline void * bus_to_virt ( unsigned long bus_addr ) {
191 return phys_to_virt ( bus_to_phys ( bus_addr ) );
192 }
193
194 /**
195 * Map bus address as an I/O address
196 *
197 * @v bus_addr Bus address
198 * @v len Length of region
199 * @ret io_addr I/O address
200 */
201 void * ioremap ( unsigned long bus_addr, size_t len );
202
203 /**
204 * Unmap I/O address
205 *
206 * @v io_addr I/O address
207 */
208 void iounmap ( volatile const void *io_addr );
209
210 /**
211 * Convert I/O address to bus address (for debug only)
212 *
213 * @v io_addr I/O address
214 * @ret bus_addr Bus address
215 */
216 unsigned long io_to_bus ( volatile const void *io_addr );
217
218 /**
219 * Read byte from memory-mapped device
220 *
221 * @v io_addr I/O address
222 * @ret data Value read
223 */
224 uint8_t readb ( volatile uint8_t *io_addr );
225 #define readb( io_addr ) IOAPI_READ ( readb, uint8_t, io_addr, "MEM", 2 )
226
227 /**
228 * Read 16-bit word from memory-mapped device
229 *
230 * @v io_addr I/O address
231 * @ret data Value read
232 */
233 uint16_t readw ( volatile uint16_t *io_addr );
234 #define readw( io_addr ) IOAPI_READ ( readw, uint16_t, io_addr, "MEM", 4 )
235
236 /**
237 * Read 32-bit dword from memory-mapped device
238 *
239 * @v io_addr I/O address
240 * @ret data Value read
241 */
242 uint32_t readl ( volatile uint32_t *io_addr );
243 #define readl( io_addr ) IOAPI_READ ( readl, uint32_t, io_addr, "MEM", 8 )
244
245 /**
246 * Read 64-bit qword from memory-mapped device
247 *
248 * @v io_addr I/O address
249 * @ret data Value read
250 */
251 uint64_t readq ( volatile uint64_t *io_addr );
252 #define readq( io_addr ) IOAPI_READ ( readq, uint64_t, io_addr, "MEM", 16 )
253
254 /**
255 * Write byte to memory-mapped device
256 *
257 * @v data Value to write
258 * @v io_addr I/O address
259 */
260 void writeb ( uint8_t data, volatile uint8_t *io_addr );
261 #define writeb( data, io_addr ) \
262 IOAPI_WRITE ( writeb, uint8_t, data, io_addr, "MEM", 2 )
263
264 /**
265 * Write 16-bit word to memory-mapped device
266 *
267 * @v data Value to write
268 * @v io_addr I/O address
269 */
270 void writew ( uint16_t data, volatile uint16_t *io_addr );
271 #define writew( data, io_addr ) \
272 IOAPI_WRITE ( writew, uint16_t, data, io_addr, "MEM", 4 )
273
274 /**
275 * Write 32-bit dword to memory-mapped device
276 *
277 * @v data Value to write
278 * @v io_addr I/O address
279 */
280 void writel ( uint32_t data, volatile uint32_t *io_addr );
281 #define writel( data, io_addr ) \
282 IOAPI_WRITE ( writel, uint32_t, data, io_addr, "MEM", 8 )
283
284 /**
285 * Write 64-bit qword to memory-mapped device
286 *
287 * @v data Value to write
288 * @v io_addr I/O address
289 */
290 void writeq ( uint64_t data, volatile uint64_t *io_addr );
291 #define writeq( data, io_addr ) \
292 IOAPI_WRITE ( writeq, uint64_t, data, io_addr, "MEM", 16 )
293
294 /**
295 * Read byte from I/O-mapped device
296 *
297 * @v io_addr I/O address
298 * @ret data Value read
299 */
300 uint8_t inb ( volatile uint8_t *io_addr );
301 #define inb( io_addr ) IOAPI_READ ( inb, uint8_t, io_addr, "IO", 2 )
302
303 /**
304 * Read 16-bit word from I/O-mapped device
305 *
306 * @v io_addr I/O address
307 * @ret data Value read
308 */
309 uint16_t inw ( volatile uint16_t *io_addr );
310 #define inw( io_addr ) IOAPI_READ ( inw, uint16_t, io_addr, "IO", 4 )
311
312 /**
313 * Read 32-bit dword from I/O-mapped device
314 *
315 * @v io_addr I/O address
316 * @ret data Value read
317 */
318 uint32_t inl ( volatile uint32_t *io_addr );
319 #define inl( io_addr ) IOAPI_READ ( inl, uint32_t, io_addr, "IO", 8 )
320
321 /**
322 * Write byte to I/O-mapped device
323 *
324 * @v data Value to write
325 * @v io_addr I/O address
326 */
327 void outb ( uint8_t data, volatile uint8_t *io_addr );
328 #define outb( data, io_addr ) \
329 IOAPI_WRITE ( outb, uint8_t, data, io_addr, "IO", 2 )
330
331 /**
332 * Write 16-bit word to I/O-mapped device
333 *
334 * @v data Value to write
335 * @v io_addr I/O address
336 */
337 void outw ( uint16_t data, volatile uint16_t *io_addr );
338 #define outw( data, io_addr ) \
339 IOAPI_WRITE ( outw, uint16_t, data, io_addr, "IO", 4 )
340
341 /**
342 * Write 32-bit dword to I/O-mapped device
343 *
344 * @v data Value to write
345 * @v io_addr I/O address
346 */
347 void outl ( uint32_t data, volatile uint32_t *io_addr );
348 #define outl( data, io_addr ) \
349 IOAPI_WRITE ( outl, uint32_t, data, io_addr, "IO", 8 )
350
351 /**
352 * Read bytes from I/O-mapped device
353 *
354 * @v io_addr I/O address
355 * @v data Data buffer
356 * @v count Number of bytes to read
357 */
358 void insb ( volatile uint8_t *io_addr, uint8_t *data, unsigned int count );
359 #define insb( io_addr, data, count ) \
360 IOAPI_READS ( insb, uint8_t, io_addr, data, count, "IO", 2 )
361
362 /**
363 * Read 16-bit words from I/O-mapped device
364 *
365 * @v io_addr I/O address
366 * @v data Data buffer
367 * @v count Number of words to read
368 */
369 void insw ( volatile uint16_t *io_addr, uint16_t *data, unsigned int count );
370 #define insw( io_addr, data, count ) \
371 IOAPI_READS ( insw, uint16_t, io_addr, data, count, "IO", 4 )
372
373 /**
374 * Read 32-bit words from I/O-mapped device
375 *
376 * @v io_addr I/O address
377 * @v data Data buffer
378 * @v count Number of words to read
379 */
380 void insl ( volatile uint32_t *io_addr, uint32_t *data, unsigned int count );
381 #define insl( io_addr, data, count ) \
382 IOAPI_READS ( insl, uint32_t, io_addr, data, count, "IO", 8 )
383
384 /**
385 * Write bytes to I/O-mapped device
386 *
387 * @v io_addr I/O address
388 * @v data Data buffer
389 * @v count Number of bytes to write
390 */
391 void outsb ( volatile uint8_t *io_addr, const uint8_t *data,
392 unsigned int count );
393 #define outsb( io_addr, data, count ) \
394 IOAPI_WRITES ( outsb, uint8_t, io_addr, data, count, "IO", 2 )
395
396 /**
397 * Write 16-bit words to I/O-mapped device
398 *
399 * @v io_addr I/O address
400 * @v data Data buffer
401 * @v count Number of words to write
402 */
403 void outsw ( volatile uint16_t *io_addr, const uint16_t *data,
404 unsigned int count );
405 #define outsw( io_addr, data, count ) \
406 IOAPI_WRITES ( outsw, uint16_t, io_addr, data, count, "IO", 4 )
407
408 /**
409 * Write 32-bit words to I/O-mapped device
410 *
411 * @v io_addr I/O address
412 * @v data Data buffer
413 * @v count Number of words to write
414 */
415 void outsl ( volatile uint32_t *io_addr, const uint32_t *data,
416 unsigned int count );
417 #define outsl( io_addr, data, count ) \
418 IOAPI_WRITES ( outsl, uint32_t, io_addr, data, count, "IO", 8 )
419
420 /**
421 * Slow down I/O
422 *
423 */
424 void iodelay ( void );
425
426 /**
427 * Read value from I/O-mapped device, slowly
428 *
429 * @v _func Function to use to read value
430 * @v data Value to write
431 * @v io_addr I/O address
432 */
433 #define INX_P( _func, _type, io_addr ) ( { \
434 _type _data = _func ( (io_addr) ); \
435 iodelay(); \
436 _data; } )
437
438 /**
439 * Read byte from I/O-mapped device
440 *
441 * @v io_addr I/O address
442 * @ret data Value read
443 */
444 #define inb_p( io_addr ) INX_P ( inb, uint8_t, io_addr )
445
446 /**
447 * Read 16-bit word from I/O-mapped device
448 *
449 * @v io_addr I/O address
450 * @ret data Value read
451 */
452 #define inw_p( io_addr ) INX_P ( inw, uint16_t, io_addr )
453
454 /**
455 * Read 32-bit dword from I/O-mapped device
456 *
457 * @v io_addr I/O address
458 * @ret data Value read
459 */
460 #define inl_p( io_addr ) INX_P ( inl, uint32_t, io_addr )
461
462 /**
463 * Write value to I/O-mapped device, slowly
464 *
465 * @v _func Function to use to write value
466 * @v data Value to write
467 * @v io_addr I/O address
468 */
469 #define OUTX_P( _func, data, io_addr ) do { \
470 _func ( (data), (io_addr) ); \
471 iodelay(); \
472 } while ( 0 )
473
474 /**
475 * Write byte to I/O-mapped device, slowly
476 *
477 * @v data Value to write
478 * @v io_addr I/O address
479 */
480 #define outb_p( data, io_addr ) OUTX_P ( outb, data, io_addr )
481
482 /**
483 * Write 16-bit word to I/O-mapped device, slowly
484 *
485 * @v data Value to write
486 * @v io_addr I/O address
487 */
488 #define outw_p( data, io_addr ) OUTX_P ( outw, data, io_addr )
489
490 /**
491 * Write 32-bit dword to I/O-mapped device, slowly
492 *
493 * @v data Value to write
494 * @v io_addr I/O address
495 */
496 #define outl_p( data, io_addr ) OUTX_P ( outl, data, io_addr )
497
498 /**
499 * Memory barrier
500 *
501 */
502 void mb ( void );
503 #define rmb() mb()
504 #define wmb() mb()
505
506 #endif /* _GPXE_IO_H */
507