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 * Convert virtual address to a physical address
154 * @v addr Virtual address
155 * @ret phys_addr Physical address
157 unsigned long virt_to_phys ( volatile const void *addr );
160 * Convert physical address to a virtual address
162 * @v addr Virtual address
163 * @ret phys_addr Physical address
165 * This operation isn't actually valid within our memory model, and is
166 * impossible to achieve under -DKEEP_IT_REAL. Some drivers haven't
167 * been updated to avoid it yet, though.
169 void * phys_to_virt ( unsigned long phys_addr );
172 * Convert virtual address to a bus address
174 * @v addr Virtual address
175 * @ret bus_addr Bus address
177 unsigned long virt_to_bus ( volatile const void *addr );
180 * Convert bus address to a virtual address
182 * @v bus_addr Bus address
183 * @ret addr Virtual address
185 * This operation isn't actually valid within our memory model, and is
186 * impossible to achieve under -DKEEP_IT_REAL. Some drivers haven't
187 * been updated to avoid it yet, though.
189 void * bus_to_virt ( unsigned long bus_addr );
192 * Map bus address as an I/O address
194 * @v bus_addr Bus address
195 * @v len Length of region
196 * @ret io_addr I/O address
198 void * ioremap ( unsigned long bus_addr, size_t len );
203 * @v io_addr I/O address
205 void iounmap ( volatile const void *io_addr );
208 * Convert I/O address to bus address (for debug only)
210 * @v io_addr I/O address
211 * @ret bus_addr Bus address
213 unsigned long io_to_bus ( volatile const void *io_addr );
216 * Read byte from memory-mapped device
218 * @v io_addr I/O address
219 * @ret data Value read
221 uint8_t readb ( volatile uint8_t *io_addr );
222 #define readb( io_addr ) IOAPI_READ ( readb, uint8_t, io_addr, "MEM", 2 )
225 * Read 16-bit word from memory-mapped device
227 * @v io_addr I/O address
228 * @ret data Value read
230 uint16_t readw ( volatile uint16_t *io_addr );
231 #define readw( io_addr ) IOAPI_READ ( readw, uint16_t, io_addr, "MEM", 4 )
234 * Read 32-bit dword from memory-mapped device
236 * @v io_addr I/O address
237 * @ret data Value read
239 uint32_t readl ( volatile uint32_t *io_addr );
240 #define readl( io_addr ) IOAPI_READ ( readl, uint32_t, io_addr, "MEM", 8 )
243 * Read 64-bit qword from memory-mapped device
245 * @v io_addr I/O address
246 * @ret data Value read
248 uint64_t readq ( volatile uint64_t *io_addr );
249 #define readq( io_addr ) IOAPI_READ ( readq, uint64_t, io_addr, "MEM", 16 )
252 * Write byte to memory-mapped device
254 * @v data Value to write
255 * @v io_addr I/O address
257 void writeb ( uint8_t data, volatile uint8_t *io_addr );
258 #define writeb( data, io_addr ) \
259 IOAPI_WRITE ( writeb, uint8_t, data, io_addr, "MEM", 2 )
262 * Write 16-bit word to memory-mapped device
264 * @v data Value to write
265 * @v io_addr I/O address
267 void writew ( uint16_t data, volatile uint16_t *io_addr );
268 #define writew( data, io_addr ) \
269 IOAPI_WRITE ( writew, uint16_t, data, io_addr, "MEM", 4 )
272 * Write 32-bit dword to memory-mapped device
274 * @v data Value to write
275 * @v io_addr I/O address
277 void writel ( uint32_t data, volatile uint32_t *io_addr );
278 #define writel( data, io_addr ) \
279 IOAPI_WRITE ( writel, uint32_t, data, io_addr, "MEM", 8 )
282 * Write 64-bit qword to memory-mapped device
284 * @v data Value to write
285 * @v io_addr I/O address
287 void writeq ( uint64_t data, volatile uint64_t *io_addr );
288 #define writeq( data, io_addr ) \
289 IOAPI_WRITE ( writeq, uint64_t, data, io_addr, "MEM", 16 )
292 * Read byte from I/O-mapped device
294 * @v io_addr I/O address
295 * @ret data Value read
297 uint8_t inb ( volatile uint8_t *io_addr );
298 #define inb( io_addr ) IOAPI_READ ( inb, uint8_t, io_addr, "IO", 2 )
301 * Read 16-bit word from I/O-mapped device
303 * @v io_addr I/O address
304 * @ret data Value read
306 uint16_t inw ( volatile uint16_t *io_addr );
307 #define inw( io_addr ) IOAPI_READ ( inw, uint16_t, io_addr, "IO", 4 )
310 * Read 32-bit dword from I/O-mapped device
312 * @v io_addr I/O address
313 * @ret data Value read
315 uint32_t inl ( volatile uint32_t *io_addr );
316 #define inl( io_addr ) IOAPI_READ ( inl, uint32_t, io_addr, "IO", 8 )
319 * Write byte to I/O-mapped device
321 * @v data Value to write
322 * @v io_addr I/O address
324 void outb ( uint8_t data, volatile uint8_t *io_addr );
325 #define outb( data, io_addr ) \
326 IOAPI_WRITE ( outb, uint8_t, data, io_addr, "IO", 2 )
329 * Write 16-bit word to I/O-mapped device
331 * @v data Value to write
332 * @v io_addr I/O address
334 void outw ( uint16_t data, volatile uint16_t *io_addr );
335 #define outw( data, io_addr ) \
336 IOAPI_WRITE ( outw, uint16_t, data, io_addr, "IO", 4 )
339 * Write 32-bit dword to I/O-mapped device
341 * @v data Value to write
342 * @v io_addr I/O address
344 void outl ( uint32_t data, volatile uint32_t *io_addr );
345 #define outl( data, io_addr ) \
346 IOAPI_WRITE ( outl, uint32_t, data, io_addr, "IO", 8 )
349 * Read bytes from I/O-mapped device
351 * @v io_addr I/O address
352 * @v data Data buffer
353 * @v count Number of bytes to read
355 void insb ( volatile uint8_t *io_addr, uint8_t *data, unsigned int count );
356 #define insb( io_addr, data, count ) \
357 IOAPI_READS ( insb, uint8_t, io_addr, data, count, "IO", 2 )
360 * Read 16-bit words from I/O-mapped device
362 * @v io_addr I/O address
363 * @v data Data buffer
364 * @v count Number of words to read
366 void insw ( volatile uint16_t *io_addr, uint16_t *data, unsigned int count );
367 #define insw( io_addr, data, count ) \
368 IOAPI_READS ( insw, uint16_t, io_addr, data, count, "IO", 4 )
371 * Read 32-bit words from I/O-mapped device
373 * @v io_addr I/O address
374 * @v data Data buffer
375 * @v count Number of words to read
377 void insl ( volatile uint32_t *io_addr, uint32_t *data, unsigned int count );
378 #define insl( io_addr, data, count ) \
379 IOAPI_READS ( insl, uint32_t, io_addr, data, count, "IO", 8 )
382 * Write bytes to I/O-mapped device
384 * @v io_addr I/O address
385 * @v data Data buffer
386 * @v count Number of bytes to write
388 void outsb ( volatile uint8_t *io_addr, const uint8_t *data,
389 unsigned int count );
390 #define outsb( io_addr, data, count ) \
391 IOAPI_WRITES ( outsb, uint8_t, io_addr, data, count, "IO", 2 )
394 * Write 16-bit words to I/O-mapped device
396 * @v io_addr I/O address
397 * @v data Data buffer
398 * @v count Number of words to write
400 void outsw ( volatile uint16_t *io_addr, const uint16_t *data,
401 unsigned int count );
402 #define outsw( io_addr, data, count ) \
403 IOAPI_WRITES ( outsw, uint16_t, io_addr, data, count, "IO", 4 )
406 * Write 32-bit words to I/O-mapped device
408 * @v io_addr I/O address
409 * @v data Data buffer
410 * @v count Number of words to write
412 void outsl ( volatile uint32_t *io_addr, const uint32_t *data,
413 unsigned int count );
414 #define outsl( io_addr, data, count ) \
415 IOAPI_WRITES ( outsl, uint32_t, io_addr, data, count, "IO", 8 )
421 void iodelay ( void );
424 * Read value from I/O-mapped device, slowly
426 * @v _func Function to use to read value
427 * @v data Value to write
428 * @v io_addr I/O address
430 #define INX_P( _func, _type, io_addr ) ( { \
431 _type _data = _func ( (io_addr) ); \
436 * Read byte from I/O-mapped device
438 * @v io_addr I/O address
439 * @ret data Value read
441 #define inb_p( io_addr ) INX_P ( inb, uint8_t, io_addr )
444 * Read 16-bit word from I/O-mapped device
446 * @v io_addr I/O address
447 * @ret data Value read
449 #define inw_p( io_addr ) INX_P ( inw, uint16_t, io_addr )
452 * Read 32-bit dword from I/O-mapped device
454 * @v io_addr I/O address
455 * @ret data Value read
457 #define inl_p( io_addr ) INX_P ( inl, uint32_t, io_addr )
460 * Write value to I/O-mapped device, slowly
462 * @v _func Function to use to write value
463 * @v data Value to write
464 * @v io_addr I/O address
466 #define OUTX_P( _func, data, io_addr ) do { \
467 _func ( (data), (io_addr) ); \
472 * Write byte to I/O-mapped device, slowly
474 * @v data Value to write
475 * @v io_addr I/O address
477 #define outb_p( data, io_addr ) OUTX_P ( outb, data, io_addr )
480 * Write 16-bit word to I/O-mapped device, slowly
482 * @v data Value to write
483 * @v io_addr I/O address
485 #define outw_p( data, io_addr ) OUTX_P ( outw, data, io_addr )
488 * Write 32-bit dword to I/O-mapped device, slowly
490 * @v data Value to write
491 * @v io_addr I/O address
493 #define outl_p( data, io_addr ) OUTX_P ( outl, data, io_addr )
503 #endif /* _GPXE_IO_H */