| Jakub Kicinski | 3e9b311 | 2016-08-31 12:46:44 +0100 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2014 Felix Fietkau <nbd@nbd.name> | 
|  | 3 | * Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> | 
|  | 4 | * | 
|  | 5 | * This program is free software; you can redistribute it and/or modify | 
|  | 6 | * it under the terms of the GNU General Public License version 2 | 
|  | 7 | * as published by the Free Software Foundation | 
|  | 8 | * | 
|  | 9 | * This program is distributed in the hope that it will be useful, | 
|  | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | 12 | * GNU General Public License for more details. | 
|  | 13 | */ | 
|  | 14 |  | 
|  | 15 | #ifndef _LINUX_BITFIELD_H | 
|  | 16 | #define _LINUX_BITFIELD_H | 
|  | 17 |  | 
|  | 18 | #include <linux/bug.h> | 
|  | 19 |  | 
|  | 20 | /* | 
|  | 21 | * Bitfield access macros | 
|  | 22 | * | 
|  | 23 | * FIELD_{GET,PREP} macros take as first parameter shifted mask | 
|  | 24 | * from which they extract the base mask and shift amount. | 
|  | 25 | * Mask must be a compilation time constant. | 
|  | 26 | * | 
|  | 27 | * Example: | 
|  | 28 | * | 
|  | 29 | *  #define REG_FIELD_A  GENMASK(6, 0) | 
|  | 30 | *  #define REG_FIELD_B  BIT(7) | 
|  | 31 | *  #define REG_FIELD_C  GENMASK(15, 8) | 
|  | 32 | *  #define REG_FIELD_D  GENMASK(31, 16) | 
|  | 33 | * | 
|  | 34 | * Get: | 
|  | 35 | *  a = FIELD_GET(REG_FIELD_A, reg); | 
|  | 36 | *  b = FIELD_GET(REG_FIELD_B, reg); | 
|  | 37 | * | 
|  | 38 | * Set: | 
|  | 39 | *  reg = FIELD_PREP(REG_FIELD_A, 1) | | 
|  | 40 | *	  FIELD_PREP(REG_FIELD_B, 0) | | 
|  | 41 | *	  FIELD_PREP(REG_FIELD_C, c) | | 
|  | 42 | *	  FIELD_PREP(REG_FIELD_D, 0x40); | 
|  | 43 | * | 
|  | 44 | * Modify: | 
|  | 45 | *  reg &= ~REG_FIELD_C; | 
|  | 46 | *  reg |= FIELD_PREP(REG_FIELD_C, c); | 
|  | 47 | */ | 
|  | 48 |  | 
|  | 49 | #define __bf_shf(x) (__builtin_ffsll(x) - 1) | 
|  | 50 |  | 
|  | 51 | #define __BF_FIELD_CHECK(_mask, _reg, _val, _pfx)			\ | 
|  | 52 | ({								\ | 
|  | 53 | BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask),		\ | 
|  | 54 | _pfx "mask is not constant");		\ | 
|  | 55 | BUILD_BUG_ON_MSG(!(_mask), _pfx "mask is zero");	\ | 
|  | 56 | BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ?		\ | 
|  | 57 | ~((_mask) >> __bf_shf(_mask)) & (_val) : 0, \ | 
|  | 58 | _pfx "value too large for the field"); \ | 
|  | 59 | BUILD_BUG_ON_MSG((_mask) > (typeof(_reg))~0ull,		\ | 
|  | 60 | _pfx "type of reg too small for mask"); \ | 
|  | 61 | __BUILD_BUG_ON_NOT_POWER_OF_2((_mask) +			\ | 
|  | 62 | (1ULL << __bf_shf(_mask))); \ | 
|  | 63 | }) | 
|  | 64 |  | 
|  | 65 | /** | 
| Jakub Kicinski | 1697599 | 2017-02-09 09:17:27 -0800 | [diff] [blame^] | 66 | * FIELD_FIT() - check if value fits in the field | 
|  | 67 | * @_mask: shifted mask defining the field's length and position | 
|  | 68 | * @_val:  value to test against the field | 
|  | 69 | * | 
|  | 70 | * Return: true if @_val can fit inside @_mask, false if @_val is too big. | 
|  | 71 | */ | 
|  | 72 | #define FIELD_FIT(_mask, _val)						\ | 
|  | 73 | ({								\ | 
|  | 74 | __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_FIT: ");	\ | 
|  | 75 | !((((typeof(_mask))_val) << __bf_shf(_mask)) & ~(_mask)); \ | 
|  | 76 | }) | 
|  | 77 |  | 
|  | 78 | /** | 
| Jakub Kicinski | 3e9b311 | 2016-08-31 12:46:44 +0100 | [diff] [blame] | 79 | * FIELD_PREP() - prepare a bitfield element | 
|  | 80 | * @_mask: shifted mask defining the field's length and position | 
|  | 81 | * @_val:  value to put in the field | 
|  | 82 | * | 
|  | 83 | * FIELD_PREP() masks and shifts up the value.  The result should | 
|  | 84 | * be combined with other fields of the bitfield using logical OR. | 
|  | 85 | */ | 
|  | 86 | #define FIELD_PREP(_mask, _val)						\ | 
|  | 87 | ({								\ | 
|  | 88 | __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: ");	\ | 
|  | 89 | ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask);	\ | 
|  | 90 | }) | 
|  | 91 |  | 
|  | 92 | /** | 
|  | 93 | * FIELD_GET() - extract a bitfield element | 
|  | 94 | * @_mask: shifted mask defining the field's length and position | 
|  | 95 | * @_reg:  32bit value of entire bitfield | 
|  | 96 | * | 
|  | 97 | * FIELD_GET() extracts the field specified by @_mask from the | 
|  | 98 | * bitfield passed in as @_reg by masking and shifting it down. | 
|  | 99 | */ | 
|  | 100 | #define FIELD_GET(_mask, _reg)						\ | 
|  | 101 | ({								\ | 
|  | 102 | __BF_FIELD_CHECK(_mask, _reg, 0U, "FIELD_GET: ");	\ | 
|  | 103 | (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask));	\ | 
|  | 104 | }) | 
|  | 105 |  | 
|  | 106 | #endif |