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 FILE_SECBOOT ( PERMITTED );
18 
19 #include <stdint.h>
20 
21 /**
22  * Set bit atomically
23  *
24  * @v bit Bit to set
25  * @v bits Bit field
26  */
27 static inline __attribute__ (( always_inline )) void
28 set_bit ( unsigned int bit, volatile void *bits ) {
29  volatile struct {
30  uint8_t byte[ ( bit / 8 ) + 1 ];
31  } *bytes = bits;
32 
33  __asm__ __volatile__ ( "lock btsl %k1, %0"
34  : "+m" ( *bytes ) : "Ir" ( bit ) );
35 }
36 
37 /**
38  * Clear bit atomically
39  *
40  * @v bit Bit to set
41  * @v bits Bit field
42  */
43 static inline __attribute__ (( always_inline )) void
44 clear_bit ( unsigned int bit, volatile void *bits ) {
45  volatile struct {
46  uint8_t byte[ ( bit / 8 ) + 1 ];
47  } *bytes = bits;
48 
49  __asm__ __volatile__ ( "lock btrl %k1, %0"
50  : "+m" ( *bytes ) : "Ir" ( bit ) );
51 }
52 
53 /**
54  * Test and set bit atomically
55  *
56  * @v bit Bit to set
57  * @v bits Bit field
58  * @ret old Old value of bit (zero or non-zero)
59  */
60 static inline __attribute__ (( always_inline )) int
61 test_and_set_bit ( unsigned int bit, volatile void *bits ) {
62  volatile struct {
63  uint8_t byte[ ( bit / 8 ) + 1 ];
64  } *bytes = bits;
65  int old;
66 
67  __asm__ __volatile__ ( "lock btsl %k2, %0\n\t"
68  "sbb %1, %1\n\t"
69  : "+m" ( *bytes ), "=r" ( old )
70  : "Ir" ( bit ) );
71  return old;
72 }
73 
74 /**
75  * Test and clear bit atomically
76  *
77  * @v bit Bit to set
78  * @v bits Bit field
79  * @ret old Old value of bit (zero or non-zero)
80  */
81 static inline __attribute__ (( always_inline )) int
82 test_and_clear_bit ( unsigned int bit, volatile void *bits ) {
83  volatile struct {
84  uint8_t byte[ ( bit / 8 ) + 1 ];
85  } *bytes = bits;
86  int old;
87 
88  __asm__ __volatile__ ( "lock btrl %k2, %0\n\t"
89  "sbb %1, %1\n\t"
90  : "+m" ( *bytes ), "=r" ( old )
91  : "Ir" ( bit ) );
92  return old;
93 }
94 
95 #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))
int old
Definition: bitops.h:65
static unsigned int unsigned int bit
Definition: bigint.h:392
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:28
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
int test_and_clear_bit(unsigned int bit, volatile void *bits)
uint8_t bytes[64]
Definition: ib_mad.h:17
FILE_SECBOOT(PERMITTED)
void clear_bit(unsigned int bit, volatile void *bits)