1// SPDX-License-Identifier: GPL-3.0-or-later
2
3#pragma once
4
5#ifdef __MOS_KERNEL__
6#include <abi-bits/errno.h>
7#endif
8#include <mos/compiler.h>
9#include <stddef.h>
10
11#ifdef __cplusplus
12#define MOS_STATIC_ASSERT static_assert
13#else
14#define MOS_STATIC_ASSERT _Static_assert
15#endif
16
17// clang-format off
18#if defined(__MOS_KERNEL__) && defined(__cplusplus)
19#define __BEGIN_DECLS extern "C" {
20#define __END_DECLS }
21#else
22#define __BEGIN_DECLS
23#define __END_DECLS
24#endif
25// clang-format on
26
27#define __aligned(x) __attribute__((__aligned__(x)))
28#define __malloc __attribute__((__malloc__))
29#define __packed __attribute__((__packed__))
30#define __printf(a, b) __attribute__((__format__(__printf__, a, b)))
31#define __pure __attribute__((__pure__))
32#define __section(S) __attribute__((__section__(S)))
33#define __maybe_unused __attribute__((__unused__))
34#define __used __attribute__((__used__))
35#define __nodiscard __attribute__((__warn_unused_result__))
36
37#define should_inline __maybe_unused static inline
38
39#define likely(x) __builtin_expect(!!(x), 1)
40#define unlikely(x) __builtin_expect(!!(x), 0)
41
42#define __types_compatible(a, b) __builtin_types_compatible_p(__typeof(a), __typeof(b))
43
44#ifndef __cplusplus
45#define do_container_of(ptr, type, member) \
46 __extension__({ \
47 void *real_ptr = (void *) (ptr); \
48 _Static_assert(__types_compatible(*(ptr), ((type *) 0)->member) | __types_compatible(*(ptr), void), "type mismatch: (" #type ") vs (" #ptr "->" #member ")"); \
49 ((type *) (real_ptr - offsetof(type, member))); \
50 })
51
52#define container_of(ptr, type, member) \
53 _Generic(ptr, const __typeof(*(ptr)) *: ((const type *) do_container_of(ptr, type, member)), default: ((type *) do_container_of(ptr, type, member)))
54#endif
55
56#define is_aligned(ptr, alignment) (((ptr_t) ptr & (alignment - 1)) == 0)
57
58#define GET_BIT(x, n) (((x) >> (n)) & 1)
59#define MASK_BITS(value, width) ((value) & ((1 << (width)) - 1))
60#define SET_BITS(bit, width, value) (MASK_BITS(value, width) << (bit))
61
62#define MOS_STRINGIFY2(x) #x
63#define MOS_STRINGIFY(x) MOS_STRINGIFY2(x)
64
65#define MOS_UNUSED(x) (void) (x)
66
67#define MOS_CONCAT_INNER(a, b) a##b
68#define MOS_CONCAT(a, b) MOS_CONCAT_INNER(a, b)
69
70#define MOS_WARNING_PUSH MOS_PRAGMA(diagnostic push)
71#define MOS_WARNING_POP MOS_PRAGMA(diagnostic pop)
72#define MOS_WARNING_DISABLE(text) MOS_PRAGMA(diagnostic ignored text)
73
74#define ALIGN_UP(addr, size) (((addr) + (size - 1)) & ~(size - 1))
75#define ALIGN_DOWN(addr, size) ((addr) & ~(size - 1))
76#define ALIGN_UP_TO_PAGE(addr) ALIGN_UP(addr, MOS_PAGE_SIZE)
77#define ALIGN_DOWN_TO_PAGE(addr) ALIGN_DOWN(addr, MOS_PAGE_SIZE)
78
79#define MOS_IN_RANGE(addr, start, end) ((addr) >= (start) && (addr) < (end))
80
81#define MOS_FOURCC(a, b, c, d) ((u32) (a) | ((u32) (b) << 8) | ((u32) (c) << 16) | ((u32) (d) << 24))
82
83#ifndef __cplusplus
84#define MOS_ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
85#else
86template<size_t N, typename T>
87constexpr size_t MOS_ARRAY_SIZE(const T (&)[N])
88{
89 return N;
90}
91#endif
92
93#define MOS_MAX_VADDR ((ptr_t) ~0)
94
95#define READ_ONCE(x) (*(volatile typeof(x) *) &(x))
96
97// clang-format off
98#define KB * 1024
99#define MB * 1024 KB
100#define GB * (u64) 1024 MB
101#define TB * (u64) 1024 GB
102#define statement_expr(type, ...) __extension__({ type retval; __VA_ARGS__; retval; })
103// clang-format on
104
105#define __NO_OP(...)
106
107#define BIT(x) (1ull << (x))
108
109#ifdef __cplusplus
110#define MOSAPI extern "C"
111#else
112#define MOSAPI extern
113#endif
114
115// If the feature is enabled, the expression will be 1, otherwise -1.
116// If the given feature is not defined, the expression will be 0, which throws a division by zero error.
117#define MOS_CONFIG(feat) (1 / feat == 1)
118
119#define MOS_DEBUG_FEATURE(feat) MOS_CONFIG(MOS_CONCAT(MOS_DEBUG_, feat))
120
121/**
122 * @brief Returns true for the first call, false for all subsequent calls.
123 */
124#define once() \
125 __extension__({ \
126 static bool __seen = false; \
127 bool ret = false; \
128 if (__seen) \
129 ret = false; \
130 else \
131 __seen = true, ret = true; \
132 ret; \
133 })
134
135#define MOS_PUT_IN_SECTION(_section, _struct, _var, ...) static const _struct _var __used __section(_section) = __VA_ARGS__
136
137#define IS_ERR_VALUE(x) unlikely((unsigned long) (void *) (x) >= (unsigned long) -4095)
138
139#define MOS_STUB_IMPL(...) \
140 MOS_WARNING_PUSH \
141 MOS_WARNING_DISABLE("-Wunused-parameter") \
142 __VA_ARGS__ \
143 { \
144 MOS_UNREACHABLE_X("unimplemented: file %s, line %d", __FILE__, __LINE__); \
145 } \
146 MOS_WARNING_POP
147