/*
 * KVM in-kernel PIT (i8254) support
 *
 * Copyright (c) 2003-2004 Fabrice Bellard
 * Copyright (c) 2012      Jan Kiszka, Siemens AG
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include <linux/kvm.h>
#include "qapi/qapi-types-misc.h"
#include "qapi/error.h"
#include "qemu/module.h"
#include "qemu/timer.h"
#include "sysemu/runstate.h"
#include "hw/timer/i8254.h"
#include "hw/timer/i8254_internal.h"
#include "sysemu/kvm.h"

#define KVM_PIT_REINJECT_BIT 0

#define CALIBRATION_ROUNDS   3

#define KVM_PIT(obj) OBJECT_CHECK(KVMPITState, (obj), TYPE_KVM_I8254)
#define KVM_PIT_CLASS(class) \
    OBJECT_CLASS_CHECK(KVMPITClass, (class), TYPE_KVM_I8254)
#define KVM_PIT_GET_CLASS(obj) \
    OBJECT_GET_CLASS(KVMPITClass, (obj), TYPE_KVM_I8254)

typedef struct KVMPITState {
    PITCommonState parent_obj;

    LostTickPolicy lost_tick_policy;
    bool vm_stopped;
    int64_t kernel_clock_offset;
} KVMPITState;

typedef struct KVMPITClass {
    PITCommonClass parent_class;

    DeviceRealize parent_realize;
} KVMPITClass;

static int64_t abs64(int64_t v)
{
    return v < 0 ? -v : v;
}

static void kvm_pit_update_clock_offset(KVMPITState *s)
{
    int64_t offset, clock_offset;
    struct timespec ts;
    int i;

    /*
     * Measure the delta between CLOCK_MONOTONIC, the base used for
     * kvm_pit_channel_state::count_load_time, and QEMU_CLOCK_VIRTUAL. Take the
     * minimum of several samples to filter out scheduling noise.
     */
    clock_offset = INT64_MAX;
    for (i = 0; i < CALIBRATION_ROUNDS; i++) {
        offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
        clock_gettime(CLOCK_MONOTONIC, &ts);
        offset -= ts.tv_nsec;
        offset -= (int64_t)ts.tv_sec * 1000000000;
        if (abs64(offset) < abs64(clock_offset)) {
            clock_offset = offset;
        }
    }
    s->kernel_clock_offset = clock_offset;
}

static void kvm_pit_get(PITCommonState *pit)
{
    KVMPITState *s = KVM_PIT(pit);
    struct kvm_pit_state2 kpit;
    struct kvm_pit_channel_state *kchan;
    struct PITChannelState *sc;
    int i, ret;

    /* No need to re-read the state if VM is stopped. */
    if (s->vm_stopped) {
        return;
    }

    if (kvm_has_pit_state2()) {
        ret = kvm_vm_ioctl(kvm_state, KVM_GET_PIT2, &kpit);
        if (ret < 0) {
            fprintf(stderr, "KVM_GET_PIT2 failed: %s\n", strerror(ret));
            abort();
        }
        pit->channels[0].irq_disabled = kpit.flags & KVM_PIT_FLAGS_HPET_LEGACY;
    } else {
        /*
         * kvm_pit_state2 is superset of kvm_pit_state struct,
         * so we can use it for KVM_GET_PIT as well.
         */
        ret = kvm_vm_ioctl(kvm_state, KVM_GET_PIT, &kpit);
        if (ret < 0) {
            fprintf(stderr, "KVM_GET_PIT failed: %s\n", strerror(ret));
            abort();
        }
    }
    for (i = 0; i < 3; i++) {
        kchan = &kpit.channels[i];
        sc = &pit->channels[i];
        sc->count = kchan->count;
        sc->latched_count = kchan->latched_count;
        sc->count_latched = kchan->count_latched;
        sc->status_latched = kchan->status_latched;
        sc->status = kchan->status;
        sc->read_state = kchan->read_state;
        sc->write_state = kchan->write_state;
        sc->write_latch = kchan->write_latch;
        sc->rw_mode = kchan->rw_mode;
        sc->mode = kchan->mode;
        sc->bcd = kchan->bcd;
        sc->gate = kchan->gate;
        sc->count_load_time = kchan->count_load_time + s->kernel_clock_offset;
    }

    sc = &pit->channels[0];
    sc->next_transition_time =
        pit_get_next_transition_time(sc, sc->count_load_time);
}

static void kvm_pit_put(PITCommonState *pit)
{
    KVMPITState *s = KVM_PIT(pit);
    struct kvm_pit_state2 kpit = {};
    struct kvm_pit_channel_state *kchan;
    struct PITChannelState *sc;
    int i, ret;

    /* The offset keeps changing as long as the VM is stopped. */
    if (s->vm_stopped) {
        kvm_pit_update_clock_offset(s);
    }

    kpit.flags = pit->channels[0].irq_disabled ? KVM_PIT_FLAGS_HPET_LEGACY : 0;
    for (i = 0; i < 3; i++) {
        kchan = &kpit.channels[i];
        sc = &pit->channels[i];
        kchan->count = sc->count;
        kchan->latched_count = sc->latched_count;
        kchan->count_latched = sc->count_latched;
        kchan->status_latched = sc->status_latched;
        kchan->status = sc->status;
        kchan->read_state = sc->read_state;
        kchan->write_state = sc->write_state;
        kchan->write_latch = sc->write_latch;
        kchan->rw_mode = sc->rw_mode;
        kchan->mode = sc->mode;
        kchan->bcd = sc->bcd;
        kchan->gate = sc->gate;
        kchan->count_load_time = sc->count_load_time - s->kernel_clock_offset;
    }

    ret = kvm_vm_ioctl(kvm_state,
                       kvm_has_pit_state2() ? KVM_SET_PIT2 : KVM_SET_PIT,
                       &kpit);
    if (ret < 0) {
        fprintf(stderr, "%s failed: %s\n",
                kvm_has_pit_state2() ? "KVM_SET_PIT2" : "KVM_SET_PIT",
                strerror(ret));
        abort();
    }
}

static void kvm_pit_set_gate(PITCommonState *s, PITChannelState *sc, int val)
{
    kvm_pit_get(s);

    switch (sc->mode) {
    default:
    case 0:
    case 4:
        /* XXX: just disable/enable counting */
        break;
    case 1:
    case 2:
    case 3:
    case 5:
        if (sc->gate < val) {
            /* restart counting on rising edge */
            sc->count_load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
        }
        break;
    }
    sc->gate = val;

    kvm_pit_put(s);
}

static void kvm_pit_get_channel_info(PITCommonState *s, PITChannelState *sc,
                                     PITChannelInfo *info)
{
    kvm_pit_get(s);

    pit_get_channel_info_common(s, sc, info);
}

static void kvm_pit_reset(DeviceState *dev)
{
    PITCommonState *s = PIT_COMMON(dev);

    pit_reset_common(s);

    kvm_pit_put(s);
}

static void kvm_pit_irq_control(void *opaque, int n, int enable)
{
    PITCommonState *pit = opaque;
    PITChannelState *s = &pit->channels[0];

    kvm_pit_get(pit);

    s->irq_disabled = !enable;

    kvm_pit_put(pit);
}

static void kvm_pit_vm_state_change(void *opaque, int running,
                                    RunState state)
{
    KVMPITState *s = opaque;

    if (running) {
        kvm_pit_update_clock_offset(s);
        kvm_pit_put(PIT_COMMON(s));
        s->vm_stopped = false;
    } else {
        kvm_pit_update_clock_offset(s);
        kvm_pit_get(PIT_COMMON(s));
        s->vm_stopped = true;
    }
}

static void kvm_pit_realizefn(DeviceState *dev, Error **errp)
{
    PITCommonState *pit = PIT_COMMON(dev);
    KVMPITClass *kpc = KVM_PIT_GET_CLASS(dev);
    KVMPITState *s = KVM_PIT(pit);
    struct kvm_pit_config config = {
        .flags = 0,
    };
    int ret;

    if (kvm_check_extension(kvm_state, KVM_CAP_PIT2)) {
        ret = kvm_vm_ioctl(kvm_state, KVM_CREATE_PIT2, &config);
    } else {
        ret = kvm_vm_ioctl(kvm_state, KVM_CREATE_PIT);
    }
    if (ret < 0) {
        error_setg(errp, "Create kernel PIC irqchip failed: %s",
                   strerror(ret));
        return;
    }
    switch (s->lost_tick_policy) {
    case LOST_TICK_POLICY_DELAY:
        break; /* enabled by default */
    case LOST_TICK_POLICY_DISCARD:
        if (kvm_check_extension(kvm_state, KVM_CAP_REINJECT_CONTROL)) {
            struct kvm_reinject_control control = { .pit_reinject = 0 };

            ret = kvm_vm_ioctl(kvm_state, KVM_REINJECT_CONTROL, &control);
            if (ret < 0) {
                error_setg(errp,
                           "Can't disable in-kernel PIT reinjection: %s",
                           strerror(ret));
                return;
            }
        }
        break;
    default:
        error_setg(errp, "Lost tick policy not supported.");
        return;
    }

    memory_region_init_io(&pit->ioports, OBJECT(dev), NULL, NULL, "kvm-pit", 4);

    qdev_init_gpio_in(dev, kvm_pit_irq_control, 1);

    qemu_add_vm_change_state_handler(kvm_pit_vm_state_change, s);

    kpc->parent_realize(dev, errp);
}

static Property kvm_pit_properties[] = {
    DEFINE_PROP_UINT32("iobase", PITCommonState, iobase,  -1),
    DEFINE_PROP_LOSTTICKPOLICY("lost_tick_policy", KVMPITState,
                               lost_tick_policy, LOST_TICK_POLICY_DELAY),
    DEFINE_PROP_END_OF_LIST(),
};

static void kvm_pit_class_init(ObjectClass *klass, void *data)
{
    KVMPITClass *kpc = KVM_PIT_CLASS(klass);
    PITCommonClass *k = PIT_COMMON_CLASS(klass);
    DeviceClass *dc = DEVICE_CLASS(klass);

    device_class_set_parent_realize(dc, kvm_pit_realizefn,
                                    &kpc->parent_realize);
    k->set_channel_gate = kvm_pit_set_gate;
    k->get_channel_info = kvm_pit_get_channel_info;
    dc->reset = kvm_pit_reset;
    dc->props = kvm_pit_properties;
}

static const TypeInfo kvm_pit_info = {
    .name          = TYPE_KVM_I8254,
    .parent        = TYPE_PIT_COMMON,
    .instance_size = sizeof(KVMPITState),
    .class_init = kvm_pit_class_init,
    .class_size = sizeof(KVMPITClass),
};

static void kvm_pit_register(void)
{
    type_register_static(&kvm_pit_info);
}

type_init(kvm_pit_register)
