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