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