Major reworking to integrate cache coloring into the kernel.
[akaros.git] / kern / arch / i386 / types.h
1 #ifndef ROS_INC_TYPES_H
2 #define ROS_INC_TYPES_H
3
4 #define LITTLE_ENDIAN
5
6 #ifndef NULL
7 #define NULL ((void*) 0)
8 #endif
9
10 #ifndef TRUE
11 #define TRUE    1
12 #endif
13
14 #ifndef FALSE
15 #define FALSE   0
16 #endif
17
18 #define CHECK_FLAG(flags,bit)   ((flags) & (1 << (bit)))
19
20 // Represents true-or-false values
21 typedef int bool;
22
23 #define NUM_ADDR_BITS 32
24 #define MAX_VADDR     ((uint64_t)(~0) >> (64-NUM_ADDR_BITS))
25
26 //Constants for byte sizes
27 #define ONE_KILOBYTE  (1L<<10)
28 #define ONE_MEGABYTE  (1L<<20)
29 #define ONE_GIGABYTE  (1L<<30)
30
31 // Explicitly-sized versions of integer types
32 typedef __signed char int8_t;
33 typedef unsigned char uint8_t;
34 typedef short int16_t;
35 typedef unsigned short uint16_t;
36 typedef int int32_t;
37 typedef unsigned int uint32_t;
38 typedef long long int64_t;
39 typedef unsigned long long uint64_t;
40
41 // Pointers and addresses are 32 bits long.
42 // We use pointer types to represent virtual addresses,
43 // uintptr_t to represent the numerical values of virtual addresses,
44 // and physaddr_t to represent physical addresses.
45 typedef int32_t intptr_t;
46 typedef uint32_t uintptr_t;
47 typedef uint32_t physaddr_t;
48
49 // Registers are 32 bits long
50 typedef int32_t intreg_t;
51 typedef uint32_t uintreg_t;
52
53 // Page numbers are 32 bits long.
54 typedef uint32_t ppn_t;
55
56 // size_t is used for memory object sizes.
57 typedef uint32_t size_t;
58 // ssize_t is a signed version of ssize_t, used in case there might be an
59 // error return.
60 typedef int32_t ssize_t;
61
62 // off_t is used for file offsets and lengths.
63 typedef int32_t off_t;
64
65 // Efficient min and max operations
66 #define MIN(_a, _b)                                             \
67 ({                                                              \
68         typeof(_a) __a = (_a);                                  \
69         typeof(_b) __b = (_b);                                  \
70         __a <= __b ? __a : __b;                                 \
71 })
72 #define MAX(_a, _b)                                             \
73 ({                                                              \
74         typeof(_a) __a = (_a);                                  \
75         typeof(_b) __b = (_b);                                  \
76         __a >= __b ? __a : __b;                                 \
77 })
78
79 // Rounding operations (efficient when n is a power of 2)
80 // Round down to the nearest multiple of n
81 #define ROUNDDOWN(a, n)                                         \
82 ({                                                              \
83         uint32_t __a = (uint32_t) (a);                          \
84         (typeof(a)) (__a - __a % (n));                          \
85 })
86 // Round up to the nearest multiple of n
87 #define ROUNDUP(a, n)                                           \
88 ({                                                              \
89         uint32_t __n = (uint32_t) (n);                          \
90         (typeof(a)) (ROUNDDOWN((uint32_t) (a) + __n - 1, __n)); \
91 })
92
93 // Round down to the nearest multiple of n
94 #define PTRROUNDDOWN(a, n)                                              \
95 ({                                                              \
96         char * __a = (char *) (a);                              \
97         (typeof(a)) (__a - (uint32_t)__a % (n));                                \
98 })
99 // Round pointer up to the nearest multiple of n
100 #define PTRROUNDUP(a, n)                                                \
101 ({                                                              \
102         uint32_t __n = (uint32_t) (n);                          \
103         (typeof(a)) (PTRROUNDDOWN((char *) (a) + __n - 1, __n));        \
104 })
105
106 // Return the integer logarithm of the value provided rounded up
107 static inline uint32_t LOG2(uint32_t value)
108 {
109     uint32_t l = 0;
110     while( (value >> l) > 1 ) ++l;
111     return l;
112 }
113
114 // Return the offset of 'member' relative to the beginning of a struct type
115 #ifndef offsetof
116 #define offsetof(type, member)  ((size_t) (&((type*)0)->member))
117 #endif
118
119 // Ivy currently can only handle 63 bits (OCaml thing), so use this to make
120 // a uint64_t programatically
121 #define UINT64(upper, lower) ( (((uint64_t)(upper)) << 32) | (lower) )
122
123 /*********************** Bitmask stuff **********************/
124 #define BYTES_FOR_BITMASK(size) (((size) - 1) / 8 + 1)
125 #define BYTES_FOR_BITMASK_WITH_CHECK(size) ((size) ? ((size) - (1)) / (8) + (1) : (0))
126 #define DECL_BITMASK(name, size) uint8_t (name)[BYTES_FOR_BITMASK((size))]
127
128 #define GET_BITMASK_BIT(name, bit) (((name)[(bit)/8] & (1 << ((bit) % 8))) ? 1 : 0)
129 #define SET_BITMASK_BIT(name, bit) ((name)[(bit)/8] |= (1 << ((bit) % 8)))
130 #define CLR_BITMASK_BIT(name, bit) ((name)[(bit)/8] &= ~(1 << ((bit) % 8)))
131 #define SET_BITMASK_BIT_ATOMIC(name, bit) (atomic_orb(&(name)[(bit)/8], (1 << ((bit) % 8))))
132 #define CLR_BITMASK_BIT_ATOMIC(name, bit) (atomic_andb(&(name)[(bit)/8], ~(1 << ((bit) % 8))))
133
134 #define CLR_BITMASK(name, size) \
135 ({ \
136         {TRUSTEDBLOCK \
137         memset((void*)((uintptr_t)(name)), 0, BYTES_FOR_BITMASK((size))); \
138         } \
139 })
140
141 #define FILL_BITMASK(name, size) \
142 ({ \
143         {TRUSTEDBLOCK \
144         memset((void*)((uintptr_t)(name)), 255, BYTES_FOR_BITMASK((size))); \
145         } \
146         (name)[BYTES_FOR_BITMASK((size))-1] >>= (((size) % 8) ? (8 - ((size) % 8)) : 0 ); \
147 }) 
148
149 #define COPY_BITMASK(newmask, oldmask, size) \
150 ({ \
151         {TRUSTEDBLOCK \
152         memcpy((void*)((uintptr_t)(newmask)), \
153            (void*)((uintptr_t)(oldmask)), \
154            BYTES_FOR_BITMASK((size))); \
155         } \
156 })
157
158 // this checks the entire last byte, so keep it 0 in the other macros
159 #define BITMASK_IS_CLEAR(name, size) ({ \
160         uint32_t __n = BYTES_FOR_BITMASK((size)); \
161         bool clear = 1; \
162         while (__n-- > 0) { \
163                 if ((name)[__n]) { \
164                         clear = 0; \
165                         break;\
166                 }\
167         } \
168         clear; })
169
170 #define PRINT_BITMASK(name, size) { \
171         int i;  \
172         for (i = 0; i < BYTES_FOR_BITMASK(size); i++) { \
173                 int j;  \
174                 for (j = 0; j < 8; j++) \
175                         printk("%x", ((name)[i] >> j) & 1);     \
176         } \
177         printk("\n"); \
178 }
179 /**************************************************************/
180
181 #endif /* !ROS_INC_TYPES_H */