aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/pvr/pvr_debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/pvr/pvr_debug.c')
-rw-r--r--drivers/gpu/pvr/pvr_debug.c420
1 files changed, 420 insertions, 0 deletions
diff --git a/drivers/gpu/pvr/pvr_debug.c b/drivers/gpu/pvr/pvr_debug.c
new file mode 100644
index 00000000000..091f6590e70
--- /dev/null
+++ b/drivers/gpu/pvr/pvr_debug.c
@@ -0,0 +1,420 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef AUTOCONF_INCLUDED
28 #include <linux/config.h>
29#endif
30
31#include <asm/io.h>
32#include <asm/uaccess.h>
33#include <linux/kernel.h>
34#include <linux/hardirq.h>
35#include <linux/module.h>
36#include <linux/spinlock.h>
37#include <linux/string.h>
38#include <stdarg.h>
39#include "img_types.h"
40#include "servicesext.h"
41#include "pvr_debug.h"
42#include "srvkm.h"
43#include "proc.h"
44#include "mutex.h"
45#include "linkage.h"
46#include "pvr_uaccess.h"
47
48static IMG_BOOL VBAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz,
49 const IMG_CHAR* pszFormat, va_list VArgs)
50 IMG_FORMAT_PRINTF(3, 0);
51
52
53#if defined(PVRSRV_NEED_PVR_DPF)
54
55#define PVR_MAX_FILEPATH_LEN 256
56
57static IMG_BOOL BAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz,
58 const IMG_CHAR *pszFormat, ...)
59 IMG_FORMAT_PRINTF(3, 4);
60
61IMG_UINT32 gPVRDebugLevel =
62 (DBGPRIV_FATAL | DBGPRIV_ERROR | DBGPRIV_WARNING);
63
64#endif
65
66#define PVR_MAX_MSG_LEN PVR_MAX_DEBUG_MESSAGE_LEN
67
68static IMG_CHAR gszBufferNonIRQ[PVR_MAX_MSG_LEN + 1];
69
70static IMG_CHAR gszBufferIRQ[PVR_MAX_MSG_LEN + 1];
71
72static PVRSRV_LINUX_MUTEX gsDebugMutexNonIRQ;
73
74
75static spinlock_t gsDebugLockIRQ = SPIN_LOCK_UNLOCKED;
76
77#if !defined (USE_SPIN_LOCK)
78#define USE_SPIN_LOCK (in_interrupt() || !preemptible())
79#endif
80
81static inline void GetBufferLock(unsigned long *pulLockFlags)
82{
83 if (USE_SPIN_LOCK)
84 {
85 spin_lock_irqsave(&gsDebugLockIRQ, *pulLockFlags);
86 }
87 else
88 {
89 LinuxLockMutex(&gsDebugMutexNonIRQ);
90 }
91}
92
93static inline void ReleaseBufferLock(unsigned long ulLockFlags)
94{
95 if (USE_SPIN_LOCK)
96 {
97 spin_unlock_irqrestore(&gsDebugLockIRQ, ulLockFlags);
98 }
99 else
100 {
101 LinuxUnLockMutex(&gsDebugMutexNonIRQ);
102 }
103}
104
105static inline void SelectBuffer(IMG_CHAR **ppszBuf, IMG_UINT32 *pui32BufSiz)
106{
107 if (USE_SPIN_LOCK)
108 {
109 *ppszBuf = gszBufferIRQ;
110 *pui32BufSiz = sizeof(gszBufferIRQ);
111 }
112 else
113 {
114 *ppszBuf = gszBufferNonIRQ;
115 *pui32BufSiz = sizeof(gszBufferNonIRQ);
116 }
117}
118
119static IMG_BOOL VBAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, const IMG_CHAR* pszFormat, va_list VArgs)
120{
121 IMG_UINT32 ui32Used;
122 IMG_UINT32 ui32Space;
123 IMG_INT32 i32Len;
124
125 ui32Used = strlen(pszBuf);
126 BUG_ON(ui32Used >= ui32BufSiz);
127 ui32Space = ui32BufSiz - ui32Used;
128
129 i32Len = vsnprintf(&pszBuf[ui32Used], ui32Space, pszFormat, VArgs);
130 pszBuf[ui32BufSiz - 1] = 0;
131
132
133 return (i32Len < 0 || i32Len >= (IMG_INT32)ui32Space) ? IMG_TRUE : IMG_FALSE;
134}
135
136IMG_VOID PVRDPFInit(IMG_VOID)
137{
138 LinuxInitMutex(&gsDebugMutexNonIRQ);
139}
140
141IMG_VOID PVRSRVReleasePrintf(const IMG_CHAR *pszFormat, ...)
142{
143 va_list vaArgs;
144 unsigned long ulLockFlags = 0;
145 IMG_CHAR *pszBuf;
146 IMG_UINT32 ui32BufSiz;
147
148 SelectBuffer(&pszBuf, &ui32BufSiz);
149
150 va_start(vaArgs, pszFormat);
151
152 GetBufferLock(&ulLockFlags);
153 strncpy (pszBuf, "PVR_K: ", (ui32BufSiz -1));
154
155 if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs))
156 {
157 printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
158 }
159 else
160 {
161 printk(KERN_INFO "%s\n", pszBuf);
162 }
163
164 ReleaseBufferLock(ulLockFlags);
165 va_end(vaArgs);
166
167}
168
169#if defined(PVRSRV_NEED_PVR_ASSERT)
170
171IMG_VOID PVRSRVDebugAssertFail(const IMG_CHAR* pszFile, IMG_UINT32 uLine)
172{
173 PVRSRVDebugPrintf(DBGPRIV_FATAL, pszFile, uLine, "Debug assertion failed!");
174 BUG();
175}
176
177#endif
178
179#if defined(PVRSRV_NEED_PVR_TRACE)
180
181IMG_VOID PVRSRVTrace(const IMG_CHAR* pszFormat, ...)
182{
183 va_list VArgs;
184 unsigned long ulLockFlags = 0;
185 IMG_CHAR *pszBuf;
186 IMG_UINT32 ui32BufSiz;
187
188 SelectBuffer(&pszBuf, &ui32BufSiz);
189
190 va_start(VArgs, pszFormat);
191
192 GetBufferLock(&ulLockFlags);
193
194 strncpy(pszBuf, "PVR: ", (ui32BufSiz -1));
195
196 if (VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs))
197 {
198 printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
199 }
200 else
201 {
202 printk(KERN_INFO "%s\n", pszBuf);
203 }
204
205 ReleaseBufferLock(ulLockFlags);
206
207 va_end(VArgs);
208}
209
210#endif
211
212#if defined(PVRSRV_NEED_PVR_DPF)
213
214static IMG_BOOL BAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, const IMG_CHAR *pszFormat, ...)
215{
216 va_list VArgs;
217 IMG_BOOL bTrunc;
218
219 va_start (VArgs, pszFormat);
220
221 bTrunc = VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs);
222
223 va_end (VArgs);
224
225 return bTrunc;
226}
227
228IMG_VOID PVRSRVDebugPrintf (
229 IMG_UINT32 ui32DebugLevel,
230 const IMG_CHAR* pszFullFileName,
231 IMG_UINT32 ui32Line,
232 const IMG_CHAR* pszFormat,
233 ...
234 )
235{
236 IMG_BOOL bTrace;
237 const IMG_CHAR *pszFileName = pszFullFileName;
238 IMG_CHAR *pszLeafName;
239
240
241 bTrace = (IMG_BOOL)(ui32DebugLevel & DBGPRIV_CALLTRACE) ? IMG_TRUE : IMG_FALSE;
242
243 if (gPVRDebugLevel & ui32DebugLevel)
244 {
245 va_list vaArgs;
246 unsigned long ulLockFlags = 0;
247 IMG_CHAR *pszBuf;
248 IMG_UINT32 ui32BufSiz;
249
250 SelectBuffer(&pszBuf, &ui32BufSiz);
251
252 va_start(vaArgs, pszFormat);
253
254 GetBufferLock(&ulLockFlags);
255
256
257 if (bTrace == IMG_FALSE)
258 {
259 switch(ui32DebugLevel)
260 {
261 case DBGPRIV_FATAL:
262 {
263 strncpy (pszBuf, "PVR_K:(Fatal): ", (ui32BufSiz -1));
264 break;
265 }
266 case DBGPRIV_ERROR:
267 {
268 strncpy (pszBuf, "PVR_K:(Error): ", (ui32BufSiz -1));
269 break;
270 }
271 case DBGPRIV_WARNING:
272 {
273 strncpy (pszBuf, "PVR_K:(Warning): ", (ui32BufSiz -1));
274 break;
275 }
276 case DBGPRIV_MESSAGE:
277 {
278 strncpy (pszBuf, "PVR_K:(Message): ", (ui32BufSiz -1));
279 break;
280 }
281 case DBGPRIV_VERBOSE:
282 {
283 strncpy (pszBuf, "PVR_K:(Verbose): ", (ui32BufSiz -1));
284 break;
285 }
286 default:
287 {
288 strncpy (pszBuf, "PVR_K:(Unknown message level)", (ui32BufSiz -1));
289 break;
290 }
291 }
292 }
293 else
294 {
295 strncpy (pszBuf, "PVR_K: ", (ui32BufSiz -1));
296 }
297
298 if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs))
299 {
300 printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
301 }
302 else
303 {
304
305 if (bTrace == IMG_FALSE)
306 {
307#ifdef DEBUG_LOG_PATH_TRUNCATE
308
309 static IMG_CHAR szFileNameRewrite[PVR_MAX_FILEPATH_LEN];
310
311 IMG_CHAR* pszTruncIter;
312 IMG_CHAR* pszTruncBackInter;
313
314
315 pszFileName = pszFullFileName + strlen(DEBUG_LOG_PATH_TRUNCATE)+1;
316
317
318 strncpy(szFileNameRewrite, pszFileName,PVR_MAX_FILEPATH_LEN);
319
320 if(strlen(szFileNameRewrite) == PVR_MAX_FILEPATH_LEN-1) {
321 IMG_CHAR szTruncateMassage[] = "FILENAME TRUNCATED";
322 strcpy(szFileNameRewrite + (PVR_MAX_FILEPATH_LEN - 1 - strlen(szTruncateMassage)), szTruncateMassage);
323 }
324
325 pszTruncIter = szFileNameRewrite;
326 while(*pszTruncIter++ != 0)
327 {
328 IMG_CHAR* pszNextStartPoint;
329
330 if(
331 !( ( *pszTruncIter == '/' && (pszTruncIter-4 >= szFileNameRewrite) ) &&
332 ( *(pszTruncIter-1) == '.') &&
333 ( *(pszTruncIter-2) == '.') &&
334 ( *(pszTruncIter-3) == '/') )
335 ) continue;
336
337
338 pszTruncBackInter = pszTruncIter - 3;
339 while(*(--pszTruncBackInter) != '/')
340 {
341 if(pszTruncBackInter <= szFileNameRewrite) break;
342 }
343 pszNextStartPoint = pszTruncBackInter;
344
345
346 while(*pszTruncIter != 0)
347 {
348 *pszTruncBackInter++ = *pszTruncIter++;
349 }
350 *pszTruncBackInter = 0;
351
352
353 pszTruncIter = pszNextStartPoint;
354 }
355
356 pszFileName = szFileNameRewrite;
357
358 if(*pszFileName == '/') pszFileName++;
359#endif
360
361#if !defined(__sh__)
362 pszLeafName = (IMG_CHAR *)strrchr (pszFileName, '\\');
363
364 if (pszLeafName)
365 {
366 pszFileName = pszLeafName;
367 }
368#endif
369
370 if (BAppend(pszBuf, ui32BufSiz, " [%u, %s]", ui32Line, pszFileName))
371 {
372 printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
373 }
374 else
375 {
376 printk(KERN_INFO "%s\n", pszBuf);
377 }
378 }
379 else
380 {
381 printk(KERN_INFO "%s\n", pszBuf);
382 }
383 }
384
385 ReleaseBufferLock(ulLockFlags);
386
387 va_end (vaArgs);
388 }
389}
390
391#endif
392
393#if defined(DEBUG)
394
395IMG_INT PVRDebugProcSetLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data)
396{
397#define _PROC_SET_BUFFER_SZ 2
398 IMG_CHAR data_buffer[_PROC_SET_BUFFER_SZ];
399
400 if (count != _PROC_SET_BUFFER_SZ)
401 {
402 return -EINVAL;
403 }
404 else
405 {
406 if (pvr_copy_from_user(data_buffer, buffer, count))
407 return -EINVAL;
408 if (data_buffer[count - 1] != '\n')
409 return -EINVAL;
410 gPVRDebugLevel = data_buffer[0] - '0';
411 }
412 return (count);
413}
414
415void ProcSeqShowDebugLevel(struct seq_file *sfile,void* el)
416{
417 seq_printf(sfile, "%u\n", gPVRDebugLevel);
418}
419
420#endif