1 /*************************************************************************/ /*!
3 @Title PVR Debug Declarations
4 @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
5 @Description Provides debug functionality
6 @License Dual MIT/GPLv2
8 The contents of this file are subject to the MIT license as set out below.
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files (the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
17 The above copyright notice and this permission notice shall be included in
18 all copies or substantial portions of the Software.
20 Alternatively, the contents of this file may be used under the terms of
21 the GNU General Public License Version 2 ("GPL") in which case the provisions
22 of GPL are applicable instead of those above.
24 If you wish to allow use of your version of this file only under the terms of
25 GPL, and not to allow others to use your version of this file under the terms
26 of the MIT license, indicate your decision by deleting the provisions above
27 and replace them with the notice and other provisions required by GPL as set
28 out in the file called "GPL-COPYING" included in this distribution. If you do
29 not delete the provisions above, a recipient may use your version of this file
30 under the terms of either the MIT license or GPL.
32 This License is also included in this distribution in the file called
35 EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
36 PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
37 BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
38 PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
39 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
40 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
41 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42 */ /**************************************************************************/
44 #ifndef __PVR_DEBUG_H__
45 #define __PVR_DEBUG_H__
47 #include "img_types.h"
48 #include "pvrsrv_error.h"
52 # define MSC_SUPPRESS_4127 __pragma(warning(suppress:4127))
54 # define MSC_SUPPRESS_4127
57 #if defined (__cplusplus)
61 #define PVR_MAX_DEBUG_MESSAGE_LEN (512) /*!< Max length of a Debug Message */
63 /* These are privately used by pvr_debug, use the PVR_DBG_ defines instead */
64 #define DBGPRIV_FATAL 0x001UL /*!< Debug-Fatal. Privately used by pvr_debug. */
65 #define DBGPRIV_ERROR 0x002UL /*!< Debug-Error. Privately used by pvr_debug. */
66 #define DBGPRIV_WARNING 0x004UL /*!< Debug-Warning. Privately used by pvr_debug. */
67 #define DBGPRIV_MESSAGE 0x008UL /*!< Debug-Message. Privately used by pvr_debug. */
68 #define DBGPRIV_VERBOSE 0x010UL /*!< Debug-Verbose. Privately used by pvr_debug. */
69 #define DBGPRIV_CALLTRACE 0x020UL /*!< Debug-CallTrace. Privately used by pvr_debug. */
70 #define DBGPRIV_ALLOC 0x040UL /*!< Debug-Alloc. Privately used by pvr_debug. */
71 #define DBGPRIV_BUFFERED 0x080UL /*!< Debug-Buffered. Privately used by pvr_debug. */
72 #define DBGPRIV_DEBUG 0x100UL /*!< Debug-AdHoc-Debug. Never submitted. Privately used by pvr_debug. */
73 #define DBGPRIV_DBGDRV_MESSAGE 0x200UL /*!< Debug-DbgDrivMessage. Privately used by pvr_debug. */
74 #define DBGPRIV_LAST 0x200UL /*!< Always set to highest mask value. Privately used by pvr_debug. */
77 #if !defined(PVRSRV_NEED_PVR_ASSERT) && defined(DEBUG)
78 #define PVRSRV_NEED_PVR_ASSERT
81 //zxl: Force open debug info. gPVRDebugLevel is defined in pvr_debug.c
82 //#if defined(PVRSRV_NEED_PVR_ASSERT) && !defined(PVRSRV_NEED_PVR_DPF)
83 #define PVRSRV_NEED_PVR_DPF
86 #if !defined(PVRSRV_NEED_PVR_TRACE) && (defined(DEBUG) || defined(TIMING))
87 #define PVRSRV_NEED_PVR_TRACE
90 #if defined(__KERNEL__)
91 IMG_IMPORT const IMG_CHAR *PVRSRVGetErrorStringKM(PVRSRV_ERROR eError);
92 # define PVRSRVGETERRORSTRING PVRSRVGetErrorStringKM
94 IMG_IMPORT const IMG_CHAR *PVRSRVGetErrorString(PVRSRV_ERROR eError);
95 # define PVRSRVGETERRORSTRING PVRSRVGetErrorString
98 /* PVR_ASSERT() and PVR_DBG_BREAK handling */
100 #if defined(PVRSRV_NEED_PVR_ASSERT)
102 /* Unfortunately the klocworks static analysis checker doesn't understand our
103 * ASSERT macros. Thus it reports lots of false positive. Defining our Assert
104 * macros in a special way when the code is analysed by klocworks avoids
106 #if defined(__KLOCWORK__)
107 #define PVR_ASSERT(x) do { if (!(x)) abort(); } while (0)
108 #else /* ! __KLOCWORKS__ */
111 #define PVR_ASSERT(expr) do \
116 PVRSRVDebugPrintf(DBGPRIV_FATAL, __FILE__, __LINE__,\
117 "*** Debug assertion failed!"); \
125 #if defined(LINUX) && defined(__KERNEL__)
126 #include <linux/kernel.h>
127 #include <linux/bug.h>
129 /* In Linux kernel mode, use BUG() directly. This produces the correct
130 filename and line number in the panic message. */
131 #define PVR_ASSERT(EXPR) do \
135 PVRSRVDebugPrintf(DBGPRIV_FATAL, __FILE__, __LINE__, \
136 "Debug assertion failed!"); \
141 #else /* defined(LINUX) && defined(__KERNEL__) */
143 IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVDebugAssertFail(const IMG_CHAR *pszFile,
145 const IMG_CHAR *pszAssertion)
146 #if defined(__GNUC__)
147 __attribute__((noreturn))
151 #if defined(_MSC_VER)
152 /* This alternate definition is for MSVC, which warns about do {} while (0) */
153 #define PVR_ASSERT(EXPR) MSC_SUPPRESS_4127 \
154 if (!(EXPR)) PVRSRVDebugAssertFail(__FILE__, __LINE__)
156 #define PVR_ASSERT(EXPR) do \
159 PVRSRVDebugAssertFail(__FILE__, __LINE__, #EXPR); \
163 #endif /* defined(LINUX) && defined(__KERNEL__) */
164 #endif /* __KLOCWORKS__ */
165 #endif /* defined(PVRSRV_NEED_PVR_ASSERT)*/
167 #if defined(__KLOCWORK__)
168 #define PVR_DBG_BREAK do { abort(); } while (0)
171 #define PVR_DBG_BREAK __debugbreak(); /*!< Implementation of PVR_DBG_BREAK for (non-WinCE) Win32 */
173 #if defined(PVR_DBG_BREAK_ASSERT_FAIL)
174 /*!< Implementation of PVR_DBG_BREAK that maps onto PVRSRVDebugAssertFail */
176 #define PVR_DBG_BREAK DBG_BREAK
178 #if defined(LINUX) && defined(__KERNEL__)
179 #define PVR_DBG_BREAK BUG()
181 #define PVR_DBG_BREAK PVRSRVDebugAssertFail(__FILE__, __LINE__, "PVR_DBG_BREAK")
185 /*!< Null Implementation of PVR_DBG_BREAK (does nothing) */
186 #define PVR_DBG_BREAK
192 #else /* defined(PVRSRV_NEED_PVR_ASSERT) */
193 /* Unfortunately the klocworks static analysis checker doesn't understand our
194 * ASSERT macros. Thus it reports lots of false positive. Defining our Assert
195 * macros in a special way when the code is analysed by klocworks avoids
197 #if defined(__KLOCWORK__)
198 #define PVR_ASSERT(EXPR) do { if (!(EXPR)) abort(); } while (0)
200 #define PVR_ASSERT(EXPR) (IMG_VOID)(EXPR) /*!< Null Implementation of PVR_ASSERT (does nothing) */
203 #define PVR_DBG_BREAK /*!< Null Implementation of PVR_DBG_BREAK (does nothing) */
205 #endif /* defined(PVRSRV_NEED_PVR_ASSERT) */
208 /* PVR_DPF() handling */
210 #if defined(PVRSRV_NEED_PVR_DPF)
212 /* New logging mechanism */
213 #define PVR_DBG_FATAL DBGPRIV_FATAL
214 #define PVR_DBG_ERROR DBGPRIV_ERROR
215 #define PVR_DBG_WARNING DBGPRIV_WARNING
216 #define PVR_DBG_MESSAGE DBGPRIV_MESSAGE
217 #define PVR_DBG_VERBOSE DBGPRIV_VERBOSE
218 #define PVR_DBG_CALLTRACE DBGPRIV_CALLTRACE
219 #define PVR_DBG_ALLOC DBGPRIV_ALLOC
220 #define PVR_DBG_BUFFERED DBGPRIV_BUFFERED
221 #define PVR_DBG_DEBUG DBGPRIV_DEBUG
222 #define PVR_DBGDRIV_MESSAGE DBGPRIV_DBGDRV_MESSAGE
224 /* These levels are always on with PVRSRV_NEED_PVR_DPF */
225 #define __PVR_DPF_0x001UL(...) PVRSRVDebugPrintf(DBGPRIV_FATAL, __VA_ARGS__)
226 #define __PVR_DPF_0x002UL(...) PVRSRVDebugPrintf(DBGPRIV_ERROR, __VA_ARGS__)
227 #define __PVR_DPF_0x080UL(...) PVRSRVDebugPrintf(DBGPRIV_BUFFERED, __VA_ARGS__)
230 The AdHoc-Debug level is only supported when enabled in the local
231 build environment and may need to be used in both debug and release
232 builds. An error is generated in the formal build if it is checked in.
234 #if defined(PVR_DPF_ADHOC_DEBUG_ON)
235 #define __PVR_DPF_0x100UL(...) PVRSRVDebugPrintf(DBGPRIV_DEBUG, __VA_ARGS__)
237 /* Use an undefined token here to stop compilation dead in the offending module */
238 #define __PVR_DPF_0x100UL(...) __ERROR__PVR_DBG_DEBUG_is_in_use_but_has_not_been_enabled__Note_Debug_DPF_must_not_be_checked_in__Define_PVR_DPF_ADHOC_DEBUG_ON_for_testing
241 /* Some are compiled out completely in release builds */
243 #define __PVR_DPF_0x004UL(...) PVRSRVDebugPrintf(DBGPRIV_WARNING, __VA_ARGS__)
244 #define __PVR_DPF_0x008UL(...) PVRSRVDebugPrintf(DBGPRIV_MESSAGE, __VA_ARGS__)
245 #define __PVR_DPF_0x010UL(...) PVRSRVDebugPrintf(DBGPRIV_VERBOSE, __VA_ARGS__)
246 #define __PVR_DPF_0x020UL(...) PVRSRVDebugPrintf(DBGPRIV_CALLTRACE, __VA_ARGS__)
247 #define __PVR_DPF_0x040UL(...) PVRSRVDebugPrintf(DBGPRIV_ALLOC, __VA_ARGS__)
248 #define __PVR_DPF_0x200UL(...) PVRSRVDebugPrintf(DBGPRIV_DBGDRV_MESSAGE, __VA_ARGS__)
250 #define __PVR_DPF_0x004UL(...)
251 #define __PVR_DPF_0x008UL(...)
252 #define __PVR_DPF_0x010UL(...)
253 #define __PVR_DPF_0x020UL(...)
254 #define __PVR_DPF_0x040UL(...)
255 #define __PVR_DPF_0x200UL(...)
258 /* Translate the different log levels to separate macros
259 * so they can each be compiled out.
261 //zxl: Force open debug info. gPVRDebugLevel is defined in pvr_debug.c
263 #define __PVR_DPF(lvl, ...) __PVR_DPF_ ## lvl (__FILE__, __LINE__, __VA_ARGS__)
265 #define __PVR_DPF(lvl, ...) __PVR_DPF_ ## lvl ("", 0, __VA_ARGS__)
268 /* Get rid of the double bracketing */
269 #define PVR_DPF(x) __PVR_DPF x
271 #define PVR_LOG_ERROR(_rc, _call) \
272 PVR_DPF((PVR_DBG_ERROR, "%s() failed (%s) in %s()", _call, PVRSRVGETERRORSTRING(_rc), __func__));
274 #define PVR_LOG_IF_ERROR(_rc, _call) do \
275 { if (_rc != PVRSRV_OK) \
276 PVR_DPF((PVR_DBG_ERROR, "%s() failed (%s) in %s()", _call, PVRSRVGETERRORSTRING(_rc), __func__)); \
281 #define PVR_LOGR_IF_ERROR(_rc, _call) do \
282 { if (_rc != PVRSRV_OK) { \
283 PVR_DPF((PVR_DBG_ERROR, "%s() failed (%s) in %s()", _call, PVRSRVGETERRORSTRING(_rc), __func__)); \
288 #define PVR_LOGRN_IF_ERROR(_rc, _call) do \
289 { if (_rc != PVRSRV_OK) { \
290 PVR_DPF((PVR_DBG_ERROR, "%s() failed (%s) in %s()", _call, PVRSRVGETERRORSTRING(_rc), __func__)); \
295 #define PVR_LOGG_IF_ERROR(_rc, _call, _go) do \
296 { if (_rc != PVRSRV_OK) { \
297 PVR_DPF((PVR_DBG_ERROR, "%s() failed (%s) in %s()", _call, PVRSRVGETERRORSTRING(_rc), __func__)); \
302 #define PVR_LOG_IF_FALSE(_expr, _msg) do \
304 PVR_DPF((PVR_DBG_ERROR, "%s in %s()", _msg, __func__)); \
308 #define PVR_LOGR_IF_FALSE(_expr, _msg, _rc) do \
310 PVR_DPF((PVR_DBG_ERROR, "%s in %s()", _msg, __func__)); \
315 #define PVR_LOGG_IF_FALSE(_expr, _msg, _go) do \
317 PVR_DPF((PVR_DBG_ERROR, "%s in %s()", _msg, __func__)); \
322 IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVDebugPrintf(IMG_UINT32 ui32DebugLevel,
323 const IMG_CHAR *pszFileName,
325 const IMG_CHAR *pszFormat,
326 ...) IMG_FORMAT_PRINTF(4, 5);
328 IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVDebugPrintfDumpCCB(void);
330 #else /* defined(PVRSRV_NEED_PVR_DPF) */
332 #define PVR_DPF(X) /*!< Null Implementation of PowerVR Debug Printf (does nothing) */
334 #define PVR_LOG_ERROR(_rc, _call) (void)(_rc)
335 #define PVR_LOG_IF_ERROR(_rc, _call) (void)(_rc)
336 #define PVR_LOGR_IF_ERROR(_rc, _call) do { if (_rc != PVRSRV_OK) { return (_rc); } MSC_SUPPRESS_4127 } while(0)
337 #define PVR_LOGRN_IF_ERROR(_rc, _call) do { if (_rc != PVRSRV_OK) { return; } MSC_SUPPRESS_4127 } while(0)
338 #define PVR_LOGG_IF_ERROR(_rc, _call, _go) do { if (_rc != PVRSRV_OK) { goto _go; } MSC_SUPPRESS_4127 } while(0)
340 #define PVR_LOG_IF_FALSE(_expr, _msg) (void)(_expr)
341 #define PVR_LOGR_IF_FALSE(_expr, _msg, _rc) do { if (!(_expr)) { return (_rc); } MSC_SUPPRESS_4127 } while(0)
342 #define PVR_LOGG_IF_FALSE(_expr, _msg, _go) do { if (!(_expr)) { goto _go; } MSC_SUPPRESS_4127 } while(0)
344 #undef PVR_DPF_FUNCTION_TRACE_ON
346 #endif /* defined(PVRSRV_NEED_PVR_DPF) */
349 #if defined(PVR_DPF_FUNCTION_TRACE_ON)
351 #define PVR_DPF_ENTERED \
352 PVR_DPF((PVR_DBG_CALLTRACE, "--> %s:%d entered", __func__, __LINE__))
354 #define PVR_DPF_ENTERED1(p1) \
355 PVR_DPF((PVR_DBG_CALLTRACE, "--> %s:%d entered (0x%lx)", __func__, __LINE__, ((unsigned long)p1)))
357 #define PVR_DPF_RETURN_RC(a) \
358 do { int _r = (a); PVR_DPF((PVR_DBG_CALLTRACE, "-< %s:%d returned %d", __func__, __LINE__, (_r))); return (_r); MSC_SUPPRESS_4127 } while (0)
360 #define PVR_DPF_RETURN_RC1(a,p1) \
361 do { int _r = (a); PVR_DPF((PVR_DBG_CALLTRACE, "-< %s:%d returned %d (0x%lx)", __func__, __LINE__, (_r), ((unsigned long)p1))); return (_r); MSC_SUPPRESS_4127 } while (0)
363 #define PVR_DPF_RETURN_VAL(a) \
364 do { PVR_DPF((PVR_DBG_CALLTRACE, "-< %s:%d returned with value", __func__, __LINE__ )); return (a); MSC_SUPPRESS_4127 } while (0)
366 #define PVR_DPF_RETURN_OK \
367 do { PVR_DPF((PVR_DBG_CALLTRACE, "-< %s:%d returned ok", __func__, __LINE__)); return PVRSRV_OK; MSC_SUPPRESS_4127 } while (0)
369 #define PVR_DPF_RETURN \
370 do { PVR_DPF((PVR_DBG_CALLTRACE, "-< %s:%d returned", __func__, __LINE__)); return; MSC_SUPPRESS_4127 } while (0)
373 #error PVR DPF Function trace enabled in release build, rectify
376 #else /* defined(PVR_DPF_FUNCTION_TRACE_ON) */
378 #define PVR_DPF_ENTERED
379 #define PVR_DPF_ENTERED1(p1)
380 #define PVR_DPF_RETURN_RC(a) return (a)
381 #define PVR_DPF_RETURN_RC1(a,p1) return (a)
382 #define PVR_DPF_RETURN_VAL(a) return (a)
383 #define PVR_DPF_RETURN_OK return PVRSRV_OK
384 #define PVR_DPF_RETURN return
386 #endif /* defined(PVR_DPF_FUNCTION_TRACE_ON) */
389 /* PVR_TRACE() handling */
391 #if defined(PVRSRV_NEED_PVR_TRACE)
393 #define PVR_TRACE(X) PVRSRVTrace X /*!< PowerVR Debug Trace Macro */
394 /* Empty string implementation that is -O0 build friendly */
395 #define PVR_TRACE_EMPTY_LINE() PVR_TRACE(("%s", ""))
397 IMG_IMPORT IMG_VOID IMG_CALLCONV PVRSRVTrace(const IMG_CHAR* pszFormat, ... )
398 IMG_FORMAT_PRINTF(1, 2);
400 #else /* defined(PVRSRV_NEED_PVR_TRACE) */
401 /*! Null Implementation of PowerVR Debug Trace Macro (does nothing) */
404 #endif /* defined(PVRSRV_NEED_PVR_TRACE) */
407 #if defined(PVRSRV_NEED_PVR_ASSERT)
408 #ifdef INLINE_IS_PRAGMA
409 #pragma inline(TRUNCATE_64BITS_TO_32BITS)
411 INLINE static IMG_UINT32 TRUNCATE_64BITS_TO_32BITS(IMG_UINT64 uiInput)
413 IMG_UINT32 uiTruncated;
415 uiTruncated = (IMG_UINT32)uiInput;
416 PVR_ASSERT(uiInput == uiTruncated);
421 #ifdef INLINE_IS_PRAGMA
422 #pragma inline(TRUNCATE_64BITS_TO_SIZE_T)
424 INLINE static IMG_SIZE_T TRUNCATE_64BITS_TO_SIZE_T(IMG_UINT64 uiInput)
426 IMG_SIZE_T uiTruncated;
428 uiTruncated = (IMG_SIZE_T)uiInput;
429 PVR_ASSERT(uiInput == uiTruncated);
434 #ifdef INLINE_IS_PRAGMA
435 #pragma inline(TRUNCATE_SIZE_T_TO_32BITS)
437 INLINE static IMG_UINT32 TRUNCATE_SIZE_T_TO_32BITS(IMG_SIZE_T uiInput)
439 IMG_UINT32 uiTruncated;
441 uiTruncated = (IMG_UINT32)uiInput;
442 PVR_ASSERT(uiInput == uiTruncated);
447 #else /* defined(PVRSRV_NEED_PVR_ASSERT) */
448 #define TRUNCATE_64BITS_TO_32BITS(expr) ((IMG_UINT32)(expr))
449 #define TRUNCATE_64BITS_TO_SIZE_T(expr) ((IMG_SIZE_T)(expr))
450 #define TRUNCATE_SIZE_T_TO_32BITS(expr) ((IMG_UINT32)(expr))
451 #endif /* defined(PVRSRV_NEED_PVR_ASSERT) */
453 /* Macros used to trace calls */
455 #define PVR_DBG_FILELINE , __FILE__, __LINE__
456 #define PVR_DBG_FILELINE_PARAM , const IMG_CHAR *pszaFile, IMG_UINT32 ui32Line
457 #define PVR_DBG_FILELINE_ARG , pszaFile, ui32Line
458 #define PVR_DBG_FILELINE_FMT " %s:%u"
459 #define PVR_DBG_FILELINE_UNREF() do { PVR_UNREFERENCED_PARAMETER(pszaFile); \
460 PVR_UNREFERENCED_PARAMETER(ui32Line); } while(0)
462 #define PVR_DBG_FILELINE
463 #define PVR_DBG_FILELINE_PARAM
464 #define PVR_DBG_FILELINE_ARG
465 #define PVR_DBG_FILELINE_FMT
466 #define PVR_DBG_FILELINE_UNREF()
469 #if defined (__cplusplus)
473 #endif /* __PVR_DEBUG_H__ */
475 /******************************************************************************
476 End of file (pvr_debug.h)
477 ******************************************************************************/