x86: vmm: Use a separate vector for posted IRQs
[akaros.git] / kern / lib / address_range.c
1 /* Copyright (c) 2015 Google Inc
2  * Davide Libenzi <dlibenzi@google.com>
3  * See LICENSE for details.
4  */
5
6 #include <ros/errno.h>
7 #include <sys/types.h>
8 #include <stdio.h>
9 #include <sort.h>
10 #include <address_range.h>
11
12 static int address_range_cmp(const void *f1, const void *f2)
13 {
14         return ((const struct address_range *) f1)->start <
15                 ((const struct address_range *) f2)->start ? -1 : 1;
16 }
17
18 int address_range_validate(const struct address_range *ars, size_t count)
19 {
20         for (size_t i = 0; i < count; i++) {
21                 if (ars[i].start > ars[i].end)
22                         return -EINVAL;
23                 if ((i > 0) && (ars[i - 1].end >= ars[i].start))
24                         return -EINVAL;
25         }
26
27         return 0;
28 }
29
30 int address_range_init(struct address_range *ars, size_t count)
31 {
32         sort(ars, count, sizeof(*ars), address_range_cmp);
33
34         return address_range_validate(ars, count);
35 }
36
37 const struct address_range *address_range_find(const struct address_range *ars,
38                                                                                            size_t count, uintptr_t addr)
39 {
40         ssize_t l = 0, r = count - 1;
41
42         while (l <= r) {
43                 ssize_t x = l + (r - l) / 2;
44                 const struct address_range *car = ars + x;
45
46                 if (car->end < addr)
47                         l = x + 1;
48                 else if (car->start > addr)
49                         r = x - 1;
50                 else
51                         return car;
52         }
53
54         return NULL;
55 }