/*
 * 8253/8254 interval timer emulation
 *
 * Copyright (c) 2003-2004 Fabrice Bellard
 * Copyright (c) 2006 Intel Corporation
 * Copyright (c) 2007 Keir Fraser, XenSource Inc
 * Copyright (c) 2008 Intel Corporation
 *
 * 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.
 *
 * Authors:
 *   Sheng Yang <sheng.yang@intel.com>
 *   Based on QEMU and Xen.
 */

#include <linux/kvm_host.h>

#include "irq.h"
#include "i8254.h"

#ifndef CONFIG_X86_64
#define mod_64(x, y) ((x) - (y) * div64_64(x, y))
#else
#define mod_64(x, y) ((x) % (y))
#endif

#define RW_STATE_LSB 1
#define RW_STATE_MSB 2
#define RW_STATE_WORD0 3
#define RW_STATE_WORD1 4

/* Compute with 96 bit intermediate result: (a*b)/c */
static u64 muldiv64(u64 a, u32 b, u32 c)
{
	union {
		u64 ll;
		struct {
			u32 low, high;
		} l;
	} u, res;
	u64 rl, rh;

	u.ll = a;
	rl = (u64)u.l.low * (u64)b;
	rh = (u64)u.l.high * (u64)b;
	rh += (rl >> 32);
	res.l.high = div64_64(rh, c);
	res.l.low = div64_64(((mod_64(rh, c) << 32) + (rl & 0xffffffff)), c);
	return res.ll;
}

static void pit_set_gate(struct kvm *kvm, int channel, u32 val)
{
	struct kvm_kpit_channel_state *c =
		&kvm->arch.vpit->pit_state.channels[channel];

	WARN_ON(!mutex_is_locked(&kvm->arch.vpit->pit_state.lock));

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

	c->gate = val;
}

int pit_get_gate(struct kvm *kvm, int channel)
{
	WARN_ON(!mutex_is_locked(&kvm->arch.vpit->pit_state.lock));

	return kvm->arch.vpit->pit_state.channels[channel].gate;
}

static int pit_get_count(struct kvm *kvm, int channel)
{
	struct kvm_kpit_channel_state *c =
		&kvm->arch.vpit->pit_state.channels[channel];
	s64 d, t;
	int counter;

	WARN_ON(!mutex_is_locked(&kvm->arch.vpit->pit_state.lock));

	t = ktime_to_ns(ktime_sub(ktime_get(), c->count_load_time));
	d = muldiv64(t, KVM_PIT_FREQ, NSEC_PER_SEC);

	switch (c->mode) {
	case 0:
	case 1:
	case 4:
	case 5:
		counter = (c->count - d) & 0xffff;
		break;
	case 3:
		/* XXX: may be incorrect for odd counts */
		counter = c->count - (mod_64((2 * d), c->count));
		break;
	default:
		counter = c->count - mod_64(d, c->count);
		break;
	}
	return counter;
}

static int pit_get_out(struct kvm *kvm, int channel)
{
	struct kvm_kpit_channel_state *c =
		&kvm->arch.vpit->pit_state.channels[channel];
	s64 d, t;
	int out;

	WARN_ON(!mutex_is_locked(&kvm->arch.vpit->pit_state.lock));

	t = ktime_to_ns(ktime_sub(ktime_get(), c->count_load_time));
	d = muldiv64(t, KVM_PIT_FREQ, NSEC_PER_SEC);

	switch (c->mode) {
	default:
	case 0:
		out = (d >= c->count);
		break;
	case 1:
		out = (d < c->count);
		break;
	case 2:
		out = ((mod_64(d, c->count) == 0) && (d != 0));
		break;
	case 3:
		out = (mod_64(d, c->count) < ((c->count + 1) >> 1));
		break;
	case 4:
	case 5:
		out = (d == c->count);
		break;
	}

	return out;
}

static void pit_latch_count(struct kvm *kvm, int channel)
{
	struct kvm_kpit_channel_state *c =
		&kvm->arch.vpit->pit_state.channels[channel];

	WARN_ON(!mutex_is_locked(&kvm->arch.vpit->pit_state.lock));

	if (!c->count_latched) {
		c->latched_count = pit_get_count(kvm, channel);
		c->count_latched = c->rw_mode;
	}
}

static void pit_latch_status(struct kvm *kvm, int channel)
{
	struct kvm_kpit_channel_state *c =
		&kvm->arch.vpit->pit_state.channels[channel];

	WARN_ON(!mutex_is_locked(&kvm->arch.vpit->pit_state.lock));

	if (!c->status_latched) {
		/* TODO: Return NULL COUNT (bit 6). */
		c->status = ((pit_get_out(kvm, channel) << 7) |
				(c->rw_mode << 4) |
				(c->mode << 1) |
				c->bcd);
		c->status_latched = 1;
	}
}

int __pit_timer_fn(struct kvm_kpit_state *ps)
{
	struct kvm_vcpu *vcpu0 = ps->pit->kvm->vcpus[0];
	struct kvm_kpit_timer *pt = &ps->pit_timer;

	atomic_inc(&pt->pending);
	smp_mb__after_atomic_inc();
	/* FIXME: handle case where the guest is in guest mode */
	if (vcpu0 && waitqueue_active(&vcpu0->wq)) {
		vcpu0->arch.mp_state = KVM_MP_STATE_RUNNABLE;
		wake_up_interruptible(&vcpu0->wq);
	}

	pt->timer.expires = ktime_add_ns(pt->timer.expires, pt->period);
	pt->scheduled = ktime_to_ns(pt->timer.expires);

	return (pt->period == 0 ? 0 : 1);
}

int pit_has_pending_timer(struct kvm_vcpu *vcpu)
{
	struct kvm_pit *pit = vcpu->kvm->arch.vpit;

	if (pit && vcpu->vcpu_id == 0)
		return atomic_read(&pit->pit_state.pit_timer.pending);

	return 0;
}

static enum hrtimer_restart pit_timer_fn(struct hrtimer *data)
{
	struct kvm_kpit_state *ps;
	int restart_timer = 0;

	ps = container_of(data, struct kvm_kpit_state, pit_timer.timer);

	restart_timer = __pit_timer_fn(ps);

	if (restart_timer)
		return HRTIMER_RESTART;
	else
		return HRTIMER_NORESTART;
}

static void destroy_pit_timer(struct kvm_kpit_timer *pt)
{
	pr_debug("pit: execute del timer!\n");
	hrtimer_cancel(&pt->timer);
}

static void create_pit_timer(struct kvm_kpit_timer *pt, u32 val, int is_period)
{
	s64 interval;

	interval = muldiv64(val, NSEC_PER_SEC, KVM_PIT_FREQ);

	pr_debug("pit: create pit timer, interval is %llu nsec\n", interval);

	/* TODO The new value only affected after the retriggered */
	hrtimer_cancel(&pt->timer);
	pt->period = (is_period == 0) ? 0 : interval;
	pt->timer.function = pit_timer_fn;
	atomic_set(&pt->pending, 0);

	hrtimer_start(&pt->timer, ktime_add_ns(ktime_get(), interval),
		      HRTIMER_MODE_ABS);
}

static void pit_load_count(struct kvm *kvm, int channel, u32 val)
{
	struct kvm_kpit_state *ps = &kvm->arch.vpit->pit_state;

	WARN_ON(!mutex_is_locked(&ps->lock));

	pr_debug("pit: load_count val is %d, channel is %d\n", val, channel);

	/*
	 * Though spec said the state of 8254 is undefined after power-up,
	 * seems some tricky OS like Windows XP depends on IRQ0 interrupt
	 * when booting up.
	 * So here setting initialize rate for it, and not a specific number
	 */
	if (val == 0)
		val = 0x10000;

	ps->channels[channel].count_load_time = ktime_get();
	ps->channels[channel].count = val;

	if (channel != 0)
		return;

	/* Two types of timer
	 * mode 1 is one shot, mode 2 is period, otherwise del timer */
	switch (ps->channels[0].mode) {
	case 1:
		create_pit_timer(&ps->pit_timer, val, 0);
		break;
	case 2:
		create_pit_timer(&ps->pit_timer, val, 1);
		break;
	default:
		destroy_pit_timer(&ps->pit_timer);
	}
}

void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val)
{
	mutex_lock(&kvm->arch.vpit->pit_state.lock);
	pit_load_count(kvm, channel, val);
	mutex_unlock(&kvm->arch.vpit->pit_state.lock);
}

static void pit_ioport_write(struct kvm_io_device *this,
			     gpa_t addr, int len, const void *data)
{
	struct kvm_pit *pit = (struct kvm_pit *)this->private;
	struct kvm_kpit_state *pit_state = &pit->pit_state;
	struct kvm *kvm = pit->kvm;
	int channel, access;
	struct kvm_kpit_channel_state *s;
	u32 val = *(u32 *) data;

	val  &= 0xff;
	addr &= KVM_PIT_CHANNEL_MASK;

	mutex_lock(&pit_state->lock);

	if (val != 0)
		pr_debug("pit: write addr is 0x%x, len is %d, val is 0x%x\n",
			  (unsigned int)addr, len, val);

	if (addr == 3) {
		channel = val >> 6;
		if (channel == 3) {
			/* Read-Back Command. */
			for (channel = 0; channel < 3; channel++) {
				s = &pit_state->channels[channel];
				if (val & (2 << channel)) {
					if (!(val & 0x20))
						pit_latch_count(kvm, channel);
					if (!(val & 0x10))
						pit_latch_status(kvm, channel);
				}
			}
		} else {
			/* Select Counter <channel>. */
			s = &pit_state->channels[channel];
			access = (val >> 4) & KVM_PIT_CHANNEL_MASK;
			if (access == 0) {
				pit_latch_count(kvm, channel);
			} else {
				s->rw_mode = access;
				s->read_state = access;
				s->write_state = access;
				s->mode = (val >> 1) & 7;
				if (s->mode > 5)
					s->mode -= 4;
				s->bcd = val & 1;
			}
		}
	} else {
		/* Write Count. */
		s = &pit_state->channels[addr];
		switch (s->write_state) {
		default:
		case RW_STATE_LSB:
			pit_load_count(kvm, addr, val);
			break;
		case RW_STATE_MSB:
			pit_load_count(kvm, addr, val << 8);
			break;
		case RW_STATE_WORD0:
			s->write_latch = val;
			s->write_state = RW_STATE_WORD1;
			break;
		case RW_STATE_WORD1:
			pit_load_count(kvm, addr, s->write_latch | (val << 8));
			s->write_state = RW_STATE_WORD0;
			break;
		}
	}

	mutex_unlock(&pit_state->lock);
}

static void pit_ioport_read(struct kvm_io_device *this,
			    gpa_t addr, int len, void *data)
{
	struct kvm_pit *pit = (struct kvm_pit *)this->private;
	struct kvm_kpit_state *pit_state = &pit->pit_state;
	struct kvm *kvm = pit->kvm;
	int ret, count;
	struct kvm_kpit_channel_state *s;

	addr &= KVM_PIT_CHANNEL_MASK;
	s = &pit_state->channels[addr];

	mutex_lock(&pit_state->lock);

	if (s->status_latched) {
		s->status_latched = 0;
		ret = s->status;
	} else if (s->count_latched) {
		switch (s->count_latched) {
		default:
		case RW_STATE_LSB:
			ret = s->latched_count & 0xff;
			s->count_latched = 0;
			break;
		case RW_STATE_MSB:
			ret = s->latched_count >> 8;
			s->count_latched = 0;
			break;
		case RW_STATE_WORD0:
			ret = s->latched_count & 0xff;
			s->count_latched = RW_STATE_MSB;
			break;
		}
	} else {
		switch (s->read_state) {
		default:
		case RW_STATE_LSB:
			count = pit_get_count(kvm, addr);
			ret = count & 0xff;
			break;
		case RW_STATE_MSB:
			count = pit_get_count(kvm, addr);
			ret = (count >> 8) & 0xff;
			break;
		case RW_STATE_WORD0:
			count = pit_get_count(kvm, addr);
			ret = count & 0xff;
			s->read_state = RW_STATE_WORD1;
			break;
		case RW_STATE_WORD1:
			count = pit_get_count(kvm, addr);
			ret = (count >> 8) & 0xff;
			s->read_state = RW_STATE_WORD0;
			break;
		}
	}

	if (len > sizeof(ret))
		len = sizeof(ret);
	memcpy(data, (char *)&ret, len);

	mutex_unlock(&pit_state->lock);
}

static int pit_in_range(struct kvm_io_device *this, gpa_t addr)
{
	return ((addr >= KVM_PIT_BASE_ADDRESS) &&
		(addr < KVM_PIT_BASE_ADDRESS + KVM_PIT_MEM_LENGTH));
}

static void speaker_ioport_write(struct kvm_io_device *this,
				 gpa_t addr, int len, const void *data)
{
	struct kvm_pit *pit = (struct kvm_pit *)this->private;
	struct kvm_kpit_state *pit_state = &pit->pit_state;
	struct kvm *kvm = pit->kvm;
	u32 val = *(u32 *) data;

	mutex_lock(&pit_state->lock);
	pit_state->speaker_data_on = (val >> 1) & 1;
	pit_set_gate(kvm, 2, val & 1);
	mutex_unlock(&pit_state->lock);
}

static void speaker_ioport_read(struct kvm_io_device *this,
				gpa_t addr, int len, void *data)
{
	struct kvm_pit *pit = (struct kvm_pit *)this->private;
	struct kvm_kpit_state *pit_state = &pit->pit_state;
	struct kvm *kvm = pit->kvm;
	unsigned int refresh_clock;
	int ret;

	/* Refresh clock toggles at about 15us. We approximate as 2^14ns. */
	refresh_clock = ((unsigned int)ktime_to_ns(ktime_get()) >> 14) & 1;

	mutex_lock(&pit_state->lock);
	ret = ((pit_state->speaker_data_on << 1) | pit_get_gate(kvm, 2) |
		(pit_get_out(kvm, 2) << 5) | (refresh_clock << 4));
	if (len > sizeof(ret))
		len = sizeof(ret);
	memcpy(data, (char *)&ret, len);
	mutex_unlock(&pit_state->lock);
}

static int speaker_in_range(struct kvm_io_device *this, gpa_t addr)
{
	return (addr == KVM_SPEAKER_BASE_ADDRESS);
}

void kvm_pit_reset(struct kvm_pit *pit)
{
	int i;
	struct kvm_kpit_channel_state *c;

	mutex_lock(&pit->pit_state.lock);
	for (i = 0; i < 3; i++) {
		c = &pit->pit_state.channels[i];
		c->mode = 0xff;
		c->gate = (i != 2);
		pit_load_count(pit->kvm, i, 0);
	}
	mutex_unlock(&pit->pit_state.lock);

	atomic_set(&pit->pit_state.pit_timer.pending, 0);
	pit->pit_state.inject_pending = 1;
}

struct kvm_pit *kvm_create_pit(struct kvm *kvm)
{
	struct kvm_pit *pit;
	struct kvm_kpit_state *pit_state;

	pit = kzalloc(sizeof(struct kvm_pit), GFP_KERNEL);
	if (!pit)
		return NULL;

	mutex_init(&pit->pit_state.lock);
	mutex_lock(&pit->pit_state.lock);

	/* Initialize PIO device */
	pit->dev.read = pit_ioport_read;
	pit->dev.write = pit_ioport_write;
	pit->dev.in_range = pit_in_range;
	pit->dev.private = pit;
	kvm_io_bus_register_dev(&kvm->pio_bus, &pit->dev);

	pit->speaker_dev.read = speaker_ioport_read;
	pit->speaker_dev.write = speaker_ioport_write;
	pit->speaker_dev.in_range = speaker_in_range;
	pit->speaker_dev.private = pit;
	kvm_io_bus_register_dev(&kvm->pio_bus, &pit->speaker_dev);

	kvm->arch.vpit = pit;
	pit->kvm = kvm;

	pit_state = &pit->pit_state;
	pit_state->pit = pit;
	hrtimer_init(&pit_state->pit_timer.timer,
		     CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
	mutex_unlock(&pit->pit_state.lock);

	kvm_pit_reset(pit);

	return pit;
}

void kvm_free_pit(struct kvm *kvm)
{
	struct hrtimer *timer;

	if (kvm->arch.vpit) {
		mutex_lock(&kvm->arch.vpit->pit_state.lock);
		timer = &kvm->arch.vpit->pit_state.pit_timer.timer;
		hrtimer_cancel(timer);
		mutex_unlock(&kvm->arch.vpit->pit_state.lock);
		kfree(kvm->arch.vpit);
	}
}

void __inject_pit_timer_intr(struct kvm *kvm)
{
	mutex_lock(&kvm->lock);
	kvm_ioapic_set_irq(kvm->arch.vioapic, 0, 1);
	kvm_ioapic_set_irq(kvm->arch.vioapic, 0, 0);
	kvm_pic_set_irq(pic_irqchip(kvm), 0, 1);
	kvm_pic_set_irq(pic_irqchip(kvm), 0, 0);
	mutex_unlock(&kvm->lock);
}

void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu)
{
	struct kvm_pit *pit = vcpu->kvm->arch.vpit;
	struct kvm *kvm = vcpu->kvm;
	struct kvm_kpit_state *ps;

	if (vcpu && pit) {
		ps = &pit->pit_state;

		/* Try to inject pending interrupts when:
		 * 1. Pending exists
		 * 2. Last interrupt was accepted or waited for too long time*/
		if (atomic_read(&ps->pit_timer.pending) &&
		    (ps->inject_pending ||
		    (jiffies - ps->last_injected_time
				>= KVM_MAX_PIT_INTR_INTERVAL))) {
			ps->inject_pending = 0;
			__inject_pit_timer_intr(kvm);
			ps->last_injected_time = jiffies;
		}
	}
}

void kvm_pit_timer_intr_post(struct kvm_vcpu *vcpu, int vec)
{
	struct kvm_arch *arch = &vcpu->kvm->arch;
	struct kvm_kpit_state *ps;

	if (vcpu && arch->vpit) {
		ps = &arch->vpit->pit_state;
		if (atomic_read(&ps->pit_timer.pending) &&
		(((arch->vpic->pics[0].imr & 1) == 0 &&
		  arch->vpic->pics[0].irq_base == vec) ||
		  (arch->vioapic->redirtbl[0].fields.vector == vec &&
		  arch->vioapic->redirtbl[0].fields.mask != 1))) {
			ps->inject_pending = 1;
			atomic_dec(&ps->pit_timer.pending);
			ps->channels[0].count_load_time = ktime_get();
		}
	}
}
