xref: /rk3399_ARM-atf/include/lib/utils_def.h (revision 46c613ee0a4b5d6ff2dd016c455f8cc7ee9cabd4)
153d9c9c8SScott Branden /*
29f85f9e3SJoel Hutton  * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
353d9c9c8SScott Branden  *
482cb2c1aSdp-arm  * SPDX-License-Identifier: BSD-3-Clause
553d9c9c8SScott Branden  */
653d9c9c8SScott Branden 
7f00119deSAntonio Nino Diaz #ifndef UTILS_DEF_H
8f00119deSAntonio Nino Diaz #define UTILS_DEF_H
953d9c9c8SScott Branden 
1053d9c9c8SScott Branden /* Compute the number of elements in the given array */
1153d9c9c8SScott Branden #define ARRAY_SIZE(a)				\
1253d9c9c8SScott Branden 	(sizeof(a) / sizeof((a)[0]))
1353d9c9c8SScott Branden 
1453d9c9c8SScott Branden #define IS_POWER_OF_TWO(x)			\
1553d9c9c8SScott Branden 	(((x) & ((x) - 1)) == 0)
1653d9c9c8SScott Branden 
1753d9c9c8SScott Branden #define SIZE_FROM_LOG2_WORDS(n)		(4 << (n))
1853d9c9c8SScott Branden 
19167c5f80SYann Gautier #define BIT_32(nr)			(U(1) << (nr))
20167c5f80SYann Gautier #define BIT_64(nr)			(ULL(1) << (nr))
21167c5f80SYann Gautier 
22167c5f80SYann Gautier #ifdef AARCH32
23167c5f80SYann Gautier #define BIT				BIT_32
24167c5f80SYann Gautier #else
25167c5f80SYann Gautier #define BIT				BIT_64
26167c5f80SYann Gautier #endif
2753d9c9c8SScott Branden 
28ebf1ca10SSoby Mathew /*
2939676357SYann Gautier  * Create a contiguous bitmask starting at bit position @l and ending at
3039676357SYann Gautier  * position @h. For example
3139676357SYann Gautier  * GENMASK_64(39, 21) gives us the 64bit vector 0x000000ffffe00000.
3239676357SYann Gautier  */
33*46c613eeSYann Gautier #if defined(__LINKER__) || defined(__ASSEMBLY__)
34*46c613eeSYann Gautier #define GENMASK_32(h, l) \
35*46c613eeSYann Gautier 	(((0xFFFFFFFF) << (l)) & (0xFFFFFFFF >> (32 - 1 - (h))))
36*46c613eeSYann Gautier 
37*46c613eeSYann Gautier #define GENMASK_64(h, l) \
38*46c613eeSYann Gautier 	((~0 << (l)) & (~0 >> (64 - 1 - (h))))
39*46c613eeSYann Gautier #else
4039676357SYann Gautier #define GENMASK_32(h, l) \
4139676357SYann Gautier 	(((~UINT32_C(0)) << (l)) & (~UINT32_C(0) >> (32 - 1 - (h))))
4239676357SYann Gautier 
4339676357SYann Gautier #define GENMASK_64(h, l) \
4439676357SYann Gautier 	(((~UINT64_C(0)) << (l)) & (~UINT64_C(0) >> (64 - 1 - (h))))
45*46c613eeSYann Gautier #endif
4639676357SYann Gautier 
4739676357SYann Gautier #ifdef AARCH32
4839676357SYann Gautier #define GENMASK				GENMASK_32
4939676357SYann Gautier #else
5039676357SYann Gautier #define GENMASK				GENMASK_64
5139676357SYann Gautier #endif
5239676357SYann Gautier 
5339676357SYann Gautier /*
54ebf1ca10SSoby Mathew  * This variant of div_round_up can be used in macro definition but should not
55ebf1ca10SSoby Mathew  * be used in C code as the `div` parameter is evaluated twice.
56ebf1ca10SSoby Mathew  */
57ebf1ca10SSoby Mathew #define DIV_ROUND_UP_2EVAL(n, d)	(((n) + (d) - 1) / (d))
58ebf1ca10SSoby Mathew 
597baa7bcaSJulius Werner #define div_round_up(val, div) __extension__ ({	\
607baa7bcaSJulius Werner 	__typeof__(div) _div = (div);		\
61d47509d6SSathees Balya 	((val) + _div - (__typeof__(div)) 1) / _div;		\
627baa7bcaSJulius Werner })
637baa7bcaSJulius Werner 
6453d9c9c8SScott Branden #define MIN(x, y) __extension__ ({	\
6553d9c9c8SScott Branden 	__typeof__(x) _x = (x);		\
6653d9c9c8SScott Branden 	__typeof__(y) _y = (y);		\
6753d9c9c8SScott Branden 	(void)(&_x == &_y);		\
6853d9c9c8SScott Branden 	_x < _y ? _x : _y;		\
6953d9c9c8SScott Branden })
7053d9c9c8SScott Branden 
7153d9c9c8SScott Branden #define MAX(x, y) __extension__ ({	\
7253d9c9c8SScott Branden 	__typeof__(x) _x = (x);		\
7353d9c9c8SScott Branden 	__typeof__(y) _y = (y);		\
7453d9c9c8SScott Branden 	(void)(&_x == &_y);		\
7553d9c9c8SScott Branden 	_x > _y ? _x : _y;		\
7653d9c9c8SScott Branden })
7753d9c9c8SScott Branden 
7853d9c9c8SScott Branden /*
7953d9c9c8SScott Branden  * The round_up() macro rounds up a value to the given boundary in a
8053d9c9c8SScott Branden  * type-agnostic yet type-safe manner. The boundary must be a power of two.
8153d9c9c8SScott Branden  * In other words, it computes the smallest multiple of boundary which is
8253d9c9c8SScott Branden  * greater than or equal to value.
8353d9c9c8SScott Branden  *
8453d9c9c8SScott Branden  * round_down() is similar but rounds the value down instead.
8553d9c9c8SScott Branden  */
8653d9c9c8SScott Branden #define round_boundary(value, boundary)		\
8753d9c9c8SScott Branden 	((__typeof__(value))((boundary) - 1))
8853d9c9c8SScott Branden 
8953d9c9c8SScott Branden #define round_up(value, boundary)		\
9053d9c9c8SScott Branden 	((((value) - 1) | round_boundary(value, boundary)) + 1)
9153d9c9c8SScott Branden 
9253d9c9c8SScott Branden #define round_down(value, boundary)		\
9353d9c9c8SScott Branden 	((value) & ~round_boundary(value, boundary))
9453d9c9c8SScott Branden 
9553d9c9c8SScott Branden /*
9653d9c9c8SScott Branden  * Evaluates to 1 if (ptr + inc) overflows, 0 otherwise.
9753d9c9c8SScott Branden  * Both arguments must be unsigned pointer values (i.e. uintptr_t).
9853d9c9c8SScott Branden  */
99f00119deSAntonio Nino Diaz #define check_uptr_overflow(_ptr, _inc)		\
100f00119deSAntonio Nino Diaz 	((_ptr) > (UINTPTR_MAX - (_inc)))
10153d9c9c8SScott Branden 
10253d9c9c8SScott Branden /*
10330d81c36SJeenu Viswambharan  * Evaluates to 1 if (u32 + inc) overflows, 0 otherwise.
10430d81c36SJeenu Viswambharan  * Both arguments must be 32-bit unsigned integers (i.e. effectively uint32_t).
10530d81c36SJeenu Viswambharan  */
106f00119deSAntonio Nino Diaz #define check_u32_overflow(_u32, _inc) \
107f00119deSAntonio Nino Diaz 	((_u32) > (UINT32_MAX - (_inc)))
10830d81c36SJeenu Viswambharan 
10930d81c36SJeenu Viswambharan /*
110029f5a28SAntonio Nino Diaz  * For those constants to be shared between C and other sources, apply a 'U',
111029f5a28SAntonio Nino Diaz  * 'UL', 'ULL', 'L' or 'LL' suffix to the argument only in C, to avoid
112029f5a28SAntonio Nino Diaz  * undefined or unintended behaviour.
11353d9c9c8SScott Branden  *
114029f5a28SAntonio Nino Diaz  * The GNU assembler and linker do not support these suffixes (it causes the
115029f5a28SAntonio Nino Diaz  * build process to fail) therefore the suffix is omitted when used in linker
116029f5a28SAntonio Nino Diaz  * scripts and assembler files.
11753d9c9c8SScott Branden */
11853d9c9c8SScott Branden #if defined(__LINKER__) || defined(__ASSEMBLY__)
1196176b4fcSVarun Wadekar # define   U(_x)	(_x)
120029f5a28SAntonio Nino Diaz # define  UL(_x)	(_x)
12153d9c9c8SScott Branden # define ULL(_x)	(_x)
122029f5a28SAntonio Nino Diaz # define   L(_x)	(_x)
123029f5a28SAntonio Nino Diaz # define  LL(_x)	(_x)
12453d9c9c8SScott Branden #else
1255724481fSDavid Cunado # define   U(_x)	(_x##U)
126029f5a28SAntonio Nino Diaz # define  UL(_x)	(_x##UL)
1275724481fSDavid Cunado # define ULL(_x)	(_x##ULL)
128029f5a28SAntonio Nino Diaz # define   L(_x)	(_x##L)
129029f5a28SAntonio Nino Diaz # define  LL(_x)	(_x##LL)
13053d9c9c8SScott Branden #endif
13153d9c9c8SScott Branden 
132155a1006SJulius Werner /* Register size of the current architecture. */
133155a1006SJulius Werner #ifdef AARCH32
134155a1006SJulius Werner #define REGSZ		U(4)
135155a1006SJulius Werner #else
136155a1006SJulius Werner #define REGSZ		U(8)
137155a1006SJulius Werner #endif
138155a1006SJulius Werner 
139f45e232aSJeenu Viswambharan /*
140f45e232aSJeenu Viswambharan  * Test for the current architecture version to be at least the version
141f45e232aSJeenu Viswambharan  * expected.
142f45e232aSJeenu Viswambharan  */
143f45e232aSJeenu Viswambharan #define ARM_ARCH_AT_LEAST(_maj, _min) \
1440cc7aa89SJeenu Viswambharan 	((ARM_ARCH_MAJOR > (_maj)) || \
1450cc7aa89SJeenu Viswambharan 	 ((ARM_ARCH_MAJOR == (_maj)) && (ARM_ARCH_MINOR >= (_min))))
146f45e232aSJeenu Viswambharan 
1479f85f9e3SJoel Hutton /*
1489f85f9e3SJoel Hutton  * Import an assembly or linker symbol as a C expression with the specified
1499f85f9e3SJoel Hutton  * type
1509f85f9e3SJoel Hutton  */
1519f85f9e3SJoel Hutton #define IMPORT_SYM(type, sym, name) \
1529f85f9e3SJoel Hutton 	extern char sym[];\
1539f85f9e3SJoel Hutton 	static const __attribute__((unused)) type name = (type) sym;
1549f85f9e3SJoel Hutton 
1559f85f9e3SJoel Hutton /*
1569f85f9e3SJoel Hutton  * When the symbol is used to hold a pointer, its alignment can be asserted
1579f85f9e3SJoel Hutton  * with this macro. For example, if there is a linker symbol that is going to
1589f85f9e3SJoel Hutton  * be used as a 64-bit pointer, the value of the linker symbol must also be
1599f85f9e3SJoel Hutton  * aligned to 64 bit. This macro makes sure this is the case.
1609f85f9e3SJoel Hutton  */
1619f85f9e3SJoel Hutton #define ASSERT_SYM_PTR_ALIGN(sym) assert(((size_t)(sym) % __alignof__(*(sym))) == 0)
1629f85f9e3SJoel Hutton 
1639f85f9e3SJoel Hutton 
164f00119deSAntonio Nino Diaz #endif /* UTILS_DEF_H */
165