blob: 2dc310af6462d80fc2575ad73238cf1a98d02ee7 [file] [log] [blame]
Soby Mathewb4c6df42022-11-09 11:13:29 +00001/*
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 */