/*
 * 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 GNU General Public License version 2. Note that NO WARRANTY is provided.
 * See "LICENSE_GPLv2.txt" for details.
 *
 * @TAG(DATA61_GPL)
 */

/* Initialization functions related to the seL4 side of vmm
 * booting and management. */

#include <autoconf.h>
#include <sel4vmm/gen_config.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <sel4/sel4.h>
#include <simple/simple.h>
#include <vka/capops.h>

#include "vmm/platform/boot.h"
#include "vmm/platform/guest_vspace.h"
#include "vmm/processor/apicdef.h"
#include "vmm/processor/lapic.h"

int vmm_init(vmm_t *vmm, allocman_t *allocman, simple_t simple, vka_t vka, vspace_t vspace,
             platform_callbacks_t callbacks)
{
    int err;
    memset(vmm, 0, sizeof(vmm_t));
    vmm->allocman = allocman;
    vmm->vka = vka;
    vmm->host_simple = simple;
    vmm->host_vspace = vspace;
    vmm->plat_callbacks = callbacks;
    vmm->tcb = simple_get_tcb(&simple);
    vmm->sc = simple_get_sc(&simple);
    vmm->sched_ctrl = simple_get_sched_ctrl(&simple, 0);
    // Currently set this to 4k pages by default
    vmm->page_size = seL4_PageBits;
    err = vmm_pci_init(&vmm->pci);
    if (err) {
        return err;
    }
    err = vmm_io_port_init(&vmm->io_port);
    if (err) {
        return err;
    }
    err = vmm_mmio_init(&vmm->mmio_list);
    if (err) {
        return err;
    }

    vmm->vmcall_handlers = NULL;
    vmm->vmcall_num_handlers = 0;

    return 0;
}

int vmm_init_host(vmm_t *vmm)
{
    vmm->done_host_init = 1;
    return 0;
}

static int vmm_init_vcpu(vmm_t *vmm, unsigned int vcpu_num, int priority)
{
    int UNUSED error;
    assert(vcpu_num < vmm->num_vcpus);
    vmm_vcpu_t *vcpu = &vmm->vcpus[vcpu_num];

    /* sel4 vcpu (vmcs) */
    vcpu->guest_vcpu = vka_alloc_vcpu_leaky(&vmm->vka);
    if (vcpu->guest_vcpu == 0) {
        return -1;
    }

    /* bind the VCPU to the VMM thread */
    error = seL4_X86_VCPU_SetTCB(vcpu->guest_vcpu, vmm->tcb);
    assert(error == seL4_NoError);

    vcpu->vmm = vmm;
    vcpu->vcpu_id = vcpu_num;

    /* All LAPICs are created enabled, in virtual wire mode */
    vmm_create_lapic(vcpu, 1);

    return 0;
}

int vmm_init_guest(vmm_t *vmm, int priority)
{
    return vmm_init_guest_multi(vmm, priority, 1);
}

int vmm_init_guest_multi(vmm_t *vmm, int priority, int num_vcpus)
{
    int error;

    assert(vmm->done_host_init);

    vmm->num_vcpus = num_vcpus;
    vmm->vcpus = malloc(num_vcpus * sizeof(vmm_vcpu_t));
    if (!vmm->vcpus) {
        return -1;
    }

    /* Create an EPT which is the pd for all the vcpu tcbs */
    vmm->guest_pd = vka_alloc_ept_pml4_leaky(&vmm->vka);
    if (vmm->guest_pd == 0) {
        return -1;
    }
    /* Assign an ASID */
    error = simple_ASIDPool_assign(&vmm->host_simple, vmm->guest_pd);
    if (error != seL4_NoError) {
        ZF_LOGE("Failed to assign ASID pool to EPT root");
        return -1;
    }
    /* Install the guest PD */
    error = seL4_TCB_SetEPTRoot(vmm->tcb, vmm->guest_pd);
    assert(error == seL4_NoError);
    /* Initialize a vspace for the guest */
    error = vmm_get_guest_vspace(&vmm->host_vspace, &vmm->host_vspace,
                                 &vmm->guest_mem.vspace, &vmm->vka, vmm->guest_pd);
    if (error) {
        return error;
    }

    for (int i = 0; i < num_vcpus; i++) {
        vmm_init_vcpu(vmm, i, priority);
    }

    /* Init guest memory information.
     * TODO: should probably done elsewhere */
    vmm->guest_mem.num_ram_regions = 0;
    vmm->guest_mem.ram_regions = malloc(0);

    vmm_mmio_add_handler(&vmm->mmio_list, APIC_DEFAULT_PHYS_BASE,
                         APIC_DEFAULT_PHYS_BASE + sizeof(struct local_apic_regs) - 1,
                         NULL, "Local APIC", vmm_apic_mmio_read, vmm_apic_mmio_write);

    vmm->done_guest_init = 1;
    return 0;
}
