xref: /rk3399_ARM-atf/include/lib/utils.h (revision ed7562521b8b68e6e3d681c9564cd69afbf93e89)
1 /*
2  * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of ARM nor the names of its contributors may be used
15  * to endorse or promote products derived from this software without specific
16  * prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #ifndef __UTILS_H__
32 #define __UTILS_H__
33 
34 /* Compute the number of elements in the given array */
35 #define ARRAY_SIZE(a)				\
36 	(sizeof(a) / sizeof((a)[0]))
37 
38 #define IS_POWER_OF_TWO(x)			\
39 	(((x) & ((x) - 1)) == 0)
40 
41 #define SIZE_FROM_LOG2_WORDS(n)		(4 << (n))
42 
43 #define BIT(nr)				(1UL << (nr))
44 
45 #define MIN(x, y) __extension__ ({	\
46 	__typeof__(x) _x = (x);		\
47 	__typeof__(y) _y = (y);		\
48 	(void)(&_x == &_y);		\
49 	_x < _y ? _x : _y;		\
50 })
51 
52 #define MAX(x, y) __extension__ ({	\
53 	__typeof__(x) _x = (x);		\
54 	__typeof__(y) _y = (y);		\
55 	(void)(&_x == &_y);		\
56 	_x > _y ? _x : _y;		\
57 })
58 
59 /*
60  * The round_up() macro rounds up a value to the given boundary in a
61  * type-agnostic yet type-safe manner. The boundary must be a power of two.
62  * In other words, it computes the smallest multiple of boundary which is
63  * greater than or equal to value.
64  *
65  * round_down() is similar but rounds the value down instead.
66  */
67 #define round_boundary(value, boundary)		\
68 	((__typeof__(value))((boundary) - 1))
69 
70 #define round_up(value, boundary)		\
71 	((((value) - 1) | round_boundary(value, boundary)) + 1)
72 
73 #define round_down(value, boundary)		\
74 	((value) & ~round_boundary(value, boundary))
75 
76 /*
77  * Evaluates to 1 if (ptr + inc) overflows, 0 otherwise.
78  * Both arguments must be unsigned pointer values (i.e. uintptr_t).
79  */
80 #define check_uptr_overflow(ptr, inc)		\
81 	(((ptr) > UINTPTR_MAX - (inc)) ? 1 : 0)
82 
83 /*
84  * For those constants to be shared between C and other sources, apply a 'ull'
85  * suffix to the argument only in C, to avoid undefined or unintended behaviour.
86  *
87  * The GNU assembler and linker do not support the 'ull' suffix (it causes the
88  * build process to fail) therefore the suffix is omitted when used in linker
89  * scripts and assembler files.
90 */
91 #if defined(__LINKER__) || defined(__ASSEMBLY__)
92 # define ULL(_x)	(_x)
93 #else
94 # define ULL(_x)	(_x##ull)
95 #endif
96 
97 /*
98  * C code should be put in this part of the header to avoid breaking ASM files
99  * or linker scripts including it.
100  */
101 #if !(defined(__LINKER__) || defined(__ASSEMBLY__))
102 
103 #include <types.h>
104 
105 /*
106  * Fill a region of normal memory of size "length" in bytes with zero bytes.
107  *
108  * WARNING: This function can only operate on normal memory. This means that
109  *          the MMU must be enabled when using this function. Otherwise, use
110  *          zeromem.
111  */
112 void zero_normalmem(void *mem, u_register_t length);
113 
114 /*
115  * Fill a region of memory of size "length" in bytes with null bytes.
116  *
117  * Unlike zero_normalmem, this function has no restriction on the type of
118  * memory targeted and can be used for any device memory as well as normal
119  * memory. This function must be used instead of zero_normalmem when MMU is
120  * disabled.
121  *
122  * NOTE: When data cache and MMU are enabled, prefer zero_normalmem for faster
123  *       zeroing.
124  */
125 void zeromem(void *mem, u_register_t length);
126 #endif /* !(defined(__LINKER__) || defined(__ASSEMBLY__)) */
127 
128 #endif /* __UTILS_H__ */
129