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

#include <allocman/mspace/virtual_pool.h>
#include <allocman/allocman.h>
#include <allocman/util.h>
#include <stdlib.h>
#include <sel4/sel4.h>
#include <sel4utils/mapping.h>
#include <vka/kobject_t.h>
#include <vspace/mapping.h>
#include <string.h>

/* This allocator deliberately does not use the vspace library to manage mappings to prevent
 * circular dependencies between the vspace library and the allocator */

static int _add_page(allocman_t *alloc, seL4_CPtr pd, void *vaddr)
{
    cspacepath_t frame_path;
    seL4_Word frame_cookie;
    int error;
    error = allocman_cspace_alloc(alloc, &frame_path);
    if (error) {
        ZF_LOGV("Failed to allocate slot");
        return error;
    }
    frame_cookie = allocman_utspace_alloc(alloc, seL4_PageBits, seL4_ARCH_4KPage, &frame_path, true, &error);
    if (error) {
        allocman_cspace_free(alloc, &frame_path);
        ZF_LOGV("Failed to allocate frame");
        return error;
    }
    while ((error = seL4_ARCH_Page_Map(frame_path.capPtr, pd, (seL4_Word) vaddr, seL4_AllRights,
                    seL4_ARCH_Default_VMAttributes)) == seL4_FailedLookup) {
        cspacepath_t path;
        error = allocman_cspace_alloc(alloc, &path);
        if (error) {
            ZF_LOGV("Failed to allocate slot");
            break;
        }
        seL4_Word failed_bits = seL4_MappingFailedLookupLevel();
        vspace_map_obj_t obj;
        error = vspace_get_map_obj(failed_bits, &obj);
        assert(error == 0);

        seL4_Word cookie = allocman_utspace_alloc(alloc, obj.size_bits, obj.type, &path, false, &error);
        if (error) {
            allocman_cspace_free(alloc, &path);
            ZF_LOGV("Failed to allocate paging structure");
            break;
        }
        error = vspace_map_obj(&obj, path.capPtr, pd, (seL4_Word) vaddr, seL4_ARCH_Default_VMAttributes);
        if (error != seL4_NoError) {
            allocman_utspace_free(alloc, cookie, seL4_PageTableBits);
            allocman_cspace_free(alloc, &path);
            break;
        }
    }
    if (error != seL4_NoError) {
        allocman_cspace_free(alloc, &frame_path);
        allocman_utspace_free(alloc, frame_cookie, seL4_PageBits);
        return error;
    }
    /* zero the memory in case we were allocated from a device range */
    memset(vaddr, 0, PAGE_SIZE_4K);
    return 0;
}

static k_r_malloc_header_t *_morecore(size_t cookie, mspace_k_r_malloc_t *k_r_malloc, size_t new_units)
{
    size_t new_size;
    k_r_malloc_header_t *new_header;
    mspace_virtual_pool_t *virtual_pool = (mspace_virtual_pool_t*)cookie;
    new_size = new_units * sizeof(k_r_malloc_header_t);

    if (virtual_pool->pool_ptr + new_size > virtual_pool->pool_limit) {
        ZF_LOGV("morecore out of virtual pool");
        return NULL;
    }
    while (virtual_pool->pool_ptr + new_size > virtual_pool->pool_top) {
        int error;
        error = _add_page(virtual_pool->morecore_alloc, virtual_pool->pd, virtual_pool->pool_top);
        if (error) {
            ZF_LOGV("morecore failed to add page");
            return NULL;
        }
        virtual_pool->pool_top += PAGE_SIZE_4K;
    }
    new_header = (k_r_malloc_header_t*)virtual_pool->pool_ptr;
    virtual_pool->pool_ptr += new_size;
    return new_header;
}

void mspace_virtual_pool_create(mspace_virtual_pool_t *virtual_pool, struct mspace_virtual_pool_config config)
{
    virtual_pool->pool_ptr = config.vstart;
    virtual_pool->pool_top = virtual_pool->pool_ptr;
    virtual_pool->pool_limit = config.vstart + config.size;
    virtual_pool->morecore_alloc = NULL;
    virtual_pool->pd = config.pd;
    mspace_k_r_malloc_init(&virtual_pool->k_r_malloc, (size_t)virtual_pool, _morecore);
}

void *_mspace_virtual_pool_alloc(struct allocman *alloc, void *_virtual_pool, size_t bytes, int *error)
{
    void *ret;
    mspace_virtual_pool_t *virtual_pool = (mspace_virtual_pool_t*)_virtual_pool;
    virtual_pool->morecore_alloc = alloc;
    ret = mspace_k_r_malloc_alloc(&virtual_pool->k_r_malloc, bytes);
    virtual_pool->morecore_alloc = NULL;
    SET_ERROR(error, (ret == NULL) ? 1 : 0);
    return ret;
}

void _mspace_virtual_pool_free(struct allocman *alloc, void *_virtual_pool, void *ptr, size_t bytes)
{
    mspace_virtual_pool_t *virtual_pool = (mspace_virtual_pool_t*)_virtual_pool;
    virtual_pool->morecore_alloc = alloc;
    mspace_k_r_malloc_free(&virtual_pool->k_r_malloc, ptr);
    virtual_pool->morecore_alloc = NULL;
}
