1 /*
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
4 */
5 #ifndef _TYPES_H_
6 #define _TYPES_H_
7
8 #include "macros.h"
9 #include <stdint.h>
10 #include <stdarg.h>
11 #include <sched.h>
12 #include <sys/types.h>
13
14 #define MAXCOMLEN 19 /* max command name remembered */
15 #define MAXINTERP PATH_MAX /* max interpreter file name length */
16 #define MAXLOGNAME 33 /* max login name length (incl. NUL) */
17 #define SPECNAMELEN 63 /* max length of devicename */
18
19 typedef cpu_set_t cpuset_t;
20 typedef uint64_t vm_paddr_t;
21 typedef uint64_t vm_ooffset_t;
22 typedef uint64_t cap_ioctl_t;
23
24 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
25
26 #define container_of(ptr, type, member) ({ \
27 const typeof(((type *)0)->member) * __mptr = (ptr); \
28 (type *)((char *)__mptr - (offsetof(type, member))); \
29 })
30
31 #define __aligned(x) __attribute__((aligned(x)))
32 #define __section(x) __attribute__((__section__(x)))
33 #define __MAKE_SET(set, sym) \
34 static void const * const __set_##set##_sym_##sym \
35 __section("set_" #set) __attribute__((used)) = &sym
36
37 #define DATA_SET(set, sym) __MAKE_SET(set, sym)
38
39 #define SET_DECLARE(set, ptype)\
40 extern ptype * __CONCAT(__start_set_, set); \
41 extern ptype *__CONCAT(__stop_set_, set)
42
43 #define SET_BEGIN(set) \
44 (&__CONCAT(__start_set_, set))
45 #define SET_LIMIT(set) \
46 (&__CONCAT(__stop_set_, set))
47
48 #define SET_FOREACH(pvar, set) \
49 for (pvar = SET_BEGIN(set); pvar < SET_LIMIT(set); pvar++)
50
51 #define nitems(x) (sizeof((x)) / sizeof((x)[0]))
52 #define roundup2(x, y) (((x)+((y)-1))&(~((y)-1)))
53 #define rounddown2(x, y) ((x)&(~((y)-1)))
54
55 static inline uint16_t
be16dec(const void * pp)56 be16dec(const void *pp)
57 {
58 uint8_t const *p = (uint8_t const *)pp;
59
60 return ((p[0] << 8) | p[1]);
61 }
62
63 static inline uint32_t
be32dec(const void * pp)64 be32dec(const void *pp)
65 {
66 uint8_t const *p = (uint8_t const *)pp;
67
68 return (((uint32_t)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
69 }
70
71 static inline void
be16enc(void * pp,uint16_t u)72 be16enc(void *pp, uint16_t u)
73 {
74 uint8_t *p = (uint8_t *)pp;
75
76 p[0] = (u >> 8) & 0xff;
77 p[1] = u & 0xff;
78 }
79
80 static inline void
be32enc(void * pp,uint32_t u)81 be32enc(void *pp, uint32_t u)
82 {
83 uint8_t *p = (uint8_t *)pp;
84
85 p[0] = (u >> 24) & 0xff;
86 p[1] = (u >> 16) & 0xff;
87 p[2] = (u >> 8) & 0xff;
88 p[3] = u & 0xff;
89 }
90 static inline int
flsl(uint64_t mask)91 flsl(uint64_t mask)
92 {
93 return mask ? 64 - __builtin_clzl(mask) : 0;
94 }
95
96 static inline int
fls(uint32_t mask)97 fls(uint32_t mask)
98 {
99 return mask ? 32 - __builtin_clz(mask) : 0;
100 }
101
102 /* Returns the number of 1-bits in bits. */
103 static inline int
bitmap_weight(uint64_t bits)104 bitmap_weight(uint64_t bits)
105 {
106 return __builtin_popcountl(bits);
107
108 }
109
110 #define build_bitmap_clear(name, op_len, op_type, lock) \
111 static inline void name(uint16_t nr_arg, volatile op_type *addr) \
112 { \
113 uint16_t nr; \
114 nr = nr_arg & ((8U * sizeof(op_type)) - 1U); \
115 asm volatile(lock "and" op_len " %1,%0" \
116 : "+m" (*addr) \
117 : "r" ((op_type)(~(1UL<<(nr)))) \
118 : "cc", "memory"); \
119 }
120 build_bitmap_clear(bitmap_clear_nolock, "q", uint64_t, "")
121
122 /*
123 * ffs64 - Find the first (least significant) bit set of value
124 * and return the index of that bit.
125 *
126 * @return value: zero-based bit index, or if value is zero, returns INVALID_BIT_INDEX
127 */
128 #define INVALID_BIT_INDEX 0xffffU
ffs64(uint64_t value)129 static inline uint16_t ffs64(uint64_t value)
130 {
131 /*
132 * __builtin_ffsl: returns one plus the index of the least significant 1-bit of value,
133 * or if value is zero, returns zero.
134 */
135 return value ? (uint16_t)__builtin_ffsl(value) - 1U: INVALID_BIT_INDEX;
136 }
137
138 /* memory barrier */
139 #define mb() ({ asm volatile("mfence" ::: "memory"); (void)0; })
140
141 static inline void
do_cpuid(uint32_t leaf,uint32_t subleaf,uint32_t * eax,uint32_t * ebx,uint32_t * ecx,uint32_t * edx)142 do_cpuid(uint32_t leaf, uint32_t subleaf, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
143 {
144 __asm __volatile("cpuid"
145 : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
146 : "a" (leaf), "c" (subleaf)
147 : "memory");
148 }
149
150 /*
151 * @brief Get the order value of given count.
152 *
153 * @param num 32-bits value.
154 *
155 * @return the order value of data on success and -1 on fail.
156 *
157 */
get_num_order(uint32_t num)158 static inline int get_num_order(uint32_t num)
159 {
160 return ((num > 0) ? fls(num - 1) : -1);
161 }
162
163 #define UGETW(w) \
164 ((w)[0] | \
165 (((uint16_t)((w)[1])) << 8))
166
167 #define UGETDW(w) \
168 ((w)[0] | \
169 (((uint16_t)((w)[1])) << 8) | \
170 (((uint32_t)((w)[2])) << 16) | \
171 (((uint32_t)((w)[3])) << 24))
172
173 #define UGETQW(w) \
174 ((w)[0] | \
175 (((uint16_t)((w)[1])) << 8) | \
176 (((uint32_t)((w)[2])) << 16) | \
177 (((uint32_t)((w)[3])) << 24) | \
178 (((uint64_t)((w)[4])) << 32) | \
179 (((uint64_t)((w)[5])) << 40) | \
180 (((uint64_t)((w)[6])) << 48) | \
181 (((uint64_t)((w)[7])) << 56))
182
183 #define USETW(w, v) do { \
184 (w)[0] = (uint8_t)(v); \
185 (w)[1] = (uint8_t)((v) >> 8); \
186 } while (0)
187
188 #define USETDW(w, v) do { \
189 (w)[0] = (uint8_t)(v); \
190 (w)[1] = (uint8_t)((v) >> 8); \
191 (w)[2] = (uint8_t)((v) >> 16); \
192 (w)[3] = (uint8_t)((v) >> 24); \
193 } while (0)
194
195 #define USETQW(w, v) do { \
196 (w)[0] = (uint8_t)(v); \
197 (w)[1] = (uint8_t)((v) >> 8); \
198 (w)[2] = (uint8_t)((v) >> 16); \
199 (w)[3] = (uint8_t)((v) >> 24); \
200 (w)[4] = (uint8_t)((v) >> 32); \
201 (w)[5] = (uint8_t)((v) >> 40); \
202 (w)[6] = (uint8_t)((v) >> 48); \
203 (w)[7] = (uint8_t)((v) >> 56); \
204 } while (0)
205
206 #define __packed __attribute__((packed))
207
208 #endif
209