Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / include / ipxe / uaccess.h
1 #ifndef _IPXE_UACCESS_H
2 #define _IPXE_UACCESS_H
3
4 /**
5  * @file
6  *
7  * Access to external ("user") memory
8  *
9  * iPXE often needs to transfer data between internal and external
10  * buffers.  On i386, the external buffers may require access via a
11  * different segment, and the buffer address cannot be encoded into a
12  * simple void * pointer.  The @c userptr_t type encapsulates the
13  * information needed to identify an external buffer, and the
14  * copy_to_user() and copy_from_user() functions provide methods for
15  * transferring data between internal and external buffers.
16  *
17  * Note that userptr_t is an opaque type; in particular, performing
18  * arithmetic upon a userptr_t is not allowed.
19  *
20  */
21
22 FILE_LICENCE ( GPL2_OR_LATER );
23
24 #include <stdint.h>
25 #include <string.h>
26 #include <ipxe/api.h>
27 #include <config/ioapi.h>
28
29 /**
30  * A pointer to a user buffer
31  *
32  */
33 typedef unsigned long userptr_t;
34
35 /** Equivalent of NULL for user pointers */
36 #define UNULL ( ( userptr_t ) 0 )
37
38 /**
39  * @defgroup uaccess_trivial Trivial user access API implementations
40  *
41  * User access API implementations that can be used by environments in
42  * which virtual addresses allow access to all of memory.
43  *
44  * @{
45  *
46  */
47
48 /**
49  * Convert virtual address to user pointer
50  *
51  * @v addr              Virtual address
52  * @ret userptr         User pointer
53  */
54 static inline __always_inline userptr_t
55 trivial_virt_to_user ( volatile const void *addr ) {
56         return ( ( userptr_t ) addr );
57 }
58
59 /**
60  * Convert user pointer to virtual address
61  *
62  * @v userptr           User pointer
63  * @v offset            Offset from user pointer
64  * @ret addr            Virtual address
65  *
66  * This operation is not available under all memory models.
67  */
68 static inline __always_inline void *
69 trivial_user_to_virt ( userptr_t userptr, off_t offset ) {
70         return ( ( void * ) userptr + offset );
71 }
72
73 /**
74  * Add offset to user pointer
75  *
76  * @v userptr           User pointer
77  * @v offset            Offset
78  * @ret userptr         New pointer value
79  */
80 static inline __always_inline userptr_t
81 trivial_userptr_add ( userptr_t userptr, off_t offset ) {
82         return ( userptr + offset );
83 }
84
85 /**
86  * Subtract user pointers
87  *
88  * @v userptr           User pointer
89  * @v subtrahend        User pointer to be subtracted
90  * @ret offset          Offset
91  */
92 static inline __always_inline off_t
93 trivial_userptr_sub ( userptr_t userptr, userptr_t subtrahend ) {
94         return ( userptr - subtrahend );
95 }
96
97 /**
98  * Copy data between user buffers
99  *
100  * @v dest              Destination
101  * @v dest_off          Destination offset
102  * @v src               Source
103  * @v src_off           Source offset
104  * @v len               Length
105  */
106 static inline __always_inline void
107 trivial_memcpy_user ( userptr_t dest, off_t dest_off,
108                       userptr_t src, off_t src_off, size_t len ) {
109         memcpy ( ( ( void * ) dest + dest_off ),
110                  ( ( void * ) src + src_off ), len );
111 }
112
113 /**
114  * Copy data between user buffers, allowing for overlap
115  *
116  * @v dest              Destination
117  * @v dest_off          Destination offset
118  * @v src               Source
119  * @v src_off           Source offset
120  * @v len               Length
121  */
122 static inline __always_inline void
123 trivial_memmove_user ( userptr_t dest, off_t dest_off,
124                        userptr_t src, off_t src_off, size_t len ) {
125         memmove ( ( ( void * ) dest + dest_off ),
126                   ( ( void * ) src + src_off ), len );
127 }
128
129 /**
130  * Compare data between user buffers
131  *
132  * @v first             First buffer
133  * @v first_off         First buffer offset
134  * @v second            Second buffer
135  * @v second_off        Second buffer offset
136  * @v len               Length
137  * @ret diff            Difference
138  */
139 static inline __always_inline int
140 trivial_memcmp_user ( userptr_t first, off_t first_off,
141                       userptr_t second, off_t second_off, size_t len ) {
142         return memcmp ( ( ( void * ) first + first_off ),
143                         ( ( void * ) second + second_off ), len );
144 }
145
146 /**
147  * Fill user buffer with a constant byte
148  *
149  * @v buffer            User buffer
150  * @v offset            Offset within buffer
151  * @v c                 Constant byte with which to fill
152  * @v len               Length
153  */
154 static inline __always_inline void
155 trivial_memset_user ( userptr_t buffer, off_t offset, int c, size_t len ) {
156         memset ( ( ( void * ) buffer + offset ), c, len );
157 }
158
159 /**
160  * Find length of NUL-terminated string in user buffer
161  *
162  * @v buffer            User buffer
163  * @v offset            Offset within buffer
164  * @ret len             Length of string (excluding NUL)
165  */
166 static inline __always_inline size_t
167 trivial_strlen_user ( userptr_t buffer, off_t offset ) {
168         return strlen ( ( void * ) buffer + offset );
169 }
170
171 /**
172  * Find character in user buffer
173  *
174  * @v buffer            User buffer
175  * @v offset            Starting offset within buffer
176  * @v c                 Character to search for
177  * @v len               Length of user buffer
178  * @ret offset          Offset of character, or <0 if not found
179  */
180 static inline __always_inline off_t
181 trivial_memchr_user ( userptr_t buffer, off_t offset, int c, size_t len ) {
182         void *found;
183
184         found = memchr ( ( ( void * ) buffer + offset ), c, len );
185         return ( found ? ( found - ( void * ) buffer ) : -1 );
186 }
187
188 /** @} */
189
190 /**
191  * Calculate static inline user access API function name
192  *
193  * @v _prefix           Subsystem prefix
194  * @v _api_func         API function
195  * @ret _subsys_func    Subsystem API function
196  */
197 #define UACCESS_INLINE( _subsys, _api_func ) \
198         SINGLE_API_INLINE ( UACCESS_PREFIX_ ## _subsys, _api_func )
199
200 /**
201  * Provide an user access API implementation
202  *
203  * @v _prefix           Subsystem prefix
204  * @v _api_func         API function
205  * @v _func             Implementing function
206  */
207 #define PROVIDE_UACCESS( _subsys, _api_func, _func ) \
208         PROVIDE_SINGLE_API ( UACCESS_PREFIX_ ## _subsys, _api_func, _func )
209
210 /**
211  * Provide a static inline user access API implementation
212  *
213  * @v _prefix           Subsystem prefix
214  * @v _api_func         API function
215  */
216 #define PROVIDE_UACCESS_INLINE( _subsys, _api_func ) \
217         PROVIDE_SINGLE_API_INLINE ( UACCESS_PREFIX_ ## _subsys, _api_func )
218
219 /* Include all architecture-independent user access API headers */
220 #include <ipxe/efi/efi_uaccess.h>
221 #include <ipxe/linux/linux_uaccess.h>
222
223 /* Include all architecture-dependent user access API headers */
224 #include <bits/uaccess.h>
225
226 /**
227  * Convert physical address to user pointer
228  *
229  * @v phys_addr         Physical address
230  * @ret userptr         User pointer
231  */
232 userptr_t phys_to_user ( unsigned long phys_addr );
233
234 /**
235  * Convert user pointer to physical address
236  *
237  * @v userptr           User pointer
238  * @v offset            Offset from user pointer
239  * @ret phys_addr       Physical address
240  */
241 unsigned long user_to_phys ( userptr_t userptr, off_t offset );
242
243 /**
244  * Convert virtual address to user pointer
245  *
246  * @v addr              Virtual address
247  * @ret userptr         User pointer
248  */
249 userptr_t virt_to_user ( volatile const void *addr );
250
251 /**
252  * Convert user pointer to virtual address
253  *
254  * @v userptr           User pointer
255  * @v offset            Offset from user pointer
256  * @ret addr            Virtual address
257  *
258  * This operation is not available under all memory models.
259  */
260 void * user_to_virt ( userptr_t userptr, off_t offset );
261
262 /**
263  * Add offset to user pointer
264  *
265  * @v userptr           User pointer
266  * @v offset            Offset
267  * @ret userptr         New pointer value
268  */
269 userptr_t userptr_add ( userptr_t userptr, off_t offset );
270
271 /**
272  * Subtract user pointers
273  *
274  * @v userptr           User pointer
275  * @v subtrahend        User pointer to be subtracted
276  * @ret offset          Offset
277  */
278 off_t userptr_sub ( userptr_t userptr, userptr_t subtrahend );
279
280 /**
281  * Convert virtual address to a physical address
282  *
283  * @v addr              Virtual address
284  * @ret phys_addr       Physical address
285  */
286 static inline __always_inline unsigned long
287 virt_to_phys ( volatile const void *addr ) {
288         return user_to_phys ( virt_to_user ( addr ), 0 );
289 }
290
291 /**
292  * Convert physical address to a virtual address
293  *
294  * @v addr              Virtual address
295  * @ret phys_addr       Physical address
296  *
297  * This operation is not available under all memory models.
298  */
299 static inline __always_inline void * phys_to_virt ( unsigned long phys_addr ) {
300         return user_to_virt ( phys_to_user ( phys_addr ), 0 );
301 }
302
303 /**
304  * Copy data between user buffers
305  *
306  * @v dest              Destination
307  * @v dest_off          Destination offset
308  * @v src               Source
309  * @v src_off           Source offset
310  * @v len               Length
311  */
312 void memcpy_user ( userptr_t dest, off_t dest_off,
313                    userptr_t src, off_t src_off, size_t len );
314
315 /**
316  * Copy data to user buffer
317  *
318  * @v dest              Destination
319  * @v dest_off          Destination offset
320  * @v src               Source
321  * @v len               Length
322  */
323 static inline __always_inline void
324 copy_to_user ( userptr_t dest, off_t dest_off, const void *src, size_t len ) {
325         memcpy_user ( dest, dest_off, virt_to_user ( src ), 0, len );
326 }
327
328 /**
329  * Copy data from user buffer
330  *
331  * @v dest              Destination
332  * @v src               Source
333  * @v src_off           Source offset
334  * @v len               Length
335  */
336 static inline __always_inline void
337 copy_from_user ( void *dest, userptr_t src, off_t src_off, size_t len ) {
338         memcpy_user ( virt_to_user ( dest ), 0, src, src_off, len );
339 }
340
341 /**
342  * Copy data between user buffers, allowing for overlap
343  *
344  * @v dest              Destination
345  * @v dest_off          Destination offset
346  * @v src               Source
347  * @v src_off           Source offset
348  * @v len               Length
349  */
350 void memmove_user ( userptr_t dest, off_t dest_off,
351                     userptr_t src, off_t src_off, size_t len );
352
353 /**
354  * Compare data between user buffers
355  *
356  * @v first             First buffer
357  * @v first_off         First buffer offset
358  * @v second            Second buffer
359  * @v second_off        Second buffer offset
360  * @v len               Length
361  * @ret diff            Difference
362  */
363 int memcmp_user ( userptr_t first, off_t first_off,
364                   userptr_t second, off_t second_off, size_t len );
365
366 /**
367  * Fill user buffer with a constant byte
368  *
369  * @v userptr           User buffer
370  * @v offset            Offset within buffer
371  * @v c                 Constant byte with which to fill
372  * @v len               Length
373  */
374 void memset_user ( userptr_t userptr, off_t offset, int c, size_t len );
375
376 /**
377  * Find length of NUL-terminated string in user buffer
378  *
379  * @v userptr           User buffer
380  * @v offset            Offset within buffer
381  * @ret len             Length of string (excluding NUL)
382  */
383 size_t strlen_user ( userptr_t userptr, off_t offset );
384
385 /**
386  * Find character in user buffer
387  *
388  * @v userptr           User buffer
389  * @v offset            Starting offset within buffer
390  * @v c                 Character to search for
391  * @v len               Length of user buffer
392  * @ret offset          Offset of character, or <0 if not found
393  */
394 off_t memchr_user ( userptr_t userptr, off_t offset, int c, size_t len );
395
396 #endif /* _IPXE_UACCESS_H */