/*
 * Copyright (c) 2018 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include "serial.h"
#include "vgacon.h"
#include "printf.h"
#include "xuk.h"

/* Tiny demonstration of the core64 code.  Implements enough of an
 * "OS" layer to do some simple unit testing.
 */

static void putchar(int c)
{
	serial_putc(c);
	vgacon_putc(c);
}

void test_timers(void)
{
	/* Quickly calibrate the timers against each other.  Note that
	 * the APIC is counting DOWN instead of up!  Seems like on
	 * qemu, the APIC base frequency is 3.7x slower than the tsc.
	 * Looking at source, it seems like APIC is uniformly shifted
	 * down from a nominal 1Ghz reference
	 * (i.e. qemu_get_time_ns()), where the TSC is based on
	 * cpu_get_ticks() and thus pulls in wall clock time & such.
	 * If you specify "-icount shift=1", then they synchronize
	 * properly.
	 */
	int tsc0, apic0, tsc1, apic1;

	__asm__ volatile("rdtsc" : "=a"(tsc0) : : "rdx");
	apic0 = _apic.CURR_COUNT;
	do {
		/* Qemu misbehaves if I spam these registers. */
		for (int i = 0; i < 1000; i++) {
			__asm__ volatile("nop");
		}

		__asm__ volatile("rdtsc" : "=a"(tsc1) : : "rdx");
		apic1 = _apic.CURR_COUNT;
	} while ((tsc1 - tsc0) < 10000 || (apic0 - apic1) < 10000);
	printf("tsc %d apic %d\n", tsc1 - tsc0, apic0 - apic1);
}

unsigned int _init_cpu_stack(int cpu)
{
	return (long)alloc_page(0) + 4096;
}

void handler_timer(void *arg, int err)
{
	printf("Timer expired on CPU%d\n", (int)(long)xuk_get_f_ptr());
}

void handler_f3(void *arg, int err)
{
	printf("f3 handler on cpu%d arg %x, triggering INT 0xff\n",
	       (int)(long)xuk_get_f_ptr(), (int)(long)arg);
	__asm__ volatile("int $0xff");
	printf("end f3 handler\n");
}

void _unhandled_vector(int vector, int err, struct xuk_entry_frame *f)
{
	(void)f;
	_putchar = putchar;
	printf("Unhandled vector %d (err %xh) on CPU%d\n",
	       vector, err, (int)(long)xuk_get_f_ptr());
}

void _isr_entry(void)
{
}

void *_isr_exit_restore_stack(void *interrupted)
{
	/* Somewhat hacky test of the ISR exit modes.  Two ways of
	 * specifying "this stack", one of which does the full spill
	 * and restore and one shortcuts that due to the NULL
	 * return
	 */
	if (rdtsc() & 1) {
		return interrupted;
	} else {
		return 0;
	}
}

void *switch_back_to;

void switch_back(int arg1, int arg2, int arg3)
{
	printf("Switching back (%d, %d, %d) sbt %xh\n",
	       arg1, arg2, arg3, (int)(long)switch_back_to);
	xuk_switch(switch_back_to, &switch_back_to);
}

void test_switch(void)
{
	static unsigned long long stack[256];
	long args[] = { 5, 4, 3 };
	int eflags = 0x20; /* interrupts disabled */

	long handle = xuk_setup_stack((long)(sizeof(stack) + (char *)stack),
				      switch_back, eflags, args, 3);

	printf("Switching to %xh (stack %xh)\n",
	       (int)handle, (int)(long)&stack[0]);
	__asm__ volatile("cli");
	xuk_switch((void *)handle, &switch_back_to);
	__asm__ volatile("sti");
	printf("Back from switch\n");
}

void local_ipi_handler(void *arg, int err)
{
	printf("local IPI handler on CPU%d\n", (int)(long)xuk_get_f_ptr());
}

/* Sends an IPI to the current CPU and validates it ran */
void test_local_ipi(void)
{
	printf("Testing a local IPI on CPU%d\n", (int)(long)xuk_get_f_ptr());

	_apic.ICR_HI = (struct apic_icr_hi) {};
	_apic.ICR_LO = (struct apic_icr_lo) {
		.delivery_mode = FIXED,
		.vector = 0x90,
		.shorthand = SELF,
	};
}

void _cpu_start(int cpu)
{
	_putchar = putchar;
	printf("Entering demo kernel\n");

	/* Make sure the FS/GS pointers work, then set F to store our
	 * CPU ID
	 */
	xuk_set_f_ptr(cpu, (void *)(long)(0x19283700 + cpu));
	xuk_set_g_ptr(cpu, (void *)(long)(0xabacad00 + cpu));
	printf("fptr %p gptr %p\n", xuk_get_f_ptr(), xuk_get_g_ptr());

	xuk_set_f_ptr(cpu, (void *)(long)cpu);

	/* Set up this CPU's timer */
	/* FIXME: this sets up a separate vector for every CPU's
	 * timer, and we'll run out.  They should share the vector but
	 * still have individually-set APIC config.  Probably wants a
	 * "timer" API
	 */
	xuk_set_isr(INT_APIC_LVT_TIMER, 10, handler_timer, 0);
	_apic.INIT_COUNT = 5000000;
	test_timers();

	if (cpu == 0) {
		xuk_set_isr(0x1f3, 0, (void *)handler_f3, (void *)0x12345678);
	}

	__asm__ volatile("int $0xf3");

	/* Fire it all up */
	printf("Enabling Interrupts\n");
	__asm__ volatile("sti");
	printf("Interrupts are unmasked (eflags %xh), here we go...\n",
	       eflags());

	/* Wait a teeny bit then send an IPI to CPU0, which will hit
	 * the unhandled_vector handler
	 */
	if (cpu == 1) {
		int t0 = rdtsc();

		while (rdtsc() - t0 < 1000000) {
		}

		_apic.ICR_HI = (struct apic_icr_hi) {
			.destination = 0
		};
		_apic.ICR_LO = (struct apic_icr_lo) {
			.delivery_mode = FIXED,
			.vector = 66,
		};
		while (_apic.ICR_LO.send_pending) {
		}
	}

	test_switch();

	xuk_set_isr(XUK_INT_RAW_VECTOR(0x90), -1, local_ipi_handler, 0);
	test_local_ipi();

	printf("CPU%d initialized, sleeping\n", cpu);
	while (1) {
		__asm__ volatile("hlt");
	}
}
