io.h

Go to the documentation of this file.
00001 #ifndef _GPXE_IO_H
00002 #define _GPXE_IO_H
00003 
00004 /** @file
00005  *
00006  * gPXE I/O API
00007  *
00008  * The I/O API provides methods for reading from and writing to
00009  * memory-mapped and I/O-mapped devices.
00010  *
00011  * The standard methods (readl()/writel() etc.) do not strictly check
00012  * the type of the address parameter; this is because traditional
00013  * usage does not necessarily provide the correct pointer type.  For
00014  * example, code written for ISA devices at fixed I/O addresses (such
00015  * as the keyboard controller) tend to use plain integer constants for
00016  * the address parameter.
00017  */
00018 
00019 FILE_LICENCE ( GPL2_OR_LATER );
00020 
00021 #include <stdint.h>
00022 #include <gpxe/api.h>
00023 #include <config/ioapi.h>
00024 #include <gpxe/uaccess.h>
00025 
00026 /**
00027  * Calculate static inline I/O API function name
00028  *
00029  * @v _prefix           Subsystem prefix
00030  * @v _api_func         API function
00031  * @ret _subsys_func    Subsystem API function
00032  */
00033 #define IOAPI_INLINE( _subsys, _api_func ) \
00034         SINGLE_API_INLINE ( IOAPI_PREFIX_ ## _subsys, _api_func )
00035 
00036 /**
00037  * Provide an I/O API implementation
00038  *
00039  * @v _prefix           Subsystem prefix
00040  * @v _api_func         API function
00041  * @v _func             Implementing function
00042  */
00043 #define PROVIDE_IOAPI( _subsys, _api_func, _func ) \
00044         PROVIDE_SINGLE_API ( IOAPI_PREFIX_ ## _subsys, _api_func, _func )
00045 
00046 /**
00047  * Provide a static inline I/O API implementation
00048  *
00049  * @v _prefix           Subsystem prefix
00050  * @v _api_func         API function
00051  */
00052 #define PROVIDE_IOAPI_INLINE( _subsys, _api_func ) \
00053         PROVIDE_SINGLE_API_INLINE ( IOAPI_PREFIX_ ## _subsys, _api_func )
00054 
00055 /* Include all architecture-independent I/O API headers */
00056 #include <gpxe/efi/efi_io.h>
00057 
00058 /* Include all architecture-dependent I/O API headers */
00059 #include <bits/io.h>
00060 
00061 /**
00062  * Wrap an I/O read
00063  *
00064  * @v _func             I/O API function
00065  * @v _type             Data type
00066  * @v io_addr           I/O address
00067  * @v _prefix           Prefix for address in debug message
00068  * @v _ndigits          Number of hex digits for this data type
00069  */
00070 #define IOAPI_READ( _func, _type, io_addr, _prefix, _ndigits ) ( {            \
00071         volatile _type *_io_addr =                                            \
00072                 ( ( volatile _type * ) ( intptr_t ) (io_addr) );              \
00073         _type _data = _func ( _io_addr );                                     \
00074         DBGIO ( "[" _prefix " %08lx] => %0" #_ndigits "llx\n",                \
00075                 io_to_bus ( _io_addr ), ( unsigned long long ) _data );       \
00076         _data; } )
00077 
00078 /**
00079  * Wrap an I/O write
00080  *
00081  * @v _func             I/O API function
00082  * @v _type             Data type
00083  * @v data              Value to write
00084  * @v io_addr           I/O address
00085  * @v _prefix           Prefix for address in debug message
00086  * @v _ndigits          Number of hex digits for this data type
00087  */
00088 #define IOAPI_WRITE( _func, _type, data, io_addr, _prefix, _ndigits ) do {    \
00089         volatile _type *_io_addr =                                            \
00090                 ( ( volatile _type * ) ( intptr_t ) (io_addr) );              \
00091         _type _data = (data);                                                 \
00092         DBGIO ( "[" _prefix " %08lx] <= %0" #_ndigits "llx\n",                \
00093                 io_to_bus ( _io_addr ), ( unsigned long long ) _data );       \
00094         _func ( _data, _io_addr );                                            \
00095         } while ( 0 )
00096 
00097 /**
00098  * Wrap an I/O string read
00099  *
00100  * @v _func             I/O API function
00101  * @v _type             Data type
00102  * @v io_addr           I/O address
00103  * @v data              Data buffer
00104  * @v count             Number of elements to read
00105  * @v _prefix           Prefix for address in debug message
00106  * @v _ndigits          Number of hex digits for this data type
00107  */
00108 #define IOAPI_READS( _func, _type, io_addr, data, count, _prefix, _ndigits )  \
00109         do {                                                                  \
00110         volatile _type *_io_addr =                                            \
00111                 ( ( volatile _type * ) ( intptr_t ) (io_addr) );              \
00112         void *_data_void = (data); /* Check data is a pointer */              \
00113         _type * _data = ( ( _type * ) _data_void );                           \
00114         const _type * _dbg_data = _data;                                      \
00115         unsigned int _count = (count);                                        \
00116         unsigned int _dbg_count = _count;                                     \
00117         _func ( _io_addr, _data, _count );                                    \
00118         DBGIO ( "[" _prefix " %08lx] =>", io_to_bus ( _io_addr ) );           \
00119         while ( _dbg_count-- ) {                                              \
00120                 DBGIO ( " %0" #_ndigits "llx",                                \
00121                         ( ( unsigned long long ) *(_dbg_data++) ) );          \
00122         }                                                                     \
00123         DBGIO ( "\n" );                                                       \
00124         } while ( 0 )
00125 
00126 /**
00127  * Wrap an I/O string write
00128  *
00129  * @v _func             I/O API function
00130  * @v _type             Data type
00131  * @v io_addr           I/O address
00132  * @v data              Data buffer
00133  * @v count             Number of elements to write
00134  * @v _prefix           Prefix for address in debug message
00135  * @v _ndigits          Number of hex digits for this data type
00136  */
00137 #define IOAPI_WRITES( _func, _type, io_addr, data, count, _prefix, _ndigits ) \
00138         do {                                                                  \
00139         volatile _type *_io_addr =                                            \
00140                 ( ( volatile _type * ) ( intptr_t ) (io_addr) );              \
00141         const void *_data_void = (data); /* Check data is a pointer */        \
00142         const _type * _data = ( ( const _type * ) _data_void );               \
00143         const _type * _dbg_data = _data;                                      \
00144         unsigned int _count = (count);                                        \
00145         unsigned int _dbg_count = _count;                                     \
00146         DBGIO ( "[" _prefix " %08lx] <=", io_to_bus ( _io_addr ) );           \
00147         while ( _dbg_count-- ) {                                              \
00148                 DBGIO ( " %0" #_ndigits "llx",                                \
00149                         ( ( unsigned long long ) *(_dbg_data++) ) );          \
00150         }                                                                     \
00151         DBGIO ( "\n" );                                                       \
00152         _func ( _io_addr, _data, _count );                                    \
00153         } while ( 0 )
00154 
00155 /**
00156  * Convert physical address to a bus address
00157  *
00158  * @v phys_addr         Physical address
00159  * @ret bus_addr        Bus address
00160  */
00161 unsigned long phys_to_bus ( unsigned long phys_addr );
00162 
00163 /**
00164  * Convert bus address to a physical address
00165  *
00166  * @v bus_addr          Bus address
00167  * @ret phys_addr       Physical address
00168  */
00169 unsigned long bus_to_phys ( unsigned long bus_addr );
00170 
00171 /**
00172  * Convert virtual address to a bus address
00173  *
00174  * @v addr              Virtual address
00175  * @ret bus_addr        Bus address
00176  */
00177 static inline __always_inline unsigned long
00178 virt_to_bus ( volatile const void *addr ) {
00179         return phys_to_bus ( virt_to_phys ( addr ) );
00180 }
00181 
00182 /**
00183  * Convert bus address to a virtual address
00184  *
00185  * @v bus_addr          Bus address
00186  * @ret addr            Virtual address
00187  *
00188  * This operation is not available under all memory models.
00189  */
00190 static inline __always_inline void * bus_to_virt ( unsigned long bus_addr ) {
00191         return phys_to_virt ( bus_to_phys ( bus_addr ) );
00192 }
00193 
00194 /**
00195  * Map bus address as an I/O address
00196  *
00197  * @v bus_addr          Bus address
00198  * @v len               Length of region
00199  * @ret io_addr         I/O address
00200  */
00201 void * ioremap ( unsigned long bus_addr, size_t len );
00202 
00203 /**
00204  * Unmap I/O address
00205  *
00206  * @v io_addr           I/O address
00207  */
00208 void iounmap ( volatile const void *io_addr );
00209 
00210 /**
00211  * Convert I/O address to bus address (for debug only)
00212  *
00213  * @v io_addr           I/O address
00214  * @ret bus_addr        Bus address
00215  */
00216 unsigned long io_to_bus ( volatile const void *io_addr );
00217 
00218 /**
00219  * Read byte from memory-mapped device
00220  *
00221  * @v io_addr           I/O address
00222  * @ret data            Value read
00223  */
00224 uint8_t readb ( volatile uint8_t *io_addr );
00225 #define readb( io_addr ) IOAPI_READ ( readb, uint8_t, io_addr, "MEM", 2 )
00226 
00227 /**
00228  * Read 16-bit word from memory-mapped device
00229  *
00230  * @v io_addr           I/O address
00231  * @ret data            Value read
00232  */
00233 uint16_t readw ( volatile uint16_t *io_addr );
00234 #define readw( io_addr ) IOAPI_READ ( readw, uint16_t, io_addr, "MEM", 4 )
00235 
00236 /**
00237  * Read 32-bit dword from memory-mapped device
00238  *
00239  * @v io_addr           I/O address
00240  * @ret data            Value read
00241  */
00242 uint32_t readl ( volatile uint32_t *io_addr );
00243 #define readl( io_addr ) IOAPI_READ ( readl, uint32_t, io_addr, "MEM", 8 )
00244 
00245 /**
00246  * Read 64-bit qword from memory-mapped device
00247  *
00248  * @v io_addr           I/O address
00249  * @ret data            Value read
00250  */
00251 uint64_t readq ( volatile uint64_t *io_addr );
00252 #define readq( io_addr ) IOAPI_READ ( readq, uint64_t, io_addr, "MEM", 16 )
00253 
00254 /**
00255  * Write byte to memory-mapped device
00256  *
00257  * @v data              Value to write
00258  * @v io_addr           I/O address
00259  */
00260 void writeb ( uint8_t data, volatile uint8_t *io_addr );
00261 #define writeb( data, io_addr ) \
00262         IOAPI_WRITE ( writeb, uint8_t, data, io_addr, "MEM", 2 )
00263 
00264 /**
00265  * Write 16-bit word to memory-mapped device
00266  *
00267  * @v data              Value to write
00268  * @v io_addr           I/O address
00269  */
00270 void writew ( uint16_t data, volatile uint16_t *io_addr );
00271 #define writew( data, io_addr ) \
00272         IOAPI_WRITE ( writew, uint16_t, data, io_addr, "MEM", 4 )
00273 
00274 /**
00275  * Write 32-bit dword to memory-mapped device
00276  *
00277  * @v data              Value to write
00278  * @v io_addr           I/O address
00279  */
00280 void writel ( uint32_t data, volatile uint32_t *io_addr );
00281 #define writel( data, io_addr ) \
00282         IOAPI_WRITE ( writel, uint32_t, data, io_addr, "MEM", 8 )
00283 
00284 /**
00285  * Write 64-bit qword to memory-mapped device
00286  *
00287  * @v data              Value to write
00288  * @v io_addr           I/O address
00289  */
00290 void writeq ( uint64_t data, volatile uint64_t *io_addr );
00291 #define writeq( data, io_addr ) \
00292         IOAPI_WRITE ( writeq, uint64_t, data, io_addr, "MEM", 16 )
00293 
00294 /**
00295  * Read byte from I/O-mapped device
00296  *
00297  * @v io_addr           I/O address
00298  * @ret data            Value read
00299  */
00300 uint8_t inb ( volatile uint8_t *io_addr );
00301 #define inb( io_addr ) IOAPI_READ ( inb, uint8_t, io_addr, "IO", 2 )
00302 
00303 /**
00304  * Read 16-bit word from I/O-mapped device
00305  *
00306  * @v io_addr           I/O address
00307  * @ret data            Value read
00308  */
00309 uint16_t inw ( volatile uint16_t *io_addr );
00310 #define inw( io_addr ) IOAPI_READ ( inw, uint16_t, io_addr, "IO", 4 )
00311 
00312 /**
00313  * Read 32-bit dword from I/O-mapped device
00314  *
00315  * @v io_addr           I/O address
00316  * @ret data            Value read
00317  */
00318 uint32_t inl ( volatile uint32_t *io_addr );
00319 #define inl( io_addr ) IOAPI_READ ( inl, uint32_t, io_addr, "IO", 8 )
00320 
00321 /**
00322  * Write byte to I/O-mapped device
00323  *
00324  * @v data              Value to write
00325  * @v io_addr           I/O address
00326  */
00327 void outb ( uint8_t data, volatile uint8_t *io_addr );
00328 #define outb( data, io_addr ) \
00329         IOAPI_WRITE ( outb, uint8_t, data, io_addr, "IO", 2 )
00330 
00331 /**
00332  * Write 16-bit word to I/O-mapped device
00333  *
00334  * @v data              Value to write
00335  * @v io_addr           I/O address
00336  */
00337 void outw ( uint16_t data, volatile uint16_t *io_addr );
00338 #define outw( data, io_addr ) \
00339         IOAPI_WRITE ( outw, uint16_t, data, io_addr, "IO", 4 )
00340 
00341 /**
00342  * Write 32-bit dword to I/O-mapped device
00343  *
00344  * @v data              Value to write
00345  * @v io_addr           I/O address
00346  */
00347 void outl ( uint32_t data, volatile uint32_t *io_addr );
00348 #define outl( data, io_addr ) \
00349         IOAPI_WRITE ( outl, uint32_t, data, io_addr, "IO", 8 )
00350 
00351 /**
00352  * Read bytes from I/O-mapped device
00353  *
00354  * @v io_addr           I/O address
00355  * @v data              Data buffer
00356  * @v count             Number of bytes to read
00357  */
00358 void insb ( volatile uint8_t *io_addr, uint8_t *data, unsigned int count );
00359 #define insb( io_addr, data, count ) \
00360         IOAPI_READS ( insb, uint8_t, io_addr, data, count, "IO", 2 )
00361 
00362 /**
00363  * Read 16-bit words from I/O-mapped device
00364  *
00365  * @v io_addr           I/O address
00366  * @v data              Data buffer
00367  * @v count             Number of words to read
00368  */
00369 void insw ( volatile uint16_t *io_addr, uint16_t *data, unsigned int count );
00370 #define insw( io_addr, data, count ) \
00371         IOAPI_READS ( insw, uint16_t, io_addr, data, count, "IO", 4 )
00372 
00373 /**
00374  * Read 32-bit words from I/O-mapped device
00375  *
00376  * @v io_addr           I/O address
00377  * @v data              Data buffer
00378  * @v count             Number of words to read
00379  */
00380 void insl ( volatile uint32_t *io_addr, uint32_t *data, unsigned int count );
00381 #define insl( io_addr, data, count ) \
00382         IOAPI_READS ( insl, uint32_t, io_addr, data, count, "IO", 8 )
00383 
00384 /**
00385  * Write bytes to I/O-mapped device
00386  *
00387  * @v io_addr           I/O address
00388  * @v data              Data buffer
00389  * @v count             Number of bytes to write
00390  */
00391 void outsb ( volatile uint8_t *io_addr, const uint8_t *data,
00392              unsigned int count );
00393 #define outsb( io_addr, data, count ) \
00394         IOAPI_WRITES ( outsb, uint8_t, io_addr, data, count, "IO", 2 )
00395 
00396 /**
00397  * Write 16-bit words to I/O-mapped device
00398  *
00399  * @v io_addr           I/O address
00400  * @v data              Data buffer
00401  * @v count             Number of words to write
00402  */
00403 void outsw ( volatile uint16_t *io_addr, const uint16_t *data,
00404              unsigned int count );
00405 #define outsw( io_addr, data, count ) \
00406         IOAPI_WRITES ( outsw, uint16_t, io_addr, data, count, "IO", 4 )
00407 
00408 /**
00409  * Write 32-bit words to I/O-mapped device
00410  *
00411  * @v io_addr           I/O address
00412  * @v data              Data buffer
00413  * @v count             Number of words to write
00414  */
00415 void outsl ( volatile uint32_t *io_addr, const uint32_t *data,
00416              unsigned int count );
00417 #define outsl( io_addr, data, count ) \
00418         IOAPI_WRITES ( outsl, uint32_t, io_addr, data, count, "IO", 8 )
00419 
00420 /**
00421  * Slow down I/O
00422  *
00423  */
00424 void iodelay ( void );
00425 
00426 /**
00427  * Read value from I/O-mapped device, slowly
00428  *
00429  * @v _func             Function to use to read value
00430  * @v data              Value to write
00431  * @v io_addr           I/O address
00432  */
00433 #define INX_P( _func, _type, io_addr ) ( {                                    \
00434         _type _data = _func ( (io_addr) );                                    \
00435         iodelay();                                                            \
00436         _data; } )
00437 
00438 /**
00439  * Read byte from I/O-mapped device
00440  *
00441  * @v io_addr           I/O address
00442  * @ret data            Value read
00443  */
00444 #define inb_p( io_addr ) INX_P ( inb, uint8_t, io_addr )
00445 
00446 /**
00447  * Read 16-bit word from I/O-mapped device
00448  *
00449  * @v io_addr           I/O address
00450  * @ret data            Value read
00451  */
00452 #define inw_p( io_addr ) INX_P ( inw, uint16_t, io_addr )
00453 
00454 /**
00455  * Read 32-bit dword from I/O-mapped device
00456  *
00457  * @v io_addr           I/O address
00458  * @ret data            Value read
00459  */
00460 #define inl_p( io_addr ) INX_P ( inl, uint32_t, io_addr )
00461 
00462 /**
00463  * Write value to I/O-mapped device, slowly
00464  *
00465  * @v _func             Function to use to write value
00466  * @v data              Value to write
00467  * @v io_addr           I/O address
00468  */
00469 #define OUTX_P( _func, data, io_addr ) do {                                   \
00470         _func ( (data), (io_addr) );                                          \
00471         iodelay();                                                            \
00472         } while ( 0 )
00473 
00474 /**
00475  * Write byte to I/O-mapped device, slowly
00476  *
00477  * @v data              Value to write
00478  * @v io_addr           I/O address
00479  */
00480 #define outb_p( data, io_addr ) OUTX_P ( outb, data, io_addr )
00481 
00482 /**
00483  * Write 16-bit word to I/O-mapped device, slowly
00484  *
00485  * @v data              Value to write
00486  * @v io_addr           I/O address
00487  */
00488 #define outw_p( data, io_addr ) OUTX_P ( outw, data, io_addr )
00489 
00490 /**
00491  * Write 32-bit dword to I/O-mapped device, slowly
00492  *
00493  * @v data              Value to write
00494  * @v io_addr           I/O address
00495  */
00496 #define outl_p( data, io_addr ) OUTX_P ( outl, data, io_addr )
00497 
00498 /**
00499  * Memory barrier
00500  *
00501  */
00502 void mb ( void );
00503 #define rmb()   mb()
00504 #define wmb()   mb()
00505 
00506 #endif /* _GPXE_IO_H */

Generated on Tue Apr 6 20:01:08 2010 for gPXE by  doxygen 1.5.7.1