sys: util: provide bitfield construction/extraction utility macros
Those are especially useful with hardware device registers. They behave the same way as their Linux equivalent, with a much simpler implementation for now. Example: #define REG_FIELD_A GENMASK(6, 0) #define REG_FIELD_B BIT(7) #define REG_FIELD_C GENMASK(15, 8) #define REG_FIELD_D GENMASK(31, 16) Get: a = FIELD_GET(REG_FIELD_A, reg); b = FIELD_GET(REG_FIELD_B, reg); Set: reg = FIELD_PREP(REG_FIELD_A, 1) | FIELD_PREP(REG_FIELD_B, 0) | FIELD_PREP(REG_FIELD_C, c) | FIELD_PREP(REG_FIELD_D, 0x40); Modify: reg &= ~REG_FIELD_C; reg |= FIELD_PREP(REG_FIELD_C, c); Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
This commit is contained in:
parent
aeee57bfe1
commit
bd73cd5512
1 changed files with 16 additions and 0 deletions
|
@ -58,6 +58,22 @@ extern "C" {
|
|||
#define GENMASK(h, l) \
|
||||
(((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
|
||||
|
||||
/** @brief Extract the Least Significant Bit from @p value. */
|
||||
#define LSB_GET(value) ((value) & -(value))
|
||||
|
||||
/**
|
||||
* @brief Extract a bitfield element from @p value corresponding to
|
||||
* the field mask @p mask.
|
||||
*/
|
||||
#define FIELD_GET(mask, value) (((value) & (mask)) / LSB_GET(mask))
|
||||
|
||||
/**
|
||||
* @brief Prepare a bitfield element using @p value with @p mask representing
|
||||
* its field position and width. The result should be combined
|
||||
* with other fields using a logical OR.
|
||||
*/
|
||||
#define FIELD_PREP(mask, value) (((value) * LSB_GET(mask)) & (mask))
|
||||
|
||||
/** @brief 0 if @p cond is true-ish; causes a compile error otherwise. */
|
||||
#define ZERO_OR_COMPILE_ERROR(cond) ((int) sizeof(char[1 - 2 * !(cond)]) - 1)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue