iPXE
io.h
Go to the documentation of this file.
1 #ifndef _IPXE_IO_H
2 #define _IPXE_IO_H
3 
4 /** @file
5  *
6  * iPXE I/O API
7  *
8  * The I/O API provides methods for reading from and writing to
9  * memory-mapped and I/O-mapped devices.
10  *
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.
17  */
18 
19 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
20 FILE_SECBOOT ( PERMITTED );
21 
22 #include <stdint.h>
23 #include <ipxe/api.h>
24 #include <ipxe/iomap.h>
25 #include <config/ioapi.h>
26 
27 /** Page size */
28 #define PAGE_SIZE ( 1 << PAGE_SHIFT )
29 
30 /** Page mask */
31 #define PAGE_MASK ( PAGE_SIZE - 1 )
32 
33 /**
34  * Calculate static inline I/O API function name
35  *
36  * @v _prefix Subsystem prefix
37  * @v _api_func API function
38  * @ret _subsys_func Subsystem API function
39  */
40 #define IOAPI_INLINE( _subsys, _api_func ) \
41  SINGLE_API_INLINE ( IOAPI_PREFIX_ ## _subsys, _api_func )
42 
43 /**
44  * Provide an I/O API implementation
45  *
46  * @v _prefix Subsystem prefix
47  * @v _api_func API function
48  * @v _func Implementing function
49  */
50 #define PROVIDE_IOAPI( _subsys, _api_func, _func ) \
51  PROVIDE_SINGLE_API ( IOAPI_PREFIX_ ## _subsys, _api_func, _func )
52 
53 /**
54  * Provide a static inline I/O API implementation
55  *
56  * @v _prefix Subsystem prefix
57  * @v _api_func API function
58  */
59 #define PROVIDE_IOAPI_INLINE( _subsys, _api_func ) \
60  PROVIDE_SINGLE_API_INLINE ( IOAPI_PREFIX_ ## _subsys, _api_func )
61 
62 /* Include all architecture-independent I/O API headers */
63 
64 /* Include all architecture-dependent I/O API headers */
65 #include <bits/io.h>
66 
67 /**
68  * Wrap an I/O read
69  *
70  * @v _func I/O API function
71  * @v _type Data type
72  * @v io_addr I/O address
73  * @v _prefix Prefix for address in debug message
74  * @v _ndigits Number of hex digits for this data type
75  */
76 #define IOAPI_READ( _func, _type, io_addr, _prefix, _ndigits ) ( { \
77  volatile _type *_io_addr = \
78  ( ( volatile _type * ) ( intptr_t ) (io_addr) ); \
79  _type _data = _func ( _io_addr ); \
80  DBGIO ( "[" _prefix " %08lx] => %0" #_ndigits "llx\n", \
81  io_to_bus ( _io_addr ), ( unsigned long long ) _data ); \
82  _data; } )
83 
84 /**
85  * Wrap an I/O write
86  *
87  * @v _func I/O API function
88  * @v _type Data type
89  * @v data Value to write
90  * @v io_addr I/O address
91  * @v _prefix Prefix for address in debug message
92  * @v _ndigits Number of hex digits for this data type
93  */
94 #define IOAPI_WRITE( _func, _type, data, io_addr, _prefix, _ndigits ) do { \
95  volatile _type *_io_addr = \
96  ( ( volatile _type * ) ( intptr_t ) (io_addr) ); \
97  _type _data = (data); \
98  DBGIO ( "[" _prefix " %08lx] <= %0" #_ndigits "llx\n", \
99  io_to_bus ( _io_addr ), ( unsigned long long ) _data ); \
100  _func ( _data, _io_addr ); \
101  } while ( 0 )
102 
103 /**
104  * Wrap an I/O string read
105  *
106  * @v _func I/O API function
107  * @v _type Data type
108  * @v io_addr I/O address
109  * @v data Data buffer
110  * @v count Number of elements to read
111  * @v _prefix Prefix for address in debug message
112  * @v _ndigits Number of hex digits for this data type
113  */
114 #define IOAPI_READS( _func, _type, io_addr, data, count, _prefix, _ndigits ) \
115  do { \
116  volatile _type *_io_addr = \
117  ( ( volatile _type * ) ( intptr_t ) (io_addr) ); \
118  void *_data_void = (data); /* Check data is a pointer */ \
119  _type * _data = ( ( _type * ) _data_void ); \
120  const _type * _dbg_data = _data; \
121  unsigned int _count = (count); \
122  unsigned int _dbg_count = _count; \
123  _func ( _io_addr, _data, _count ); \
124  DBGIO ( "[" _prefix " %08lx] =>", io_to_bus ( _io_addr ) ); \
125  while ( _dbg_count-- ) { \
126  DBGIO ( " %0" #_ndigits "llx", \
127  ( ( unsigned long long ) *(_dbg_data++) ) ); \
128  } \
129  DBGIO ( "\n" ); \
130  } while ( 0 )
131 
132 /**
133  * Wrap an I/O string write
134  *
135  * @v _func I/O API function
136  * @v _type Data type
137  * @v io_addr I/O address
138  * @v data Data buffer
139  * @v count Number of elements to write
140  * @v _prefix Prefix for address in debug message
141  * @v _ndigits Number of hex digits for this data type
142  */
143 #define IOAPI_WRITES( _func, _type, io_addr, data, count, _prefix, _ndigits ) \
144  do { \
145  volatile _type *_io_addr = \
146  ( ( volatile _type * ) ( intptr_t ) (io_addr) ); \
147  const void *_data_void = (data); /* Check data is a pointer */ \
148  const _type * _data = ( ( const _type * ) _data_void ); \
149  const _type * _dbg_data = _data; \
150  unsigned int _count = (count); \
151  unsigned int _dbg_count = _count; \
152  DBGIO ( "[" _prefix " %08lx] <=", io_to_bus ( _io_addr ) ); \
153  while ( _dbg_count-- ) { \
154  DBGIO ( " %0" #_ndigits "llx", \
155  ( ( unsigned long long ) *(_dbg_data++) ) ); \
156  } \
157  DBGIO ( "\n" ); \
158  _func ( _io_addr, _data, _count ); \
159  } while ( 0 )
160 
161 /**
162  * Convert physical address to a bus address
163  *
164  * @v phys_addr Physical address
165  * @ret bus_addr Bus address
166  */
167 unsigned long phys_to_bus ( unsigned long phys_addr );
168 
169 /**
170  * Convert bus address to a physical address
171  *
172  * @v bus_addr Bus address
173  * @ret phys_addr Physical address
174  */
175 unsigned long bus_to_phys ( unsigned long bus_addr );
176 
177 /**
178  * Convert virtual address to a bus address
179  *
180  * @v addr Virtual address
181  * @ret bus_addr Bus address
182  */
183 static inline __always_inline unsigned long
184 virt_to_bus ( volatile const void *addr ) {
185  return phys_to_bus ( virt_to_phys ( addr ) );
186 }
187 
188 /**
189  * Convert bus address to a virtual address
190  *
191  * @v bus_addr Bus address
192  * @ret addr Virtual address
193  *
194  * This operation is not available under all memory models.
195  */
196 static inline __always_inline void * bus_to_virt ( unsigned long bus_addr ) {
197  return phys_to_virt ( bus_to_phys ( bus_addr ) );
198 }
199 
200 /**
201  * Read byte from memory-mapped device
202  *
203  * @v io_addr I/O address
204  * @ret data Value read
205  */
206 uint8_t readb ( volatile uint8_t *io_addr );
207 #define readb( io_addr ) IOAPI_READ ( readb, uint8_t, io_addr, "MEM", 2 )
208 
209 /**
210  * Read 16-bit word from memory-mapped device
211  *
212  * @v io_addr I/O address
213  * @ret data Value read
214  */
215 uint16_t readw ( volatile uint16_t *io_addr );
216 #define readw( io_addr ) IOAPI_READ ( readw, uint16_t, io_addr, "MEM", 4 )
217 
218 /**
219  * Read 32-bit dword from memory-mapped device
220  *
221  * @v io_addr I/O address
222  * @ret data Value read
223  */
224 uint32_t readl ( volatile uint32_t *io_addr );
225 #define readl( io_addr ) IOAPI_READ ( readl, uint32_t, io_addr, "MEM", 8 )
226 
227 /**
228  * Read 64-bit qword from memory-mapped device
229  *
230  * @v io_addr I/O address
231  * @ret data Value read
232  */
233 uint64_t readq ( volatile uint64_t *io_addr );
234 #define readq( io_addr ) IOAPI_READ ( readq, uint64_t, io_addr, "MEM", 16 )
235 
236 /**
237  * Write byte to memory-mapped device
238  *
239  * @v data Value to write
240  * @v io_addr I/O address
241  */
242 void writeb ( uint8_t data, volatile uint8_t *io_addr );
243 #define writeb( data, io_addr ) \
244  IOAPI_WRITE ( writeb, uint8_t, data, io_addr, "MEM", 2 )
245 
246 /**
247  * Write 16-bit word to memory-mapped device
248  *
249  * @v data Value to write
250  * @v io_addr I/O address
251  */
252 void writew ( uint16_t data, volatile uint16_t *io_addr );
253 #define writew( data, io_addr ) \
254  IOAPI_WRITE ( writew, uint16_t, data, io_addr, "MEM", 4 )
255 
256 /**
257  * Write 32-bit dword to memory-mapped device
258  *
259  * @v data Value to write
260  * @v io_addr I/O address
261  */
262 void writel ( uint32_t data, volatile uint32_t *io_addr );
263 #define writel( data, io_addr ) \
264  IOAPI_WRITE ( writel, uint32_t, data, io_addr, "MEM", 8 )
265 
266 /**
267  * Write 64-bit qword to memory-mapped device
268  *
269  * @v data Value to write
270  * @v io_addr I/O address
271  */
272 void writeq ( uint64_t data, volatile uint64_t *io_addr );
273 #define writeq( data, io_addr ) \
274  IOAPI_WRITE ( writeq, uint64_t, data, io_addr, "MEM", 16 )
275 
276 /**
277  * Read byte from I/O-mapped device
278  *
279  * @v io_addr I/O address
280  * @ret data Value read
281  */
282 uint8_t inb ( volatile uint8_t *io_addr );
283 #define inb( io_addr ) IOAPI_READ ( inb, uint8_t, io_addr, "IO", 2 )
284 
285 /**
286  * Read 16-bit word from I/O-mapped device
287  *
288  * @v io_addr I/O address
289  * @ret data Value read
290  */
291 uint16_t inw ( volatile uint16_t *io_addr );
292 #define inw( io_addr ) IOAPI_READ ( inw, uint16_t, io_addr, "IO", 4 )
293 
294 /**
295  * Read 32-bit dword from I/O-mapped device
296  *
297  * @v io_addr I/O address
298  * @ret data Value read
299  */
300 uint32_t inl ( volatile uint32_t *io_addr );
301 #define inl( io_addr ) IOAPI_READ ( inl, uint32_t, io_addr, "IO", 8 )
302 
303 /**
304  * Write byte to I/O-mapped device
305  *
306  * @v data Value to write
307  * @v io_addr I/O address
308  */
309 void outb ( uint8_t data, volatile uint8_t *io_addr );
310 #define outb( data, io_addr ) \
311  IOAPI_WRITE ( outb, uint8_t, data, io_addr, "IO", 2 )
312 
313 /**
314  * Write 16-bit word to I/O-mapped device
315  *
316  * @v data Value to write
317  * @v io_addr I/O address
318  */
319 void outw ( uint16_t data, volatile uint16_t *io_addr );
320 #define outw( data, io_addr ) \
321  IOAPI_WRITE ( outw, uint16_t, data, io_addr, "IO", 4 )
322 
323 /**
324  * Write 32-bit dword to I/O-mapped device
325  *
326  * @v data Value to write
327  * @v io_addr I/O address
328  */
329 void outl ( uint32_t data, volatile uint32_t *io_addr );
330 #define outl( data, io_addr ) \
331  IOAPI_WRITE ( outl, uint32_t, data, io_addr, "IO", 8 )
332 
333 /**
334  * Read byte from I/O-mapped or memory-mapped device
335  *
336  * @v io_addr I/O address
337  * @ret data Value read
338  */
339 uint8_t ioread8 ( volatile uint8_t *io_addr );
340 #define ioread8( io_addr ) \
341  IOAPI_READ ( ioread8, uint8_t, io_addr, "IO/MEM", 2 )
342 
343 /**
344  * Read 16-bit word from I/O-mapped or memory-mapped device
345  *
346  * @v io_addr I/O address
347  * @ret data Value read
348  */
349 uint16_t ioread16 ( volatile uint16_t *io_addr );
350 #define ioread16( io_addr ) \
351  IOAPI_READ ( ioread16, uint16_t, io_addr, "IO/MEM", 4 )
352 
353 /**
354  * Read 32-bit dword from I/O-mapped or memory-mapped device
355  *
356  * @v io_addr I/O address
357  * @ret data Value read
358  */
359 uint32_t ioread32 ( volatile uint32_t *io_addr );
360 #define ioread32( io_addr ) \
361  IOAPI_READ ( ioread32, uint32_t, io_addr, "IO/MEM", 8 )
362 
363 /**
364  * Write byte to I/O-mapped or memory-mapped device
365  *
366  * @v data Value to write
367  * @v io_addr I/O address
368  */
369 void iowrite8 ( uint8_t data, volatile uint8_t *io_addr );
370 #define iowrite8( data, io_addr ) \
371  IOAPI_WRITE ( iowrite8, uint8_t, data, io_addr, "IO/MEM", 2 )
372 
373 /**
374  * Write 16-bit word to I/O-mapped or memory-mapped device
375  *
376  * @v data Value to write
377  * @v io_addr I/O address
378  */
379 void iowrite16 ( uint16_t data, volatile uint16_t *io_addr );
380 #define iowrite16( data, io_addr ) \
381  IOAPI_WRITE ( iowrite16, uint16_t, data, io_addr, "IO/MEM", 4 )
382 
383 /**
384  * Write 32-bit dword to I/O-mapped or memory-mapped device
385  *
386  * @v data Value to write
387  * @v io_addr I/O address
388  */
389 void iowrite32 ( uint32_t data, volatile uint32_t *io_addr );
390 #define iowrite32( data, io_addr ) \
391  IOAPI_WRITE ( iowrite32, uint32_t, data, io_addr, "IO/MEM", 8 )
392 
393 /**
394  * Read bytes from I/O-mapped device
395  *
396  * @v io_addr I/O address
397  * @v data Data buffer
398  * @v count Number of bytes to read
399  */
400 void insb ( volatile uint8_t *io_addr, uint8_t *data, unsigned int count );
401 #define insb( io_addr, data, count ) \
402  IOAPI_READS ( insb, uint8_t, io_addr, data, count, "IO", 2 )
403 
404 /**
405  * Read 16-bit words from I/O-mapped device
406  *
407  * @v io_addr I/O address
408  * @v data Data buffer
409  * @v count Number of words to read
410  */
411 void insw ( volatile uint16_t *io_addr, uint16_t *data, unsigned int count );
412 #define insw( io_addr, data, count ) \
413  IOAPI_READS ( insw, uint16_t, io_addr, data, count, "IO", 4 )
414 
415 /**
416  * Read 32-bit words from I/O-mapped device
417  *
418  * @v io_addr I/O address
419  * @v data Data buffer
420  * @v count Number of words to read
421  */
422 void insl ( volatile uint32_t *io_addr, uint32_t *data, unsigned int count );
423 #define insl( io_addr, data, count ) \
424  IOAPI_READS ( insl, uint32_t, io_addr, data, count, "IO", 8 )
425 
426 /**
427  * Write bytes to I/O-mapped device
428  *
429  * @v io_addr I/O address
430  * @v data Data buffer
431  * @v count Number of bytes to write
432  */
433 void outsb ( volatile uint8_t *io_addr, const uint8_t *data,
434  unsigned int count );
435 #define outsb( io_addr, data, count ) \
436  IOAPI_WRITES ( outsb, uint8_t, io_addr, data, count, "IO", 2 )
437 
438 /**
439  * Write 16-bit words to I/O-mapped device
440  *
441  * @v io_addr I/O address
442  * @v data Data buffer
443  * @v count Number of words to write
444  */
445 void outsw ( volatile uint16_t *io_addr, const uint16_t *data,
446  unsigned int count );
447 #define outsw( io_addr, data, count ) \
448  IOAPI_WRITES ( outsw, uint16_t, io_addr, data, count, "IO", 4 )
449 
450 /**
451  * Write 32-bit words to I/O-mapped device
452  *
453  * @v io_addr I/O address
454  * @v data Data buffer
455  * @v count Number of words to write
456  */
457 void outsl ( volatile uint32_t *io_addr, const uint32_t *data,
458  unsigned int count );
459 #define outsl( io_addr, data, count ) \
460  IOAPI_WRITES ( outsl, uint32_t, io_addr, data, count, "IO", 8 )
461 
462 /**
463  * Slow down I/O
464  *
465  */
466 void iodelay ( void );
467 
468 /**
469  * Read value from I/O-mapped device, slowly
470  *
471  * @v _func Function to use to read value
472  * @v data Value to write
473  * @v io_addr I/O address
474  */
475 #define INX_P( _func, _type, io_addr ) ( { \
476  _type _data = _func ( (io_addr) ); \
477  iodelay(); \
478  _data; } )
479 
480 /**
481  * Read byte from I/O-mapped device
482  *
483  * @v io_addr I/O address
484  * @ret data Value read
485  */
486 #define inb_p( io_addr ) INX_P ( inb, uint8_t, io_addr )
487 
488 /**
489  * Read 16-bit word from I/O-mapped device
490  *
491  * @v io_addr I/O address
492  * @ret data Value read
493  */
494 #define inw_p( io_addr ) INX_P ( inw, uint16_t, io_addr )
495 
496 /**
497  * Read 32-bit dword from I/O-mapped device
498  *
499  * @v io_addr I/O address
500  * @ret data Value read
501  */
502 #define inl_p( io_addr ) INX_P ( inl, uint32_t, io_addr )
503 
504 /**
505  * Write value to I/O-mapped device, slowly
506  *
507  * @v _func Function to use to write value
508  * @v data Value to write
509  * @v io_addr I/O address
510  */
511 #define OUTX_P( _func, data, io_addr ) do { \
512  _func ( (data), (io_addr) ); \
513  iodelay(); \
514  } while ( 0 )
515 
516 /**
517  * Write byte to I/O-mapped device, slowly
518  *
519  * @v data Value to write
520  * @v io_addr I/O address
521  */
522 #define outb_p( data, io_addr ) OUTX_P ( outb, data, io_addr )
523 
524 /**
525  * Write 16-bit word to I/O-mapped device, slowly
526  *
527  * @v data Value to write
528  * @v io_addr I/O address
529  */
530 #define outw_p( data, io_addr ) OUTX_P ( outw, data, io_addr )
531 
532 /**
533  * Write 32-bit dword to I/O-mapped device, slowly
534  *
535  * @v data Value to write
536  * @v io_addr I/O address
537  */
538 #define outl_p( data, io_addr ) OUTX_P ( outl, data, io_addr )
539 
540 /**
541  * Memory barrier
542  *
543  */
544 void mb ( void );
545 #define rmb() mb()
546 #define wmb() mb()
547 
548 #endif /* _IPXE_IO_H */
x86-specific I/O API implementations
unsigned short uint16_t
Definition: stdint.h:11
#define outsl(io_addr, data, count)
Definition: io.h:459
iPXE internal APIs
#define writel(data, io_addr)
Definition: io.h:263
#define outw(data, io_addr)
Definition: io.h:320
#define iowrite16(data, io_addr)
Definition: io.h:380
#define ioread32(io_addr)
Definition: io.h:360
unsigned long long uint64_t
Definition: stdint.h:13
#define writeq(data, io_addr)
Definition: io.h:273
#define insw(io_addr, data, count)
Definition: io.h:412
static __always_inline void unsigned long bus_addr
Definition: pcibios.h:156
static __always_inline void * bus_to_virt(unsigned long bus_addr)
Convert bus address to a virtual address.
Definition: io.h:196
#define inw(io_addr)
Definition: io.h:292
static __always_inline unsigned long virt_to_bus(volatile const void *addr)
Convert virtual address to a bus address.
Definition: io.h:184
#define ioread8(io_addr)
Definition: io.h:340
#define readb(io_addr)
Definition: io.h:207
static unsigned int count
Number of entries.
Definition: dwmac.h:225
#define readl(io_addr)
Definition: io.h:225
#define writew(data, io_addr)
Definition: io.h:253
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
#define readw(io_addr)
Definition: io.h:216
#define outl(data, io_addr)
Definition: io.h:330
#define outsw(io_addr, data, count)
Definition: io.h:447
#define __always_inline
Declare a function to be always inline.
Definition: compiler.h:611
uint32_t addr
Buffer address.
Definition: dwmac.h:20
#define iowrite32(data, io_addr)
Definition: io.h:390
unsigned char uint8_t
Definition: stdint.h:10
#define readq(io_addr)
Definition: io.h:234
unsigned int uint32_t
Definition: stdint.h:12
unsigned long phys_to_bus(unsigned long phys_addr)
Convert physical address to a bus address.
#define insb(io_addr, data, count)
Definition: io.h:401
I/O API configuration.
#define outb(data, io_addr)
Definition: io.h:310
#define iowrite8(data, io_addr)
Definition: io.h:370
#define inb(io_addr)
Definition: io.h:283
#define ioread16(io_addr)
Definition: io.h:350
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define insl(io_addr, data, count)
Definition: io.h:423
#define writeb(data, io_addr)
Definition: io.h:243
FILE_SECBOOT(PERMITTED)
void mb(void)
Memory barrier.
void iodelay(void)
Slow down I/O.
unsigned long bus_to_phys(unsigned long bus_addr)
Convert bus address to a physical address.
#define inl(io_addr)
Definition: io.h:301
#define outsb(io_addr, data, count)
Definition: io.h:435
iPXE I/O mapping API