[PATCH 1/1] riscv: define find_{first, next}_zero_bit in asm/bitops.h

E Shattow lucent at gmail.com
Sat Jul 27 12:35:50 CEST 2024


Is this a problem in Linux upstream? or specific to U-Boot, and is it
a regression?

refrerence https://lore.kernel.org/u-boot/20240504183354.GL2568172@bill-the-cat/
and reference https://lore.kernel.org/u-boot/BJXPR01MB0855813DD38EF86CCA6DD5C8E6E92@BJXPR01MB0855.CHNPR01.prod.partner.outlook.cn/

On Fri, Jul 26, 2024 at 5:44 AM Maxim Kochetkov <fido_max at inbox.ru> wrote:
>
> These seem to be missing, and trying to build fastboot cmd without
> them is causing errors due to these being missing.
>
> Signed-off-by: Maxim Kochetkov <fido_max at inbox.ru>
> ---
>  arch/riscv/include/asm/bitops.h | 40 +++++++++++++++++++++++++++++++++
>  1 file changed, 40 insertions(+)
>
> diff --git a/arch/riscv/include/asm/bitops.h b/arch/riscv/include/asm/bitops.h
> index 35f1368b83..2f2994c4dd 100644
> --- a/arch/riscv/include/asm/bitops.h
> +++ b/arch/riscv/include/asm/bitops.h
> @@ -138,6 +138,43 @@ static inline unsigned long ffz(unsigned long word)
>         return k;
>  }
>
> +static inline int find_next_zero_bit(void *addr, int size, int offset)
> +{
> +       unsigned long *p = ((unsigned long *)addr) + (offset / BITS_PER_LONG);
> +       unsigned long result = offset & ~(BITS_PER_LONG - 1);
> +       unsigned long tmp;
> +
> +       if (offset >= size)
> +               return size;
> +       size -= result;
> +       offset &= (BITS_PER_LONG - 1);
> +       if (offset) {
> +               tmp = *(p++);
> +               tmp |= ~0UL >> (BITS_PER_LONG - offset);
> +               if (size < BITS_PER_LONG)
> +                       goto found_first;
> +               if (~tmp)
> +                       goto found_middle;
> +               size -= BITS_PER_LONG;
> +               result += BITS_PER_LONG;
> +       }
> +       while (size & ~(BITS_PER_LONG - 1)) {
> +               tmp = *(p++);
> +               if (~tmp)
> +                       goto found_middle;
> +               result += BITS_PER_LONG;
> +               size -= BITS_PER_LONG;
> +       }
> +       if (!size)
> +               return result;
> +       tmp = *p;
> +
> +found_first:
> +       tmp |= ~0UL << size;
> +found_middle:
> +       return result + ffz(tmp);
> +}
> +
>  /*
>   * ffs: find first bit set. This is defined the same way as
>   * the libc and compiler builtin ffs routines, therefore
> @@ -158,6 +195,9 @@ static inline unsigned long ffz(unsigned long word)
>  #define hweight16(x) generic_hweight16(x)
>  #define hweight8(x) generic_hweight8(x)
>
> +#define find_first_zero_bit(addr, size) \
> +       find_next_zero_bit((addr), (size), 0)
> +
>  #define test_and_set_bit               __test_and_set_bit
>  #define test_and_clear_bit             __test_and_clear_bit
>
> --
> 2.45.2
>

-E


More information about the U-Boot mailing list