#include "libcflat.h"
#include "apic.h"
#include "msr.h"
#include "processor.h"
#include "smp.h"
#include "asm/barrier.h"

/* xAPIC and I/O APIC are identify mapped, and never relocated. */
static void *g_apic = (void *)APIC_DEFAULT_PHYS_BASE;
static void *g_ioapic = (void *)IO_APIC_DEFAULT_PHYS_BASE;

u8 id_map[MAX_TEST_CPUS];

struct apic_ops {
	u32 (*reg_read)(unsigned reg);
	void (*reg_write)(unsigned reg, u32 val);
	void (*icr_write)(u32 val, u32 dest);
	u32 (*id)(void);
};

static struct apic_ops *get_apic_ops(void)
{
	return this_cpu_read_apic_ops();
}

static void outb(unsigned char data, unsigned short port)
{
	asm volatile ("out %0, %1" : : "a"(data), "d"(port));
}

void eoi(void)
{
	apic_write(APIC_EOI, 0);
}

static u32 xapic_read(unsigned reg)
{
	return *(volatile u32 *)(g_apic + reg);
}

static void xapic_write(unsigned reg, u32 val)
{
	*(volatile u32 *)(g_apic + reg) = val;
}

static void xapic_icr_write(u32 val, u32 dest)
{
	while (xapic_read(APIC_ICR) & APIC_ICR_BUSY)
		;
	xapic_write(APIC_ICR2, dest << 24);
	xapic_write(APIC_ICR, val);
}

static uint32_t xapic_id(void)
{
	return xapic_read(APIC_ID) >> 24;
}

static const struct apic_ops xapic_ops = {
	.reg_read = xapic_read,
	.reg_write = xapic_write,
	.icr_write = xapic_icr_write,
	.id = xapic_id,
};

static u32 x2apic_read(unsigned reg)
{
	unsigned a, d;

	asm volatile ("rdmsr" : "=a"(a), "=d"(d) : "c"(APIC_BASE_MSR + reg/16));
	return a | (u64)d << 32;
}

static void x2apic_write(unsigned reg, u32 val)
{
	asm volatile ("wrmsr" : : "a"(val), "d"(0), "c"(APIC_BASE_MSR + reg/16));
}

static void x2apic_icr_write(u32 val, u32 dest)
{
	mb();
	asm volatile ("wrmsr" : : "a"(val), "d"(dest),
		      "c"(APIC_BASE_MSR + APIC_ICR/16));
}

static uint32_t x2apic_id(void)
{
	return x2apic_read(APIC_ID);
}

static const struct apic_ops x2apic_ops = {
	.reg_read = x2apic_read,
	.reg_write = x2apic_write,
	.icr_write = x2apic_icr_write,
	.id = x2apic_id,
};

u32 apic_read(unsigned reg)
{
	return get_apic_ops()->reg_read(reg);
}

void apic_write(unsigned reg, u32 val)
{
	get_apic_ops()->reg_write(reg, val);
}

bool apic_read_bit(unsigned reg, int n)
{
	reg += (n >> 5) << 4;
	n &= 31;
	return (apic_read(reg) & (1 << n)) != 0;
}

void apic_icr_write(u32 val, u32 dest)
{
	get_apic_ops()->icr_write(val, dest);
}

uint32_t apic_id(void)
{
	return get_apic_ops()->id();
}

uint8_t apic_get_tpr(void)
{
	unsigned long tpr;

#ifdef __x86_64__
	asm volatile ("mov %%cr8, %0" : "=r"(tpr));
#else
	tpr = apic_read(APIC_TASKPRI) >> 4;
#endif
	return tpr;
}

void apic_set_tpr(uint8_t tpr)
{
#ifdef __x86_64__
	asm volatile ("mov %0, %%cr8" : : "r"((unsigned long) tpr));
#else
	apic_write(APIC_TASKPRI, tpr << 4);
#endif
}

int enable_x2apic(void)
{
	unsigned a, b, c, d;

	asm ("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "0"(1));

	if (c & (1 << 21)) {
		asm ("rdmsr" : "=a"(a), "=d"(d) : "c"(MSR_IA32_APICBASE));
		a |= 1 << 10;
		asm ("wrmsr" : : "a"(a), "d"(d), "c"(MSR_IA32_APICBASE));
		this_cpu_write_apic_ops((void *)&x2apic_ops);
		return 1;
	} else {
		return 0;
	}
}

uint32_t pre_boot_apic_id(void)
{
	u32 msr_lo, msr_hi;

	asm ("rdmsr" : "=a"(msr_lo), "=d"(msr_hi) : "c"(MSR_IA32_APICBASE));

	return (msr_lo & APIC_EXTD) ? x2apic_id() : xapic_id();
}

void disable_apic(void)
{
	wrmsr(MSR_IA32_APICBASE, rdmsr(MSR_IA32_APICBASE) & ~(APIC_EN | APIC_EXTD));
	this_cpu_write_apic_ops((void *)&xapic_ops);
}

void reset_apic(void)
{
	disable_apic();
	wrmsr(MSR_IA32_APICBASE, rdmsr(MSR_IA32_APICBASE) | APIC_EN);
	xapic_write(APIC_SPIV, 0x1ff);
}

u32 ioapic_read_reg(unsigned reg)
{
	*(volatile u32 *)g_ioapic = reg;
	return *(volatile u32 *)(g_ioapic + 0x10);
}

void ioapic_write_reg(unsigned reg, u32 value)
{
	*(volatile u32 *)g_ioapic = reg;
	*(volatile u32 *)(g_ioapic + 0x10) = value;
}

void ioapic_write_redir(unsigned line, ioapic_redir_entry_t e)
{
	ioapic_write_reg(0x10 + line * 2 + 0, ((u32 *)&e)[0]);
	ioapic_write_reg(0x10 + line * 2 + 1, ((u32 *)&e)[1]);
}

ioapic_redir_entry_t ioapic_read_redir(unsigned line)
{
	ioapic_redir_entry_t e;

	((u32 *)&e)[0] = ioapic_read_reg(0x10 + line * 2 + 0);
	((u32 *)&e)[1] = ioapic_read_reg(0x10 + line * 2 + 1);
	return e;

}

void ioapic_set_redir(unsigned line, unsigned vec,
			     trigger_mode_t trig_mode)
{
	ioapic_redir_entry_t e = {
		.vector = vec,
		.delivery_mode = 0,
		.trig_mode = trig_mode,
	};

	ioapic_write_redir(line, e);
}

void set_mask(unsigned line, int mask)
{
	ioapic_redir_entry_t e = ioapic_read_redir(line);

	e.mask = mask;
	ioapic_write_redir(line, e);
}

void set_irq_line(unsigned line, int val)
{
	asm volatile("out %0, %1" : : "a"((u8)val), "d"((u16)(0x2000 + line)));
}

void enable_apic(void)
{
	printf("enabling apic\n");
	xapic_write(APIC_SPIV, 0x1ff);
}

void mask_pic_interrupts(void)
{
	outb(0xff, 0x21);
	outb(0xff, 0xa1);
}

void init_apic_map(void)
{
	unsigned int i, j = 0;

	for (i = 0; i < MAX_TEST_CPUS; i++) {
		if ((1ul << (i % 8)) & (online_cpus[i / 8]))
			id_map[j++] = i;
	}
}

void apic_setup_timer(int vector, u32 mode)
{
	apic_cleanup_timer();

	assert((mode & APIC_LVT_TIMER_MASK) == mode);

	apic_write(APIC_TDCR, APIC_TDR_DIV_1);
	apic_write(APIC_LVTT, vector | mode);
}

void apic_start_timer(u32 value)
{
	/*
	 * APIC timer runs at the 'core crystal clock', divided by the value in
	 * APIC_TDCR.
	 */
	apic_write(APIC_TMICT, value);
}

void apic_stop_timer(void)
{
	apic_write(APIC_TMICT, 0);
}

void apic_cleanup_timer(void)
{
	u32 lvtt = apic_read(APIC_LVTT);

	/* Stop the timer/counter. */
	apic_stop_timer();

	/* Mask the timer interrupt in the local vector table. */
	apic_write(APIC_LVTT, lvtt | APIC_LVT_MASKED);

	/* Enable interrupts to ensure any pending timer IRQs are serviced. */
	sti_nop_cli();
}
