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