1 /*******************************************************************************
2 * Copyright (C) 2018 Cadence Design Systems, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to use this Software with Cadence processor cores only and
7 * not with any other processors and platforms, subject to
8 * the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included
11 * in all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
17 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
18 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
19 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 
21 ******************************************************************************/
22 
23 #ifndef __XF_H
24 #error  "xf-debug.h mustn't be included directly"
25 #endif
26 
27 /*******************************************************************************
28  * Auxiliary macros (put into "xf-types.h"?)
29  ******************************************************************************/
30 
31 #ifndef offset_of
32 #define offset_of(type, member)         \
33     ((int)(intptr_t)&(((const type *)(0))->member))
34 #endif
35 
36 #ifndef container_of
37 #define container_of(ptr, type, member) \
38     ((type *)((void *)(ptr) - offset_of(type, member)))
39 #endif
40 
41 /*******************************************************************************
42  * Bug check for constant conditions (file scope)
43  ******************************************************************************/
44 
45 #define __C_BUG(n)      __C_BUG2(n)
46 #define __C_BUG2(n)     __c_bug_##n
47 #define C_BUG(expr)     typedef char __C_BUG(__LINE__)[(expr) ? -1 : 1]
48 
49 /*******************************************************************************
50  * Compilation-time types control
51  ******************************************************************************/
52 
53 #if XF_DEBUG
54 #define __C_TYPE_CONTROL(d, type)       ((void) ((d) != (type*) 0))
55 #else
56 #define __C_TYPE_CONTROL(d, type)       ((void) 0)
57 #endif
58 
59 /*******************************************************************************
60  * Unused variable
61  ******************************************************************************/
62 
63 #define C_UNUSED(v)                     (void)(0 ? (v) = (v), 1 : 0)
64 
65 /*******************************************************************************
66  * Auxiliary macros
67  ******************************************************************************/
68 
69 /* ...define a stub for unused declarator */
70 #define __xf_stub(tag, line)            __xf_stub2(tag, line)
71 #define __xf_stub2(tag, line)           typedef int __xf_##tag##_##line
72 
73 /* ...convert anything into string */
74 #define __xf_string(x)                  __xf_string2(x)
75 #define __xf_string2(x)                 #x
76 
77 /*******************************************************************************
78  * Tracing facility
79  ******************************************************************************/
80 
81 #if XF_TRACE
82 
83 /* ...tracing to communication processor */
84 extern int  xf_trace(const char *format, ...);
85 
86 /* ...tracing facility initialization */
87 extern void xf_trace_init(const char *banner);
88 
89 /* ...initialize tracing facility */
90 #define TRACE_INIT(banner)              (xf_trace_init(banner))
91 
92 /* ...trace tag definition */
93 #define TRACE_TAG(tag, on)              enum { __xf_trace_##tag = on }
94 
95 /* ...check if the trace tag is enabled */
96 #define TRACE_CFG(tag)                  (__xf_trace_##tag)
97 
98 /* ...tagged tracing primitive */
99 #define TRACE(tag, fmt, ...)            (void)(__xf_trace_##tag ? __xf_trace(tag, __xf_format##fmt, ## __VA_ARGS__), 1 : 0)
100 
101 /*******************************************************************************
102  * Tagged tracing formats
103  ******************************************************************************/
104 
105 /* ...tracing primitive */
106 #define __xf_trace(tag, fmt, ...)       \
107     ({ __attribute__((unused)) const char *__xf_tag = #tag; xf_trace(fmt, ## __VA_ARGS__); })
108 
109 /* ...just a format string */
110 #define __xf_format_n(fmt)              fmt
111 
112 /* ...module tag and trace tag shown */
113 #define __xf_format_b(fmt)              "[%s.%s] " fmt, __xf_string(MODULE_TAG), __xf_tag
114 
115 /* ...module tag, trace tag, file name and line shown */
116 #define __xf_format_x(fmt)              "[%s.%s] - %s@%d - " fmt,  __xf_string(MODULE_TAG), __xf_tag, __FILE__, __LINE__
117 
118 /*******************************************************************************
119  * Globally defined tags
120  ******************************************************************************/
121 
122 /* ...unconditionally OFF */
123 TRACE_TAG(0, 0);
124 
125 /* ...unconditionally ON */
126 TRACE_TAG(1, 1);
127 
128 /* ...error output - on by default */
129 TRACE_TAG(ERROR, 1);
130 
131 #else
132 
133 #define TRACE_INIT(banner)              (void)0
134 #define TRACE_TAG(tag, on)              __xf_stub(trace_##tag, __LINE__)
135 #define TRACE(tag, fmt, ...)            (void)0
136 #define __xf_trace(tag, fmt, ...)       (void)0
137 
138 #endif  /* XF_TRACE */
139 
140 /*******************************************************************************
141  * Bugchecks
142  ******************************************************************************/
143 
144 #if XF_DEBUG
145 
146 /* ...run-time bugcheck */
147 #define BUG(cond, fmt, ...)                                     \
148 do                                                              \
149 {                                                               \
150     if (cond)                                                   \
151     {                                                           \
152         /* ...output message */                                 \
153         __xf_trace(BUG, __xf_format##fmt, ## __VA_ARGS__);      \
154                                                                 \
155         /* ...and die  */                                       \
156         abort();                                                \
157     }                                                           \
158 }                                                               \
159 while (0)
160 
161 #else
162 #define BUG(cond, fmt, ...)             (void)0
163 #endif  /* XF_DEBUG */
164 
165 /*******************************************************************************
166  * Run-time error processing
167  ******************************************************************************/
168 
169 /* ...check the API call succeeds */
170 #define XF_CHK_API(cond)                                \
171 ({                                                      \
172     int __ret;                                          \
173                                                         \
174     if ((__ret = (int)(cond)) < 0)                      \
175     {                                                   \
176         TRACE(ERROR, _x("API error: %d"), __ret);       \
177         return __ret;                                   \
178     }                                                   \
179     __ret;                                              \
180 })
181 
182 /* ...check the condition is true */
183 #define XF_CHK_ERR(cond, error)                 \
184 ({                                              \
185     intptr_t __ret;                             \
186                                                 \
187     if (!(__ret = (intptr_t)(cond)))            \
188     {                                           \
189         TRACE(ERROR, _x("check failed"));       \
190         return (error);                         \
191     }                                           \
192     (int)__ret;                                 \
193 })
194 
195