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