* [U-Boot-Users] [Patch 2/9] U-boot-V2:ARM: Introduce additional bitops
@ 2008-06-18 12:34 Menon, Nishanth
2008-06-18 15:30 ` Sascha Hauer
0 siblings, 1 reply; 8+ messages in thread
From: Menon, Nishanth @ 2008-06-18 12:34 UTC (permalink / raw)
To: u-boot
Add linux-like bitops definitions - this is based on 2.6.25 rc5 kernel
Signed-off-by: Nishanth Menon <x0nishan@ti.com>
---
arch/arm/lib/Makefile | 1
arch/arm/lib/findbit.S | 181 +++++++++++++++++++++++++++++++++++++++++++++++
include/asm-arm/bitops.h | 86 +++++++++++++++++++++-
3 files changed, 265 insertions(+), 3 deletions(-)
Index: u-boot-v2.git/arch/arm/lib/findbit.S
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ u-boot-v2.git/arch/arm/lib/findbit.S 2008-06-17 17:01:06.000000000 -0500
@@ -0,0 +1,181 @@
+/**
+ * @file
+ * @brief common bitops
+ */
+/*
+ * Originally from Linux kernel
+ * arch/arm/lib/findbit.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 16th March 2001 - John Ripley <jripley@sonicblue.com>
+ * Fixed so that "size" is an exclusive not an inclusive quantity.
+ * All users of these functions expect exclusive sizes, and may
+ * also call with zero size.
+ * Reworked by rmk.
+ */
+ .text
+
+/*
+ * Purpose : Find a 'zero' bit
+ * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);
+ */
+ .globl _find_first_zero_bit_le;
+_find_first_zero_bit_le:
+ teq r1, #0
+ beq 3f
+ mov r2, #0
+1: ldrb r3, [r0, r2, lsr #3]
+ eors r3, r3, #0xff @ invert bits
+ bne .L_found @ any now set - found zero bit
+ add r2, r2, #8 @ next bit pointer
+2: cmp r2, r1 @ any more?
+ blo 1b
+3: mov r0, r1 @ no free bits
+ mov pc, lr
+
+/*
+ * Purpose : Find next 'zero' bit
+ * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit,
+ * int offset)
+ */
+ .globl _find_next_zero_bit_le;
+_find_next_zero_bit_le:
+ teq r1, #0
+ beq 3b
+ ands ip, r2, #7
+ beq 1b @ If new byte, goto old routine
+ ldrb r3, [r0, r2, lsr #3]
+ eor r3, r3, #0xff @ now looking for a 1 bit
+ movs r3, r3, lsr ip @ shift off unused bits
+ bne .L_found
+ orr r2, r2, #7 @ if zero, then no bits here
+ add r2, r2, #1 @ align bit pointer
+ b 2b @ loop for next bit
+
+/*
+ * Purpose : Find a 'one' bit
+ * Prototype: int find_first_bit(const unsigned long *addr, unsigned int maxbit)
+ */
+ .globl _find_first_bit_le;
+_find_first_bit_le:
+ teq r1, #0
+ beq 3f
+ mov r2, #0
+1: ldrb r3, [r0, r2, lsr #3]
+ movs r3, r3
+ bne .L_found @ any now set - found zero bit
+ add r2, r2, #8 @ next bit pointer
+2: cmp r2, r1 @ any more?
+ blo 1b
+3: mov r0, r1 @ no free bits
+ mov pc, lr
+
+/*
+ * Purpose : Find next 'one' bit
+ * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit,
+ * int offset)
+ */
+ .globl _find_next_bit_le;
+_find_next_bit_le:
+ teq r1, #0
+ beq 3b
+ ands ip, r2, #7
+ beq 1b @ If new byte, goto old routine
+ ldrb r3, [r0, r2, lsr #3]
+ movs r3, r3, lsr ip @ shift off unused bits
+ bne .L_found
+ orr r2, r2, #7 @ if zero, then no bits here
+ add r2, r2, #1 @ align bit pointer
+ b 2b @ loop for next bit
+
+#ifdef __ARMEB__
+
+ .globl _find_first_zero_bit_be;
+_find_first_zero_bit_be:
+ teq r1, #0
+ beq 3f
+ mov r2, #0
+1: eor r3, r2, #0x18 @ big endian byte ordering
+ ldrb r3, [r0, r3, lsr #3]
+ eors r3, r3, #0xff @ invert bits
+ bne .L_found @ any now set - found zero bit
+ add r2, r2, #8 @ next bit pointer
+2: cmp r2, r1 @ any more?
+ blo 1b
+3: mov r0, r1 @ no free bits
+ mov pc, lr
+
+ .globl _find_next_zero_bit_be;
+_find_next_zero_bit_be:
+ teq r1, #0
+ beq 3b
+ ands ip, r2, #7
+ beq 1b @ If new byte, goto old routine
+ eor r3, r2, #0x18 @ big endian byte ordering
+ ldrb r3, [r0, r3, lsr #3]
+ eor r3, r3, #0xff @ now looking for a 1 bit
+ movs r3, r3, lsr ip @ shift off unused bits
+ bne .L_found
+ orr r2, r2, #7 @ if zero, then no bits here
+ add r2, r2, #1 @ align bit pointer
+ b 2b @ loop for next bit
+
+ .globl _find_first_bit_be;
+_find_first_bit_be:
+ teq r1, #0
+ beq 3f
+ mov r2, #0
+1: eor r3, r2, #0x18 @ big endian byte ordering
+ ldrb r3, [r0, r3, lsr #3]
+ movs r3, r3
+ bne .L_found @ any now set - found zero bit
+ add r2, r2, #8 @ next bit pointer
+2: cmp r2, r1 @ any more?
+ blo 1b
+3: mov r0, r1 @ no free bits
+ mov pc, lr
+
+ .globl _find_next_bit_be;
+_find_next_bit_be:
+ teq r1, #0
+ beq 3b
+ ands ip, r2, #7
+ beq 1b @ If new byte, goto old routine
+ eor r3, r2, #0x18 @ big endian byte ordering
+ ldrb r3, [r0, r3, lsr #3]
+ movs r3, r3, lsr ip @ shift off unused bits
+ bne .L_found
+ orr r2, r2, #7 @ if zero, then no bits here
+ add r2, r2, #1 @ align bit pointer
+ b 2b @ loop for next bit
+
+#endif
+
+/*
+ * One or more bits in the LSB of r3 are assumed to be set.
+ */
+.L_found:
+#if __LINUX_ARM_ARCH__ >= 5
+ rsb r1, r3, #0
+ and r3, r3, r1
+ clz r3, r3
+ rsb r3, r3, #31
+ add r0, r2, r3
+#else
+ tst r3, #0x0f
+ addeq r2, r2, #4
+ movne r3, r3, lsl #4
+ tst r3, #0x30
+ addeq r2, r2, #2
+ movne r3, r3, lsl #2
+ tst r3, #0x40
+ addeq r2, r2, #1
+ mov r0, r2
+#endif
+ mov pc, lr
+
Index: u-boot-v2.git/arch/arm/lib/Makefile
===================================================================
--- u-boot-v2.git.orig/arch/arm/lib/Makefile 2008-06-17 16:52:31.000000000 -0500
+++ u-boot-v2.git/arch/arm/lib/Makefile 2008-06-17 17:01:06.000000000 -0500
@@ -8,6 +8,7 @@
obj-y += _udivsi3.o
obj-y += _umodsi3.o
obj-y += _lshrdi3.o
+obj-y += findbit.o
obj-y += arm.o
obj-$(CONFIG_MODULES) += module.o
extra-$(CONFIG_GENERIC_LINKER_SCRIPT) += u-boot.lds
Index: u-boot-v2.git/include/asm-arm/bitops.h
===================================================================
--- u-boot-v2.git.orig/include/asm-arm/bitops.h 2008-06-17 16:52:31.000000000 -0500
+++ u-boot-v2.git/include/asm-arm/bitops.h 2008-06-17 17:01:06.000000000 -0500
@@ -75,9 +75,6 @@
return oldval & mask;
}
-extern int find_first_zero_bit(void * addr, unsigned size);
-extern int find_next_zero_bit(void * addr, int size, int offset);
-
/*
* This routine doesn't need to be atomic.
*/
@@ -86,6 +83,44 @@
return ((unsigned char *) addr)[nr >> 3] & (1U << (nr & 7));
}
+
+
+
+#ifndef __ARMEB__
+/*
+ * These are the little endian definitions.
+ */
+extern int _find_first_zero_bit_le(const void *p, unsigned size);
+extern int _find_next_zero_bit_le(const void *p, int size, int offset);
+extern int _find_first_bit_le(const unsigned long *p, unsigned size);
+extern int _find_next_bit_le(const unsigned long *p, int size, int offset);
+#define find_first_zero_bit(p, sz) _find_first_zero_bit_le(p, sz)
+#define find_next_zero_bit(p, sz, off) _find_next_zero_bit_le(p, sz, off)
+#define find_first_bit(p, sz) _find_first_bit_le(p, sz)
+#define find_next_bit(p, sz, off) _find_next_bit_le(p, sz, off)
+
+#define WORD_BITOFF_TO_LE(x) ((x))
+
+#else
+
+/*
+ * These are the big endian definitions.
+ */
+extern int _find_first_zero_bit_be(const void *p, unsigned size);
+extern int _find_next_zero_bit_be(const void *p, int size, int offset);
+extern int _find_first_bit_be(const unsigned long *p, unsigned size);
+extern int _find_next_bit_be(const unsigned long *p, int size, int offset);
+#define find_first_zero_bit(p, sz) _find_first_zero_bit_be(p, sz)
+#define find_next_zero_bit(p, sz, off) _find_next_zero_bit_be(p, sz, off)
+#define find_first_bit(p, sz) _find_first_bit_be(p, sz)
+#define find_next_bit(p, sz, off) _find_next_bit_be(p, sz, off)
+
+#define WORD_BITOFF_TO_LE(x) ((x) ^ 0x18)
+
+#endif
+
+#if (defined(__LINUX_ARM_ARCH__) && (__LINUX_ARM_ARCH__ < 5))
+
/*
* ffz = Find First Zero in word. Undefined if no zero exists,
* so code should check against ~0UL first..
@@ -112,6 +147,51 @@
#define ffs(x) generic_ffs(x)
+#else
+
+static inline int constant_fls(int x)
+{
+ int r = 32;
+
+ if (!x)
+ return 0;
+ if (!(x & 0xffff0000u)) {
+ x <<= 16;
+ r -= 16;
+ }
+ if (!(x & 0xff000000u)) {
+ x <<= 8;
+ r -= 8;
+ }
+ if (!(x & 0xf0000000u)) {
+ x <<= 4;
+ r -= 4;
+ }
+ if (!(x & 0xc0000000u)) {
+ x <<= 2;
+ r -= 2;
+ }
+ if (!(x & 0x80000000u)) {
+ x <<= 1;
+ r -= 1;
+ }
+ return r;
+}
+
+/*
+ * On ARMv5 and above those functions can be implemented around
+ * the clz instruction for much better code efficiency.
+ */
+
+#define fls(x) \
+ (__builtin_constant_p(x) ? constant_fls(x) : \
+ ({ int __r; asm("clz\t%0, %1" : "=r"(__r) : "r"(x) : "cc"); 32-__r; }))
+#define ffs(x) ({ unsigned long __t = (x); fls(__t &-__t); })
+#define __ffs(x) (ffs(x) - 1)
+#define ffz(x) __ffs(~(x))
+
+#endif
+
/*
* hweightN: returns the hamming weight (i.e. the number
* of bits set) of a N-bit word
^ permalink raw reply [flat|nested] 8+ messages in thread
* [U-Boot-Users] [Patch 2/9] U-boot-V2:ARM: Introduce additional bitops
2008-06-18 12:34 [U-Boot-Users] [Patch 2/9] U-boot-V2:ARM: Introduce additional bitops Menon, Nishanth
@ 2008-06-18 15:30 ` Sascha Hauer
2008-06-18 15:41 ` Menon, Nishanth
0 siblings, 1 reply; 8+ messages in thread
From: Sascha Hauer @ 2008-06-18 15:30 UTC (permalink / raw)
To: u-boot
On Wed, Jun 18, 2008 at 07:34:05AM -0500, Menon, Nishanth wrote:
> Add linux-like bitops definitions - this is based on 2.6.25 rc5 kernel
I haven't looked at it, but I guess you need these for the following
patches. It would be better to first introduce generic bitops. Otherwise
we end up with i2c only working on arm.
Sascha
>
> Signed-off-by: Nishanth Menon <x0nishan@ti.com>
>
> ---
> arch/arm/lib/Makefile | 1
> arch/arm/lib/findbit.S | 181 +++++++++++++++++++++++++++++++++++++++++++++++
> include/asm-arm/bitops.h | 86 +++++++++++++++++++++-
> 3 files changed, 265 insertions(+), 3 deletions(-)
>
> Index: u-boot-v2.git/arch/arm/lib/findbit.S
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ u-boot-v2.git/arch/arm/lib/findbit.S 2008-06-17 17:01:06.000000000 -0500
> @@ -0,0 +1,181 @@
> +/**
> + * @file
> + * @brief common bitops
> + */
> +/*
> + * Originally from Linux kernel
> + * arch/arm/lib/findbit.S
> + *
> + * Copyright (C) 1995-2000 Russell King
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 16th March 2001 - John Ripley <jripley@sonicblue.com>
> + * Fixed so that "size" is an exclusive not an inclusive quantity.
> + * All users of these functions expect exclusive sizes, and may
> + * also call with zero size.
> + * Reworked by rmk.
> + */
> + .text
> +
> +/*
> + * Purpose : Find a 'zero' bit
> + * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);
> + */
> + .globl _find_first_zero_bit_le;
> +_find_first_zero_bit_le:
> + teq r1, #0
> + beq 3f
> + mov r2, #0
> +1: ldrb r3, [r0, r2, lsr #3]
> + eors r3, r3, #0xff @ invert bits
> + bne .L_found @ any now set - found zero bit
> + add r2, r2, #8 @ next bit pointer
> +2: cmp r2, r1 @ any more?
> + blo 1b
> +3: mov r0, r1 @ no free bits
> + mov pc, lr
> +
> +/*
> + * Purpose : Find next 'zero' bit
> + * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit,
> + * int offset)
> + */
> + .globl _find_next_zero_bit_le;
> +_find_next_zero_bit_le:
> + teq r1, #0
> + beq 3b
> + ands ip, r2, #7
> + beq 1b @ If new byte, goto old routine
> + ldrb r3, [r0, r2, lsr #3]
> + eor r3, r3, #0xff @ now looking for a 1 bit
> + movs r3, r3, lsr ip @ shift off unused bits
> + bne .L_found
> + orr r2, r2, #7 @ if zero, then no bits here
> + add r2, r2, #1 @ align bit pointer
> + b 2b @ loop for next bit
> +
> +/*
> + * Purpose : Find a 'one' bit
> + * Prototype: int find_first_bit(const unsigned long *addr, unsigned int maxbit)
> + */
> + .globl _find_first_bit_le;
> +_find_first_bit_le:
> + teq r1, #0
> + beq 3f
> + mov r2, #0
> +1: ldrb r3, [r0, r2, lsr #3]
> + movs r3, r3
> + bne .L_found @ any now set - found zero bit
> + add r2, r2, #8 @ next bit pointer
> +2: cmp r2, r1 @ any more?
> + blo 1b
> +3: mov r0, r1 @ no free bits
> + mov pc, lr
> +
> +/*
> + * Purpose : Find next 'one' bit
> + * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit,
> + * int offset)
> + */
> + .globl _find_next_bit_le;
> +_find_next_bit_le:
> + teq r1, #0
> + beq 3b
> + ands ip, r2, #7
> + beq 1b @ If new byte, goto old routine
> + ldrb r3, [r0, r2, lsr #3]
> + movs r3, r3, lsr ip @ shift off unused bits
> + bne .L_found
> + orr r2, r2, #7 @ if zero, then no bits here
> + add r2, r2, #1 @ align bit pointer
> + b 2b @ loop for next bit
> +
> +#ifdef __ARMEB__
> +
> + .globl _find_first_zero_bit_be;
> +_find_first_zero_bit_be:
> + teq r1, #0
> + beq 3f
> + mov r2, #0
> +1: eor r3, r2, #0x18 @ big endian byte ordering
> + ldrb r3, [r0, r3, lsr #3]
> + eors r3, r3, #0xff @ invert bits
> + bne .L_found @ any now set - found zero bit
> + add r2, r2, #8 @ next bit pointer
> +2: cmp r2, r1 @ any more?
> + blo 1b
> +3: mov r0, r1 @ no free bits
> + mov pc, lr
> +
> + .globl _find_next_zero_bit_be;
> +_find_next_zero_bit_be:
> + teq r1, #0
> + beq 3b
> + ands ip, r2, #7
> + beq 1b @ If new byte, goto old routine
> + eor r3, r2, #0x18 @ big endian byte ordering
> + ldrb r3, [r0, r3, lsr #3]
> + eor r3, r3, #0xff @ now looking for a 1 bit
> + movs r3, r3, lsr ip @ shift off unused bits
> + bne .L_found
> + orr r2, r2, #7 @ if zero, then no bits here
> + add r2, r2, #1 @ align bit pointer
> + b 2b @ loop for next bit
> +
> + .globl _find_first_bit_be;
> +_find_first_bit_be:
> + teq r1, #0
> + beq 3f
> + mov r2, #0
> +1: eor r3, r2, #0x18 @ big endian byte ordering
> + ldrb r3, [r0, r3, lsr #3]
> + movs r3, r3
> + bne .L_found @ any now set - found zero bit
> + add r2, r2, #8 @ next bit pointer
> +2: cmp r2, r1 @ any more?
> + blo 1b
> +3: mov r0, r1 @ no free bits
> + mov pc, lr
> +
> + .globl _find_next_bit_be;
> +_find_next_bit_be:
> + teq r1, #0
> + beq 3b
> + ands ip, r2, #7
> + beq 1b @ If new byte, goto old routine
> + eor r3, r2, #0x18 @ big endian byte ordering
> + ldrb r3, [r0, r3, lsr #3]
> + movs r3, r3, lsr ip @ shift off unused bits
> + bne .L_found
> + orr r2, r2, #7 @ if zero, then no bits here
> + add r2, r2, #1 @ align bit pointer
> + b 2b @ loop for next bit
> +
> +#endif
> +
> +/*
> + * One or more bits in the LSB of r3 are assumed to be set.
> + */
> +.L_found:
> +#if __LINUX_ARM_ARCH__ >= 5
> + rsb r1, r3, #0
> + and r3, r3, r1
> + clz r3, r3
> + rsb r3, r3, #31
> + add r0, r2, r3
> +#else
> + tst r3, #0x0f
> + addeq r2, r2, #4
> + movne r3, r3, lsl #4
> + tst r3, #0x30
> + addeq r2, r2, #2
> + movne r3, r3, lsl #2
> + tst r3, #0x40
> + addeq r2, r2, #1
> + mov r0, r2
> +#endif
> + mov pc, lr
> +
> Index: u-boot-v2.git/arch/arm/lib/Makefile
> ===================================================================
> --- u-boot-v2.git.orig/arch/arm/lib/Makefile 2008-06-17 16:52:31.000000000 -0500
> +++ u-boot-v2.git/arch/arm/lib/Makefile 2008-06-17 17:01:06.000000000 -0500
> @@ -8,6 +8,7 @@
> obj-y += _udivsi3.o
> obj-y += _umodsi3.o
> obj-y += _lshrdi3.o
> +obj-y += findbit.o
> obj-y += arm.o
> obj-$(CONFIG_MODULES) += module.o
> extra-$(CONFIG_GENERIC_LINKER_SCRIPT) += u-boot.lds
> Index: u-boot-v2.git/include/asm-arm/bitops.h
> ===================================================================
> --- u-boot-v2.git.orig/include/asm-arm/bitops.h 2008-06-17 16:52:31.000000000 -0500
> +++ u-boot-v2.git/include/asm-arm/bitops.h 2008-06-17 17:01:06.000000000 -0500
> @@ -75,9 +75,6 @@
> return oldval & mask;
> }
>
> -extern int find_first_zero_bit(void * addr, unsigned size);
> -extern int find_next_zero_bit(void * addr, int size, int offset);
> -
> /*
> * This routine doesn't need to be atomic.
> */
> @@ -86,6 +83,44 @@
> return ((unsigned char *) addr)[nr >> 3] & (1U << (nr & 7));
> }
>
> +
> +
> +
> +#ifndef __ARMEB__
> +/*
> + * These are the little endian definitions.
> + */
> +extern int _find_first_zero_bit_le(const void *p, unsigned size);
> +extern int _find_next_zero_bit_le(const void *p, int size, int offset);
> +extern int _find_first_bit_le(const unsigned long *p, unsigned size);
> +extern int _find_next_bit_le(const unsigned long *p, int size, int offset);
> +#define find_first_zero_bit(p, sz) _find_first_zero_bit_le(p, sz)
> +#define find_next_zero_bit(p, sz, off) _find_next_zero_bit_le(p, sz, off)
> +#define find_first_bit(p, sz) _find_first_bit_le(p, sz)
> +#define find_next_bit(p, sz, off) _find_next_bit_le(p, sz, off)
> +
> +#define WORD_BITOFF_TO_LE(x) ((x))
> +
> +#else
> +
> +/*
> + * These are the big endian definitions.
> + */
> +extern int _find_first_zero_bit_be(const void *p, unsigned size);
> +extern int _find_next_zero_bit_be(const void *p, int size, int offset);
> +extern int _find_first_bit_be(const unsigned long *p, unsigned size);
> +extern int _find_next_bit_be(const unsigned long *p, int size, int offset);
> +#define find_first_zero_bit(p, sz) _find_first_zero_bit_be(p, sz)
> +#define find_next_zero_bit(p, sz, off) _find_next_zero_bit_be(p, sz, off)
> +#define find_first_bit(p, sz) _find_first_bit_be(p, sz)
> +#define find_next_bit(p, sz, off) _find_next_bit_be(p, sz, off)
> +
> +#define WORD_BITOFF_TO_LE(x) ((x) ^ 0x18)
> +
> +#endif
> +
> +#if (defined(__LINUX_ARM_ARCH__) && (__LINUX_ARM_ARCH__ < 5))
> +
> /*
> * ffz = Find First Zero in word. Undefined if no zero exists,
> * so code should check against ~0UL first..
> @@ -112,6 +147,51 @@
>
> #define ffs(x) generic_ffs(x)
>
> +#else
> +
> +static inline int constant_fls(int x)
> +{
> + int r = 32;
> +
> + if (!x)
> + return 0;
> + if (!(x & 0xffff0000u)) {
> + x <<= 16;
> + r -= 16;
> + }
> + if (!(x & 0xff000000u)) {
> + x <<= 8;
> + r -= 8;
> + }
> + if (!(x & 0xf0000000u)) {
> + x <<= 4;
> + r -= 4;
> + }
> + if (!(x & 0xc0000000u)) {
> + x <<= 2;
> + r -= 2;
> + }
> + if (!(x & 0x80000000u)) {
> + x <<= 1;
> + r -= 1;
> + }
> + return r;
> +}
> +
> +/*
> + * On ARMv5 and above those functions can be implemented around
> + * the clz instruction for much better code efficiency.
> + */
> +
> +#define fls(x) \
> + (__builtin_constant_p(x) ? constant_fls(x) : \
> + ({ int __r; asm("clz\t%0, %1" : "=r"(__r) : "r"(x) : "cc"); 32-__r; }))
> +#define ffs(x) ({ unsigned long __t = (x); fls(__t &-__t); })
> +#define __ffs(x) (ffs(x) - 1)
> +#define ffz(x) __ffs(~(x))
> +
> +#endif
> +
> /*
> * hweightN: returns the hamming weight (i.e. the number
> * of bits set) of a N-bit word
>
--
Pengutronix e.K. - Linux Solutions for Science and Industry
-----------------------------------------------------------
Kontakt-Informationen finden Sie im Header dieser Mail oder
auf der Webseite -> http://www.pengutronix.de/impressum/ <-
^ permalink raw reply [flat|nested] 8+ messages in thread
* [U-Boot-Users] [Patch 2/9] U-boot-V2:ARM: Introduce additional bitops
2008-06-18 15:30 ` Sascha Hauer
@ 2008-06-18 15:41 ` Menon, Nishanth
2008-06-18 15:50 ` Sascha Hauer
0 siblings, 1 reply; 8+ messages in thread
From: Menon, Nishanth @ 2008-06-18 15:41 UTC (permalink / raw)
To: u-boot
Sascha,
> -----Original Message-----
> From: Sascha Hauer [mailto:s.hauer at pengutronix.de]
> Sent: Wednesday, June 18, 2008 10:31 AM
> To: Menon, Nishanth
> Cc: Kamat, Nishant; u-boot-users at lists.sourceforge.net; Laurent Desnogues; philip.balister at gmail.com;
> dirk.behme at googlemail.com
> Subject: Re: [Patch 2/9] U-boot-V2:ARM: Introduce additional bitops
>
> On Wed, Jun 18, 2008 at 07:34:05AM -0500, Menon, Nishanth wrote:
> > Add linux-like bitops definitions - this is based on 2.6.25 rc5 kernel
>
> I haven't looked at it, but I guess you need these for the following
> patches. It would be better to first introduce generic bitops. Otherwise
> we end up with i2c only working on arm.
Would you have a proposal for it? I am not familiar with ppc and other archs :( I can help on ARM side of things.
Regards,
Nishanth Menon
^ permalink raw reply [flat|nested] 8+ messages in thread
* [U-Boot-Users] [Patch 2/9] U-boot-V2:ARM: Introduce additional bitops
2008-06-18 15:41 ` Menon, Nishanth
@ 2008-06-18 15:50 ` Sascha Hauer
2008-06-19 6:12 ` [U-Boot-Users] [Patch 1/3] U-Boot-V2: Bitops cleanup: introduce asm-generic bitops Menon, Nishanth
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Sascha Hauer @ 2008-06-18 15:50 UTC (permalink / raw)
To: u-boot
On Wed, Jun 18, 2008 at 10:41:44AM -0500, Menon, Nishanth wrote:
> Sascha,
> > -----Original Message-----
> > From: Sascha Hauer [mailto:s.hauer at pengutronix.de]
> > Sent: Wednesday, June 18, 2008 10:31 AM
> > To: Menon, Nishanth
> > Cc: Kamat, Nishant; u-boot-users at lists.sourceforge.net; Laurent Desnogues; philip.balister at gmail.com;
> > dirk.behme at googlemail.com
> > Subject: Re: [Patch 2/9] U-boot-V2:ARM: Introduce additional bitops
> >
> > On Wed, Jun 18, 2008 at 07:34:05AM -0500, Menon, Nishanth wrote:
> > > Add linux-like bitops definitions - this is based on 2.6.25 rc5 kernel
> >
> > I haven't looked at it, but I guess you need these for the following
> > patches. It would be better to first introduce generic bitops. Otherwise
> > we end up with i2c only working on arm.
> Would you have a proposal for it? I am not familiar with ppc and other archs :( I can help on ARM side of things.
In the kernel are generic bitops, #ifdefed with CONFIG_GENERIC_XXX
Regards,
Sascha
--
Pengutronix e.K. - Linux Solutions for Science and Industry
-----------------------------------------------------------
Kontakt-Informationen finden Sie im Header dieser Mail oder
auf der Webseite -> http://www.pengutronix.de/impressum/ <-
^ permalink raw reply [flat|nested] 8+ messages in thread
* [U-Boot-Users] [Patch 1/3] U-Boot-V2: Bitops cleanup: introduce asm-generic bitops
2008-06-18 15:50 ` Sascha Hauer
@ 2008-06-19 6:12 ` Menon, Nishanth
2008-06-19 12:56 ` Jon Loeliger
2008-06-19 6:13 ` [U-Boot-Users] [Patch 2/3] U-Boot-V2: Bitops cleanup: cleanup ARM bitops Menon, Nishanth
2008-06-19 6:13 ` [U-Boot-Users] [Patch 3/3] U-Boot-V2: Bitops cleanup: cleanup rest of generic_xxx functions Menon, Nishanth
2 siblings, 1 reply; 8+ messages in thread
From: Menon, Nishanth @ 2008-06-19 6:12 UTC (permalink / raw)
To: u-boot
Sascha,
The following 3 patches are for cleaning up the bitops
> -----Original Message-----
> From: Sascha Hauer [mailto:s.hauer at pengutronix.de]
> Sent: Wednesday, June 18, 2008 10:51 AM
> To: Menon, Nishanth
> Cc: Kamat, Nishant; u-boot-users at lists.sourceforge.net; Laurent Desnogues; philip.balister at gmail.com;
> dirk.behme at googlemail.com
> Subject: Re: [Patch 2/9] U-boot-V2:ARM: Introduce additional bitops
>
>
> In the kernel are generic bitops, #ifdefed with CONFIG_GENERIC_XXX
This introduces selected generic bitop files from kernel. We don't need minix, ext2, sched or lock based bitops. Those have been dropped.
Signed-off-by: Nishanth Menon <x0nishan@ti.com>
---
include/asm-generic/bitops/__ffs.h | 43 ++++++++++++++++
include/asm-generic/bitops/__fls.h | 43 ++++++++++++++++
include/asm-generic/bitops/ffs.h | 41 +++++++++++++++
include/asm-generic/bitops/ffz.h | 12 ++++
include/asm-generic/bitops/find.h | 15 +++++
include/asm-generic/bitops/fls.h | 41 +++++++++++++++
include/asm-generic/bitops/fls64.h | 36 +++++++++++++
include/asm-generic/bitops/hweight.h | 35 +++++++++++++
include/asm-generic/bitops/ops.h | 91 +++++++++++++++++++++++++++++++++++
9 files changed, 357 insertions(+)
Index: u-boot-v2.git/include/asm-generic/bitops/__ffs.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ u-boot-v2.git/include/asm-generic/bitops/__ffs.h 2008-06-19 01:06:03.000000000 -0500
@@ -0,0 +1,43 @@
+#ifndef _ASM_GENERIC_BITOPS___FFS_H_
+#define _ASM_GENERIC_BITOPS___FFS_H_
+
+#include <asm/types.h>
+
+/**
+ * __ffs - find first bit in word.
+ * @word: The word to search
+ *
+ * Undefined if no bit exists, so code should check against 0 first.
+ */
+static inline unsigned long __ffs(unsigned long word)
+{
+ int num = 0;
+
+#if BITS_PER_LONG == 64
+ if ((word & 0xffffffff) == 0) {
+ num += 32;
+ word >>= 32;
+ }
+#endif
+ if ((word & 0xffff) == 0) {
+ num += 16;
+ word >>= 16;
+ }
+ if ((word & 0xff) == 0) {
+ num += 8;
+ word >>= 8;
+ }
+ if ((word & 0xf) == 0) {
+ num += 4;
+ word >>= 4;
+ }
+ if ((word & 0x3) == 0) {
+ num += 2;
+ word >>= 2;
+ }
+ if ((word & 0x1) == 0)
+ num += 1;
+ return num;
+}
+
+#endif /* _ASM_GENERIC_BITOPS___FFS_H_ */
Index: u-boot-v2.git/include/asm-generic/bitops/__fls.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ u-boot-v2.git/include/asm-generic/bitops/__fls.h 2008-06-19 01:06:03.000000000 -0500
@@ -0,0 +1,43 @@
+#ifndef _ASM_GENERIC_BITOPS___FLS_H_
+#define _ASM_GENERIC_BITOPS___FLS_H_
+
+#include <asm/types.h>
+
+/**
+ * __fls - find last (most-significant) set bit in a long word
+ * @word: the word to search
+ *
+ * Undefined if no set bit exists, so code should check against 0 first.
+ */
+static inline unsigned long __fls(unsigned long word)
+{
+ int num = BITS_PER_LONG - 1;
+
+#if BITS_PER_LONG == 64
+ if (!(word & (~0ul << 32))) {
+ num -= 32;
+ word <<= 32;
+ }
+#endif
+ if (!(word & (~0ul << (BITS_PER_LONG-16)))) {
+ num -= 16;
+ word <<= 16;
+ }
+ if (!(word & (~0ul << (BITS_PER_LONG-8)))) {
+ num -= 8;
+ word <<= 8;
+ }
+ if (!(word & (~0ul << (BITS_PER_LONG-4)))) {
+ num -= 4;
+ word <<= 4;
+ }
+ if (!(word & (~0ul << (BITS_PER_LONG-2)))) {
+ num -= 2;
+ word <<= 2;
+ }
+ if (!(word & (~0ul << (BITS_PER_LONG-1))))
+ num -= 1;
+ return num;
+}
+
+#endif /* _ASM_GENERIC_BITOPS___FLS_H_ */
Index: u-boot-v2.git/include/asm-generic/bitops/ffs.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ u-boot-v2.git/include/asm-generic/bitops/ffs.h 2008-06-19 01:06:03.000000000 -0500
@@ -0,0 +1,41 @@
+#ifndef _ASM_GENERIC_BITOPS_FFS_H_
+#define _ASM_GENERIC_BITOPS_FFS_H_
+
+/**
+ * ffs - find first bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as
+ * the libc and compiler builtin ffs routines, therefore
+ * differs in spirit from the above ffz (man ffs).
+ */
+static inline int ffs(int x)
+{
+ int r = 1;
+
+ if (!x)
+ return 0;
+ if (!(x & 0xffff)) {
+ x >>= 16;
+ r += 16;
+ }
+ if (!(x & 0xff)) {
+ x >>= 8;
+ r += 8;
+ }
+ if (!(x & 0xf)) {
+ x >>= 4;
+ r += 4;
+ }
+ if (!(x & 3)) {
+ x >>= 2;
+ r += 2;
+ }
+ if (!(x & 1)) {
+ x >>= 1;
+ r += 1;
+ }
+ return r;
+}
+
+#endif /* _ASM_GENERIC_BITOPS_FFS_H_ */
Index: u-boot-v2.git/include/asm-generic/bitops/ffz.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ u-boot-v2.git/include/asm-generic/bitops/ffz.h 2008-06-19 01:06:03.000000000 -0500
@@ -0,0 +1,12 @@
+#ifndef _ASM_GENERIC_BITOPS_FFZ_H_
+#define _ASM_GENERIC_BITOPS_FFZ_H_
+
+/*
+ * ffz - find first zero in word.
+ * @word: The word to search
+ *
+ * Undefined if no zero exists, so code should check against ~0UL first.
+ */
+#define ffz(x) __ffs(~(x))
+
+#endif /* _ASM_GENERIC_BITOPS_FFZ_H_ */
Index: u-boot-v2.git/include/asm-generic/bitops/find.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ u-boot-v2.git/include/asm-generic/bitops/find.h 2008-06-19 01:06:03.000000000 -0500
@@ -0,0 +1,15 @@
+#ifndef _ASM_GENERIC_BITOPS_FIND_H_
+#define _ASM_GENERIC_BITOPS_FIND_H_
+
+#ifndef CONFIG_GENERIC_FIND_NEXT_BIT
+extern unsigned long find_next_bit(const unsigned long *addr, unsigned long
+ size, unsigned long offset);
+
+extern unsigned long find_next_zero_bit(const unsigned long *addr, unsigned
+ long size, unsigned long offset);
+#endif
+
+#define find_first_bit(addr, size) find_next_bit((addr), (size), 0)
+#define find_first_zero_bit(addr, size) find_next_zero_bit((addr), (size), 0)
+
+#endif /*_ASM_GENERIC_BITOPS_FIND_H_ */
Index: u-boot-v2.git/include/asm-generic/bitops/fls.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ u-boot-v2.git/include/asm-generic/bitops/fls.h 2008-06-19 01:06:03.000000000 -0500
@@ -0,0 +1,41 @@
+#ifndef _ASM_GENERIC_BITOPS_FLS_H_
+#define _ASM_GENERIC_BITOPS_FLS_H_
+
+/**
+ * fls - find last (most-significant) bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as ffs.
+ * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
+ */
+
+static inline int fls(int x)
+{
+ int r = 32;
+
+ if (!x)
+ return 0;
+ if (!(x & 0xffff0000u)) {
+ x <<= 16;
+ r -= 16;
+ }
+ if (!(x & 0xff000000u)) {
+ x <<= 8;
+ r -= 8;
+ }
+ if (!(x & 0xf0000000u)) {
+ x <<= 4;
+ r -= 4;
+ }
+ if (!(x & 0xc0000000u)) {
+ x <<= 2;
+ r -= 2;
+ }
+ if (!(x & 0x80000000u)) {
+ x <<= 1;
+ r -= 1;
+ }
+ return r;
+}
+
+#endif /* _ASM_GENERIC_BITOPS_FLS_H_ */
Index: u-boot-v2.git/include/asm-generic/bitops/fls64.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ u-boot-v2.git/include/asm-generic/bitops/fls64.h 2008-06-19 01:06:03.000000000 -0500
@@ -0,0 +1,36 @@
+#ifndef _ASM_GENERIC_BITOPS_FLS64_H_
+#define _ASM_GENERIC_BITOPS_FLS64_H_
+
+#include <asm/types.h>
+
+/**
+ * fls64 - find last set bit in a 64-bit word
+ * @x: the word to search
+ *
+ * This is defined in a similar way as the libc and compiler builtin
+ * ffsll, but returns the position of the most significant set bit.
+ *
+ * fls64(value) returns 0 if value is 0 or the position of the last
+ * set bit if value is nonzero. The last (most significant) bit is
+ * at position 64.
+ */
+#if BITS_PER_LONG == 32
+static inline int fls64(__u64 x)
+{
+ __u32 h = x >> 32;
+ if (h)
+ return fls(h) + 32;
+ return fls(x);
+}
+#elif BITS_PER_LONG == 64
+static inline int fls64(__u64 x)
+{
+ if (x == 0)
+ return 0;
+ return __fls(x) + 1;
+}
+#else
+#error BITS_PER_LONG not 32 or 64
+#endif
+
+#endif /* _ASM_GENERIC_BITOPS_FLS64_H_ */
Index: u-boot-v2.git/include/asm-generic/bitops/hweight.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ u-boot-v2.git/include/asm-generic/bitops/hweight.h 2008-06-19 01:06:03.000000000 -0500
@@ -0,0 +1,35 @@
+#ifndef _ASM_GENERIC_BITOPS_HWEIGHT_H_
+#define _ASM_GENERIC_BITOPS_HWEIGHT_H_
+
+#include <asm/types.h>
+
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
+
+static inline unsigned int hweight32(unsigned int w)
+{
+ unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
+ res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
+ res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
+ res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
+ return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
+}
+
+static inline unsigned int hweight16(unsigned int w)
+{
+ unsigned int res = (w & 0x5555) + ((w >> 1) & 0x5555);
+ res = (res & 0x3333) + ((res >> 2) & 0x3333);
+ res = (res & 0x0F0F) + ((res >> 4) & 0x0F0F);
+ return (res & 0x00FF) + ((res >> 8) & 0x00FF);
+}
+
+static inline unsigned int hweight8(unsigned int w)
+{
+ unsigned int res = (w & 0x55) + ((w >> 1) & 0x55);
+ res = (res & 0x33) + ((res >> 2) & 0x33);
+ return (res & 0x0F) + ((res >> 4) & 0x0F);
+}
+
+#endif /* _ASM_GENERIC_BITOPS_HWEIGHT_H_ */
Index: u-boot-v2.git/include/asm-generic/bitops/ops.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ u-boot-v2.git/include/asm-generic/bitops/ops.h 2008-06-19 01:06:03.000000000 -0500
@@ -0,0 +1,91 @@
+#ifndef _ASM_GENERIC_BITOPS_OPS_H_
+#define _ASM_GENERIC_BITOPS_OPS_H_
+
+#include <asm/types.h>
+
+/**
+ * __set_bit - Set a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ */
+static inline void __set_bit(int nr, volatile unsigned long *addr)
+{
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
+
+ *p |= mask;
+}
+
+static inline void __clear_bit(int nr, volatile unsigned long *addr)
+{
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
+
+ *p &= ~mask;
+}
+
+/**
+ * __change_bit - Toggle a bit in memory
+ * @nr: the bit to change
+ * @addr: the address to start counting from
+ */
+static inline void __change_bit(int nr, volatile unsigned long *addr)
+{
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
+
+ *p ^= mask;
+}
+
+/**
+ * __test_and_set_bit - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ */
+static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
+{
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
+ unsigned long old = *p;
+
+ *p = old | mask;
+ return (old & mask) != 0;
+}
+
+/**
+ * __test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to clear
+ * @addr: Address to count from
+ */
+static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
+{
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
+ unsigned long old = *p;
+
+ *p = old & ~mask;
+ return (old & mask) != 0;
+}
+
+static inline int __test_and_change_bit(int nr,
+ volatile unsigned long *addr)
+{
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
+ unsigned long old = *p;
+
+ *p = old ^ mask;
+ return (old & mask) != 0;
+}
+
+/**
+ * test_bit - Determine whether a bit is set
+ * @nr: bit number to test
+ * @addr: Address to start counting from
+ */
+static inline int test_bit(int nr, const volatile unsigned long *addr)
+{
+ return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
+}
+
+#endif /* _ASM_GENERIC_BITOPS_OPS_H_ */
^ permalink raw reply [flat|nested] 8+ messages in thread
* [U-Boot-Users] [Patch 2/3] U-Boot-V2: Bitops cleanup: cleanup ARM bitops
2008-06-18 15:50 ` Sascha Hauer
2008-06-19 6:12 ` [U-Boot-Users] [Patch 1/3] U-Boot-V2: Bitops cleanup: introduce asm-generic bitops Menon, Nishanth
@ 2008-06-19 6:13 ` Menon, Nishanth
2008-06-19 6:13 ` [U-Boot-Users] [Patch 3/3] U-Boot-V2: Bitops cleanup: cleanup rest of generic_xxx functions Menon, Nishanth
2 siblings, 0 replies; 8+ messages in thread
From: Menon, Nishanth @ 2008-06-19 6:13 UTC (permalink / raw)
To: u-boot
Cleanup of ARM bitops functions. Introduce the findbits.S which allows for optimized algo.
Signed-off-by: Nishanth Menon <x0nishan@ti.com>
---
arch/arm/lib/Makefile | 1
arch/arm/lib/findbit.S | 181 +++++++++++++++++++++++++++++++++++++++++++++++
include/asm-arm/bitops.h | 133 +++++++++++++++++++++++-----------
3 files changed, 273 insertions(+), 42 deletions(-)
Index: u-boot-v2.git/arch/arm/lib/Makefile
===================================================================
--- u-boot-v2.git.orig/arch/arm/lib/Makefile 2008-06-19 00:52:51.000000000 -0500
+++ u-boot-v2.git/arch/arm/lib/Makefile 2008-06-19 00:54:17.000000000 -0500
@@ -8,6 +8,7 @@
obj-y += _udivsi3.o
obj-y += _umodsi3.o
obj-y += _lshrdi3.o
+obj-y += findbit.o
obj-y += arm.o
obj-$(CONFIG_MODULES) += module.o
extra-$(CONFIG_GENERIC_LINKER_SCRIPT) += u-boot.lds
Index: u-boot-v2.git/arch/arm/lib/findbit.S
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ u-boot-v2.git/arch/arm/lib/findbit.S 2008-06-19 00:54:17.000000000 -0500
@@ -0,0 +1,181 @@
+/**
+ * @file
+ * @brief common bitops
+ */
+/*
+ * Originally from Linux kernel
+ * arch/arm/lib/findbit.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 16th March 2001 - John Ripley <jripley@sonicblue.com>
+ * Fixed so that "size" is an exclusive not an inclusive quantity.
+ * All users of these functions expect exclusive sizes, and may
+ * also call with zero size.
+ * Reworked by rmk.
+ */
+ .text
+
+/*
+ * Purpose : Find a 'zero' bit
+ * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);
+ */
+ .globl _find_first_zero_bit_le;
+_find_first_zero_bit_le:
+ teq r1, #0
+ beq 3f
+ mov r2, #0
+1: ldrb r3, [r0, r2, lsr #3]
+ eors r3, r3, #0xff @ invert bits
+ bne .L_found @ any now set - found zero bit
+ add r2, r2, #8 @ next bit pointer
+2: cmp r2, r1 @ any more?
+ blo 1b
+3: mov r0, r1 @ no free bits
+ mov pc, lr
+
+/*
+ * Purpose : Find next 'zero' bit
+ * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit,
+ * int offset)
+ */
+ .globl _find_next_zero_bit_le;
+_find_next_zero_bit_le:
+ teq r1, #0
+ beq 3b
+ ands ip, r2, #7
+ beq 1b @ If new byte, goto old routine
+ ldrb r3, [r0, r2, lsr #3]
+ eor r3, r3, #0xff @ now looking for a 1 bit
+ movs r3, r3, lsr ip @ shift off unused bits
+ bne .L_found
+ orr r2, r2, #7 @ if zero, then no bits here
+ add r2, r2, #1 @ align bit pointer
+ b 2b @ loop for next bit
+
+/*
+ * Purpose : Find a 'one' bit
+ * Prototype: int find_first_bit(const unsigned long *addr, unsigned int maxbit)
+ */
+ .globl _find_first_bit_le;
+_find_first_bit_le:
+ teq r1, #0
+ beq 3f
+ mov r2, #0
+1: ldrb r3, [r0, r2, lsr #3]
+ movs r3, r3
+ bne .L_found @ any now set - found zero bit
+ add r2, r2, #8 @ next bit pointer
+2: cmp r2, r1 @ any more?
+ blo 1b
+3: mov r0, r1 @ no free bits
+ mov pc, lr
+
+/*
+ * Purpose : Find next 'one' bit
+ * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit,
+ * int offset)
+ */
+ .globl _find_next_bit_le;
+_find_next_bit_le:
+ teq r1, #0
+ beq 3b
+ ands ip, r2, #7
+ beq 1b @ If new byte, goto old routine
+ ldrb r3, [r0, r2, lsr #3]
+ movs r3, r3, lsr ip @ shift off unused bits
+ bne .L_found
+ orr r2, r2, #7 @ if zero, then no bits here
+ add r2, r2, #1 @ align bit pointer
+ b 2b @ loop for next bit
+
+#ifdef __ARMEB__
+
+ .globl _find_first_zero_bit_be;
+_find_first_zero_bit_be:
+ teq r1, #0
+ beq 3f
+ mov r2, #0
+1: eor r3, r2, #0x18 @ big endian byte ordering
+ ldrb r3, [r0, r3, lsr #3]
+ eors r3, r3, #0xff @ invert bits
+ bne .L_found @ any now set - found zero bit
+ add r2, r2, #8 @ next bit pointer
+2: cmp r2, r1 @ any more?
+ blo 1b
+3: mov r0, r1 @ no free bits
+ mov pc, lr
+
+ .globl _find_next_zero_bit_be;
+_find_next_zero_bit_be:
+ teq r1, #0
+ beq 3b
+ ands ip, r2, #7
+ beq 1b @ If new byte, goto old routine
+ eor r3, r2, #0x18 @ big endian byte ordering
+ ldrb r3, [r0, r3, lsr #3]
+ eor r3, r3, #0xff @ now looking for a 1 bit
+ movs r3, r3, lsr ip @ shift off unused bits
+ bne .L_found
+ orr r2, r2, #7 @ if zero, then no bits here
+ add r2, r2, #1 @ align bit pointer
+ b 2b @ loop for next bit
+
+ .globl _find_first_bit_be;
+_find_first_bit_be:
+ teq r1, #0
+ beq 3f
+ mov r2, #0
+1: eor r3, r2, #0x18 @ big endian byte ordering
+ ldrb r3, [r0, r3, lsr #3]
+ movs r3, r3
+ bne .L_found @ any now set - found zero bit
+ add r2, r2, #8 @ next bit pointer
+2: cmp r2, r1 @ any more?
+ blo 1b
+3: mov r0, r1 @ no free bits
+ mov pc, lr
+
+ .globl _find_next_bit_be;
+_find_next_bit_be:
+ teq r1, #0
+ beq 3b
+ ands ip, r2, #7
+ beq 1b @ If new byte, goto old routine
+ eor r3, r2, #0x18 @ big endian byte ordering
+ ldrb r3, [r0, r3, lsr #3]
+ movs r3, r3, lsr ip @ shift off unused bits
+ bne .L_found
+ orr r2, r2, #7 @ if zero, then no bits here
+ add r2, r2, #1 @ align bit pointer
+ b 2b @ loop for next bit
+
+#endif
+
+/*
+ * One or more bits in the LSB of r3 are assumed to be set.
+ */
+.L_found:
+#if __LINUX_ARM_ARCH__ >= 5
+ rsb r1, r3, #0
+ and r3, r3, r1
+ clz r3, r3
+ rsb r3, r3, #31
+ add r0, r2, r3
+#else
+ tst r3, #0x0f
+ addeq r2, r2, #4
+ movne r3, r3, lsl #4
+ tst r3, #0x30
+ addeq r2, r2, #2
+ movne r3, r3, lsl #2
+ tst r3, #0x40
+ addeq r2, r2, #1
+ mov r0, r2
+#endif
+ mov pc, lr
+
Index: u-boot-v2.git/include/asm-arm/bitops.h
===================================================================
--- u-boot-v2.git.orig/include/asm-arm/bitops.h 2008-06-19 00:52:51.000000000 -0500
+++ u-boot-v2.git/include/asm-arm/bitops.h 2008-06-19 00:54:30.000000000 -0500
@@ -15,32 +15,28 @@
#ifndef __ASM_ARM_BITOPS_H
#define __ASM_ARM_BITOPS_H
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
/*
- * Function prototypes to keep gcc -Wall happy.
+ * Functions equivalent of ops.h
*/
-extern void set_bit(int nr, volatile void * addr);
-
static inline void __set_bit(int nr, volatile void *addr)
{
((unsigned char *) addr)[nr >> 3] |= (1U << (nr & 7));
}
-extern void clear_bit(int nr, volatile void * addr);
-
static inline void __clear_bit(int nr, volatile void *addr)
{
((unsigned char *) addr)[nr >> 3] &= ~(1U << (nr & 7));
}
-extern void change_bit(int nr, volatile void * addr);
-
static inline void __change_bit(int nr, volatile void *addr)
{
((unsigned char *) addr)[nr >> 3] ^= (1U << (nr & 7));
}
-extern int test_and_set_bit(int nr, volatile void * addr);
-
static inline int __test_and_set_bit(int nr, volatile void *addr)
{
unsigned int mask = 1 << (nr & 7);
@@ -51,8 +47,6 @@
return oldval & mask;
}
-extern int test_and_clear_bit(int nr, volatile void * addr);
-
static inline int __test_and_clear_bit(int nr, volatile void *addr)
{
unsigned int mask = 1 << (nr & 7);
@@ -63,8 +57,6 @@
return oldval & mask;
}
-extern int test_and_change_bit(int nr, volatile void * addr);
-
static inline int __test_and_change_bit(int nr, volatile void *addr)
{
unsigned int mask = 1 << (nr & 7);
@@ -75,9 +67,6 @@
return oldval & mask;
}
-extern int find_first_zero_bit(void * addr, unsigned size);
-extern int find_next_zero_bit(void * addr, int size, int offset);
-
/*
* This routine doesn't need to be atomic.
*/
@@ -86,6 +75,48 @@
return ((unsigned char *) addr)[nr >> 3] & (1U << (nr & 7));
}
+#define set_bit(x, y) __set_bit(x, y)
+#define clear_bit(x, y) __clear_bit(x, y)
+#define change_bit(x, y) __change_bit(x, y)
+#define test_and_set_bit(x, y) __test_and_set_bit(x, y)
+#define test_and_clear_bit(x, y) __test_and_clear_bit(x, y)
+#define test_and_change_bit(x, y) __test_and_change_bit(x, y)
+
+#ifndef __ARMEB__
+/*
+ * These are the little endian definitions.
+ */
+extern int _find_first_zero_bit_le(const void *p, unsigned size);
+extern int _find_next_zero_bit_le(const void *p, int size, int offset);
+extern int _find_first_bit_le(const unsigned long *p, unsigned size);
+extern int _find_next_bit_le(const unsigned long *p, int size, int offset);
+#define find_first_zero_bit(p, sz) _find_first_zero_bit_le(p, sz)
+#define find_next_zero_bit(p, sz, off) _find_next_zero_bit_le(p, sz, off)
+#define find_first_bit(p, sz) _find_first_bit_le(p, sz)
+#define find_next_bit(p, sz, off) _find_next_bit_le(p, sz, off)
+
+#define WORD_BITOFF_TO_LE(x) ((x))
+
+#else /* ! __ARMEB__ */
+
+/*
+ * These are the big endian definitions.
+ */
+extern int _find_first_zero_bit_be(const void *p, unsigned size);
+extern int _find_next_zero_bit_be(const void *p, int size, int offset);
+extern int _find_first_bit_be(const unsigned long *p, unsigned size);
+extern int _find_next_bit_be(const unsigned long *p, int size, int offset);
+#define find_first_zero_bit(p, sz) _find_first_zero_bit_be(p, sz)
+#define find_next_zero_bit(p, sz, off) _find_next_zero_bit_be(p, sz, off)
+#define find_first_bit(p, sz) _find_first_bit_be(p, sz)
+#define find_next_bit(p, sz, off) _find_next_bit_be(p, sz, off)
+
+#define WORD_BITOFF_TO_LE(x) ((x) ^ 0x18)
+
+#endif /* __ARMEB__ */
+
+#if defined(__LINUX_ARM_ARCH__) && (__LINUX_ARM_ARCH__ < 5)
+
/*
* ffz = Find First Zero in word. Undefined if no zero exists,
* so code should check against ~0UL first..
@@ -103,35 +134,53 @@
if (word & 0x40000000) { k -= 1; }
return k;
}
+#include <asm-generic/bitops/__ffs.h>
+#include <asm-generic/bitops/ffs.h>
+#include <asm-generic/bitops/fls.h>
+#else /* ! __ARM__USE_GENERIC_FF */
+
+static inline int constant_fls(int x)
+{
+ int r = 32;
+
+ if (!x)
+ return 0;
+ if (!(x & 0xffff0000u)) {
+ x <<= 16;
+ r -= 16;
+ }
+ if (!(x & 0xff000000u)) {
+ x <<= 8;
+ r -= 8;
+ }
+ if (!(x & 0xf0000000u)) {
+ x <<= 4;
+ r -= 4;
+ }
+ if (!(x & 0xc0000000u)) {
+ x <<= 2;
+ r -= 2;
+ }
+ if (!(x & 0x80000000u)) {
+ x <<= 1;
+ r -= 1;
+ }
+ return r;
+}
/*
- * ffs: find first bit set. This is defined the same way as
- * the libc and compiler builtin ffs routines, therefore
- * differs in spirit from the above ffz (man ffs).
- */
-
-#define ffs(x) generic_ffs(x)
-
-/*
- * hweightN: returns the hamming weight (i.e. the number
- * of bits set) of a N-bit word
+ * On ARMv5 and above those functions can be implemented around
+ * the clz instruction for much better code efficiency.
*/
+#define fls(x) \
+ (__builtin_constant_p(x) ? constant_fls(x) : \
+ ({ int __r; asm("clz\t%0, %1" : "=r"(__r) : "r"(x) : "cc"); 32-__r; }))
+#define ffs(x) ({ unsigned long __t = (x); fls(__t &-__t); })
+#define __ffs(x) (ffs(x) - 1)
+#define ffz(x) __ffs(~(x))
+#endif /* __ARM__USE_GENERIC_FF */
+#include <asm-generic/bitops/fls64.h>
-#define hweight32(x) generic_hweight32(x)
-#define hweight16(x) generic_hweight16(x)
-#define hweight8(x) generic_hweight8(x)
-
-#define ext2_set_bit test_and_set_bit
-#define ext2_clear_bit test_and_clear_bit
-#define ext2_test_bit test_bit
-#define ext2_find_first_zero_bit find_first_zero_bit
-#define ext2_find_next_zero_bit find_next_zero_bit
-
-/* Bitmap functions for the minix filesystem. */
-#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
-#define minix_set_bit(nr,addr) set_bit(nr,addr)
-#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
-#define minix_test_bit(nr,addr) test_bit(nr,addr)
-#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
+#include <asm-generic/bitops/hweight.h>
#endif /* _ARM_BITOPS_H */
^ permalink raw reply [flat|nested] 8+ messages in thread
* [U-Boot-Users] [Patch 3/3] U-Boot-V2: Bitops cleanup: cleanup rest of generic_xxx functions
2008-06-18 15:50 ` Sascha Hauer
2008-06-19 6:12 ` [U-Boot-Users] [Patch 1/3] U-Boot-V2: Bitops cleanup: introduce asm-generic bitops Menon, Nishanth
2008-06-19 6:13 ` [U-Boot-Users] [Patch 2/3] U-Boot-V2: Bitops cleanup: cleanup ARM bitops Menon, Nishanth
@ 2008-06-19 6:13 ` Menon, Nishanth
2 siblings, 0 replies; 8+ messages in thread
From: Menon, Nishanth @ 2008-06-19 6:13 UTC (permalink / raw)
To: u-boot
Use the asm-generic/bitops/xyz.h instead of using generic_xyz functions.
Signed-off-by: Nishanth Menon <x0nishan@ti.com>
---
include/asm-blackfin/bitops.h | 18 +---------
include/asm-m68k/bitops.h | 18 +---------
include/asm-ppc/bitops.h | 9 -----
include/linux/bitops.h | 71 ++++--------------------------------------
4 files changed, 12 insertions(+), 104 deletions(-)
Index: u-boot-v2.git/include/asm-blackfin/bitops.h
===================================================================
--- u-boot-v2.git.orig/include/asm-blackfin/bitops.h 2008-06-19 00:50:37.000000000 -0500
+++ u-boot-v2.git/include/asm-blackfin/bitops.h 2008-06-19 00:51:52.000000000 -0500
@@ -268,22 +268,8 @@
return result + ffz(tmp);
}
-/*
- * ffs: find first bit set. This is defined the same way as
- * the libc and compiler builtin ffs routines, therefore
- * differs in spirit from the above ffz (man ffs).
- */
-
-#define ffs(x) generic_ffs(x)
-
-/*
- * hweightN: returns the hamming weight (i.e. the number
- * of bits set) of a N-bit word
- */
-
-#define hweight32(x) generic_hweight32(x)
-#define hweight16(x) generic_hweight16(x)
-#define hweight8(x) generic_hweight8(x)
+#include <asm-generic/bitops/ffs.h>
+#include <asm-generic/bitops/hweight.h>
static __inline__ int ext2_set_bit(int nr, volatile void *addr)
{
Index: u-boot-v2.git/include/asm-m68k/bitops.h
===================================================================
--- u-boot-v2.git.orig/include/asm-m68k/bitops.h 2008-06-19 00:50:13.000000000 -0500
+++ u-boot-v2.git/include/asm-m68k/bitops.h 2008-06-19 00:51:52.000000000 -0500
@@ -122,22 +122,8 @@
return k;
}
-/*
- * ffs: find first bit set. This is defined the same way as
- * the libc and compiler builtin ffs routines, therefore
- * differs in spirit from the above ffz (man ffs).
- */
-
-#define ffs(x) generic_ffs(x)
-
-/*
- * hweightN: returns the hamming weight (i.e. the number
- * of bits set) of a N-bit word
- */
-
-#define hweight32(x) generic_hweight32(x)
-#define hweight16(x) generic_hweight16(x)
-#define hweight8(x) generic_hweight8(x)
+#include <asm-generic/bitops/ffs.h>
+#include <asm-generic/bitops/hweight.h>
#define ext2_set_bit test_and_set_bit
#define ext2_clear_bit test_and_clear_bit
Index: u-boot-v2.git/include/linux/bitops.h
===================================================================
--- u-boot-v2.git.orig/include/linux/bitops.h 2008-06-19 00:50:13.000000000 -0500
+++ u-boot-v2.git/include/linux/bitops.h 2008-06-19 00:52:34.000000000 -0500
@@ -1,70 +1,13 @@
#ifndef _LINUX_BITOPS_H
#define _LINUX_BITOPS_H
-
-/*
- * ffs: find first bit set. This is defined the same way as
- * the libc and compiler builtin ffs routines, therefore
- * differs in spirit from the above ffz (man ffs).
- */
-
-static inline int generic_ffs(int x)
-{
- int r = 1;
-
- if (!x)
- return 0;
- if (!(x & 0xffff)) {
- x >>= 16;
- r += 16;
- }
- if (!(x & 0xff)) {
- x >>= 8;
- r += 8;
- }
- if (!(x & 0xf)) {
- x >>= 4;
- r += 4;
- }
- if (!(x & 3)) {
- x >>= 2;
- r += 2;
- }
- if (!(x & 1)) {
- x >>= 1;
- r += 1;
- }
- return r;
-}
-
-/*
- * hweightN: returns the hamming weight (i.e. the number
- * of bits set) of a N-bit word
- */
-
-static inline unsigned int generic_hweight32(unsigned int w)
-{
- unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
- res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
- res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
- res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
- return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
-}
-
-static inline unsigned int generic_hweight16(unsigned int w)
-{
- unsigned int res = (w & 0x5555) + ((w >> 1) & 0x5555);
- res = (res & 0x3333) + ((res >> 2) & 0x3333);
- res = (res & 0x0F0F) + ((res >> 4) & 0x0F0F);
- return (res & 0x00FF) + ((res >> 8) & 0x00FF);
-}
-
-static inline unsigned int generic_hweight8(unsigned int w)
-{
- unsigned int res = (w & 0x55) + ((w >> 1) & 0x55);
- res = (res & 0x33) + ((res >> 2) & 0x33);
- return (res & 0x0F) + ((res >> 4) & 0x0F);
-}
+#ifdef __U_BOOT__
+#define BIT(nr) (1UL << (nr))
+#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
+#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
+#define BITS_PER_BYTE 8
+#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
+#endif
#include <asm/bitops.h>
Index: u-boot-v2.git/include/asm-ppc/bitops.h
===================================================================
--- u-boot-v2.git.orig/include/asm-ppc/bitops.h 2008-06-19 00:50:37.000000000 -0500
+++ u-boot-v2.git/include/asm-ppc/bitops.h 2008-06-19 00:51:52.000000000 -0500
@@ -178,14 +178,7 @@
return __ilog2(x & -x) + 1;
}
-/*
- * hweightN: returns the hamming weight (i.e. the number
- * of bits set) of a N-bit word
- */
-
-#define hweight32(x) generic_hweight32(x)
-#define hweight16(x) generic_hweight16(x)
-#define hweight8(x) generic_hweight8(x)
+#include <asm-generic/bitops/hweight.h>
#endif /* __U_BOOT__ */
^ permalink raw reply [flat|nested] 8+ messages in thread
* [U-Boot-Users] [Patch 1/3] U-Boot-V2: Bitops cleanup: introduce asm-generic bitops
2008-06-19 6:12 ` [U-Boot-Users] [Patch 1/3] U-Boot-V2: Bitops cleanup: introduce asm-generic bitops Menon, Nishanth
@ 2008-06-19 12:56 ` Jon Loeliger
0 siblings, 0 replies; 8+ messages in thread
From: Jon Loeliger @ 2008-06-19 12:56 UTC (permalink / raw)
To: u-boot
Menon, Nishanth wrote:
> Sascha,
> The following 3 patches are for cleaning up the bitops
>> -----Original Message-----
>> From: Sascha Hauer [mailto:s.hauer at pengutronix.de]
>> Sent: Wednesday, June 18, 2008 10:51 AM
>> To: Menon, Nishanth
>> Cc: Kamat, Nishant; u-boot-users at lists.sourceforge.net; Laurent Desnogues; philip.balister at gmail.com;
>> dirk.behme at googlemail.com
>> Subject: Re: [Patch 2/9] U-boot-V2:ARM: Introduce additional bitops
>>
>>
>> In the kernel are generic bitops, #ifdefed with CONFIG_GENERIC_XXX
Again, either leave the above crap out entirely or place it
below the triple-dash line.
> This introduces selected generic bitop files from kernel. We don't need minix, ext2, sched or lock based bitops. Those have been dropped.
Line wrap the log message at 70 or 72.
> Signed-off-by: Nishanth Menon <x0nishan@ti.com>
>
> ---
> include/asm-generic/bitops/__ffs.h | 43 ++++++++++++++++
> include/asm-generic/bitops/__fls.h | 43 ++++++++++++++++
Thanks,
jdl
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2008-06-19 12:56 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-06-18 12:34 [U-Boot-Users] [Patch 2/9] U-boot-V2:ARM: Introduce additional bitops Menon, Nishanth
2008-06-18 15:30 ` Sascha Hauer
2008-06-18 15:41 ` Menon, Nishanth
2008-06-18 15:50 ` Sascha Hauer
2008-06-19 6:12 ` [U-Boot-Users] [Patch 1/3] U-Boot-V2: Bitops cleanup: introduce asm-generic bitops Menon, Nishanth
2008-06-19 12:56 ` Jon Loeliger
2008-06-19 6:13 ` [U-Boot-Users] [Patch 2/3] U-Boot-V2: Bitops cleanup: cleanup ARM bitops Menon, Nishanth
2008-06-19 6:13 ` [U-Boot-Users] [Patch 3/3] U-Boot-V2: Bitops cleanup: cleanup rest of generic_xxx functions Menon, Nishanth
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox