1/*
2 * Copyright (c) 2007-2011, ETH Zurich.
3 * All rights reserved.
4 *
5 * This file is distributed under the terms in the attached LICENSE file.
6 * If you do not find this file, copies can be found by writing to:
7 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
8 */
9
10#include "helper.h"
11
12#include <skb/skb.h>
13#include <stdio.h>
14#include <stdint.h>
15
16
17/* allocate a single frame, mapping it into our vspace with given attributes */
18void* alloc_map_frame(vregion_flags_t attr, size_t size, struct capref *retcap)
19{
20    struct capref frame;
21    errval_t r;
22
23    r = frame_alloc(&frame, size, NULL);
24    assert(err_is_ok(r));
25    void *va;
26    r = vspace_map_one_frame_attr(&va, size, frame, attr,
27                                  NULL, NULL);
28    if (err_is_fail(r)) {
29        DEBUG_ERR(r, "vspace_map_one_frame failed");
30        return NULL;
31    }
32
33    if (retcap != NULL) {
34        *retcap = frame;
35    }
36
37    return va;
38}
39
40/* Get APIC id for specified core */
41errval_t get_apicid_from_core(coreid_t cid, uint8_t *apicid)
42{
43    static bool connected = false;
44    errval_t err;
45    unsigned int i;
46
47    if (!connected) {
48        err = skb_client_connect();
49        if (err_is_fail(err)) {
50            return err;
51        }
52        connected = true;
53    }
54
55    err = skb_execute_query("corename(%d,_,apic(ApicID)),write(ApicID).",
56                            cid);
57    if (err_is_fail(err)) {
58        return err;
59    }
60    err = skb_read_output("%u.", &i);
61    *apicid = i;
62    return err;
63}
64
65
66/*****************************************************************************/
67/* Bitmap based allocator */
68
69
70/** Init allocator for n objects. */
71bool bmallocator_init(struct bmallocator *alloc, size_t n)
72{
73    alloc->count = n;
74    alloc->bitmap = calloc((n + BMALLOCATOR_BITS - 1) / BMALLOCATOR_BITS,
75                           BMALLOCATOR_BITS / 8);
76    return alloc->bitmap != NULL;
77}
78
79/** Release memory associated with allocator. */
80void bmallocator_destroy(struct bmallocator *alloc)
81{
82    free(alloc->bitmap);
83    alloc->bitmap = NULL;
84}
85
86/** Allocate object, return index in *n if successful (return true). */
87bool bmallocator_alloc(struct bmallocator *alloc, size_t *n)
88{
89    size_t i;
90    BMALLOCATOR_TYPE bit;
91    size_t idx;
92
93    // This could be improved
94    for (i = 0; i < alloc->count; i++) {
95        bit = 1 << (i % BMALLOCATOR_BITS);
96        idx = i / BMALLOCATOR_BITS;
97
98        if (!(alloc->bitmap[idx] & bit)) {
99            alloc->bitmap[idx] |= bit;
100            *n = i;
101            return true;
102        }
103    }
104    return false;
105}
106
107/** Free object n, return value indicates if it was allocated before. */
108bool bmallocator_free(struct bmallocator *alloc, size_t n)
109{
110    bool result;
111    BMALLOCATOR_TYPE bit;
112    size_t idx;
113
114    if (n >= alloc->count) {
115        return false;
116    }
117
118    bit = (1 << (n % BMALLOCATOR_BITS));
119    idx = n / BMALLOCATOR_BITS;
120
121    result = alloc->bitmap[idx] & bit;
122    alloc->bitmap[idx] &= ~bit;
123
124    return result;
125}
126