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 #define PAGE_SIZE ( 1 << PAGE_SHIFT )
30 #define PAGE_MASK ( PAGE_SIZE - 1 )
33 * Calculate static inline I/O API function name
35 * @v _prefix Subsystem prefix
36 * @v _api_func API function
37 * @ret _subsys_func Subsystem API function
39 #define IOAPI_INLINE( _subsys, _api_func ) \
40 SINGLE_API_INLINE ( IOAPI_PREFIX_ ## _subsys, _api_func )
43 * Provide an I/O API implementation
45 * @v _prefix Subsystem prefix
46 * @v _api_func API function
47 * @v _func Implementing function
49 #define PROVIDE_IOAPI( _subsys, _api_func, _func ) \
50 PROVIDE_SINGLE_API ( IOAPI_PREFIX_ ## _subsys, _api_func, _func )
53 * Provide a static inline I/O API implementation
55 * @v _prefix Subsystem prefix
56 * @v _api_func API function
58 #define PROVIDE_IOAPI_INLINE( _subsys, _api_func ) \
59 PROVIDE_SINGLE_API_INLINE ( IOAPI_PREFIX_ ## _subsys, _api_func )
61 /* Include all architecture-independent I/O API headers */
63 /* Include all architecture-dependent I/O API headers */
69 * @v _func I/O API function
71 * @v io_addr I/O address
72 * @v _prefix Prefix for address in debug message
73 * @v _ndigits Number of hex digits for this data type
75 #define IOAPI_READ( _func, _type, io_addr, _prefix, _ndigits ) ( { \
76 volatile _type *_io_addr = \
77 ( ( volatile _type * ) ( intptr_t ) (io_addr) ); \
78 _type _data = _func ( _io_addr ); \
79 DBGIO ( "[" _prefix " %08lx] => %0" #_ndigits "llx\n", \
80 io_to_bus ( _io_addr ), ( unsigned long long ) _data ); \
86 * @v _func I/O API function
88 * @v data Value to write
89 * @v io_addr I/O address
90 * @v _prefix Prefix for address in debug message
91 * @v _ndigits Number of hex digits for this data type
93 #define IOAPI_WRITE( _func, _type, data, io_addr, _prefix, _ndigits ) do { \
94 volatile _type *_io_addr = \
95 ( ( volatile _type * ) ( intptr_t ) (io_addr) ); \
96 _type _data = (data); \
97 DBGIO ( "[" _prefix " %08lx] <= %0" #_ndigits "llx\n", \
98 io_to_bus ( _io_addr ), ( unsigned long long ) _data ); \
99 _func ( _data, _io_addr ); \
103 * Wrap an I/O string read
105 * @v _func I/O API function
107 * @v io_addr I/O address
108 * @v data Data buffer
109 * @v count Number of elements to read
110 * @v _prefix Prefix for address in debug message
111 * @v _ndigits Number of hex digits for this data type
113 #define IOAPI_READS( _func, _type, io_addr, data, count, _prefix, _ndigits ) \
115 volatile _type *_io_addr = \
116 ( ( volatile _type * ) ( intptr_t ) (io_addr) ); \
117 void *_data_void = (data); /* Check data is a pointer */ \
118 _type * _data = ( ( _type * ) _data_void ); \
119 const _type * _dbg_data = _data; \
120 unsigned int _count = (count); \
121 unsigned int _dbg_count = _count; \
122 _func ( _io_addr, _data, _count ); \
123 DBGIO ( "[" _prefix " %08lx] =>", io_to_bus ( _io_addr ) ); \
124 while ( _dbg_count-- ) { \
125 DBGIO ( " %0" #_ndigits "llx", \
126 ( ( unsigned long long ) *(_dbg_data++) ) ); \
132 * Wrap an I/O string write
134 * @v _func I/O API function
136 * @v io_addr I/O address
137 * @v data Data buffer
138 * @v count Number of elements to write
139 * @v _prefix Prefix for address in debug message
140 * @v _ndigits Number of hex digits for this data type
142 #define IOAPI_WRITES( _func, _type, io_addr, data, count, _prefix, _ndigits ) \
144 volatile _type *_io_addr = \
145 ( ( volatile _type * ) ( intptr_t ) (io_addr) ); \
146 const void *_data_void = (data); /* Check data is a pointer */ \
147 const _type * _data = ( ( const _type * ) _data_void ); \
148 const _type * _dbg_data = _data; \
149 unsigned int _count = (count); \
150 unsigned int _dbg_count = _count; \
151 DBGIO ( "[" _prefix " %08lx] <=", io_to_bus ( _io_addr ) ); \
152 while ( _dbg_count-- ) { \
153 DBGIO ( " %0" #_ndigits "llx", \
154 ( ( unsigned long long ) *(_dbg_data++) ) ); \
157 _func ( _io_addr, _data, _count ); \
161 * Convert physical address to a bus address
163 * @v phys_addr Physical address
164 * @ret bus_addr Bus address
166 unsigned long phys_to_bus ( unsigned long phys_addr );
169 * Convert bus address to a physical address
171 * @v bus_addr Bus address
172 * @ret phys_addr Physical address
174 unsigned long bus_to_phys ( unsigned long bus_addr );
177 * Convert virtual address to a bus address
179 * @v addr Virtual address
180 * @ret bus_addr Bus address
182 static inline __always_inline unsigned long
183 virt_to_bus ( volatile const void *addr ) {
184 return phys_to_bus ( virt_to_phys ( addr ) );
188 * Convert bus address to a virtual address
190 * @v bus_addr Bus address
191 * @ret addr Virtual address
193 * This operation is not available under all memory models.
195 static inline __always_inline void * bus_to_virt ( unsigned long bus_addr ) {
196 return phys_to_virt ( bus_to_phys ( bus_addr ) );
200 * Map bus address as an I/O address
202 * @v bus_addr Bus address
203 * @v len Length of region
204 * @ret io_addr I/O address
206 void * ioremap ( unsigned long bus_addr, size_t len );
211 * @v io_addr I/O address
213 void iounmap ( volatile const void *io_addr );
216 * Convert I/O address to bus address (for debug only)
218 * @v io_addr I/O address
219 * @ret bus_addr Bus address
221 unsigned long io_to_bus ( volatile const void *io_addr );
224 * Read byte from memory-mapped device
226 * @v io_addr I/O address
227 * @ret data Value read
229 uint8_t readb ( volatile uint8_t *io_addr );
230 #define readb( io_addr ) IOAPI_READ ( readb, uint8_t, io_addr, "MEM", 2 )
233 * Read 16-bit word from memory-mapped device
235 * @v io_addr I/O address
236 * @ret data Value read
238 uint16_t readw ( volatile uint16_t *io_addr );
239 #define readw( io_addr ) IOAPI_READ ( readw, uint16_t, io_addr, "MEM", 4 )
242 * Read 32-bit dword from memory-mapped device
244 * @v io_addr I/O address
245 * @ret data Value read
247 uint32_t readl ( volatile uint32_t *io_addr );
248 #define readl( io_addr ) IOAPI_READ ( readl, uint32_t, io_addr, "MEM", 8 )
251 * Read 64-bit qword from memory-mapped device
253 * @v io_addr I/O address
254 * @ret data Value read
256 uint64_t readq ( volatile uint64_t *io_addr );
257 #define readq( io_addr ) IOAPI_READ ( readq, uint64_t, io_addr, "MEM", 16 )
260 * Write byte to memory-mapped device
262 * @v data Value to write
263 * @v io_addr I/O address
265 void writeb ( uint8_t data, volatile uint8_t *io_addr );
266 #define writeb( data, io_addr ) \
267 IOAPI_WRITE ( writeb, uint8_t, data, io_addr, "MEM", 2 )
270 * Write 16-bit word to memory-mapped device
272 * @v data Value to write
273 * @v io_addr I/O address
275 void writew ( uint16_t data, volatile uint16_t *io_addr );
276 #define writew( data, io_addr ) \
277 IOAPI_WRITE ( writew, uint16_t, data, io_addr, "MEM", 4 )
280 * Write 32-bit dword to memory-mapped device
282 * @v data Value to write
283 * @v io_addr I/O address
285 void writel ( uint32_t data, volatile uint32_t *io_addr );
286 #define writel( data, io_addr ) \
287 IOAPI_WRITE ( writel, uint32_t, data, io_addr, "MEM", 8 )
290 * Write 64-bit qword to memory-mapped device
292 * @v data Value to write
293 * @v io_addr I/O address
295 void writeq ( uint64_t data, volatile uint64_t *io_addr );
296 #define writeq( data, io_addr ) \
297 IOAPI_WRITE ( writeq, uint64_t, data, io_addr, "MEM", 16 )
300 * Read byte from I/O-mapped device
302 * @v io_addr I/O address
303 * @ret data Value read
305 uint8_t inb ( volatile uint8_t *io_addr );
306 #define inb( io_addr ) IOAPI_READ ( inb, uint8_t, io_addr, "IO", 2 )
309 * Read 16-bit word from I/O-mapped device
311 * @v io_addr I/O address
312 * @ret data Value read
314 uint16_t inw ( volatile uint16_t *io_addr );
315 #define inw( io_addr ) IOAPI_READ ( inw, uint16_t, io_addr, "IO", 4 )
318 * Read 32-bit dword from I/O-mapped device
320 * @v io_addr I/O address
321 * @ret data Value read
323 uint32_t inl ( volatile uint32_t *io_addr );
324 #define inl( io_addr ) IOAPI_READ ( inl, uint32_t, io_addr, "IO", 8 )
327 * Write byte to I/O-mapped device
329 * @v data Value to write
330 * @v io_addr I/O address
332 void outb ( uint8_t data, volatile uint8_t *io_addr );
333 #define outb( data, io_addr ) \
334 IOAPI_WRITE ( outb, uint8_t, data, io_addr, "IO", 2 )
337 * Write 16-bit word to I/O-mapped device
339 * @v data Value to write
340 * @v io_addr I/O address
342 void outw ( uint16_t data, volatile uint16_t *io_addr );
343 #define outw( data, io_addr ) \
344 IOAPI_WRITE ( outw, uint16_t, data, io_addr, "IO", 4 )
347 * Write 32-bit dword to I/O-mapped device
349 * @v data Value to write
350 * @v io_addr I/O address
352 void outl ( uint32_t data, volatile uint32_t *io_addr );
353 #define outl( data, io_addr ) \
354 IOAPI_WRITE ( outl, uint32_t, data, io_addr, "IO", 8 )
357 * Read bytes from I/O-mapped device
359 * @v io_addr I/O address
360 * @v data Data buffer
361 * @v count Number of bytes to read
363 void insb ( volatile uint8_t *io_addr, uint8_t *data, unsigned int count );
364 #define insb( io_addr, data, count ) \
365 IOAPI_READS ( insb, uint8_t, io_addr, data, count, "IO", 2 )
368 * Read 16-bit words from I/O-mapped device
370 * @v io_addr I/O address
371 * @v data Data buffer
372 * @v count Number of words to read
374 void insw ( volatile uint16_t *io_addr, uint16_t *data, unsigned int count );
375 #define insw( io_addr, data, count ) \
376 IOAPI_READS ( insw, uint16_t, io_addr, data, count, "IO", 4 )
379 * Read 32-bit words from I/O-mapped device
381 * @v io_addr I/O address
382 * @v data Data buffer
383 * @v count Number of words to read
385 void insl ( volatile uint32_t *io_addr, uint32_t *data, unsigned int count );
386 #define insl( io_addr, data, count ) \
387 IOAPI_READS ( insl, uint32_t, io_addr, data, count, "IO", 8 )
390 * Write bytes to I/O-mapped device
392 * @v io_addr I/O address
393 * @v data Data buffer
394 * @v count Number of bytes to write
396 void outsb ( volatile uint8_t *io_addr, const uint8_t *data,
397 unsigned int count );
398 #define outsb( io_addr, data, count ) \
399 IOAPI_WRITES ( outsb, uint8_t, io_addr, data, count, "IO", 2 )
402 * Write 16-bit words to I/O-mapped device
404 * @v io_addr I/O address
405 * @v data Data buffer
406 * @v count Number of words to write
408 void outsw ( volatile uint16_t *io_addr, const uint16_t *data,
409 unsigned int count );
410 #define outsw( io_addr, data, count ) \
411 IOAPI_WRITES ( outsw, uint16_t, io_addr, data, count, "IO", 4 )
414 * Write 32-bit words to I/O-mapped device
416 * @v io_addr I/O address
417 * @v data Data buffer
418 * @v count Number of words to write
420 void outsl ( volatile uint32_t *io_addr, const uint32_t *data,
421 unsigned int count );
422 #define outsl( io_addr, data, count ) \
423 IOAPI_WRITES ( outsl, uint32_t, io_addr, data, count, "IO", 8 )
429 void iodelay ( void );
432 * Read value from I/O-mapped device, slowly
434 * @v _func Function to use to read value
435 * @v data Value to write
436 * @v io_addr I/O address
438 #define INX_P( _func, _type, io_addr ) ( { \
439 _type _data = _func ( (io_addr) ); \
444 * Read byte from I/O-mapped device
446 * @v io_addr I/O address
447 * @ret data Value read
449 #define inb_p( io_addr ) INX_P ( inb, uint8_t, io_addr )
452 * Read 16-bit word from I/O-mapped device
454 * @v io_addr I/O address
455 * @ret data Value read
457 #define inw_p( io_addr ) INX_P ( inw, uint16_t, io_addr )
460 * Read 32-bit dword from I/O-mapped device
462 * @v io_addr I/O address
463 * @ret data Value read
465 #define inl_p( io_addr ) INX_P ( inl, uint32_t, io_addr )
468 * Write value to I/O-mapped device, slowly
470 * @v _func Function to use to write value
471 * @v data Value to write
472 * @v io_addr I/O address
474 #define OUTX_P( _func, data, io_addr ) do { \
475 _func ( (data), (io_addr) ); \
480 * Write byte to I/O-mapped device, slowly
482 * @v data Value to write
483 * @v io_addr I/O address
485 #define outb_p( data, io_addr ) OUTX_P ( outb, data, io_addr )
488 * Write 16-bit word to I/O-mapped device, slowly
490 * @v data Value to write
491 * @v io_addr I/O address
493 #define outw_p( data, io_addr ) OUTX_P ( outw, data, io_addr )
496 * Write 32-bit dword to I/O-mapped device, slowly
498 * @v data Value to write
499 * @v io_addr I/O address
501 #define outl_p( data, io_addr ) OUTX_P ( outl, data, io_addr )
511 /** A usable memory region */
512 struct memory_region {
513 /** Physical start address */
515 /** Physical end address */
519 /** Maximum number of memory regions we expect to encounter */
520 #define MAX_MEMORY_REGIONS 8
524 /** Memory regions */
525 struct memory_region regions[MAX_MEMORY_REGIONS];
526 /** Number of used regions */
533 * @v memmap Memory map to fill in
535 void get_memmap ( struct memory_map *memmap );
537 #endif /* _IPXE_IO_H */