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
19FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
20FILE_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 */
167unsigned 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 */
175unsigned 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 */
183static inline __always_inline unsigned long
184virt_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 */
196static 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 */
206uint8_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 */
215uint16_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 */
224uint32_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 */
233uint64_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 */
242void 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 */
252void 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 */
262void 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 */
272void 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 */
282uint8_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 */
291uint16_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 */
300uint32_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 */
309void 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 */
319void 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 */
329void 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 */
339uint8_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 */
349uint16_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 */
359uint32_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 */
369void 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 */
379void 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 */
389void 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 */
400void 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 */
411void 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 */
422void 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 */
433void 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 */
445void 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 */
457void 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 */
466void 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 */
544void mb ( void );
545#define rmb() mb()
546#define wmb() mb()
547
548#endif /* _IPXE_IO_H */
iPXE internal APIs
unsigned short uint16_t
Definition stdint.h:11
unsigned int uint32_t
Definition stdint.h:12
unsigned long long uint64_t
Definition stdint.h:13
unsigned char uint8_t
Definition stdint.h:10
x86-specific I/O API implementations
uint32_t addr
Buffer address.
Definition dwmac.h:9
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define __always_inline
Declare a function to be always inline.
Definition compiler.h:611
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define inw(io_addr)
Definition io.h:292
#define outb(data, io_addr)
Definition io.h:310
#define ioread16(io_addr)
Definition io.h:350
#define writeb(data, io_addr)
Definition io.h:243
static __always_inline void * bus_to_virt(unsigned long bus_addr)
Convert bus address to a virtual address.
Definition io.h:196
void mb(void)
Memory barrier.
#define outw(data, io_addr)
Definition io.h:320
unsigned long phys_to_bus(unsigned long phys_addr)
Convert physical address to a bus address.
#define inl(io_addr)
Definition io.h:301
#define insw(io_addr, data, count)
Definition io.h:412
#define readb(io_addr)
Definition io.h:207
#define outl(data, io_addr)
Definition io.h:330
void iodelay(void)
Slow down I/O.
#define outsl(io_addr, data, count)
Definition io.h:459
#define inb(io_addr)
Definition io.h:283
#define insb(io_addr, data, count)
Definition io.h:401
unsigned long bus_to_phys(unsigned long bus_addr)
Convert bus address to a physical address.
#define readq(io_addr)
Definition io.h:234
static __always_inline unsigned long virt_to_bus(volatile const void *addr)
Convert virtual address to a bus address.
Definition io.h:184
#define insl(io_addr, data, count)
Definition io.h:423
#define outsw(io_addr, data, count)
Definition io.h:447
#define outsb(io_addr, data, count)
Definition io.h:435
#define readw(io_addr)
Definition io.h:216
#define writel(data, io_addr)
Definition io.h:263
#define ioread32(io_addr)
Definition io.h:360
#define iowrite8(data, io_addr)
Definition io.h:370
#define iowrite16(data, io_addr)
Definition io.h:380
#define readl(io_addr)
Definition io.h:225
#define writew(data, io_addr)
Definition io.h:253
#define writeq(data, io_addr)
Definition io.h:273
#define ioread8(io_addr)
Definition io.h:340
#define iowrite32(data, io_addr)
Definition io.h:390
iPXE I/O mapping API
I/O API configuration.
static __always_inline void unsigned long bus_addr
Definition pcibios.h:156