summaryrefslogtreecommitdiff
path: root/sys/include/vm.h
diff options
context:
space:
mode:
Diffstat (limited to 'sys/include/vm.h')
-rw-r--r--sys/include/vm.h66
1 files changed, 65 insertions, 1 deletions
diff --git a/sys/include/vm.h b/sys/include/vm.h
index 1883ea7..4378552 100644
--- a/sys/include/vm.h
+++ b/sys/include/vm.h
@@ -1,6 +1,70 @@
#ifndef _VM_H
#define _VM_H
-void vminit(void);
+#include <stdint.h>
+
+#define PAGEBITS_VALID (1 << 0)
+#define PAGEBITS_R (1 << 1)
+#define PAGEBITS_W (1 << 2)
+#define PAGEBITS_X (1 << 3)
+#define PAGEBITS_USER (1 << 4)
+#define PAGEBITS_GLOBAL (1 << 5)
+#define PAGEBITS_ACCESSED (1 << 6)
+#define PAGEBITS_DIRTY (1 << 7)
+
+#define PAGEBITS_RO PAGEBITS_R
+#define PAGEBITS_XO PAGEBITS_X
+#define PAGEBITS_RW (PAGEBITS_R | PAGEBITS_W)
+#define PAGEPITS_RX (PAGEBITS_R | PAGEBITS_X)
+#define PAGEBITS_RWX (PAGEBITS_R | PAGEBITS_W | PAGEBITS_X)
+
+#define MODE_SV39 (8L << 60)
+
+typedef uint64_t pt_entry_t;
+typedef struct _pagetable {
+ pt_entry_t entries[512];
+} pagetable_t;
+
+/* allocate kernel pagetable */
+void kptinit(void);
+void kptinithart(void);
+//void kptinitharts(uintptr_t mask);
+
+/* maps virtual address to physical address for @pt. */
+void vmap(pagetable_t *root, uintptr_t vaddr, uintptr_t paddr, int bits, int level);
+
+/* returns address of page table entry for @vaddr. if @alloc, next level page tables will be allocated */
+pt_entry_t *walkpt(pagetable_t *root, uintptr_t vaddr, int alloc);
+
+/* helper functions */
+static inline void write_satp(uintptr_t mode, uintptr_t ppn);
+static inline int pte_is_branch(pt_entry_t);
+static inline int pte_is_valid(pt_entry_t);
+
+#define PA2PTE(pa) ((uintptr_t)pa >> 2)
+#define PTE2PA(pa) ((uintptr_t)pa << 2)
+#define FLUSH_TLB() asm volatile("sfence.vma zero, zero")
+
+static inline void
+write_satp(uintptr_t mode, uintptr_t ppn)
+{
+ FLUSH_TLB();
+ asm volatile("csrw satp, %0" : : "r"((ppn >> 12) | mode));
+ FLUSH_TLB();
+}
+
+static inline int
+pte_is_branch(pt_entry_t e)
+{
+ return ((e & PAGEBITS_RWX) == 0);
+}
+#define pte_is_leaf(e) (!pte_is_branch(e))
+
+static inline int
+pte_is_valid(pt_entry_t e)
+{
+ return (e & PAGEBITS_VALID);
+}
+
#endif /* _VM_H */