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
16FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
17FILE_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 */
27static inline __attribute__ (( always_inline )) void
28set_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 */
43static inline __attribute__ (( always_inline )) void
44clear_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 */
60static inline __attribute__ (( always_inline )) int
61test_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 */
81static inline __attribute__ (( always_inline )) int
82test_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 */
__asm__ __volatile__("call *%9" :"=a"(result), "=c"(discard_ecx), "=d"(discard_edx) :"d"(0), "a"(code), "b"(0), "c"(in_phys), "D"(0), "S"(out_phys), "m"(hypercall))
unsigned char uint8_t
Definition stdint.h:10
static volatile void * bits
Definition bitops.h:28
int old
Definition bitops.h:65
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
uint8_t bytes[64]
Definition ib_mad.h:5
#define __attribute__(x)
Definition compiler.h:10
static unsigned int unsigned int bit
Definition bigint.h:392
int test_and_clear_bit(unsigned int bit, volatile void *bits)
int test_and_set_bit(unsigned int bit, volatile void *bits)
__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")
#define clear_bit(bit, loc)
Definition vxge_main.h:167
#define set_bit(bit, loc)
Definition vxge_main.h:166