1 /****************************************************************************
2 * Copyright 2002-2005: Level 5 Networks Inc.
3 * Copyright 2005-2008: Solarflare Communications Inc,
4 * 9501 Jeronimo Road, Suite 250,
5 * Irvine, CA 92618, USA
7 * Maintained by Solarflare Communications
8 * <linux-xen-drivers@solarflare.com>
9 * <onload-dev@solarflare.com>
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 2 as published
13 * by the Free Software Foundation, incorporated herein by reference.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 ****************************************************************************
28 * \brief Handy utility macros.
32 /*! \cidoxg_include_ci_compat */
34 #ifndef __CI_COMPAT_UTILS_H__
35 #define __CI_COMPAT_UTILS_H__
38 /**********************************************************************
39 * Alignment -- [align] must be a power of 2.
40 **********************************************************************/
42 /*! Align forward onto next boundary. */
44 #define CI_ALIGN_FWD(p, align) (((p)+(align)-1u) & ~((align)-1u))
47 /*! Align back onto prev boundary. */
49 #define CI_ALIGN_BACK(p, align) ((p) & ~((align)-1u))
52 /*! How far to next boundary? */
54 #define CI_ALIGN_NEEDED(p, align, signed_t) (-(signed_t)(p) & ((align)-1u))
57 /*! How far beyond prev boundary? */
59 #define CI_OFFSET(p, align) ((p) & ((align)-1u))
62 /*! Does object fit in gap before next boundary? */
64 #define CI_FITS(p, size, align, signed_t) \
65 (CI_ALIGN_NEEDED((p) + 1, (align), signed_t) + 1 >= (size))
68 /*! Align forward onto next boundary. */
70 #define CI_PTR_ALIGN_FWD(p, align) \
71 ((char*) CI_ALIGN_FWD(((ci_ptr_arith_t)(p)), ((ci_ptr_arith_t)(align))))
73 /*! Align back onto prev boundary. */
75 #define CI_PTR_ALIGN_BACK(p, align) \
76 ((char*) CI_ALIGN_BACK(((ci_ptr_arith_t)(p)), ((ci_ptr_arith_t)(align))))
78 /*! How far to next boundary? */
80 #define CI_PTR_ALIGN_NEEDED(p, align) \
81 CI_ALIGN_NEEDED(((ci_ptr_arith_t)(p)), ((ci_ptr_arith_t)(align)), \
84 /*! How far to next boundary? NZ = not zero i.e. give align if on boundary */
86 #define CI_PTR_ALIGN_NEEDED_NZ(p, align) \
87 ((align) - (((char*)p) - \
88 ((char*) CI_ALIGN_BACK(((ci_ptr_arith_t)(p)), ((ci_ptr_arith_t)(align))))))
90 /*! How far beyond prev boundary? */
92 #define CI_PTR_OFFSET(p, align) \
93 CI_OFFSET(((ci_ptr_arith_t)(p)), ((ci_ptr_arith_t)(align)))
96 /* Same as CI_ALIGN_FWD and CI_ALIGN_BACK. */
98 #define CI_ROUND_UP(i, align) (((i)+(align)-1u) & ~((align)-1u))
100 #define CI_ROUND_DOWN(i, align) ((i) & ~((align)-1u))
103 /**********************************************************************
105 **********************************************************************/
107 /* These are not flags. They are enumeration values for use with
108 * CI_MY_BYTE_ORDER. */
109 #define CI_BIG_ENDIAN 1
110 #define CI_LITTLE_ENDIAN 0
113 ** Note that these byte-swapping primitives may leave junk in bits above
114 ** the range they operate on.
116 ** The CI_BSWAP_nn() routines require that bits above [nn] are zero. Use
117 ** CI_BSWAPM_nn(x) if this cannot be guaranteed.
120 /* ?? May be able to improve on some of these with inline assembler on some
124 #define CI_BSWAP_16(v) ((((v) & 0xff) << 8) | ((v) >> 8))
125 #define CI_BSWAPM_16(v) ((((v) & 0xff) << 8) | (((v) & 0xff00) >> 8))
127 #define CI_BSWAP_32(v) (((v) >> 24) | \
128 (((v) & 0x00ff0000) >> 8) | \
129 (((v) & 0x0000ff00) << 8) | \
131 #define CI_BSWAPM_32(v) ((((v) & 0xff000000) >> 24) | \
132 (((v) & 0x00ff0000) >> 8) | \
133 (((v) & 0x0000ff00) << 8) | \
136 #define CI_BSWAP_64(v) (((v) >> 56) | \
137 (((v) & 0x00ff000000000000) >> 40) | \
138 (((v) & 0x0000ff0000000000) >> 24) | \
139 (((v) & 0x000000ff00000000) >> 8) | \
140 (((v) & 0x00000000ff000000) << 8) | \
141 (((v) & 0x0000000000ff0000) << 24) | \
142 (((v) & 0x000000000000ff00) << 40) | \
145 # define CI_BSWAPPED_16_IF(c,v) ((c) ? CI_BSWAP_16(v) : (v))
146 # define CI_BSWAPPED_32_IF(c,v) ((c) ? CI_BSWAP_32(v) : (v))
147 # define CI_BSWAPPED_64_IF(c,v) ((c) ? CI_BSWAP_64(v) : (v))
148 # define CI_BSWAP_16_IF(c,v) do{ if((c)) (v) = CI_BSWAP_16(v); }while(0)
149 # define CI_BSWAP_32_IF(c,v) do{ if((c)) (v) = CI_BSWAP_32(v); }while(0)
150 # define CI_BSWAP_64_IF(c,v) do{ if((c)) (v) = CI_BSWAP_64(v); }while(0)
152 #if (CI_MY_BYTE_ORDER == CI_LITTLE_ENDIAN)
153 # define CI_BSWAP_LE16(v) (v)
154 # define CI_BSWAP_LE32(v) (v)
155 # define CI_BSWAP_LE64(v) (v)
156 # define CI_BSWAP_BE16(v) CI_BSWAP_16(v)
157 # define CI_BSWAP_BE32(v) CI_BSWAP_32(v)
158 # define CI_BSWAP_BE64(v) CI_BSWAP_64(v)
159 # define CI_BSWAPM_LE16(v) (v)
160 # define CI_BSWAPM_LE32(v) (v)
161 # define CI_BSWAPM_LE64(v) (v)
162 # define CI_BSWAPM_BE16(v) CI_BSWAPM_16(v)
163 # define CI_BSWAPM_BE32(v) CI_BSWAPM_32(v)
164 #elif (CI_MY_BYTE_ORDER == CI_BIG_ENDIAN)
165 # define CI_BSWAP_BE16(v) (v)
166 # define CI_BSWAP_BE32(v) (v)
167 # define CI_BSWAP_BE64(v) (v)
168 # define CI_BSWAP_LE16(v) CI_BSWAP_16(v)
169 # define CI_BSWAP_LE32(v) CI_BSWAP_32(v)
170 # define CI_BSWAP_LE64(v) CI_BSWAP_64(v)
171 # define CI_BSWAPM_BE16(v) (v)
172 # define CI_BSWAPM_BE32(v) (v)
173 # define CI_BSWAPM_BE64(v) (v)
174 # define CI_BSWAPM_LE16(v) CI_BSWAPM_16(v)
175 # define CI_BSWAPM_LE32(v) CI_BSWAPM_32(v)
181 /**********************************************************************
182 * Get pointer to struct from pointer to member
183 **********************************************************************/
185 #define CI_MEMBER_OFFSET(c_type, mbr_name) \
186 ((ci_uint32) (ci_uintptr_t)(&((c_type*)0)->mbr_name))
188 #define CI_MEMBER_SIZE(c_type, mbr_name) \
189 sizeof(((c_type*)0)->mbr_name)
191 #define __CI_CONTAINER(c_type, mbr_name, p_mbr) \
192 ( (c_type*) ((char*)(p_mbr) - CI_MEMBER_OFFSET(c_type, mbr_name)) )
195 # define CI_CONTAINER(t,m,p) __CI_CONTAINER(t,m,p)
199 /**********************************************************************
200 * Structure member initialiser.
201 **********************************************************************/
203 #ifndef CI_STRUCT_MBR
204 # define CI_STRUCT_MBR(name, val) .name = val
208 /**********************************************************************
210 **********************************************************************/
212 #define CI_MIN(x,y) (((x) < (y)) ? (x) : (y))
213 #define CI_MAX(x,y) (((x) > (y)) ? (x) : (y))
215 /**********************************************************************
217 **********************************************************************/
219 #define CI_ABS(x) (((x) < 0) ? -(x) : (x))
221 /**********************************************************************
222 * Conditional debugging
223 **********************************************************************/
227 # define CI_NDEBUG(x) x
228 # define CI_IF_DEBUG(y,n) (n)
229 # define CI_DEBUG_ARG(x)
231 # define CI_DEBUG(x) x
232 # define CI_NDEBUG(x)
233 # define CI_IF_DEBUG(y,n) (y)
234 # define CI_DEBUG_ARG(x) ,x
238 #define CI_KERNEL_ARG(x) ,x
240 #define CI_KERNEL_ARG(x)
244 # define CI_KERNEL_ARG_WIN(x) CI_KERNEL_ARG(x)
245 # define CI_ARG_WIN(x) ,x
247 # define CI_KERNEL_ARG_WIN(x)
248 # define CI_ARG_WIN(x)
252 # define CI_KERNEL_ARG_UNIX(x) CI_KERNEL_ARG(x)
253 # define CI_ARG_UNIX(x) ,x
255 # define CI_KERNEL_ARG_UNIX(x)
256 # define CI_ARG_UNIX(x)
260 # define CI_KERNEL_ARG_LINUX(x) CI_KERNEL_ARG(x)
261 # define CI_ARG_LINUX(x) ,x
263 # define CI_KERNEL_ARG_LINUX(x)
264 # define CI_ARG_LINUX(x)
268 #endif /* __CI_COMPAT_UTILS_H__ */