linux-bk/include/asm-arm/bitops.h
<<
>>
Prefs
   1/*
   2 * Copyright 1995, Russell King.
   3 * Various bits and pieces copyrights include:
   4 *  Linus Torvalds (test_bit).
   5 * Big endian support: Copyright 2001, Nicolas Pitre
   6 *  reworked by rmk.
   7 *
   8 * bit 0 is the LSB of an "unsigned long" quantity.
   9 *
  10 * Please note that the code in this file should never be included
  11 * from user space.  Many of these are not implemented in assembler
  12 * since they would be too costly.  Also, they require privileged
  13 * instructions (which are not available from user mode) to ensure
  14 * that they are atomic.
  15 */
  16
  17#ifndef __ASM_ARM_BITOPS_H
  18#define __ASM_ARM_BITOPS_H
  19
  20#ifdef __KERNEL__
  21
  22#include <asm/system.h>
  23
  24#define smp_mb__before_clear_bit()      do { } while (0)
  25#define smp_mb__after_clear_bit()       do { } while (0)
  26
  27/*
  28 * These functions are the basis of our bit ops.
  29 *
  30 * First, the atomic bitops. These use native endian.
  31 */
  32static inline void ____atomic_set_bit(unsigned int bit, volatile unsigned long *p)
  33{
  34        unsigned long flags;
  35        unsigned long mask = 1UL << (bit & 31);
  36
  37        p += bit >> 5;
  38
  39        local_irq_save(flags);
  40        *p |= mask;
  41        local_irq_restore(flags);
  42}
  43
  44static inline void ____atomic_clear_bit(unsigned int bit, volatile unsigned long *p)
  45{
  46        unsigned long flags;
  47        unsigned long mask = 1UL << (bit & 31);
  48
  49        p += bit >> 5;
  50
  51        local_irq_save(flags);
  52        *p &= ~mask;
  53        local_irq_restore(flags);
  54}
  55
  56static inline void ____atomic_change_bit(unsigned int bit, volatile unsigned long *p)
  57{
  58        unsigned long flags;
  59        unsigned long mask = 1UL << (bit & 31);
  60
  61        p += bit >> 5;
  62
  63        local_irq_save(flags);
  64        *p ^= mask;
  65        local_irq_restore(flags);
  66}
  67
  68static inline int
  69____atomic_test_and_set_bit(unsigned int bit, volatile unsigned long *p)
  70{
  71        unsigned long flags;
  72        unsigned int res;
  73        unsigned long mask = 1UL << (bit & 31);
  74
  75        p += bit >> 5;
  76
  77        local_irq_save(flags);
  78        res = *p;
  79        *p = res | mask;
  80        local_irq_restore(flags);
  81
  82        return res & mask;
  83}
  84
  85static inline int
  86____atomic_test_and_clear_bit(unsigned int bit, volatile unsigned long *p)
  87{
  88        unsigned long flags;
  89        unsigned int res;
  90        unsigned long mask = 1UL << (bit & 31);
  91
  92        p += bit >> 5;
  93
  94        local_irq_save(flags);
  95        res = *p;
  96        *p = res & ~mask;
  97        local_irq_restore(flags);
  98
  99        return res & mask;
 100}
 101
 102static inline int
 103____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p)
 104{
 105        unsigned long flags;
 106        unsigned int res;
 107        unsigned long mask = 1UL << (bit & 31);
 108
 109        p += bit >> 5;
 110
 111        local_irq_save(flags);
 112        res = *p;
 113        *p = res ^ mask;
 114        local_irq_restore(flags);
 115
 116        return res & mask;
 117}
 118
 119/*
 120 * Now the non-atomic variants.  We let the compiler handle all
 121 * optimisations for these.  These are all _native_ endian.
 122 */
 123static inline void __set_bit(int nr, volatile unsigned long *p)
 124{
 125        p[nr >> 5] |= (1UL << (nr & 31));
 126}
 127
 128static inline void __clear_bit(int nr, volatile unsigned long *p)
 129{
 130        p[nr >> 5] &= ~(1UL << (nr & 31));
 131}
 132
 133static inline void __change_bit(int nr, volatile unsigned long *p)
 134{
 135        p[nr >> 5] ^= (1UL << (nr & 31));
 136}
 137
 138static inline int __test_and_set_bit(int nr, volatile unsigned long *p)
 139{
 140        unsigned long oldval, mask = 1UL << (nr & 31);
 141
 142        p += nr >> 5;
 143
 144        oldval = *p;
 145        *p = oldval | mask;
 146        return oldval & mask;
 147}
 148
 149static inline int __test_and_clear_bit(int nr, volatile unsigned long *p)
 150{
 151        unsigned long oldval, mask = 1UL << (nr & 31);
 152
 153        p += nr >> 5;
 154
 155        oldval = *p;
 156        *p = oldval & ~mask;
 157        return oldval & mask;
 158}
 159
 160static inline int __test_and_change_bit(int nr, volatile unsigned long *p)
 161{
 162        unsigned long oldval, mask = 1UL << (nr & 31);
 163
 164        p += nr >> 5;
 165
 166        oldval = *p;
 167        *p = oldval ^ mask;
 168        return oldval & mask;
 169}
 170
 171/*
 172 * This routine doesn't need to be atomic.
 173 */
 174static inline int __test_bit(int nr, const volatile unsigned long * p)
 175{
 176        return (p[nr >> 5] >> (nr & 31)) & 1UL;
 177}
 178
 179/*
 180 *  A note about Endian-ness.
 181 *  -------------------------
 182 *
 183 * When the ARM is put into big endian mode via CR15, the processor
 184 * merely swaps the order of bytes within words, thus:
 185 *
 186 *          ------------ physical data bus bits -----------
 187 *          D31 ... D24  D23 ... D16  D15 ... D8  D7 ... D0
 188 * little     byte 3       byte 2       byte 1      byte 0
 189 * big        byte 0       byte 1       byte 2      byte 3
 190 *
 191 * This means that reading a 32-bit word at address 0 returns the same
 192 * value irrespective of the endian mode bit.
 193 *
 194 * Peripheral devices should be connected with the data bus reversed in
 195 * "Big Endian" mode.  ARM Application Note 61 is applicable, and is
 196 * available from http://www.arm.com/.
 197 *
 198 * The following assumes that the data bus connectivity for big endian
 199 * mode has been followed.
 200 *
 201 * Note that bit 0 is defined to be 32-bit word bit 0, not byte 0 bit 0.
 202 */
 203
 204/*
 205 * Little endian assembly bitops.  nr = 0 -> byte 0 bit 0.
 206 */
 207extern void _set_bit_le(int nr, volatile unsigned long * p);
 208extern void _clear_bit_le(int nr, volatile unsigned long * p);
 209extern void _change_bit_le(int nr, volatile unsigned long * p);
 210extern int _test_and_set_bit_le(int nr, volatile unsigned long * p);
 211extern int _test_and_clear_bit_le(int nr, volatile unsigned long * p);
 212extern int _test_and_change_bit_le(int nr, volatile unsigned long * p);
 213extern int _find_first_zero_bit_le(const void * p, unsigned size);
 214extern int _find_next_zero_bit_le(const void * p, int size, int offset);
 215extern int _find_first_bit_le(const unsigned long *p, unsigned size);
 216extern int _find_next_bit_le(const unsigned long *p, int size, int offset);
 217
 218/*
 219 * Big endian assembly bitops.  nr = 0 -> byte 3 bit 0.
 220 */
 221extern void _set_bit_be(int nr, volatile unsigned long * p);
 222extern void _clear_bit_be(int nr, volatile unsigned long * p);
 223extern void _change_bit_be(int nr, volatile unsigned long * p);
 224extern int _test_and_set_bit_be(int nr, volatile unsigned long * p);
 225extern int _test_and_clear_bit_be(int nr, volatile unsigned long * p);
 226extern int _test_and_change_bit_be(int nr, volatile unsigned long * p);
 227extern int _find_first_zero_bit_be(const void * p, unsigned size);
 228extern int _find_next_zero_bit_be(const void * p, int size, int offset);
 229extern int _find_first_bit_be(const unsigned long *p, unsigned size);
 230extern int _find_next_bit_be(const unsigned long *p, int size, int offset);
 231
 232/*
 233 * The __* form of bitops are non-atomic and may be reordered.
 234 */
 235#define ATOMIC_BITOP_LE(name,nr,p)              \
 236        (__builtin_constant_p(nr) ?             \
 237         ____atomic_##name(nr, p) :             \
 238         _##name##_le(nr,p))
 239
 240#define ATOMIC_BITOP_BE(name,nr,p)              \
 241        (__builtin_constant_p(nr) ?             \
 242         ____atomic_##name(nr, p) :             \
 243         _##name##_be(nr,p))
 244
 245#define NONATOMIC_BITOP(name,nr,p)              \
 246        (____nonatomic_##name(nr, p))
 247
 248#ifndef __ARMEB__
 249/*
 250 * These are the little endian, atomic definitions.
 251 */
 252#define set_bit(nr,p)                   ATOMIC_BITOP_LE(set_bit,nr,p)
 253#define clear_bit(nr,p)                 ATOMIC_BITOP_LE(clear_bit,nr,p)
 254#define change_bit(nr,p)                ATOMIC_BITOP_LE(change_bit,nr,p)
 255#define test_and_set_bit(nr,p)          ATOMIC_BITOP_LE(test_and_set_bit,nr,p)
 256#define test_and_clear_bit(nr,p)        ATOMIC_BITOP_LE(test_and_clear_bit,nr,p)
 257#define test_and_change_bit(nr,p)       ATOMIC_BITOP_LE(test_and_change_bit,nr,p)
 258#define test_bit(nr,p)                  __test_bit(nr,p)
 259#define find_first_zero_bit(p,sz)       _find_first_zero_bit_le(p,sz)
 260#define find_next_zero_bit(p,sz,off)    _find_next_zero_bit_le(p,sz,off)
 261#define find_first_bit(p,sz)            _find_first_bit_le(p,sz)
 262#define find_next_bit(p,sz,off)         _find_next_bit_le(p,sz,off)
 263
 264#define WORD_BITOFF_TO_LE(x)            ((x))
 265
 266#else
 267
 268/*
 269 * These are the big endian, atomic definitions.
 270 */
 271#define set_bit(nr,p)                   ATOMIC_BITOP_BE(set_bit,nr,p)
 272#define clear_bit(nr,p)                 ATOMIC_BITOP_BE(clear_bit,nr,p)
 273#define change_bit(nr,p)                ATOMIC_BITOP_BE(change_bit,nr,p)
 274#define test_and_set_bit(nr,p)          ATOMIC_BITOP_BE(test_and_set_bit,nr,p)
 275#define test_and_clear_bit(nr,p)        ATOMIC_BITOP_BE(test_and_clear_bit,nr,p)
 276#define test_and_change_bit(nr,p)       ATOMIC_BITOP_BE(test_and_change_bit,nr,p)
 277#define test_bit(nr,p)                  __test_bit(nr,p)
 278#define find_first_zero_bit(p,sz)       _find_first_zero_bit_be(p,sz)
 279#define find_next_zero_bit(p,sz,off)    _find_next_zero_bit_be(p,sz,off)
 280#define find_first_bit(p,sz)            _find_first_bit_be(p,sz)
 281#define find_next_bit(p,sz,off)         _find_next_bit_be(p,sz,off)
 282
 283#define WORD_BITOFF_TO_LE(x)            ((x) ^ 0x18)
 284
 285#endif
 286
 287#if __LINUX_ARM_ARCH__ < 5
 288
 289/*
 290 * ffz = Find First Zero in word. Undefined if no zero exists,
 291 * so code should check against ~0UL first..
 292 */
 293static inline unsigned long ffz(unsigned long word)
 294{
 295        int k;
 296
 297        word = ~word;
 298        k = 31;
 299        if (word & 0x0000ffff) { k -= 16; word <<= 16; }
 300        if (word & 0x00ff0000) { k -= 8;  word <<= 8;  }
 301        if (word & 0x0f000000) { k -= 4;  word <<= 4;  }
 302        if (word & 0x30000000) { k -= 2;  word <<= 2;  }
 303        if (word & 0x40000000) { k -= 1; }
 304        return k;
 305}
 306
 307/*
 308 * ffz = Find First Zero in word. Undefined if no zero exists,
 309 * so code should check against ~0UL first..
 310 */
 311static inline unsigned long __ffs(unsigned long word)
 312{
 313        int k;
 314
 315        k = 31;
 316        if (word & 0x0000ffff) { k -= 16; word <<= 16; }
 317        if (word & 0x00ff0000) { k -= 8;  word <<= 8;  }
 318        if (word & 0x0f000000) { k -= 4;  word <<= 4;  }
 319        if (word & 0x30000000) { k -= 2;  word <<= 2;  }
 320        if (word & 0x40000000) { k -= 1; }
 321        return k;
 322}
 323
 324/*
 325 * fls: find last bit set.
 326 */
 327
 328#define fls(x) generic_fls(x)
 329
 330/*
 331 * ffs: find first bit set. This is defined the same way as
 332 * the libc and compiler builtin ffs routines, therefore
 333 * differs in spirit from the above ffz (man ffs).
 334 */
 335
 336#define ffs(x) generic_ffs(x)
 337
 338#else
 339
 340/*
 341 * On ARMv5 and above those functions can be implemented around
 342 * the clz instruction for much better code efficiency.
 343 */
 344
 345static __inline__ int generic_fls(int x);
 346#define fls(x) \
 347        ( __builtin_constant_p(x) ? generic_fls(x) : \
 348          ({ int __r; asm("clz\t%0, %1" : "=r"(__r) : "r"(x) : "cc"); 32-__r; }) )
 349#define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); })
 350#define __ffs(x) (ffs(x) - 1)
 351#define ffz(x) __ffs( ~(x) )
 352
 353#endif
 354
 355/*
 356 * Find first bit set in a 168-bit bitmap, where the first
 357 * 128 bits are unlikely to be set.
 358 */
 359static inline int sched_find_first_bit(const unsigned long *b)
 360{
 361        unsigned long v;
 362        unsigned int off;
 363
 364        for (off = 0; v = b[off], off < 4; off++) {
 365                if (unlikely(v))
 366                        break;
 367        }
 368        return __ffs(v) + off * 32;
 369}
 370
 371/*
 372 * hweightN: returns the hamming weight (i.e. the number
 373 * of bits set) of a N-bit word
 374 */
 375
 376#define hweight32(x) generic_hweight32(x)
 377#define hweight16(x) generic_hweight16(x)
 378#define hweight8(x) generic_hweight8(x)
 379
 380/*
 381 * Ext2 is defined to use little-endian byte ordering.
 382 * These do not need to be atomic.
 383 */
 384#define ext2_set_bit(nr,p)                      \
 385                __test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 386#define ext2_set_bit_atomic(lock,nr,p)          \
 387                test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 388#define ext2_clear_bit(nr,p)                    \
 389                __test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 390#define ext2_clear_bit_atomic(lock,nr,p)        \
 391                test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 392#define ext2_test_bit(nr,p)                     \
 393                __test_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 394#define ext2_find_first_zero_bit(p,sz)          \
 395                _find_first_zero_bit_le(p,sz)
 396#define ext2_find_next_zero_bit(p,sz,off)       \
 397                _find_next_zero_bit_le(p,sz,off)
 398
 399/*
 400 * Minix is defined to use little-endian byte ordering.
 401 * These do not need to be atomic.
 402 */
 403#define minix_set_bit(nr,p)                     \
 404                __set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 405#define minix_test_bit(nr,p)                    \
 406                __test_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 407#define minix_test_and_set_bit(nr,p)            \
 408                __test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 409#define minix_test_and_clear_bit(nr,p)          \
 410                __test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
 411#define minix_find_first_zero_bit(p,sz)         \
 412                _find_first_zero_bit_le(p,sz)
 413
 414#endif /* __KERNEL__ */
 415
 416#endif /* _ARM_BITOPS_H */
 417
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.