gpu os abstraction: remove stats api (unused)
[efikamx:linux-kernel.git] / drivers / mxc / amd-gpu / os / kernel / src / linux / kos_lib.c
1 /* Copyright (c) 2008-2010, Advanced Micro Devices. All rights reserved.
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 and
5  * only version 2 as published by the Free Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  *
17  */
18  
19 #include <linux/mm.h>
20 #include <linux/slab.h>
21 #include <linux/kernel.h>
22 #include <linux/string.h>
23 #include <linux/limits.h>
24 #include <linux/delay.h>
25 #include <linux/dma-mapping.h>
26 #include <linux/mutex.h>
27 #include <asm/atomic.h>
28 #include <asm/current.h>
29 #include <linux/sched.h>
30 #include <linux/jiffies.h>
31 #include <linux/kthread.h>
32 #include "kos_libapi.h"
33
34 //  defines
35
36 //  macros
37 #define KOS_MALLOC(s)               kmalloc(s, GFP_KERNEL)
38 #define KOS_CALLOC(num, size)       kcalloc(num, size, GFP_KERNEL)
39 #define KOS_REALLOC(p, s)           krealloc(p, s, GFP_KERNEL)
40 #define KOS_FREE(p)                 kfree(p); p = 0
41 #define KOS_DBGFLAGS_SET(flag)
42
43 //  assert API
44 KOS_API void
45 kos_assert_hook(const char* file, int line, int expression)
46 {
47     if (expression)
48     {
49         return;
50     }
51     else
52     {
53         printk(KERN_ERR "Assertion failed at %s:%d!\n", file, line);
54         //BUG();
55     }
56
57     // put breakpoint here
58 }
59
60
61 //////////////////////////////////////////////////////////////////////////////
62 //  heap API (per process)
63 //////////////////////////////////////////////////////////////////////////////
64 KOS_API void*
65 kos_malloc(int size)
66 {
67     void* ptr = KOS_MALLOC(size);
68
69     KOS_ASSERT(ptr);
70
71     return (ptr);
72 }
73
74
75 //----------------------------------------------------------------------------
76
77 KOS_API void*
78 kos_calloc(int num, int size)
79 {
80     void* ptr = KOS_CALLOC(num, size);
81
82     KOS_ASSERT(ptr);
83
84     return (ptr);
85 }
86
87 //----------------------------------------------------------------------------
88
89 KOS_API void*
90 kos_realloc(void* ptr, int size)
91 {
92     void* newptr;
93
94     KOS_ASSERT(ptr);
95     newptr = KOS_REALLOC(ptr, size);
96
97     KOS_ASSERT(newptr);
98
99     return (newptr);
100 }
101
102 //----------------------------------------------------------------------------
103
104 KOS_API void
105 kos_free(void* ptr)
106 {
107     KOS_FREE(ptr);
108 }
109
110 //----------------------------------------------------------------------------
111
112 KOS_API void
113 kos_memoryfence(void)
114 {
115 }
116
117 //----------------------------------------------------------------------------
118
119 KOS_API void
120 kos_enable_memoryleakcheck(void)
121 {
122     // perform automatic leak checking at program exit
123     KOS_DBGFLAGS_SET(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
124 }
125
126 //////////////////////////////////////////////////////////////////////////////
127 //  sync API
128 //////////////////////////////////////////////////////////////////////////////
129
130 KOS_API oshandle_t
131 kos_mutex_create(const char *name)
132 {
133         struct mutex *mutex = KOS_MALLOC(sizeof(struct mutex));
134         if (!mutex)
135                 return 0;
136         mutex_init(mutex);
137         return mutex;
138 }
139
140 //----------------------------------------------------------------------------
141
142 KOS_API oshandle_t
143 kos_mutex_open(const char *name)
144 {
145         // not implemented
146         return 0;
147 }
148
149 //----------------------------------------------------------------------------
150
151 KOS_API int
152 kos_mutex_free(oshandle_t mutexhandle)
153 {
154         struct mutex *mutex = (struct mutex *)mutexhandle;
155         if (!mutex)
156                 return OS_FAILURE;
157         KOS_FREE(mutex);
158         return OS_SUCCESS;
159 }
160
161 //----------------------------------------------------------------------------
162
163 KOS_API int
164 kos_mutex_lock(oshandle_t mutexhandle)
165 {
166         struct mutex *mutex = (struct mutex *)mutexhandle;
167         if (!mutex)
168                 return OS_FAILURE;
169         if (mutex_lock_interruptible(mutex) == -EINTR)
170                 return OS_FAILURE;
171         return OS_SUCCESS;
172 }
173
174 //----------------------------------------------------------------------------
175
176 KOS_API int
177 kos_mutex_locktry(oshandle_t mutexhandle)
178 {
179         struct mutex *mutex = (struct mutex *)mutexhandle;
180         if (!mutex)
181                 return OS_FAILURE;
182         if (!mutex_trylock(mutex))
183                 return OS_FAILURE;
184         return OS_SUCCESS;
185 }
186
187 //----------------------------------------------------------------------------
188
189 KOS_API int
190 kos_mutex_unlock(oshandle_t mutexhandle)
191 {
192         struct mutex *mutex = (struct mutex *)mutexhandle;
193         if (!mutex)
194                 return OS_FAILURE;
195         KOS_ASSERT(mutex_is_locked(mutex));
196         mutex_unlock(mutex);
197         return OS_SUCCESS;
198 }
199
200 //----------------------------------------------------------------------------
201
202 KOS_API unsigned int
203 kos_process_getid(void)
204 {
205         return current->tgid;
206 }
207
208 //----------------------------------------------------------------------------
209
210 /* ------------------------------------------------------------------- *//*
211  * \brief           Creates new event semaphore
212  * \param           uint32 a_manualReset
213  *                  When this param is zero, system automatically resets the
214  *                  event state to nonsignaled after waiting thread has been
215  *                  released
216  * \return          oshandle_t
217 *//* ------------------------------------------------------------------- */
218 KOS_API oshandle_t
219 kos_event_create(int a_manualReset)
220 {
221     struct completion *comp = KOS_MALLOC(sizeof(struct completion));
222
223     KOS_ASSERT(comp);
224     if(!comp)
225     {
226         return (oshandle_t)NULL;
227     }
228
229     init_completion(comp);
230
231     return (oshandle_t)comp;
232 }
233
234 /* ------------------------------------------------------------------- *//*
235  * \brief           Frees event semaphore
236  * \param           oshandle_t a_event, event semaphore
237  * \return          int
238 *//* ------------------------------------------------------------------- */
239 KOS_API int
240 kos_event_destroy(oshandle_t a_event)
241 {
242     struct completion *comp = (struct completion *)a_event;
243
244     KOS_ASSERT(comp);
245 //  KOS_ASSERT(completion_done(comp));
246
247     KOS_FREE(comp);
248     return (OS_SUCCESS);
249 }
250
251 /* ------------------------------------------------------------------- *//*
252  * \brief           Signals event semaphore
253  * \param           oshandle_t a_event, event semaphore
254  * \return          int
255 *//* ------------------------------------------------------------------- */
256 KOS_API int
257 kos_event_signal(oshandle_t a_event)
258 {
259     struct completion *comp = (struct completion *)a_event;
260
261     KOS_ASSERT(comp);
262     complete_all(comp);     // perhaps complete_all?
263     return (OS_SUCCESS);
264 }
265
266 /* ------------------------------------------------------------------- *//*
267  * \brief           Resets event semaphore state to nonsignaled
268  * \param           oshandle_t a_event, event semaphore
269  * \return          int
270 *//* ------------------------------------------------------------------- */
271 KOS_API int
272 kos_event_reset(oshandle_t a_event)
273 {
274     struct completion *comp = (struct completion *)a_event;
275
276     KOS_ASSERT(comp);
277     INIT_COMPLETION(*comp);
278     return (OS_SUCCESS);
279 }
280
281 /* ------------------------------------------------------------------- *//*
282  * \brief           Waits event semaphore to be signaled
283  * \param           oshandle_t a_event, event semaphore
284  * \return          int
285 *//* ------------------------------------------------------------------- */
286 KOS_API int
287 kos_event_wait(oshandle_t a_event, int a_milliSeconds)
288 {
289     struct completion *comp = (struct completion *)a_event;
290
291     KOS_ASSERT(comp);
292     if(a_milliSeconds == OS_INFINITE)
293     {
294         wait_for_completion_killable(comp);
295     }
296     else
297     {
298         // should interpret milliseconds really to jiffies?
299         if(!wait_for_completion_timeout(comp, msecs_to_jiffies(a_milliSeconds)))
300         {
301             return (OS_FAILURE);
302         }
303     }
304     return (OS_SUCCESS);
305 }
306
307 //----------------------------------------------------------------------------
308
309 /*-------------------------------------------------------------------*//*!
310  * \brief Sync block API
311  *        Same mutex needed from different blocks of driver
312  *//*-------------------------------------------------------------------*/
313
314 /*-------------------------------------------------------------------*//*!
315  * \external
316  * \brief   Sync block start
317  *
318  * \param   void
319  * \return  Returns NULL if no error, otherwise an error code.
320  *//*-------------------------------------------------------------------*/
321
322 static struct mutex* syncblock_mutex = 0;
323
324 KOS_API int kos_syncblock_start(void)
325 {
326     int return_value;
327
328     if(!syncblock_mutex)
329     {
330         syncblock_mutex = kos_mutex_create("syncblock");
331     }
332
333     if(syncblock_mutex)
334     {
335         return_value = kos_mutex_lock(syncblock_mutex);
336     }
337     else
338     {
339         return_value = -1;
340     }
341
342     return return_value;
343 }
344 /*-------------------------------------------------------------------*//*!
345  * \external
346  * \brief   Sync block end
347  *
348  * \param   void
349  * \return  Returns NULL if no error, otherwise an error code.
350  *//*-------------------------------------------------------------------*/
351 KOS_API int kos_syncblock_end(void)
352 {
353     int return_value;
354
355     if(syncblock_mutex)
356     {
357         return_value = kos_mutex_unlock(syncblock_mutex);
358     }
359     else
360     {
361         return_value = -1;
362     }
363
364     return return_value;
365 }
366
367 KOS_API oshandle_t kos_thread_create(oshandle_t a_function, unsigned int* a_threadId)
368 {
369         struct task_struct *task = kthread_run(a_function, 0, "kos_thread_%p", a_threadId);
370         *a_threadId = (unsigned int)task;
371         return (oshandle_t)task;
372 }
373
374 KOS_API void kos_thread_destroy( oshandle_t a_task )
375 {
376         kthread_stop((struct task_struct *)a_task);
377 }