1/**
2 * \file
3 * \brief IREF allocation/management
4 */
5
6/*
7 * Copyright (c) 2007, 2008, 2010, ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#include "monitor.h"
16
17struct iref_service {
18    struct monitor_binding *binding;
19    uintptr_t service_id;
20};
21
22#define MAX_IREF_PERCORE 256
23static struct iref_service iref_table[MAX_IREF_PERCORE];
24
25/**
26 * \brief Allocate a new iref
27 *
28 * Associate it with the server's connection and service id.
29 */
30errval_t iref_alloc(struct monitor_binding *binding, uintptr_t service_id,
31                    iref_t *iref)
32{
33    assert(binding != NULL);
34
35    // find a free slot in the local table
36    for (iref_t i = 0; i < MAX_IREF_PERCORE; i++) {
37        if (iref_table[i].binding == NULL) {
38            iref_table[i].binding = binding;
39            iref_table[i].service_id = service_id;
40            // XXX: avoid zero being a valid iref
41            *iref = MAX_IREF_PERCORE * my_core_id + i + 1;
42            return SYS_ERR_OK;
43        }
44    }
45
46    return MON_ERR_IREF_ALLOC;
47}
48
49/**
50 * \brief Return core_id
51 *
52 * The core_id is stored in the iref itself.
53 */
54errval_t iref_get_core_id(iref_t iref, coreid_t *core_id)
55{
56    *core_id = (iref - 1) / MAX_IREF_PERCORE;
57    return SYS_ERR_OK;
58}
59
60/**
61 * \brief Return conn
62 */
63errval_t iref_get_binding(iref_t iref, struct monitor_binding **binding)
64{
65    if ((iref - 1) / MAX_IREF_PERCORE != my_core_id) {
66        return MON_ERR_INVALID_CORE_ID;
67    }
68
69    *binding = iref_table[(iref - 1) % MAX_IREF_PERCORE].binding;
70    if (*binding == NULL) {
71        return MON_ERR_INVALID_IREF;
72    } else {
73        return SYS_ERR_OK;
74    }
75}
76
77/**
78 * \brief Return service_id
79 */
80errval_t iref_get_service_id(iref_t iref, uintptr_t *service_id)
81{
82    if ((iref - 1) / MAX_IREF_PERCORE != my_core_id) {
83        return MON_ERR_INVALID_CORE_ID;
84    }
85
86    *service_id = iref_table[(iref - 1) % MAX_IREF_PERCORE].service_id;
87    return SYS_ERR_OK;
88}
89