/*
 * 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(AccelCPUState *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(AccelCPUState *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->accel->hThread, 0)) {
            fprintf(stderr, "%s: QueueUserAPC failed with error %lu\n",
                    __func__, GetLastError());
            exit(1);
        }
    }
}
