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
virt_to_bus(volatile const void * addr)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 */
bus_to_virt(unsigned long bus_addr)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 */
488 struct memory_region {
489 /** Physical start address */
490 uint64_t start;
491 /** Physical end address */
492 uint64_t end;
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 */
501 struct memory_region regions[MAX_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 */
514