blob: e96134ef59570875d57301a9f2cdc12cf26e17ed [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#ifndef OPENTITAN_SW_DEVICE_LIB_BASE_BITFIELD_H_
#define OPENTITAN_SW_DEVICE_LIB_BASE_BITFIELD_H_
#include <stdint.h>
/**
* Masked field offset for 32-bit bitfields, with optional value.
*
* `index` represents a shift in bits starting from the 0 bit of a given 32-bit
* bitfield. It is used to zero the memory inside this bitfield by applying an
* inverted `mask` at the `index` offset. `value` is then capped by applying
* `mask` and is shifted to the `index` bits of the bitfield.
*
* Example:
* ```
* 32-bit bitfield = 0b11111111'11111111'11111111'11111111
* set_field32( mask = 0b11111111, index = 16, value = 0b01111110 (126) )
* result 32-bit bitfield = 0b11111111'01111110'11111111'11111111
* ```
*/
typedef struct bitfield_field32 {
uint32_t mask; /**< The field mask. */
uint32_t index; /**< The field position within a bitfield. */
uint32_t
value; /**< The field value to be written, if using a `set` function. */
} bitfield_field32_t;
/**
* Gets `field` in `bitfield`.
*
* This function uses the `field` parameter to get a value at the given
* offset (and mask) in `bitfield`. Only `mask` and `index` are used;
* `value` is ignored.
*
* @param bitfield Bitfield to get the field from.
* @param field Field to read out from.
* @return The read value, zero-extended to 32 bits.
*/
inline uint32_t bitfield_get_field32(uint32_t bitfield,
bitfield_field32_t field) {
return (bitfield >> field.index) & field.mask;
}
/**
* Sets `field` in `bitfield`.
*
* This function uses the `field` parameter to set a value
* at a given offset in `bitfield`. The relevant portion of `bitfield`
* is zeroed before the value is set.
*
* @param bitfield Bitfield to set the field in.
* @param field Field within selected register field to be set.
* @return The 32-bit resulting bitfield.
*/
inline uint32_t bitfield_set_field32(uint32_t bitfield,
bitfield_field32_t field) {
bitfield &= ~(field.mask << field.index);
bitfield |= (field.value & field.mask) << field.index;
return bitfield;
}
#endif // OPENTITAN_SW_DEVICE_LIB_BASE_BITFIELD_H_