staging: emgd: experimental build 2667
[profile/ivi/intel-emgd-kmod.git] / emgd / include / memory.h
1 /*
2  *-----------------------------------------------------------------------------
3  * Filename: memory.h
4  * $Revision: 1.7 $
5  *-----------------------------------------------------------------------------
6  * Copyright (c) 2002-2010, Intel Corporation.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24  * THE SOFTWARE.
25  *
26  *-----------------------------------------------------------------------------
27  * Description:
28  *  This file contains OS abstracted interfaces to common memory operations.
29  *-----------------------------------------------------------------------------
30  */
31
32 #ifndef _OAL_MEMORY_H
33 #define _OAL_MEMORY_H
34
35 #include <linux/slab.h>
36
37 unsigned long os_gart_alloc_page( void );
38 unsigned long os_gart_virt_to_phys( unsigned char *a );
39 void os_gart_free_page( unsigned char *a );
40
41 /* #define INSTRUMENT_KERNEL_ALLOCS */
42 #ifdef INSTRUMENT_KERNEL_ALLOCS
43 #define MAX_FUNC_NAME 64
44
45 typedef struct _os_allocd_mem {
46         void *ptr;
47         unsigned int size;
48         char function[MAX_FUNC_NAME];
49         struct _os_allocd_mem *next;
50 } os_allocd_mem;
51
52 extern os_allocd_mem *list_head;
53 extern os_allocd_mem *list_tail;
54
55 static inline void *_os_alloc(unsigned int size, const char *function) {
56         os_allocd_mem *mem;
57         void *ptr = kmalloc(size, GFP_KERNEL);
58         printk(KERN_DEBUG "%s OS_ALLOC(size=%u)=0x%p\n", function, size, ptr);
59         mem = kmalloc(sizeof(os_allocd_mem), GFP_KERNEL);
60         if (!ZERO_OR_NULL_PTR(mem)) {
61                 mem->ptr = ptr;
62                 mem->size = size;
63                 strncpy(mem->function, function, MAX_FUNC_NAME);
64                 mem->function[MAX_FUNC_NAME-1] = '\0';
65                 mem->next = NULL;
66                 if (NULL == list_tail) {
67                         list_head = mem;
68                 } else {
69                         list_tail->next = mem;
70                 }
71                 list_tail = mem;
72         }
73         return ptr;
74 }
75
76 static inline void _os_free(void *ptr, const char *function) {
77         printk(KERN_DEBUG "%s OS_FREE(0x%p)\n", function, ptr);
78         if (NULL != list_head) {
79                 os_allocd_mem *mem = list_head;
80                 os_allocd_mem *prev = NULL;
81                 while (NULL != mem) {
82                         if (mem->ptr == ptr) {
83                                 if (mem == list_head) {
84                                         list_head = mem->next;
85                                         if (mem == list_tail) {
86                                                 list_tail = NULL;
87                                         }
88                                 } else {
89                                         prev->next = mem->next;
90                                         if (mem == list_tail) {
91                                                 list_tail = prev;
92                                         }
93                                 }
94                                 kfree(mem);
95                                 break;
96                         }
97                         prev = mem;
98                         mem = mem->next;
99                 }
100         }
101         kfree(ptr);
102 }
103
104 static inline void emgd_report_unfreed_memory(void) {
105         os_allocd_mem *mem = list_head;
106         os_allocd_mem *prev;
107
108         printk(KERN_DEBUG "%s() REPORT ON NON-FREED MEMORY:\n", __FUNCTION__);
109         while (NULL != mem) {
110                 printk(KERN_DEBUG "  addr=0x%p, size=%u, function=\"%s\"\n",
111                                 mem->ptr, mem->size, mem->function);
112                 prev = mem;
113                 mem = mem->next;
114                 kfree(prev);
115         }
116 }
117
118
119 /*!
120  * void *OS_ALLOC(size_t size)
121  *
122  * OS_ALLOC is used by OS independent code to allocate system memory and
123  * return a CPU writeable address to the allocated memory (Virtual address)
124  * The returned address has no guarenteed alignment.
125  * size should be <= 4k for larger sizes use OS_ALLOC_LARGE().
126  *
127  * Allocations returned from OS_ALLOC() should be freed with OS_FREE().
128  *
129  * All Full OAL implementations must implement the _OS_ALLOC entry point
130  * to enable use of this function.
131  *
132  * @return NULL on Failure
133  * @return Virtual or Flat address on Success
134  */
135 #define OS_ALLOC(a) _os_alloc(a, __FUNCTION__)
136
137 /*!
138  * void OS_FREE(void *p)
139  * OS_FREE should be used to free allocations returned from OS_ALLOC()
140  *
141  * All Full OAL implementations must implement the _OS_FREE entry point
142  * to enable use of this function.
143  */
144 #define OS_FREE(a) _os_free(a, __FUNCTION__)
145
146 /*!
147  * void *OS_ALLOC_LARGE(size_t size)
148  *
149  * OS_ALLOC_LARGE is used by OS independent code to allocate system memory
150  * in the same manner as OS_ALLOC except that size must be > 4k.
151  *
152  * Allocations returned from OS_ALLOC_LARGE() should be freed with
153  * OS_FREE_LARGE().
154  *
155  * All Full OAL implementations must implement the _OS_ALLOC_LARGE entry point
156  * to enable use of this function. This entry point may be implemented
157  * exactly the same as _OS_ALLOC is no diferentiation is required.
158  *
159  * @return NULL on Failure
160  * @return Virtual or Flat address on Success
161  */
162 #define OS_ALLOC_LARGE(a) _os_alloc(a, __FUNCTION__)
163
164 /*!
165  * void OS_FREE_LARGE(void *p)
166  * OS_FREE_LARGE should be used to free allocations returned from
167  * OS_ALLOC_LARGE()
168  *
169  * All Full OAL implementations must implement the _OS_FREE_LARGE entry point
170  * to enable use of this function. This entry point may be implemented
171  * exactly the same as _OS_FREE is no diferentiation is required.
172  *
173  */
174 #define OS_FREE_LARGE(a) _os_free(a, __FUNCTION__)
175
176 #else /* INSTRUMENT_KERNEL_ALLOCS */
177
178 #define OS_ALLOC(a) kmalloc((a), GFP_KERNEL)
179 #define OS_FREE(a) kfree(a)
180 #define OS_ALLOC_LARGE(a) kmalloc((a), GFP_KERNEL)
181 #define OS_FREE_LARGE(a) kfree(a)
182
183 #endif /* INSTRUMENT_KERNEL_ALLOCS */
184
185 #define OS_ALLOC_PAGE() NULL
186 /*!
187  * void *OS_VIRT_TO_PHYS( void *p )
188  *
189  * OS_VIRT_TO_PHYS is used by OS independent code to obtain the physical
190  * address referenced by the virtual address p. The virtual address must be
191  * one returned by OS_ALLOC_PAGE or OS_ALLOC_CONTIGUOUS.
192  *
193  * This entry point is OPTIONAL. Only OAL implementations that have
194  * implemented the _OS_ALLOC_PAGE or _OS_ALLOC_CONTIGUOUS macros need
195  * implement the _OS_VIRT_TO_PHYS macro. OS independent code that must
196  * function on all implementation may not use this entry point.
197  *
198  * @returns Physical Address
199  */
200 #define OS_VIRT_TO_PHYS(a) os_gart_virt_to_phys(a)
201
202 /*!
203  * void OS_FREE_PAGE(void *p)
204  * OS_FREE_PAGE should be used to free allocations returned from
205  * OS_ALLOC_PAGE()
206  *
207  * This entry point is OPTIONAL. Only OAL implementations that have implemented
208  * the _OS_ALLOC_PAGE macro need implement the _OS_FREE_PAGE macro.
209  */
210 #define OS_FREE_PAGE(a) os_gart_free_page(a)
211
212 #define OS_MEMSET(a,b,c) memset(a,b,c)
213 #define OS_MEMCPY(a,b,c) memcpy(a,b,c)
214 #define OS_MEMCMP(a,b,c) memcmp(a,b,c)
215
216 #define OS_OFFSETOF(t,m) offsetof(t,m)
217
218
219 /*
220  * void *OS_MEMSET(void *s, int c, size_t n)
221  *
222  * OS_MEMSET sets all bytes of the memory area referenced by address s and
223  * size n to the char value c.
224  *
225  * ALL Full OAL implementations must implement the entry point _OS_MEMSET
226  * to enable use of this function.
227  *
228  * @returns Address s
229  */
230 #ifndef OS_MEMSET
231 #define OS_MEMSET(a,b,c) _oal_memset(a,b,c)
232 #endif
233
234 /*
235  * void *OS_MEMCPY(void *dest, void *src, size_t n)
236  *
237  * OS_MEMCPY copies n bytes from the memory referenced by src to the
238  * memory referenced by dest. The areas may not overlap.
239  *
240  * ALL Full OAL implementations must implement the entry point _OS_MEMCPY
241  * to enable use of this function.
242  *
243  * @returns Address dest
244  */
245 #ifndef OS_MEMCPY
246 #define OS_MEMCPY(a,b,c) _oal_memcpy(a,b,c)
247 #endif
248
249 /*
250  * void *OS_MEMCMP(void *s1, void *s2, size_t n)
251  *
252  * OS_MEMCMP compares n bytes from the memory referenced by s1 to the
253  * corresponding bytes referenced by s2.
254  *
255  * This entry point is available in all full OAL implementations. An OAL
256  * may implement _OS_MEMCMP macro or the built-in version will be used.
257  *
258  * @returns < 0 if the s1 value is less than s2
259  * @returns > 0 if the s1 value is greater than s2
260  * @returns 0 if the values are equal
261  */
262 #ifndef OS_MEMCMP
263 #define OS_MEMCMP(a,b,c) _oal_memcmp(a,b,c)
264 #endif
265
266
267 /*
268  * void *OS_MEMZERO(void *s, size_t n)
269  *
270  * OS_MEMZERO sets all bytes of the memory area referenced by address s and
271  * size n to 0.
272  *
273  * This entry point is available in all full OAL implementations. An OAL
274  * may implement _OS_MEMZERO macro or the built-in version making use of
275  * of _OS_MEMSET will be used.
276  *
277  * @returns Address s
278  */
279 #ifndef OS_MEMZERO
280 #define OS_MEMZERO(a,b)  OS_MEMSET(a, 0, b)
281 #endif
282
283 /*
284  * void *OS_MEMZERO(void *s, size_t n)
285  *
286  * OS_MEMZERO sets all bytes of the memory area referenced by address s and
287  * size n to 0.
288  *
289  * This entry point is available in all full OAL implementations. An OAL
290  * may implement _OS_MEMZERO macro or the built-in version making use of
291  * of _OS_MEMSET will be used.
292  *
293  * @returns Address s
294  */
295 #ifndef OS_STRNCPY
296 #define OS_STRNCPY(d, s, n)  _oal_strncpy(d, s, n)
297 #endif
298
299
300
301
302
303 /*!
304  * void *OS_ALLOC_CONTIGUOUS( size_t n, size_t align )
305  *
306  * OS_ALLOC_CONTIGUOUS is used by OS independent code to allocate a number
307  * of aligned system memory pages and return a CPU writeable address to the
308  * allocated memory (Virtual address) The returned address must point to
309  * physically contiguous memory aligned to the requested alignment.
310  *
311  * Allocations returned from OS_ALLOC_CONTIGUOUS() should be freed with
312  * OS_FREE_CONTIGUOUS().
313  *
314  * This entry point is OPTIONAL. Only OAL implementations that have the
315  * ability to allocate such pages need implement the _OS_ALLOC_CONTIGUOUS
316  * macro. OS independent code that must function on all implementation may
317  * not use this entry point.
318  *
319  * @return NULL on Failure
320  * @return Virtual or Flat address on Success
321  */
322 #define OS_ALLOC_CONTIGUOUS(a,b) _OS_ALLOC_CONTIGUOUS(a,b)
323 /*!
324  * void OS_FREE_CONTIGUOUS(void *p)
325  * OS_FREE_CONTIGUOUS should be used to free allocations returned from
326  * OS_ALLOC_CONTIGUOUS()
327  *
328  * This entry point is OPTIONAL. Only OAL implementations that have implemented
329  * the _OS_ALLOC_CONTIGUOUS macro need implement the _OS_FREE_CONTIGUOUS macro.
330  */
331 #define OS_FREE_CONTIGUOUS(a) _OS_FREE_CONTIGUOUS(a)
332
333 /*!
334  * size_t OS_OFFSETOF(type, member)
335  *
336  * OS_OFFSETOF is used by OS independent code to obtain the offset of a
337  * given member within a type.
338  *
339  * @returns size_t of the offset of member m within type t
340  */
341 #ifndef OS_OFFSETOF
342 #define OS_OFFSETOF(t,m) ((size_t)&(((t *)0)->m))
343 #endif
344
345 /*
346  * This is a OS independent helper is case the operating environment
347  * does not supply a memcmp() function. The OAL may use this implementation.
348  */
349 static __inline int _oal_memcmp(const void *s1, const void *s2, unsigned long n)
350 {
351         const unsigned char *cs1 = (const unsigned char *) s1;
352         const unsigned char *cs2 = (const unsigned char *)s2;
353
354         for ( ; n-- > 0; cs1++, cs2++) {
355                 if (*cs1 != *cs2) {
356                         return *cs1 - *cs2;
357                 }
358         }
359         return 0;
360 }
361
362 static __inline void *_oal_memcpy(void *dest, const void *src, size_t n)
363 {
364         size_t i;
365
366         i=0;
367         while( i < n ) {
368                 ((unsigned char *)dest)[i] = ((unsigned char *)src)[i];
369                 i++;
370         }
371         return dest;
372 }
373
374 static __inline char *_oal_strncpy(char *dest, const char *src, size_t n)
375 {
376         size_t i;
377
378         for(i=0; i<n; i++) {
379                 if(!(dest[i] = src[i])) {
380                         for(i=i; i<n; i++) {
381                                 dest[i] = '\0';
382                         }
383                         return dest;
384                 }
385         }
386         return dest;
387 }
388
389 static __inline void *_oal_memset(void *s, int c, size_t n)
390 {
391         unsigned int i;
392         for(i=0; i<n; i++) {
393                 ((unsigned char *)s)[i] = (unsigned char)c;
394         }
395         return s;
396 }
397
398 /*
399  * These macros are optional for the OAL port. They are used to do memory
400  * management for virtual apterture space process.
401  */
402
403 #ifdef _OS_MAP_STOLEN_MEM
404 #define OS_MAP_STOLEN_MEM(a, b, c)        _OS_MAP_STOLEN_MEM(a, b, c)
405 #else
406 #define OS_MAP_STOLEN_MEM(a, b, c)        0
407 #endif
408
409 #ifdef _OS_VIRT_APERT_AVAILABLE
410 #define OS_VIRT_APERT_AVAILABLE()         _OS_VIRT_APERT_AVAILABLE()
411 #else
412 #define OS_VIRT_APERT_AVAILABLE()         0
413 #endif
414
415 #ifdef _OS_GET_VIRT_APERT_BASE
416 #define OS_GET_VIRT_APERT_BASE()          _OS_GET_VIRT_APERT_BASE()
417 #else
418 #define OS_GET_VIRT_APERT_BASE()          NULL
419 #endif
420
421 #endif