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 
21 #include <stdint.h>
22 #include <ipxe/api.h>
23 #include <ipxe/iomap.h>
24 #include <config/ioapi.h>
25 
26 /** Page size */
27 #define PAGE_SIZE ( 1 << PAGE_SHIFT )
28 
29 /** Page mask */
30 #define PAGE_MASK ( PAGE_SIZE - 1 )
31 
32 /**
33  * Calculate static inline I/O API function name
34  *
35  * @v _prefix Subsystem prefix
36  * @v _api_func API function
37  * @ret _subsys_func Subsystem API function
38  */
39 #define IOAPI_INLINE( _subsys, _api_func ) \
40  SINGLE_API_INLINE ( IOAPI_PREFIX_ ## _subsys, _api_func )
41 
42 /**
43  * Provide an I/O API implementation
44  *
45  * @v _prefix Subsystem prefix
46  * @v _api_func API function
47  * @v _func Implementing function
48  */
49 #define PROVIDE_IOAPI( _subsys, _api_func, _func ) \
50  PROVIDE_SINGLE_API ( IOAPI_PREFIX_ ## _subsys, _api_func, _func )
51 
52 /**
53  * Provide a static inline I/O API implementation
54  *
55  * @v _prefix Subsystem prefix
56  * @v _api_func API function
57  */
58 #define PROVIDE_IOAPI_INLINE( _subsys, _api_func ) \
59  PROVIDE_SINGLE_API_INLINE ( IOAPI_PREFIX_ ## _subsys, _api_func )
60 
61 /* Include all architecture-independent I/O API headers */
62 
63 /* Include all architecture-dependent I/O API headers */
64 #include <bits/io.h>
65 
66 /**
67  * Wrap an I/O read
68  *
69  * @v _func I/O API function
70  * @v _type Data type
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
74  */
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 ); \
81  _data; } )
82 
83 /**
84  * Wrap an I/O write
85  *
86  * @v _func I/O API function
87  * @v _type Data type
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
92  */
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 ); \
100  } while ( 0 )
101 
102 /**
103  * Wrap an I/O string read
104  *
105  * @v _func I/O API function
106  * @v _type Data type
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
112  */
113 #define IOAPI_READS( _func, _type, io_addr, data, count, _prefix, _ndigits ) \
114  do { \
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++) ) ); \
127  } \
128  DBGIO ( "\n" ); \
129  } while ( 0 )
130 
131 /**
132  * Wrap an I/O string write
133  *
134  * @v _func I/O API function
135  * @v _type Data type
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
141  */
142 #define IOAPI_WRITES( _func, _type, io_addr, data, count, _prefix, _ndigits ) \
143  do { \
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++) ) ); \
155  } \
156  DBGIO ( "\n" ); \
157  _func ( _io_addr, _data, _count ); \
158  } while ( 0 )
159 
160 /**
161  * Convert physical address to a bus address
162  *
163  * @v phys_addr Physical address
164  * @ret bus_addr Bus address
165  */
166 unsigned long phys_to_bus ( unsigned long phys_addr );
167 
168 /**
169  * Convert bus address to a physical address
170  *
171  * @v bus_addr Bus address
172  * @ret phys_addr Physical address
173  */
174 unsigned long bus_to_phys ( unsigned long bus_addr );
175 
176 /**
177  * Convert virtual address to a bus address
178  *
179  * @v addr Virtual address
180  * @ret bus_addr Bus address
181  */
182 static inline __always_inline unsigned long
183 virt_to_bus ( volatile const void *addr ) {
184  return phys_to_bus ( virt_to_phys ( addr ) );
185 }
186 
187 /**
188  * Convert bus address to a virtual address
189  *
190  * @v bus_addr Bus address
191  * @ret addr Virtual address
192  *
193  * This operation is not available under all memory models.
194  */
195 static inline __always_inline void * bus_to_virt ( unsigned long bus_addr ) {
196  return phys_to_virt ( bus_to_phys ( bus_addr ) );
197 }
198 
199 /**
200  * Read byte from memory-mapped device
201  *
202  * @v io_addr I/O address
203  * @ret data Value read
204  */
205 uint8_t readb ( volatile uint8_t *io_addr );
206 #define readb( io_addr ) IOAPI_READ ( readb, uint8_t, io_addr, "MEM", 2 )
207 
208 /**
209  * Read 16-bit word from memory-mapped device
210  *
211  * @v io_addr I/O address
212  * @ret data Value read
213  */
214 uint16_t readw ( volatile uint16_t *io_addr );
215 #define readw( io_addr ) IOAPI_READ ( readw, uint16_t, io_addr, "MEM", 4 )
216 
217 /**
218  * Read 32-bit dword from memory-mapped device
219  *
220  * @v io_addr I/O address
221  * @ret data Value read
222  */
223 uint32_t readl ( volatile uint32_t *io_addr );
224 #define readl( io_addr ) IOAPI_READ ( readl, uint32_t, io_addr, "MEM", 8 )
225 
226 /**
227  * Read 64-bit qword from memory-mapped device
228  *
229  * @v io_addr I/O address
230  * @ret data Value read
231  */
232 uint64_t readq ( volatile uint64_t *io_addr );
233 #define readq( io_addr ) IOAPI_READ ( readq, uint64_t, io_addr, "MEM", 16 )
234 
235 /**
236  * Write byte to memory-mapped device
237  *
238  * @v data Value to write
239  * @v io_addr I/O address
240  */
241 void writeb ( uint8_t data, volatile uint8_t *io_addr );
242 #define writeb( data, io_addr ) \
243  IOAPI_WRITE ( writeb, uint8_t, data, io_addr, "MEM", 2 )
244 
245 /**
246  * Write 16-bit word to memory-mapped device
247  *
248  * @v data Value to write
249  * @v io_addr I/O address
250  */
251 void writew ( uint16_t data, volatile uint16_t *io_addr );
252 #define writew( data, io_addr ) \
253  IOAPI_WRITE ( writew, uint16_t, data, io_addr, "MEM", 4 )
254 
255 /**
256  * Write 32-bit dword to memory-mapped device
257  *
258  * @v data Value to write
259  * @v io_addr I/O address
260  */
261 void writel ( uint32_t data, volatile uint32_t *io_addr );
262 #define writel( data, io_addr ) \
263  IOAPI_WRITE ( writel, uint32_t, data, io_addr, "MEM", 8 )
264 
265 /**
266  * Write 64-bit qword to memory-mapped device
267  *
268  * @v data Value to write
269  * @v io_addr I/O address
270  */
271 void writeq ( uint64_t data, volatile uint64_t *io_addr );
272 #define writeq( data, io_addr ) \
273  IOAPI_WRITE ( writeq, uint64_t, data, io_addr, "MEM", 16 )
274 
275 /**
276  * Read byte from I/O-mapped device
277  *
278  * @v io_addr I/O address
279  * @ret data Value read
280  */
281 uint8_t inb ( volatile uint8_t *io_addr );
282 #define inb( io_addr ) IOAPI_READ ( inb, uint8_t, io_addr, "IO", 2 )
283 
284 /**
285  * Read 16-bit word from I/O-mapped device
286  *
287  * @v io_addr I/O address
288  * @ret data Value read
289  */
290 uint16_t inw ( volatile uint16_t *io_addr );
291 #define inw( io_addr ) IOAPI_READ ( inw, uint16_t, io_addr, "IO", 4 )
292 
293 /**
294  * Read 32-bit dword from I/O-mapped device
295  *
296  * @v io_addr I/O address
297  * @ret data Value read
298  */
299 uint32_t inl ( volatile uint32_t *io_addr );
300 #define inl( io_addr ) IOAPI_READ ( inl, uint32_t, io_addr, "IO", 8 )
301 
302 /**
303  * Write byte to I/O-mapped device
304  *
305  * @v data Value to write
306  * @v io_addr I/O address
307  */
308 void outb ( uint8_t data, volatile uint8_t *io_addr );
309 #define outb( data, io_addr ) \
310  IOAPI_WRITE ( outb, uint8_t, data, io_addr, "IO", 2 )
311 
312 /**
313  * Write 16-bit word to I/O-mapped device
314  *
315  * @v data Value to write
316  * @v io_addr I/O address
317  */
318 void outw ( uint16_t data, volatile uint16_t *io_addr );
319 #define outw( data, io_addr ) \
320  IOAPI_WRITE ( outw, uint16_t, data, io_addr, "IO", 4 )
321 
322 /**
323  * Write 32-bit dword to I/O-mapped device
324  *
325  * @v data Value to write
326  * @v io_addr I/O address
327  */
328 void outl ( uint32_t data, volatile uint32_t *io_addr );
329 #define outl( data, io_addr ) \
330  IOAPI_WRITE ( outl, uint32_t, data, io_addr, "IO", 8 )
331 
332 /**
333  * Read bytes from I/O-mapped device
334  *
335  * @v io_addr I/O address
336  * @v data Data buffer
337  * @v count Number of bytes to read
338  */
339 void insb ( volatile uint8_t *io_addr, uint8_t *data, unsigned int count );
340 #define insb( io_addr, data, count ) \
341  IOAPI_READS ( insb, uint8_t, io_addr, data, count, "IO", 2 )
342 
343 /**
344  * Read 16-bit words from I/O-mapped device
345  *
346  * @v io_addr I/O address
347  * @v data Data buffer
348  * @v count Number of words to read
349  */
350 void insw ( volatile uint16_t *io_addr, uint16_t *data, unsigned int count );
351 #define insw( io_addr, data, count ) \
352  IOAPI_READS ( insw, uint16_t, io_addr, data, count, "IO", 4 )
353 
354 /**
355  * Read 32-bit words from I/O-mapped device
356  *
357  * @v io_addr I/O address
358  * @v data Data buffer
359  * @v count Number of words to read
360  */
361 void insl ( volatile uint32_t *io_addr, uint32_t *data, unsigned int count );
362 #define insl( io_addr, data, count ) \
363  IOAPI_READS ( insl, uint32_t, io_addr, data, count, "IO", 8 )
364 
365 /**
366  * Write bytes to I/O-mapped device
367  *
368  * @v io_addr I/O address
369  * @v data Data buffer
370  * @v count Number of bytes to write
371  */
372 void outsb ( volatile uint8_t *io_addr, const uint8_t *data,
373  unsigned int count );
374 #define outsb( io_addr, data, count ) \
375  IOAPI_WRITES ( outsb, uint8_t, io_addr, data, count, "IO", 2 )
376 
377 /**
378  * Write 16-bit words to I/O-mapped device
379  *
380  * @v io_addr I/O address
381  * @v data Data buffer
382  * @v count Number of words to write
383  */
384 void outsw ( volatile uint16_t *io_addr, const uint16_t *data,
385  unsigned int count );
386 #define outsw( io_addr, data, count ) \
387  IOAPI_WRITES ( outsw, uint16_t, io_addr, data, count, "IO", 4 )
388 
389 /**
390  * Write 32-bit words to I/O-mapped device
391  *
392  * @v io_addr I/O address
393  * @v data Data buffer
394  * @v count Number of words to write
395  */
396 void outsl ( volatile uint32_t *io_addr, const uint32_t *data,
397  unsigned int count );
398 #define outsl( io_addr, data, count ) \
399  IOAPI_WRITES ( outsl, uint32_t, io_addr, data, count, "IO", 8 )
400 
401 /**
402  * Slow down I/O
403  *
404  */
405 void iodelay ( void );
406 
407 /**
408  * Read value from I/O-mapped device, slowly
409  *
410  * @v _func Function to use to read value
411  * @v data Value to write
412  * @v io_addr I/O address
413  */
414 #define INX_P( _func, _type, io_addr ) ( { \
415  _type _data = _func ( (io_addr) ); \
416  iodelay(); \
417  _data; } )
418 
419 /**
420  * Read byte from I/O-mapped device
421  *
422  * @v io_addr I/O address
423  * @ret data Value read
424  */
425 #define inb_p( io_addr ) INX_P ( inb, uint8_t, io_addr )
426 
427 /**
428  * Read 16-bit word from I/O-mapped device
429  *
430  * @v io_addr I/O address
431  * @ret data Value read
432  */
433 #define inw_p( io_addr ) INX_P ( inw, uint16_t, io_addr )
434 
435 /**
436  * Read 32-bit dword from I/O-mapped device
437  *
438  * @v io_addr I/O address
439  * @ret data Value read
440  */
441 #define inl_p( io_addr ) INX_P ( inl, uint32_t, io_addr )
442 
443 /**
444  * Write value to I/O-mapped device, slowly
445  *
446  * @v _func Function to use to write value
447  * @v data Value to write
448  * @v io_addr I/O address
449  */
450 #define OUTX_P( _func, data, io_addr ) do { \
451  _func ( (data), (io_addr) ); \
452  iodelay(); \
453  } while ( 0 )
454 
455 /**
456  * Write byte to I/O-mapped device, slowly
457  *
458  * @v data Value to write
459  * @v io_addr I/O address
460  */
461 #define outb_p( data, io_addr ) OUTX_P ( outb, data, io_addr )
462 
463 /**
464  * Write 16-bit word to I/O-mapped device, slowly
465  *
466  * @v data Value to write
467  * @v io_addr I/O address
468  */
469 #define outw_p( data, io_addr ) OUTX_P ( outw, data, io_addr )
470 
471 /**
472  * Write 32-bit dword to I/O-mapped device, slowly
473  *
474  * @v data Value to write
475  * @v io_addr I/O address
476  */
477 #define outl_p( data, io_addr ) OUTX_P ( outl, data, io_addr )
478 
479 /**
480  * Memory barrier
481  *
482  */
483 void mb ( void );
484 #define rmb() mb()
485 #define wmb() mb()
486 
487 /** A usable memory region */
489  /** Physical start address */
491  /** Physical end address */
493 };
494 
495 /** Maximum number of memory regions we expect to encounter */
496 #define MAX_MEMORY_REGIONS 8
497 
498 /** A memory map */
499 struct memory_map {
500  /** Memory regions */
502  /** Number of used regions */
503  unsigned int count;
504 };
505 
506 /**
507  * Get memory map
508  *
509  * @v memmap Memory map to fill in
510  */
511 void get_memmap ( struct memory_map *memmap );
512 
513 #endif /* _IPXE_IO_H */
x86-specific I/O API implementations
unsigned short uint16_t
Definition: stdint.h:11
void get_memmap(struct memory_map *memmap)
Get memory map.
#define outsl(io_addr, data, count)
Definition: io.h:398
iPXE internal APIs
#define writel(data, io_addr)
Definition: io.h:262
#define outw(data, io_addr)
Definition: io.h:319
unsigned int count
Number of used regions.
Definition: io.h:503
unsigned long long uint64_t
Definition: stdint.h:13
#define writeq(data, io_addr)
Definition: io.h:272
A memory map.
Definition: io.h:499
#define insw(io_addr, data, count)
Definition: io.h:351
static __always_inline unsigned long virt_to_phys(volatile const void *addr)
Convert virtual address to a physical address.
Definition: uaccess.h:287
static __always_inline void * bus_to_virt(unsigned long bus_addr)
Convert bus address to a virtual address.
Definition: io.h:195
#define inw(io_addr)
Definition: io.h:291
#define MAX_MEMORY_REGIONS
Maximum number of memory regions we expect to encounter.
Definition: io.h:496
struct memory_region regions[MAX_MEMORY_REGIONS]
Memory regions.
Definition: io.h:501
static __always_inline void * phys_to_virt(unsigned long phys_addr)
Convert physical address to a virtual address.
Definition: uaccess.h:299
static __always_inline unsigned long virt_to_bus(volatile const void *addr)
Convert virtual address to a bus address.
Definition: io.h:183
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
#define readb(io_addr)
Definition: io.h:206
#define readl(io_addr)
Definition: io.h:224
#define writew(data, io_addr)
Definition: io.h:252
#define readw(io_addr)
Definition: io.h:215
#define outl(data, io_addr)
Definition: io.h:329
#define outsw(io_addr, data, count)
Definition: io.h:386
#define __always_inline
Declare a function to be always inline.
Definition: compiler.h:611
u32 addr
Definition: sky2.h:8
unsigned char uint8_t
Definition: stdint.h:10
#define readq(io_addr)
Definition: io.h:233
A usable memory region.
Definition: io.h:488
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:340
I/O API configuration.
#define outb(data, io_addr)
Definition: io.h:309
uint64_t start
Physical start address.
Definition: io.h:490
#define inb(io_addr)
Definition: io.h:282
uint16_t count
Number of entries.
Definition: ena.h:22
#define insl(io_addr, data, count)
Definition: io.h:362
#define writeb(data, io_addr)
Definition: io.h:242
void mb(void)
Memory barrier.
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
void iodelay(void)
Slow down I/O.
uint64_t end
Physical end address.
Definition: io.h:492
unsigned long bus_to_phys(unsigned long bus_addr)
Convert bus address to a physical address.
#define inl(io_addr)
Definition: io.h:300
#define outsb(io_addr, data, count)
Definition: io.h:374
iPXE I/O mapping API