1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2019 Intel Corporation. All rights reserved.
4  *
5  * Author: Tomasz Lauda <tomasz.lauda@linux.intel.com>
6  *         Janusz Jankowski <janusz.jankowski@linux.intel.com>
7  */
8 
9 #ifndef __SOF_COMMON_H__
10 #define __SOF_COMMON_H__
11 
12 #if !defined(LINKER)
13 
14 /* callers must check/use the return value */
15 #define __must_check __attribute__((warn_unused_result))
16 
17 /* Align the number to the nearest alignment value */
18 #define IS_ALIGNED(size, alignment) ((size) % (alignment) == 0)
19 
20 /* Treat zero as a special case because it wraps around */
21 #define is_power_of_2(x) ((x) && !((x) & ((x) - 1)))
22 
23 #define compile_check(x) (sizeof(struct { int _f[2 * (x) - 1]; }) != 0)
24 
25 #define ALIGN_UP_INTERNAL(val, align) (((val) + (align) - 1) & ~((align) - 1))
26 
27 #if !defined(__ASSEMBLER__) && defined(__XTENSA__)
28 
29 #include <ipc/trace.h>
30 #include <rtos/panic.h>
31 #define VERIFY_ALIGN
32 
33 #endif
34 
35 #ifdef VERIFY_ALIGN
36 
37 /* Using this when 'alignment' is a constant and when compiling with gcc
38  * -O0 saves about 30 bytes of .text and a few CPU cycles compared to
39  * the ALIGN_UP() combined check. There's no .text difference when
40  * optimizing.
41  */
42 #define ALIGN_UP_COMPILE(size, alignment)					\
43 	(compile_check(is_power_of_2(alignment)) ?				\
44 	 ALIGN_UP_INTERNAL(size, alignment) : 0xBADCAFE)
45 
46 #ifdef __XCC__
47 
48 /*
49  * xcc doesn't support __builtin_constant_p() so we can only do run-time
50  * verification
51  */
52 
53 #define ALIGN_UP(size, alignment) ({						\
54 	if (!is_power_of_2(alignment))						\
55 		sof_panic(SOF_IPC_PANIC_ASSERT);				\
56 	ALIGN_UP_INTERNAL(size, alignment);					\
57 })
58 
59 #define ALIGN_DOWN(size, alignment) ({						\
60 	if (!is_power_of_2(alignment))						\
61 		sof_panic(SOF_IPC_PANIC_ASSERT);				\
62 	(size) & ~((alignment) - 1);						\
63 })
64 
65 #else /* not __XCC__ */
66 
67 /* If we can't tell at compile time, assume it's OK and defer to run-time */
68 #define COMPILE_TIME_ALIGNED(align) (!__builtin_constant_p(align) ||		\
69 				     is_power_of_2(align))
70 
71 #define ALIGN_UP(size, alignment) ({						\
72 	if (!compile_check(COMPILE_TIME_ALIGNED(alignment)) ||			\
73 	    !is_power_of_2(alignment))						\
74 		sof_panic(SOF_IPC_PANIC_ASSERT);				\
75 	ALIGN_UP_INTERNAL(size, alignment);					\
76 })
77 
78 #define ALIGN_DOWN(size, alignment) ({						\
79 	if (!compile_check(COMPILE_TIME_ALIGNED(alignment)) ||			\
80 	    !is_power_of_2(alignment))						\
81 		sof_panic(SOF_IPC_PANIC_ASSERT);				\
82 	(size) & ~((alignment) - 1);						\
83 })
84 
85 #endif /* not __XCC__ */
86 
87 #else /* not VERIFY_ALIGN */
88 
89 #define ALIGN_UP(size, alignment) ALIGN_UP_INTERNAL(size, alignment)
90 #define ALIGN_UP_COMPILE ALIGN_UP
91 #define ALIGN_DOWN(size, alignment) ((size) & ~((alignment) - 1))
92 
93 #endif
94 
95 /* This most basic ALIGN() must be used in header files that are
96  * included in both C and assembly code. memory.h files require this
97  * exact spelling matching the linker function because memory.h values
98  * are _also_ copied unprocessed to the .x[.in] linker script
99  */
100 #define ALIGN(val, align) ALIGN_UP_INTERNAL(val, align)
101 #define SOF_DIV_ROUND_UP(val, div) (((val) + (div) - 1) / (div))
102 
103 #if !defined(__ASSEMBLER__)
104 
105 #include <sof/trace/preproc.h>
106 #include <sof/compiler_attributes.h>
107 #include <stddef.h>
108 
109 /* use same syntax as Linux for simplicity */
110 #ifndef __ZEPHYR__ /* Already present and compatible via Zephyr headers */
111 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
112 #endif
113 #define container_of(ptr, type, member) \
114 	({const typeof(((type *)0)->member)*__memberptr = (ptr); \
115 	(type *)((char *)__memberptr - offsetof(type, member)); })
116 /*
117  * typeof() doesn't preserve __attribute__((address_space(x))) sparse
118  * annotations, so if an object belongs to such an address space, using the
119  * original form of container_of() will lose that annotation, which then will
120  * lead to sparse "different address spaces" warnings. We need to explicitly
121  * re-inforce the address space onto the new pointer.
122  */
123 #define attr_container_of(ptr, type, member, attr) \
124 	({const typeof(((type *)0)->member) attr *__memberptr = (ptr); \
125 	(type *)((char attr *)__memberptr - offsetof(type, member)); })
126 
127 #define ffs(i) __builtin_ffs(i)
128 #define ffsl(i) __builtin_ffsl(i)
129 #define ffsll(i) __builtin_ffsll(i)
130 
131 #define clz(i) __builtin_clz(i)
132 #define clzl(i) __builtin_clzl(i)
133 #define clzll(i) __builtin_clzll(i)
134 
135 #define popcount(x) __builtin_popcount(x)
136 
137 /* count number of var args */
138 #define PP_NARG(...) (sizeof((unsigned int[]){0, ##__VA_ARGS__}) \
139 	/ sizeof(unsigned int) - 1)
140 
141 /* Compile-time assertion.
142  *
143  * The first, typedef-based solution silently succeeds with variables,
144  * for instance STATIC_ASSERT(n == 42, always_succeeds) when 'n' is a
145  * variable in a function. The second, array-based solution is not
146  * fooled by variables but it increases the .bss size at the -O0
147  * optimization level (no difference with any real -O).  As we're often
148  * short on space, use the typedef-based version by default.  If you're
149  * afraid that some assertions are being fooled by variables then
150  * temporarily and locally switch to the second one.
151  */
152 #if 1
153 #define STATIC_ASSERT(COND, MESSAGE)	\
154 	__attribute__((unused))		\
155 	typedef char META_CONCAT(assertion_failed_, MESSAGE)[(COND) ? 1 : -1]
156 #else
157 #define STATIC_ASSERT(COND, MESSAGE)	\
158 	__attribute__((unused))		\
159 	static char  META_CONCAT(arr_assertion_failed_, MESSAGE)[(COND) ? 1 : -1]
160 #endif
161 
162 /* Allows checking preprocessor symbols in compile-time.
163  * Returns true for config with value 1, false for undefined or any other value.
164  *
165  * Expression like (CONFIG_MY ? a : b) rises compilation error when CONFIG_MY
166  * is undefined, (IS_ENABLED(CONFIG_MY) ? a : b) can be used instead of it.
167  *
168  * It is intended to be used with Kconfig's bool configs - it should rise
169  * error for other types, except positive integers, but it shouldn't be
170  * used with them.
171  */
172 #ifndef __ZEPHYR__ /* Already present and compatible via Zephyr headers */
173 #define IS_ENABLED(config) IS_ENABLED_STEP_1(config)
174 #define IS_ENABLED_DUMMY_1 0,
175 #define IS_ENABLED_STEP_1(config) IS_ENABLED_STEP_2(IS_ENABLED_DUMMY_ ## config)
176 #define IS_ENABLED_STEP_2(values) IS_ENABLED_STEP_3(values 1, 0)
177 #define IS_ENABLED_STEP_3(ignore, value, ...) (!!(value))
178 #endif
179 
180 #ifndef __GLIBC_USE
181 #define __GLIBC_USE(x) 0
182 #endif
183 
184 #if defined(__XCC__) || defined(__CHECKER__)
185 /* XCC does not currently check alignment for packed data so no need for any
186  * compiler hints.
187  */
188 #define ASSUME_ALIGNED(x, a)	x
189 #else
190 /* GCC 9.x has checks for pointer alignment within packed structures when
191  * cast from one type to another. This macro should only be used after checking
192  * alignment. This compiler builtin may not be available on all compilers so
193  * this macro can be defined as NULL if needed.
194  */
195 #define ASSUME_ALIGNED(x, a) ((typeof(x))__builtin_assume_aligned((x), a))
196 #endif /* __XCC__ */
197 
198 #endif /* __ASSEMBLER__ */
199 #else /* LINKER */
200 
201 #define ALIGN_UP_INTERNAL(val, align) (((val) + (align) - 1) & ~((align) - 1))
202 
203 #endif /* LINKER */
204 #endif /* __SOF_COMMON_H__ */
205