summaryrefslogtreecommitdiffstats
path: root/exynos5/hal/include/ump.h
blob: 487e2c2472832e9a008f72da05c51a54590bbe59 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
/*
 * This confidential and proprietary software may be used only as
 * authorised by a licensing agreement from ARM Limited
 * (C) COPYRIGHT 2008-2011 ARM Limited
 * ALL RIGHTS RESERVED
 * The entire notice above must be reproduced on all authorised
 * copies and copies may only be made to the extent permitted
 * by a licensing agreement from ARM Limited.
 */

/**
 * @file ump.h
 *
 * This file contains the user space part of the UMP API.
 *
 */

#ifndef _UMP_H_
#define _UMP_H_

/**
 * @page page_base_ump Unified Memory Provider API
 *
 * UMP(Universal Memory Provider) is an API to allocate memory with some special unique requirements;
 * @li Known physical addresses
 * @li Non-relocatable/pinned
 * @li Won't be paged out
 * @li Shareable between processes (selectable per allocation for security reasons)
 * @li Shareable with multiple hardware devices
 * @li Physically contiguous (optional)
 * @li Extended (not valid with the physically contiguous requirement for obvious reasons)
 *
 * Allocations from UMP can safely be used with hardware devices and other processes.
 * 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.
 * This means that even if a process frees memory too early or crashes any hardware using the memory won't corrupt freed memory.
 *
 * Allocations inside a process is represented using an UMP memory handle.
 *
 * Each allocation is represented by a system-wide unique ID (called a secure ID),
 * which can be obtained from a handle and be shared with other processes or given to a device driver.
 *
 * Based on a secure ID a new handle can be created either in kernel space by a driver
 * or in user space by some other process to use the same allocation.
 *
 * Based on the handle a driver in kernel space can obtain information about the physical memory block(s)
 * an allocation consists of and increment or decrement the reference count.
 *
 * Usage in user-space also adds a reference to the memory, but it's managed by the UMP device driver.
 *
 * The user-space reference count is only local to the process, so a process can't by accident decrement
 * the count one time too many and cause the memory to be freed while it's in use by a hardware device.
 *
 * This is all handled by the UMP kernel code, no user-space code cooperation is needed.
 *
 * By default an allocation is only accessible in the same process or what other security boundary the OS uses.
 * If marked as shared it can be accessed in all processes, the kernel space customer defined security filter permitting of course.
 * See @ref ump_dd_security_filter for more information about this security filter.
 *
 * @sa ump_api
 * @sa example_user_api.c
 * @sa example_kernel_api.c
 *
 * @example example_user_api.c
 * @example example_kernel_api.c
 *
 */

/** @defgroup ump_api Unified Memory Provider APIs
 */

/**
 * @addtogroup ump_api
 * @{
 */

/** @defgroup ump_user_space_api UMP User Space API
 * @{ */


#include "ump_platform.h"
#include "ump_common.h"
#include "ion.h"

#ifndef __KERNEL__
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#endif

#ifdef __cplusplus
extern "C"
{
#endif

/**
 * External representation of a UMP handle in user space.
 */
typedef void * ump_handle;

/**
 * Value to indicate an invalid UMP memory handle.
 */
#define UMP_INVALID_MEMORY_HANDLE ((ump_handle)0)

/**
 * Opens and initializes the UMP library.
 *
 * This function must be called at least once before calling any other UMP API functions.
 * Each successful open call is reference counted and must be matched with a call to @ref ump_close.
 * It is safe to call @a ump_open after a @a ump_close has terminated a previous session.
 *
 * UMP_ERROR will be returned if:
 *   - the reference count is ULONG_MAX so would overflow.
 *   - the reference count is 0 and the backend fails to open.
 *
 * UMP API: v1 and v2
 * @see ump_close
 *
 * @return UMP_OK indicates success, UMP_ERROR indicates failure.
 */
UMP_API_EXPORT ump_result ump_open(void) CHECK_RESULT;


/**
 * Terminate the UMP library.
 *
 * This must be called once for every successful @ref ump_open. The UMP library is
 * terminated when, and only when, the last open reference to the UMP interface is closed.
 *
 * If this is called while having active allocations or mappings the behavior is undefined.
 *
 * UMP API: v1 and v2
 * @see ump_open
 */
UMP_API_EXPORT void ump_close(void);


/**
 * Retrieves the secure ID for the specified UMP memory.
 *
 * This identifier is unique across the entire system, and uniquely identifies
 * the specified UMP memory allocation. This identifier can later be used through the
 * v2 API:
 * @ref ump_from_secure_id or
 * @ref ump_dd_from_secure_id
 * v1 API:
 * @ref ump_handle_create_from_secure_id or
 * @ref ump_dd_handle_create_from_secure_id
 *
 * functions in order to access this UMP memory, for instance from another process.
 * Unless the allocation was marked as shared the returned ID will only be resolvable in the same process as did the allocation.
 *
 * If called on an @a UMP_INVALID_MEMORY_HANDLE it will return @a UMP_INVALID_SECURE_ID.
 *
 * @note There is a kernel space equivalent function called @ref ump_dd_secure_id_get
 *
 * UMP API: v1 and v2
 *
 * @see ump_dd_secure_id_get
 * v2 API:
 * @see ump_from_secure_id
 * @see ump_dd_from_secure_id
 * v1 API:
 * @see ump_handle_create_from_secure_id
 * @see ump_dd_from_secure_id
 *
 * @param mem Handle to UMP memory.
 *
 * @return Returns the secure ID for the specified UMP memory.
 */
UMP_API_EXPORT ump_secure_id ump_secure_id_get(const ump_handle mem) CHECK_RESULT;


/**
 * Synchronous mapping cache sync operation.
 *
 * Performs the requested CPU side cache sync operations before returning.
 * A clean must be done before the memory is guaranteed to be visible in main memory.
 * Any device-specific cache clean/invalidate must be done in combination with this routine, if needed.
 * Function returns cache status for the allocation.
 *
 * Example:
 * @code
 * 	ump_cpu_msync_now(handle, UMP_MSYNC_CLEAN, ptr, size);
 * 	device_invalidate(...);
 * 	// ... run device ...
 * 	device_clean(...);
 * 	ump_cpu_msync_now(handle, UMP_MSYNC_CLEAN_AND_INVALIDATE, ptr, size);
 * 	// ... safe to access on the cpu side again ...
 * @endcode
 *
 *
 * Calls to operate on an @a UMP_INVALID_MEMORY_HANDLE will result in undefined behavior.
 * Debug builds will assert on this.
 *
 * If @a address is not inside a mapping previously obtained from the @a ump_handle provided results in undefined behavior.
 * If @a address combined with @a size results on reaching beyond the end of the buffer results in undefined behavior.
 *
 * UMP API: v1 and v2
 * @param mem Handle to UMP memory
 * @param op Cache operation to perform
 * @param[in] address The CPU address where to start the sync operation, this can be at an offset from the start of the allocation.
 * @param size The number of bytes to be synced.
 *
 * @return Returns 1 if cache is enabled, 0 if cache is disabled for the given allocation.
 *
 */
UMP_API_EXPORT int ump_cpu_msync_now(ump_handle mem, ump_cpu_msync_op op, void * address, size_t size);


#ifndef UMP_BLOCK_V2_API

/**
 * Allocate a buffer.
 * The life-time of the allocation is controlled by a reference count.
 * The reference count of the returned buffer is set to 1.
 * The memory will be freed once the reference count reaches 0.
 * Use @ref ump_retain and @ref ump_release to control the reference count.
 * The contens of the memory returned will be zero initialized.
 *
 * The @ref UMP_V1_API_DEFAULT_ALLOCATION_FLAGS can be used
 * to create a buffer that can be shared with v1 API applications.
 * The allocation will be limited to 32-bit PA.
 *
 * The @ref UMP_CONSTRAINT_UNCACHED flag disables cache for all cpu mappings for this allocation.
 *
 * UMP API: v2
 * @param size Number of bytes to allocate. Will be padded up to a multiple of the page size.
 * @param flags Bit-wise OR of zero or more of the allocation flag bits.
 * @return Handle to the new allocation, or @a UMP_INVALID_MEMORY_HANDLE on allocation failure.
 */
UMP_API_EXPORT ump_handle ump_allocate_64(u64 size, ump_alloc_flags flags) CHECK_RESULT;


/**
 * Creates a handle based on a shared UMP memory allocation.
 *
 * The usage of UMP memory is reference counted, so this will increment the reference
 * count by one for the specified UMP memory.
 *
 * If called on an @a UMP_INVALID_SECURE_ID this will return @a UMP_INVALID_MEMORY_HANDLE.
 * If called on an non-shared allocation and this is a different process @a UMP_INVALID_MEMORY_HANDLE will be returned.
 *
 * Use @ref ump_release when there is no longer any
 * use for the retrieved handle.
 *
 * @note There is a kernel space equivalent function called @ref ump_dd_from_secure_id
 *
 * UMP API: v2
 * @see ump_release
 * @see ump_dd_from_secure_id
 *
 * @param secure_id The secure ID of the UMP memory to open, that can be retrieved using the @ref ump_secure_id_get function.
 *
 * @return @a UMP_INVALID_MEMORY_HANDLE indicates failure, otherwise a valid handle is returned.
 */
UMP_API_EXPORT ump_handle ump_from_secure_id(ump_secure_id secure_id) CHECK_RESULT;


/**
 * 64 bit version of @ref ump_size_get. Retrieves the actual size of the specified UMP memory.
 *
 * The size is reported in bytes, and is typically a multiple of the page size.
 * If called on an @a UMP_INVALID_MEMORY_HANDLE will result in undefined behavior.
 * Debug builds will assert on this.
 *
 * @note There is a kernel space equivalent function called @ref ump_dd_size_get_64
 *
 * UMP API: v2
 * @see ump_dd_size_get_64
 *
 * @param mem Handle to UMP memory.
 *
 * @return Returns the allocated 64-bit size of the specified UMP memory, in bytes.
 */
UMP_API_EXPORT u64 ump_size_get_64(const ump_handle mem) CHECK_RESULT;


/**
 * Retrieves a memory mapped pointer to the specified UMP memory.
 *
 * This function retrieves a memory mapped pointer to the specified UMP memory, that can be used by the CPU.@n
 * Every successful call to @a ump_map must be matched with a call to @ref ump_unmap when the mapping is no longer needed.
 *
 * An offset and/or size resulting in going beyond the end of the buffer will case  the function to return NULL.
 *
 * Calling on @a UMP_INVALID_MEMORY_HANDLE results in undefined behavior.
 * Debug builds will assert on this.
 *
 * @note Systems without a MMU for the CPU only return the physical address, because no mapping is required.
 *
 * UMP API: v2
 * @see ump_unmap
 *
 * @param mem Handle to UMP memory.
 * @param offset An offset at which the mapping begins.
 * @param size The number of bytes to map. Passing 0 does not retrieve a memory mapped
 * pointer - instead NULL is returned.
 *
 * @return NULL indicates failure, otherwise a CPU mapped pointer is returned.
 */
UMP_API_EXPORT void * ump_map(ump_handle mem, u64 offset, size_t size) CHECK_RESULT;


/**
 * Releases a previously mapped pointer to the specified UMP memory.
 *
 * Every successful call to @ref ump_map must be matched with a call to @a ump_unmap when the mapping is no longer needed.
 *
 * The following results in undefined behavior:
 * - Called with an address not returned from @ref ump_map
 * - Called with a different @a ump_handle than was used to obtain the pointer
 * - Called with a different @a size than was used to obtain the pointer
 *
 * @note Systems without a MMU must still implement this function, even though no unmapping should be needed.
 *
 * UMP API: v2
 * @param mem Handle to UMP memory.
 * @param[in] address The CPU virtual address returned by @ref ump_map
 * @param size Size matching argument given to ump_map
 */
UMP_API_EXPORT void ump_unmap(ump_handle mem, void* address, size_t size);


/**
 * Adds an extra reference to the specified UMP memory.
 *
 * This function adds an extra reference to the specified UMP memory. This function should
 * be used every time a UMP memory handle is duplicated, that is, assigned to another ump_handle
 * variable. The function @ref ump_release must then be used
 * to release each copy of the UMP memory handle.
 *
 * It's safe to call this on both shared and non-shared handles.
 * Calling on an @a UMP_INVALID_MEMORY_HANDLE results in undefined behavior.
 * Debug builds will assert on this.
 *
 * @note You are not required to call @ref ump_retain
 * for UMP handles returned from
 * @ref ump_from_secure_id,
 * because these handles are already reference counted by this function.
 *
 * @note There is a kernel space equivalent function called @ref ump_dd_retain
 *
 * UMP API: v2
 * @see ump_dd_retain
 *
 * @param mem Handle to UMP memory.
 * @return UMP_OK indicates success, UMP_ERROR indicates failure.
 */
UMP_API_EXPORT ump_result ump_retain(ump_handle mem);


/**
 * Releases a reference from the specified UMP memory.
 *
 * This function should be called once for every reference to the UMP memory handle.
 * When the last reference is released, all resources associated with this UMP memory
 * handle are freed.
 *
 * One can only call ump_release when matched with a successful ump_retain, ump_allocate_64 or ump_from_secure_id
 * It's safe to call this on both shared and non-shared handles.
 * If called on an @a UMP_INVALID_MEMORY_HANDLE it will return early.
 *
 * @note There is a kernel space equivalent function called @ref ump_dd_release
 *
 * UMP API: v2
 * @see ump_release
 *
 * @param mem Handle to UMP memory.
 */
UMP_API_EXPORT void ump_release(ump_handle mem);


/**
 * Import external memory into UMP.
 *
 * This function creates a ump_handle wrapping memory provided by some external source.
 *
 * For reference counted types the returned handle represents one new reference,
 * which must be freed using @a ump_release.
 * The handle passed in still holds its reference and can still be used and must be released
 * as it would be normally.
 *
 * For ownership based types the returned handle has claimed the ownership which will be released
 * with @a ump_release.
 * The handle passed in is no longer valid.
 *
 * A pointer to the handle type is required, not the type it self.
 *
 * The flags are used in the same way as for @a ump_allocate_64, except that these flags are ignored:
 * @li UMP_CONSTRAINT_32BIT_ADDRESSABLE
 * @li UMP_CONSTRAINT_PHYSICALLY_LINEAR
 *
 * The returned UMP handle can be used as any other ump_handle.
 *
 * Example for UMP_EXTERNAL_MEM_TYPE_ION:
 *
 * @code
 * ump_handle h;
 * ump_alloc_flags flags = get_requested_flags();
 * int fd = ion_fd_get();
 * h = ump_import(UMP_EXTERNAL_MEM_TYPE_ION, &fd, flags);
 * // native release
 * close(fd);
 * ...
 * ump_release(h);
 * @endcode
 *
 * Example for a generic ownership based type:
 *
 * @code
 * ump_handle h;
 * ump_alloc_flags = get_requested_flags();
 * type t = type_claim();
 * h = ump_import(UMP_OWNERSHIP_BASED_TYPE, &t, flags);
 * // native handle no longer valid
 * t = INVALID;
 * ...
 * ump_release(h);
 * @endcode
 *
 * UMP API: v2
 * @see ump_release
 *
 * @param type Type of external memory to import
 * @param phandle Pointer to the handle to import.
 * @param flags Bit-wise OR of zero or more of the allocation flag bits.
 * @return Handle wrapping the imported memory, or @a UMP_INVALID_MEMORY_HANDLE on import failure.
 */
UMP_API_EXPORT ump_handle ump_import(enum ump_external_memory_type type, void * phandle, ump_alloc_flags flags) CHECK_RESULT;

#endif /* UMP_BLOCK_V2_API */

/** @name UMP v1 API
 * Functions provided to support compatibility with UMP v1 API
 *
 * You should use v1 API only with handles created with @ref ump_ref_drv_allocate
 * and @ref ump_handle_create_from_secure_id.
 * Using v1 API for handles created with v2 API can cause undefined behavior.
 *
 *@{
 */

#ifndef UMP_BLOCK_V1_API

/** Allocate an UMP handle containing a memory buffer.
 *
 * If usage is UMP_REF_DRV_CONSTRAINT_USE_CACHE, the allocation is mapped as cached by the cpu.
 * If it is UMP_REF_DRV_CONSTRAINT_NONE it is mapped as noncached.
 * The flag UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR is not supported.
 *
 * UMP API: v1
 * @param size The minimum size for the allocation.
 * @param usage The allocation constraints.
 */

UMP_API_EXPORT ump_handle ump_ref_drv_allocate(unsigned long size, ump_alloc_constraints usage);


/**
 * Retrieves the actual size of the specified UMP memory.
 *
 * The size is reported in bytes, and is typically page aligned.
 *
 * @note There is a kernel space equivalent function called @ref ump_dd_size_get "ump_dd_size_get"
 *
 * UMP API: v1
 * @see ump_dd_size_get
 *
 * @param mem Handle to UMP memory.
 *
 * @return Returns the allocated size of the specified UMP memory, in bytes.
 */
UMP_API_EXPORT unsigned long ump_size_get(ump_handle mem) CHECK_RESULT;


/**
 * Retrieves a handle to allocated UMP memory.
 *
 * The usage of UMP memory is reference counted, so this will increment the reference
 * count by one for the specified UMP memory.
 * Use @ref ump_reference_release "ump_reference_release" when there is no longer any
 * use for the retrieved handle.
 *
 * @note There is a kernel space equivalent function called @ref ump_dd_handle_create_from_secure_id "ump_dd_handle_create_from_secure_id"
 *
 * UMP API: v1
 * @see ump_reference_release
 * @see ump_dd_handle_create_from_secure_id
 *
 * @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.
 *
 * @return UMP_INVALID_MEMORY_HANDLE indicates failure, otherwise a valid handle is returned.
 */
UMP_API_EXPORT ump_handle ump_handle_create_from_secure_id(ump_secure_id secure_id) CHECK_RESULT;


/**
 * Adds an extra reference to the specified UMP memory.
 *
 * This function adds an extra reference to the specified UMP memory. This function should
 * be used every time a UMP memory handle is duplicated, that is, assigned to another ump_handle
 * variable. The function @ref ump_reference_release "ump_reference_release" must then be used
 * to release each copy of the UMP memory handle.
 *
 * @note You are not required to call @ref ump_reference_add "ump_reference_add"
 * for UMP handles returned from
 * @ref ump_handle_create_from_secure_id "ump_handle_create_from_secure_id",
 * because these handles are already reference counted by this function.
 *
 * @note There is a kernel space equivalent function called @ref ump_dd_reference_add "ump_dd_reference_add"
 *
 * UMP API: v1
 * @see ump_dd_reference_add
 *
 * @param mem Handle to UMP memory.
 */
UMP_API_EXPORT void ump_reference_add(ump_handle mem);


/**
 * Releases a reference from the specified UMP memory.
 *
 * This function should be called once for every reference to the UMP memory handle.
 * When the last reference is released, all resources associated with this UMP memory
 * handle are freed.
 *
 * @note There is a kernel space equivalent function called @ref ump_dd_reference_release "ump_dd_reference_release"
 *
 * UMP API: v1
 * @see ump_dd_reference_release
 *
 * @param mem Handle to UMP memory.
 */
UMP_API_EXPORT void ump_reference_release(ump_handle mem);


/**
 * Retrieves a memory mapped pointer to the specified UMP memory.
 *
 * This function retrieves a memory mapped pointer to the specified UMP memory,
 * that can be used by the CPU. Every successful call to
 * @ref ump_mapped_pointer_get "ump_mapped_pointer_get" is reference counted,
 * and must therefor be followed by a call to
 * @ref ump_mapped_pointer_release "ump_mapped_pointer_release " when the
 * memory mapping is no longer needed.
 *
 * @note Systems without a MMU for the CPU only return the physical address, because no mapping is required.
 *
 * UMP API: v1
 * @see ump_mapped_pointer_release
 *
 * @param mem Handle to UMP memory.
 *
 * @return NULL indicates failure, otherwise a CPU mapped pointer is returned.
 */
UMP_API_EXPORT void * ump_mapped_pointer_get(ump_handle mem);


/**
 * Releases a previously mapped pointer to the specified UMP memory.
 *
 * The CPU mapping of the specified UMP memory memory is reference counted,
 * so every call to @ref ump_mapped_pointer_get "ump_mapped_pointer_get" must
 * be matched with a call to this function when the mapping is no longer needed.
 *
 * The CPU mapping is not removed before all references to the mapping is released.
 *
 * UMP API: v1
 * @note Systems without a MMU must still implement this function, even though no unmapping should be needed.
 *
 * @param mem Handle to UMP memory.
 */
UMP_API_EXPORT void ump_mapped_pointer_release(ump_handle mem);


/**
 * Read from specified UMP memory.
 *
 * Another way of reading from (and writing to) UMP memory is to use the
 * @ref ump_mapped_pointer_get "ump_mapped_pointer_get" to retrieve
 * a CPU mapped pointer to the memory.
 *
 * UMP API: v1
 * @see ump_mapped_pointer_get
 *
 * @param dst Destination buffer.
 * @param src Handle to UMP memory to read from.
 * @param offset Where to start reading, given in bytes.
 * @param length How much to read, given in bytes.
 */
UMP_API_EXPORT void ump_read(void * dst, ump_handle src, unsigned long offset, unsigned long length);


/**
 * Write to specified UMP memory.
 *
 * Another way of writing to (and reading from) UMP memory is to use the
 * @ref ump_mapped_pointer_get "ump_mapped_pointer_get" to retrieve
 * a CPU mapped pointer to the memory.
 *
 * UMP API: v1
 * @see ump_mapped_pointer_get
 *
 * @param dst Handle to UMP memory to write to.
 * @param offset Where to start writing, given in bytes.
 * @param src Buffer to read from.
 * @param length How much to write, given in bytes.
 */
UMP_API_EXPORT void ump_write(ump_handle dst, unsigned long offset, const void * src, unsigned long length);

#endif /* UMP_BLOCK_V1_API */

/* @} */

#ifdef __cplusplus
}
#endif


/** @} */ /* end group ump_user_space_api */

/** @} */ /* end group ump_api */

#endif /* _UMP_H_ */