Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / drivers / infiniband / mlx_bitops.h
1 #ifndef _MLX_BITOPS_H
2 #define _MLX_BITOPS_H
3
4 /*
5  * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of the
10  * License, or any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  * 02110-1301, USA.
21  */
22
23 FILE_LICENCE ( GPL2_OR_LATER );
24
25 /**
26  * @file
27  *
28  * Mellanox bit operations
29  *
30  */
31
32 /* Datatype used to represent a bit in the Mellanox autogenerated headers */
33 typedef unsigned char pseudo_bit_t;
34
35 /**
36  * Wrapper structure for pseudo_bit_t structures
37  *
38  * This structure provides a wrapper around the autogenerated
39  * pseudo_bit_t structures.  It has the correct size, and also
40  * encapsulates type information about the underlying pseudo_bit_t
41  * structure, which allows the MLX_FILL etc. macros to work without
42  * requiring explicit type information.
43  */
44 #define MLX_DECLARE_STRUCT( _structure )                                     \
45         _structure {                                                         \
46             union {                                                          \
47                 uint8_t bytes[ sizeof ( struct _structure ## _st ) / 8 ];    \
48                 uint32_t dwords[ sizeof ( struct _structure ## _st ) / 32 ]; \
49                 struct _structure ## _st *dummy[0];                          \
50             } __attribute__ (( packed )) u;                                  \
51         } __attribute__ (( packed ))
52
53 /** Get pseudo_bit_t structure type from wrapper structure pointer */
54 #define MLX_PSEUDO_STRUCT( _ptr )                                            \
55         typeof ( *((_ptr)->u.dummy[0]) )
56
57 /** Bit offset of a field within a pseudo_bit_t structure */
58 #define MLX_BIT_OFFSET( _structure_st, _field )                              \
59         offsetof ( _structure_st, _field )
60
61 /** Dword offset of a field within a pseudo_bit_t structure */
62 #define MLX_DWORD_OFFSET( _structure_st, _field )                            \
63         ( MLX_BIT_OFFSET ( _structure_st, _field ) / 32 )
64
65 /** Dword bit offset of a field within a pseudo_bit_t structure
66  *
67  * Yes, using mod-32 would work, but would lose the check for the
68  * error of specifying a mismatched field name and dword index.
69  */
70 #define MLX_DWORD_BIT_OFFSET( _structure_st, _index, _field )                \
71         ( MLX_BIT_OFFSET ( _structure_st, _field ) - ( 32 * (_index) ) )
72
73 /** Bit width of a field within a pseudo_bit_t structure */
74 #define MLX_BIT_WIDTH( _structure_st, _field )                               \
75         sizeof ( ( ( _structure_st * ) NULL )->_field )
76
77 /** Bit mask for a field within a pseudo_bit_t structure */
78 #define MLX_BIT_MASK( _structure_st, _field )                                \
79         ( ( ~( ( uint32_t ) 0 ) ) >>                                         \
80           ( 32 - MLX_BIT_WIDTH ( _structure_st, _field ) ) )
81
82 /*
83  * Assemble native-endian dword from named fields and values
84  *
85  */
86
87 #define MLX_ASSEMBLE_1( _structure_st, _index, _field, _value )              \
88         ( (_value) << MLX_DWORD_BIT_OFFSET ( _structure_st, _index, _field ) )
89
90 #define MLX_ASSEMBLE_2( _structure_st, _index, _field, _value, ... )         \
91         ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) |         \
92           MLX_ASSEMBLE_1 ( _structure_st, _index, __VA_ARGS__ ) )
93
94 #define MLX_ASSEMBLE_3( _structure_st, _index, _field, _value, ... )         \
95         ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) |         \
96           MLX_ASSEMBLE_2 ( _structure_st, _index, __VA_ARGS__ ) )
97
98 #define MLX_ASSEMBLE_4( _structure_st, _index, _field, _value, ... )         \
99         ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) |         \
100           MLX_ASSEMBLE_3 ( _structure_st, _index, __VA_ARGS__ ) )
101
102 #define MLX_ASSEMBLE_5( _structure_st, _index, _field, _value, ... )         \
103         ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) |         \
104           MLX_ASSEMBLE_4 ( _structure_st, _index, __VA_ARGS__ ) )
105
106 #define MLX_ASSEMBLE_6( _structure_st, _index, _field, _value, ... )         \
107         ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) |         \
108           MLX_ASSEMBLE_5 ( _structure_st, _index, __VA_ARGS__ ) )
109
110 #define MLX_ASSEMBLE_7( _structure_st, _index, _field, _value, ... )         \
111         ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) |         \
112           MLX_ASSEMBLE_6 ( _structure_st, _index, __VA_ARGS__ ) )
113
114 #define MLX_ASSEMBLE_8( _structure_st, _index, _field, _value, ... )         \
115         ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) |         \
116           MLX_ASSEMBLE_7 ( _structure_st, _index, __VA_ARGS__ ) )
117
118 /*
119  * Build native-endian (positive) dword bitmasks from named fields
120  *
121  */
122
123 #define MLX_MASK_1( _structure_st, _index, _field )                          \
124         ( MLX_BIT_MASK ( _structure_st, _field ) <<                          \
125           MLX_DWORD_BIT_OFFSET ( _structure_st, _index, _field ) )
126
127 #define MLX_MASK_2( _structure_st, _index, _field, ... )                     \
128         ( MLX_MASK_1 ( _structure_st, _index, _field ) |                     \
129           MLX_MASK_1 ( _structure_st, _index, __VA_ARGS__ ) )
130
131 #define MLX_MASK_3( _structure_st, _index, _field, ... )                     \
132         ( MLX_MASK_1 ( _structure_st, _index, _field ) |                     \
133           MLX_MASK_2 ( _structure_st, _index, __VA_ARGS__ ) )
134
135 #define MLX_MASK_4( _structure_st, _index, _field, ... )                     \
136         ( MLX_MASK_1 ( _structure_st, _index, _field ) |                     \
137           MLX_MASK_3 ( _structure_st, _index, __VA_ARGS__ ) )
138
139 #define MLX_MASK_5( _structure_st, _index, _field, ... )                     \
140         ( MLX_MASK_1 ( _structure_st, _index, _field ) |                     \
141           MLX_MASK_4 ( _structure_st, _index, __VA_ARGS__ ) )
142
143 #define MLX_MASK_6( _structure_st, _index, _field, ... )                     \
144         ( MLX_MASK_1 ( _structure_st, _index, _field ) |                     \
145           MLX_MASK_5 ( _structure_st, _index, __VA_ARGS__ ) )
146
147 #define MLX_MASK_7( _structure_st, _index, _field, ... )                     \
148         ( MLX_MASK_1 ( _structure_st, _index, _field ) |                     \
149           MLX_MASK_6 ( _structure_st, _index, __VA_ARGS__ ) )
150
151 #define MLX_MASK_8( _structure_st, _index, _field, ... )                     \
152         ( MLX_MASK_1 ( _structure_st, _index, _field ) |                     \
153           MLX_MASK_7 ( _structure_st, _index, __VA_ARGS__ ) )
154
155 /*
156  * Populate big-endian dwords from named fields and values
157  *
158  */
159
160 #define MLX_FILL( _ptr, _index, _assembled )                                 \
161         do {                                                                 \
162                 uint32_t *__ptr = &(_ptr)->u.dwords[(_index)];               \
163                 uint32_t __assembled = (_assembled);                         \
164                 *__ptr = cpu_to_be32 ( __assembled );                        \
165         } while ( 0 )
166
167 #define MLX_FILL_1( _ptr, _index, ... )                                      \
168         MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_1 ( MLX_PSEUDO_STRUCT ( _ptr ),\
169                                                   _index, __VA_ARGS__ ) )
170
171 #define MLX_FILL_2( _ptr, _index, ... )                                      \
172         MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_2 ( MLX_PSEUDO_STRUCT ( _ptr ),\
173                                                   _index, __VA_ARGS__ ) )
174
175 #define MLX_FILL_3( _ptr, _index, ... )                                      \
176         MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_3 ( MLX_PSEUDO_STRUCT ( _ptr ),\
177                                                   _index, __VA_ARGS__ ) )
178
179 #define MLX_FILL_4( _ptr, _index, ... )                                      \
180         MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_4 ( MLX_PSEUDO_STRUCT ( _ptr ),\
181                                                   _index, __VA_ARGS__ ) )
182
183 #define MLX_FILL_5( _ptr, _index, ... )                                      \
184         MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_5 ( MLX_PSEUDO_STRUCT ( _ptr ),\
185                                                   _index, __VA_ARGS__ ) )
186
187 #define MLX_FILL_6( _ptr, _index, ... )                                      \
188         MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_6 ( MLX_PSEUDO_STRUCT ( _ptr ),\
189                                                   _index, __VA_ARGS__ ) )
190
191 #define MLX_FILL_7( _ptr, _index, ... )                                      \
192         MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_7 ( MLX_PSEUDO_STRUCT ( _ptr ),\
193                                                   _index, __VA_ARGS__ ) )
194
195 #define MLX_FILL_8( _ptr, _index, ... )                                      \
196         MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_8 ( MLX_PSEUDO_STRUCT ( _ptr ),\
197                                                   _index, __VA_ARGS__ ) )
198
199 /*
200  * Modify big-endian dword using named field and value
201  *
202  */
203
204 #define MLX_SET( _ptr, _field, _value )                                      \
205         do {                                                                 \
206                 unsigned int __index =                                       \
207                     MLX_DWORD_OFFSET ( MLX_PSEUDO_STRUCT ( _ptr ), _field ); \
208                 uint32_t *__ptr = &(_ptr)->u.dwords[__index];                \
209                 uint32_t __value = be32_to_cpu ( *__ptr );                   \
210                 __value &= ~( MLX_MASK_1 ( MLX_PSEUDO_STRUCT ( _ptr ),       \
211                                            __index, _field ) );              \
212                 __value |= MLX_ASSEMBLE_1 ( MLX_PSEUDO_STRUCT ( _ptr ),      \
213                                             __index, _field, _value );       \
214                 *__ptr = cpu_to_be32 ( __value );                            \
215         } while ( 0 )
216
217 /*
218  * Extract value of named field
219  *
220  */
221
222 #define MLX_GET( _ptr, _field )                                              \
223         ( {                                                                  \
224                 unsigned int __index =                                       \
225                     MLX_DWORD_OFFSET ( MLX_PSEUDO_STRUCT ( _ptr ), _field ); \
226                 uint32_t *__ptr = &(_ptr)->u.dwords[__index];                \
227                 uint32_t __value = be32_to_cpu ( *__ptr );                   \
228                 __value >>=                                                  \
229                     MLX_DWORD_BIT_OFFSET ( MLX_PSEUDO_STRUCT ( _ptr ),       \
230                                             __index, _field );               \
231                 __value &=                                                   \
232                     MLX_BIT_MASK ( MLX_PSEUDO_STRUCT ( _ptr ), _field );     \
233                 __value;                                                     \
234         } )
235
236 /*
237  * Fill high dword of physical address, if necessary
238  *
239  */
240 #define MLX_FILL_H( _structure_st, _index, _field, _address ) do {           \
241         if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) ) {                 \
242                 MLX_FILL_1 ( _structure_st, _index, _field,                  \
243                              ( ( ( uint64_t ) (_address) ) >> 32 ) );        \
244         } } while ( 0 )
245
246 #endif /* _MLX_BITOPS_H */