diff options
Diffstat (limited to 'drivers/gpu/pvr/pvr_debug.c')
-rw-r--r-- | drivers/gpu/pvr/pvr_debug.c | 420 |
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 | |||
48 | static 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 | |||
57 | static IMG_BOOL BAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, | ||
58 | const IMG_CHAR *pszFormat, ...) | ||
59 | IMG_FORMAT_PRINTF(3, 4); | ||
60 | |||
61 | IMG_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 | |||
68 | static IMG_CHAR gszBufferNonIRQ[PVR_MAX_MSG_LEN + 1]; | ||
69 | |||
70 | static IMG_CHAR gszBufferIRQ[PVR_MAX_MSG_LEN + 1]; | ||
71 | |||
72 | static PVRSRV_LINUX_MUTEX gsDebugMutexNonIRQ; | ||
73 | |||
74 | |||
75 | static spinlock_t gsDebugLockIRQ = SPIN_LOCK_UNLOCKED; | ||
76 | |||
77 | #if !defined (USE_SPIN_LOCK) | ||
78 | #define USE_SPIN_LOCK (in_interrupt() || !preemptible()) | ||
79 | #endif | ||
80 | |||
81 | static 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 | |||
93 | static 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 | |||
105 | static 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 | |||
119 | static 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 | |||
136 | IMG_VOID PVRDPFInit(IMG_VOID) | ||
137 | { | ||
138 | LinuxInitMutex(&gsDebugMutexNonIRQ); | ||
139 | } | ||
140 | |||
141 | IMG_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 | |||
171 | IMG_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 | |||
181 | IMG_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 | |||
214 | static 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 | |||
228 | IMG_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 | |||
395 | IMG_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 | |||
415 | void ProcSeqShowDebugLevel(struct seq_file *sfile,void* el) | ||
416 | { | ||
417 | seq_printf(sfile, "%u\n", gPVRDebugLevel); | ||
418 | } | ||
419 | |||
420 | #endif | ||