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

#include <autoconf.h>
#include <sel4/types.h>
#include <sel4/sel4.h>
#include <stdio.h>
#include <allocman/allocman.h>
#include <allocman/cspace/simple1level.h>
#include <allocman/mspace/fixed_pool.h>
#include <allocman/utspace/twinkle.h>
#include <allocman/cspace/two_level.h>
#include <allocman/mspace/virtual_pool.h>
#include <allocman/utspace/trickle.h>
#include <allocman/bootstrap.h>
#include <allocman/cspaceops.h>
#include <string.h>
#include <sel4utils/vspace.h>
#include <allocman/vka.h>

#define VIRTUAL_START 0xA0000000

#define MEM_POOL_SIZE (1*1024*1024)

static char initial_mem_pool[MEM_POOL_SIZE];

allocman_t *test_use_current_cspace_bootinfo() {
    int error;
    allocman_t *allocman;
    vspace_alloc_t vspace;
    vka_t *vka;
    allocman = bootstrap_use_bootinfo(seL4_GetBootInfo(), sizeof(initial_mem_pool), initial_mem_pool);
    assert(allocman);
    vka = allocman_mspace_alloc(allocman, sizeof(*vka), &error);
    assert(!error);
    allocman_make_vka(vka, allocman);
    sel4util_get_vspace_alloc_leaky(&vspace, seL4_CapInitThreadPD, vka, seL4_GetBootInfo());

    reservation_t *reservation = vspace_reserve_range_at(&vspace, VIRTUAL_START, MEM_POOL_SIZE, seL4_AllRights, 1);
    assert(reservation);

    bootstrap_configure_virtual_pool(allocman, VIRTUAL_START, MEM_POOL_SIZE, seL4_CapInitThreadPD);
    error = allocman_fill_reserves(allocman);
    assert(!error);
    return allocman;
}

void test_use_current_1level_cspace() {
    int error;
    seL4_CPtr i;
    allocman_t *allocman;
    seL4_BootInfo *bi = seL4_GetBootInfo();
    allocman = bootstrap_use_current_1level(seL4_CapInitThreadCNode, bi->initThreadCNodeSizeBits, bi->empty.start, bi->empty.end, sizeof(initial_mem_pool), initial_mem_pool);
    assert(allocman);
    /* have to add all our resources manually */
    for (i = bi->untyped.start; i < bi->untyped.end; i++) {
        cspacepath_t slot = allocman_cspace_make_path(allocman, i);
        uint32_t size_bits = bi->untypedSizeBitsList[i - bi->untyped.start];
        uint32_t paddr = bi->untypedPaddrList[i - bi->untyped.start];
        error = allocman_utspace_add_uts(allocman, 1, &slot, &size_bits, &paddr);
        assert(!error);
    }
    error = allocman_fill_reserves(allocman);
    assert(!error);
}

void test_use_current_cspace() {
    int error;
    seL4_CPtr i;
    allocman_t *allocman;
    cspace_single_level_t *cspace;
    utspace_trickle_t *utspace;
    seL4_BootInfo *bi = seL4_GetBootInfo();
    allocman = bootstrap_create_allocman(sizeof(initial_mem_pool), initial_mem_pool);
    assert(allocman);
    /* construct a description of our current cspace */
    cspace = allocman_mspace_alloc(allocman, sizeof(*cspace), &error);
    assert(!error);
    error = cspace_single_level_create(allocman, cspace, (struct cspace_single_level_config) {
        .cnode = seL4_CapInitThreadCNode,
        .cnode_size_bits = bi->initThreadCNodeSizeBits,
        .cnode_guard_bits = seL4_WordBits - bi->initThreadCNodeSizeBits,
        .first_slot = bi->empty.start,
        .end_slot = bi->empty.end
    });
    assert(!error);

    error = allocman_attach_cspace(allocman, cspace_single_level_make_interface(cspace));
    assert(!error);

    utspace = allocman_mspace_alloc(allocman, sizeof(*utspace), &error);
    assert(!error);
    error = allocman_attach_utspace(allocman, utspace_trickle_make_interface(utspace));
    assert(!error);

    /* have to add all our resources manually */
    for (i = bi->untyped.start; i < bi->untyped.end; i++) {
        cspacepath_t slot = allocman_cspace_make_path(allocman, i);
        uint32_t size_bits = bi->untypedSizeBitsList[i - bi->untyped.start];
        uint32_t paddr = bi->untypedPaddrList[i - bi->untyped.start];
        error = allocman_utspace_add_uts(allocman, 1, &slot, &size_bits);
        assert(!error);
    }
    error = allocman_fill_reserves(allocman);
    assert(!error);
}

void test_new_1level_cspace_bootinfo() {
    int error;
    allocman_t *allocman;
    cspace_simple1level_t *boot_cspace;
    cspacepath_t new_path;
    allocman = bootstrap_new_1level_bootinfo(seL4_GetBootInfo(), 14, sizeof(initial_mem_pool), initial_mem_pool, &boot_cspace);
    assert(allocman);
    error = allocman_fill_reserves(allocman);
    assert(!error);
    /* test we can easily use our old cspace */
    error = cspace_move_alloc_cptr(allocman, cspace_simple1level_make_interface(boot_cspace), seL4_CapInitThreadTCB, &new_path);
    assert(!error);
    /* drop our priority */
    error = seL4_TCB_SetPriority(new_path.capPtr, new_path.capPtr, 100);
    assert(error == seL4_NoError);
    /* no longer need that boot cspace information */
    allocman_mspace_free(allocman, boot_cspace, sizeof(*boot_cspace));
}

void test_new_1level_cspace() {
    bootstrap_info_t *bootstrap;
    seL4_BootInfo *bi = seL4_GetBootInfo();
    cspace_simple1level_t boot_cspace;
    allocman_t *allocman;
    cspacepath_t oldroot;
    cspacepath_t currentroot;
    cspacepath_t new_path;
    cspacepath_t tcb;
    cspacepath_t pd;
    seL4_CPtr i;
    int error;
    bootstrap = bootstrap_create_info(sizeof(initial_mem_pool), initial_mem_pool);
    assert(bootstrap);
    /* describe the current cspace */
    cspace_simple1level_create(&boot_cspace, (struct cspace_simple1level_config){
        .cnode = seL4_CapInitThreadCNode,
        .cnode_size_bits = bi->initThreadCNodeSizeBits,
        .cnode_guard_bits = seL4_WordBits - bi->initThreadCNodeSizeBits,
        .first_slot = bi->empty.start,
        .end_slot = bi->empty.end - 1
    });
    /* pass to the boot strapper */
    currentroot = _cspace_simple1level_make_path(&boot_cspace, seL4_CapInitThreadCNode);
    bootstrap_set_boot_cspace(bootstrap, cspace_simple1level_make_interface(&boot_cspace), currentroot);
    /* give the untypeds to the bootstrapper */
    for (i = bi->untyped.start; i < bi->untyped.end; i++) {
        cspacepath_t slot = _cspace_simple1level_make_path(&boot_cspace, i);
        uint32_t size_bits = bi->untypedSizeBitsList[i - bi->untyped.start];
        uint32_t paddr = bi->untypedPaddrList[i - bi->untyped.start];
        error = bootstrap_add_untypeds(bootstrap, 1, &slot, &size_bits, &paddr);
        assert(!error);
    }
    /* bootstrapper has enough information to create */
    tcb = _cspace_simple1level_make_path(&boot_cspace, seL4_CapInitThreadTCB);
    pd = _cspace_simple1level_make_path(&boot_cspace, seL4_CapInitThreadPD);
    allocman = bootstrap_new_1level(bootstrap, 14, tcb, pd, &oldroot);
    assert(allocman);
    /* take advantage of knowledge of simple1level cspace and just shift its root :) */
    assert(oldroot.capDepth == 32);
    boot_cspace.config.cnode = oldroot.capPtr;
    /* now test we can use it */
    error = cspace_move_alloc_cptr(allocman, cspace_simple1level_make_interface(&boot_cspace), seL4_CapInitThreadTCB, &new_path);
    assert(!error);
    /* drop our priority */
    error = seL4_TCB_SetPriority(new_path.capPtr, new_path.capPtr, 100);
    assert(error == seL4_NoError);
}

void test_new_2level_cspace_bootinfo() {
    int error;
    allocman_t *allocman;
    cspace_simple1level_t *boot_cspace;
    cspacepath_t new_path;
    allocman = bootstrap_new_2level_bootinfo(seL4_GetBootInfo(), 6,10, sizeof(initial_mem_pool), initial_mem_pool, &boot_cspace);
    assert(allocman);
    error = allocman_fill_reserves(allocman);
    assert(!error);
    /* test we can easily use our old cspace */
    error = cspace_move_alloc_cptr(allocman, cspace_simple1level_make_interface(boot_cspace), seL4_CapInitThreadTCB, &new_path);
    assert(!error);
    /* drop our priority */
    error = seL4_TCB_SetPriority(new_path.capPtr, new_path.capPtr, 100);
    assert(error == seL4_NoError);
    /* no longer need that boot cspace information */
    allocman_mspace_free(allocman, boot_cspace, sizeof(*boot_cspace));
}

void test_new_2level_cspace() {
    bootstrap_info_t *bootstrap;
    seL4_BootInfo *bi = seL4_GetBootInfo();
    cspace_simple1level_t boot_cspace;
    allocman_t *allocman;
    cspacepath_t oldroot;
    cspacepath_t currentroot;
    cspacepath_t new_path;
    cspacepath_t tcb;
    cspacepath_t pd;
    seL4_CPtr i;
    int error;
    bootstrap = bootstrap_create_info(sizeof(initial_mem_pool), initial_mem_pool);
    assert(bootstrap);
    /* describe the current cspace */
    cspace_simple1level_create(&boot_cspace, (struct cspace_simple1level_config){
        .cnode = seL4_CapInitThreadCNode,
        .cnode_size_bits = bi->initThreadCNodeSizeBits,
        .cnode_guard_bits = seL4_WordBits - bi->initThreadCNodeSizeBits,
        .first_slot = bi->empty.start,
        .end_slot = bi->empty.end - 1
    });
    /* pass to the boot strapper */
    currentroot = _cspace_simple1level_make_path(&boot_cspace, seL4_CapInitThreadCNode);
    bootstrap_set_boot_cspace(bootstrap, cspace_simple1level_make_interface(&boot_cspace), currentroot);
    /* give the untypeds to the bootstrapper */
    for (i = bi->untyped.start; i < bi->untyped.end; i++) {
        cspacepath_t slot = _cspace_simple1level_make_path(&boot_cspace, i);
        uint32_t size_bits = bi->untypedSizeBitsList[i - bi->untyped.start];
        uint32_t paddr = bi->untypedPaddrList[i - bi->untyped.start];
        error = bootstrap_add_untypeds(bootstrap, 1, &slot, &size_bits, &paddr);
        assert(!error);
    }
    /* bootstrapper has enough information to create */
    tcb = _cspace_simple1level_make_path(&boot_cspace, seL4_CapInitThreadTCB);
    pd = _cspace_simple1level_make_path(&boot_cspace, seL4_CapInitThreadPD);
    allocman = bootstrap_new_2level(bootstrap, 6, 10, tcb, pd, &oldroot);
    assert(allocman);
    /* take advantage of knowledge of simple1level cspace and just shift its root :) */
    assert(oldroot.capDepth == 32);
    boot_cspace.config.cnode = oldroot.capPtr;
    /* now test we can use it */
    error = cspace_move_alloc_cptr(allocman, cspace_simple1level_make_interface(&boot_cspace), seL4_CapInitThreadTCB, &new_path);
    assert(!error);
    /* drop our priority */
    error = seL4_TCB_SetPriority(new_path.capPtr, new_path.capPtr, 100);
    assert(error == seL4_NoError);
}

int main(void) {
    allocman_t *alloc;
    alloc = test_use_current_cspace_bootinfo();
//    test_use_current_1level_cspace();
//    test_use_current_cspace();
//    test_new_1level_cspace_bootinfo();
//    test_new_1level_cspace();
//    test_new_2level_cspace_bootinfo();
//    test_new_2level_cspace();
    printf("All is well in the universe.\n");
    while(1);
}
