mlx_bitops.h

Go to the documentation of this file.
00001 #ifndef _MLX_BITOPS_H
00002 #define _MLX_BITOPS_H
00003 
00004 /*
00005  * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License as
00009  * published by the Free Software Foundation; either version 2 of the
00010  * License, or any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00020  */
00021 
00022 FILE_LICENCE ( GPL2_OR_LATER );
00023 
00024 /**
00025  * @file
00026  *
00027  * Mellanox bit operations
00028  *
00029  */
00030 
00031 /* Datatype used to represent a bit in the Mellanox autogenerated headers */
00032 typedef unsigned char pseudo_bit_t;
00033 
00034 /**
00035  * Wrapper structure for pseudo_bit_t structures
00036  *
00037  * This structure provides a wrapper around the autogenerated
00038  * pseudo_bit_t structures.  It has the correct size, and also
00039  * encapsulates type information about the underlying pseudo_bit_t
00040  * structure, which allows the MLX_FILL etc. macros to work without
00041  * requiring explicit type information.
00042  */
00043 #define MLX_DECLARE_STRUCT( _structure )                                     \
00044         _structure {                                                         \
00045             union {                                                          \
00046                 uint8_t bytes[ sizeof ( struct _structure ## _st ) / 8 ];    \
00047                 uint32_t dwords[ sizeof ( struct _structure ## _st ) / 32 ]; \
00048                 struct _structure ## _st *dummy[0];                          \
00049             } u;                                                             \
00050         }
00051 
00052 /** Get pseudo_bit_t structure type from wrapper structure pointer */
00053 #define MLX_PSEUDO_STRUCT( _ptr )                                            \
00054         typeof ( *((_ptr)->u.dummy[0]) )
00055 
00056 /** Bit offset of a field within a pseudo_bit_t structure */
00057 #define MLX_BIT_OFFSET( _structure_st, _field )                              \
00058         offsetof ( _structure_st, _field )
00059 
00060 /** Dword offset of a field within a pseudo_bit_t structure */
00061 #define MLX_DWORD_OFFSET( _structure_st, _field )                            \
00062         ( MLX_BIT_OFFSET ( _structure_st, _field ) / 32 )
00063 
00064 /** Dword bit offset of a field within a pseudo_bit_t structure
00065  *
00066  * Yes, using mod-32 would work, but would lose the check for the
00067  * error of specifying a mismatched field name and dword index.
00068  */
00069 #define MLX_DWORD_BIT_OFFSET( _structure_st, _index, _field )                \
00070         ( MLX_BIT_OFFSET ( _structure_st, _field ) - ( 32 * (_index) ) )
00071 
00072 /** Bit width of a field within a pseudo_bit_t structure */
00073 #define MLX_BIT_WIDTH( _structure_st, _field )                               \
00074         sizeof ( ( ( _structure_st * ) NULL )->_field )
00075 
00076 /** Bit mask for a field within a pseudo_bit_t structure */
00077 #define MLX_BIT_MASK( _structure_st, _field )                                \
00078         ( ( ~( ( uint32_t ) 0 ) ) >>                                         \
00079           ( 32 - MLX_BIT_WIDTH ( _structure_st, _field ) ) )
00080 
00081 /*
00082  * Assemble native-endian dword from named fields and values
00083  *
00084  */
00085 
00086 #define MLX_ASSEMBLE_1( _structure_st, _index, _field, _value )              \
00087         ( (_value) << MLX_DWORD_BIT_OFFSET ( _structure_st, _index, _field ) )
00088 
00089 #define MLX_ASSEMBLE_2( _structure_st, _index, _field, _value, ... )         \
00090         ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) |         \
00091           MLX_ASSEMBLE_1 ( _structure_st, _index, __VA_ARGS__ ) )
00092 
00093 #define MLX_ASSEMBLE_3( _structure_st, _index, _field, _value, ... )         \
00094         ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) |         \
00095           MLX_ASSEMBLE_2 ( _structure_st, _index, __VA_ARGS__ ) )
00096 
00097 #define MLX_ASSEMBLE_4( _structure_st, _index, _field, _value, ... )         \
00098         ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) |         \
00099           MLX_ASSEMBLE_3 ( _structure_st, _index, __VA_ARGS__ ) )
00100 
00101 #define MLX_ASSEMBLE_5( _structure_st, _index, _field, _value, ... )         \
00102         ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) |         \
00103           MLX_ASSEMBLE_4 ( _structure_st, _index, __VA_ARGS__ ) )
00104 
00105 #define MLX_ASSEMBLE_6( _structure_st, _index, _field, _value, ... )         \
00106         ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) |         \
00107           MLX_ASSEMBLE_5 ( _structure_st, _index, __VA_ARGS__ ) )
00108 
00109 #define MLX_ASSEMBLE_7( _structure_st, _index, _field, _value, ... )         \
00110         ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) |         \
00111           MLX_ASSEMBLE_6 ( _structure_st, _index, __VA_ARGS__ ) )
00112 
00113 /*
00114  * Build native-endian (positive) dword bitmasks from named fields
00115  *
00116  */
00117 
00118 #define MLX_MASK_1( _structure_st, _index, _field )                          \
00119         ( MLX_BIT_MASK ( _structure_st, _field ) <<                          \
00120           MLX_DWORD_BIT_OFFSET ( _structure_st, _index, _field ) )
00121 
00122 #define MLX_MASK_2( _structure_st, _index, _field, ... )                     \
00123         ( MLX_MASK_1 ( _structure_st, _index, _field ) |                     \
00124           MLX_MASK_1 ( _structure_st, _index, __VA_ARGS__ ) )
00125 
00126 #define MLX_MASK_3( _structure_st, _index, _field, ... )                     \
00127         ( MLX_MASK_1 ( _structure_st, _index, _field ) |                     \
00128           MLX_MASK_2 ( _structure_st, _index, __VA_ARGS__ ) )
00129 
00130 #define MLX_MASK_4( _structure_st, _index, _field, ... )                     \
00131         ( MLX_MASK_1 ( _structure_st, _index, _field ) |                     \
00132           MLX_MASK_3 ( _structure_st, _index, __VA_ARGS__ ) )
00133 
00134 #define MLX_MASK_5( _structure_st, _index, _field, ... )                     \
00135         ( MLX_MASK_1 ( _structure_st, _index, _field ) |                     \
00136           MLX_MASK_4 ( _structure_st, _index, __VA_ARGS__ ) )
00137 
00138 #define MLX_MASK_6( _structure_st, _index, _field, ... )                     \
00139         ( MLX_MASK_1 ( _structure_st, _index, _field ) |                     \
00140           MLX_MASK_5 ( _structure_st, _index, __VA_ARGS__ ) )
00141 
00142 #define MLX_MASK_7( _structure_st, _index, _field, ... )                     \
00143         ( MLX_MASK_1 ( _structure_st, _index, _field ) |                     \
00144           MLX_MASK_6 ( _structure_st, _index, __VA_ARGS__ ) )
00145 
00146 /*
00147  * Populate big-endian dwords from named fields and values
00148  *
00149  */
00150 
00151 #define MLX_FILL( _ptr, _index, _assembled )                                 \
00152         do {                                                                 \
00153                 uint32_t *__ptr = &(_ptr)->u.dwords[(_index)];               \
00154                 uint32_t __assembled = (_assembled);                         \
00155                 *__ptr = cpu_to_be32 ( __assembled );                        \
00156         } while ( 0 )
00157 
00158 #define MLX_FILL_1( _ptr, _index, ... )                                      \
00159         MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_1 ( MLX_PSEUDO_STRUCT ( _ptr ),\
00160                                                   _index, __VA_ARGS__ ) )
00161 
00162 #define MLX_FILL_2( _ptr, _index, ... )                                      \
00163         MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_2 ( MLX_PSEUDO_STRUCT ( _ptr ),\
00164                                                   _index, __VA_ARGS__ ) )
00165 
00166 #define MLX_FILL_3( _ptr, _index, ... )                                      \
00167         MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_3 ( MLX_PSEUDO_STRUCT ( _ptr ),\
00168                                                   _index, __VA_ARGS__ ) )
00169 
00170 #define MLX_FILL_4( _ptr, _index, ... )                                      \
00171         MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_4 ( MLX_PSEUDO_STRUCT ( _ptr ),\
00172                                                   _index, __VA_ARGS__ ) )
00173 
00174 #define MLX_FILL_5( _ptr, _index, ... )                                      \
00175         MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_5 ( MLX_PSEUDO_STRUCT ( _ptr ),\
00176                                                   _index, __VA_ARGS__ ) )
00177 
00178 #define MLX_FILL_6( _ptr, _index, ... )                                      \
00179         MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_6 ( MLX_PSEUDO_STRUCT ( _ptr ),\
00180                                                   _index, __VA_ARGS__ ) )
00181 
00182 #define MLX_FILL_7( _ptr, _index, ... )                                      \
00183         MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_7 ( MLX_PSEUDO_STRUCT ( _ptr ),\
00184                                                   _index, __VA_ARGS__ ) )
00185 
00186 /*
00187  * Modify big-endian dword using named field and value
00188  *
00189  */
00190 
00191 #define MLX_SET( _ptr, _field, _value )                                      \
00192         do {                                                                 \
00193                 unsigned int __index =                                       \
00194                     MLX_DWORD_OFFSET ( MLX_PSEUDO_STRUCT ( _ptr ), _field ); \
00195                 uint32_t *__ptr = &(_ptr)->u.dwords[__index];                \
00196                 uint32_t __value = be32_to_cpu ( *__ptr );                   \
00197                 __value &= ~( MLX_MASK_1 ( MLX_PSEUDO_STRUCT ( _ptr ),       \
00198                                            __index, _field ) );              \
00199                 __value |= MLX_ASSEMBLE_1 ( MLX_PSEUDO_STRUCT ( _ptr ),      \
00200                                             __index, _field, _value );       \
00201                 *__ptr = cpu_to_be32 ( __value );                            \
00202         } while ( 0 )
00203 
00204 /*
00205  * Extract value of named field
00206  *
00207  */
00208 
00209 #define MLX_GET( _ptr, _field )                                              \
00210         ( {                                                                  \
00211                 unsigned int __index =                                       \
00212                     MLX_DWORD_OFFSET ( MLX_PSEUDO_STRUCT ( _ptr ), _field ); \
00213                 uint32_t *__ptr = &(_ptr)->u.dwords[__index];                \
00214                 uint32_t __value = be32_to_cpu ( *__ptr );                   \
00215                 __value >>=                                                  \
00216                     MLX_DWORD_BIT_OFFSET ( MLX_PSEUDO_STRUCT ( _ptr ),       \
00217                                             __index, _field );               \
00218                 __value &=                                                   \
00219                     MLX_BIT_MASK ( MLX_PSEUDO_STRUCT ( _ptr ), _field );     \
00220                 __value;                                                     \
00221         } )
00222 
00223 #endif /* _MLX_BITOPS_H */

Generated on Tue Apr 6 20:00:53 2010 for gPXE by  doxygen 1.5.7.1