/*
 * Copyright 2019, 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 BSD 2-Clause license. Note that NO WARRANTY is provided.
 * See "LICENSE_BSD2.txt" for details.
 *
 * @TAG(DATA61_BSD)
 */

#include <autoconf.h>

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <utils/util.h>

#include <sel4vm/guest_vm.h>
#include <sel4vm/boot.h>
#include <sel4vm/guest_vm_exits.h>
#include <sel4vm/guest_vm_util.h>

#include "vm_boot.h"

static int curr_vcpu_index = 0;

int vm_init(vm_t *vm, vka_t *vka, simple_t *host_simple, vspace_t host_vspace,
            ps_io_ops_t *io_ops, seL4_CPtr host_endpoint, const char *name)
{
    int err;
    bzero(vm, sizeof(vm_t));
    /* Initialise vm fields */
    vm->vka = vka;
    vm->simple = host_simple;
    vm->io_ops = io_ops;
    vm->mem.vmm_vspace = host_vspace;
    vm->host_endpoint = host_endpoint;
    vm->vm_name = strndup(name, strlen(name));
    vm->run.exit_reason = VM_GUEST_UNKNOWN_EXIT;
    /* Initialise ram region */
    vm->mem.num_ram_regions = 0;
    vm->mem.ram_regions = malloc(0);
    assert(vm->vcpus);
    /* Initialise vm memory management interface */
    err = vm_memory_init(vm);
    if (err) {
        ZF_LOGE("Failed to initialise VM memory manager");
        return err;
    }

    /* Initialise vm architecture support */
    err = vm_init_arch(vm);
    if (err) {
        ZF_LOGE("Failed to initialise VM architecture support");
        return err;
    }

    /* Flag that the vm has been initialised */
    vm->vm_initialised = true;
    return 0;
}

vm_vcpu_t *vm_create_vcpu(vm_t *vm, int priority)
{
    int err;
    if (vm->num_vcpus >= CONFIG_MAX_NUM_NODES) {
        ZF_LOGE("Failed to create vcpu, reached maximum number of support vcpus");
        return NULL;
    }
    vm_vcpu_t *vcpu_new = calloc(1, sizeof(vm_vcpu_t));
    assert(vcpu_new);
    /* Create VCPU */
    err = vka_alloc_vcpu(vm->vka, &vcpu_new->vcpu);
    assert(!err);
    /* Initialise vcpu fields */
    vcpu_new->vm = vm;
    vcpu_new->vcpu_id = curr_vcpu_index++;
    vcpu_new->tcb.priority = priority;
    vcpu_new->vcpu_online = false;
    vcpu_new->target_cpu = -1;
    err = vm_create_vcpu_arch(vm, vcpu_new);
    assert(!err);
    vm->vcpus[vm->num_vcpus] = vcpu_new;
    vm->num_vcpus++;
    return vcpu_new;
}

int vm_assign_vcpu_target(vm_vcpu_t *vcpu, int target_cpu)
{
    if (vcpu == NULL) {
        ZF_LOGE("Failed to assign target cpu - Invalid vcpu");
        return -1;
    }
    vm_vcpu_t *target_vcpu = vm_vcpu_for_target_cpu(vcpu->vm, target_cpu);
    if (target_vcpu) {
        ZF_LOGE("Failed to assign target cpu - A VCPU is already assigned to core %d", target_cpu);
        return -1;
    }
    vcpu->target_cpu = target_cpu;
    return 0;
}
