/*
 * 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.
 *
 */

#include "qemu/osdep.h"
#include "cpu.h"
#include "hax-accel-ops.h"

/*
 * return 0 when success, -1 when driver not loaded,
 * other negative value for other failure
 */
static int hax_open_device(hax_fd *fd)
{
    uint32_t errNum = 0;
    HANDLE hDevice;

    if (!fd) {
        return -2;
    }

    hDevice = CreateFile("\\\\.\\HAX",
                         GENERIC_READ | GENERIC_WRITE,
                         0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    if (hDevice == INVALID_HANDLE_VALUE) {
        fprintf(stderr, "Failed to open the HAX device!\n");
        errNum = GetLastError();
        if (errNum == ERROR_FILE_NOT_FOUND) {
            return -1;
        }
        return -2;
    }
    *fd = hDevice;
    return 0;
}

/* hax_fd hax_mod_open */
 hax_fd hax_mod_open(void)
{
    int ret;
    hax_fd fd = NULL;

    ret = hax_open_device(&fd);
    if (ret != 0) {
        fprintf(stderr, "Open HAX device failed\n");
    }

    return fd;
}

int hax_populate_ram(uint64_t va, uint64_t size)
{
    int ret;
    HANDLE hDeviceVM;
    DWORD dSize = 0;

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

    hDeviceVM = hax_global.vm->fd;
    if (hax_global.supports_64bit_ramblock) {
        struct hax_ramblock_info ramblock = {
            .start_va = va,
            .size = size,
            .reserved = 0
        };

        ret = DeviceIoControl(hDeviceVM,
                              HAX_VM_IOCTL_ADD_RAMBLOCK,
                              &ramblock, sizeof(ramblock), NULL, 0, &dSize,
                              (LPOVERLAPPED) NULL);
    } else {
        struct hax_alloc_ram_info info = {
            .size = (uint32_t) size,
            .pad = 0,
            .va = va
        };

        ret = DeviceIoControl(hDeviceVM,
                              HAX_VM_IOCTL_ALLOC_RAM,
                              &info, sizeof(info), NULL, 0, &dSize,
                              (LPOVERLAPPED) NULL);
    }

    if (!ret) {
        fprintf(stderr, "Failed to register RAM block: va=0x%" PRIx64
                ", size=0x%" PRIx64 ", method=%s\n", va, size,
                hax_global.supports_64bit_ramblock ? "new" : "legacy");
        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;
    HANDLE hDeviceVM = hax_global.vm->fd;
    DWORD dSize = 0;
    int ret;

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

    ret = DeviceIoControl(hDeviceVM, HAX_VM_IOCTL_SET_RAM,
                          &info, sizeof(info), NULL, 0, &dSize,
                          (LPOVERLAPPED) NULL);

    if (!ret) {
        return -EFAULT;
    } else {
        return 0;
    }
}

int hax_capability(struct hax_state *hax, struct hax_capabilityinfo *cap)
{
    int ret;
    HANDLE hDevice = hax->fd;        /* handle to hax module */
    DWORD dSize = 0;
    DWORD err = 0;

    if (hax_invalid_fd(hDevice)) {
        fprintf(stderr, "Invalid fd for hax device!\n");
        return -ENODEV;
    }

    ret = DeviceIoControl(hDevice, HAX_IOCTL_CAPABILITY, NULL, 0, cap,
                          sizeof(*cap), &dSize, (LPOVERLAPPED) NULL);

    if (!ret) {
        err = GetLastError();
        if (err == ERROR_INSUFFICIENT_BUFFER || err == ERROR_MORE_DATA) {
            fprintf(stderr, "hax capability is too long to hold.\n");
        }
        fprintf(stderr, "Failed to get Hax capability:%luu\n", err);
        return -EFAULT;
    } else {
        return 0;
    }
}

int hax_mod_version(struct hax_state *hax, struct hax_module_version *version)
{
    int ret;
    HANDLE hDevice = hax->fd; /* handle to hax module */
    DWORD dSize = 0;
    DWORD err = 0;

    if (hax_invalid_fd(hDevice)) {
        fprintf(stderr, "Invalid fd for hax device!\n");
        return -ENODEV;
    }

    ret = DeviceIoControl(hDevice,
                          HAX_IOCTL_VERSION,
                          NULL, 0,
                          version, sizeof(*version), &dSize,
                          (LPOVERLAPPED) NULL);

    if (!ret) {
        err = GetLastError();
        if (err == ERROR_INSUFFICIENT_BUFFER || err == ERROR_MORE_DATA) {
            fprintf(stderr, "hax module verion is too long to hold.\n");
        }
        fprintf(stderr, "Failed to get Hax module version:%lu\n", err);
        return -EFAULT;
    } else {
        return 0;
    }
}

static char *hax_vm_devfs_string(int vm_id)
{
    return g_strdup_printf("\\\\.\\hax_vm%02d", vm_id);
}

static char *hax_vcpu_devfs_string(int vm_id, int vcpu_id)
{
    return g_strdup_printf("\\\\.\\hax_vm%02d_vcpu%02d", vm_id, vcpu_id);
}

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

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

    if (hax->vm) {
        return 0;
    }

    ret = DeviceIoControl(hax->fd,
                          HAX_IOCTL_CREATE_VM,
                          NULL, 0, &vm_id, sizeof(vm_id), &dSize,
                          (LPOVERLAPPED) NULL);
    if (!ret) {
        fprintf(stderr, "Failed to create VM. Error code: %lu\n",
                GetLastError());
        return -1;
    }
    *vmid = vm_id;
    return 0;
}

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

    vm_name = hax_vm_devfs_string(vm_id);
    if (!vm_name) {
        fprintf(stderr, "Failed to open VM. VM name is null\n");
        return INVALID_HANDLE_VALUE;
    }

    hDeviceVM = CreateFile(vm_name,
                           GENERIC_READ | GENERIC_WRITE,
                           0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hDeviceVM == INVALID_HANDLE_VALUE) {
        fprintf(stderr, "Open the vm device error:%s, ec:%lu\n",
                vm_name, GetLastError());
    }

    g_free(vm_name);
    return hDeviceVM;
}

int hax_notify_qemu_version(hax_fd vm_fd, struct hax_qemu_version *qversion)
{
    int ret;
    DWORD dSize = 0;
    if (hax_invalid_fd(vm_fd)) {
        return -EINVAL;
    }
    ret = DeviceIoControl(vm_fd,
                          HAX_VM_IOCTL_NOTIFY_QEMU_VERSION,
                          qversion, sizeof(struct hax_qemu_version),
                          NULL, 0, &dSize, (LPOVERLAPPED) NULL);
    if (!ret) {
        fprintf(stderr, "Failed to notify qemu API version\n");
        return -1;
    }
    return 0;
}

int hax_host_create_vcpu(hax_fd vm_fd, int vcpuid)
{
    int ret;
    DWORD dSize = 0;

    ret = DeviceIoControl(vm_fd,
                          HAX_VM_IOCTL_VCPU_CREATE,
                          &vcpuid, sizeof(vcpuid), NULL, 0, &dSize,
                          (LPOVERLAPPED) NULL);
    if (!ret) {
        fprintf(stderr, "Failed to create vcpu %x\n", vcpuid);
        return -1;
    }

    return 0;
}

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

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

    hDeviceVCPU = CreateFile(devfs_path,
                             GENERIC_READ | GENERIC_WRITE,
                             0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
                             NULL);

    if (hDeviceVCPU == INVALID_HANDLE_VALUE) {
        fprintf(stderr, "Failed to open the vcpu devfs\n");
    }
    g_free(devfs_path);
    return hDeviceVCPU;
}

int hax_host_setup_vcpu_channel(struct hax_vcpu_state *vcpu)
{
    hax_fd hDeviceVCPU = vcpu->fd;
    int ret;
    struct hax_tunnel_info info;
    DWORD dSize = 0;

    ret = DeviceIoControl(hDeviceVCPU,
                          HAX_VCPU_IOCTL_SETUP_TUNNEL,
                          NULL, 0, &info, sizeof(info), &dSize,
                          (LPOVERLAPPED) NULL);
    if (!ret) {
        fprintf(stderr, "Failed to setup the hax tunnel\n");
        return -1;
    }

    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;
    HANDLE hDeviceVCPU = vcpu->fd;
    DWORD dSize = 0;

    ret = DeviceIoControl(hDeviceVCPU,
                          HAX_VCPU_IOCTL_RUN,
                          NULL, 0, NULL, 0, &dSize, (LPOVERLAPPED) NULL);
    if (!ret) {
        return -EFAULT;
    } else {
        return 0;
    }
}

int hax_sync_fpu(CPUArchState *env, struct fx_layout *fl, int set)
{
    int ret;
    hax_fd fd;
    HANDLE hDeviceVCPU;
    DWORD dSize = 0;

    fd = hax_vcpu_get_fd(env);
    if (hax_invalid_fd(fd)) {
        return -1;
    }

    hDeviceVCPU = fd;

    if (set) {
        ret = DeviceIoControl(hDeviceVCPU,
                              HAX_VCPU_IOCTL_SET_FPU,
                              fl, sizeof(*fl), NULL, 0, &dSize,
                              (LPOVERLAPPED) NULL);
    } else {
        ret = DeviceIoControl(hDeviceVCPU,
                              HAX_VCPU_IOCTL_GET_FPU,
                              NULL, 0, fl, sizeof(*fl), &dSize,
                              (LPOVERLAPPED) NULL);
    }
    if (!ret) {
        return -EFAULT;
    } else {
        return 0;
    }
}

int hax_sync_msr(CPUArchState *env, struct hax_msr_data *msrs, int set)
{
    int ret;
    hax_fd fd;
    HANDLE hDeviceVCPU;
    DWORD dSize = 0;

    fd = hax_vcpu_get_fd(env);
    if (hax_invalid_fd(fd)) {
        return -1;
    }
    hDeviceVCPU = fd;

    if (set) {
        ret = DeviceIoControl(hDeviceVCPU,
                              HAX_VCPU_IOCTL_SET_MSRS,
                              msrs, sizeof(*msrs),
                              msrs, sizeof(*msrs), &dSize, (LPOVERLAPPED) NULL);
    } else {
        ret = DeviceIoControl(hDeviceVCPU,
                              HAX_VCPU_IOCTL_GET_MSRS,
                              msrs, sizeof(*msrs),
                              msrs, sizeof(*msrs), &dSize, (LPOVERLAPPED) NULL);
    }
    if (!ret) {
        return -EFAULT;
    } else {
        return 0;
    }
}

int hax_sync_vcpu_state(CPUArchState *env, struct vcpu_state_t *state, int set)
{
    int ret;
    hax_fd fd;
    HANDLE hDeviceVCPU;
    DWORD dSize;

    fd = hax_vcpu_get_fd(env);
    if (hax_invalid_fd(fd)) {
        return -1;
    }

    hDeviceVCPU = fd;

    if (set) {
        ret = DeviceIoControl(hDeviceVCPU,
                              HAX_VCPU_SET_REGS,
                              state, sizeof(*state),
                              NULL, 0, &dSize, (LPOVERLAPPED) NULL);
    } else {
        ret = DeviceIoControl(hDeviceVCPU,
                              HAX_VCPU_GET_REGS,
                              NULL, 0,
                              state, sizeof(*state), &dSize,
                              (LPOVERLAPPED) NULL);
    }
    if (!ret) {
        return -EFAULT;
    } else {
        return 0;
    }
}

int hax_inject_interrupt(CPUArchState *env, int vector)
{
    int ret;
    hax_fd fd;
    HANDLE hDeviceVCPU;
    DWORD dSize;

    fd = hax_vcpu_get_fd(env);
    if (hax_invalid_fd(fd)) {
        return -1;
    }

    hDeviceVCPU = fd;

    ret = DeviceIoControl(hDeviceVCPU,
                          HAX_VCPU_IOCTL_INTERRUPT,
                          &vector, sizeof(vector), NULL, 0, &dSize,
                          (LPOVERLAPPED) NULL);
    if (!ret) {
        return -EFAULT;
    } else {
        return 0;
    }
}

static void CALLBACK dummy_apc_func(ULONG_PTR unused)
{
}

void hax_kick_vcpu_thread(CPUState *cpu)
{
    /*
     * FIXME: race condition with the exit_request check in
     * hax_vcpu_hax_exec
     */
    cpu->exit_request = 1;
    if (!qemu_cpu_is_self(cpu)) {
        if (!QueueUserAPC(dummy_apc_func, cpu->hThread, 0)) {
            fprintf(stderr, "%s: QueueUserAPC failed with error %lu\n",
                    __func__, GetLastError());
            exit(1);
        }
    }
}
