/* Copyright (c) 2015 Google Inc.
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * 64 bit EPT helpers */

#ifndef ROS_ARCH_VMM_EPT_H
#define ROS_ARCH_VMM_EPT_H

#include <arch/vmm/intel/vmx.h>	/* for sync/flush helpers */
#include <smp.h>				/* for current */

/* Some EPTE PTE flags are only valid for the last PTEs in a walk */
#define EPTE_R					(1ULL << 0)		/* Readable */
#define EPTE_W					(1ULL << 1)		/* Writeable */
#define EPTE_X					(1ULL << 2)		/* Executable */
#define EPTE_MEM_BITS			(7ULL << 3)		/* Memory type specifier */
#define EPTE_IGN_PAT			(1ULL << 6)		/* Ignore PAT */
#define EPTE_PS					(1ULL << 7)		/* Jumbo Page Size */
#define EPTE_A					(1ULL << 8)		/* Accessed */
#define EPTE_D					(1ULL << 9)		/* Dirty */
#define EPTE_SUP_VE				(1ULL << 63)	/* Suppress virt exceptions */
#define EPTE_P (EPTE_R | EPTE_W | EPTE_X)

/* Types available for the EPTE_MEM_TYPE */
#define EPT_MEM_TYPE_UC			0
#define EPT_MEM_TYPE_WC			1
#define EPT_MEM_TYPE_WT			4
#define EPT_MEM_TYPE_WP			5
#define EPT_MEM_TYPE_WB			6
/* Helper to align the type to its location in the PTE */
#define EPT_MEM_TYPE(type) ((type) << 3)

/* Some machines don't support A and D EPTE bits.  We'll |= 1 in those cases. */
extern int x86_ept_pte_fix_ups;

static inline epte_t *kpte_to_epte(kpte_t *kpte)
{
	return (epte_t*)(((uintptr_t)kpte) + PGSIZE);
}

static inline bool epte_is_present(epte_t *epte)
{
	/* Actually, certain combos, like W but not R could be misconfigurations */
	return *epte & EPTE_P ? TRUE : FALSE;
}

static inline bool epte_is_unmapped(epte_t *epte)
{
	return *epte == 0;
}

static inline bool epte_is_mapped(epte_t *epte)
{
	return *epte != 0;
}

static inline bool epte_is_paged_out(epte_t *epte)
{
	return *epte != 0;
}

/* Some Intel machines don't support A or D.  In these cases, we must assume
 * the pages have been accessed or dirtied... */
static inline bool epte_is_dirty(epte_t *epte)
{
	return (*epte | x86_ept_pte_fix_ups) & EPTE_D ? TRUE : FALSE;
}

static inline bool epte_is_accessed(epte_t *epte)
{
	return (*epte | x86_ept_pte_fix_ups) & EPTE_A ? TRUE : FALSE;
}

static inline bool epte_is_jumbo(epte_t *epte)
{
	return *epte & EPTE_PS ? TRUE : FALSE;
}

static inline physaddr_t epte_get_paddr(epte_t *epte)
{
	/* 63:52 are ignored/flags.  51:12 are the addr.  Technically 51:N must be
	 * 0, where N is the physical addr width */
	return *epte & 0x000ffffffffff000;
}

static inline int __pte_to_epte_perm(int perm)
{
	switch (perm) {
		/* Since we keep the EPT in lockstep with the KPT, we might get some
		 * mapping requests for the kernel (e.g. vmap_pmem).  */
		case PTE_KERN_RW:
		case PTE_KERN_RO:
		case PTE_NONE:
			return 0;
		case PTE_USER_RW:
			return EPTE_W | EPTE_R | EPTE_X;
		case PTE_USER_RO:
			return EPTE_R | EPTE_X;
		default:
			panic("Bad PTE type 0x%x\n", perm);
	}
}

static inline void epte_write(epte_t *epte, physaddr_t pa, int settings)
{
	/* Could put in a check against the max physaddr len */
	epte_t temp = pa;
	temp |= __pte_to_epte_perm(settings & PTE_PERM);
	temp |= settings & PTE_PS ? EPTE_PS : 0;
	/* All memory is WB by default, but the guest can override that with their
	 * PAT on the first page walk (guest KPT/cr3) */
	temp |= EPT_MEM_TYPE(EPT_MEM_TYPE_WB);
	*epte = temp;
}

static inline void epte_clear_present(epte_t *epte)
{
	*epte &= ~EPTE_P;
}

static inline void epte_clear(epte_t *epte)
{
	*epte = 0;
}

static inline bool epte_has_perm_ur(epte_t *epte)
{
	return (*epte & (EPTE_R | EPTE_X)) == (EPTE_R | EPTE_X);
}

static inline bool epte_has_perm_urw(epte_t *epte)
{
	return (*epte & (EPTE_R | EPTE_W | EPTE_X)) == (EPTE_R | EPTE_W | EPTE_X);
}

static inline int epte_get_settings(epte_t *epte)
{
	int settings = 0;
	if (*epte & EPTE_P) {
		/* We want to know User and Writable, in the 'PTE' sense.  All present
		 * epte entries are User PTEs. */
		settings |= PTE_P | PTE_U;
		settings |= *epte & EPTE_W ? PTE_W : 0;
	}
	settings |= *epte & EPTE_PS ? PTE_PS : 0;
	settings |= *epte & EPTE_A ? PTE_A : 0;
	settings |= *epte & EPTE_D ? PTE_D : 0;
	return settings;
}

/* Again, we're replacing the old perms with U and/or W.  Any non-U are ignored,
 * as with epte_write.  */
static inline void epte_replace_perm(epte_t *epte, int perm)
{
	*epte = (*epte & ~EPTE_P) | __pte_to_epte_perm(perm & PTE_PERM);
}

/* These ops might be the same for AMD as Intel; in which case we can move the
 * body of these ept_sync_* funcs into here */
static inline void ept_inval_addr(unsigned long addr)
{
	if (current && current->vmm.vmmcp)
		ept_sync_individual_addr(current->env_pgdir.eptp, addr);
}

static inline void ept_inval_context(void)
{
	if (current && current->vmm.vmmcp)
		ept_sync_context(current->env_pgdir.eptp);
}

static inline void ept_inval_global(void)
{
	ept_sync_global();
}

#endif /* ROS_ARCH_VMM_EPT_H */
