00001 #ifndef _GPXE_IO_H
00002 #define _GPXE_IO_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
00028
00029
00030
00031
00032
00033 #define IOAPI_INLINE( _subsys, _api_func ) \
00034 SINGLE_API_INLINE ( IOAPI_PREFIX_ ## _subsys, _api_func )
00035
00036
00037
00038
00039
00040
00041
00042
00043 #define PROVIDE_IOAPI( _subsys, _api_func, _func ) \
00044 PROVIDE_SINGLE_API ( IOAPI_PREFIX_ ## _subsys, _api_func, _func )
00045
00046
00047
00048
00049
00050
00051
00052 #define PROVIDE_IOAPI_INLINE( _subsys, _api_func ) \
00053 PROVIDE_SINGLE_API_INLINE ( IOAPI_PREFIX_ ## _subsys, _api_func )
00054
00055
00056 #include <gpxe/efi/efi_io.h>
00057
00058
00059 #include <bits/io.h>
00060
00061
00062
00063
00064
00065
00066
00067
00068
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
00080
00081
00082
00083
00084
00085
00086
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
00099
00100
00101
00102
00103
00104
00105
00106
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); \
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
00128
00129
00130
00131
00132
00133
00134
00135
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); \
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
00157
00158
00159
00160
00161 unsigned long phys_to_bus ( unsigned long phys_addr );
00162
00163
00164
00165
00166
00167
00168
00169 unsigned long bus_to_phys ( unsigned long bus_addr );
00170
00171
00172
00173
00174
00175
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
00184
00185
00186
00187
00188
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
00196
00197
00198
00199
00200
00201 void * ioremap ( unsigned long bus_addr, size_t len );
00202
00203
00204
00205
00206
00207
00208 void iounmap ( volatile const void *io_addr );
00209
00210
00211
00212
00213
00214
00215
00216 unsigned long io_to_bus ( volatile const void *io_addr );
00217
00218
00219
00220
00221
00222
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
00229
00230
00231
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
00238
00239
00240
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
00247
00248
00249
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
00256
00257
00258
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
00266
00267
00268
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
00276
00277
00278
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
00286
00287
00288
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
00296
00297
00298
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
00305
00306
00307
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
00314
00315
00316
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
00323
00324
00325
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
00333
00334
00335
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
00343
00344
00345
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
00353
00354
00355
00356
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
00364
00365
00366
00367
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
00375
00376
00377
00378
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
00386
00387
00388
00389
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
00398
00399
00400
00401
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
00410
00411
00412
00413
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
00422
00423
00424 void iodelay ( void );
00425
00426
00427
00428
00429
00430
00431
00432
00433 #define INX_P( _func, _type, io_addr ) ( { \
00434 _type _data = _func ( (io_addr) ); \
00435 iodelay(); \
00436 _data; } )
00437
00438
00439
00440
00441
00442
00443
00444 #define inb_p( io_addr ) INX_P ( inb, uint8_t, io_addr )
00445
00446
00447
00448
00449
00450
00451
00452 #define inw_p( io_addr ) INX_P ( inw, uint16_t, io_addr )
00453
00454
00455
00456
00457
00458
00459
00460 #define inl_p( io_addr ) INX_P ( inl, uint32_t, io_addr )
00461
00462
00463
00464
00465
00466
00467
00468
00469 #define OUTX_P( _func, data, io_addr ) do { \
00470 _func ( (data), (io_addr) ); \
00471 iodelay(); \
00472 } while ( 0 )
00473
00474
00475
00476
00477
00478
00479
00480 #define outb_p( data, io_addr ) OUTX_P ( outb, data, io_addr )
00481
00482
00483
00484
00485
00486
00487
00488 #define outw_p( data, io_addr ) OUTX_P ( outw, data, io_addr )
00489
00490
00491
00492
00493
00494
00495
00496 #define outl_p( data, io_addr ) OUTX_P ( outl, data, io_addr )
00497
00498
00499
00500
00501
00502 void mb ( void );
00503 #define rmb() mb()
00504 #define wmb() mb()
00505
00506 #endif