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