8 * The I/O API provides methods for reading from and writing to
9 * memory-mapped and I/O-mapped devices.
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.
21 #include <config/ioapi.h>
22 #include <gpxe/uaccess.h>
25 * Calculate static inline I/O API function name
27 * @v _prefix Subsystem prefix
28 * @v _api_func API function
29 * @ret _subsys_func Subsystem API function
31 #define IOAPI_INLINE( _subsys, _api_func ) \
32 SINGLE_API_INLINE ( IOAPI_PREFIX_ ## _subsys, _api_func )
35 * Provide an I/O API implementation
37 * @v _prefix Subsystem prefix
38 * @v _api_func API function
39 * @v _func Implementing function
41 #define PROVIDE_IOAPI( _subsys, _api_func, _func ) \
42 PROVIDE_SINGLE_API ( IOAPI_PREFIX_ ## _subsys, _api_func, _func )
45 * Provide a static inline I/O API implementation
47 * @v _prefix Subsystem prefix
48 * @v _api_func API function
50 #define PROVIDE_IOAPI_INLINE( _subsys, _api_func ) \
51 PROVIDE_SINGLE_API_INLINE ( IOAPI_PREFIX_ ## _subsys, _api_func )
53 /* Include all architecture-independent I/O API headers */
54 #include <gpxe/efi/efi_io.h>
56 /* Include all architecture-dependent I/O API headers */
62 * @v _func I/O API function
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
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 ); \
79 * @v _func I/O API function
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
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 ); \
96 * Wrap an I/O string read
98 * @v _func I/O API function
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
106 #define IOAPI_READS( _func, _type, io_addr, data, count, _prefix, _ndigits ) \
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++) ) ); \
125 * Wrap an I/O string write
127 * @v _func I/O API function
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
135 #define IOAPI_WRITES( _func, _type, io_addr, data, count, _prefix, _ndigits ) \
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++) ) ); \
150 _func ( _io_addr, _data, _count ); \
154 * Convert physical address to a bus address
156 * @v phys_addr Physical address
157 * @ret bus_addr Bus address
159 unsigned long phys_to_bus ( unsigned long phys_addr
);
162 * Convert bus address to a physical address
164 * @v bus_addr Bus address
165 * @ret phys_addr Physical address
167 unsigned long bus_to_phys ( unsigned long bus_addr
);
170 * Convert virtual address to a bus address
172 * @v addr Virtual address
173 * @ret bus_addr Bus address
175 static inline __always_inline
unsigned long
176 virt_to_bus ( volatile const void *addr
) {
177 return phys_to_bus ( virt_to_phys ( addr
) );
181 * Convert bus address to a virtual address
183 * @v bus_addr Bus address
184 * @ret addr Virtual address
186 * This operation is not available under all memory models.
188 static inline __always_inline
void * bus_to_virt ( unsigned long bus_addr
) {
189 return phys_to_virt ( bus_to_phys ( bus_addr
) );
193 * Map bus address as an I/O address
195 * @v bus_addr Bus address
196 * @v len Length of region
197 * @ret io_addr I/O address
199 void * ioremap ( unsigned long bus_addr
, size_t len
);
204 * @v io_addr I/O address
206 void iounmap ( volatile const void *io_addr
);
209 * Convert I/O address to bus address (for debug only)
211 * @v io_addr I/O address
212 * @ret bus_addr Bus address
214 unsigned long io_to_bus ( volatile const void *io_addr
);
217 * Read byte from memory-mapped device
219 * @v io_addr I/O address
220 * @ret data Value read
222 uint8_t readb ( volatile uint8_t *io_addr
);
223 #define readb( io_addr ) IOAPI_READ ( readb, uint8_t, io_addr, "MEM", 2 )
226 * Read 16-bit word from memory-mapped device
228 * @v io_addr I/O address
229 * @ret data Value read
231 uint16_t readw ( volatile uint16_t *io_addr
);
232 #define readw( io_addr ) IOAPI_READ ( readw, uint16_t, io_addr, "MEM", 4 )
235 * Read 32-bit dword from memory-mapped device
237 * @v io_addr I/O address
238 * @ret data Value read
240 uint32_t readl ( volatile uint32_t *io_addr
);
241 #define readl( io_addr ) IOAPI_READ ( readl, uint32_t, io_addr, "MEM", 8 )
244 * Read 64-bit qword from memory-mapped device
246 * @v io_addr I/O address
247 * @ret data Value read
249 uint64_t readq ( volatile uint64_t *io_addr
);
250 #define readq( io_addr ) IOAPI_READ ( readq, uint64_t, io_addr, "MEM", 16 )
253 * Write byte to memory-mapped device
255 * @v data Value to write
256 * @v io_addr I/O address
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 )
263 * Write 16-bit word to memory-mapped device
265 * @v data Value to write
266 * @v io_addr I/O address
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 )
273 * Write 32-bit dword to memory-mapped device
275 * @v data Value to write
276 * @v io_addr I/O address
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 )
283 * Write 64-bit qword to memory-mapped device
285 * @v data Value to write
286 * @v io_addr I/O address
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 )
293 * Read byte from I/O-mapped device
295 * @v io_addr I/O address
296 * @ret data Value read
298 uint8_t inb ( volatile uint8_t *io_addr
);
299 #define inb( io_addr ) IOAPI_READ ( inb, uint8_t, io_addr, "IO", 2 )
302 * Read 16-bit word from I/O-mapped device
304 * @v io_addr I/O address
305 * @ret data Value read
307 uint16_t inw ( volatile uint16_t *io_addr
);
308 #define inw( io_addr ) IOAPI_READ ( inw, uint16_t, io_addr, "IO", 4 )
311 * Read 32-bit dword from I/O-mapped device
313 * @v io_addr I/O address
314 * @ret data Value read
316 uint32_t inl ( volatile uint32_t *io_addr
);
317 #define inl( io_addr ) IOAPI_READ ( inl, uint32_t, io_addr, "IO", 8 )
320 * Write byte to I/O-mapped device
322 * @v data Value to write
323 * @v io_addr I/O address
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 )
330 * Write 16-bit word to I/O-mapped device
332 * @v data Value to write
333 * @v io_addr I/O address
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 )
340 * Write 32-bit dword to I/O-mapped device
342 * @v data Value to write
343 * @v io_addr I/O address
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 )
350 * Read bytes from I/O-mapped device
352 * @v io_addr I/O address
353 * @v data Data buffer
354 * @v count Number of bytes to read
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 )
361 * Read 16-bit words from I/O-mapped device
363 * @v io_addr I/O address
364 * @v data Data buffer
365 * @v count Number of words to read
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 )
372 * Read 32-bit words from I/O-mapped device
374 * @v io_addr I/O address
375 * @v data Data buffer
376 * @v count Number of words to read
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 )
383 * Write bytes to I/O-mapped device
385 * @v io_addr I/O address
386 * @v data Data buffer
387 * @v count Number of bytes to write
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 )
395 * Write 16-bit words to I/O-mapped device
397 * @v io_addr I/O address
398 * @v data Data buffer
399 * @v count Number of words to write
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 )
407 * Write 32-bit words to I/O-mapped device
409 * @v io_addr I/O address
410 * @v data Data buffer
411 * @v count Number of words to write
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 )
422 void iodelay ( void );
425 * Read value from I/O-mapped device, slowly
427 * @v _func Function to use to read value
428 * @v data Value to write
429 * @v io_addr I/O address
431 #define INX_P( _func, _type, io_addr ) ( { \
432 _type _data = _func ( (io_addr) ); \
437 * Read byte from I/O-mapped device
439 * @v io_addr I/O address
440 * @ret data Value read
442 #define inb_p( io_addr ) INX_P ( inb, uint8_t, io_addr )
445 * Read 16-bit word from I/O-mapped device
447 * @v io_addr I/O address
448 * @ret data Value read
450 #define inw_p( io_addr ) INX_P ( inw, uint16_t, io_addr )
453 * Read 32-bit dword from I/O-mapped device
455 * @v io_addr I/O address
456 * @ret data Value read
458 #define inl_p( io_addr ) INX_P ( inl, uint32_t, io_addr )
461 * Write value to I/O-mapped device, slowly
463 * @v _func Function to use to write value
464 * @v data Value to write
465 * @v io_addr I/O address
467 #define OUTX_P( _func, data, io_addr ) do { \
468 _func ( (data), (io_addr) ); \
473 * Write byte to I/O-mapped device, slowly
475 * @v data Value to write
476 * @v io_addr I/O address
478 #define outb_p( data, io_addr ) OUTX_P ( outb, data, io_addr )
481 * Write 16-bit word to I/O-mapped device, slowly
483 * @v data Value to write
484 * @v io_addr I/O address
486 #define outw_p( data, io_addr ) OUTX_P ( outw, data, io_addr )
489 * Write 32-bit dword to I/O-mapped device, slowly
491 * @v data Value to write
492 * @v io_addr I/O address
494 #define outl_p( data, io_addr ) OUTX_P ( outl, data, io_addr )
504 #endif /* _GPXE_IO_H */