|
|
1.1 ! root 1: #ifndef _MLX_BITOPS_H ! 2: #define _MLX_BITOPS_H ! 3: ! 4: /* ! 5: * Copyright (C) 2007 Michael Brown <[email protected]>. ! 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: ! 22: FILE_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 */ ! 32: typedef 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: } __attribute__ (( packed )) u; \ ! 50: } __attribute__ (( packed )) ! 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: #define MLX_ASSEMBLE_8( _structure_st, _index, _field, _value, ... ) \ ! 114: ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) | \ ! 115: MLX_ASSEMBLE_7 ( _structure_st, _index, __VA_ARGS__ ) ) ! 116: ! 117: /* ! 118: * Build native-endian (positive) dword bitmasks from named fields ! 119: * ! 120: */ ! 121: ! 122: #define MLX_MASK_1( _structure_st, _index, _field ) \ ! 123: ( MLX_BIT_MASK ( _structure_st, _field ) << \ ! 124: MLX_DWORD_BIT_OFFSET ( _structure_st, _index, _field ) ) ! 125: ! 126: #define MLX_MASK_2( _structure_st, _index, _field, ... ) \ ! 127: ( MLX_MASK_1 ( _structure_st, _index, _field ) | \ ! 128: MLX_MASK_1 ( _structure_st, _index, __VA_ARGS__ ) ) ! 129: ! 130: #define MLX_MASK_3( _structure_st, _index, _field, ... ) \ ! 131: ( MLX_MASK_1 ( _structure_st, _index, _field ) | \ ! 132: MLX_MASK_2 ( _structure_st, _index, __VA_ARGS__ ) ) ! 133: ! 134: #define MLX_MASK_4( _structure_st, _index, _field, ... ) \ ! 135: ( MLX_MASK_1 ( _structure_st, _index, _field ) | \ ! 136: MLX_MASK_3 ( _structure_st, _index, __VA_ARGS__ ) ) ! 137: ! 138: #define MLX_MASK_5( _structure_st, _index, _field, ... ) \ ! 139: ( MLX_MASK_1 ( _structure_st, _index, _field ) | \ ! 140: MLX_MASK_4 ( _structure_st, _index, __VA_ARGS__ ) ) ! 141: ! 142: #define MLX_MASK_6( _structure_st, _index, _field, ... ) \ ! 143: ( MLX_MASK_1 ( _structure_st, _index, _field ) | \ ! 144: MLX_MASK_5 ( _structure_st, _index, __VA_ARGS__ ) ) ! 145: ! 146: #define MLX_MASK_7( _structure_st, _index, _field, ... ) \ ! 147: ( MLX_MASK_1 ( _structure_st, _index, _field ) | \ ! 148: MLX_MASK_6 ( _structure_st, _index, __VA_ARGS__ ) ) ! 149: ! 150: #define MLX_MASK_8( _structure_st, _index, _field, ... ) \ ! 151: ( MLX_MASK_1 ( _structure_st, _index, _field ) | \ ! 152: MLX_MASK_7 ( _structure_st, _index, __VA_ARGS__ ) ) ! 153: ! 154: /* ! 155: * Populate big-endian dwords from named fields and values ! 156: * ! 157: */ ! 158: ! 159: #define MLX_FILL( _ptr, _index, _assembled ) \ ! 160: do { \ ! 161: uint32_t *__ptr = &(_ptr)->u.dwords[(_index)]; \ ! 162: uint32_t __assembled = (_assembled); \ ! 163: *__ptr = cpu_to_be32 ( __assembled ); \ ! 164: } while ( 0 ) ! 165: ! 166: #define MLX_FILL_1( _ptr, _index, ... ) \ ! 167: MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_1 ( MLX_PSEUDO_STRUCT ( _ptr ),\ ! 168: _index, __VA_ARGS__ ) ) ! 169: ! 170: #define MLX_FILL_2( _ptr, _index, ... ) \ ! 171: MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_2 ( MLX_PSEUDO_STRUCT ( _ptr ),\ ! 172: _index, __VA_ARGS__ ) ) ! 173: ! 174: #define MLX_FILL_3( _ptr, _index, ... ) \ ! 175: MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_3 ( MLX_PSEUDO_STRUCT ( _ptr ),\ ! 176: _index, __VA_ARGS__ ) ) ! 177: ! 178: #define MLX_FILL_4( _ptr, _index, ... ) \ ! 179: MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_4 ( MLX_PSEUDO_STRUCT ( _ptr ),\ ! 180: _index, __VA_ARGS__ ) ) ! 181: ! 182: #define MLX_FILL_5( _ptr, _index, ... ) \ ! 183: MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_5 ( MLX_PSEUDO_STRUCT ( _ptr ),\ ! 184: _index, __VA_ARGS__ ) ) ! 185: ! 186: #define MLX_FILL_6( _ptr, _index, ... ) \ ! 187: MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_6 ( MLX_PSEUDO_STRUCT ( _ptr ),\ ! 188: _index, __VA_ARGS__ ) ) ! 189: ! 190: #define MLX_FILL_7( _ptr, _index, ... ) \ ! 191: MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_7 ( MLX_PSEUDO_STRUCT ( _ptr ),\ ! 192: _index, __VA_ARGS__ ) ) ! 193: ! 194: #define MLX_FILL_8( _ptr, _index, ... ) \ ! 195: MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_8 ( MLX_PSEUDO_STRUCT ( _ptr ),\ ! 196: _index, __VA_ARGS__ ) ) ! 197: ! 198: /* ! 199: * Modify big-endian dword using named field and value ! 200: * ! 201: */ ! 202: ! 203: #define MLX_SET( _ptr, _field, _value ) \ ! 204: do { \ ! 205: unsigned int __index = \ ! 206: MLX_DWORD_OFFSET ( MLX_PSEUDO_STRUCT ( _ptr ), _field ); \ ! 207: uint32_t *__ptr = &(_ptr)->u.dwords[__index]; \ ! 208: uint32_t __value = be32_to_cpu ( *__ptr ); \ ! 209: __value &= ~( MLX_MASK_1 ( MLX_PSEUDO_STRUCT ( _ptr ), \ ! 210: __index, _field ) ); \ ! 211: __value |= MLX_ASSEMBLE_1 ( MLX_PSEUDO_STRUCT ( _ptr ), \ ! 212: __index, _field, _value ); \ ! 213: *__ptr = cpu_to_be32 ( __value ); \ ! 214: } while ( 0 ) ! 215: ! 216: /* ! 217: * Extract value of named field ! 218: * ! 219: */ ! 220: ! 221: #define MLX_GET( _ptr, _field ) \ ! 222: ( { \ ! 223: unsigned int __index = \ ! 224: MLX_DWORD_OFFSET ( MLX_PSEUDO_STRUCT ( _ptr ), _field ); \ ! 225: uint32_t *__ptr = &(_ptr)->u.dwords[__index]; \ ! 226: uint32_t __value = be32_to_cpu ( *__ptr ); \ ! 227: __value >>= \ ! 228: MLX_DWORD_BIT_OFFSET ( MLX_PSEUDO_STRUCT ( _ptr ), \ ! 229: __index, _field ); \ ! 230: __value &= \ ! 231: MLX_BIT_MASK ( MLX_PSEUDO_STRUCT ( _ptr ), _field ); \ ! 232: __value; \ ! 233: } ) ! 234: ! 235: /* ! 236: * Fill high dword of physical address, if necessary ! 237: * ! 238: */ ! 239: #define MLX_FILL_H( _structure_st, _index, _field, _address ) do { \ ! 240: if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) ) { \ ! 241: MLX_FILL_1 ( _structure_st, _index, _field, \ ! 242: ( ( ( uint64_t ) (_address) ) >> 32 ) ); \ ! 243: } } while ( 0 ) ! 244: ! 245: #endif /* _MLX_BITOPS_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.