Home | History | Annotate | Download | only in gpxe
      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
    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  */
    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