00001 #ifndef _GPXE_BITOPS_H
00002 #define _GPXE_BITOPS_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 FILE_LICENCE ( GPL2_OR_LATER );
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <stdint.h>
00032 #include <byteswap.h>
00033
00034
00035
00036
00037
00038 #ifdef BITOPS_LITTLE_ENDIAN
00039 #define cpu_to_BIT64 cpu_to_le64
00040 #define cpu_to_BIT32 cpu_to_le32
00041 #define BIT64_to_cpu le64_to_cpu
00042 #define BIT32_to_cpu le32_to_cpu
00043 #endif
00044 #ifdef BITOPS_BIG_ENDIAN
00045 #define cpu_to_BIT64 cpu_to_be64
00046 #define cpu_to_BIT32 cpu_to_be32
00047 #define BIT64_to_cpu be64_to_cpu
00048 #define BIT32_to_cpu be32_to_cpu
00049 #endif
00050
00051
00052 typedef unsigned char pseudo_bit_t;
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 #define PSEUDO_BIT_STRUCT( _structure ) \
00064 union { \
00065 uint8_t bytes[ sizeof ( _structure ) / 8 ]; \
00066 uint32_t dwords[ sizeof ( _structure ) / 32 ]; \
00067 uint64_t qwords[ sizeof ( _structure ) / 64 ]; \
00068 _structure *dummy[0]; \
00069 } u
00070
00071
00072 #define PSEUDO_BIT_STRUCT_TYPE( _ptr ) \
00073 typeof ( *((_ptr)->u.dummy[0]) )
00074
00075
00076 #define BIT_OFFSET( _ptr, _field ) \
00077 offsetof ( PSEUDO_BIT_STRUCT_TYPE ( _ptr ), _field )
00078
00079
00080 #define BIT_WIDTH( _ptr, _field ) \
00081 sizeof ( ( ( PSEUDO_BIT_STRUCT_TYPE ( _ptr ) * ) NULL )->_field )
00082
00083
00084 #define QWORD_OFFSET( _ptr, _field ) \
00085 ( BIT_OFFSET ( _ptr, _field ) / 64 )
00086
00087
00088 #define QWORD_BIT_OFFSET( _ptr, _index, _field ) \
00089 ( BIT_OFFSET ( _ptr, _field ) - ( 64 * (_index) ) )
00090
00091
00092 #define BIT_MASK( _ptr, _field ) \
00093 ( ( ~( ( uint64_t ) 0 ) ) >> \
00094 ( 64 - BIT_WIDTH ( _ptr, _field ) ) )
00095
00096
00097
00098
00099
00100
00101 #define BIT_ASSEMBLE_1( _ptr, _index, _field, _value ) \
00102 ( ( ( uint64_t) (_value) ) << \
00103 QWORD_BIT_OFFSET ( _ptr, _index, _field ) )
00104
00105 #define BIT_ASSEMBLE_2( _ptr, _index, _field, _value, ... ) \
00106 ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) | \
00107 BIT_ASSEMBLE_1 ( _ptr, _index, __VA_ARGS__ ) )
00108
00109 #define BIT_ASSEMBLE_3( _ptr, _index, _field, _value, ... ) \
00110 ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) | \
00111 BIT_ASSEMBLE_2 ( _ptr, _index, __VA_ARGS__ ) )
00112
00113 #define BIT_ASSEMBLE_4( _ptr, _index, _field, _value, ... ) \
00114 ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) | \
00115 BIT_ASSEMBLE_3 ( _ptr, _index, __VA_ARGS__ ) )
00116
00117 #define BIT_ASSEMBLE_5( _ptr, _index, _field, _value, ... ) \
00118 ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) | \
00119 BIT_ASSEMBLE_4 ( _ptr, _index, __VA_ARGS__ ) )
00120
00121 #define BIT_ASSEMBLE_6( _ptr, _index, _field, _value, ... ) \
00122 ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) | \
00123 BIT_ASSEMBLE_5 ( _ptr, _index, __VA_ARGS__ ) )
00124
00125 #define BIT_ASSEMBLE_7( _ptr, _index, _field, _value, ... ) \
00126 ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) | \
00127 BIT_ASSEMBLE_6 ( _ptr, _index, __VA_ARGS__ ) )
00128
00129
00130
00131
00132
00133
00134 #define BIT_MASK_1( _ptr, _index, _field ) \
00135 ( BIT_MASK ( _ptr, _field ) << \
00136 QWORD_BIT_OFFSET ( _ptr, _index, _field ) )
00137
00138 #define BIT_MASK_2( _ptr, _index, _field, ... ) \
00139 ( BIT_MASK_1 ( _ptr, _index, _field ) | \
00140 BIT_MASK_1 ( _ptr, _index, __VA_ARGS__ ) )
00141
00142 #define BIT_MASK_3( _ptr, _index, _field, ... ) \
00143 ( BIT_MASK_1 ( _ptr, _index, _field ) | \
00144 BIT_MASK_2 ( _ptr, _index, __VA_ARGS__ ) )
00145
00146 #define BIT_MASK_4( _ptr, _index, _field, ... ) \
00147 ( BIT_MASK_1 ( _ptr, _index, _field ) | \
00148 BIT_MASK_3 ( _ptr, _index, __VA_ARGS__ ) )
00149
00150 #define BIT_MASK_5( _ptr, _index, _field, ... ) \
00151 ( BIT_MASK_1 ( _ptr, _index, _field ) | \
00152 BIT_MASK_4 ( _ptr, _index, __VA_ARGS__ ) )
00153
00154 #define BIT_MASK_6( _ptr, _index, _field, ... ) \
00155 ( BIT_MASK_1 ( _ptr, _index, _field ) | \
00156 BIT_MASK_5 ( _ptr, _index, __VA_ARGS__ ) )
00157
00158 #define BIT_MASK_7( _ptr, _index, _field, ... ) \
00159 ( BIT_MASK_1 ( _ptr, _index, _field ) | \
00160 BIT_MASK_6 ( _ptr, _index, __VA_ARGS__ ) )
00161
00162
00163
00164
00165
00166
00167 #define BIT_FILL( _ptr, _index, _assembled ) do { \
00168 uint64_t *__ptr = &(_ptr)->u.qwords[(_index)]; \
00169 uint64_t __assembled = (_assembled); \
00170 *__ptr = cpu_to_BIT64 ( __assembled ); \
00171 } while ( 0 )
00172
00173 #define BIT_FILL_1( _ptr, _field1, ... ) \
00174 BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ), \
00175 BIT_ASSEMBLE_1 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ), \
00176 _field1, __VA_ARGS__ ) )
00177
00178 #define BIT_FILL_2( _ptr, _field1, ... ) \
00179 BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ), \
00180 BIT_ASSEMBLE_2 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ), \
00181 _field1, __VA_ARGS__ ) )
00182
00183 #define BIT_FILL_3( _ptr, _field1, ... ) \
00184 BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ), \
00185 BIT_ASSEMBLE_3 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ), \
00186 _field1, __VA_ARGS__ ) )
00187
00188 #define BIT_FILL_4( _ptr, _field1, ... ) \
00189 BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ), \
00190 BIT_ASSEMBLE_4 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ), \
00191 _field1, __VA_ARGS__ ) )
00192
00193 #define BIT_FILL_5( _ptr, _field1, ... ) \
00194 BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ), \
00195 BIT_ASSEMBLE_5 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ), \
00196 _field1, __VA_ARGS__ ) )
00197
00198 #define BIT_FILL_6( _ptr, _field1, ... ) \
00199 BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ), \
00200 BIT_ASSEMBLE_6 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ), \
00201 _field1, __VA_ARGS__ ) )
00202
00203
00204 #define BIT_GET64( _ptr, _field ) \
00205 ( { \
00206 unsigned int __index = QWORD_OFFSET ( _ptr, _field ); \
00207 uint64_t *__ptr = &(_ptr)->u.qwords[__index]; \
00208 uint64_t __value = BIT64_to_cpu ( *__ptr ); \
00209 __value >>= \
00210 QWORD_BIT_OFFSET ( _ptr, __index, _field ); \
00211 __value &= BIT_MASK ( _ptr, _field ); \
00212 __value; \
00213 } )
00214
00215
00216 #define BIT_GET( _ptr, _field ) \
00217 ( ( unsigned long ) BIT_GET64 ( _ptr, _field ) )
00218
00219 #define BIT_SET( _ptr, _field, _value ) do { \
00220 unsigned int __index = QWORD_OFFSET ( _ptr, _field ); \
00221 uint64_t *__ptr = &(_ptr)->u.qwords[__index]; \
00222 unsigned int __shift = \
00223 QWORD_BIT_OFFSET ( _ptr, __index, _field ); \
00224 uint64_t __value = (_value); \
00225 *__ptr &= cpu_to_BIT64 ( ~( BIT_MASK ( _ptr, _field ) << \
00226 __shift ) ); \
00227 *__ptr |= cpu_to_BIT64 ( __value << __shift ); \
00228 } while ( 0 )
00229
00230 #endif