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 /*******************************************************************************
24  * xf-debug.h
25  *
26  * Debugging interface for Xtensa Audio DSP codec server
27  *
28  *******************************************************************************/
29 
30 #ifndef __XF_H
31 #error  "xf-debug.h mustn't be included directly"
32 #endif
33 
34 #include "dsp_debug.h"
35 
36 /*******************************************************************************
37  * Auxiliary macros (put into "xf-types.h"?)
38  ******************************************************************************/
39 
40 #ifndef offset_of
41 #define offset_of(type, member)         \
42     ((int)&(((const type *)(0))->member))
43 #endif
44 
45 #ifndef container_of
46 #define container_of(ptr, type, member) \
47     ((type *)((void *)(ptr) - offset_of(type, member)))
48 #endif
49 
50 /* ...next power-of-two calculation */
51 #define xf_next_power_of_two(v)     __xf_power_of_two_1((v) - 1)
52 #define __xf_power_of_two_1(v)      __xf_power_of_two_2((v) | ((v) >> 1))
53 #define __xf_power_of_two_2(v)      __xf_power_of_two_3((v) | ((v) >> 2))
54 #define __xf_power_of_two_3(v)      __xf_power_of_two_4((v) | ((v) >> 4))
55 #define __xf_power_of_two_4(v)      __xf_power_of_two_5((v) | ((v) >> 8))
56 #define __xf_power_of_two_5(v)      __xf_power_of_two_6((v) | ((v) >> 16))
57 #define __xf_power_of_two_6(v)      ((v) + 1)
58 
59 /* ...check if non-zero value is a power-of-two */
60 #define xf_is_power_of_two(v)       (((v) & ((v) - 1)) == 0)
61 
62 /*******************************************************************************
63  * Bug check for constant conditions (file scope)
64  ******************************************************************************/
65 
66 #define __C_BUG(n)      __C_BUG2(n)
67 #define __C_BUG2(n)     __c_bug_##n
68 #define C_BUG(expr)     typedef char __C_BUG(__LINE__)[(expr) ? -1 : 1]
69 
70 /*******************************************************************************
71  * Compilation-time types control
72  ******************************************************************************/
73 
74 #if XF_DEBUG
75 #define __C_TYPE_CONTROL(d, type)       ((void) ((d) != (type*) 0))
76 #else
77 #define __C_TYPE_CONTROL(d, type)       ((void) 0)
78 #endif
79 
80 /*******************************************************************************
81  * Unused variable
82  ******************************************************************************/
83 
84 #define C_UNUSED(v)                     (void)(0 ? (v) = (v), 1 : 0)
85 
86 /*******************************************************************************
87  * Auxiliary macros
88  ******************************************************************************/
89 
90 /* ...define a stub for unused declarator */
91 #define __xf_stub(tag, line)            __xf_stub2(tag, line)
92 #define __xf_stub2(tag, line)           typedef int __xf_##tag##_##line
93 
94 /* ...convert anything into string */
95 #define __xf_string(x)                  __xf_string2(x)
96 #define __xf_string2(x)                 #x
97 
98 /*******************************************************************************
99  * Tracing facility
100  ******************************************************************************/
101 
102 #if XF_TRACE
103 
104 /* ...tracing to communication processor */
105 extern int  xf_trace(const char *format, ...) __attribute__((format (printf, 1, 2)));
106 
107 /* ...tracing facility initialization */
108 extern void xf_trace_init(const char *banner);
109 
110 /* ...initialize tracing facility */
111 //#define TRACE_INIT(banner)              (xf_trace_init(banner))
112 #define TRACE_INIT(banner)              ({ dsp_debug_init(); DSP_TRACE("\n"banner); })
113 
114 /* ...trace tag definition */
115 #define TRACE_TAG(tag, on)              enum { __xf_trace_##tag = on }
116 
117 /* ...check if the trace tag is enabled */
118 #define TRACE_CFG(tag)                  (__xf_trace_##tag)
119 
120 /* ...tagged tracing primitive */
121 #define TRACE(tag, fmt, ...)            (void)(__xf_trace_##tag ? __xf_trace(tag, __xf_format##fmt, ## __VA_ARGS__), 1 : 0)
122 
123 /*******************************************************************************
124  * Tagged tracing formats
125  ******************************************************************************/
126 
127 /* ...tracing primitive */
128 #define __xf_trace(tag, fmt, ...)       \
129     ({ __attribute__((unused)) const char *__xf_tag = #tag; DSP_TRACE(fmt, ## __VA_ARGS__); })
130 
131 /* ...just a format string */
132 #define __xf_format_n(fmt)              fmt
133 
134 /* ...module tag and trace tag shown */
135 #define __xf_format_b(fmt)              "[%s.%s] " fmt, __xf_string(MODULE_TAG), __xf_tag
136 
137 /* ...module tag, trace tag, file name and line shown */
138 #define __xf_format_x(fmt)              "[%s.%s] - %s@%d - " fmt,  __xf_string(MODULE_TAG), __xf_tag, __FILE__, __LINE__
139 
140 /*******************************************************************************
141  * Globally defined tags
142  ******************************************************************************/
143 
144 /* ...unconditionally OFF */
145 TRACE_TAG(0, 0);
146 
147 /* ...unconditionally ON */
148 TRACE_TAG(1, 1);
149 
150 /* ...error output - on by default */
151 TRACE_TAG(ERROR, 1);
152 
153 #else
154 
155 #define TRACE_INIT(banner)              (void)0
156 #define TRACE_TAG(tag, on)              __xf_stub(trace_##tag, __LINE__)
157 #define TRACE_CFG(tag)			0
158 #define TRACE(tag, fmt, ...)            (void)0
159 #define __xf_trace(tag, fmt, ...)       (void)0
160 
161 #endif  /* XF_TRACE */
162 
163 /*******************************************************************************
164  * Bugchecks
165  ******************************************************************************/
166 
167 #if XF_DEBUG
168 
169 /* ...run-time bugcheck */
170 #define BUG(cond, fmt, ...)                                     \
171 do                                                              \
172 {                                                               \
173     if (cond)                                                   \
174     {                                                           \
175         /* ...output message */                                 \
176         __xf_trace(BUG, __xf_format##fmt, ## __VA_ARGS__);      \
177                                                                 \
178         /* ...and die (tbd) */                                  \
179         __xf_abort();                                           \
180     }                                                           \
181 }                                                               \
182 while (0)
183 
184 #else
185 #define BUG(cond, fmt, ...)             (void)0
186 #endif  /* XF_DEBUG */
187 
188 /*******************************************************************************
189  * Run-time error processing
190  ******************************************************************************/
191 
192 /* ...check the API call succeeds */
193 #define XF_CHK_API(cond)                                \
194 ({                                                      \
195     int __ret;                                          \
196                                                         \
197     if ((__ret = (int)(cond)) < 0)                      \
198     {                                                   \
199         TRACE(ERROR, _x("API error: %d"), __ret);       \
200         return __ret;                                   \
201     }                                                   \
202     __ret;                                              \
203 })
204 
205 /* ...check the condition is true */
206 #define XF_CHK_ERR(cond, error)                         \
207 ({                                                      \
208     int __ret;                                          \
209                                                         \
210     if (!(__ret = (int)(cond)))                         \
211     {                                                   \
212         TRACE(ERROR, _x("check failed: %d"), __ret);    \
213         return (error);                                 \
214     }                                                   \
215     __ret;                                              \
216 })
217