source: bootcd/isolinux/syslinux-6.03/gpxe/src/drivers/infiniband/mlx_bitops.h

Last change on this file was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 8.1 KB
Line 
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., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22FILE_LICENCE ( GPL2_OR_LATER );
23
24/**
25 * @file
26 *
27 * Mellanox bit operations
28 *
29 */
30
31/* Datatype used to represent a bit in the Mellanox autogenerated headers */
32typedef unsigned char pseudo_bit_t;
33
34/**
35 * Wrapper structure for pseudo_bit_t structures
36 *
37 * This structure provides a wrapper around the autogenerated
38 * pseudo_bit_t structures.  It has the correct size, and also
39 * encapsulates type information about the underlying pseudo_bit_t
40 * structure, which allows the MLX_FILL etc. macros to work without
41 * requiring explicit type information.
42 */
43#define MLX_DECLARE_STRUCT( _structure )                                     \
44        _structure {                                                         \
45            union {                                                          \
46                uint8_t bytes[ sizeof ( struct _structure ## _st ) / 8 ];    \
47                uint32_t dwords[ sizeof ( struct _structure ## _st ) / 32 ]; \
48                struct _structure ## _st *dummy[0];                          \
49            } u;                                                             \
50        }
51
52/** Get pseudo_bit_t structure type from wrapper structure pointer */
53#define MLX_PSEUDO_STRUCT( _ptr )                                            \
54        typeof ( *((_ptr)->u.dummy[0]) )
55
56/** Bit offset of a field within a pseudo_bit_t structure */
57#define MLX_BIT_OFFSET( _structure_st, _field )                              \
58        offsetof ( _structure_st, _field )
59
60/** Dword offset of a field within a pseudo_bit_t structure */
61#define MLX_DWORD_OFFSET( _structure_st, _field )                            \
62        ( MLX_BIT_OFFSET ( _structure_st, _field ) / 32 )
63
64/** Dword bit offset of a field within a pseudo_bit_t structure
65 *
66 * Yes, using mod-32 would work, but would lose the check for the
67 * error of specifying a mismatched field name and dword index.
68 */
69#define MLX_DWORD_BIT_OFFSET( _structure_st, _index, _field )                \
70        ( MLX_BIT_OFFSET ( _structure_st, _field ) - ( 32 * (_index) ) )
71
72/** Bit width of a field within a pseudo_bit_t structure */
73#define MLX_BIT_WIDTH( _structure_st, _field )                               \
74        sizeof ( ( ( _structure_st * ) NULL )->_field )
75
76/** Bit mask for a field within a pseudo_bit_t structure */
77#define MLX_BIT_MASK( _structure_st, _field )                                \
78        ( ( ~( ( uint32_t ) 0 ) ) >>                                         \
79          ( 32 - MLX_BIT_WIDTH ( _structure_st, _field ) ) )
80
81/*
82 * Assemble native-endian dword from named fields and values
83 *
84 */
85
86#define MLX_ASSEMBLE_1( _structure_st, _index, _field, _value )              \
87        ( (_value) << MLX_DWORD_BIT_OFFSET ( _structure_st, _index, _field ) )
88
89#define MLX_ASSEMBLE_2( _structure_st, _index, _field, _value, ... )         \
90        ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) |         \
91          MLX_ASSEMBLE_1 ( _structure_st, _index, __VA_ARGS__ ) )
92
93#define MLX_ASSEMBLE_3( _structure_st, _index, _field, _value, ... )         \
94        ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) |         \
95          MLX_ASSEMBLE_2 ( _structure_st, _index, __VA_ARGS__ ) )
96
97#define MLX_ASSEMBLE_4( _structure_st, _index, _field, _value, ... )         \
98        ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) |         \
99          MLX_ASSEMBLE_3 ( _structure_st, _index, __VA_ARGS__ ) )
100
101#define MLX_ASSEMBLE_5( _structure_st, _index, _field, _value, ... )         \
102        ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) |         \
103          MLX_ASSEMBLE_4 ( _structure_st, _index, __VA_ARGS__ ) )
104
105#define MLX_ASSEMBLE_6( _structure_st, _index, _field, _value, ... )         \
106        ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) |         \
107          MLX_ASSEMBLE_5 ( _structure_st, _index, __VA_ARGS__ ) )
108
109#define MLX_ASSEMBLE_7( _structure_st, _index, _field, _value, ... )         \
110        ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) |         \
111          MLX_ASSEMBLE_6 ( _structure_st, _index, __VA_ARGS__ ) )
112
113/*
114 * Build native-endian (positive) dword bitmasks from named fields
115 *
116 */
117
118#define MLX_MASK_1( _structure_st, _index, _field )                          \
119        ( MLX_BIT_MASK ( _structure_st, _field ) <<                          \
120          MLX_DWORD_BIT_OFFSET ( _structure_st, _index, _field ) )
121
122#define MLX_MASK_2( _structure_st, _index, _field, ... )                     \
123        ( MLX_MASK_1 ( _structure_st, _index, _field ) |                     \
124          MLX_MASK_1 ( _structure_st, _index, __VA_ARGS__ ) )
125
126#define MLX_MASK_3( _structure_st, _index, _field, ... )                     \
127        ( MLX_MASK_1 ( _structure_st, _index, _field ) |                     \
128          MLX_MASK_2 ( _structure_st, _index, __VA_ARGS__ ) )
129
130#define MLX_MASK_4( _structure_st, _index, _field, ... )                     \
131        ( MLX_MASK_1 ( _structure_st, _index, _field ) |                     \
132          MLX_MASK_3 ( _structure_st, _index, __VA_ARGS__ ) )
133
134#define MLX_MASK_5( _structure_st, _index, _field, ... )                     \
135        ( MLX_MASK_1 ( _structure_st, _index, _field ) |                     \
136          MLX_MASK_4 ( _structure_st, _index, __VA_ARGS__ ) )
137
138#define MLX_MASK_6( _structure_st, _index, _field, ... )                     \
139        ( MLX_MASK_1 ( _structure_st, _index, _field ) |                     \
140          MLX_MASK_5 ( _structure_st, _index, __VA_ARGS__ ) )
141
142#define MLX_MASK_7( _structure_st, _index, _field, ... )                     \
143        ( MLX_MASK_1 ( _structure_st, _index, _field ) |                     \
144          MLX_MASK_6 ( _structure_st, _index, __VA_ARGS__ ) )
145
146/*
147 * Populate big-endian dwords from named fields and values
148 *
149 */
150
151#define MLX_FILL( _ptr, _index, _assembled )                                 \
152        do {                                                                 \
153                uint32_t *__ptr = &(_ptr)->u.dwords[(_index)];               \
154                uint32_t __assembled = (_assembled);                         \
155                *__ptr = cpu_to_be32 ( __assembled );                        \
156        } while ( 0 )
157
158#define MLX_FILL_1( _ptr, _index, ... )                                      \
159        MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_1 ( MLX_PSEUDO_STRUCT ( _ptr ),\
160                                                  _index, __VA_ARGS__ ) )
161
162#define MLX_FILL_2( _ptr, _index, ... )                                      \
163        MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_2 ( MLX_PSEUDO_STRUCT ( _ptr ),\
164                                                  _index, __VA_ARGS__ ) )
165
166#define MLX_FILL_3( _ptr, _index, ... )                                      \
167        MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_3 ( MLX_PSEUDO_STRUCT ( _ptr ),\
168                                                  _index, __VA_ARGS__ ) )
169
170#define MLX_FILL_4( _ptr, _index, ... )                                      \
171        MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_4 ( MLX_PSEUDO_STRUCT ( _ptr ),\
172                                                  _index, __VA_ARGS__ ) )
173
174#define MLX_FILL_5( _ptr, _index, ... )                                      \
175        MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_5 ( MLX_PSEUDO_STRUCT ( _ptr ),\
176                                                  _index, __VA_ARGS__ ) )
177
178#define MLX_FILL_6( _ptr, _index, ... )                                      \
179        MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_6 ( MLX_PSEUDO_STRUCT ( _ptr ),\
180                                                  _index, __VA_ARGS__ ) )
181
182#define MLX_FILL_7( _ptr, _index, ... )                                      \
183        MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_7 ( MLX_PSEUDO_STRUCT ( _ptr ),\
184                                                  _index, __VA_ARGS__ ) )
185
186/*
187 * Modify big-endian dword using named field and value
188 *
189 */
190
191#define MLX_SET( _ptr, _field, _value )                                      \
192        do {                                                                 \
193                unsigned int __index =                                       \
194                    MLX_DWORD_OFFSET ( MLX_PSEUDO_STRUCT ( _ptr ), _field ); \
195                uint32_t *__ptr = &(_ptr)->u.dwords[__index];                \
196                uint32_t __value = be32_to_cpu ( *__ptr );                   \
197                __value &= ~( MLX_MASK_1 ( MLX_PSEUDO_STRUCT ( _ptr ),       \
198                                           __index, _field ) );              \
199                __value |= MLX_ASSEMBLE_1 ( MLX_PSEUDO_STRUCT ( _ptr ),      \
200                                            __index, _field, _value );       \
201                *__ptr = cpu_to_be32 ( __value );                            \
202        } while ( 0 )
203
204/*
205 * Extract value of named field
206 *
207 */
208
209#define MLX_GET( _ptr, _field )                                              \
210        ( {                                                                  \
211                unsigned int __index =                                       \
212                    MLX_DWORD_OFFSET ( MLX_PSEUDO_STRUCT ( _ptr ), _field ); \
213                uint32_t *__ptr = &(_ptr)->u.dwords[__index];                \
214                uint32_t __value = be32_to_cpu ( *__ptr );                   \
215                __value >>=                                                  \
216                    MLX_DWORD_BIT_OFFSET ( MLX_PSEUDO_STRUCT ( _ptr ),       \
217                                            __index, _field );               \
218                __value &=                                                   \
219                    MLX_BIT_MASK ( MLX_PSEUDO_STRUCT ( _ptr ), _field );     \
220                __value;                                                     \
221        } )
222
223#endif /* _MLX_BITOPS_H */
Note: See TracBrowser for help on using the repository browser.