/*
 * 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 UNUSED 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);
}
