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>
24 * Calculate static inline I/O API function name
26 * @v _prefix Subsystem prefix
27 * @v _api_func API function
28 * @ret _subsys_func Subsystem API function
30 #define IOAPI_INLINE( _subsys, _api_func ) \
31 SINGLE_API_INLINE ( IOAPI_PREFIX_ ## _subsys, _api_func )
34 * Provide an I/O API implementation
36 * @v _prefix Subsystem prefix
37 * @v _api_func API function
38 * @v _func Implementing function
40 #define PROVIDE_IOAPI( _subsys, _api_func, _func ) \
41 PROVIDE_SINGLE_API ( IOAPI_PREFIX_ ## _subsys, _api_func, _func )
44 * Provide a static inline I/O API implementation
46 * @v _prefix Subsystem prefix
47 * @v _api_func API function
49 #define PROVIDE_IOAPI_INLINE( _subsys, _api_func ) \
50 PROVIDE_SINGLE_API_INLINE ( IOAPI_PREFIX_ ## _subsys, _api_func )
52 /* Include all architecture-independent I/O API headers */
54 /* Include all architecture-dependent I/O API headers */
60 * @v _func I/O API function
62 * @v io_addr I/O address
63 * @v _prefix Prefix for address in debug message
64 * @v _ndigits Number of hex digits for this data type
66 #define IOAPI_READ( _func, _type, io_addr, _prefix, _ndigits ) ( { \
67 volatile _type *_io_addr = \
68 ( ( volatile _type * ) ( intptr_t ) (io_addr) ); \
69 _type _data = _func ( _io_addr ); \
70 DBGIO ( "[" _prefix " %08lx] => %0" #_ndigits "llx\n", \
71 io_to_bus ( _io_addr ), ( unsigned long long ) _data ); \
77 * @v _func I/O API function
79 * @v data Value to write
80 * @v io_addr I/O address
81 * @v _prefix Prefix for address in debug message
82 * @v _ndigits Number of hex digits for this data type
84 #define IOAPI_WRITE( _func, _type, data, io_addr, _prefix, _ndigits ) do { \
85 volatile _type *_io_addr = \
86 ( ( volatile _type * ) ( intptr_t ) (io_addr) ); \
87 _type _data = (data); \
88 DBGIO ( "[" _prefix " %08lx] <= %0" #_ndigits "llx\n", \
89 io_to_bus ( _io_addr ), ( unsigned long long ) _data ); \
90 _func ( _data, _io_addr ); \
94 * Wrap an I/O string read
96 * @v _func I/O API function
98 * @v io_addr I/O address
100 * @v count Number of elements to read
101 * @v _prefix Prefix for address in debug message
102 * @v _ndigits Number of hex digits for this data type
104 #define IOAPI_READS( _func, _type, io_addr, data, count, _prefix, _ndigits ) \
106 volatile _type *_io_addr = \
107 ( ( volatile _type * ) ( intptr_t ) (io_addr) ); \
108 void *_data_void = (data); /* Check data is a pointer */ \
109 _type * _data = ( ( _type * ) _data_void ); \
110 const _type * _dbg_data = _data; \
111 unsigned int _count = (count); \
112 unsigned int _dbg_count = _count; \
113 _func ( _io_addr, _data, _count ); \
114 DBGIO ( "[" _prefix " %08lx] =>", io_to_bus ( _io_addr ) ); \
115 while ( _dbg_count-- ) { \
116 DBGIO ( " %0" #_ndigits "llx", \
117 ( ( unsigned long long ) *(_dbg_data++) ) ); \
123 * Wrap an I/O string write
125 * @v _func I/O API function
127 * @v io_addr I/O address
128 * @v data Data buffer
129 * @v count Number of elements to write
130 * @v _prefix Prefix for address in debug message
131 * @v _ndigits Number of hex digits for this data type
133 #define IOAPI_WRITES( _func, _type, io_addr, data, count, _prefix, _ndigits ) \
135 volatile _type *_io_addr = \
136 ( ( volatile _type * ) ( intptr_t ) (io_addr) ); \
137 const void *_data_void = (data); /* Check data is a pointer */ \
138 const _type * _data = ( ( const _type * ) _data_void ); \
139 const _type * _dbg_data = _data; \
140 unsigned int _count = (count); \
141 unsigned int _dbg_count = _count; \
142 DBGIO ( "[" _prefix " %08lx] <=", io_to_bus ( _io_addr ) ); \
143 while ( _dbg_count-- ) { \
144 DBGIO ( " %0" #_ndigits "llx", \
145 ( ( unsigned long long ) *(_dbg_data++) ) ); \
148 _func ( _io_addr, _data, _count ); \
152 * Map bus address as an I/O address
154 * @v bus_addr Bus address
155 * @v len Length of region
156 * @ret io_addr I/O address
158 void * ioremap ( unsigned long bus_addr, size_t len );
163 * @v io_addr I/O address
165 void iounmap ( volatile const void *io_addr );
168 * Convert I/O address to bus address (for debug only)
170 * @v io_addr I/O address
171 * @ret bus_addr Bus address
173 unsigned long io_to_bus ( volatile const void *io_addr );
176 * Convert virtual address to a bus address
178 * @v addr Virtual address
179 * @ret bus_addr Bus address
181 unsigned long virt_to_bus ( volatile const void *addr );
184 * Convert bus address to a virtual address
186 * @v bus_addr Bus address
187 * @ret addr Virtual address
189 * This operation isn't actually valid within our memory model, and is
190 * impossible to achieve under -DKEEP_IT_REAL. Some drivers haven't
191 * been updated to avoid it yet, though.
193 void * bus_to_virt ( unsigned long bus_addr );
196 * Read byte from memory-mapped device
198 * @v io_addr I/O address
199 * @ret data Value read
201 uint8_t readb ( volatile uint8_t *io_addr );
202 #define readb( io_addr ) IOAPI_READ ( readb, uint8_t, io_addr, "MEM", 2 )
205 * Read 16-bit word from memory-mapped device
207 * @v io_addr I/O address
208 * @ret data Value read
210 uint16_t readw ( volatile uint16_t *io_addr );
211 #define readw( io_addr ) IOAPI_READ ( readw, uint16_t, io_addr, "MEM", 4 )
214 * Read 32-bit dword from memory-mapped device
216 * @v io_addr I/O address
217 * @ret data Value read
219 uint32_t readl ( volatile uint32_t *io_addr );
220 #define readl( io_addr ) IOAPI_READ ( readl, uint32_t, io_addr, "MEM", 8 )
223 * Read 64-bit qword from memory-mapped device
225 * @v io_addr I/O address
226 * @ret data Value read
228 uint64_t readq ( volatile uint64_t *io_addr );
229 #define readq( io_addr ) IOAPI_READ ( readq, uint64_t, io_addr, "MEM", 16 )
232 * Write byte to memory-mapped device
234 * @v data Value to write
235 * @v io_addr I/O address
237 void writeb ( uint8_t data, volatile uint8_t *io_addr );
238 #define writeb( data, io_addr ) \
239 IOAPI_WRITE ( writeb, uint8_t, data, io_addr, "MEM", 2 )
242 * Write 16-bit word to memory-mapped device
244 * @v data Value to write
245 * @v io_addr I/O address
247 void writew ( uint16_t data, volatile uint16_t *io_addr );
248 #define writew( data, io_addr ) \
249 IOAPI_WRITE ( writew, uint16_t, data, io_addr, "MEM", 4 )
252 * Write 32-bit dword to memory-mapped device
254 * @v data Value to write
255 * @v io_addr I/O address
257 void writel ( uint32_t data, volatile uint32_t *io_addr );
258 #define writel( data, io_addr ) \
259 IOAPI_WRITE ( writel, uint32_t, data, io_addr, "MEM", 8 )
262 * Write 64-bit qword to memory-mapped device
264 * @v data Value to write
265 * @v io_addr I/O address
267 void writeq ( uint64_t data, volatile uint64_t *io_addr );
268 #define writeq( data, io_addr ) \
269 IOAPI_WRITE ( writeq, uint64_t, data, io_addr, "MEM", 16 )
272 * Read byte from I/O-mapped device
274 * @v io_addr I/O address
275 * @ret data Value read
277 uint8_t inb ( volatile uint8_t *io_addr );
278 #define inb( io_addr ) IOAPI_READ ( inb, uint8_t, io_addr, "IO", 2 )
281 * Read 16-bit word from I/O-mapped device
283 * @v io_addr I/O address
284 * @ret data Value read
286 uint16_t inw ( volatile uint16_t *io_addr );
287 #define inw( io_addr ) IOAPI_READ ( inw, uint16_t, io_addr, "IO", 4 )
290 * Read 32-bit dword from I/O-mapped device
292 * @v io_addr I/O address
293 * @ret data Value read
295 uint32_t inl ( volatile uint32_t *io_addr );
296 #define inl( io_addr ) IOAPI_READ ( inl, uint32_t, io_addr, "IO", 8 )
299 * Write byte to I/O-mapped device
301 * @v data Value to write
302 * @v io_addr I/O address
304 void outb ( uint8_t data, volatile uint8_t *io_addr );
305 #define outb( data, io_addr ) \
306 IOAPI_WRITE ( outb, uint8_t, data, io_addr, "IO", 2 )
309 * Write 16-bit word to I/O-mapped device
311 * @v data Value to write
312 * @v io_addr I/O address
314 void outw ( uint16_t data, volatile uint16_t *io_addr );
315 #define outw( data, io_addr ) \
316 IOAPI_WRITE ( outw, uint16_t, data, io_addr, "IO", 4 )
319 * Write 32-bit dword to I/O-mapped device
321 * @v data Value to write
322 * @v io_addr I/O address
324 void outl ( uint32_t data, volatile uint32_t *io_addr );
325 #define outl( data, io_addr ) \
326 IOAPI_WRITE ( outl, uint32_t, data, io_addr, "IO", 8 )
329 * Read bytes from I/O-mapped device
331 * @v io_addr I/O address
332 * @v data Data buffer
333 * @v count Number of bytes to read
335 void insb ( volatile uint8_t *io_addr, uint8_t *data, unsigned int count );
336 #define insb( io_addr, data, count ) \
337 IOAPI_READS ( insb, uint8_t, io_addr, data, count, "IO", 2 )
340 * Read 16-bit words from I/O-mapped device
342 * @v io_addr I/O address
343 * @v data Data buffer
344 * @v count Number of words to read
346 void insw ( volatile uint16_t *io_addr, uint16_t *data, unsigned int count );
347 #define insw( io_addr, data, count ) \
348 IOAPI_READS ( insw, uint16_t, io_addr, data, count, "IO", 4 )
351 * Read 32-bit words from I/O-mapped device
353 * @v io_addr I/O address
354 * @v data Data buffer
355 * @v count Number of words to read
357 void insl ( volatile uint32_t *io_addr, uint32_t *data, unsigned int count );
358 #define insl( io_addr, data, count ) \
359 IOAPI_READS ( insl, uint32_t, io_addr, data, count, "IO", 8 )
362 * Write bytes to I/O-mapped device
364 * @v io_addr I/O address
365 * @v data Data buffer
366 * @v count Number of bytes to write
368 void outsb ( volatile uint8_t *io_addr, const uint8_t *data,
369 unsigned int count );
370 #define outsb( io_addr, data, count ) \
371 IOAPI_WRITES ( outsb, uint8_t, io_addr, data, count, "IO", 2 )
374 * Write 16-bit words to I/O-mapped device
376 * @v io_addr I/O address
377 * @v data Data buffer
378 * @v count Number of words to write
380 void outsw ( volatile uint16_t *io_addr, const uint16_t *data,
381 unsigned int count );
382 #define outsw( io_addr, data, count ) \
383 IOAPI_WRITES ( outsw, uint16_t, io_addr, data, count, "IO", 4 )
386 * Write 32-bit words to I/O-mapped device
388 * @v io_addr I/O address
389 * @v data Data buffer
390 * @v count Number of words to write
392 void outsl ( volatile uint32_t *io_addr, const uint32_t *data,
393 unsigned int count );
394 #define outsl( io_addr, data, count ) \
395 IOAPI_WRITES ( outsl, uint32_t, io_addr, data, count, "IO", 8 )
401 void iodelay ( void );
404 * Read value from I/O-mapped device, slowly
406 * @v _func Function to use to read value
407 * @v data Value to write
408 * @v io_addr I/O address
410 #define INX_P( _func, _type, io_addr ) ( { \
411 _type _data = _func ( (io_addr) ); \
416 * Read byte from I/O-mapped device
418 * @v io_addr I/O address
419 * @ret data Value read
421 #define inb_p( io_addr ) INX_P ( inb, uint8_t, io_addr )
424 * Read 16-bit word from I/O-mapped device
426 * @v io_addr I/O address
427 * @ret data Value read
429 #define inw_p( io_addr ) INX_P ( inw, uint16_t, io_addr )
432 * Read 32-bit dword from I/O-mapped device
434 * @v io_addr I/O address
435 * @ret data Value read
437 #define inl_p( io_addr ) INX_P ( inl, uint32_t, io_addr )
440 * Write value to I/O-mapped device, slowly
442 * @v _func Function to use to write value
443 * @v data Value to write
444 * @v io_addr I/O address
446 #define OUTX_P( _func, data, io_addr ) do { \
447 _func ( (data), (io_addr) ); \
452 * Write byte to I/O-mapped device, slowly
454 * @v data Value to write
455 * @v io_addr I/O address
457 #define outb_p( data, io_addr ) OUTX_P ( outb, data, io_addr )
460 * Write 16-bit word to I/O-mapped device, slowly
462 * @v data Value to write
463 * @v io_addr I/O address
465 #define outw_p( data, io_addr ) OUTX_P ( outw, data, io_addr )
468 * Write 32-bit dword to I/O-mapped device, slowly
470 * @v data Value to write
471 * @v io_addr I/O address
473 #define outl_p( data, io_addr ) OUTX_P ( outl, data, io_addr )
483 #endif /* _GPXE_IO_H */