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