/* 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 <kclock.h>
#include <env.h>
#include <stdio.h>
#include <kmalloc.h>
#include <page_alloc.h>

static int nvram_read(int r)
{
	return mc146818_read(r) | (mc146818_read(r + 1) << 8);
}

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();
}
