iPXE
bitops.h
Go to the documentation of this file.
1 #ifndef _BITS_BITOPS_H
2 #define _BITS_BITOPS_H
3 
4 /** @file
5  *
6  * x86 bit operations
7  *
8  * We perform atomic bit set and bit clear operations using "lock bts"
9  * and "lock btr". We use the output constraint to inform the
10  * compiler that any memory from the start of the bit field up to and
11  * including the byte containing the bit may be modified. (This is
12  * overkill but shouldn't matter in practice since we're unlikely to
13  * subsequently read other bits from the same bit field.)
14  */
15 
16 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
17 
18 #include <stdint.h>
19 
20 /**
21  * Set bit atomically
22  *
23  * @v bit Bit to set
24  * @v bits Bit field
25  */
26 static inline __attribute__ (( always_inline )) void
27 set_bit ( unsigned int bit, volatile void *bits ) {
28  volatile struct {
29  uint8_t byte[ ( bit / 8 ) + 1 ];
30  } *bytes = bits;
31 
32  __asm__ __volatile__ ( "lock btsl %k1, %0"
33  : "+m" ( *bytes ) : "Ir" ( bit ) );
34 }
35 
36 /**
37  * Clear bit atomically
38  *
39  * @v bit Bit to set
40  * @v bits Bit field
41  */
42 static inline __attribute__ (( always_inline )) void
43 clear_bit ( unsigned int bit, volatile void *bits ) {
44  volatile struct {
45  uint8_t byte[ ( bit / 8 ) + 1 ];
46  } *bytes = bits;
47 
48  __asm__ __volatile__ ( "lock btrl %k1, %0"
49  : "+m" ( *bytes ) : "Ir" ( bit ) );
50 }
51 
52 /**
53  * Test and set bit atomically
54  *
55  * @v bit Bit to set
56  * @v bits Bit field
57  * @ret old Old value of bit (zero or non-zero)
58  */
59 static inline __attribute__ (( always_inline )) int
60 test_and_set_bit ( unsigned int bit, volatile void *bits ) {
61  volatile struct {
62  uint8_t byte[ ( bit / 8 ) + 1 ];
63  } *bytes = bits;
64  int old;
65 
66  __asm__ __volatile__ ( "lock btsl %k2, %0\n\t"
67  "sbb %1, %1\n\t"
68  : "+m" ( *bytes ), "=r" ( old )
69  : "Ir" ( bit ) );
70  return old;
71 }
72 
73 /**
74  * Test and clear bit atomically
75  *
76  * @v bit Bit to set
77  * @v bits Bit field
78  * @ret old Old value of bit (zero or non-zero)
79  */
80 static inline __attribute__ (( always_inline )) int
81 test_and_clear_bit ( unsigned int bit, volatile void *bits ) {
82  volatile struct {
83  uint8_t byte[ ( bit / 8 ) + 1 ];
84  } *bytes = bits;
85  int old;
86 
87  __asm__ __volatile__ ( "lock btrl %k2, %0\n\t"
88  "sbb %1, %1\n\t"
89  : "+m" ( *bytes ), "=r" ( old )
90  : "Ir" ( bit ) );
91  return old;
92 }
93 
94 #endif /* _BITS_BITOPS_H */
int test_and_set_bit(unsigned int bit, volatile void *bits)
__asm__ __volatile__("lock btsl %k1, %0" :"+m"(*bytes) :"Ir"(bit))
static unsigned int unsigned int bit
Definition: bigint.h:208
int old
Definition: bitops.h:64
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
unsigned char uint8_t
Definition: stdint.h:10
void set_bit(unsigned int bit, volatile void *bits)
static __attribute__((always_inline)) void set_bit(unsigned int bit
Set bit atomically.
__asm__(".section \".rodata\", \"a\", " PROGBITS "\n\t" "\nprivate_key_data:\n\t" ".size private_key_data, ( . - private_key_data )\n\t" ".equ private_key_len, ( . - private_key_data )\n\t" ".previous\n\t")
static volatile void * bits
Definition: bitops.h:27
int test_and_clear_bit(unsigned int bit, volatile void *bits)
uint8_t bytes[64]
Definition: ib_mad.h:16
void clear_bit(unsigned int bit, volatile void *bits)