/*
** 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_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;
}
