aboutsummaryrefslogtreecommitdiff
path: root/kernel/include/mm/pagetable.h
diff options
context:
space:
mode:
authornthnluu <nate1299@me.com>2024-01-28 21:20:27 -0500
committernthnluu <nate1299@me.com>2024-01-28 21:20:27 -0500
commitc63f340d90800895f007de64b7d2d14624263331 (patch)
tree2c0849fa597dd6da831c8707b6f2603403778d7b /kernel/include/mm/pagetable.h
Created student weenix repository
Diffstat (limited to 'kernel/include/mm/pagetable.h')
-rw-r--r--kernel/include/mm/pagetable.h94
1 files changed, 94 insertions, 0 deletions
diff --git a/kernel/include/mm/pagetable.h b/kernel/include/mm/pagetable.h
new file mode 100644
index 0000000..cc1fa3e
--- /dev/null
+++ b/kernel/include/mm/pagetable.h
@@ -0,0 +1,94 @@
+#pragma once
+
+#include "mm/page.h"
+#include "vm/vmmap.h"
+
+#define PT_PRESENT 0x001
+#define PT_WRITE 0x002
+#define PT_USER 0x004
+#define PT_WRITE_THROUGH 0x008
+#define PT_CACHE_DISABLED 0x010
+#define PT_ACCESSED 0x020
+#define PT_DIRTY 0x040
+#define PT_SIZE 0x080
+#define PT_GLOBAL 0x100
+
+#define PT_ENTRY_COUNT (PAGE_SIZE / sizeof(uintptr_t))
+
+typedef struct page
+{
+ uint8_t data[PAGE_SIZE];
+} page_t;
+
+// Generalized structure for all directory like entries
+typedef struct pt
+{
+ uintptr_t phys[PT_ENTRY_COUNT];
+} pt_t, pd_t, pdp_t, pml4_t;
+
+#define INDEX_MASK 0b111111111
+#define PML4E(x) ((((uintptr_t)(x)) >> 39) & INDEX_MASK)
+#define PDPE(x) ((((uintptr_t)(x)) >> 30) & INDEX_MASK)
+#define PDE(x) ((((uintptr_t)(x)) >> 21) & INDEX_MASK)
+#define PTE(x) ((((uintptr_t)(x)) >> 12) & INDEX_MASK)
+
+#define PT_ENTRY_COUNT (PAGE_SIZE / sizeof(uintptr_t))
+#define PT_VADDR_SIZE (PAGE_SIZE * PT_ENTRY_COUNT)
+#define PD_VADDR_SIZE (PAGE_SIZE * PT_ENTRY_COUNT * PT_ENTRY_COUNT)
+#define PDP_VADDR_SIZE \
+ (PAGE_SIZE * PT_ENTRY_COUNT * PT_ENTRY_COUNT * PT_ENTRY_COUNT)
+#define PML4_VADDR_SIZE \
+ (PAGE_SIZE * PT_ENTRY_COUNT * PT_ENTRY_COUNT * PT_ENTRY_COUNT * \
+ PT_ENTRY_COUNT)
+
+#define IS_PRESENT(n) ((n)&PT_PRESENT)
+#define IS_2MB_PAGE(n) ((n)&PT_SIZE)
+#define IS_1GB_PAGE IS_2MB_PAGE
+
+#define GDB_PT_PHYSADDR(pt, v) (pt->phys[PTE(v)] & PAGE_MASK)
+#define GDB_PD_PHYSADDR(pd, v) (pd->phys[PDE(v)] & PAGE_MASK)
+#define GDB_PDP_PHYSADDR(pdp, v) (pdp->phys[PDPE(v)] & PAGE_MASK)
+#define GDB_PML4_PHYSADDR(pml4, v) (pml4->phys[PML4E(v)] & PAGE_MASK)
+
+#define GDB_PHYSADDR(pml4, v) \
+ (GDB_PT_PHYSADDR( \
+ GDB_PD_PHYSADDR( \
+ GDB_PDP_PHYSADDR(GDB_PML4_PHYSADDR(pml4, (v)) + PHYS_OFFSET, \
+ (v)) + \
+ PHYS_OFFSET, \
+ (v)) + \
+ PHYS_OFFSET, \
+ (v)) + \
+ PHYS_OFFSET)
+#define GDB_CUR_PHYSADDR(v) GDB_PHYSADDR(curproc->p_pml4, (v))
+
+uintptr_t pt_virt_to_phys_helper(pml4_t *pml4, uintptr_t vaddr);
+
+uintptr_t pt_virt_to_phys(uintptr_t vaddr);
+
+void pt_init(void);
+
+/* Currently unused. */
+void pt_template_init(void);
+
+pml4_t *pt_get();
+
+void pt_set(pml4_t *pml4);
+
+pml4_t *clone_pml4(pml4_t *pml4, long include_user_mappings);
+
+pml4_t *pt_create();
+
+void pt_destroy(pml4_t *pml4);
+
+long pt_map(pml4_t *pml4, uintptr_t paddr, uintptr_t vaddr, uint32_t pdflags,
+ uint32_t ptflags);
+
+long pt_map_range(pml4_t *pml4, uintptr_t paddr, uintptr_t vaddr,
+ uintptr_t vmax, uint32_t pdflags, uint32_t ptflags);
+
+void pt_unmap(pml4_t *pml4, uintptr_t vaddr);
+
+void pt_unmap_range(pml4_t *pml4, uintptr_t vaddr, uintptr_t vmax);
+
+void check_invalid_mappings(pml4_t *pml4, vmmap_t *vmmap, char *prompt);