/*
** Copyright (c) 2011, Intel Corporation
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/

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

/*
 * return 0 upon success, -1 when the driver is not loaded,
 * other negative value for other failures
 */
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)
    {
        dprint("Failed to open the HAX device!\n");
        errNum = GetLastError();
        if (errNum == ERROR_FILE_NOT_FOUND)
            return -1;
        return -2;
    }
    *fd = hDevice;
    dprint("device fd:%d\n", *fd);
    return 0;
}


hax_fd hax_mod_open(void)
{
    int ret;
    hax_fd fd;

    ret = hax_open_device(&fd);
    if (ret != 0)
        dprint("Open HAX device failed\n");

    return fd;
}

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

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

    info.size = size;
    info.va = va;

    hDeviceVM = hax_global.vm->fd;

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

    if (!ret) {
        dprint("Failed to allocate %x memory\n", size);
        return ret;
    }

    return 0;
}


int hax_set_phys_mem(target_phys_addr_t start_addr, ram_addr_t size, ram_addr_t phys_offset)
{
    struct hax_set_ram_info info, *pinfo = &info;
    ram_addr_t flags = phys_offset & ~TARGET_PAGE_MASK;
    HANDLE hDeviceVM;
    DWORD dSize = 0;
    int ret = 0;

    /* We look for the  RAM and ROM only */
    if (flags >= IO_MEM_UNASSIGNED)
        return 0;

    if ( (start_addr & ~TARGET_PAGE_MASK) || (size & ~TARGET_PAGE_MASK))
    {
        dprint(
          "set_phys_mem %x %lx requires page aligned addr and size\n",
          start_addr, size);
        return -1;
    }

    info.pa_start = start_addr;
    info.size = size;
    info.va = (uint64_t)qemu_get_ram_ptr(phys_offset);
    info.flags = (flags & IO_MEM_ROM) ? 1 : 0;

    hDeviceVM = hax_global.vm->fd;

    ret = DeviceIoControl(hDeviceVM,
      HAX_VM_IOCTL_SET_RAM,
      pinfo, sizeof(*pinfo),
      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)) {
        dprint("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)
            dprint("hax capability is too long to hold.\n");
        dprint("Failed to get Hax capability:%d\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)) {
        dprint("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)
            dprint("HAX module is too large.\n");
        dprint("Failed to get Hax module version:%d\n", err);
        return -EFAULT;
    } else
        return 0;
}

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

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

    name = qemu_strdup("\\\\.\\hax_vmxx");
    if (!name)
        return NULL;
    sprintf(name, "\\\\.\\hax_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)
    {
        dprint("Too big vm id %x or vcpu id %x\n", vm_id, vcpu_id);
        return NULL;
    }
    name = qemu_strdup("\\\\.\\hax_vmxx_vcpuxx");
    if (!name)
        return NULL;
    sprintf(name, "\\\\.\\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;
    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) {
        dprint("error code:%d", 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) {
        dprint("Incorrect name\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)
        dprint("Open the vm devcie error:%s, ec:%d\n", vm_name, GetLastError());

    qemu_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)
    {
        dprint("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)
    {
        dprint("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)
    {
        dprint("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)
        dprint("Failed to open the vcpu devfs\n");
    qemu_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)
    {
        dprint("Failed to setup the hax tunnel\n");
        return -1;
    }

    if (!valid_hax_tunnel_size(info.size))
    {
        dprint("Invalid hax tunnel size %x\n", info.size);
        ret = -EINVAL;
        return ret;
    }
    vcpu->tunnel = (struct hax_tunnel *)(info.va);
    vcpu->iobuf = (unsigned char *)(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(CPUState *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(CPUState *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(CPUState *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(CPUState *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;
}
