akaros/kern/arch/riscv/pmap_ops.h
<<
>>
Prefs
   1/* Copyright (c) 2015 Google Inc.
   2 * Barret Rhoden <brho@cs.berkeley.edu>
   3 * See LICENSE for details.
   4 *
   5 * Arch-specific operations for page tables and PTEs */
   6
   7#warning "These are the x86 ops.  Adopt them for RISC-V"
   8
   9#pragma once
  10
  11static inline bool pte_walk_okay(pte_t pte)
  12{
  13        return pte ? TRUE : FALSE;
  14}
  15
  16/* PTE states:
  17 * - present: the PTE is involved in a valid page table walk, with the physaddr
  18 *   part pointing to a physical page.
  19 *
  20 * - mapped: the PTE is involved in some sort of mapping, e.g. a VMR.  We're
  21 *   storing something in the PTE, but it is isn't necessarily present and
  22 *   pointing to an actual physical page.  All present are mapped, but not vice
  23 *   versa.  Mapped could also include paged-out, if we support that later.
  24 *
  25 * - unmapped: completely unused. (0 value) */
  26static inline bool pte_is_present(pte_t pte)
  27{
  28        return *(kpte_t*)pte & PTE_P ? TRUE : FALSE;
  29}
  30
  31static inline bool pte_is_unmapped(pte_t pte)
  32{
  33        return PAGE_UNMAPPED(*(kpte_t*)pte);
  34}
  35
  36static inline bool pte_is_mapped(pte_t pte)
  37{
  38        return !PAGE_UNMAPPED(*(kpte_t*)pte);
  39}
  40
  41static inline bool pte_is_paged_out(pte_t pte)
  42{
  43        return PAGE_PAGED_OUT(*(kpte_t*)pte);
  44}
  45
  46static inline bool pte_is_dirty(pte_t pte)
  47{
  48        return *(kpte_t*)pte & PTE_D ? TRUE : FALSE;
  49}
  50
  51static inline bool pte_is_accessed(pte_t pte)
  52{
  53        return *(kpte_t*)pte & PTE_A ? TRUE : FALSE;
  54}
  55
  56/* Used in debugging code - want something better involving the walk */
  57static inline bool pte_is_jumbo(pte_t pte)
  58{
  59        return *(kpte_t*)pte & PTE_PS ? TRUE : FALSE;
  60}
  61
  62static inline physaddr_t pte_get_paddr(pte_t pte)
  63{
  64        return PTE_ADDR(*(kpte_t*)pte);
  65}
  66
  67/* Returns the PTE in an unsigned long, for debugging mostly. */
  68static inline unsigned long pte_print(pte_t pte)
  69{
  70        return *(kpte_t*)pte;
  71}
  72
  73static inline void pte_write(pte_t pte, physaddr_t pa, int settings)
  74{
  75        *(kpte_t*)pte = build_pte(pa, settings);
  76}
  77
  78static inline void pte_clear_present(pte_t pte)
  79{
  80        *(kpte_t*)pte &= ~PTE_P;
  81}
  82
  83static inline void pte_clear_dirty(pte_t pte)
  84{
  85        *(kpte_t*)pte &= ~PTE_D;
  86}
  87
  88static inline void pte_clear(pte_t pte)
  89{
  90        *(kpte_t*)pte = 0;
  91}
  92
  93/* These are used by memcpy_*_user, but are very dangerous (and possibly used
  94 * incorrectly there).  These aren't the overall perms for a VA.  For U and W,
  95 * we need the intersection of the PTEs along the walk and not just the last
  96 * one.  It just so happens that the W is only cleared on the last PTE, so the
  97 * check works for that.  But if there was a page under ULIM that wasn't U due
  98 * to an intermediate PTE, we'd miss that. */
  99static inline bool pte_has_perm_ur(pte_t pte)
 100{
 101        return *(kpte_t*)pte & PTE_USER_RO ? TRUE : FALSE;
 102}
 103
 104static inline bool pte_has_perm_urw(pte_t pte)
 105{
 106        return *(kpte_t*)pte & PTE_USER_RW ? TRUE : FALSE;
 107}
 108
 109/* Settings includes protection (maskable via PTE_PROT) and other bits, such as
 110 * jumbo, dirty, accessed, etc.  Whatever this returns can get fed back to
 111 * replace_settings or pte_write.
 112 *
 113 * Arch-indep settings include: PTE_PERM (U, W, P, etc), PTE_D, PTE_A, PTE_PS.
 114 * Other OSs (x86) may include others. */
 115static inline int pte_get_settings(pte_t pte)
 116{
 117        return *(kpte_t*)pte & PTE_PERM;
 118}
 119
 120static inline void pte_replace_perm(pte_t pte, int perm)
 121{
 122        *(kpte_t*)pte = (*(kpte_t*)pte & ~PTE_PERM) | perm;
 123}
 124