• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _GPXE_IO_H
2 #define _GPXE_IO_H
3 
4 /** @file
5  *
6  * gPXE 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 );
20 
21 #include <stdint.h>
22 #include <gpxe/api.h>
23 #include <config/ioapi.h>
24 #include <gpxe/uaccess.h>
25 
26 /**
27  * Calculate static inline I/O API function name
28  *
29  * @v _prefix		Subsystem prefix
30  * @v _api_func		API function
31  * @ret _subsys_func	Subsystem API function
32  */
33 #define IOAPI_INLINE( _subsys, _api_func ) \
34 	SINGLE_API_INLINE ( IOAPI_PREFIX_ ## _subsys, _api_func )
35 
36 /**
37  * Provide an I/O API implementation
38  *
39  * @v _prefix		Subsystem prefix
40  * @v _api_func		API function
41  * @v _func		Implementing function
42  */
43 #define PROVIDE_IOAPI( _subsys, _api_func, _func ) \
44 	PROVIDE_SINGLE_API ( IOAPI_PREFIX_ ## _subsys, _api_func, _func )
45 
46 /**
47  * Provide a static inline I/O API implementation
48  *
49  * @v _prefix		Subsystem prefix
50  * @v _api_func		API function
51  */
52 #define PROVIDE_IOAPI_INLINE( _subsys, _api_func ) \
53 	PROVIDE_SINGLE_API_INLINE ( IOAPI_PREFIX_ ## _subsys, _api_func )
54 
55 /* Include all architecture-independent I/O API headers */
56 #include <gpxe/efi/efi_io.h>
57 
58 /* Include all architecture-dependent I/O API headers */
59 #include <bits/io.h>
60 
61 /**
62  * Wrap an I/O read
63  *
64  * @v _func		I/O API function
65  * @v _type		Data type
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
69  */
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 );	      \
76 	_data; } )
77 
78 /**
79  * Wrap an I/O write
80  *
81  * @v _func		I/O API function
82  * @v _type		Data type
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
87  */
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 );					      \
95 	} while ( 0 )
96 
97 /**
98  * Wrap an I/O string read
99  *
100  * @v _func		I/O API function
101  * @v _type		Data type
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
107  */
108 #define IOAPI_READS( _func, _type, io_addr, data, count, _prefix, _ndigits )  \
109 	do {								      \
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++) ) );	      \
122 	}								      \
123 	DBGIO ( "\n" );							      \
124 	} while ( 0 )
125 
126 /**
127  * Wrap an I/O string write
128  *
129  * @v _func		I/O API function
130  * @v _type		Data type
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
136  */
137 #define IOAPI_WRITES( _func, _type, io_addr, data, count, _prefix, _ndigits ) \
138 	do {								      \
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++) ) );	      \
150 	}								      \
151 	DBGIO ( "\n" );							      \
152 	_func ( _io_addr, _data, _count );				      \
153 	} while ( 0 )
154 
155 /**
156  * Convert physical address to a bus address
157  *
158  * @v phys_addr		Physical address
159  * @ret bus_addr	Bus address
160  */
161 unsigned long phys_to_bus ( unsigned long phys_addr );
162 
163 /**
164  * Convert bus address to a physical address
165  *
166  * @v bus_addr		Bus address
167  * @ret phys_addr	Physical address
168  */
169 unsigned long bus_to_phys ( unsigned long bus_addr );
170 
171 /**
172  * Convert virtual address to a bus address
173  *
174  * @v addr		Virtual address
175  * @ret bus_addr	Bus address
176  */
177 static inline __always_inline unsigned long
virt_to_bus(volatile const void * addr)178 virt_to_bus ( volatile const void *addr ) {
179 	return phys_to_bus ( virt_to_phys ( addr ) );
180 }
181 
182 /**
183  * Convert bus address to a virtual address
184  *
185  * @v bus_addr		Bus address
186  * @ret addr		Virtual address
187  *
188  * This operation is not available under all memory models.
189  */
bus_to_virt(unsigned long bus_addr)190 static inline __always_inline void * bus_to_virt ( unsigned long bus_addr ) {
191 	return phys_to_virt ( bus_to_phys ( bus_addr ) );
192 }
193 
194 /**
195  * Map bus address as an I/O address
196  *
197  * @v bus_addr		Bus address
198  * @v len		Length of region
199  * @ret io_addr		I/O address
200  */
201 void * ioremap ( unsigned long bus_addr, size_t len );
202 
203 /**
204  * Unmap I/O address
205  *
206  * @v io_addr		I/O address
207  */
208 void iounmap ( volatile const void *io_addr );
209 
210 /**
211  * Convert I/O address to bus address (for debug only)
212  *
213  * @v io_addr		I/O address
214  * @ret bus_addr	Bus address
215  */
216 unsigned long io_to_bus ( volatile const void *io_addr );
217 
218 /**
219  * Read byte from memory-mapped device
220  *
221  * @v io_addr		I/O address
222  * @ret data		Value read
223  */
224 uint8_t readb ( volatile uint8_t *io_addr );
225 #define readb( io_addr ) IOAPI_READ ( readb, uint8_t, io_addr, "MEM", 2 )
226 
227 /**
228  * Read 16-bit word from memory-mapped device
229  *
230  * @v io_addr		I/O address
231  * @ret data		Value read
232  */
233 uint16_t readw ( volatile uint16_t *io_addr );
234 #define readw( io_addr ) IOAPI_READ ( readw, uint16_t, io_addr, "MEM", 4 )
235 
236 /**
237  * Read 32-bit dword from memory-mapped device
238  *
239  * @v io_addr		I/O address
240  * @ret data		Value read
241  */
242 uint32_t readl ( volatile uint32_t *io_addr );
243 #define readl( io_addr ) IOAPI_READ ( readl, uint32_t, io_addr, "MEM", 8 )
244 
245 /**
246  * Read 64-bit qword from memory-mapped device
247  *
248  * @v io_addr		I/O address
249  * @ret data		Value read
250  */
251 uint64_t readq ( volatile uint64_t *io_addr );
252 #define readq( io_addr ) IOAPI_READ ( readq, uint64_t, io_addr, "MEM", 16 )
253 
254 /**
255  * Write byte to memory-mapped device
256  *
257  * @v data		Value to write
258  * @v io_addr		I/O address
259  */
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 )
263 
264 /**
265  * Write 16-bit word to memory-mapped device
266  *
267  * @v data		Value to write
268  * @v io_addr		I/O address
269  */
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 )
273 
274 /**
275  * Write 32-bit dword to memory-mapped device
276  *
277  * @v data		Value to write
278  * @v io_addr		I/O address
279  */
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 )
283 
284 /**
285  * Write 64-bit qword to memory-mapped device
286  *
287  * @v data		Value to write
288  * @v io_addr		I/O address
289  */
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 )
293 
294 /**
295  * Read byte from I/O-mapped device
296  *
297  * @v io_addr		I/O address
298  * @ret data		Value read
299  */
300 uint8_t inb ( volatile uint8_t *io_addr );
301 #define inb( io_addr ) IOAPI_READ ( inb, uint8_t, io_addr, "IO", 2 )
302 
303 /**
304  * Read 16-bit word from I/O-mapped device
305  *
306  * @v io_addr		I/O address
307  * @ret data		Value read
308  */
309 uint16_t inw ( volatile uint16_t *io_addr );
310 #define inw( io_addr ) IOAPI_READ ( inw, uint16_t, io_addr, "IO", 4 )
311 
312 /**
313  * Read 32-bit dword from I/O-mapped device
314  *
315  * @v io_addr		I/O address
316  * @ret data		Value read
317  */
318 uint32_t inl ( volatile uint32_t *io_addr );
319 #define inl( io_addr ) IOAPI_READ ( inl, uint32_t, io_addr, "IO", 8 )
320 
321 /**
322  * Write byte to I/O-mapped device
323  *
324  * @v data		Value to write
325  * @v io_addr		I/O address
326  */
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 )
330 
331 /**
332  * Write 16-bit word to I/O-mapped device
333  *
334  * @v data		Value to write
335  * @v io_addr		I/O address
336  */
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 )
340 
341 /**
342  * Write 32-bit dword to I/O-mapped device
343  *
344  * @v data		Value to write
345  * @v io_addr		I/O address
346  */
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 )
350 
351 /**
352  * Read bytes from I/O-mapped device
353  *
354  * @v io_addr		I/O address
355  * @v data		Data buffer
356  * @v count		Number of bytes to read
357  */
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 )
361 
362 /**
363  * Read 16-bit words from I/O-mapped device
364  *
365  * @v io_addr		I/O address
366  * @v data		Data buffer
367  * @v count		Number of words to read
368  */
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 )
372 
373 /**
374  * Read 32-bit words from I/O-mapped device
375  *
376  * @v io_addr		I/O address
377  * @v data		Data buffer
378  * @v count		Number of words to read
379  */
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 )
383 
384 /**
385  * Write bytes to I/O-mapped device
386  *
387  * @v io_addr		I/O address
388  * @v data		Data buffer
389  * @v count		Number of bytes to write
390  */
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 )
395 
396 /**
397  * Write 16-bit words to I/O-mapped device
398  *
399  * @v io_addr		I/O address
400  * @v data		Data buffer
401  * @v count		Number of words to write
402  */
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 )
407 
408 /**
409  * Write 32-bit words to I/O-mapped device
410  *
411  * @v io_addr		I/O address
412  * @v data		Data buffer
413  * @v count		Number of words to write
414  */
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 )
419 
420 /**
421  * Slow down I/O
422  *
423  */
424 void iodelay ( void );
425 
426 /**
427  * Read value from I/O-mapped device, slowly
428  *
429  * @v _func		Function to use to read value
430  * @v data		Value to write
431  * @v io_addr		I/O address
432  */
433 #define INX_P( _func, _type, io_addr ) ( {				      \
434 	_type _data = _func ( (io_addr) );				      \
435 	iodelay();							      \
436 	_data; } )
437 
438 /**
439  * Read byte from I/O-mapped device
440  *
441  * @v io_addr		I/O address
442  * @ret data		Value read
443  */
444 #define inb_p( io_addr ) INX_P ( inb, uint8_t, io_addr )
445 
446 /**
447  * Read 16-bit word from I/O-mapped device
448  *
449  * @v io_addr		I/O address
450  * @ret data		Value read
451  */
452 #define inw_p( io_addr ) INX_P ( inw, uint16_t, io_addr )
453 
454 /**
455  * Read 32-bit dword from I/O-mapped device
456  *
457  * @v io_addr		I/O address
458  * @ret data		Value read
459  */
460 #define inl_p( io_addr ) INX_P ( inl, uint32_t, io_addr )
461 
462 /**
463  * Write value to I/O-mapped device, slowly
464  *
465  * @v _func		Function to use to write value
466  * @v data		Value to write
467  * @v io_addr		I/O address
468  */
469 #define OUTX_P( _func, data, io_addr ) do {				      \
470 	_func ( (data), (io_addr) );					      \
471 	iodelay();							      \
472 	} while ( 0 )
473 
474 /**
475  * Write byte to I/O-mapped device, slowly
476  *
477  * @v data		Value to write
478  * @v io_addr		I/O address
479  */
480 #define outb_p( data, io_addr ) OUTX_P ( outb, data, io_addr )
481 
482 /**
483  * Write 16-bit word to I/O-mapped device, slowly
484  *
485  * @v data		Value to write
486  * @v io_addr		I/O address
487  */
488 #define outw_p( data, io_addr ) OUTX_P ( outw, data, io_addr )
489 
490 /**
491  * Write 32-bit dword to I/O-mapped device, slowly
492  *
493  * @v data		Value to write
494  * @v io_addr		I/O address
495  */
496 #define outl_p( data, io_addr ) OUTX_P ( outl, data, io_addr )
497 
498 /**
499  * Memory barrier
500  *
501  */
502 void mb ( void );
503 #define rmb()	mb()
504 #define wmb()	mb()
505 
506 #endif /* _GPXE_IO_H */
507