Blame view
include/bitfield.h
2.51 KB
989ce0499 arch: bcm281xx: I... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
/* * Copyright 2013 Broadcom Corporation. * * SPDX-License-Identifier: GPL-2.0+ */ /* * Bitfield operations * * These are generic bitfield operations which allow manipulation of variable * width bitfields within a word. One use of this would be to use data tables * to determine how to reprogram fields within R/W hardware registers. * * Example: * * old_reg_val * +--------+----+---+--+-----+----------+ * | | | | | old | | * +--------+----+---+--+-----+----------+ * * new_reg_val * +--------+----+---+--+-----+----------+ * | | | | | new | | * +--------+----+---+--+-----+----------+ * * mask = bitfield_mask(10, 5); * old = bitfield_extract(old_reg_val, 10, 5); * new_reg_val = bitfield_replace(old_reg_val, 10, 5, new); * |
8756de282 include/bitfield:... |
30 31 32 33 34 35 |
* or * * mask = bitfield_mask(10, 5); * old = bitfield_extract_by_mask(old_reg_val, mask); * new_reg_val = bitfield_replace_by_mask(old_reg_val, mask, new); * |
989ce0499 arch: bcm281xx: I... |
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
* The numbers 10 and 5 could for example come from data * tables which describe all bitfields in all registers. */ #include <linux/types.h> /* Produces a mask of set bits covering a range of a uint value */ static inline uint bitfield_mask(uint shift, uint width) { return ((1 << width) - 1) << shift; } /* Extract the value of a bitfield found within a given register value */ static inline uint bitfield_extract(uint reg_val, uint shift, uint width) { return (reg_val & bitfield_mask(shift, width)) >> shift; } /* * Replace the value of a bitfield found within a given register value * Returns the newly modified uint value with the replaced field. */ static inline uint bitfield_replace(uint reg_val, uint shift, uint width, uint bitfield_val) { uint mask = bitfield_mask(shift, width); |
c69abd801 include/bitfield.... |
62 |
return (reg_val & ~mask) | ((bitfield_val << shift) & mask); |
989ce0499 arch: bcm281xx: I... |
63 |
} |
8756de282 include/bitfield:... |
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
/* Produces a shift of the bitfield given a mask */ static inline uint bitfield_shift(uint mask) { return mask ? ffs(mask) - 1 : 0; } /* Extract the value of a bitfield found within a given register value */ static inline uint bitfield_extract_by_mask(uint reg_val, uint mask) { uint shift = bitfield_shift(mask); return (reg_val & mask) >> shift; } /* * Replace the value of a bitfield found within a given register value * Returns the newly modified uint value with the replaced field. */ static inline uint bitfield_replace_by_mask(uint reg_val, uint mask, uint bitfield_val) { uint shift = bitfield_shift(mask); return (reg_val & ~mask) | ((bitfield_val << shift) & mask); } |