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

#include <arch/arch.h>
#include <arch/x86.h>
#include <arch/mmu.h>
#include <stdio.h>
#include <assert.h>
#include <ros/memlayout.h>
#include <pmap.h>
#include <kdebug.h>
#include <string.h>
#include <cpu_feat.h>

/* Check Intel's SDM 2a for Table 3-17 for the cpuid leaves */
void print_cpuinfo(void)
{
	uint32_t eax, ebx, ecx, edx;
	uint32_t model, family;
	uint64_t msr_val;
	char vendor_id[13];
	int max_std_lvl, max_extd_lvl;
	extern char _start[];

	if (sizeof(long) == 8)
		printk("64 bit Kernel Booting...\n");
	else
		printk("32 bit Kernel Booting...\n");

	// x86 Vendor Detection:
	asm volatile ("cpuid;"
	          "movl    %%ebx, (%2);"
	          "movl    %%edx, 4(%2);"
	          "movl    %%ecx, 8(%2);"
	         : "=a"(eax)
	         : "a"(0), "D"(vendor_id)
	         : "%ebx", "%ecx", "%edx");

	vendor_id[12] = '\0';
	cprintf("Vendor ID: %s\n", vendor_id);
	/* not a great check - old intel P5s have no vendor id */
	if (!strcmp(vendor_id, "GenuineIntel"))
		cpu_set_feat(CPU_FEAT_X86_VENDOR_INTEL);
	else if (!strcmp(vendor_id, "AuthenticAMD"))
		cpu_set_feat(CPU_FEAT_X86_VENDOR_AMD);


	/* intel supports a way to hide the upper leaves of cpuid, beyond 3.  the
	 * bios might have done this, so we'll make sure it is off. */
	if (cpu_has_feat(CPU_FEAT_X86_VENDOR_INTEL)) {
		msr_val = read_msr(IA32_MISC_ENABLE);
		if (msr_val & (1 << 22))
			write_msr(IA32_MISC_ENABLE, msr_val & ~(1 << 22));
	}
	cprintf("Largest Standard Function Number Supported: %d\n", eax);
	max_std_lvl = eax;
	cpuid(0x80000000, 0x0, &eax, 0, 0, 0);
	cprintf("Largest Extended Function Number Supported: 0x%08x\n", eax);
	max_extd_lvl = eax;
	cpuid(1, 0x0, &eax, &ebx, &ecx, &edx);
	family = ((eax & 0x0FF00000) >> 20) + ((eax & 0x00000F00) >> 8);
	model = ((eax & 0x000F0000) >> 16) + ((eax & 0x000000F0) >> 4);
	cprintf("Family: %d\n", family);
	cprintf("Model: %d\n", model);
	cprintf("Stepping: %d\n", eax & 0x0000000F);
	// eventually can fill this out with SDM Vol3B App B info, or
	// better yet with stepping info.  or cpuid 8000_000{2,3,4}
	switch ( family << 8 | model ) {
		case(0x061a):
			cprintf("Processor: Core i7\n");
			break;
		case(0x060f):
			cprintf("Processor: Core 2 Duo or Similar\n");
			break;
		default:
			cprintf("Unknown or non-Intel CPU\n");
	}
	if (!(edx & 0x00000020))
		panic("MSRs not supported!");
	if (!(edx & 0x00001000))
		panic("MTRRs not supported!");
	if (!(edx & (1 << 16)))
		panic("PAT not supported!");
	if (!(edx & 0x00002000))
		panic("Global Pages not supported!");
	if (!(edx & 0x00000200))
		panic("Local APIC Not Detected!");
	if (ecx & 0x00200000)
		cprintf("x2APIC Detected\n");
	else
		cprintf("x2APIC Not Detected\n");
	/* Not sure how to detect AMD HW virt yet. */
	if ((ecx & 0x00000060) && cpu_has_feat(CPU_FEAT_X86_VENDOR_INTEL)) {
		msr_val = read_msr(IA32_FEATURE_CONTROL);
		printd("64 Bit Feature Control: 0x%08x\n", msr_val);
		if ((msr_val & 0x5) == 0x5)
			printk("Hardware virtualization supported\n");
		else
			printk("Hardware virtualization not supported\n");
	} else {
		printk("Hardware virtualization not detected.  (AMD?)\n");
	}
	/* FP and SSE Checks */
	if (edx & 0x00000001)
		printk("FPU Detected\n");
	else
		panic("FPU Not Detected!!\n");
	printk("SSE support: ");
	if (edx & (1 << 25))
		printk("sse ");
	else
		panic("SSE Support Not Detected!!\n");
	if (edx & (1 << 26))
		printk("sse2 ");
	if (ecx & (1 << 0))
		printk("sse3 ");
	if (ecx & (1 << 9))
		printk("ssse3 ");
	if (ecx & (1 << 19))
		printk("sse4.1 ");
	if (ecx & (1 << 20))
		printk("sse4.2 ");
	if (edx & (1 << 23))
		printk("mmx ");
	if ((edx & (1 << 25)) && (!(edx & (1 << 24))))
		panic("SSE support, but no FXSAVE!");
	printk("\n");
	cpuid(0x80000008, 0x0, &eax, &ebx, &ecx, &edx);
	cprintf("Physical Address Bits: %d\n", eax & 0x000000FF);
	msr_val = read_msr(IA32_APIC_BASE);
	if (!(msr_val & MSR_APIC_ENABLE))
		panic("Local APIC Disabled!!");
	cpuid(0x80000007, 0x0, &eax, &ebx, &ecx, &edx);
	if (edx & 0x00000100)
		printk("Invariant TSC present\n");
	else
		printk("Invariant TSC not present\n");
	cpuid(0x07, 0x0, &eax, &ebx, &ecx, &edx);
	if (ebx & 0x00000001) {
		printk("FS/GS Base RD/W supported\n");
		cpu_set_feat(CPU_FEAT_X86_FSGSBASE);
	} else {
		printk("FS/GS Base RD/W not supported\n");
		#ifdef CONFIG_NOFASTCALL_FSBASE
		panic("Can't write FS Base from userspace, and no FASTCALL support!");
		#endif
	}
	cpuid(0x80000001, 0x0, &eax, &ebx, &ecx, &edx);
	if (edx & (1 << 27)) {
		printk("RDTSCP supported\n");
		/* Set core 0's id, for use during boot (if FAST_COREID) */
		write_msr(MSR_TSC_AUX, 0);
	} else {
		printk("RDTSCP not supported, but emulated for userspace\n");
	}
	/* Regardless, make sure userspace can access rdtsc (and rdtscp) */
	lcr4(rcr4() & ~CR4_TSD);
	printk("1 GB Jumbo pages %ssupported\n", edx & (1 << 26) ? "" : "not ");
	printk("FS/GS MSRs %ssupported\n", edx & (1 << 29) ? "" : "not ");
	if (!(edx & (1 << 29))) {
		printk("Can't handle no FS/GS MSRs!\n");
		while (1)
			asm volatile ("hlt");
	}
	cpuid(0x00000006, 0x0, &eax, 0, 0, 0);
	if (eax & (1 << 2))
		printk("Always running APIC detected\n");
	else
		printk("Always running APIC *not* detected\n");

	/* TODO: Eventually consolidate all of our "cpuid" stuff. */
	#define CPUID_FXSR_SUPPORT          (1 << 24)
	#define CPUID_XSAVE_SUPPORT         (1 << 26)
	#define CPUID_XSAVEOPT_SUPPORT      (1 << 0)
	#define CPUID_MONITOR_MWAIT         (1 << 3)
	#define CPUID_MWAIT_PWR_MGMT        (1 << 0)

	cpuid(0x01, 0x00, 0, 0, &ecx, &edx);
	if (CPUID_FXSR_SUPPORT & edx)
		cpu_set_feat(CPU_FEAT_X86_FXSR);
	if (CPUID_XSAVE_SUPPORT & ecx)
		cpu_set_feat(CPU_FEAT_X86_XSAVE);

	cpuid(0x0d, 0x01, &eax, 0, 0, 0);
	if (CPUID_XSAVEOPT_SUPPORT & eax)
		cpu_set_feat(CPU_FEAT_X86_XSAVEOPT);

	cpuid(0x01, 0x00, 0, 0, &ecx, 0);
	if (CPUID_MONITOR_MWAIT & ecx) {
		cpuid(0x05, 0x00, 0, 0, &ecx, 0);
		if (CPUID_MWAIT_PWR_MGMT & ecx)
			cpu_set_feat(CPU_FEAT_X86_MWAIT);
	}
}

#define BIT_SPACING "        "
#define BIT_DASHES "----------------"

void show_mapping(pgdir_t pgdir, uintptr_t start, size_t size)
{
	pte_t pte;
	int perm;
	page_t *page;
	uintptr_t i;

	printk("   %sVirtual    %sPhysical  Ps Dr Ac CD WT U W P EPTE\n",
	       BIT_SPACING, BIT_SPACING);
	printk("-------------------------------------------------%s\n", BIT_DASHES);
	for(i = 0; i < size; i += PGSIZE, start += PGSIZE) {
		pte = pgdir_walk(pgdir, (void*)start, 0);
		printk("%p  ", start);
		if (pte_walk_okay(pte)) {
			/* A note on PTE perms.  If you look at just the PTE, you don't get
			 * the full picture for W and U.  Those are the intersection of all
			 * bits.  In Akaros, we do U or not at the earliest point (PML4
			 * entries).  All other PTEs have U set.  For W, it's the opposite.
			 * The PTE for the actual page has W or not, and all others has W
			 * set.  W needs to be more fine-grained, but U doesn't.  Plus the
			 * UVPT mapping requires the U to see interior pages (but have W
			 * off). */
			perm = get_va_perms(pgdir, (void*)start);
			printk("%p  %1d  %1d  %1d  %1d  %1d  %1d %1d %1d 0x%llx\n",
			       pte_get_paddr(pte),
			       pte_is_jumbo(pte),
			       pte_is_dirty(pte),
			       pte_is_accessed(pte),
			       (pte_print(pte) & __PTE_PCD) / __PTE_PCD,
			       (pte_print(pte) & __PTE_PWT) / __PTE_PWT,
			       (perm & PTE_U) / PTE_U,
			       (perm & PTE_W) / PTE_W,
			       pte_is_present(pte),
			       *(unsigned long*)kpte_to_epte(pte));
		} else {
			printk("%p\n", 0);
		}
	}
}

/* return 0 if ok, -1 if it failed for some reason.
 * Be sensible and call it with 16 bytes.
 */
int vendor_id(char *vid)
{
	uint32_t eax, ebx, ecx, edx;

	asm volatile ("cpuid;"
	          "movl    %%ebx, (%2);"
	          "movl    %%edx, 4(%2);"
	          "movl    %%ecx, 8(%2);"
	         : "=a"(eax)
	         : "a"(0), "D"(vid)
	         : "%ebx", "%ecx", "%edx");

	vid[12] = '\0';
	return 0;
}
