Sound Open Firmware
Loading...
Searching...
No Matches
common.h
Go to the documentation of this file.
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#ifdef __ZEPHYR__
18#include <zephyr/sys/util.h>
19#endif
20
21/* Align the number to the nearest alignment value */
22#ifndef IS_ALIGNED
23#define IS_ALIGNED(size, alignment) ((size) % (alignment) == 0)
24#endif
25
26/* Treat zero as a special case because it wraps around */
27#define is_power_of_2(x) ((x) && !((x) & ((x) - 1)))
28
29#define compile_check(x) (sizeof(struct { int _f[2 * (x) - 1]; }) != 0)
30
31#define ALIGN_UP_INTERNAL(val, align) (((val) + (align) - 1) & ~((align) - 1))
32
33#if !defined(__ASSEMBLER__) && defined(__XTENSA__)
34
35#include <ipc/trace.h>
36#include <rtos/panic.h>
37#define VERIFY_ALIGN
38
39#endif
40
41#ifdef VERIFY_ALIGN
42
43/* Using this when 'alignment' is a constant and when compiling with gcc
44 * -O0 saves about 30 bytes of .text and a few CPU cycles compared to
45 * the ALIGN_UP() combined check. There's no .text difference when
46 * optimizing.
47 */
48#define ALIGN_UP_COMPILE(size, alignment) \
49 (compile_check(is_power_of_2(alignment)) ? \
50 ALIGN_UP_INTERNAL(size, alignment) : 0xBADCAFE)
51
52#if defined(__XCC__) || defined(__clang__)
53
54/*
55 * xcc doesn't support __builtin_constant_p() so we can only do run-time
56 * verification
57 */
58
59#define ALIGN_UP(size, alignment) ({ \
60 if (!is_power_of_2(alignment)) \
61 sof_panic(SOF_IPC_PANIC_ASSERT); \
62 ALIGN_UP_INTERNAL(size, alignment); \
63})
64
65#define ALIGN_DOWN(size, alignment) ({ \
66 if (!is_power_of_2(alignment)) \
67 sof_panic(SOF_IPC_PANIC_ASSERT); \
68 (size) & ~((alignment) - 1); \
69})
70
71#else /* not __XCC__ or __clang__ */
72
73/* If we can't tell at compile time, assume it's OK and defer to run-time */
74#define COMPILE_TIME_ALIGNED(align) (!__builtin_constant_p(align) || \
75 is_power_of_2(align))
76
77#define ALIGN_UP(size, alignment) ({ \
78 if (!compile_check(COMPILE_TIME_ALIGNED(alignment)) || \
79 !is_power_of_2(alignment)) \
80 sof_panic(SOF_IPC_PANIC_ASSERT); \
81 ALIGN_UP_INTERNAL(size, alignment); \
82})
83
84#define ALIGN_DOWN(size, alignment) ({ \
85 if (!compile_check(COMPILE_TIME_ALIGNED(alignment)) || \
86 !is_power_of_2(alignment)) \
87 sof_panic(SOF_IPC_PANIC_ASSERT); \
88 (size) & ~((alignment) - 1); \
89})
90
91#endif /* not __XCC__ or __clang__ */
92
93#else /* not VERIFY_ALIGN */
94
95#define ALIGN_UP(size, alignment) ALIGN_UP_INTERNAL(size, alignment)
96#define ALIGN_UP_COMPILE ALIGN_UP
97#define ALIGN_DOWN(size, alignment) ((size) & ~((alignment) - 1))
98
99#endif
100
101/* This most basic ALIGN() must be used in header files that are
102 * included in both C and assembly code. memory.h files require this
103 * exact spelling matching the linker function because memory.h values
104 * are _also_ copied unprocessed to the .x[.in] linker script
105 */
106#define ALIGN(val, align) ALIGN_UP_INTERNAL(val, align)
107#define SOF_DIV_ROUND_UP(val, div) (((val) + (div) - 1) / (div))
108
109#if !defined(__ASSEMBLER__)
110
111#include <rtos/string_macro.h>
112#include <sof/compiler_attributes.h>
113#include <stddef.h>
114
115/* use same syntax as Linux for simplicity */
116#ifndef __ZEPHYR__ /* Already present and compatible via Zephyr headers */
117#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
118#endif
119#define container_of(ptr, type, member) \
120 ({const __typeof__(((type *)0)->member)*__memberptr = (ptr); \
121 (type *)((char *)__memberptr - offsetof(type, member)); })
122/*
123 * typeof() doesn't preserve __attribute__((address_space(x))) sparse
124 * annotations, so if an object belongs to such an address space, using the
125 * original form of container_of() will lose that annotation, which then will
126 * lead to sparse "different address spaces" warnings. We need to explicitly
127 * re-inforce the address space onto the new pointer.
128 */
129#define attr_container_of(ptr, type, member, attr) \
130 ({const __typeof__(((type *)0)->member) attr *__memberptr = (ptr); \
131 (type *)((char attr *)__memberptr - offsetof(type, member)); })
132
133#define ffs(i) __builtin_ffs(i)
134#define ffsl(i) __builtin_ffsl(i)
135#define ffsll(i) __builtin_ffsll(i)
136
137#define clz(i) __builtin_clz(i)
138#define clzl(i) __builtin_clzl(i)
139#define clzll(i) __builtin_clzll(i)
140
141#define popcount(x) __builtin_popcount(x)
142
143/* count number of var args */
144#define PP_NARG(...) (sizeof((unsigned int[]){0, ##__VA_ARGS__}) \
145 / sizeof(unsigned int) - 1)
146
147/* Compile-time assertion.
148 *
149 * The first, typedef-based solution silently succeeds with variables,
150 * for instance STATIC_ASSERT(n == 42, always_succeeds) when 'n' is a
151 * variable in a function. The second, array-based solution is not
152 * fooled by variables but it increases the .bss size at the -O0
153 * optimization level (no difference with any real -O). As we're often
154 * short on space, use the typedef-based version by default. If you're
155 * afraid that some assertions are being fooled by variables then
156 * temporarily and locally switch to the second one.
157 */
158#define STATIC_ASSERT(COND, MESSAGE) \
159 __attribute__((unused)) \
160 typedef char _CONCAT(assertion_failed_, MESSAGE)[(COND) ? 1 : -1]
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#define SOF_CONFIG_HIFI(level, component) (CONFIG_ ## component ## _HIFI_ ## level)
181
182/* True if:
183 * (1) EITHER this particular level was manually forced in Kconfig,
184 * (2) OR: - this component defaulted to "MAX"
185 * - AND this level is the max available in the XC HAL.
186 */
187#define SOF_USE_HIFI(level, component) (SOF_CONFIG_HIFI(level, component) || \
188 (SOF_CONFIG_HIFI(MAX, component) && level == SOF_MAX_XCHAL_HIFI))
189
190/* True if:
191 * (1) EITHER this particular level was manually forced in Kconfig,
192 * (2) OR: - this component defaulted to "MAX"
193 * - AND this level is less or equal to max available in the XC HAL.
194 *
195 * Use e.g. for highest optimization level source file, e.g. SOF_USE_MIN_HIFI(4, component)
196 * for HiFi4 code version that can be built with HiFi4 or HiFi5 tool chain.
197 */
198#define SOF_USE_MIN_HIFI(minlevel, component) (SOF_CONFIG_HIFI(minlevel, component) || \
199 (SOF_CONFIG_HIFI(MAX, component) && minlevel <= SOF_MAX_XCHAL_HIFI))
200
201#ifndef __XCC__ // Cadence toolchains: either xt-xcc or xt-clang.
202# define SOF_MAX_XCHAL_HIFI NONE
203#else
204# include <xtensa/config/core-isa.h>
205// Maybe we could make this fully generic (and less readable!) using
206// IS_ENABLED() above.
207# if XCHAL_HAVE_HIFI5
208# define SOF_MAX_XCHAL_HIFI 5
209# define SOF_FRAME_BYTE_ALIGN 16
210# elif XCHAL_HAVE_HIFI4
211# define SOF_MAX_XCHAL_HIFI 4
212# define SOF_FRAME_BYTE_ALIGN 8
213# elif XCHAL_HAVE_HIFI3
214# define SOF_MAX_XCHAL_HIFI 3
215# define SOF_FRAME_BYTE_ALIGN 8
216# else
217# define SOF_MAX_XCHAL_HIFI NONE
218# endif
219#endif
220
221/* Keep this last after all platform specific align defaults */
222#ifndef SOF_FRAME_BYTE_ALIGN
223# define SOF_FRAME_BYTE_ALIGN 4
224#endif
225
226/* Default frame-count alignment is 1 */
227#define SOF_FRAME_COUNT_ALIGN 1
228
229#ifndef __GLIBC_USE
230#define __GLIBC_USE(x) 0
231#endif
232
233#if defined(__XCC__) || defined(__CHECKER__)
234/* XCC does not currently check alignment for packed data so no need for any
235 * compiler hints.
236 */
237#define ASSUME_ALIGNED(x, a) x
238#else
239/* GCC 9.x has checks for pointer alignment within packed structures when
240 * cast from one type to another. This macro should only be used after checking
241 * alignment. This compiler builtin may not be available on all compilers so
242 * this macro can be defined as NULL if needed.
243 */
244#define ASSUME_ALIGNED(x, a) ((__typeof__(x))__builtin_assume_aligned((x), a))
245#endif /* __XCC__ */
246
247#endif /* __ASSEMBLER__ */
248#else /* LINKER */
249
250#define ALIGN_UP_INTERNAL(val, align) (((val) + (align) - 1) & ~((align) - 1))
251
252#endif /* LINKER */
253#endif /* __SOF_COMMON_H__ */
IPC definitions.