blob: 487e2c2472832e9a008f72da05c51a54590bbe59 [file] [log] [blame]
codeworkx62f02ba2012-05-20 12:00:36 +02001/*
2 * This confidential and proprietary software may be used only as
3 * authorised by a licensing agreement from ARM Limited
4 * (C) COPYRIGHT 2008-2011 ARM Limited
5 * ALL RIGHTS RESERVED
6 * The entire notice above must be reproduced on all authorised
7 * copies and copies may only be made to the extent permitted
8 * by a licensing agreement from ARM Limited.
9 */
10
11/**
12 * @file ump.h
13 *
14 * This file contains the user space part of the UMP API.
15 *
16 */
17
18#ifndef _UMP_H_
19#define _UMP_H_
20
21/**
22 * @page page_base_ump Unified Memory Provider API
23 *
24 * UMP(Universal Memory Provider) is an API to allocate memory with some special unique requirements;
25 * @li Known physical addresses
26 * @li Non-relocatable/pinned
27 * @li Won't be paged out
28 * @li Shareable between processes (selectable per allocation for security reasons)
29 * @li Shareable with multiple hardware devices
30 * @li Physically contiguous (optional)
31 * @li Extended (not valid with the physically contiguous requirement for obvious reasons)
32 *
33 * Allocations from UMP can safely be used with hardware devices and other processes.
34 * All uses are reference counted, so memory won't be released until all participating hardware devices and processes have released their use of the allocation.
35 * This means that even if a process frees memory too early or crashes any hardware using the memory won't corrupt freed memory.
36 *
37 * Allocations inside a process is represented using an UMP memory handle.
38 *
39 * Each allocation is represented by a system-wide unique ID (called a secure ID),
40 * which can be obtained from a handle and be shared with other processes or given to a device driver.
41 *
42 * Based on a secure ID a new handle can be created either in kernel space by a driver
43 * or in user space by some other process to use the same allocation.
44 *
45 * Based on the handle a driver in kernel space can obtain information about the physical memory block(s)
46 * an allocation consists of and increment or decrement the reference count.
47 *
48 * Usage in user-space also adds a reference to the memory, but it's managed by the UMP device driver.
49 *
50 * The user-space reference count is only local to the process, so a process can't by accident decrement
51 * the count one time too many and cause the memory to be freed while it's in use by a hardware device.
52 *
53 * This is all handled by the UMP kernel code, no user-space code cooperation is needed.
54 *
55 * By default an allocation is only accessible in the same process or what other security boundary the OS uses.
56 * If marked as shared it can be accessed in all processes, the kernel space customer defined security filter permitting of course.
57 * See @ref ump_dd_security_filter for more information about this security filter.
58 *
59 * @sa ump_api
60 * @sa example_user_api.c
61 * @sa example_kernel_api.c
62 *
63 * @example example_user_api.c
64 * @example example_kernel_api.c
65 *
66 */
67
68/** @defgroup ump_api Unified Memory Provider APIs
69 */
70
71/**
72 * @addtogroup ump_api
73 * @{
74 */
75
76/** @defgroup ump_user_space_api UMP User Space API
77 * @{ */
78
79
80#include "ump_platform.h"
81#include "ump_common.h"
82#include "ion.h"
83
84#ifndef __KERNEL__
85#include <stdlib.h>
86#include <pthread.h>
87#include <stdio.h>
88#include <string.h>
89#include <assert.h>
90#endif
91
92#ifdef __cplusplus
93extern "C"
94{
95#endif
96
97/**
98 * External representation of a UMP handle in user space.
99 */
100typedef void * ump_handle;
101
102/**
103 * Value to indicate an invalid UMP memory handle.
104 */
105#define UMP_INVALID_MEMORY_HANDLE ((ump_handle)0)
106
107/**
108 * Opens and initializes the UMP library.
109 *
110 * This function must be called at least once before calling any other UMP API functions.
111 * Each successful open call is reference counted and must be matched with a call to @ref ump_close.
112 * It is safe to call @a ump_open after a @a ump_close has terminated a previous session.
113 *
114 * UMP_ERROR will be returned if:
115 * - the reference count is ULONG_MAX so would overflow.
116 * - the reference count is 0 and the backend fails to open.
117 *
118 * UMP API: v1 and v2
119 * @see ump_close
120 *
121 * @return UMP_OK indicates success, UMP_ERROR indicates failure.
122 */
123UMP_API_EXPORT ump_result ump_open(void) CHECK_RESULT;
124
125
126/**
127 * Terminate the UMP library.
128 *
129 * This must be called once for every successful @ref ump_open. The UMP library is
130 * terminated when, and only when, the last open reference to the UMP interface is closed.
131 *
132 * If this is called while having active allocations or mappings the behavior is undefined.
133 *
134 * UMP API: v1 and v2
135 * @see ump_open
136 */
137UMP_API_EXPORT void ump_close(void);
138
139
140/**
141 * Retrieves the secure ID for the specified UMP memory.
142 *
143 * This identifier is unique across the entire system, and uniquely identifies
144 * the specified UMP memory allocation. This identifier can later be used through the
145 * v2 API:
146 * @ref ump_from_secure_id or
147 * @ref ump_dd_from_secure_id
148 * v1 API:
149 * @ref ump_handle_create_from_secure_id or
150 * @ref ump_dd_handle_create_from_secure_id
151 *
152 * functions in order to access this UMP memory, for instance from another process.
153 * Unless the allocation was marked as shared the returned ID will only be resolvable in the same process as did the allocation.
154 *
155 * If called on an @a UMP_INVALID_MEMORY_HANDLE it will return @a UMP_INVALID_SECURE_ID.
156 *
157 * @note There is a kernel space equivalent function called @ref ump_dd_secure_id_get
158 *
159 * UMP API: v1 and v2
160 *
161 * @see ump_dd_secure_id_get
162 * v2 API:
163 * @see ump_from_secure_id
164 * @see ump_dd_from_secure_id
165 * v1 API:
166 * @see ump_handle_create_from_secure_id
167 * @see ump_dd_from_secure_id
168 *
169 * @param mem Handle to UMP memory.
170 *
171 * @return Returns the secure ID for the specified UMP memory.
172 */
173UMP_API_EXPORT ump_secure_id ump_secure_id_get(const ump_handle mem) CHECK_RESULT;
174
175
176/**
177 * Synchronous mapping cache sync operation.
178 *
179 * Performs the requested CPU side cache sync operations before returning.
180 * A clean must be done before the memory is guaranteed to be visible in main memory.
181 * Any device-specific cache clean/invalidate must be done in combination with this routine, if needed.
182 * Function returns cache status for the allocation.
183 *
184 * Example:
185 * @code
186 * ump_cpu_msync_now(handle, UMP_MSYNC_CLEAN, ptr, size);
187 * device_invalidate(...);
188 * // ... run device ...
189 * device_clean(...);
190 * ump_cpu_msync_now(handle, UMP_MSYNC_CLEAN_AND_INVALIDATE, ptr, size);
191 * // ... safe to access on the cpu side again ...
192 * @endcode
193 *
194 *
195 * Calls to operate on an @a UMP_INVALID_MEMORY_HANDLE will result in undefined behavior.
196 * Debug builds will assert on this.
197 *
198 * If @a address is not inside a mapping previously obtained from the @a ump_handle provided results in undefined behavior.
199 * If @a address combined with @a size results on reaching beyond the end of the buffer results in undefined behavior.
200 *
201 * UMP API: v1 and v2
202 * @param mem Handle to UMP memory
203 * @param op Cache operation to perform
204 * @param[in] address The CPU address where to start the sync operation, this can be at an offset from the start of the allocation.
205 * @param size The number of bytes to be synced.
206 *
207 * @return Returns 1 if cache is enabled, 0 if cache is disabled for the given allocation.
208 *
209 */
210UMP_API_EXPORT int ump_cpu_msync_now(ump_handle mem, ump_cpu_msync_op op, void * address, size_t size);
211
212
213#ifndef UMP_BLOCK_V2_API
214
215/**
216 * Allocate a buffer.
217 * The life-time of the allocation is controlled by a reference count.
218 * The reference count of the returned buffer is set to 1.
219 * The memory will be freed once the reference count reaches 0.
220 * Use @ref ump_retain and @ref ump_release to control the reference count.
221 * The contens of the memory returned will be zero initialized.
222 *
223 * The @ref UMP_V1_API_DEFAULT_ALLOCATION_FLAGS can be used
224 * to create a buffer that can be shared with v1 API applications.
225 * The allocation will be limited to 32-bit PA.
226 *
227 * The @ref UMP_CONSTRAINT_UNCACHED flag disables cache for all cpu mappings for this allocation.
228 *
229 * UMP API: v2
230 * @param size Number of bytes to allocate. Will be padded up to a multiple of the page size.
231 * @param flags Bit-wise OR of zero or more of the allocation flag bits.
232 * @return Handle to the new allocation, or @a UMP_INVALID_MEMORY_HANDLE on allocation failure.
233 */
234UMP_API_EXPORT ump_handle ump_allocate_64(u64 size, ump_alloc_flags flags) CHECK_RESULT;
235
236
237/**
238 * Creates a handle based on a shared UMP memory allocation.
239 *
240 * The usage of UMP memory is reference counted, so this will increment the reference
241 * count by one for the specified UMP memory.
242 *
243 * If called on an @a UMP_INVALID_SECURE_ID this will return @a UMP_INVALID_MEMORY_HANDLE.
244 * If called on an non-shared allocation and this is a different process @a UMP_INVALID_MEMORY_HANDLE will be returned.
245 *
246 * Use @ref ump_release when there is no longer any
247 * use for the retrieved handle.
248 *
249 * @note There is a kernel space equivalent function called @ref ump_dd_from_secure_id
250 *
251 * UMP API: v2
252 * @see ump_release
253 * @see ump_dd_from_secure_id
254 *
255 * @param secure_id The secure ID of the UMP memory to open, that can be retrieved using the @ref ump_secure_id_get function.
256 *
257 * @return @a UMP_INVALID_MEMORY_HANDLE indicates failure, otherwise a valid handle is returned.
258 */
259UMP_API_EXPORT ump_handle ump_from_secure_id(ump_secure_id secure_id) CHECK_RESULT;
260
261
262/**
263 * 64 bit version of @ref ump_size_get. Retrieves the actual size of the specified UMP memory.
264 *
265 * The size is reported in bytes, and is typically a multiple of the page size.
266 * If called on an @a UMP_INVALID_MEMORY_HANDLE will result in undefined behavior.
267 * Debug builds will assert on this.
268 *
269 * @note There is a kernel space equivalent function called @ref ump_dd_size_get_64
270 *
271 * UMP API: v2
272 * @see ump_dd_size_get_64
273 *
274 * @param mem Handle to UMP memory.
275 *
276 * @return Returns the allocated 64-bit size of the specified UMP memory, in bytes.
277 */
278UMP_API_EXPORT u64 ump_size_get_64(const ump_handle mem) CHECK_RESULT;
279
280
281/**
282 * Retrieves a memory mapped pointer to the specified UMP memory.
283 *
284 * This function retrieves a memory mapped pointer to the specified UMP memory, that can be used by the CPU.@n
285 * Every successful call to @a ump_map must be matched with a call to @ref ump_unmap when the mapping is no longer needed.
286 *
287 * An offset and/or size resulting in going beyond the end of the buffer will case the function to return NULL.
288 *
289 * Calling on @a UMP_INVALID_MEMORY_HANDLE results in undefined behavior.
290 * Debug builds will assert on this.
291 *
292 * @note Systems without a MMU for the CPU only return the physical address, because no mapping is required.
293 *
294 * UMP API: v2
295 * @see ump_unmap
296 *
297 * @param mem Handle to UMP memory.
298 * @param offset An offset at which the mapping begins.
299 * @param size The number of bytes to map. Passing 0 does not retrieve a memory mapped
300 * pointer - instead NULL is returned.
301 *
302 * @return NULL indicates failure, otherwise a CPU mapped pointer is returned.
303 */
304UMP_API_EXPORT void * ump_map(ump_handle mem, u64 offset, size_t size) CHECK_RESULT;
305
306
307/**
308 * Releases a previously mapped pointer to the specified UMP memory.
309 *
310 * Every successful call to @ref ump_map must be matched with a call to @a ump_unmap when the mapping is no longer needed.
311 *
312 * The following results in undefined behavior:
313 * - Called with an address not returned from @ref ump_map
314 * - Called with a different @a ump_handle than was used to obtain the pointer
315 * - Called with a different @a size than was used to obtain the pointer
316 *
317 * @note Systems without a MMU must still implement this function, even though no unmapping should be needed.
318 *
319 * UMP API: v2
320 * @param mem Handle to UMP memory.
321 * @param[in] address The CPU virtual address returned by @ref ump_map
322 * @param size Size matching argument given to ump_map
323 */
324UMP_API_EXPORT void ump_unmap(ump_handle mem, void* address, size_t size);
325
326
327/**
328 * Adds an extra reference to the specified UMP memory.
329 *
330 * This function adds an extra reference to the specified UMP memory. This function should
331 * be used every time a UMP memory handle is duplicated, that is, assigned to another ump_handle
332 * variable. The function @ref ump_release must then be used
333 * to release each copy of the UMP memory handle.
334 *
335 * It's safe to call this on both shared and non-shared handles.
336 * Calling on an @a UMP_INVALID_MEMORY_HANDLE results in undefined behavior.
337 * Debug builds will assert on this.
338 *
339 * @note You are not required to call @ref ump_retain
340 * for UMP handles returned from
341 * @ref ump_from_secure_id,
342 * because these handles are already reference counted by this function.
343 *
344 * @note There is a kernel space equivalent function called @ref ump_dd_retain
345 *
346 * UMP API: v2
347 * @see ump_dd_retain
348 *
349 * @param mem Handle to UMP memory.
350 * @return UMP_OK indicates success, UMP_ERROR indicates failure.
351 */
352UMP_API_EXPORT ump_result ump_retain(ump_handle mem);
353
354
355/**
356 * Releases a reference from the specified UMP memory.
357 *
358 * This function should be called once for every reference to the UMP memory handle.
359 * When the last reference is released, all resources associated with this UMP memory
360 * handle are freed.
361 *
362 * One can only call ump_release when matched with a successful ump_retain, ump_allocate_64 or ump_from_secure_id
363 * It's safe to call this on both shared and non-shared handles.
364 * If called on an @a UMP_INVALID_MEMORY_HANDLE it will return early.
365 *
366 * @note There is a kernel space equivalent function called @ref ump_dd_release
367 *
368 * UMP API: v2
369 * @see ump_release
370 *
371 * @param mem Handle to UMP memory.
372 */
373UMP_API_EXPORT void ump_release(ump_handle mem);
374
375
376/**
377 * Import external memory into UMP.
378 *
379 * This function creates a ump_handle wrapping memory provided by some external source.
380 *
381 * For reference counted types the returned handle represents one new reference,
382 * which must be freed using @a ump_release.
383 * The handle passed in still holds its reference and can still be used and must be released
384 * as it would be normally.
385 *
386 * For ownership based types the returned handle has claimed the ownership which will be released
387 * with @a ump_release.
388 * The handle passed in is no longer valid.
389 *
390 * A pointer to the handle type is required, not the type it self.
391 *
392 * The flags are used in the same way as for @a ump_allocate_64, except that these flags are ignored:
393 * @li UMP_CONSTRAINT_32BIT_ADDRESSABLE
394 * @li UMP_CONSTRAINT_PHYSICALLY_LINEAR
395 *
396 * The returned UMP handle can be used as any other ump_handle.
397 *
398 * Example for UMP_EXTERNAL_MEM_TYPE_ION:
399 *
400 * @code
401 * ump_handle h;
402 * ump_alloc_flags flags = get_requested_flags();
403 * int fd = ion_fd_get();
404 * h = ump_import(UMP_EXTERNAL_MEM_TYPE_ION, &fd, flags);
405 * // native release
406 * close(fd);
407 * ...
408 * ump_release(h);
409 * @endcode
410 *
411 * Example for a generic ownership based type:
412 *
413 * @code
414 * ump_handle h;
415 * ump_alloc_flags = get_requested_flags();
416 * type t = type_claim();
417 * h = ump_import(UMP_OWNERSHIP_BASED_TYPE, &t, flags);
418 * // native handle no longer valid
419 * t = INVALID;
420 * ...
421 * ump_release(h);
422 * @endcode
423 *
424 * UMP API: v2
425 * @see ump_release
426 *
427 * @param type Type of external memory to import
428 * @param phandle Pointer to the handle to import.
429 * @param flags Bit-wise OR of zero or more of the allocation flag bits.
430 * @return Handle wrapping the imported memory, or @a UMP_INVALID_MEMORY_HANDLE on import failure.
431 */
432UMP_API_EXPORT ump_handle ump_import(enum ump_external_memory_type type, void * phandle, ump_alloc_flags flags) CHECK_RESULT;
433
434#endif /* UMP_BLOCK_V2_API */
435
436/** @name UMP v1 API
437 * Functions provided to support compatibility with UMP v1 API
438 *
439 * You should use v1 API only with handles created with @ref ump_ref_drv_allocate
440 * and @ref ump_handle_create_from_secure_id.
441 * Using v1 API for handles created with v2 API can cause undefined behavior.
442 *
443 *@{
444 */
445
446#ifndef UMP_BLOCK_V1_API
447
448/** Allocate an UMP handle containing a memory buffer.
449 *
450 * If usage is UMP_REF_DRV_CONSTRAINT_USE_CACHE, the allocation is mapped as cached by the cpu.
451 * If it is UMP_REF_DRV_CONSTRAINT_NONE it is mapped as noncached.
452 * The flag UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR is not supported.
453 *
454 * UMP API: v1
455 * @param size The minimum size for the allocation.
456 * @param usage The allocation constraints.
457 */
458
459UMP_API_EXPORT ump_handle ump_ref_drv_allocate(unsigned long size, ump_alloc_constraints usage);
460
461
462/**
463 * Retrieves the actual size of the specified UMP memory.
464 *
465 * The size is reported in bytes, and is typically page aligned.
466 *
467 * @note There is a kernel space equivalent function called @ref ump_dd_size_get "ump_dd_size_get"
468 *
469 * UMP API: v1
470 * @see ump_dd_size_get
471 *
472 * @param mem Handle to UMP memory.
473 *
474 * @return Returns the allocated size of the specified UMP memory, in bytes.
475 */
476UMP_API_EXPORT unsigned long ump_size_get(ump_handle mem) CHECK_RESULT;
477
478
479/**
480 * Retrieves a handle to allocated UMP memory.
481 *
482 * The usage of UMP memory is reference counted, so this will increment the reference
483 * count by one for the specified UMP memory.
484 * Use @ref ump_reference_release "ump_reference_release" when there is no longer any
485 * use for the retrieved handle.
486 *
487 * @note There is a kernel space equivalent function called @ref ump_dd_handle_create_from_secure_id "ump_dd_handle_create_from_secure_id"
488 *
489 * UMP API: v1
490 * @see ump_reference_release
491 * @see ump_dd_handle_create_from_secure_id
492 *
493 * @param secure_id The secure ID of the UMP memory to open, that can be retrieved using the @ref ump_secure_id_get "ump_secure_id_get " function.
494 *
495 * @return UMP_INVALID_MEMORY_HANDLE indicates failure, otherwise a valid handle is returned.
496 */
497UMP_API_EXPORT ump_handle ump_handle_create_from_secure_id(ump_secure_id secure_id) CHECK_RESULT;
498
499
500/**
501 * Adds an extra reference to the specified UMP memory.
502 *
503 * This function adds an extra reference to the specified UMP memory. This function should
504 * be used every time a UMP memory handle is duplicated, that is, assigned to another ump_handle
505 * variable. The function @ref ump_reference_release "ump_reference_release" must then be used
506 * to release each copy of the UMP memory handle.
507 *
508 * @note You are not required to call @ref ump_reference_add "ump_reference_add"
509 * for UMP handles returned from
510 * @ref ump_handle_create_from_secure_id "ump_handle_create_from_secure_id",
511 * because these handles are already reference counted by this function.
512 *
513 * @note There is a kernel space equivalent function called @ref ump_dd_reference_add "ump_dd_reference_add"
514 *
515 * UMP API: v1
516 * @see ump_dd_reference_add
517 *
518 * @param mem Handle to UMP memory.
519 */
520UMP_API_EXPORT void ump_reference_add(ump_handle mem);
521
522
523/**
524 * Releases a reference from the specified UMP memory.
525 *
526 * This function should be called once for every reference to the UMP memory handle.
527 * When the last reference is released, all resources associated with this UMP memory
528 * handle are freed.
529 *
530 * @note There is a kernel space equivalent function called @ref ump_dd_reference_release "ump_dd_reference_release"
531 *
532 * UMP API: v1
533 * @see ump_dd_reference_release
534 *
535 * @param mem Handle to UMP memory.
536 */
537UMP_API_EXPORT void ump_reference_release(ump_handle mem);
538
539
540/**
541 * Retrieves a memory mapped pointer to the specified UMP memory.
542 *
543 * This function retrieves a memory mapped pointer to the specified UMP memory,
544 * that can be used by the CPU. Every successful call to
545 * @ref ump_mapped_pointer_get "ump_mapped_pointer_get" is reference counted,
546 * and must therefor be followed by a call to
547 * @ref ump_mapped_pointer_release "ump_mapped_pointer_release " when the
548 * memory mapping is no longer needed.
549 *
550 * @note Systems without a MMU for the CPU only return the physical address, because no mapping is required.
551 *
552 * UMP API: v1
553 * @see ump_mapped_pointer_release
554 *
555 * @param mem Handle to UMP memory.
556 *
557 * @return NULL indicates failure, otherwise a CPU mapped pointer is returned.
558 */
559UMP_API_EXPORT void * ump_mapped_pointer_get(ump_handle mem);
560
561
562/**
563 * Releases a previously mapped pointer to the specified UMP memory.
564 *
565 * The CPU mapping of the specified UMP memory memory is reference counted,
566 * so every call to @ref ump_mapped_pointer_get "ump_mapped_pointer_get" must
567 * be matched with a call to this function when the mapping is no longer needed.
568 *
569 * The CPU mapping is not removed before all references to the mapping is released.
570 *
571 * UMP API: v1
572 * @note Systems without a MMU must still implement this function, even though no unmapping should be needed.
573 *
574 * @param mem Handle to UMP memory.
575 */
576UMP_API_EXPORT void ump_mapped_pointer_release(ump_handle mem);
577
578
579/**
580 * Read from specified UMP memory.
581 *
582 * Another way of reading from (and writing to) UMP memory is to use the
583 * @ref ump_mapped_pointer_get "ump_mapped_pointer_get" to retrieve
584 * a CPU mapped pointer to the memory.
585 *
586 * UMP API: v1
587 * @see ump_mapped_pointer_get
588 *
589 * @param dst Destination buffer.
590 * @param src Handle to UMP memory to read from.
591 * @param offset Where to start reading, given in bytes.
592 * @param length How much to read, given in bytes.
593 */
594UMP_API_EXPORT void ump_read(void * dst, ump_handle src, unsigned long offset, unsigned long length);
595
596
597/**
598 * Write to specified UMP memory.
599 *
600 * Another way of writing to (and reading from) UMP memory is to use the
601 * @ref ump_mapped_pointer_get "ump_mapped_pointer_get" to retrieve
602 * a CPU mapped pointer to the memory.
603 *
604 * UMP API: v1
605 * @see ump_mapped_pointer_get
606 *
607 * @param dst Handle to UMP memory to write to.
608 * @param offset Where to start writing, given in bytes.
609 * @param src Buffer to read from.
610 * @param length How much to write, given in bytes.
611 */
612UMP_API_EXPORT void ump_write(ump_handle dst, unsigned long offset, const void * src, unsigned long length);
613
614#endif /* UMP_BLOCK_V1_API */
615
616/* @} */
617
618#ifdef __cplusplus
619}
620#endif
621
622
623/** @} */ /* end group ump_user_space_api */
624
625/** @} */ /* end group ump_api */
626
627#endif /* _UMP_H_ */