/*
 * QEMU HAXM support
 *
 * Copyright (c) 2011 Intel Corporation
 *  Written by:
 *  Jiang Yunhong<yunhong.jiang@intel.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 *
 */

/* HAX module interface - darwin version */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>

#include "target-i386/hax-i386.h"

hax_fd hax_mod_open(void)
{
    int fd = open("/dev/HAX", O_RDWR);
    if (fd == -1) {
        fprintf(stderr, "Failed to open the hax module\n");
    }

    fcntl(fd, F_SETFD, FD_CLOEXEC);

    return fd;
}

int hax_populate_ram(uint64_t va, uint32_t size)
{
    int ret;
    struct hax_alloc_ram_info info;

    if (!hax_global.vm || !hax_global.vm->fd) {
        fprintf(stderr, "Allocate memory before vm create?\n");
        return -EINVAL;
    }

    info.size = size;
    info.va = va;
    ret = ioctl(hax_global.vm->fd, HAX_VM_IOCTL_ALLOC_RAM, &info);
    if (ret < 0) {
        fprintf(stderr, "Failed to allocate %x memory\n", size);
        return ret;
    }
    return 0;
}

int hax_set_ram(uint64_t start_pa, uint32_t size, uint64_t host_va, int flags)
{
    struct hax_set_ram_info info;
    int ret;

    info.pa_start = start_pa;
    info.size = size;
    info.va = host_va;
    info.flags = (uint8_t) flags;

    ret = ioctl(hax_global.vm->fd, HAX_VM_IOCTL_SET_RAM, &info);
    if (ret < 0) {
        return -errno;
    }
    return 0;
}

int hax_get_max_ram(uint64_t *max_ram) {
    int fd = hax_mod_open();
    if (fd < 0) {
        return -1;
    }
    struct hax_capabilityinfo cap;
    int result = ioctl(fd, HAX_IOCTL_CAPABILITY, &cap);
    close(fd);
    if (result == -1) {
        return -1;
    }
    *max_ram = cap.mem_quota;
    return 0;
}

int hax_capability(struct hax_state *hax, struct hax_capabilityinfo *cap)
{
    int ret;

    ret = ioctl(hax->fd, HAX_IOCTL_CAPABILITY, cap);
    if (ret == -1) {
        fprintf(stderr, "Failed to get HAX capability\n");
        return -errno;
    }

    return 0;
}

int hax_mod_version(struct hax_state *hax, struct hax_module_version *version)
{
    int ret;

    ret = ioctl(hax->fd, HAX_IOCTL_VERSION, version);
    if (ret == -1) {
        fprintf(stderr, "Failed to get HAX version\n");
        return -errno;
    }

    return 0;
}

static char *hax_vm_devfs_string(int vm_id)
{
    char *name;

    if (vm_id > MAX_VM_ID) {
        fprintf(stderr, "Too big VM id\n");
        return NULL;
    }

#define HAX_VM_DEVFS "/dev/hax_vm/vmxx"
    name = g_strdup(HAX_VM_DEVFS);
    if (!name)
        return NULL;

    snprintf(name, sizeof HAX_VM_DEVFS, "/dev/hax_vm/vm%02d", vm_id);
    return name;
}

static char *hax_vcpu_devfs_string(int vm_id, int vcpu_id)
{
    char *name;

    if (vm_id > MAX_VM_ID || vcpu_id > MAX_VCPU_ID) {
        fprintf(stderr, "Too big vm id %x or vcpu id %x\n", vm_id, vcpu_id);
        return NULL;
    }

#define HAX_VCPU_DEVFS "/dev/hax_vmxx/vcpuxx"
    name = g_strdup(HAX_VCPU_DEVFS);
    if (!name)
        return NULL;

    snprintf(name, sizeof HAX_VCPU_DEVFS, "/dev/hax_vm%02d/vcpu%02d",
             vm_id, vcpu_id);
    return name;
}

int hax_host_create_vm(struct hax_state *hax, int *vmid)
{
    int ret;
    int vm_id = 0;

    if (hax_invalid_fd(hax->fd))
        return -EINVAL;

    if (hax->vm)
        return 0;

    ret = ioctl(hax->fd, HAX_IOCTL_CREATE_VM, &vm_id);
    *vmid = vm_id;
    return ret;
}

hax_fd hax_host_open_vm(struct hax_state * hax, int vm_id)
{
    hax_fd fd;
    char *vm_name = NULL;

    vm_name = hax_vm_devfs_string(vm_id);
    if (!vm_name)
        return -1;

    fd = open(vm_name, O_RDWR);
    qemu_vfree(vm_name);

    fcntl(fd, F_SETFD, FD_CLOEXEC);

    return fd;
}

int hax_notify_qemu_version(hax_fd vm_fd, struct hax_qemu_version *qversion)
{
    int ret;

    if (hax_invalid_fd(vm_fd))
        return -EINVAL;

    ret = ioctl(vm_fd, HAX_VM_IOCTL_NOTIFY_QEMU_VERSION, qversion);

    if (ret < 0) {
        fprintf(stderr, "Failed to notify qemu API version\n");
        return ret;
    }
    return 0;
}

/* Simply assume the size should be bigger than the hax_tunnel,
 * since the hax_tunnel can be extended later with compatibility considered
 */
int hax_host_create_vcpu(hax_fd vm_fd, int vcpuid)
{
    int ret;

    ret = ioctl(vm_fd, HAX_VM_IOCTL_VCPU_CREATE, &vcpuid);
    if (ret < 0)
        fprintf(stderr, "Failed to create vcpu %x\n", vcpuid);

    return ret;
}

hax_fd hax_host_open_vcpu(int vmid, int vcpuid)
{
    char *devfs_path = NULL;
    hax_fd fd;

    devfs_path = hax_vcpu_devfs_string(vmid, vcpuid);
    if (!devfs_path) {
        fprintf(stderr, "Failed to get the devfs\n");
        return -EINVAL;
    }

    fd = open(devfs_path, O_RDWR);
    qemu_vfree(devfs_path);
    if (fd < 0)
        fprintf(stderr, "Failed to open the vcpu devfs\n");
    fcntl(fd, F_SETFD, FD_CLOEXEC);
    return fd;
}

int hax_host_setup_vcpu_channel(struct hax_vcpu_state *vcpu)
{
    int ret;
    struct hax_tunnel_info info;

    ret = ioctl(vcpu->fd, HAX_VCPU_IOCTL_SETUP_TUNNEL, &info);
    if (ret) {
        fprintf(stderr, "Failed to setup the hax tunnel\n");
        return ret;
    }

    if (!valid_hax_tunnel_size(info.size)) {
        fprintf(stderr, "Invalid hax tunnel size %x\n", info.size);
        ret = -EINVAL;
        return ret;
    }

    vcpu->tunnel = (struct hax_tunnel *) (intptr_t) (info.va);
    vcpu->iobuf = (unsigned char *) (intptr_t) (info.io_va);
    return 0;
}

int hax_vcpu_run(struct hax_vcpu_state *vcpu)
{
    int ret;

    ret = ioctl(vcpu->fd, HAX_VCPU_IOCTL_RUN, NULL);
    return ret;
}

int hax_sync_fpu(CPUArchState * env, struct fx_layout *fl, int set)
{
    int ret, fd;

    fd = hax_vcpu_get_fd(env);
    if (fd <= 0)
        return -1;

    if (set)
        ret = ioctl(fd, HAX_VCPU_IOCTL_SET_FPU, fl);
    else
        ret = ioctl(fd, HAX_VCPU_IOCTL_GET_FPU, fl);
    return ret;
}

int hax_sync_msr(CPUArchState * env, struct hax_msr_data *msrs, int set)
{
    int ret, fd;

    fd = hax_vcpu_get_fd(env);
    if (fd <= 0)
        return -1;
    if (set)
        ret = ioctl(fd, HAX_VCPU_IOCTL_SET_MSRS, msrs);
    else
        ret = ioctl(fd, HAX_VCPU_IOCTL_GET_MSRS, msrs);
    return ret;
}

int hax_sync_vcpu_state(CPUArchState * env, struct vcpu_state_t *state, int set)
{
    int ret, fd;

    fd = hax_vcpu_get_fd(env);
    if (fd <= 0)
        return -1;

    if (set)
        ret = ioctl(fd, HAX_VCPU_SET_REGS, state);
    else
        ret = ioctl(fd, HAX_VCPU_GET_REGS, state);
    return ret;
}

int hax_inject_interrupt(CPUArchState * env, int vector)
{
    int ret, fd;

    fd = hax_vcpu_get_fd(env);
    if (fd <= 0)
        return -1;

    ret = ioctl(fd, HAX_VCPU_IOCTL_INTERRUPT, &vector);
    return ret;
}
