xref: /aosp_15_r20/external/arm-trusted-firmware/include/lib/utils_def.h (revision 54fd6939e177f8ff529b10183254802c76df6d08)
1*54fd6939SJiyong Park /*
2*54fd6939SJiyong Park  * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
3*54fd6939SJiyong Park  * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
4*54fd6939SJiyong Park  *
5*54fd6939SJiyong Park  * SPDX-License-Identifier: BSD-3-Clause
6*54fd6939SJiyong Park  */
7*54fd6939SJiyong Park 
8*54fd6939SJiyong Park #ifndef UTILS_DEF_H
9*54fd6939SJiyong Park #define UTILS_DEF_H
10*54fd6939SJiyong Park 
11*54fd6939SJiyong Park #include <export/lib/utils_def_exp.h>
12*54fd6939SJiyong Park 
13*54fd6939SJiyong Park /* Compute the number of elements in the given array */
14*54fd6939SJiyong Park #define ARRAY_SIZE(a)				\
15*54fd6939SJiyong Park 	(sizeof(a) / sizeof((a)[0]))
16*54fd6939SJiyong Park 
17*54fd6939SJiyong Park #define IS_POWER_OF_TWO(x)			\
18*54fd6939SJiyong Park 	(((x) & ((x) - 1)) == 0)
19*54fd6939SJiyong Park 
20*54fd6939SJiyong Park #define SIZE_FROM_LOG2_WORDS(n)		(U(4) << (n))
21*54fd6939SJiyong Park 
22*54fd6939SJiyong Park #define BIT_32(nr)			(U(1) << (nr))
23*54fd6939SJiyong Park #define BIT_64(nr)			(ULL(1) << (nr))
24*54fd6939SJiyong Park 
25*54fd6939SJiyong Park #ifdef __aarch64__
26*54fd6939SJiyong Park #define BIT				BIT_64
27*54fd6939SJiyong Park #else
28*54fd6939SJiyong Park #define BIT				BIT_32
29*54fd6939SJiyong Park #endif
30*54fd6939SJiyong Park 
31*54fd6939SJiyong Park /*
32*54fd6939SJiyong Park  * Create a contiguous bitmask starting at bit position @l and ending at
33*54fd6939SJiyong Park  * position @h. For example
34*54fd6939SJiyong Park  * GENMASK_64(39, 21) gives us the 64bit vector 0x000000ffffe00000.
35*54fd6939SJiyong Park  */
36*54fd6939SJiyong Park #if defined(__LINKER__) || defined(__ASSEMBLER__)
37*54fd6939SJiyong Park #define GENMASK_32(h, l) \
38*54fd6939SJiyong Park 	(((0xFFFFFFFF) << (l)) & (0xFFFFFFFF >> (32 - 1 - (h))))
39*54fd6939SJiyong Park 
40*54fd6939SJiyong Park #define GENMASK_64(h, l) \
41*54fd6939SJiyong Park 	((~0 << (l)) & (~0 >> (64 - 1 - (h))))
42*54fd6939SJiyong Park #else
43*54fd6939SJiyong Park #define GENMASK_32(h, l) \
44*54fd6939SJiyong Park 	(((~UINT32_C(0)) << (l)) & (~UINT32_C(0) >> (32 - 1 - (h))))
45*54fd6939SJiyong Park 
46*54fd6939SJiyong Park #define GENMASK_64(h, l) \
47*54fd6939SJiyong Park 	(((~UINT64_C(0)) << (l)) & (~UINT64_C(0) >> (64 - 1 - (h))))
48*54fd6939SJiyong Park #endif
49*54fd6939SJiyong Park 
50*54fd6939SJiyong Park #ifdef __aarch64__
51*54fd6939SJiyong Park #define GENMASK				GENMASK_64
52*54fd6939SJiyong Park #else
53*54fd6939SJiyong Park #define GENMASK				GENMASK_32
54*54fd6939SJiyong Park #endif
55*54fd6939SJiyong Park 
56*54fd6939SJiyong Park /*
57*54fd6939SJiyong Park  * This variant of div_round_up can be used in macro definition but should not
58*54fd6939SJiyong Park  * be used in C code as the `div` parameter is evaluated twice.
59*54fd6939SJiyong Park  */
60*54fd6939SJiyong Park #define DIV_ROUND_UP_2EVAL(n, d)	(((n) + (d) - 1) / (d))
61*54fd6939SJiyong Park 
62*54fd6939SJiyong Park #define div_round_up(val, div) __extension__ ({	\
63*54fd6939SJiyong Park 	__typeof__(div) _div = (div);		\
64*54fd6939SJiyong Park 	((val) + _div - (__typeof__(div)) 1) / _div;		\
65*54fd6939SJiyong Park })
66*54fd6939SJiyong Park 
67*54fd6939SJiyong Park #define MIN(x, y) __extension__ ({	\
68*54fd6939SJiyong Park 	__typeof__(x) _x = (x);		\
69*54fd6939SJiyong Park 	__typeof__(y) _y = (y);		\
70*54fd6939SJiyong Park 	(void)(&_x == &_y);		\
71*54fd6939SJiyong Park 	_x < _y ? _x : _y;		\
72*54fd6939SJiyong Park })
73*54fd6939SJiyong Park 
74*54fd6939SJiyong Park #define MAX(x, y) __extension__ ({	\
75*54fd6939SJiyong Park 	__typeof__(x) _x = (x);		\
76*54fd6939SJiyong Park 	__typeof__(y) _y = (y);		\
77*54fd6939SJiyong Park 	(void)(&_x == &_y);		\
78*54fd6939SJiyong Park 	_x > _y ? _x : _y;		\
79*54fd6939SJiyong Park })
80*54fd6939SJiyong Park 
81*54fd6939SJiyong Park #define CLAMP(x, min, max) __extension__ ({ \
82*54fd6939SJiyong Park 	__typeof__(x) _x = (x); \
83*54fd6939SJiyong Park 	__typeof__(min) _min = (min); \
84*54fd6939SJiyong Park 	__typeof__(max) _max = (max); \
85*54fd6939SJiyong Park 	(void)(&_x == &_min); \
86*54fd6939SJiyong Park 	(void)(&_x == &_max); \
87*54fd6939SJiyong Park 	(_x > _max ? _max : (_x < _min ? _min : _x)); \
88*54fd6939SJiyong Park })
89*54fd6939SJiyong Park 
90*54fd6939SJiyong Park /*
91*54fd6939SJiyong Park  * The round_up() macro rounds up a value to the given boundary in a
92*54fd6939SJiyong Park  * type-agnostic yet type-safe manner. The boundary must be a power of two.
93*54fd6939SJiyong Park  * In other words, it computes the smallest multiple of boundary which is
94*54fd6939SJiyong Park  * greater than or equal to value.
95*54fd6939SJiyong Park  *
96*54fd6939SJiyong Park  * round_down() is similar but rounds the value down instead.
97*54fd6939SJiyong Park  */
98*54fd6939SJiyong Park #define round_boundary(value, boundary)		\
99*54fd6939SJiyong Park 	((__typeof__(value))((boundary) - 1))
100*54fd6939SJiyong Park 
101*54fd6939SJiyong Park #define round_up(value, boundary)		\
102*54fd6939SJiyong Park 	((((value) - 1) | round_boundary(value, boundary)) + 1)
103*54fd6939SJiyong Park 
104*54fd6939SJiyong Park #define round_down(value, boundary)		\
105*54fd6939SJiyong Park 	((value) & ~round_boundary(value, boundary))
106*54fd6939SJiyong Park 
107*54fd6939SJiyong Park /*
108*54fd6939SJiyong Park  * Evaluates to 1 if (ptr + inc) overflows, 0 otherwise.
109*54fd6939SJiyong Park  * Both arguments must be unsigned pointer values (i.e. uintptr_t).
110*54fd6939SJiyong Park  */
111*54fd6939SJiyong Park #define check_uptr_overflow(_ptr, _inc)		\
112*54fd6939SJiyong Park 	((_ptr) > (UINTPTR_MAX - (_inc)))
113*54fd6939SJiyong Park 
114*54fd6939SJiyong Park /*
115*54fd6939SJiyong Park  * Evaluates to 1 if (u32 + inc) overflows, 0 otherwise.
116*54fd6939SJiyong Park  * Both arguments must be 32-bit unsigned integers (i.e. effectively uint32_t).
117*54fd6939SJiyong Park  */
118*54fd6939SJiyong Park #define check_u32_overflow(_u32, _inc) \
119*54fd6939SJiyong Park 	((_u32) > (UINT32_MAX - (_inc)))
120*54fd6939SJiyong Park 
121*54fd6939SJiyong Park /* Register size of the current architecture. */
122*54fd6939SJiyong Park #ifdef __aarch64__
123*54fd6939SJiyong Park #define REGSZ		U(8)
124*54fd6939SJiyong Park #else
125*54fd6939SJiyong Park #define REGSZ		U(4)
126*54fd6939SJiyong Park #endif
127*54fd6939SJiyong Park 
128*54fd6939SJiyong Park /*
129*54fd6939SJiyong Park  * Test for the current architecture version to be at least the version
130*54fd6939SJiyong Park  * expected.
131*54fd6939SJiyong Park  */
132*54fd6939SJiyong Park #define ARM_ARCH_AT_LEAST(_maj, _min) \
133*54fd6939SJiyong Park 	((ARM_ARCH_MAJOR > (_maj)) || \
134*54fd6939SJiyong Park 	 ((ARM_ARCH_MAJOR == (_maj)) && (ARM_ARCH_MINOR >= (_min))))
135*54fd6939SJiyong Park 
136*54fd6939SJiyong Park /*
137*54fd6939SJiyong Park  * Import an assembly or linker symbol as a C expression with the specified
138*54fd6939SJiyong Park  * type
139*54fd6939SJiyong Park  */
140*54fd6939SJiyong Park #define IMPORT_SYM(type, sym, name) \
141*54fd6939SJiyong Park 	extern char sym[];\
142*54fd6939SJiyong Park 	static const __attribute__((unused)) type name = (type) sym;
143*54fd6939SJiyong Park 
144*54fd6939SJiyong Park /*
145*54fd6939SJiyong Park  * When the symbol is used to hold a pointer, its alignment can be asserted
146*54fd6939SJiyong Park  * with this macro. For example, if there is a linker symbol that is going to
147*54fd6939SJiyong Park  * be used as a 64-bit pointer, the value of the linker symbol must also be
148*54fd6939SJiyong Park  * aligned to 64 bit. This macro makes sure this is the case.
149*54fd6939SJiyong Park  */
150*54fd6939SJiyong Park #define ASSERT_SYM_PTR_ALIGN(sym) assert(((size_t)(sym) % __alignof__(*(sym))) == 0)
151*54fd6939SJiyong Park 
152*54fd6939SJiyong Park #define COMPILER_BARRIER() __asm__ volatile ("" ::: "memory")
153*54fd6939SJiyong Park 
154*54fd6939SJiyong Park /* Compiler builtin of GCC >= 9 and planned in llvm */
155*54fd6939SJiyong Park #ifdef __HAVE_SPECULATION_SAFE_VALUE
156*54fd6939SJiyong Park # define SPECULATION_SAFE_VALUE(var) __builtin_speculation_safe_value(var)
157*54fd6939SJiyong Park #else
158*54fd6939SJiyong Park # define SPECULATION_SAFE_VALUE(var) var
159*54fd6939SJiyong Park #endif
160*54fd6939SJiyong Park 
161*54fd6939SJiyong Park /*
162*54fd6939SJiyong Park  * Ticks elapsed in one second with a signal of 1 MHz
163*54fd6939SJiyong Park  */
164*54fd6939SJiyong Park #define MHZ_TICKS_PER_SEC	U(1000000)
165*54fd6939SJiyong Park 
166*54fd6939SJiyong Park /*
167*54fd6939SJiyong Park  * Ticks elapsed in one second with a signal of 1 KHz
168*54fd6939SJiyong Park  */
169*54fd6939SJiyong Park #define KHZ_TICKS_PER_SEC U(1000)
170*54fd6939SJiyong Park 
171*54fd6939SJiyong Park #endif /* UTILS_DEF_H */
172