/*
 * Copyright 2014, NICTA
 *
 * 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(NICTA_BSD)
 */

#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>

/* This allocator deliberately does not use the vspace library 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) {
        return error;
    }
    frame_cookie = allocman_utspace_alloc(alloc, 12, seL4_ARCH_4KPage, &frame_path, &error);
    if (error) {
        allocman_cspace_free(alloc, &frame_path);
        return error;
    }
    error = seL4_ARCH_Page_Map(frame_path.capPtr, pd, (seL4_Word) vaddr, seL4_AllRights,
                seL4_ARCH_Default_VMAttributes);
    if (error == seL4_FailedLookup) {
        cspacepath_t pt_path;
        seL4_Word pt_cookie;
        error = allocman_cspace_alloc(alloc, &pt_path);
        if (error) {
            allocman_cspace_free(alloc, &frame_path);
            allocman_utspace_free(alloc, frame_cookie, 12);
            return error;
        }
        pt_cookie = allocman_utspace_alloc(alloc, seL4_PageTableBits, kobject_get_type(KOBJECT_PAGE_TABLE, 0), &pt_path, &error);
        if (error) {
            allocman_cspace_free(alloc, &frame_path);
            allocman_utspace_free(alloc, frame_cookie, 12);
            allocman_cspace_free(alloc, &pt_path);
            return error;
        }
        error = seL4_ARCH_PageTable_Map(pt_path.capPtr, pd, (seL4_Word) vaddr,
                    seL4_ARCH_Default_VMAttributes);
        if (error != seL4_NoError) {
            allocman_cspace_free(alloc, &frame_path);
            allocman_utspace_free(alloc, frame_cookie, 12);
            allocman_cspace_free(alloc, &pt_path);
            allocman_utspace_free(alloc, pt_cookie, seL4_PageTableBits);
            return error;
        }
        error = seL4_ARCH_Page_Map(frame_path.capPtr, pd, (seL4_Word) vaddr, seL4_AllRights,
                    seL4_ARCH_Default_VMAttributes);
        if (error != seL4_NoError) {
            allocman_cspace_free(alloc, &frame_path);
            allocman_utspace_free(alloc, frame_cookie, 12);
            allocman_cspace_free(alloc, &pt_path);
            allocman_utspace_free(alloc, pt_cookie, seL4_PageTableBits);
            return error;
        }
    } else if (error != seL4_NoError) {
        allocman_cspace_free(alloc, &frame_path);
        allocman_utspace_free(alloc, frame_cookie, 12);
        return error;
    }
    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) {
        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) {
            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;
}
