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