]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/device-ti-proprietary-open.git/blob - omap5/sgx_src/eurasia_km/services4/srvkm/env/linux/pvr_debug.c
SGX-BIN: DDK update for OMAP5 1.9IMG2166536_TI.0003
[android-sdk/device-ti-proprietary-open.git] / omap5 / sgx_src / eurasia_km / services4 / srvkm / env / linux / pvr_debug.c
1 /*************************************************************************/ /*!
2 @Title          Debug Functionality
3 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
4 @Description    Provides kernel side Debug Functionality
5 @License        Dual MIT/GPLv2
7 The contents of this file are subject to the MIT license as set out below.
9 Permission is hereby granted, free of charge, to any person obtaining a copy
10 of this software and associated documentation files (the "Software"), to deal
11 in the Software without restriction, including without limitation the rights
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom the Software is
14 furnished to do so, subject to the following conditions:
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
19 Alternatively, the contents of this file may be used under the terms of
20 the GNU General Public License Version 2 ("GPL") in which case the provisions
21 of GPL are applicable instead of those above.
23 If you wish to allow use of your version of this file only under the terms of
24 GPL, and not to allow others to use your version of this file under the terms
25 of the MIT license, indicate your decision by deleting the provisions above
26 and replace them with the notice and other provisions required by GPL as set
27 out in the file called "GPL-COPYING" included in this distribution. If you do
28 not delete the provisions above, a recipient may use your version of this file
29 under the terms of either the MIT license or GPL.
31 This License is also included in this distribution in the file called
32 "MIT-COPYING".
34 EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
35 PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
36 BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
37 PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
38 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
39 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
40 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
41 */ /**************************************************************************/
43 #include <linux/version.h>
45 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
46 #ifndef AUTOCONF_INCLUDED
47 #include <linux/config.h>
48 #endif
49 #endif
51 #include <asm/io.h>
52 #include <asm/uaccess.h>
53 #include <linux/kernel.h>
54 #include <linux/hardirq.h>
55 #include <linux/module.h>
56 #include <linux/spinlock.h>
57 #include <linux/string.h>                       // strncpy, strlen
58 #include <stdarg.h>
59 #include "img_types.h"
60 #include "servicesext.h"
61 #include "pvr_debug.h"
62 #include "srvkm.h"
63 #include "proc.h"
64 #include "mutex.h"
65 #include "linkage.h"
66 #include "pvr_uaccess.h"
68 #if !defined(CONFIG_PREEMPT)
69 #define PVR_DEBUG_ALWAYS_USE_SPINLOCK
70 #endif
72 static IMG_BOOL VBAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz,
73                                                  const IMG_CHAR* pszFormat, va_list VArgs)
74                                                  IMG_FORMAT_PRINTF(3, 0);
77 #if defined(PVRSRV_NEED_PVR_DPF)
79 #define PVR_MAX_FILEPATH_LEN 256
81 static IMG_BOOL BAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz,
82                                                 const IMG_CHAR *pszFormat, ...)
83                                                 IMG_FORMAT_PRINTF(3, 4);
85 /* NOTE: Must NOT be static! Used in module.c.. */
86 IMG_UINT32 gPVRDebugLevel =
87         (DBGPRIV_FATAL | DBGPRIV_ERROR | DBGPRIV_WARNING);
89 #endif /* defined(PVRSRV_NEED_PVR_DPF) || defined(PVRSRV_NEED_PVR_TRACE) */
91 #define PVR_MAX_MSG_LEN PVR_MAX_DEBUG_MESSAGE_LEN
93 #if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
94 /* Message buffer for non-IRQ messages */
95 static IMG_CHAR gszBufferNonIRQ[PVR_MAX_MSG_LEN + 1];
96 #endif
98 /* Message buffer for IRQ messages */
99 static IMG_CHAR gszBufferIRQ[PVR_MAX_MSG_LEN + 1];
101 #if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
102 /* The lock is used to control access to gszBufferNonIRQ */
103 static PVRSRV_LINUX_MUTEX gsDebugMutexNonIRQ;
104 #endif
106 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39))
107 /* The lock is used to control access to gszBufferIRQ */
108 /* PRQA S 0671,0685 1 */ /* ignore warnings about C99 style initialisation */
109 static spinlock_t gsDebugLockIRQ = SPIN_LOCK_UNLOCKED;
110 #else
111 static DEFINE_SPINLOCK(gsDebugLockIRQ);
112 #endif
114 #if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
115 #if !defined (USE_SPIN_LOCK) /* to keep QAC happy */ 
116 #define USE_SPIN_LOCK (in_interrupt() || !preemptible())
117 #endif
118 #endif
120 static inline void GetBufferLock(unsigned long *pulLockFlags)
122 #if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
123         if (USE_SPIN_LOCK)
124 #endif
125         {
126                 spin_lock_irqsave(&gsDebugLockIRQ, *pulLockFlags);
127         }
128 #if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
129         else
130         {
131                 LinuxLockMutex(&gsDebugMutexNonIRQ);
132         }
133 #endif
136 static inline void ReleaseBufferLock(unsigned long ulLockFlags)
138 #if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
139         if (USE_SPIN_LOCK)
140 #endif
141         {
142                 spin_unlock_irqrestore(&gsDebugLockIRQ, ulLockFlags);
143         }
144 #if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
145         else
146         {
147                 LinuxUnLockMutex(&gsDebugMutexNonIRQ);
148         }
149 #endif
152 static inline void SelectBuffer(IMG_CHAR **ppszBuf, IMG_UINT32 *pui32BufSiz)
154 #if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
155         if (USE_SPIN_LOCK)
156 #endif
157         {
158                 *ppszBuf = gszBufferIRQ;
159                 *pui32BufSiz = sizeof(gszBufferIRQ);
160         }
161 #if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
162         else
163         {
164                 *ppszBuf = gszBufferNonIRQ;
165                 *pui32BufSiz = sizeof(gszBufferNonIRQ);
166         }
167 #endif
170 /*
171  * Append a string to a buffer using formatted conversion.
172  * The function takes a variable number of arguments, pointed
173  * to by the var args list.
174  */
175 static IMG_BOOL VBAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, const IMG_CHAR* pszFormat, va_list VArgs)
177         IMG_UINT32 ui32Used;
178         IMG_UINT32 ui32Space;
179         IMG_INT32 i32Len;
181         ui32Used = strlen(pszBuf);
182         BUG_ON(ui32Used >= ui32BufSiz);
183         ui32Space = ui32BufSiz - ui32Used;
185         i32Len = vsnprintf(&pszBuf[ui32Used], ui32Space, pszFormat, VArgs);
186         pszBuf[ui32BufSiz - 1] = 0;
188         /* Return true if string was truncated */
189         return (i32Len < 0 || i32Len >= (IMG_INT32)ui32Space) ? IMG_TRUE : IMG_FALSE;
192 /* Actually required for ReleasePrintf too */
194 IMG_VOID PVRDPFInit(IMG_VOID)
196 #if !defined(PVR_DEBUG_ALWAYS_USE_SPINLOCK)
197     LinuxInitMutex(&gsDebugMutexNonIRQ);
198 #endif
201 /*!
202 ******************************************************************************
203         @Function    PVRSRVReleasePrintf
204         @Description To output an important message to the user in release builds
205         @Input       pszFormat - The message format string
206         @Input       ... - Zero or more arguments for use by the format string
207         @Return      None
208  ******************************************************************************/
209 IMG_VOID PVRSRVReleasePrintf(const IMG_CHAR *pszFormat, ...)
211         va_list vaArgs;
212         unsigned long ulLockFlags = 0;
213         IMG_CHAR *pszBuf;
214         IMG_UINT32 ui32BufSiz;
216         SelectBuffer(&pszBuf, &ui32BufSiz);
218         va_start(vaArgs, pszFormat);
220         GetBufferLock(&ulLockFlags);
221         strncpy (pszBuf, "PVR_K: ", (ui32BufSiz -1));
223         if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs))
224         {
225                 printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
226         }
227         else
228         {
229                 printk(KERN_INFO "%s\n", pszBuf);
230         }
232         ReleaseBufferLock(ulLockFlags);
233         va_end(vaArgs);
237 #if defined(PVRSRV_NEED_PVR_TRACE)
239 /*!
240 ******************************************************************************
241         @Function    PVRTrace
242         @Description To output a debug message to the user
243         @Input       pszFormat - The message format string
244         @Input       ... - Zero or more arguments for use by the format string
245         @Return      None
246  ******************************************************************************/
247 IMG_VOID PVRSRVTrace(const IMG_CHAR* pszFormat, ...)
249         va_list VArgs;
250         unsigned long ulLockFlags = 0;
251         IMG_CHAR *pszBuf;
252         IMG_UINT32 ui32BufSiz;
254         SelectBuffer(&pszBuf, &ui32BufSiz);
256         va_start(VArgs, pszFormat);
258         GetBufferLock(&ulLockFlags);
260         strncpy(pszBuf, "PVR: ", (ui32BufSiz -1));
262         if (VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs))
263         {
264                 printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
265         }
266         else
267         {
268                 printk(KERN_INFO "%s\n", pszBuf);
269         }
271         ReleaseBufferLock(ulLockFlags);
273         va_end(VArgs);
276 #endif /* defined(PVRSRV_NEED_PVR_TRACE) */
278 #if defined(PVRSRV_NEED_PVR_DPF)
280 /*
281  * Append a string to a buffer using formatted conversion.
282  * The function takes a variable number of arguments, calling
283  * VBAppend to do the actual work.
284  */
285 static IMG_BOOL BAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, const IMG_CHAR *pszFormat, ...)
287         va_list VArgs;
288         IMG_BOOL bTrunc;
290         va_start (VArgs, pszFormat);
292         bTrunc = VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs);
294         va_end (VArgs);
296         return bTrunc;
299 /*!
300 ******************************************************************************
301         @Function    PVRSRVDebugPrintf
302         @Description To output a debug message to the user
303         @Input       uDebugLevel - The current debug level
304         @Input       pszFile - The source file generating the message
305         @Input       uLine - The line of the source file
306         @Input       pszFormat - The message format string
307         @Input       ... - Zero or more arguments for use by the format string
308         @Return      None
309  ******************************************************************************/
310 IMG_VOID PVRSRVDebugPrintf      (
311                                                 IMG_UINT32      ui32DebugLevel,
312                                                 const IMG_CHAR* pszFullFileName,
313                                                 IMG_UINT32      ui32Line,
314                                                 const IMG_CHAR* pszFormat,
315                                                 ...
316                                         )
318         IMG_BOOL bTrace;
319         const IMG_CHAR *pszFileName = pszFullFileName;
320         IMG_CHAR *pszLeafName;
323         bTrace = (IMG_BOOL)(ui32DebugLevel & DBGPRIV_CALLTRACE) ? IMG_TRUE : IMG_FALSE;
325         if (gPVRDebugLevel & ui32DebugLevel)
326         {
327                 va_list vaArgs;
328                 unsigned long ulLockFlags = 0;
329                 IMG_CHAR *pszBuf;
330                 IMG_UINT32 ui32BufSiz;
332                 SelectBuffer(&pszBuf, &ui32BufSiz);
334                 va_start(vaArgs, pszFormat);
336                 GetBufferLock(&ulLockFlags);
338                 /* Add in the level of warning */
339                 if (bTrace == IMG_FALSE)
340                 {
341                         switch(ui32DebugLevel)
342                         {
343                                 case DBGPRIV_FATAL:
344                                 {
345                                         strncpy (pszBuf, "PVR_K:(Fatal): ", (ui32BufSiz -1));
346                                         break;
347                                 }
348                                 case DBGPRIV_ERROR:
349                                 {
350                                         strncpy (pszBuf, "PVR_K:(Error): ", (ui32BufSiz -1));
351                                         break;
352                                 }
353                                 case DBGPRIV_WARNING:
354                                 {
355                                         strncpy (pszBuf, "PVR_K:(Warning): ", (ui32BufSiz -1));
356                                         break;
357                                 }
358                                 case DBGPRIV_MESSAGE:
359                                 {
360                                         strncpy (pszBuf, "PVR_K:(Message): ", (ui32BufSiz -1));
361                                         break;
362                                 }
363                                 case DBGPRIV_VERBOSE:
364                                 {
365                                         strncpy (pszBuf, "PVR_K:(Verbose): ", (ui32BufSiz -1));
366                                         break;
367                                 }
368                                 default:
369                                 {
370                                         strncpy (pszBuf, "PVR_K:(Unknown message level)", (ui32BufSiz -1));
371                                         break;
372                                 }
373                         }
374                 }
375                 else
376                 {
377                         strncpy (pszBuf, "PVR_K: ", (ui32BufSiz -1));
378                 }
380                 if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs))
381                 {
382                         printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
383                 }
384                 else
385                 {
386                         /* Traces don't need a location */
387                         if (bTrace == IMG_FALSE)
388                         {
389 #ifdef DEBUG_LOG_PATH_TRUNCATE
390                                 /* Buffer for rewriting filepath in log messages */
391                                 static IMG_CHAR szFileNameRewrite[PVR_MAX_FILEPATH_LEN];
393                                 IMG_CHAR* pszTruncIter;
394                                 IMG_CHAR* pszTruncBackInter;
396                                 /* Truncate path (DEBUG_LOG_PATH_TRUNCATE shoud be set to EURASIA env var)*/
397                                 if (strlen(pszFullFileName) > strlen(DEBUG_LOG_PATH_TRUNCATE)+1)
398                                         pszFileName = pszFullFileName + strlen(DEBUG_LOG_PATH_TRUNCATE)+1;
400                                 /* Try to find '/../' entries and remove it together with
401                                    previous entry. Repeat unit all removed */
402                                 strncpy(szFileNameRewrite, pszFileName,PVR_MAX_FILEPATH_LEN);
404                                 if(strlen(szFileNameRewrite) == PVR_MAX_FILEPATH_LEN-1) {
405                                         IMG_CHAR szTruncateMassage[] = "FILENAME TRUNCATED";
406                                         strcpy(szFileNameRewrite + (PVR_MAX_FILEPATH_LEN - 1 - strlen(szTruncateMassage)), szTruncateMassage);
407                                 }
409                                 pszTruncIter = szFileNameRewrite;
410                                 while(*pszTruncIter++ != 0)
411                                 {
412                                         IMG_CHAR* pszNextStartPoint;
413                                         /* Find '/../' pattern */
414                                         if(
415                                            !( ( *pszTruncIter == '/' && (pszTruncIter-4 >= szFileNameRewrite) ) &&
416                                                  ( *(pszTruncIter-1) == '.') &&
417                                                  ( *(pszTruncIter-2) == '.') &&
418                                                  ( *(pszTruncIter-3) == '/') )
419                                            ) continue;
421                                         /* Find previous '/' */
422                                         pszTruncBackInter = pszTruncIter - 3;
423                                         while(*(--pszTruncBackInter) != '/')
424                                         {
425                                                 if(pszTruncBackInter <= szFileNameRewrite) break;
426                                         }
427                                         pszNextStartPoint = pszTruncBackInter;
429                                         /* Remove found region */
430                                         while(*pszTruncIter != 0)
431                                         {
432                                                 *pszTruncBackInter++ = *pszTruncIter++;
433                                         }
434                                         *pszTruncBackInter = 0;
436                                         /* Start again */
437                                         pszTruncIter = pszNextStartPoint;
438                                 }
440                                 pszFileName = szFileNameRewrite;
441                                 /* Remove first '/' if exist (it's always relative path */
442                                 if(*pszFileName == '/') pszFileName++;
443 #endif
445 #if !defined(__sh__)
446                                 pszLeafName = (IMG_CHAR *)strrchr (pszFileName, '\\');
448                                 if (pszLeafName)
449                                 {
450                                         pszFileName = pszLeafName;
451                         }
452 #endif /* __sh__ */
454                                 if (BAppend(pszBuf, ui32BufSiz, " [%u, %s]", ui32Line, pszFileName))
455                                 {
456                                         printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
457                                 }
458                                 else
459                                 {
460                                         printk(KERN_INFO "%s\n", pszBuf);
461                                 }
462                         }
463                         else
464                         {
465                                 printk(KERN_INFO "%s\n", pszBuf);
466                         }
467                 }
469                 ReleaseBufferLock(ulLockFlags);
471                 va_end (vaArgs);
472         }
475 #endif /* PVRSRV_NEED_PVR_DPF */
477 #if defined(DEBUG)
479 IMG_INT PVRDebugProcSetLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data)
481 #define _PROC_SET_BUFFER_SZ             6
482         IMG_CHAR data_buffer[_PROC_SET_BUFFER_SZ];
484         if (count > _PROC_SET_BUFFER_SZ)
485         {
486                 return -EINVAL;
487         }
488         else
489         {
490                 if (pvr_copy_from_user(data_buffer, buffer, count))
491                         return -EINVAL;
492                 if (data_buffer[count - 1] != '\n')
493                         return -EINVAL;
494                 if (sscanf(data_buffer, "%i", &gPVRDebugLevel) == 0)
495                         return -EINVAL;
496                 gPVRDebugLevel &= (1 << DBGPRIV_DBGLEVEL_COUNT) - 1;
497         }
498         return (count);
501 void ProcSeqShowDebugLevel(struct seq_file *sfile,void* el)
503         seq_printf(sfile, "%u\n", gPVRDebugLevel);
506 #endif /* defined(DEBUG) */