Changed magic number from 0xE5 to I_VMMPC_POSTED
[akaros.git] / kern / arch / x86 / bitmask.h
1 #ifndef ROS_ARCH_BITMASK_H
2 #define ROS_ARCH_BITMASK_H
3
4 #include <string.h>
5 #include <sys/types.h>
6 #include <atomic.h>
7 #include <stdio.h>
8
9 #define DECL_BITMASK(name, size) \
10         uint8_t (name)[BYTES_FOR_BITMASK((size))]
11
12 #define BYTES_FOR_BITMASK(size) \
13         (((size) - 1) / 8 + 1)
14
15 #define BYTES_FOR_BITMASK_WITH_CHECK(size) \
16         ((size) ? ((size) - (1)) / (8) + (1) : (0))
17
18 static bool GET_BITMASK_BIT(uint8_t* name, size_t bit) 
19 {
20         return (((name)[(bit)/8] & (1 << ((bit) % 8))) ? 1 : 0);
21 }
22
23 #define SET_BITMASK_BIT(name, bit) \
24         ((name)[(bit)/8] |= (1 << ((bit) % 8)));
25 /*
26 static void SET_BITMASK_BIT(uint8_t* name, size_t bit)
27 {
28         ((name)[(bit)/8] |= (1 << ((bit) % 8)));
29 }
30 */
31
32 #define CLR_BITMASK_BIT(name, bit) \
33         ((name)[(bit)/8] &= ~(1 << ((bit) % 8)));
34 /*
35 static void CLR_BITMASK_BIT(uint8_t* name, size_t bit) 
36 {
37         ((name)[(bit)/8] &= ~(1 << ((bit) % 8)));
38 }
39 */
40
41 static void SET_BITMASK_BIT_ATOMIC(uint8_t* name, size_t bit) 
42 {
43         (atomic_orb(&(name)[(bit)/8], (1 << ((bit) % 8))));
44 }
45
46 #define CLR_BITMASK_BIT_ATOMIC(name, bit) \
47         (atomic_andb(&(name)[(bit)/8], ~(1 << ((bit) % 8))))
48
49 #define CLR_BITMASK(name, size) \
50 ({ \
51         memset((void*)((uintptr_t)(name)), 0, BYTES_FOR_BITMASK((size))); \
52 })
53
54 #define FILL_BITMASK(name, size) \
55 ({ \
56         memset((void*)((uintptr_t)(name)), 255, BYTES_FOR_BITMASK((size))); \
57         (name)[BYTES_FOR_BITMASK((size))-1] >>= (((size) % 8) ? (8 - ((size) % 8)) : 0 ); \
58 }) 
59
60 #define COPY_BITMASK(newmask, oldmask, size) \
61 ({ \
62         memcpy((void*)((uintptr_t)(newmask)), \
63            (void*)((uintptr_t)(oldmask)), \
64            BYTES_FOR_BITMASK((size))); \
65 })
66
67 // this checks the entire last byte, so keep it 0 in the other macros
68 #define BITMASK_IS_CLEAR(name, size) ({ \
69         uint32_t __n = BYTES_FOR_BITMASK((size)); \
70         bool clear = 1; \
71         while (__n-- > 0) { \
72                 if ((name)[__n]) { \
73                         clear = 0; \
74                         break;\
75                 }\
76         } \
77         clear; })
78
79 static inline bool BITMASK_IS_FULL(volatile uint8_t *map, size_t size)
80 {
81         int _size = size;
82         for (int i = 0; i < BYTES_FOR_BITMASK(size); i++) {
83                 for (int j = 0; j < MIN(8,_size); j++)
84                         if(!((map[i] >> j) &1))
85                                 return FALSE;
86                         _size--;
87         }
88         return TRUE;
89 }
90
91 #define PRINT_BITMASK(name, size) { \
92         int i;  \
93         int _size = size; \
94         for (i = 0; i < BYTES_FOR_BITMASK(size); i++) { \
95                 int j;  \
96                 for (j = 0; j < MIN(8,_size); j++) \
97                         printk("%x", ((name)[i] >> j) & 1);     \
98                         _size--; \
99         } \
100         printk("\n"); \
101 }
102
103 #endif /* ROS_ARCH_BITMASK_H */