~thopiekar/arm-mali/libump-sunxi

« back to all changes in this revision

Viewing changes to src/ump_osu.h

  • Committer: Luc Verhaegen
  • Date: 2014-03-25 21:04:12 UTC
  • Revision ID: git-v1:fa5ad94ac2873793dcca65dafc3ea211de5e7226
import ump r2p4 source

Signed-off-by: Luc Verhaegen <libv@skynet.be>

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
 
3
 * 
 
4
 * Licensed under the Apache License, Version 2.0 (the "License");
 
5
 * you may not use this file except in compliance with the License.
 
6
 * You may obtain a copy of the License at
 
7
 * 
 
8
 *       http://www.apache.org/licenses/LICENSE-2.0
 
9
 * 
 
10
 * Unless required by applicable law or agreed to in writing, software
 
11
 * distributed under the License is distributed on an "AS IS" BASIS,
 
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
13
 * See the License for the specific language governing permissions and
 
14
 * limitations under the License.
 
15
 */
 
16
 
 
17
/**
 
18
 * @file ump_osu.h
 
19
 * Defines the OS abstraction layer for the base driver
 
20
 */
 
21
 
 
22
#ifndef __UMP_OSU_H__
 
23
#define __UMP_OSU_H__
 
24
 
 
25
#include <stdarg.h>
 
26
 
 
27
#ifdef __cplusplus
 
28
extern "C"
 
29
{
 
30
#endif
 
31
 
 
32
 
 
33
typedef unsigned int u32;
 
34
#ifdef _MSC_VER
 
35
        typedef unsigned __int64        u64;
 
36
        typedef signed   __int64        s64;
 
37
#else
 
38
        typedef unsigned long long      u64;
 
39
        typedef signed long long        s64;
 
40
#endif
 
41
 
 
42
#ifndef NULL
 
43
#define NULL ((void*)0)
 
44
#endif
 
45
 
 
46
typedef unsigned long ump_bool;
 
47
 
 
48
#ifndef UMP_TRUE
 
49
#define UMP_TRUE ((ump_bool)1)
 
50
#endif
 
51
 
 
52
#ifndef UMP_FALSE
 
53
#define UMP_FALSE ((ump_bool)0)
 
54
#endif
 
55
 
 
56
#define UMP_STATIC          static
 
57
 
 
58
/**
 
59
 * @addtogroup ump_user_space_api Unified Device Driver (UDD) APIs used by UMP
 
60
 *
 
61
 * @{
 
62
 */
 
63
 
 
64
/**
 
65
 * @defgroup ump_osuapi UDD OS Abstraction for User-side (OSU) APIs for UMP
 
66
 *
 
67
 * @{
 
68
 */
 
69
 
 
70
/* The following is necessary to prevent the _ump_osk_errcode_t doxygen from
 
71
 * becoming unreadable: */
 
72
/** @cond OSU_COPY_OF__UMP_OSU_ERRCODE_T */
 
73
 
 
74
/**
 
75
 * @brief OSU/OSK Error codes.
 
76
 *
 
77
 * Each OS may use its own set of error codes, and may require that the
 
78
 * User/Kernel interface take certain error code. This means that the common
 
79
 * error codes need to be sufficiently rich to pass the correct error code
 
80
 * through from the OSK/OSU to U/K layer, across all OSs.
 
81
 *
 
82
 * The result is that some error codes will appear redundant on some OSs.
 
83
 * Under all OSs, the OSK/OSU layer must translate native OS error codes to
 
84
 * _ump_osk/u_errcode_t codes. Similarly, the U/K layer must translate from
 
85
 * _ump_osk/u_errcode_t codes to native OS error codes.
 
86
 *
 
87
 */
 
88
typedef enum
 
89
{
 
90
        _UMP_OSK_ERR_OK = 0,              /**< Success. */
 
91
        _UMP_OSK_ERR_FAULT = -1,          /**< General non-success */
 
92
        _UMP_OSK_ERR_INVALID_FUNC = -2,   /**< Invalid function requested through User/Kernel interface (e.g. bad IOCTL number) */
 
93
        _UMP_OSK_ERR_INVALID_ARGS = -3,   /**< Invalid arguments passed through User/Kernel interface */
 
94
        _UMP_OSK_ERR_NOMEM = -4,          /**< Insufficient memory */
 
95
        _UMP_OSK_ERR_TIMEOUT = -5,        /**< Timeout occured */
 
96
        _UMP_OSK_ERR_RESTARTSYSCALL = -6, /**< Special: On certain OSs, must report when an interruptable mutex is interrupted. Ignore otherwise. */
 
97
        _UMP_OSK_ERR_ITEM_NOT_FOUND = -7, /**< Table Lookup failed */
 
98
        _UMP_OSK_ERR_BUSY = -8,           /**< Device/operation is busy. Try again later */
 
99
        _UMP_OSK_ERR_UNSUPPORTED = -9,  /**< Optional part of the interface used, and is unsupported */
 
100
} _ump_osk_errcode_t;
 
101
 
 
102
/** @endcond */ /* end cond OSU_COPY_OF__UMP_OSU_ERRCODE_T */
 
103
 
 
104
/**
 
105
 * @brief OSU Error codes.
 
106
 *
 
107
 * OSU error codes - enum values intentionally same as OSK
 
108
 */
 
109
typedef enum
 
110
{
 
111
        _UMP_OSU_ERR_OK = 0,           /**< Success. */
 
112
        _UMP_OSU_ERR_FAULT = -1,       /**< General non-success */
 
113
        _UMP_OSU_ERR_TIMEOUT = -2,     /**< Timeout occured */
 
114
} _ump_osu_errcode_t;
 
115
 
 
116
/** @brief Translate OSU error code to base driver error code.
 
117
 *
 
118
 * The _UMP_OSU_TRANSLATE_ERROR macro translates an OSU error code to the
 
119
 * error codes in use by the base driver.
 
120
 */
 
121
#define _UMP_OSU_TRANSLATE_ERROR(_ump_osu_errcode) ( ( _UMP_OSU_ERR_OK == (_ump_osu_errcode) ) ? UMP_ERR_NO_ERROR : UMP_ERR_FUNCTION_FAILED)
 
122
 
 
123
/** @defgroup _ump_osu_lock OSU Mutual Exclusion Locks
 
124
  * @{ */
 
125
 
 
126
/** @brief OSU Mutual Exclusion Lock flags type.
 
127
 *
 
128
 * This is made to look like and function identically to the OSK locks (refer
 
129
 * to \ref _ump_osk_lock). However, please note the following \b important
 
130
 * differences:
 
131
 * - the OSU default lock is a Sleeping, non-interruptible mutex.
 
132
 * - the OSU adds the ANYUNLOCK type of lock which allows a thread which doesn't
 
133
 * own the lock to release the lock.
 
134
 * - the order parameter when creating a lock is currently unused
 
135
 *
 
136
 * @note Pay careful attention to the difference in default locks for OSU and
 
137
 * OSK locks; OSU locks are always non-interruptible, but OSK locks are by
 
138
 * default, interruptible. This has implications for systems that do not
 
139
 * distinguish between user and kernel mode.
 
140
 */
 
141
typedef enum
 
142
{
 
143
        _UMP_OSU_LOCKFLAG_DEFAULT = 0, /**< Default lock type. */
 
144
        /** @enum _ump_osu_lock_flags_t
 
145
         *
 
146
         * Flags from 0x0--0x8000 are RESERVED for Kernel-mode
 
147
         */
 
148
        _UMP_OSU_LOCKFLAG_ANYUNLOCK = 0x10000, /**< Mutex that guarantees that any thread can unlock it when locked. Otherwise, this will not be possible. */
 
149
        /** @enum _ump_osu_lock_flags_t
 
150
         *
 
151
         * Flags from 0x10000 are RESERVED for User-mode
 
152
         */
 
153
        _UMP_OSU_LOCKFLAG_STATIC = 0x20000, /* Flag in OSU reserved range to identify lock as a statically initialized lock */
 
154
 
 
155
 } _ump_osu_lock_flags_t;
 
156
 
 
157
typedef enum
 
158
{
 
159
        _UMP_OSU_LOCKMODE_UNDEF = -1,  /**< Undefined lock mode. For internal use only */
 
160
        _UMP_OSU_LOCKMODE_RW    = 0x0, /**< Default. Lock is used to protect data that is read from and written to */
 
161
        /** @enum _ump_osu_lock_mode_t
 
162
         *
 
163
         * Lock modes 0x1--0x3F are RESERVED for Kernel-mode */
 
164
} _ump_osu_lock_mode_t;
 
165
 
 
166
/** @brief Private type for Mutual Exclusion lock objects. */
 
167
typedef struct _ump_osu_lock_t_struct _ump_osu_lock_t;
 
168
 
 
169
/** @brief The number of static locks supported in _ump_osu_lock_static(). */
 
170
#define UMP_OSU_STATIC_LOCK_COUNT (sizeof(_ump_osu_static_locks) / sizeof(_ump_osu_lock_t))
 
171
 
 
172
/** @} */ /* end group _ump_osu_lock */
 
173
 
 
174
/** @defgroup _ump_osu_memory OSU Memory Allocation
 
175
 * @{ */
 
176
 
 
177
/** @brief Allocate zero-initialized memory.
 
178
 *
 
179
 * Returns a buffer capable of containing at least \a n elements of \a size
 
180
 * bytes each. The buffer is initialized to zero.
 
181
 *
 
182
 * The buffer is suitably aligned for storage and subsequent access of every
 
183
 * type that the compiler supports. Therefore, the pointer to the start of the
 
184
 * buffer may be cast into any pointer type, and be subsequently accessed from
 
185
 * such a pointer, without loss of information.
 
186
 *
 
187
 * When the buffer is no longer in use, it must be freed with _ump_osu_free().
 
188
 * Failure to do so will cause a memory leak.
 
189
 *
 
190
 * @note Most toolchains supply memory allocation functions that meet the
 
191
 * compiler's alignment requirements.
 
192
 *
 
193
 * @param n Number of elements to allocate
 
194
 * @param size Size of each element
 
195
 * @return On success, the zero-initialized buffer allocated. NULL on failure
 
196
 */
 
197
void *_ump_osu_calloc( u32 n, u32 size );
 
198
 
 
199
/** @brief Allocate memory.
 
200
 *
 
201
 * Returns a buffer capable of containing at least \a size bytes. The
 
202
 * contents of the buffer are undefined.
 
203
 *
 
204
 * The buffer is suitably aligned for storage and subsequent access of every
 
205
 * type that the compiler supports. Therefore, the pointer to the start of the
 
206
 * buffer may be cast into any pointer type, and be subsequently accessed from
 
207
 * such a pointer, without loss of information.
 
208
 *
 
209
 * When the buffer is no longer in use, it must be freed with _ump_osu_free().
 
210
 * Failure to do so will cause a memory leak.
 
211
 *
 
212
 * @note Most toolchains supply memory allocation functions that meet the
 
213
 * compiler's alignment requirements.
 
214
 *
 
215
 * Remember to free memory using _ump_osu_free().
 
216
 * @param size Number of bytes to allocate
 
217
 * @return On success, the buffer allocated. NULL on failure.
 
218
 */
 
219
void *_ump_osu_malloc( u32 size );
 
220
 
 
221
/** @brief Free memory.
 
222
 *
 
223
 * Reclaims the buffer pointed to by the parameter \a ptr for the system.
 
224
 * All memory returned from _ump_osu_malloc(), _ump_osu_calloc() and
 
225
 * _ump_osu_realloc() must be freed before the application exits. Otherwise,
 
226
 * a memory leak will occur.
 
227
 *
 
228
 * Memory must be freed once. It is an error to free the same non-NULL pointer
 
229
 * more than once.
 
230
 *
 
231
 * It is legal to free the NULL pointer.
 
232
 *
 
233
 * @param ptr Pointer to buffer to free
 
234
 */
 
235
void _ump_osu_free( void *ptr );
 
236
 
 
237
/** @brief Copies memory.
 
238
 *
 
239
 * Copies the \a len bytes from the buffer pointed by the parameter \a src
 
240
 * directly to the buffer pointed by \a dst.
 
241
 *
 
242
 * It is an error for \a src to overlap \a dst anywhere in \a len bytes.
 
243
 *
 
244
 * @param dst Pointer to the destination array where the content is to be
 
245
 * copied.
 
246
 * @param src Pointer to the source of data to be copied.
 
247
 * @param len Number of bytes to copy.
 
248
 * @return \a dst is always passed through unmodified.
 
249
 */
 
250
void *_ump_osu_memcpy( void *dst, const void *src, u32  len );
 
251
 
 
252
/** @brief Fills memory.
 
253
 *
 
254
 * Sets the first \a size bytes of the block of memory pointed to by \a ptr to
 
255
 * the specified value
 
256
 * @param ptr Pointer to the block of memory to fill.
 
257
 * @param chr Value to be set, passed as u32. Only the 8 Least Significant Bits (LSB)
 
258
 * are used.
 
259
 * @param size Number of bytes to be set to the value.
 
260
 * @return \a ptr is always passed through unmodified
 
261
 */
 
262
void *_ump_osu_memset( void *ptr, u32 chr, u32 size );
 
263
 
 
264
/** @} */ /* end group _ump_osu_memory */
 
265
 
 
266
 
 
267
/** @addtogroup _ump_osu_lock
 
268
 * @{ */
 
269
 
 
270
/** @brief Initialize a Mutual Exclusion Lock.
 
271
 *
 
272
 * Locks are created in the signalled (unlocked) state.
 
273
 *
 
274
 * The parameter \a initial must be zero.
 
275
 *
 
276
 * At present, the parameter \a order must be zero. It remains for future
 
277
 * expansion for mutex order checking.
 
278
 *
 
279
 * @param flags flags combined with bitwise OR ('|'), or zero. There are
 
280
 * restrictions on which flags can be combined, see \ref _ump_osu_lock_flags_t.
 
281
 * @param initial For future expansion into semaphores. SBZ.
 
282
 * @param order The locking order of the mutex. SBZ.
 
283
 * @return On success, a pointer to a \ref _ump_osu_lock_t object. NULL on failure.
 
284
 */
 
285
_ump_osu_lock_t *_ump_osu_lock_init( _ump_osu_lock_flags_t flags, u32 initial, u32 order );
 
286
 
 
287
/** @brief Obtain a statically initialized Mutual Exclusion Lock.
 
288
 *
 
289
 * Retrieves a reference to a statically initialized lock. Up to
 
290
 * _UMP_OSU_STATIC_LOCK_COUNT statically initialized locks are
 
291
 * available. Only _ump_osu_lock_wait(), _ump_osu_lock_trywait(),
 
292
 * _ump_osu_lock_signal() can be used with statically initialized locks.
 
293
 * _UMP_OSU_LOCKMODE_RW mode should be used when waiting and signalling
 
294
 * statically initialized locks.
 
295
 *
 
296
 * For the same \a nr a pointer to the same statically initialized lock is
 
297
 * returned. That is, given the following code:
 
298
 * @code
 
299
 *      extern u32 n;
 
300
 *
 
301
 *      _ump_osu_lock_t *locka = _ump_osu_lock_static(n);
 
302
 *      _ump_osu_lock_t *lockb = _ump_osu_lock_static(n);
 
303
 * @endcode
 
304
 * Then (locka == lockb), for all 0 <= n < UMP_OSU_STATIC_LOCK_COUNT.
 
305
 *
 
306
 * @param nr index of a statically initialized lock [0..UMP_OSU_STATIC_LOCK_COUNT-1]
 
307
 * @return On success, a pointer to a _ump_osu_lock_t object. NULL on failure.
 
308
 */
 
309
_ump_osu_lock_t *_ump_osu_lock_static( u32 nr );
 
310
 
 
311
/** @brief Initialize a Mutual Exclusion Lock safely across multiple threads.
 
312
 *
 
313
 * The _ump_osu_lock_auto_init() function guarantees that the given lock will
 
314
 * be initialized once and precisely once, even in a situation involving
 
315
 * multiple threads.
 
316
 *
 
317
 * This is necessary because the first call to certain Public API functions must
 
318
 * initialize the API. However, there can be a race involved to call the first
 
319
 * library function in multi-threaded applications. To resolve this race, a
 
320
 * mutex can be used. This mutex must be initialized, but initialized only once
 
321
 * by any thread that might compete for its initialization. This function
 
322
 * guarantees the initialization to happen correctly, even when there is an
 
323
 * initialization race between multiple threads.
 
324
 *
 
325
 * Otherwise, the operation is identical to the _ump_osu_lock_init() function.
 
326
 * For more details, refer to _ump_osu_lock_init().
 
327
 *
 
328
 * @param pplock pointer to storage for a _ump_osu_lock_t pointer. This
 
329
 * _ump_osu_lock_t pointer may point to a _ump_osu_lock_t that has been
 
330
 * initialized already
 
331
 * @param flags flags combined with bitwise OR ('|'), or zero. There are
 
332
 * restrictions on which flags can be combined. Refer to
 
333
 * \ref _ump_osu_lock_flags_t for more information.
 
334
 * The absence of any flags (the value 0) results in a sleeping-mutex,
 
335
 * which is non-interruptible.
 
336
 * @param initial For future expansion into semaphores. SBZ.
 
337
 * @param order The locking order of the mutex. SBZ.
 
338
 * @return On success, _UMP_OSU_ERR_OK is returned and a pointer to an
 
339
 * initialized \ref _ump_osu_lock_t object is written into \a *pplock.
 
340
 * _UMP_OSU_ERR_FAULT is returned on failure.
 
341
 */
 
342
_ump_osu_errcode_t _ump_osu_lock_auto_init( _ump_osu_lock_t **pplock, _ump_osu_lock_flags_t flags, u32 initial, u32 order );
 
343
 
 
344
/** @brief Wait for a lock to be signalled (obtained).
 
345
 *
 
346
 * After a thread has successfully waited on the lock, the lock is obtained by
 
347
 * the thread, and is marked as unsignalled. The thread releases the lock by
 
348
 * signalling it.
 
349
 *
 
350
 * To prevent deadlock, locks must always be obtained in the same order.
 
351
 *
 
352
 * @param lock the lock to wait upon (obtain).
 
353
 * @param mode the mode in which the lock should be obtained. Currently this
 
354
 * must be _UMP_OSU_LOCKMODE_RW.
 
355
 * @return On success, _UMP_OSU_ERR_OK, _UMP_OSU_ERR_FAULT on error.
 
356
 */
 
357
_ump_osu_errcode_t _ump_osu_lock_wait( _ump_osu_lock_t *lock, _ump_osu_lock_mode_t mode);
 
358
 
 
359
/** @brief Wait for a lock to be signalled (obtained) with timeout
 
360
 *
 
361
 * After a thread has successfully waited on the lock, the lock is obtained by
 
362
 * the thread, and is marked as unsignalled. The thread releases the lock by
 
363
 * signalling it.
 
364
 *
 
365
 * To prevent deadlock, locks must always be obtained in the same order.
 
366
 *
 
367
 * This version can return early if it cannot obtain the lock within the given timeout.
 
368
 *
 
369
 * @param lock the lock to wait upon (obtain).
 
370
 * @param mode the mode in which the lock should be obtained. Currently this
 
371
 * must be _UMP_OSU_LOCKMODE_RW.
 
372
 * @param timeout Relative time in microseconds for the timeout
 
373
 * @return _UMP_OSU_ERR_OK if the lock was obtained, _UMP_OSU_ERR_TIMEOUT if the timeout expired or  _UMP_OSU_ERR_FAULT on error.
 
374
 */
 
375
_ump_osu_errcode_t _ump_osu_lock_timed_wait( _ump_osu_lock_t *lock, _ump_osu_lock_mode_t mode, u64 timeout);
 
376
 
 
377
/** @brief Test for a lock to be signalled and obtains the lock when so.
 
378
 *
 
379
 * Obtains the lock only when it is in signalled state. The lock is then
 
380
 * marked as unsignalled. The lock is released again by signalling
 
381
 * it by _ump_osu_lock_signal().
 
382
 *
 
383
 * If the lock could not be obtained immediately (that is, another thread
 
384
 * currently holds the lock), then this function \b does \b not wait for the
 
385
 * lock to be in a signalled state. Instead, an error code is immediately
 
386
 * returned to indicate that the thread could not obtain the lock.
 
387
 *
 
388
 * To prevent deadlock, locks must always be obtained in the same order.
 
389
 *
 
390
 * @param lock the lock to wait upon (obtain).
 
391
 * @param mode the mode in which the lock should be obtained. Currently this
 
392
 * must be _UMP_OSU_LOCKMODE_RW.
 
393
 * @return When the lock was obtained, _UMP_OSU_ERR_OK. If the lock could not
 
394
 * be obtained, _UMP_OSU_ERR_FAULT.
 
395
 */
 
396
_ump_osu_errcode_t _ump_osu_lock_trywait( _ump_osu_lock_t *lock, _ump_osu_lock_mode_t mode);
 
397
 
 
398
/** @brief Signal (release) a lock.
 
399
 *
 
400
 * Locks may only be signalled by the thread that originally waited upon the
 
401
 * lock, unless the lock was created using the _UMP_OSU_LOCKFLAG_ANYUNLOCK flag.
 
402
 *
 
403
 * @param lock the lock to signal (release).
 
404
 * @param mode the mode in which the lock should be obtained. This must match
 
405
 * the mode in which the lock was waited upon.
 
406
 */
 
407
void _ump_osu_lock_signal( _ump_osu_lock_t *lock, _ump_osu_lock_mode_t mode );
 
408
 
 
409
/** @brief Terminate a lock.
 
410
 *
 
411
 * This terminates a lock and frees all associated resources.
 
412
 *
 
413
 * It is a programming error to terminate the lock when it is held (unsignalled)
 
414
 * by a thread.
 
415
 *
 
416
 * @param lock the lock to terminate.
 
417
 */
 
418
void _ump_osu_lock_term( _ump_osu_lock_t *lock );
 
419
/** @} */ /* end group _ump_osu_lock */
 
420
 
 
421
/** @} */ /* end group osuapi */
 
422
 
 
423
/** @} */ /* end group uddapi */
 
424
 
 
425
 
 
426
#ifdef __cplusplus
 
427
}
 
428
#endif
 
429
 
 
430
#endif /* __UMP_OSU_H__ */