/*
 * Copyright 2017, Data61
 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
 * ABN 41 687 119 230.
 *
 * This software may be distributed and modified according to the terms of
 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
 * See "LICENSE_BSD2.txt" for details.
 *
 * @TAG(DATA61_BSD)
 */

#include <allocman/cspace/two_level.h>
#include <allocman/util.h>
#include <allocman/allocman.h>
#include <sel4/sel4.h>
#include <string.h>
#include <utils/attribute.h>

cspacepath_t _cspace_two_level_make_path(void *_cspace, seL4_CPtr slot)
{
    cspacepath_t l1_path, l2_path;
    size_t l1slot, l2slot;
    cspace_two_level_t *cspace = (cspace_two_level_t*)_cspace;
    l1slot = slot >> cspace->config.level_two_bits;
    l2slot = slot & MASK(cspace->config.level_two_bits);
    /* This is an excessive way of constructing the path. But it's cool to do it in a way that
       makes no assumptions about the underlying cspace structures. In particular the second level
       could be a two level cspace and this would still work */
    if(!cspace->second_levels[l1slot]) {
        assert(!"ERROR: Tried make a path to a non existant slot\n");
        return (cspacepath_t) {0, 0, 0, 0, 0, 0, 0};
    }
    l1_path = _cspace_single_level_make_path(&cspace->first_level, l1slot);
    l2_path =_cspace_single_level_make_path(&cspace->second_levels[l1slot]->second_level, l2slot);
    return (cspacepath_t) {
        .root = l1_path.root,
        .capPtr = (l1_path.capPtr << l2_path.capDepth) | l2_path.capPtr,
        .capDepth = l1_path.capDepth + l2_path.capDepth,
        .dest = (l1_path.capPtr << l2_path.destDepth) | l2_path.dest,
        .destDepth = l1_path.capDepth + l2_path.destDepth,
        .offset = l2_path.offset
    };
    /* This is the simpler version */
    /* path->root = cspace->config.cnode;
    path->slot = slot;
    path->slot_depth = cspace->config.cnode_size_bits + cspace->config.cnode_guard_bits + cspace->config.level_two_bits;
    path->cnode = l1slot;
    path->cnode_depth = cspace->config.cnode_size_bits + cspace->config.cnode_guard_bits;
    path->cnode_offset = l2slot;*/
}

static int _create_second_level(allocman_t *alloc, cspace_two_level_t *cspace, size_t index, int alloc_node)
{
    int error;
    struct cspace_single_level_config single_config = {
        /* There is no cap at depth 32 to reference the cnode of this cspace, fortunately
           though we don't actually need it */
        .cnode = 0,
        .cnode_size_bits = cspace->config.level_two_bits,
        .cnode_guard_bits = 0,
        .first_slot = 0,
        .end_slot = BIT(cspace->config.level_two_bits)
    };
    cspace->second_levels[index] = (struct cspace_two_level_node*) allocman_mspace_alloc(alloc, sizeof(struct cspace_two_level_node), &error);
    if (error) {
        return error;
    }
    if (alloc_node) {
        cspacepath_t path = _cspace_single_level_make_path(&cspace->first_level, index);
        cspace->second_levels[index]->cookie = allocman_utspace_alloc(alloc, cspace->config.level_two_bits + seL4_SlotBits, seL4_CapTableObject, &path, false, &error);
        cspace->second_levels[index]->cookie_valid = 1;
    } else {
        cspace->second_levels[index]->cookie_valid = 0;
    }
    if (error) {
        allocman_mspace_free(alloc, cspace->second_levels[index], sizeof(struct cspace_two_level_node));
        cspace->second_levels[index] = NULL;
        return error;
    }
    error = cspace_single_level_create(alloc, &cspace->second_levels[index]->second_level, single_config);
    if (error) {
        allocman_utspace_free(alloc, cspace->second_levels[index]->cookie, cspace->config.level_two_bits + seL4_SlotBits);
        allocman_mspace_free(alloc, cspace->second_levels[index], sizeof(struct cspace_two_level_node));
        cspace->second_levels[index] = NULL;
        return error;
    }
    cspace->second_levels[index]->count = 0;
    return 0;
}

int cspace_two_level_create(allocman_t *alloc, cspace_two_level_t *cspace, struct cspace_two_level_config config)
{
    int error;
    size_t i;
    struct cspace_single_level_config single_config = {
        .cnode = config.cnode,
        .cnode_size_bits = config.cnode_size_bits,
        .cnode_guard_bits = config.cnode_guard_bits,
        .first_slot = config.first_slot,
        .end_slot = config.end_slot
    };
    cspace->config = config;
    cspace->second_levels = (struct cspace_two_level_node **)allocman_mspace_alloc(alloc, sizeof(struct cspace_two_level_node*) * BIT(config.cnode_size_bits), &error);
    if (error) {
        return error;
    }
    error = cspace_single_level_create(alloc, &cspace->first_level, single_config);
    if (error) {
        allocman_mspace_free(alloc, cspace->second_levels, sizeof(struct cspace_two_level_node*) * BIT(config.cnode_size_bits));
        return error;
    }
    for (i = 0; i < BIT(config.cnode_size_bits); i++) {
        cspace->second_levels[i] = NULL;
    }
    cspace->last_second_level = 0;
    for (i = config.start_existing_index; i < config.end_existing_index; i++) {
        error = _cspace_single_level_alloc_at(alloc, &cspace->first_level, (seL4_CPtr) i);
        if (error) {
            cspace_two_level_destroy(alloc, cspace);
            return error;
        }
        error = _create_second_level(alloc, cspace, i, 0);
        if (error) {
            cspace_two_level_destroy(alloc, cspace);
            return error;
        }
    }
    /* now fill in any slots that may already be allocated */
    for (i = config.start_existing_slot; i < config.end_existing_slot; i++) {
        error = _cspace_two_level_alloc_at(alloc, cspace, (seL4_CPtr) i);
        if (error) {
            cspace_two_level_destroy(alloc, cspace);
            return error;
        }
    }
    return 0;
}

int _cspace_two_level_alloc_at(allocman_t *alloc, void *_cspace, seL4_CPtr slot) {
    cspace_two_level_t *cspace = (cspace_two_level_t*)_cspace;
    size_t l1slot;
    size_t l2slot;
    int error;
    l1slot = slot >> cspace->config.level_two_bits;
    l2slot = slot & MASK(cspace->config.level_two_bits);
    /* see if the first level exists */
    if (!cspace->second_levels[l1slot]) {
        error = _cspace_single_level_alloc_at(alloc, &cspace->first_level, l1slot);
        if(error) {
            return error;
        }
        error = _create_second_level(alloc, cspace, l1slot, 1);
        if (error) {
            return error;
        }
    }
    /* now try and allocate from the second level */
    error = _cspace_single_level_alloc_at(alloc, &cspace->second_levels[l1slot]->second_level, (seL4_CPtr) l2slot);
    if (error) {
        return error;
    }
    cspace->second_levels[l1slot]->count++;
    return 0;
}

int _cspace_two_level_alloc(allocman_t *alloc, void *_cspace, cspacepath_t *slot)
{
    cspace_two_level_t *cspace = (cspace_two_level_t*)_cspace;
    size_t i;
    int found;
    int first;
    int error;
    cspacepath_t level2_slot;
    /* Hunt for a slot */
    i = cspace->last_second_level;
    found = 0;
    first = 1;
    while (!found && (first || i != cspace->last_second_level)) {
        first = 0;
        if (cspace->second_levels[i] && cspace->second_levels[i]->count < MASK(cspace->config.level_two_bits)) {
            found = 1;
        } else {
            i = (i + 1) % BIT(cspace->config.cnode_size_bits);
        }
    }
    if (!found) {
        /* ask the first level node for an empty slot */
        cspacepath_t l1slot;
        error = _cspace_single_level_alloc(alloc, &cspace->first_level, &l1slot);
        if (error) {
            /* our cspace is just full */
            return error;
        }
        /* use this index */
        error = _create_second_level(alloc, cspace, l1slot.offset, 1);
        if (error) {
            return error;
        }
    }
    cspace->last_second_level = i;
    error = _cspace_single_level_alloc(alloc, &cspace->second_levels[i]->second_level, &level2_slot);
    if (error) {
        /* This just shouldn't be possible */
        assert(!"cspace_single_level not behaving as expected");
        return error;
    }
    cspace->second_levels[i]->count++;
    *slot = _cspace_two_level_make_path(cspace, (i << cspace->config.level_two_bits) | level2_slot.capPtr);
    return 0;
}

static void _destroy_second_level(allocman_t *alloc, cspace_two_level_t *cspace, size_t index)
{
    cspacepath_t path;
    cspace_single_level_destroy(alloc, &cspace->second_levels[index]->second_level);
    if (cspace->second_levels[index]->cookie_valid) {
        int error = seL4_CNode_Delete(cspace->config.cnode, index,
                                      seL4_WordBits - cspace->config.level_two_bits);
        assert(error == seL4_NoError);
        allocman_utspace_free(alloc, cspace->second_levels[index]->cookie, cspace->config.level_two_bits + seL4_SlotBits);
    }
    allocman_mspace_free(alloc, cspace->second_levels[index], sizeof(struct cspace_two_level_node));
    path = _cspace_single_level_make_path(&cspace->first_level, index);
    _cspace_single_level_free(alloc, &cspace->first_level, &path);
}

void _cspace_two_level_free(struct allocman *alloc, void *_cspace, const cspacepath_t *slot)
{
    size_t l1slot;
    size_t l2slot;
    seL4_CPtr cptr = slot->capPtr;
    cspacepath_t path;
    cspace_two_level_t *cspace = (cspace_two_level_t*)_cspace;
    l1slot = cptr >> cspace->config.level_two_bits;
    l2slot = cptr & MASK(cspace->config.level_two_bits);
    path = _cspace_single_level_make_path(&cspace->second_levels[l1slot]->second_level, l2slot);
    _cspace_single_level_free(alloc, &cspace->second_levels[l1slot]->second_level, &path);
    cspace->second_levels[l1slot]->count--;
    if (cspace->second_levels[l1slot]->count == 0) {
        _destroy_second_level(alloc, cspace, l1slot);
        cspace->second_levels[l1slot] = NULL;
    }
}

void cspace_two_level_destroy(struct allocman *alloc, cspace_two_level_t *cspace)
{
    size_t i;
    for (i = 0; i < BIT(cspace->config.cnode_size_bits); i++) {
        if (cspace->second_levels[i]) {
            _destroy_second_level(alloc, cspace, i);
        }
    }
    allocman_mspace_free(alloc, cspace->second_levels, sizeof(struct cspace_two_level_node*) * BIT(cspace->config.cnode_size_bits));
    cspace_single_level_destroy(alloc, &cspace->first_level);
}
