source: grub-pc/trunk/fuentes/debian/grub-extras/disabled/gpxe/src/include/gpxe/bitops.h @ 22

Last change on this file since 22 was 22, checked in by mabarracus, 4 years ago

updated version and apply net.ifnames=0 into debian/rules

File size: 8.1 KB
Line 
1#ifndef _GPXE_BITOPS_H
2#define _GPXE_BITOPS_H
3
4/*
5 * Copyright (C) 2008 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 * Bit operations
28 *
29 */
30
31#include <stdint.h>
32#include <byteswap.h>
33
34/* Endianness selection.
35 *
36 * This is a property of the NIC, not a property of the host CPU.
37 */
38#ifdef BITOPS_LITTLE_ENDIAN
39#define cpu_to_BIT64    cpu_to_le64
40#define cpu_to_BIT32    cpu_to_le32
41#define BIT64_to_cpu    le64_to_cpu
42#define BIT32_to_cpu    le32_to_cpu
43#endif
44#ifdef BITOPS_BIG_ENDIAN
45#define cpu_to_BIT64    cpu_to_be64
46#define cpu_to_BIT32    cpu_to_be32
47#define BIT64_to_cpu    be64_to_cpu
48#define BIT32_to_cpu    be32_to_cpu
49#endif
50
51/** Datatype used to represent a bit in the pseudo-structures */
52typedef unsigned char pseudo_bit_t;
53
54/**
55 * Wrapper structure for pseudo_bit_t structures
56 *
57 * This structure provides a wrapper around pseudo_bit_t structures.
58 * It has the correct size, and also encapsulates type information
59 * about the underlying pseudo_bit_t-based structure, which allows the
60 * BIT_FILL() etc. macros to work without requiring explicit type
61 * information.
62 */
63#define PSEUDO_BIT_STRUCT( _structure )                                       \
64        union {                                                               \
65                uint8_t bytes[ sizeof ( _structure ) / 8 ];                   \
66                uint32_t dwords[ sizeof ( _structure ) / 32 ];                \
67                uint64_t qwords[ sizeof ( _structure ) / 64 ];                \
68                _structure *dummy[0];                                         \
69        } u
70
71/** Get pseudo_bit_t structure type from wrapper structure pointer */
72#define PSEUDO_BIT_STRUCT_TYPE( _ptr )                                        \
73        typeof ( *((_ptr)->u.dummy[0]) )
74
75/** Bit offset of a field within a pseudo_bit_t structure */
76#define BIT_OFFSET( _ptr, _field )                                            \
77        offsetof ( PSEUDO_BIT_STRUCT_TYPE ( _ptr ), _field )
78
79/** Bit width of a field within a pseudo_bit_t structure */
80#define BIT_WIDTH( _ptr, _field )                                             \
81        sizeof ( ( ( PSEUDO_BIT_STRUCT_TYPE ( _ptr ) * ) NULL )->_field )
82
83/** Qword offset of a field within a pseudo_bit_t structure */
84#define QWORD_OFFSET( _ptr, _field )                                          \
85        ( BIT_OFFSET ( _ptr, _field ) / 64 )
86
87/** Qword bit offset of a field within a pseudo_bit_t structure */
88#define QWORD_BIT_OFFSET( _ptr, _index, _field )                              \
89        ( BIT_OFFSET ( _ptr, _field ) - ( 64 * (_index) ) )
90
91/** Bit mask for a field within a pseudo_bit_t structure */
92#define BIT_MASK( _ptr, _field )                                              \
93        ( ( ~( ( uint64_t ) 0 ) ) >>                                          \
94          ( 64 - BIT_WIDTH ( _ptr, _field ) ) )
95
96/*
97 * Assemble native-endian qword from named fields and values
98 *
99 */
100
101#define BIT_ASSEMBLE_1( _ptr, _index, _field, _value )                        \
102        ( ( ( uint64_t) (_value) ) <<                                         \
103          QWORD_BIT_OFFSET ( _ptr, _index, _field ) )
104
105#define BIT_ASSEMBLE_2( _ptr, _index, _field, _value, ... )                   \
106        ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) |                   \
107          BIT_ASSEMBLE_1 ( _ptr, _index, __VA_ARGS__ ) )
108
109#define BIT_ASSEMBLE_3( _ptr, _index, _field, _value, ... )                   \
110        ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) |                   \
111          BIT_ASSEMBLE_2 ( _ptr, _index, __VA_ARGS__ ) )
112
113#define BIT_ASSEMBLE_4( _ptr, _index, _field, _value, ... )                   \
114        ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) |                   \
115          BIT_ASSEMBLE_3 ( _ptr, _index, __VA_ARGS__ ) )
116
117#define BIT_ASSEMBLE_5( _ptr, _index, _field, _value, ... )                   \
118        ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) |                   \
119          BIT_ASSEMBLE_4 ( _ptr, _index, __VA_ARGS__ ) )
120
121#define BIT_ASSEMBLE_6( _ptr, _index, _field, _value, ... )                   \
122        ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) |                   \
123          BIT_ASSEMBLE_5 ( _ptr, _index, __VA_ARGS__ ) )
124
125#define BIT_ASSEMBLE_7( _ptr, _index, _field, _value, ... )                   \
126        ( BIT_ASSEMBLE_1 ( _ptr, _index, _field, _value ) |                   \
127          BIT_ASSEMBLE_6 ( _ptr, _index, __VA_ARGS__ ) )
128
129/*
130 * Build native-endian (positive) qword bitmasks from named fields
131 *
132 */
133
134#define BIT_MASK_1( _ptr, _index, _field )                                    \
135        ( BIT_MASK ( _ptr, _field ) <<                                        \
136          QWORD_BIT_OFFSET ( _ptr, _index, _field ) )
137
138#define BIT_MASK_2( _ptr, _index, _field, ... )                               \
139        ( BIT_MASK_1 ( _ptr, _index, _field ) |                               \
140          BIT_MASK_1 ( _ptr, _index, __VA_ARGS__ ) )
141
142#define BIT_MASK_3( _ptr, _index, _field, ... )                               \
143        ( BIT_MASK_1 ( _ptr, _index, _field ) |                               \
144          BIT_MASK_2 ( _ptr, _index, __VA_ARGS__ ) )
145
146#define BIT_MASK_4( _ptr, _index, _field, ... )                               \
147        ( BIT_MASK_1 ( _ptr, _index, _field ) |                               \
148          BIT_MASK_3 ( _ptr, _index, __VA_ARGS__ ) )
149
150#define BIT_MASK_5( _ptr, _index, _field, ... )                               \
151        ( BIT_MASK_1 ( _ptr, _index, _field ) |                               \
152          BIT_MASK_4 ( _ptr, _index, __VA_ARGS__ ) )
153
154#define BIT_MASK_6( _ptr, _index, _field, ... )                               \
155        ( BIT_MASK_1 ( _ptr, _index, _field ) |                               \
156          BIT_MASK_5 ( _ptr, _index, __VA_ARGS__ ) )
157
158#define BIT_MASK_7( _ptr, _index, _field, ... )                               \
159        ( BIT_MASK_1 ( _ptr, _index, _field ) |                               \
160          BIT_MASK_6 ( _ptr, _index, __VA_ARGS__ ) )
161
162/*
163 * Populate little-endian qwords from named fields and values
164 *
165 */
166
167#define BIT_FILL( _ptr, _index, _assembled ) do {                             \
168                uint64_t *__ptr = &(_ptr)->u.qwords[(_index)];                \
169                uint64_t __assembled = (_assembled);                          \
170                *__ptr = cpu_to_BIT64 ( __assembled );                        \
171        } while ( 0 )
172
173#define BIT_FILL_1( _ptr, _field1, ... )                                      \
174        BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),                      \
175                   BIT_ASSEMBLE_1 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),     \
176                                    _field1, __VA_ARGS__ ) )
177
178#define BIT_FILL_2( _ptr, _field1, ... )                                      \
179        BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),                      \
180                   BIT_ASSEMBLE_2 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),     \
181                                    _field1, __VA_ARGS__ ) )
182
183#define BIT_FILL_3( _ptr, _field1, ... )                                      \
184        BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),                      \
185                   BIT_ASSEMBLE_3 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),     \
186                                    _field1, __VA_ARGS__ ) )
187
188#define BIT_FILL_4( _ptr, _field1, ... )                                      \
189        BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),                      \
190                   BIT_ASSEMBLE_4 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),     \
191                                    _field1, __VA_ARGS__ ) )
192
193#define BIT_FILL_5( _ptr, _field1, ... )                                      \
194        BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),                      \
195                   BIT_ASSEMBLE_5 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),     \
196                                    _field1, __VA_ARGS__ ) )
197
198#define BIT_FILL_6( _ptr, _field1, ... )                                      \
199        BIT_FILL ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),                      \
200                   BIT_ASSEMBLE_6 ( _ptr, QWORD_OFFSET ( _ptr, _field1 ),     \
201                                    _field1, __VA_ARGS__ ) )
202
203/** Extract value of named field */
204#define BIT_GET64( _ptr, _field )                                             \
205        ( {                                                                   \
206                unsigned int __index = QWORD_OFFSET ( _ptr, _field );         \
207                uint64_t *__ptr = &(_ptr)->u.qwords[__index];                 \
208                uint64_t __value = BIT64_to_cpu ( *__ptr );                   \
209                __value >>=                                                   \
210                    QWORD_BIT_OFFSET ( _ptr, __index, _field );               \
211                __value &= BIT_MASK ( _ptr, _field );                         \
212                __value;                                                      \
213        } )
214
215/** Extract value of named field (for fields up to the size of a long) */
216#define BIT_GET( _ptr, _field )                                               \
217        ( ( unsigned long ) BIT_GET64 ( _ptr, _field ) )
218
219#define BIT_SET( _ptr, _field, _value ) do {                                  \
220                unsigned int __index = QWORD_OFFSET ( _ptr, _field );         \
221                uint64_t *__ptr = &(_ptr)->u.qwords[__index];                 \
222                unsigned int __shift =                                        \
223                        QWORD_BIT_OFFSET ( _ptr, __index, _field );           \
224                uint64_t __value = (_value);                                  \
225                *__ptr &= cpu_to_BIT64 ( ~( BIT_MASK ( _ptr, _field ) <<      \
226                                            __shift ) );                      \
227                *__ptr |= cpu_to_BIT64 ( __value << __shift );                \
228        } while ( 0 )
229
230#endif /* _GPXE_BITOPS_H */
Note: See TracBrowser for help on using the repository browser.