/*
 * qemu/kvm integration, x86 specific code
 *
 * Copyright (C) 2006-2008 Qumranet Technologies
 *
 * Licensed under the terms of the GNU GPL version 2 or higher.
 */

#include "config.h"
#include "config-host.h"

#include <string.h>
#include "hw/hw.h"
#include "gdbstub.h"
#include <sys/io.h>

#include "qemu-kvm.h"
#include <pthread.h>
#include <sys/utsname.h>
#include <linux/kvm_para.h>
#include <sys/ioctl.h>

#include "kvm.h"
#include "hw/apic.h"

static int kvm_create_pit(KVMState *s)
{
    int r;

    if (kvm_irqchip) {
        r = kvm_vm_ioctl(s, KVM_CREATE_PIT);
        if (r < 0) {
            fprintf(stderr, "Create kernel PIC irqchip failed\n");
            return r;
        }
        if (!kvm_pit_reinject) {
            r = kvm_reinject_control(s, 0);
            if (r < 0) {
                fprintf(stderr,
                        "failure to disable in-kernel PIT reinjection\n");
                return r;
            }
        }
    }
    return 0;
}

int kvm_handle_tpr_access(CPUState *env)
{
    struct kvm_run *run = env->kvm_run;
    kvm_tpr_access_report(env,
                          run->tpr_access.rip,
                          run->tpr_access.is_write);
    return 1;
}


int kvm_enable_vapic(CPUState *env, uint64_t vapic)
{
    struct kvm_vapic_addr va = {
        .vapic_addr = vapic,
    };

    return kvm_vcpu_ioctl(env, KVM_SET_VAPIC_ADDR, &va);
}

int kvm_get_lapic(CPUState *env, struct kvm_lapic_state *s)
{
    int r = 0;

    if (!kvm_irqchip_in_kernel()) {
        return r;
    }

    r = kvm_vcpu_ioctl(env, KVM_GET_LAPIC, s);
    if (r < 0) {
        fprintf(stderr, "KVM_GET_LAPIC failed\n");
    }
    return r;
}

int kvm_set_lapic(CPUState *env, struct kvm_lapic_state *s)
{
    int r = 0;

    if (!kvm_irqchip_in_kernel()) {
        return 0;
    }

    r = kvm_vcpu_ioctl(env, KVM_SET_LAPIC, s);

    if (r < 0) {
        fprintf(stderr, "KVM_SET_LAPIC failed\n");
    }
    return r;
}

int kvm_get_pit(KVMState *s, struct kvm_pit_state *pit_state)
{
    if (!kvm_irqchip_in_kernel()) {
        return 0;
    }
    return kvm_vm_ioctl(s, KVM_GET_PIT, pit_state);
}

int kvm_set_pit(KVMState *s, struct kvm_pit_state *pit_state)
{
    if (!kvm_irqchip_in_kernel()) {
        return 0;
    }
    return kvm_vm_ioctl(s, KVM_SET_PIT, pit_state);
}

int kvm_get_pit2(KVMState *s, struct kvm_pit_state2 *ps2)
{
    if (!kvm_irqchip_in_kernel()) {
        return 0;
    }
    return kvm_vm_ioctl(s, KVM_GET_PIT2, ps2);
}

int kvm_set_pit2(KVMState *s, struct kvm_pit_state2 *ps2)
{
    if (!kvm_irqchip_in_kernel()) {
        return 0;
    }
    return kvm_vm_ioctl(s, KVM_SET_PIT2, ps2);
}

static int kvm_enable_tpr_access_reporting(CPUState *env)
{
    int r;
    struct kvm_tpr_access_ctl tac = { .enabled = 1 };

    r = kvm_ioctl(env->kvm_state, KVM_CHECK_EXTENSION, KVM_CAP_VAPIC);
    if (r <= 0) {
        return -ENOSYS;
    }
    return kvm_vcpu_ioctl(env, KVM_TPR_ACCESS_REPORTING, &tac);
}

static int _kvm_arch_init_vcpu(CPUState *env)
{
    kvm_arch_reset_vcpu(env);

    kvm_enable_tpr_access_reporting(env);

    return kvm_update_ioport_access(env);
}

#ifdef CONFIG_KVM_DEVICE_ASSIGNMENT
int kvm_arch_set_ioport_access(unsigned long start, unsigned long size,
                               bool enable)
{
    if (ioperm(start, size, enable) < 0) {
        return -errno;
    }
    return 0;
}
#endif

/*
 * Setup x86 specific IRQ routing
 */
int kvm_arch_init_irq_routing(void)
{
    int i, r;

    if (kvm_has_gsi_routing()) {
        kvm_clear_gsi_routes();
        for (i = 0; i < 8; ++i) {
            if (i == 2) {
                continue;
            }
            r = kvm_add_irq_route(i, KVM_IRQCHIP_PIC_MASTER, i);
            if (r < 0) {
                return r;
            }
        }
        for (i = 8; i < 16; ++i) {
            r = kvm_add_irq_route(i, KVM_IRQCHIP_PIC_SLAVE, i - 8);
            if (r < 0) {
                return r;
            }
        }
        for (i = 0; i < 24; ++i) {
            if (i == 0) {
                r = kvm_add_irq_route(i, KVM_IRQCHIP_IOAPIC, 2);
            } else if (i != 2) {
                r = kvm_add_irq_route(i, KVM_IRQCHIP_IOAPIC, i);
            }
            if (r < 0) {
                return r;
            }
        }
        kvm_commit_irq_routes();

        if (!kvm_has_pit_state2()) {
            no_hpet = 1;
        }
    } else {
        /* If kernel can't do irq routing, interrupt source
         * override 0->2 can not be set up as required by HPET.
         * so we have to disable it.
         */
        no_hpet = 1;
    }

    return 0;
}
