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

#include <arch/mmu.h>
#include <arch/x86.h>
#include <arch/arch.h>
#include <arch/apic.h>
#include <trap.h>
#include <time.h>
#include <assert.h>
#include <stdio.h>
#include <bitmask.h>
#include <arch/topology.h>
#include <ros/procinfo.h>

bool lapic_check_spurious(int trap_nr)
{
	/* FYI: lapic_spurious is 255 on qemu and 15 on the nehalem..  We actually
	 * can set bits 4-7, and P6s have 0-3 hardwired to 0.  YMMV.  NxM seems to
	 * say the lower 3 bits are usually 1.  We'll see if the assert trips.
	 *
	 * The SDM recommends not using the spurious vector for any other IRQs (LVT
	 * or IOAPIC RTE), since the handlers don't send an EOI.  However, our check
	 * here allows us to use the vector since we can tell the diff btw a
	 * spurious and a real IRQ. */
	assert(IdtLAPIC_SPURIOUS == (apicrget(MSR_LAPIC_SPURIOUS) & 0xff));
	/* Note the lapic's vectors are not shifted by an offset. */
	if ((trap_nr == IdtLAPIC_SPURIOUS) &&
	     !lapic_get_isr_bit(IdtLAPIC_SPURIOUS)) {
		/* i'm still curious about these */
		printk("Spurious LAPIC irq %d, core %d!\n", IdtLAPIC_SPURIOUS,
		       core_id());
		lapic_print_isr();
		return TRUE;
	}
	return FALSE;
}

/* Debugging helper.  Note the ISR/IRR are 32 bits at a time, spaced every 16
 * bytes in the LAPIC address space. */
void lapic_print_isr(void)
{
	printk("LAPIC ISR on core %d\n--------------\n", core_id());
	for (int i = 7; i >= 0; i--)
		printk("%3d-%3d: %p\n", (i + 1) * 32 - 1, i * 32,
			apicrget(MSR_LAPIC_ISR_START + i));
	printk("LAPIC IRR on core %d\n--------------\n", core_id());
	for (int i = 7; i >= 0; i--)
		printk("%3d-%3d: %p\n", (i + 1) * 32 - 1, i * 32,
			apicrget(MSR_LAPIC_IRR_START + i));
}

/* Returns TRUE if the bit 'vector' is set in the LAPIC ISR or IRR (whatever you
 * pass in.  These registers consist of 8, 32 byte registers spaced every 16
 * bytes from the base in the LAPIC. */
static bool __lapic_get_isrr_bit(unsigned long base, uint8_t vector)
{
	int which_reg = vector >> 5;	/* 32 bits per reg */
	uintptr_t lapic_reg = base + which_reg;

	return (apicrget(lapic_reg) & (1 << (vector % 32)) ? 1 : 0);
}

bool lapic_get_isr_bit(uint8_t vector)
{
	return __lapic_get_isrr_bit(MSR_LAPIC_ISR_START, vector);
}

bool lapic_get_irr_bit(uint8_t vector)
{
	return __lapic_get_isrr_bit(MSR_LAPIC_IRR_START, vector);
}

void lapic_mask_irq(struct irq_handler *unused, int apic_vector)
{
	uintptr_t mm_reg;
	if (apic_vector < IdtLAPIC || IdtLAPIC + 4 < apic_vector) {
		warn("Bad apic vector %d\n", apic_vector);
		return;
	}
	mm_reg = MSR_LAPIC_LVT_TIMER + (apic_vector - IdtLAPIC);
	apicrput(mm_reg, apicrget(mm_reg) | LAPIC_LVT_MASK);
}

void lapic_unmask_irq(struct irq_handler *unused, int apic_vector)
{
	uintptr_t mm_reg;
	if (apic_vector < IdtLAPIC || IdtLAPIC + 4 < apic_vector) {
		warn("Bad apic vector %d\n", apic_vector);
		return;
	}
	mm_reg = MSR_LAPIC_LVT_TIMER + (apic_vector - IdtLAPIC);
	apicrput(mm_reg, apicrget(mm_reg) & ~LAPIC_LVT_MASK);
}

/* This works for any interrupt that goes through the LAPIC, but not things like
 * ExtInts.  To prevent abuse, we'll use it just for IPIs for now (which only
 * come via the APIC).
 *
 * We only check the ISR, due to how we send EOIs.  Since we don't send til
 * after handlers return, the ISR will show pending for the current IRQ.  It is
 * the EOI that clears the bit from the ISR. */
bool ipi_is_pending(uint8_t vector)
{
	return lapic_get_isr_bit(vector);
}

/*
 * Sets the LAPIC timer to go off after a certain number of ticks.  The primary
 * clock freq is actually the bus clock, which we figure out during timer_init
 * Unmasking is implied.  Ref SDM, 3A, 9.6.4
 */
void __lapic_set_timer(uint32_t ticks, uint8_t vec, bool periodic, uint8_t div)
{
#ifdef CONFIG_LOUSY_LAPIC_TIMER
	/* qemu without kvm seems to delay timer IRQs on occasion, and needs extra
	 * IRQs from any source to get them delivered.  periodic does the trick. */
	periodic = TRUE;
#endif
	// clears bottom bit and then set divider
	apicrput(MSR_LAPIC_DIVIDE_CONFIG_REG,
	         (apicrget(MSR_LAPIC_DIVIDE_CONFIG_REG) & ~0xf) | (div & 0xf));
	// set LVT with interrupt handling information.  also unmasks.
	apicrput(MSR_LAPIC_LVT_TIMER, vec | (periodic << 17));
	apicrput(MSR_LAPIC_INITIAL_COUNT, ticks);
	// For debugging when we expand this
	//cprintf("LAPIC LVT Timer: 0x%08x\n", apicrget(MSR_LAPIC_LVT_TIMER));
	//cprintf("LAPIC Init Count: 0x%08x\n", apicrget(MSR_LAPIC_INITIAL_COUNT));
	//cprintf("LAPIC Current Count: 0x%08x\n",
	//        apicrget(MSR_LAPIC_CURRENT_COUNT));
}

void lapic_set_timer(uint32_t usec, bool periodic)
{
	/* If we overflowed a uint32, send in the max timer possible.  The lapic can
	 * only handle a 32 bit.  We could muck with changing the divisor, but even
	 * then, we might not be able to match 4000 sec (based on the bus speed).
	 * The kernel alarm code can handle spurious timer interrupts, so we just
	 * set the timer for as close as we can get to the desired time. */
	uint64_t ticks64 = (usec * __proc_global_info.bus_freq)
	                   / LAPIC_TIMER_DIVISOR_VAL / 1000000;
	uint32_t ticks32 = ((ticks64 >> 32) ? 0xffffffff : ticks64);
	assert(ticks32 > 0);
	__lapic_set_timer(ticks32, IdtLAPIC_TIMER, periodic,
	                  LAPIC_TIMER_DIVISOR_BITS);
}

uint32_t lapic_get_default_id(void)
{
	uint32_t ebx;
	cpuid(0x1, 0x0, 0, &ebx, 0, 0);
	// p6 family only uses 4 bits here, and 0xf is reserved for the IOAPIC
	return (ebx & 0xFF000000) >> 24;
}
