1 /*
2  * SPDX-License-Identifier: BSD-3-Clause
3  * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4  * SPDX-FileCopyrightText: Copyright NVIDIA Corporation.
5  */
6 
7 #ifndef UTILS_DEF_H
8 #define UTILS_DEF_H
9 
10 #if !(defined(__ASSEMBLER__) || defined(__LINKER__))
11 #include <stdint.h>
12 #endif
13 
14 /*
15  * For those constants to be shared between C and other sources, apply a 'U',
16  * 'UL', 'ULL', 'L' or 'LL' suffix to the argument only in C, to avoid
17  * undefined or unintended behaviour.
18  *
19  * The GNU assembler and linker do not support these suffixes (it causes the
20  * build process to fail) therefore the suffix is omitted when used in linker
21  * scripts and assembler files.
22  */
23 #if defined(__ASSEMBLER__) || defined(__LINKER__)
24 # define   U(_x)	(_x)
25 # define  UL(_x)	(_x)
26 # define ULL(_x)	(_x)
27 # define   L(_x)	(_x)
28 # define  LL(_x)	(_x)
29 #else
30 # define   U(_x)	(unsigned int)(_x)
31 # define  UL(_x)	(unsigned long)(_x)
32 # define ULL(_x)	(unsigned long long)(_x)
33 # define   L(_x)	(long)(_x)
34 # define  LL(_x)	(long long)(_x)
35 #endif /* __ASSEMBLER__ */
36 
37 /* Short forms for commonly used attributes */
38 #define __dead2		__attribute__((__noreturn__))
39 #define __deprecated	__attribute__((__deprecated__))
40 #define __packed	__attribute__((__packed__))
41 #define __used		__attribute__((__used__))
42 #define __unused	__attribute__((__unused__))
43 #define __aligned(x)	__attribute__((__aligned__(x)))
44 #define __section(x)	__attribute__((__section__(x)))
45 
46 #define __printflike(fmtarg, firstvararg) \
47 		__attribute__((__format__ (__printf__, fmtarg, firstvararg)))
48 
49 /*
50  * The round_up() macro rounds up a value to the given boundary in a
51  * type-agnostic yet type-safe manner. The boundary must be a power of two.
52  * In other words, it computes the smallest multiple of boundary which is
53  * greater than or equal to value.
54  *
55  * round_down() is similar but rounds the value down instead.
56  */
57 #define round_boundary(value, boundary)		\
58 	((__typeof__(value))((boundary) - U(1)))
59 
60 #define round_up(value, boundary)		\
61 	((((value) - U(1)) | round_boundary(value, boundary)) + U(1))
62 
63 #define round_down(value, boundary)		\
64 	((value) & ~round_boundary(value, boundary))
65 
66 #define min(a, b) (((a) < (b)) ? (a) : (b))
67 
68 /* Size of a 'm_' member of 's_' structure */
69 /* cppcheck-suppress [misra-c2012-20.7] */
70 #define SIZE_OF(s_, m_)		(sizeof(((struct s_ *)NULL)->m_))
71 
72 /* Compute the number of elements in the given array */
73 #define ARRAY_SIZE(_a)	\
74 	((sizeof(_a) / sizeof((_a)[0])) + CHECK_TYPE_IS_ARRAY(_a))
75 
76 /*
77  * Macro checks types of array and variable/value to write
78  * and reports compilation error if they mismatch.
79  */
80 #define CHECK_ARRAY_TYPE(_a, _v)	\
81 	_Static_assert(__builtin_types_compatible_p(typeof((_a)[0]), typeof(_v)), \
82 	"array type mismatch")
83 
84 /*
85  * Array read/write macros with boundary and types checks
86  * _a: name of array
87  * _i: index
88  * _v: variable/value to write
89  */
90 #define SAFE_ARRAY_READ(_a, _i, _v)	\
91 ({					\
92 	CHECK_ARRAY_TYPE(_a, _v);	\
93 	if ((_i) >= ARRAY_SIZE(_a)) {	\
94 		panic();		\
95 	}				\
96 	(_v) = (_a)[_i];			\
97 })
98 
99 #define SAFE_ARRAY_WRITE(_a, _i, _v)	\
100 ({					\
101 	CHECK_ARRAY_TYPE(_a, _v);	\
102 	if ((_i) >= ARRAY_SIZE(_a)) {	\
103 		panic();		\
104 	}				\
105 	(_a)[_i] = (_v);			\
106 })
107 
108 #define COMPILER_ASSERT(_condition)	\
109 			extern char compiler_assert[(_condition) ? 1 : -1]
110 
111 /*
112  * If _expr is false, this will result in a compile time error as it tries to
113  * define a bitfield of size -1 in that case.  Otherwise, it will define a
114  * bitfield of size 0, which is valid, and not create a compiler warning.
115  *
116  * The return value is only relevant when the compilation succeeds, and by
117  * subtracting the size of the same struct, this should always return 0 as a
118  * value and can be included in other expressions.
119  */
120 #define COMPILER_ASSERT_ZERO(_expr) (sizeof(struct { unsigned char: (-!(_expr)); }) \
121 				- sizeof(struct { unsigned char: 0; }))
122 
123 #ifndef __cplusplus
124 #define CHECK_TYPE_IS_ARRAY(_v) \
125 	COMPILER_ASSERT_ZERO(!__builtin_types_compatible_p(typeof(_v),	\
126 							typeof(&((_v)[0]))))
127 #else
128 #define CHECK_TYPE_IS_ARRAY(_v)		0U
129 #endif
130 
131 #ifdef CBMC
132 #define COMPILER_ASSERT_NO_CBMC(_condition)	COMPILER_ASSERT(0 == 0)
133 #else /* CBMC */
134 #define COMPILER_ASSERT_NO_CBMC(_condition)	COMPILER_ASSERT(_condition)
135 #endif /* CBMC */
136 
137 #define IS_POWER_OF_TWO(x)			\
138 	((((x) + UL(0)) & ((x) - UL(1))) == UL(0))
139 
140 #define COMPILER_BARRIER() __asm__ volatile ("" ::: "memory")
141 
142 #define ALIGNED(_size, _alignment)		\
143 			(((unsigned long)(_size) % (_alignment)) == UL(0))
144 
145 #define GRANULE_ALIGNED(_addr) ALIGNED((uintptr_t)(_addr), GRANULE_SIZE)
146 #define ALIGNED_TO_ARRAY(_addr, _array)		\
147 			(((uintptr_t)(_addr) >= (uintptr_t)&(_array)[0]) && \
148 			 ((((uintptr_t)(_addr) - (uintptr_t)&(_array)[0]) % \
149 						sizeof((_array)[0])) == UL(0)))
150 
151 #define GRANULE_SIZE	(UL(1) << GRANULE_SHIFT)
152 #define GRANULE_MASK	(~(GRANULE_SIZE - U(1)))
153 
154 #define HAS_SPE 0
155 
156 #if HAS_SPE
157 #define SPE(_x...) _x
158 #else
159 #define SPE(_x...)
160 #endif
161 
162 #if !(defined(__ASSEMBLER__) || defined(__LINKER__))
163 
164 /*
165  * System register field definitions.
166  *
167  * For any register field we define:
168  * - <register>_<field>_SHIFT
169  *   The bit offset of the LSB of the field.
170  * - <register>_<field>_WIDTH
171  *   The width of the field in bits.
172  *
173  * For single bit fields, we define:
174  * - <register>_<field>_BIT
175  *   The in-place value of the field with the bit set.
176  *
177  * For multi-bit fields, we define:
178  * - <register>_<field>_<enum>
179  *   The in-place value of the field set to the value corresponding to the
180  *   enumeration name.
181  *
182  * For any register field, we define:
183  * - INPLACE(<register>_<field>, val)
184  *   The in-place value of the field set to val, handling any necessary type
185  *   promotion to avoid truncation of val.
186  * - MASK(<register>_<field)
187  *   An in-place bitmask covering all bits of the field.
188  * - EXTRACT(<register_field> <register_value>)
189  *   A macro to extract the value of a register field shifted down so the
190  *   value can be evaluated directly.
191  * - EXTRACT_BIT(<register_field> <register_value>)
192  *   A macro to extract the value of a register bit shifted down so the
193  *   value can be evaluated directly.
194  */
195 #define INPLACE(regfield, val) \
196 	(((val) + UL(0)) << (regfield##_SHIFT))
197 
198 #define MASK(regfield) \
199 	((~0UL >> (64UL - (regfield##_WIDTH))) << (regfield##_SHIFT))
200 
201 #define EXTRACT(regfield, reg) \
202 	(((reg) & MASK(regfield)) >> (regfield##_SHIFT))
203 
204 #define EXTRACT_BIT(regfield, reg) \
205 	(((reg) >> (regfield##_SHIFT)) & UL(1))
206 
207 /*
208  * Generates an unsigned long long (64-bit) value where the bits @_msb
209  * through @_lsb (inclusive) are set to one and all other bits are zero.  The
210  * parameters can hold values from 0 through 63 and if _msb == _lsb a single
211  * bit is set at that location.
212  */
213 #define BIT_MASK_ULL(_msb, _lsb) \
214 	((~ULL(0) >> (63UL - (_msb))) & (~ULL(0) << (_lsb)))
215 
216 /*
217  * Stringify the result of expansion of a macro argument
218  */
219 #ifndef __XSTRING
220 #define __STRING(x)	#x
221 #define __XSTRING(x)	__STRING(x)
222 #endif
223 
224 /*
225  * Defines member of structure and reserves space
226  * for the next member with specified offset.
227  */
228 /* cppcheck-suppress [misra-c2012-20.7] */
229 #define SET_MEMBER(member, start, end)	\
230 	union {				\
231 		member;			\
232 		unsigned char reserved##end[((end) - (start))]; \
233 	}
234 
235 #define FALLTHROUGH	__attribute__((fallthrough))
236 
237 /*
238  * Helper macros for making code parts to be conditionally compiled, depending
239  * on the current build being a CBMC build or not.
240  */
241 #ifdef CBMC
242 #define IF_NCBMC(x)
243 #define IF_CBMC(x)	x
244 #else /* CBMC */
245 #define IF_NCBMC(x)	x
246 #define IF_CBMC(x)
247 #endif /* CBMC */
248 
249 /* cppcheck-suppress misra-c2012-20.7 */
250 #define SIZEOF_MEMBER(struct_type, member) (sizeof(((struct_type *)0)->member))
251 
252 #define INT_TO_ULONG(_code) \
253 	/* coverity[integer_overflow:SUPPRESS] */ \
254 	/* coverity[return_overflow:SUPPRESS] */ \
255 	(unsigned long)(_code)
256 
257 #endif /* !(defined(__ASSEMBLER__) || defined(__LINKER__)) */
258 
259 #endif /* UTILS_DEF_H */
260