/* 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(void)
{
	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();
}
