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.
19 FILE_LICENCE ( GPL2_OR_LATER );
23 #include <config/ioapi.h>
24 #include <ipxe/uaccess.h>
27 * Calculate static inline I/O API function name
29 * @v _prefix Subsystem prefix
30 * @v _api_func API function
31 * @ret _subsys_func Subsystem API function
33 #define IOAPI_INLINE( _subsys, _api_func ) \
34 SINGLE_API_INLINE ( IOAPI_PREFIX_ ## _subsys, _api_func )
37 * Provide an I/O API implementation
39 * @v _prefix Subsystem prefix
40 * @v _api_func API function
41 * @v _func Implementing function
43 #define PROVIDE_IOAPI( _subsys, _api_func, _func ) \
44 PROVIDE_SINGLE_API ( IOAPI_PREFIX_ ## _subsys, _api_func, _func )
47 * Provide a static inline I/O API implementation
49 * @v _prefix Subsystem prefix
50 * @v _api_func API function
52 #define PROVIDE_IOAPI_INLINE( _subsys, _api_func ) \
53 PROVIDE_SINGLE_API_INLINE ( IOAPI_PREFIX_ ## _subsys, _api_func )
55 /* Include all architecture-independent I/O API headers */
56 #include <ipxe/efi/efi_io.h>
58 /* Include all architecture-dependent I/O API headers */
64 * @v _func I/O API function
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
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 ); \
81 * @v _func I/O API function
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
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 ); \
98 * Wrap an I/O string read
100 * @v _func I/O API function
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
108 #define IOAPI_READS( _func, _type, io_addr, data, count, _prefix, _ndigits ) \
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++) ) ); \
127 * Wrap an I/O string write
129 * @v _func I/O API function
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
137 #define IOAPI_WRITES( _func, _type, io_addr, data, count, _prefix, _ndigits ) \
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++) ) ); \
152 _func ( _io_addr, _data, _count ); \
156 * Convert physical address to a bus address
158 * @v phys_addr Physical address
159 * @ret bus_addr Bus address
161 unsigned long phys_to_bus ( unsigned long phys_addr );
164 * Convert bus address to a physical address
166 * @v bus_addr Bus address
167 * @ret phys_addr Physical address
169 unsigned long bus_to_phys ( unsigned long bus_addr );
172 * Convert virtual address to a bus address
174 * @v addr Virtual address
175 * @ret bus_addr Bus address
177 static inline __always_inline unsigned long
178 virt_to_bus ( volatile const void *addr ) {
179 return phys_to_bus ( virt_to_phys ( addr ) );
183 * Convert bus address to a virtual address
185 * @v bus_addr Bus address
186 * @ret addr Virtual address
188 * This operation is not available under all memory models.
190 static inline __always_inline void * bus_to_virt ( unsigned long bus_addr ) {
191 return phys_to_virt ( bus_to_phys ( bus_addr ) );
195 * Map bus address as an I/O address
197 * @v bus_addr Bus address
198 * @v len Length of region
199 * @ret io_addr I/O address
201 void * ioremap ( unsigned long bus_addr, size_t len );
206 * @v io_addr I/O address
208 void iounmap ( volatile const void *io_addr );
211 * Convert I/O address to bus address (for debug only)
213 * @v io_addr I/O address
214 * @ret bus_addr Bus address
216 unsigned long io_to_bus ( volatile const void *io_addr );
219 * Read byte from memory-mapped device
221 * @v io_addr I/O address
222 * @ret data Value read
224 uint8_t readb ( volatile uint8_t *io_addr );
225 #define readb( io_addr ) IOAPI_READ ( readb, uint8_t, io_addr, "MEM", 2 )
228 * Read 16-bit word from memory-mapped device
230 * @v io_addr I/O address
231 * @ret data Value read
233 uint16_t readw ( volatile uint16_t *io_addr );
234 #define readw( io_addr ) IOAPI_READ ( readw, uint16_t, io_addr, "MEM", 4 )
237 * Read 32-bit dword from memory-mapped device
239 * @v io_addr I/O address
240 * @ret data Value read
242 uint32_t readl ( volatile uint32_t *io_addr );
243 #define readl( io_addr ) IOAPI_READ ( readl, uint32_t, io_addr, "MEM", 8 )
246 * Read 64-bit qword from memory-mapped device
248 * @v io_addr I/O address
249 * @ret data Value read
251 uint64_t readq ( volatile uint64_t *io_addr );
252 #define readq( io_addr ) IOAPI_READ ( readq, uint64_t, io_addr, "MEM", 16 )
255 * Write byte to memory-mapped device
257 * @v data Value to write
258 * @v io_addr I/O address
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 )
265 * Write 16-bit word to memory-mapped device
267 * @v data Value to write
268 * @v io_addr I/O address
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 )
275 * Write 32-bit dword to memory-mapped device
277 * @v data Value to write
278 * @v io_addr I/O address
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 )
285 * Write 64-bit qword to memory-mapped device
287 * @v data Value to write
288 * @v io_addr I/O address
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 )
295 * Read byte from I/O-mapped device
297 * @v io_addr I/O address
298 * @ret data Value read
300 uint8_t inb ( volatile uint8_t *io_addr );
301 #define inb( io_addr ) IOAPI_READ ( inb, uint8_t, io_addr, "IO", 2 )
304 * Read 16-bit word from I/O-mapped device
306 * @v io_addr I/O address
307 * @ret data Value read
309 uint16_t inw ( volatile uint16_t *io_addr );
310 #define inw( io_addr ) IOAPI_READ ( inw, uint16_t, io_addr, "IO", 4 )
313 * Read 32-bit dword from I/O-mapped device
315 * @v io_addr I/O address
316 * @ret data Value read
318 uint32_t inl ( volatile uint32_t *io_addr );
319 #define inl( io_addr ) IOAPI_READ ( inl, uint32_t, io_addr, "IO", 8 )
322 * Write byte to I/O-mapped device
324 * @v data Value to write
325 * @v io_addr I/O address
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 )
332 * Write 16-bit word to I/O-mapped device
334 * @v data Value to write
335 * @v io_addr I/O address
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 )
342 * Write 32-bit dword to I/O-mapped device
344 * @v data Value to write
345 * @v io_addr I/O address
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 )
352 * Read bytes from I/O-mapped device
354 * @v io_addr I/O address
355 * @v data Data buffer
356 * @v count Number of bytes to read
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 )
363 * Read 16-bit words from I/O-mapped device
365 * @v io_addr I/O address
366 * @v data Data buffer
367 * @v count Number of words to read
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 )
374 * Read 32-bit words from I/O-mapped device
376 * @v io_addr I/O address
377 * @v data Data buffer
378 * @v count Number of words to read
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 )
385 * Write bytes to I/O-mapped device
387 * @v io_addr I/O address
388 * @v data Data buffer
389 * @v count Number of bytes to write
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 )
397 * Write 16-bit words to I/O-mapped device
399 * @v io_addr I/O address
400 * @v data Data buffer
401 * @v count Number of words to write
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 )
409 * Write 32-bit words to I/O-mapped device
411 * @v io_addr I/O address
412 * @v data Data buffer
413 * @v count Number of words to write
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 )
424 void iodelay ( void );
427 * Read value from I/O-mapped device, slowly
429 * @v _func Function to use to read value
430 * @v data Value to write
431 * @v io_addr I/O address
433 #define INX_P( _func, _type, io_addr ) ( { \
434 _type _data = _func ( (io_addr) ); \
439 * Read byte from I/O-mapped device
441 * @v io_addr I/O address
442 * @ret data Value read
444 #define inb_p( io_addr ) INX_P ( inb, uint8_t, io_addr )
447 * Read 16-bit word from I/O-mapped device
449 * @v io_addr I/O address
450 * @ret data Value read
452 #define inw_p( io_addr ) INX_P ( inw, uint16_t, io_addr )
455 * Read 32-bit dword from I/O-mapped device
457 * @v io_addr I/O address
458 * @ret data Value read
460 #define inl_p( io_addr ) INX_P ( inl, uint32_t, io_addr )
463 * Write value to I/O-mapped device, slowly
465 * @v _func Function to use to write value
466 * @v data Value to write
467 * @v io_addr I/O address
469 #define OUTX_P( _func, data, io_addr ) do { \
470 _func ( (data), (io_addr) ); \
475 * Write byte to I/O-mapped device, slowly
477 * @v data Value to write
478 * @v io_addr I/O address
480 #define outb_p( data, io_addr ) OUTX_P ( outb, data, io_addr )
483 * Write 16-bit word to I/O-mapped device, slowly
485 * @v data Value to write
486 * @v io_addr I/O address
488 #define outw_p( data, io_addr ) OUTX_P ( outw, data, io_addr )
491 * Write 32-bit dword to I/O-mapped device, slowly
493 * @v data Value to write
494 * @v io_addr I/O address
496 #define outl_p( data, io_addr ) OUTX_P ( outl, data, io_addr )
506 /** A usable memory region */
507 struct memory_region {
508 /** Physical start address */
510 /** Physical end address */
514 /** Maximum number of memory regions we expect to encounter */
515 #define MAX_MEMORY_REGIONS 8
519 /** Memory regions */
520 struct memory_region regions[MAX_MEMORY_REGIONS];
521 /** Number of used regions */
528 * @v memmap Memory map to fill in
530 void get_memmap ( struct memory_map *memmap );
532 #endif /* _IPXE_IO_H */