/* See COPYRIGHT for copyright information. */

#include <ros/common.h>
#include <smp.h>
#include <arch/x86.h>
#include <arch/pci.h>
#include <arch/console.h>
#include <arch/perfmon.h>
#include <arch/init.h>
#include <monitor.h>
#include <arch/usb.h>
#include <assert.h>
#include <ros/procinfo.h>
#include <cpu_feat.h>


struct ancillary_state x86_default_fpu;
uint32_t kerndate;

#define capchar2ctl(x) ((x) - '@')

/* irq handler for the console (kb, serial, etc) */
static void irq_console(struct hw_trapframe *hw_tf, void *data)
{
	uint8_t c;
	struct cons_dev *cdev = (struct cons_dev*)data;
	assert(cdev);
	if (cons_get_char(cdev, &c))
		return;
	/* Control code intercepts */
	switch (c) {
		case capchar2ctl('G'):
			/* traditional 'ctrl-g', will put you in the monitor gracefully */
			send_kernel_message(core_id(), __run_mon, 0, 0, 0, KMSG_ROUTINE);
			return;
		case capchar2ctl('Q'):
			/* force you into the monitor.  you might deadlock. */
			printk("\nForcing entry to the monitor\n");
			monitor(hw_tf);
			return;
		case capchar2ctl('B'):
			/* backtrace / debugging for the core receiving the irq */
			printk("\nForced trapframe and backtrace for core %d\n", core_id());
			if (!hw_tf) {
				printk("(no hw_tf, we probably polled the console)\n");
				return;
			}
			print_trapframe(hw_tf);
			backtrace_hwtf(hw_tf);
			return;
	}
	cons_add_char(c);
}

static void cons_poller(void *arg)
{
	while (1) {
		kthread_usleep(10000);
		irq_console(0, arg);
	}
}

static void cons_irq_init(void)
{
	struct cons_dev *i;
	/* Register interrupt handlers for all console devices */
	SLIST_FOREACH(i, &cdev_list, next) {
		register_irq(i->irq, irq_console, i, MKBUS(BusISA, 0, 0, 0));
		irq_console(0, i);
	}
}

/* Init x86 processor extended state */
void ancillary_state_init(void)
{
	uint32_t eax, ebx, ecx, edx;
	uint64_t proc_supported_features; /* proc supported user state components */

	// If you don't at least have FXSAVE and FXRSTOR
	// (includes OSFXSR), you don't boot.
	if (!cpu_has_feat(CPU_FEAT_X86_FXSR))
		panic("No FXSAVE/FXRSTOR (FXSR) support! Refusing to boot.");

	if (cpu_has_feat(CPU_FEAT_X86_XSAVE)) {
		// Next determine the user state components supported
		// by the processor and set x86_default_xcr0 in proc_global_info.
		cpuid(0x0d, 0x00, &eax, 0, 0, &edx);
		proc_supported_features = ((uint64_t)edx << 32) | eax;

		// Intersection of processor-supported and Akaros-supported
		// features is the Akaros-wide default at runtime.
		__proc_global_info.x86_default_xcr0 = X86_MAX_XCR0 &
		                                      proc_supported_features;

		/*
		 * Make sure CR4.OSXSAVE is set and set the local xcr0 to the default.
		 * We will do both of these things again during per-cpu init,
		 * but we are about to use XSAVE to build our default extended state
		 * record, so we need them enabled.
		 * You must set CR4_OSXSAVE before setting xcr0, or a #UD fault occurs.
		 */
		lcr4(rcr4() | CR4_OSXSAVE);
		lxcr0(__proc_global_info.x86_default_xcr0);

		/* Build a default set of extended state values that we can later use
		 * to initialize extended state on other cores, or restore on this
		 * core.  FNINIT won't actually do it - if you xsave after fninit, x87
		 * will show up as active in xstate_bv[0].  Instead, we just need
		 * the xstate_bv bits zeroed (and memset the rest for sanity's sake).
		 */
		memset(&x86_default_fpu, 0x00, sizeof(struct ancillary_state));

		/* We must set the MXCSR field in the default state struct to its
		 * power-on value of 0x1f80. This masks all SIMD floating
		 * point exceptions and clears all SIMD floating-point exception
		 * flags, sets rounding control to round-nearest, disables
		 * flush-to-zero mode, and disables denormals-are-zero mode.
		 *
		 * We don't actually have to set the MXCSR itself here,
		 * because it will be set from the default state struct when
		 * we perform per-cpu init.
		 *
		 * Right now, we set the MXCSR through fp_head_64d. Since
		 * the mxcsr is at the same offset in all fp header formats
		 * implemented for Akaros, this will function correctly for
		 * all supported operating modes.
		 */
		x86_default_fpu.fp_head_64d.mxcsr = 0x1f80;
	} else {
		// Since no program should try to use XSAVE features
		// on this processor, we set x86_default_xcr0 to 0x0
		__proc_global_info.x86_default_xcr0 = 0x0;

		/*
		 * Build a default set of extended state values that we can later use to
		 * initialize extended state on other cores, or restore on this core.
		 * We need to use FNINIT to reset the FPU before saving, in case boot
		 * agents used the FPU or it is dirty for some reason. An old comment
		 * that used to be here said "had this happen on c89, which had a full
		 * FP stack after booting." Note that FNINIT does not clear the data
		 * registers, but it tags them all as empty (0b11).
		 */

		// Zero the default extended state memory region before saving.
		// It may be possible for memset to clobber SSE registers.
		memset(&x86_default_fpu, 0x00, sizeof(struct ancillary_state));

		/*
		 * FNINIT clears FIP and FDP and, even though it is technically a
		 * control instruction, it clears FOP while initializing the FPU.
		 *
		 * This marks the STX/MMX registers as empty in the FPU tag word,
		 * but does not actually clear the values in the registers,
		 * so we manually clear them in the xsave area after saving.
		 */
		asm volatile ("fninit");

		// Save the x87 FPU state
		asm volatile("fxsave64 %0" : : "m"(x86_default_fpu));

		/*
		 * Clear junk that might have been saved from the STX/MMX registers.
		 *
		 * FXSAVE may have also saved junk from the XMM registers,
		 * depending on how the hardware was implemented and the setting
		 * of CR4.OSFXSR. So we clear that too.
		 *
		 * MMX: 128 bytes, XMM: 256 bytes
		 */
		memset(&(x86_default_fpu.st0_mm0), 0x00, 128 + 256);

		/*
		 * Finally, because Only the Paranoid Survive, we set the MXCSR
		 * for our default state. It should have been saved by FXSAVE,
		 * but who knows if the default value is still there at this
		 * point in the boot process.
		 */
		x86_default_fpu.fp_head_64d.mxcsr = 0x1f80;
	}

}

void arch_init(void)
{
	ancillary_state_init();
	pci_init();
	vmm_init();
	perfmon_global_init();
	// this returns when all other cores are done and ready to receive IPIs
	#ifdef CONFIG_SINGLE_CORE
		smp_percpu_init();
	#else
		smp_boot();
	#endif
	proc_init();

	cons_irq_init();
	intel_lpc_init();
#ifdef CONFIG_ENABLE_LEGACY_USB
	printk("Legacy USB support enabled, expect SMM interference!\n");
#else
	usb_disable_legacy();
#endif
	check_timing_stability();
}
