This is an automated email from Gerrit. "Walter J. <walter...@oss.cipunited.com>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8171
-- gerrit commit 83a229f5093beec55db964ee13fe29d27a32a239 Author: Walter Ji <walter...@oss.cipunited.com> Date: Mon Mar 4 17:29:15 2024 +0800 helper: add bitfield helper macros This patch ports FIELD_GET and FIELD_PREP macro and related macro from linux kernel, referenced file: - include/linux/bitfield.h Checkpatch-ignore: MACRO_ARG_REUSE Change-Id: I6fdf4514d3f95d62fadf7654409a4878d470a600 Signed-off-by: Walter Ji <walter...@oss.cipunited.com> diff --git a/src/helper/bitfield.h b/src/helper/bitfield.h new file mode 100644 index 0000000000..3a5d9f497e --- /dev/null +++ b/src/helper/bitfield.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/* + * Copyright (C) 2024 by Shixin 'Walter' Ji + * walter...@cipunited.com + */ + +/* + * The content of this file is copied/inspired from Linux kernel, too. + * Referenced code in include/linux/bitfield.h + */ + +#ifndef OPENOCD_HELPER_BITFIELD_H +#define OPENOCD_HELPER_BITFIELD_H + +/* + * Bitfield access macros + * + * FIELD_{GET,PREP} macros take as first parameter shifted mask + * from which they extract the base mask and shift amount. + * Mask must be a compilation time constant. + * + * Example: + * + * #include <helper/bitfield.h> + * #include <helper/bits.h> + * + * #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); + */ + +/* Returns the index of the least significant 1-bit of x, returns zero when x is 0. */ +#define __bf_shf(x) (__builtin_ffsll(x) - 1) + +/** + * FIELD_PREP() - prepare a bitfield element + * @_mask: shifted mask defining the field's length and position + * @_val: value to put in the field + * + * FIELD_PREP() masks and shifts up the value. The result should + * be combined with other fields of the bitfield using logical OR. + */ +#define FIELD_PREP(_mask, _val) (((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask)) + +/** + * FIELD_GET() - extract a bitfield element + * @_mask: shifted mask defining the field's length and position + * @_reg: value of entire bitfield + * + * FIELD_GET() extracts the field specified by @_mask from the + * bitfield passed in as @_reg by masking and shifting it down. + */ +#define FIELD_GET(_mask, _reg) ((typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask))) + +#endif /* OPENOCD_HELPER_BITFIELD_H */ --