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

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

#include <autoconf.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, simple_t simple, vka_t vka, vspace_t vspace, platform_callbacks_t callbacks) {
    int err;
    memset(vmm, 0, sizeof(vmm_t));
    vmm->vka = vka;
    vmm->host_simple = simple;
    vmm->host_vspace = vspace;
    vmm->plat_callbacks = callbacks;
    vmm->tcb = simple_get_tcb(&simple);
    // 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 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_IA32_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_page_directory_pointer_table_leaky(&vmm->vka);
    if (vmm->guest_pd == 0) {
        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;
}

