/******************************************************************************* * Copyright (C) 2018 Cadence Design Systems, Inc. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to use this Software with Cadence processor cores only and * not with any other processors and platforms, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ #ifndef __XF_H #error "xf-debug.h mustn't be included directly" #endif /******************************************************************************* * Auxiliary macros (put into "xf-types.h"?) ******************************************************************************/ #ifndef offset_of #define offset_of(type, member) \ ((int)(intptr_t)&(((const type *)(0))->member)) #endif #ifndef container_of #define container_of(ptr, type, member) \ ((type *)((void *)(ptr) - offset_of(type, member))) #endif /******************************************************************************* * Bug check for constant conditions (file scope) ******************************************************************************/ #define __C_BUG(n) __C_BUG2(n) #define __C_BUG2(n) __c_bug_##n #define C_BUG(expr) typedef char __C_BUG(__LINE__)[(expr) ? -1 : 1] /******************************************************************************* * Compilation-time types control ******************************************************************************/ #if XF_DEBUG #define __C_TYPE_CONTROL(d, type) ((void) ((d) != (type*) 0)) #else #define __C_TYPE_CONTROL(d, type) ((void) 0) #endif /******************************************************************************* * Unused variable ******************************************************************************/ #define C_UNUSED(v) (void)(0 ? (v) = (v), 1 : 0) /******************************************************************************* * Auxiliary macros ******************************************************************************/ /* ...define a stub for unused declarator */ #define __xf_stub(tag, line) __xf_stub2(tag, line) #define __xf_stub2(tag, line) typedef int __xf_##tag##_##line /* ...convert anything into string */ #define __xf_string(x) __xf_string2(x) #define __xf_string2(x) #x /******************************************************************************* * Tracing facility ******************************************************************************/ #if XF_TRACE /* ...tracing to communication processor */ extern int xf_trace(const char *format, ...); /* ...tracing facility initialization */ extern void xf_trace_init(const char *banner); /* ...initialize tracing facility */ #define TRACE_INIT(banner) (xf_trace_init(banner)) /* ...trace tag definition */ #define TRACE_TAG(tag, on) enum { __xf_trace_##tag = on } /* ...check if the trace tag is enabled */ #define TRACE_CFG(tag) (__xf_trace_##tag) /* ...tagged tracing primitive */ #define TRACE(tag, fmt, ...) (void)(__xf_trace_##tag ? __xf_trace(tag, __xf_format##fmt, ## __VA_ARGS__), 1 : 0) /******************************************************************************* * Tagged tracing formats ******************************************************************************/ /* ...tracing primitive */ #define __xf_trace(tag, fmt, ...) \ ({ __attribute__((unused)) const char *__xf_tag = #tag; xf_trace(fmt, ## __VA_ARGS__); }) /* ...just a format string */ #define __xf_format_n(fmt) fmt /* ...module tag and trace tag shown */ #define __xf_format_b(fmt) "[%s.%s] " fmt, __xf_string(MODULE_TAG), __xf_tag /* ...module tag, trace tag, file name and line shown */ #define __xf_format_x(fmt) "[%s.%s] - %s@%d - " fmt, __xf_string(MODULE_TAG), __xf_tag, __FILE__, __LINE__ /******************************************************************************* * Globally defined tags ******************************************************************************/ /* ...unconditionally OFF */ TRACE_TAG(0, 0); /* ...unconditionally ON */ TRACE_TAG(1, 1); /* ...error output - on by default */ TRACE_TAG(ERROR, 1); #else #define TRACE_INIT(banner) (void)0 #define TRACE_TAG(tag, on) __xf_stub(trace_##tag, __LINE__) #define TRACE(tag, fmt, ...) (void)0 #define __xf_trace(tag, fmt, ...) (void)0 #endif /* XF_TRACE */ /******************************************************************************* * Bugchecks ******************************************************************************/ #if XF_DEBUG /* ...run-time bugcheck */ #define BUG(cond, fmt, ...) \ do \ { \ if (cond) \ { \ /* ...output message */ \ __xf_trace(BUG, __xf_format##fmt, ## __VA_ARGS__); \ \ /* ...and die */ \ abort(); \ } \ } \ while (0) #else #define BUG(cond, fmt, ...) (void)0 #endif /* XF_DEBUG */ /******************************************************************************* * Run-time error processing ******************************************************************************/ /* ...check the API call succeeds */ #define XF_CHK_API(cond) \ ({ \ int __ret; \ \ if ((__ret = (int)(cond)) < 0) \ { \ TRACE(ERROR, _x("API error: %d"), __ret); \ return __ret; \ } \ __ret; \ }) /* ...check the condition is true */ #define XF_CHK_ERR(cond, error) \ ({ \ intptr_t __ret; \ \ if (!(__ret = (intptr_t)(cond))) \ { \ TRACE(ERROR, _x("check failed")); \ return (error); \ } \ (int)__ret; \ })