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

#pragma once

#include <arch/ros/mmu64.h>

static inline bool kpte_is_present(kpte_t *kpte)
{
	return *kpte & PTE_P ? TRUE : FALSE;
}

static inline bool kpte_is_unmapped(kpte_t *kpte)
{
	return *kpte == 0;
}

static inline bool kpte_is_mapped(kpte_t *kpte)
{
	return *kpte != 0;
}

static inline bool kpte_is_paged_out(kpte_t *kpte)
{
	return *kpte != 0;
}

static inline bool kpte_is_dirty(kpte_t *kpte)
{
	return *kpte & PTE_D ? TRUE : FALSE;
}

static inline bool kpte_is_accessed(kpte_t *kpte)
{
	return *kpte & PTE_A ? TRUE : FALSE;
}

static inline bool kpte_is_jumbo(kpte_t *kpte)
{
	return *kpte & PTE_PS ? TRUE : FALSE;
}

static inline physaddr_t kpte_get_paddr(kpte_t *kpte)
{
	return (physaddr_t)*kpte & ~(PGSIZE - 1);
}

/* Returns the PTE in an unsigned long, for debugging mostly. */
static inline unsigned long kpte_print(kpte_t *kpte)
{
	return *kpte;
}

static inline void kpte_write(kpte_t *kpte, physaddr_t pa, int settings)
{
	assert(!PGOFF(pa));
	/* The arch-bits like PTE_D, PTE_PS, etc are all in the native KPT format */
	*kpte = build_kpte(pa, settings);
}

static inline void kpte_clear_present(kpte_t *kpte)
{
	*kpte &= ~PTE_P;
}

static inline void kpte_clear(kpte_t *kpte)
{
	*kpte = 0;
}

static inline bool kpte_has_perm_ur(kpte_t *kpte)
{
	return (*kpte & PTE_USER_RO) == PTE_USER_RO;
}

static inline bool kpte_has_perm_urw(kpte_t *kpte)
{
	return (*kpte & PTE_USER_RW) == PTE_USER_RW;
}

static inline int kpte_get_settings(kpte_t *kpte)
{
	return *kpte & 0xfff;
}

static inline void kpte_replace_perm(kpte_t *kpte, int perm)
{
	*kpte = (*kpte & ~PTE_PERM) | perm;
}
