/*
 * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include <autoconf.h>
#include <allocman/utspace/twinkle.h>
#include <allocman/allocman.h>
#include <allocman/util.h>
#include <sel4/sel4.h>
#include <vka/object.h>
#include <string.h>

static inline size_t _round_up(size_t v, size_t bits)
{
    size_t mask = MASK(bits);
    if ((v & mask) != 0) {
        v = (v & ~mask) + BIT(bits);
    }
    return v;
}

void utspace_twinkle_create(utspace_twinkle_t *twinkle)
{
    twinkle->num_uts = 0;
    twinkle->uts = NULL;
}

int _utspace_twinkle_add_uts(allocman_t *alloc, void *_twinkle, size_t num, const cspacepath_t *uts, size_t *size_bits,
                             uintptr_t *paddr, int utType)
{
    utspace_twinkle_t *twinkle = (utspace_twinkle_t *) _twinkle;
    struct utspace_twinkle_ut *new_uts;
    int error;
    size_t i;
    if (utType != ALLOCMAN_UT_KERNEL) {
        ZF_LOGE("Twinkle does not support device untypeds");
        return -1;
    }
    new_uts = allocman_mspace_alloc(alloc, sizeof(struct utspace_twinkle_ut) * (num + twinkle->num_uts), &error);
    if (error) {
        return error;
    }
    if (twinkle->uts) {
        memcpy(new_uts, twinkle->uts, sizeof(struct utspace_twinkle_ut) * twinkle->num_uts);
        allocman_mspace_free(alloc, twinkle->uts, sizeof(struct utspace_twinkle_ut) * twinkle->num_uts);
    }
    for (i = 0; i < num; i++, twinkle->num_uts++) {
        new_uts[twinkle->num_uts] = (struct utspace_twinkle_ut) {
            uts[i], 0, size_bits[i]
        };
    }
    twinkle->uts = new_uts;
    return 0;
}

seL4_Word _utspace_twinkle_alloc(allocman_t *alloc, void *_twinkle, size_t size_bits, seL4_Word type,
                                 const cspacepath_t *slot, uintptr_t paddr, bool canBeDev, int *error)
{
    utspace_twinkle_t *twinkle = (utspace_twinkle_t *)_twinkle;
    size_t sel4_size_bits;
    int sel4_error;
    size_t i, j;
    if (paddr != ALLOCMAN_NO_PADDR) {
        ZF_LOGE("Twinkle does not support allocating explicit physical addresses");
        return -1;
    }
    /* get size of untyped call */
    sel4_size_bits = get_sel4_object_size(type, size_bits);
    if (size_bits != vka_get_object_size(type, sel4_size_bits) || size_bits == 0) {
        SET_ERROR(error, 1);
        return 0;
    }
    /* Search for the first thing that will support us */
    for (i = 0; i < twinkle->num_uts; i++) {
        if (_round_up(twinkle->uts[i].offset, size_bits) + BIT(size_bits) <= BIT(twinkle->uts[i].size_bits)) {
            break;
        }
    }
    if (i == twinkle->num_uts) {
        SET_ERROR(error, 1);
        return 0;
    }
    /* Check all untypeds of this size, and pick the one that will waste the least space */
    for (j = i; j < twinkle->num_uts && twinkle->uts[i].size_bits == twinkle->uts[j].size_bits; j++) {
        if ((_round_up(twinkle->uts[j].offset, size_bits) + BIT(size_bits) <= BIT(twinkle->uts[j].size_bits)) &&
            (_round_up(twinkle->uts[j].offset, size_bits) - twinkle->uts[j].offset <
             _round_up(twinkle->uts[i].offset, size_bits) - twinkle->uts[i].offset)) {
            i = j;
        }
    }
    /* if using inc retype then our offset calculation is effectively emulating the kernels calculations. This
     * means we track the free space of the untyped correctly, and since we are not going to try and free then
     * allocate again, this allocator can be used with either allocation scheme */
    sel4_error = seL4_Untyped_Retype(twinkle->uts[i].path.capPtr, type, sel4_size_bits, slot->root, slot->dest,
                                     slot->destDepth, slot->offset, 1);
    if (sel4_error != seL4_NoError) {
        /* Well this shouldn't happen */
        SET_ERROR(error, 1);
        return 0;
    }

    /* Update allocation information */
    twinkle->uts[i].offset = _round_up(twinkle->uts[i].offset, size_bits) + BIT(size_bits);

    /* We do not support free so we return an empty cookie */
    SET_ERROR(error, 0);
    return 0;
}

void _utspace_twinkle_free(allocman_t *alloc, void *_twinkle, seL4_Word cookie, size_t size_bits)
{
    /* Do nothing */
}
