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)	(_x##U)
31 # define   U(_x)	U_(_x)
32 # define  UL(_x)	(_x##UL)
33 # define ULL(_x)	(_x##ULL)
34 # define   L(_x)	(_x##L)
35 # define  LL(_x)	(_x##LL)
36 #endif /* __ASSEMBLER__ */
37 
38 /* Short forms for commonly used attributes */
39 #define __dead2		__attribute__((__noreturn__))
40 #define __deprecated	__attribute__((__deprecated__))
41 #define __packed	__attribute__((__packed__))
42 #define __used		__attribute__((__used__))
43 #define __unused	__attribute__((__unused__))
44 #define __aligned(x)	__attribute__((__aligned__(x)))
45 #define __section(x)	__attribute__((__section__(x)))
46 
47 #define __printflike(fmtarg, firstvararg) \
48 		__attribute__((__format__ (__printf__, fmtarg, firstvararg)))
49 
50 /*
51  * The round_up() macro rounds up a value to the given boundary in a
52  * type-agnostic yet type-safe manner. The boundary must be a power of two.
53  * In other words, it computes the smallest multiple of boundary which is
54  * greater than or equal to value.
55  *
56  * round_down() is similar but rounds the value down instead.
57  */
58 #define round_boundary(value, boundary)		\
59 	((__typeof__(value))((boundary) - 1))
60 
61 #define round_up(value, boundary)		\
62 	((((value) - 1) | round_boundary(value, boundary)) + 1)
63 
64 #define round_down(value, boundary)		\
65 	((value) & ~round_boundary(value, boundary))
66 
67 /* Compute the number of elements in the given array */
68 #define ARRAY_SIZE(a)	\
69 	(sizeof(a) / sizeof((a)[0]))
70 
71 #define ARRAY_LEN(_a)	\
72 	((sizeof(_a) / sizeof(_a[0])) + CHECK_TYPE_IS_ARRAY(_a))
73 
74 /*
75  * Macro checks types of array and variable/value to write
76  * and reports compilation error if they mismatch.
77  */
78 #define	CHECK_ARRAY_TYPE(_a, _v)	\
79 	_Static_assert(__builtin_types_compatible_p(typeof(_a[0]), typeof(_v)), \
80 	"array type mismatch")
81 
82 /*
83  * Array read/write macros with boundary and types checks
84  * _a: name of array
85  * _i: index
86  * _v: variable/value to write
87  */
88 #define	ARRAY_READ(_a, _i, _v)		\
89 ({					\
90 	CHECK_ARRAY_TYPE(_a, _v);	\
91 	if (_i >= ARRAY_SIZE(_a)) {	\
92 		panic();		\
93 	}				\
94 	_v = _a[_i];			\
95 })
96 
97 #define	ARRAY_WRITE(_a, _i, _v)		\
98 ({					\
99 	CHECK_ARRAY_TYPE(_a, _v);	\
100 	if (_i >= ARRAY_SIZE(_a)) {	\
101 		panic();		\
102 	}				\
103 	_a[_i] = _v;			\
104 })
105 
106 #define COMPILER_ASSERT(_condition) extern char compiler_assert[(_condition) ? 1 : -1]
107 
108 /*
109  * If _expr is false, this will result in a compile time error as it tries to
110  * define a bitfield of size -1 in that case.  Otherwise, it will define a
111  * bitfield of size 0, which is valid, and not create a compiler warning.
112  *
113  * The return value is only relevant when the compilation succeeds, and by
114  * subtracting the size of the same struct, this should always return 0 as a
115  * value and can be included in other expressions.
116  */
117 #define COMPILER_ASSERT_ZERO(_expr) (sizeof(struct { char: (-!(_expr)); }) \
118 				- sizeof(struct { char: 0; }))
119 
120 #define CHECK_TYPE_IS_ARRAY(_v) \
121 	COMPILER_ASSERT_ZERO(!__builtin_types_compatible_p(typeof(_v), typeof(&(_v[0]))))
122 
123 #define IS_POWER_OF_TWO(x)			\
124 	((((x) + UL(0)) & ((x) - UL(1))) == UL(0))
125 
126 #define COMPILER_BARRIER() __asm__ volatile ("" ::: "memory")
127 
128 #define ALIGNED(_size, _alignment) (((unsigned long)(_size) % (_alignment)) == UL(0))
129 
130 #define GRANULE_ALIGNED(_addr) ALIGNED((void *)(_addr), GRANULE_SIZE)
131 #define GRANULE_SHIFT	(UL(12))
132 #define GRANULE_MASK	(~0xfffUL)
133 
134 #define HAS_MPAM 0
135 
136 #if HAS_MPAM
137 #define MPAM(_x...) _x
138 #else
139 #define MPAM(_x...)
140 #endif
141 
142 #define HAS_SPE 0
143 
144 #if HAS_SPE
145 #define SPE(_x...) _x
146 #else
147 #define SPE(_x...)
148 #endif
149 
150 #if !(defined(__ASSEMBLER__) || defined(__LINKER__))
151 
152 /*
153  * System register field definitions.
154  *
155  * For any register field we define:
156  * - <register>_<field>_SHIFT
157  *   The bit offset of the LSB of the field.
158  * - <register>_<field>_WIDTH
159  *   The width of the field in bits.
160  *
161  * For single bit fields, we define:
162  * - <register>_<field>_BIT
163  *   The in-place value of the field with the bit set.
164  *
165  * For multi-bit fields, we define:
166  * - <register>_<field>_<enum>
167  *   The in-place value of the field set to the value corresponding to the
168  *   enumeration name.
169  *
170  * For any register field, we define:
171  * - INPLACE(<register>_<field>, val)
172  *   The in-place value of the field set to val, handling any necessary type
173  *   promotion to avoid truncation of val.
174  * - MASK(<register>_<field)
175  *   An in-place bitmask covering all bits of the field.
176  * - EXTRACT(<register_field> <register_value>)
177  *   A macro to extract the value of a register field shifted down so the
178  *   value can be evaluated directly.
179  * - EXTRACT_BIT(<register_field> <register_value>)
180  *   A macro to extract the value of a register bit shifted down so the
181  *   value can be evaluated directly.
182  */
183 #define INPLACE(regfield, val) \
184 	(((val) + UL(0)) << (regfield##_SHIFT))
185 
186 #define MASK(regfield) \
187 	((~0UL >> (64UL - (regfield##_WIDTH))) << (regfield##_SHIFT))
188 
189 #define EXTRACT(regfield, reg) \
190 	(((reg) & MASK(regfield)) >> (regfield##_SHIFT))
191 
192 #define EXTRACT_BIT(regfield, reg) \
193 	(((reg) >> (regfield##_SHIFT)) & UL(1))
194 
195 /*
196  * Generates an unsigned long long (64-bit) value where the bits @_msb
197  * through @_lsb (inclusive) are set to one and all other bits are zero.  The
198  * parameters can hold values from 0 through 63 and if _msb == _lsb a single bit
199  * is set at that location.
200  */
201 #define BIT_MASK_ULL(_msb, _lsb) \
202 	((~ULL(0) >> (63UL - (_msb))) & (~ULL(0) << (_lsb)))
203 
204 /*
205  * Stringify the result of expansion of a macro argument
206  */
207 #ifndef __XSTRING
208 #define __STRING(x)	#x
209 #define __XSTRING(x)	__STRING(x)
210 #endif
211 
212 /*
213  * Defines member of structure and reserves space
214  * for the next member with specified offset.
215  */
216 #define SET_MEMBER(member, start, end)	\
217 	union {				\
218 		member;			\
219 		unsigned char reserved##end[end - start]; \
220 	}
221 
222 #define	FALLTHROUGH	__attribute__((fallthrough))
223 
224 #endif /* !(defined(__ASSEMBLER__) || defined(__LINKER__)) */
225 
226 #endif /* UTILS_DEF_H */
227