/* Copyright (c) 2009 The Regents of the University of California
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * Physical memory managment, common to 32 and 64 bit */

#include <arch/x86.h>
#include <arch/arch.h>
#include <arch/mmu.h>
#include <arch/apic.h>

#include <error.h>
#include <sys/queue.h>

#include <atomic.h>
#include <string.h>
#include <assert.h>
#include <pmap.h>
#include <env.h>
#include <stdio.h>
#include <kmalloc.h>
#include <page_alloc.h>

bool enable_pse(void)
{
	uint32_t edx, cr4;

	cpuid(0x1, 0x0, 0, 0, 0, &edx);
	if (edx & CPUID_PSE_SUPPORT) {
		cr4 = rcr4();
		cr4 |= CR4_PSE;
		lcr4(cr4);
		return 1;
	} else
		return 0;
}

#define PAT_UC				0x00
#define PAT_WC				0x01
#define PAT_WT				0x04
#define PAT_WP				0x05
#define PAT_WB				0x06
#define PAT_UCm				0x07

static inline uint64_t mk_pat(int pat_idx, int type)
{
	return (uint64_t)type << (8 * pat_idx);
}

static void pat_init(void)
{
	uint64_t pat = 0;

	/* Default PAT at boot:
	 *   0: WB, 1: WT, 2: UC-, 3: UC, 4: WB, 5: WT, 6: UC-, 7: UC
	 *
	 * We won't use PATs 4-7, but we'll at least enforce that they are set
	 * up the way we think they are.  I'd like to avoid using the PAT flag,
	 * since that is also the PTE_PS (jumbo) flag.  That means we can't use
	 * __PTE_PAT on jumbo pages, and we'd need to be careful whenever using
	 * any unorthodox types.  We're better off just not using it.
	 *
	 * We want WB, WT, WC, and either UC or UC- for our memory types.  (WT
	 * is actually optional at this point).  We'll use UC- instead of UC,
	 * since Linux uses that for their pgprot_noncached.  The UC- type is UC
	 * with the ability to override to WC via MTRR.  We don't use the MTRRs
	 * much yet, and hopefully won't.  The UC- will only matter if we do.
	 *
	 * No one should be using the __PTE_{PAT,PCD,PWT} bits directly, and
	 * everyone should use things like PTE_NOCACHE. */
	pat |= mk_pat(0, PAT_WB);	/*           |           |           */
	pat |= mk_pat(1, PAT_WT);	/*           |           | __PTE_PWT */
	pat |= mk_pat(2, PAT_WC);	/*           | __PTE_PCD |           */
	pat |= mk_pat(3, PAT_UCm);	/*           | __PTE_PCD | __PTE_PWT */
	pat |= mk_pat(4, PAT_WB);	/* __PTE_PAT |           |           */
	pat |= mk_pat(5, PAT_WT);	/* __PTE_PAT |           | __PTE_PWT */
	pat |= mk_pat(6, PAT_UCm);	/* __PTE_PAT | __PTE_PCD |           */
	pat |= mk_pat(7, PAT_UC);	/* __PTE_PAT | __PTE_PCD | __PTE_PWT */
	write_msr(MSR_IA32_CR_PAT, pat);
}

// could consider having an API to allow these to dynamically change
// MTRRs are for physical, static ranges.  PAT are linear, more granular, and
// more dynamic
void setup_default_mtrrs(barrier_t* smp_barrier)
{
	// disable interrupts
	int8_t state = 0;
	disable_irqsave(&state);
	// barrier - if we're meant to do this for all cores, we'll be
	// passed a pointer to an initialized barrier
	if (smp_barrier)
		waiton_barrier(smp_barrier);

	// disable caching	cr0: set CD and clear NW
	lcr0((rcr0() | CR0_CD) & ~CR0_NW);
	// flush caches
	cache_flush();
	// flush tlb
	tlb_flush_global();
	// disable MTRRs, and sets default type to WB (06)
#ifndef CONFIG_NOMTRRS
	write_msr(IA32_MTRR_DEF_TYPE, 0x00000006);

	// Now we can actually safely adjust the MTRRs
	// MTRR for IO Holes (note these are 64 bit values we are writing)
	// 0x000a0000 - 0x000c0000 : VGA - WC 0x01
	write_msr(IA32_MTRR_PHYSBASE0, PTE_ADDR(VGAPHYSMEM) | 0x01);
	// if we need to have a full 64bit val, use the UINT64 macro
	write_msr(IA32_MTRR_PHYSMASK0, 0x0000000ffffe0800);
	// 0x000c0000 - 0x00100000 : IO devices (and ROM BIOS) - UC 0x00
	write_msr(IA32_MTRR_PHYSBASE1, PTE_ADDR(DEVPHYSMEM) | 0x00);
	write_msr(IA32_MTRR_PHYSMASK1, 0x0000000ffffc0800);
	// APIC/IOAPIC holes
	/* Going to skip them, since we set their mode using PAT when we
	 * map them in
	 */
	// make sure all other MTRR ranges are disabled (should be unnecessary)
	write_msr(IA32_MTRR_PHYSMASK2, 0);
	write_msr(IA32_MTRR_PHYSMASK3, 0);
	write_msr(IA32_MTRR_PHYSMASK4, 0);
	write_msr(IA32_MTRR_PHYSMASK5, 0);
	write_msr(IA32_MTRR_PHYSMASK6, 0);
	write_msr(IA32_MTRR_PHYSMASK7, 0);

	// keeps default type to WB (06), turns MTRRs on, and turns off fixed
	// ranges
	write_msr(IA32_MTRR_DEF_TYPE, 0x00000806);
#endif
	pat_init();
	// reflush caches and TLB
	cache_flush();
	tlb_flush_global();
	// turn on caching
	lcr0(rcr0() & ~(CR0_CD | CR0_NW));
	// barrier
	if (smp_barrier)
		waiton_barrier(smp_barrier);
	// enable interrupts
	enable_irqsave(&state);
}

void invlpg(void *addr)
{
	asm volatile("invlpg (%0)" : : "r" (addr) : "memory");
	if (per_cpu_info[core_id()].vmx_enabled)
		ept_inval_addr((uintptr_t)addr);
}

void tlbflush(void)
{
	unsigned long cr3;
	asm volatile("mov %%cr3,%0" : "=r" (cr3));
	asm volatile("mov %0,%%cr3" : : "r" (cr3));
	if (per_cpu_info[core_id()].vmx_enabled)
		ept_inval_context();
}

/* Flushes a TLB, including global pages.  We should always have the CR4_PGE
 * flag set, but just in case, we'll check.  Toggling this bit flushes the TLB.
 */
void tlb_flush_global(void)
{
	uint32_t cr4 = rcr4();
	if (cr4 & CR4_PGE) {
		lcr4(cr4 & ~CR4_PGE);
		lcr4(cr4);
	} else {
		lcr3(rcr3());
	}
	if (per_cpu_info[core_id_early()].vmx_enabled)
		ept_inval_global();
}
