/* Copyright (c) 2009 The Regents of the University of California
 * David (Yu) Zhu <yuzhu@cs.berkeley.edu>
 * Barret Rhoden <brho@cs.berkeley.edu>
 *
 * See LICENSE for details. */

#include <arch/x86.h>
#include <arch/arch.h>
#include <arch/pic.h>
#include <arch/apic.h>
#include <time.h>
#include <trap.h>
#include <assert.h>
#include <stdio.h>
#include <ros/procinfo.h>
#include <arch/uaccess.h>

static uint16_t pit_divisor;
static uint8_t pit_mode;

static uint64_t compute_tsc_freq(void)
{
	uint64_t tscval[2];

	/* some boards have this unmasked early on. */
	pic_mask_irq(0, 0 + PIC1_OFFSET);
	pit_set_timer(0xffff, TIMER_RATEGEN);
	tscval[0] = read_tsc();
	udelay_pit(1000000);
	tscval[1] = read_tsc();
	return tscval[1] - tscval[0];
}

static void set_tsc_freq(void)
{
	uint64_t msr_val, tsc_freq = 0;
	bool computed = FALSE;

	if (!read_msr_safe(MSR_PLATFORM_INFO, &msr_val))
		tsc_freq = __proc_global_info.bus_freq * ((msr_val >> 8) & 0xff);
	/* Even if we have the MSR, it might have given us 0. (QEMU). */
	if (!tsc_freq) {
		tsc_freq = compute_tsc_freq();
		computed = TRUE;
	}
	__proc_global_info.tsc_freq = tsc_freq;
	printk("TSC Frequency: %llu%s\n", tsc_freq, computed ? " (computed)" : "");
}

static uint64_t compute_bus_freq(void)
{
	uint32_t timercount[2];

	__lapic_set_timer(0xffffffff, IdtLAPIC_TIMER, FALSE,
	                  LAPIC_TIMER_DIVISOR_BITS);
	// Mask the LAPIC Timer, so we never receive this interrupt (minor race)
	mask_lapic_lvt(MSR_LAPIC_LVT_TIMER);
	timercount[0] = apicrget(MSR_LAPIC_CURRENT_COUNT);
	udelay_pit(1000000);
	timercount[1] = apicrget(MSR_LAPIC_CURRENT_COUNT);
	/* The time base for the timer is derived from the processor's bus clock,
	 * divided by the value specified in the divide configuration register.
	 * Note we mult and div by the divisor, saving the actual freq (even though
	 * we don't use it yet). */
	return (timercount[0] - timercount[1]) * LAPIC_TIMER_DIVISOR_VAL;
}

static uint64_t lookup_bus_freq(void)
{
	/* Got these from the good book for any model supporting MSR_PLATFORM_INFO.
	 * If they don't support that MSR, we're going to compute the TSC anyways.
	 *
	 * A couple models weren't in the book, but were reported at:
	 * http://a4lg.com/tech/x86/database/x86-families-and-models.en.html.
	 * Feel free to add more.  If we fail here, we'll compute it manually and be
	 * off slightly. */
	switch ((x86_family << 16) | x86_model) {
	case 0x6001a:
	case 0x6001e:
	case 0x6001f:
	case 0x6002e:
		/* Nehalem */
		return 133333333;
	case 0x60025:
	case 0x6002c:
	case 0x6002f:	/* from a4lg.com */
		/* Westmere */
		return 133333333;
	case 0x6002a:
	case 0x6002d:
		/* Sandy Bridge */
		return 100000000;
	case 0x6003a:	/* from a4lg.com */
	case 0x6003e:
		/* Ivy Bridge */
		return 100000000;
	case 0x6003c:
	case 0x6003f:
	case 0x60045:
	case 0x60046:
		/* Haswell */
		return 100000000;
	case 0x6003d:
	case 0x6004f:
	case 0x60056:
		/* Broadwell */
		return 100000000;
	case 0x6004d:
		/* Sky Lake */
		return 100000000;
	case 0x60057:
		/* Knights Landing */
		return 100000000;
	}
	return 0;
}

static void set_bus_freq(void)
{
	uint64_t bus_freq;
	bool computed = FALSE;

	bus_freq = lookup_bus_freq();
	if (!bus_freq) {
		bus_freq = compute_bus_freq();
		computed = TRUE;
	}
	__proc_global_info.bus_freq = bus_freq;
	printk("Bus Frequency: %llu%s\n", bus_freq, computed ? " (computed)" : "");
}

void timer_init(void)
{
	set_bus_freq();
	assert(__proc_global_info.bus_freq);
	set_tsc_freq();
}

void pit_set_timer(uint32_t divisor, uint32_t mode)
{
	if (divisor & 0xffff0000)
		warn("Divisor too large!");
	mode = TIMER_SEL0|TIMER_16BIT|mode;
	outb(TIMER_MODE, mode);
	outb(TIMER_CNTR0, divisor & 0xff);
	outb(TIMER_CNTR0, (divisor >> 8) );
	pit_mode = mode;
	pit_divisor = divisor;
	// cprintf("timer mode set to %d, divisor %d\n",mode, divisor);
}

static int getpit()
{
    int high, low;
	// TODO: need a lock to protect access to PIT

    /* Select counter 0 and latch counter value. */
    outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);

    low = inb(TIMER_CNTR0);
    high = inb(TIMER_CNTR0);

    return ((high << 8) | low);
}

// forces cpu to relax for usec miliseconds.  declared in kern/include/time.h
void udelay(uint64_t usec)
{
	#if !defined(__BOCHS__)
	if (__proc_global_info.tsc_freq != 0)
	{
		uint64_t start, end, now;

		start = read_tsc();
        end = start + usec2tsc(usec);
        //cprintf("start %llu, end %llu\n", start, end);
		if (end == 0) cprintf("This is terribly wrong \n");
		do {
            cpu_relax();
            now = read_tsc();
			//cprintf("now %llu\n", now);
		} while (now < end || (now > start && end < start));
        return;

	} else
	#endif
	{
		udelay_pit(usec);
	}
}

void udelay_pit(uint64_t usec)
{
	int64_t delta, prev_tick, tick, ticks_left;

	if (usec <= 0)
		return;

	prev_tick = getpit();
	/*
	 * Calculate ticks as (usec * (i8254_freq / 1e6)) rounded up
	 * without using floating point and without any avoidable overflows.
	 */
	ticks_left = ((usec * PIT_FREQ) + 999999) / 1000000;
	while (ticks_left > 0) {
		tick = getpit();
		delta = prev_tick - tick;
		prev_tick = tick;
		if (delta < 0) {
			// counter looped around during the delta time period
			delta += pit_divisor; // maximum count
			if (delta < 0)
				delta = 0;
		}
		ticks_left -= delta;
	}
}

uint64_t gettimer(void)
{
	return read_tsc();
}

uint64_t getfreq(void)
{
	return __proc_global_info.tsc_freq;
}

void set_core_timer(uint32_t usec, bool periodic)
{
	if (usec)
		lapic_set_timer(usec, periodic);
	else
		lapic_disable_timer();
}
