add generic kremap for kernel remapping
[lunaix-os.git] / lunaix-os / arch / generic / includes / asm-generic / init_pagetable.h
diff --git a/lunaix-os/arch/generic/includes/asm-generic/init_pagetable.h b/lunaix-os/arch/generic/includes/asm-generic/init_pagetable.h
new file mode 100644 (file)
index 0000000..ae58501
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef __LUNAIX_ARCH_GENERIC_INIT_PAGETABLE_H
+#define __LUNAIX_ARCH_GENERIC_INIT_PAGETABLE_H
+
+#include <lunaix/types.h>
+#include <lunaix/mm/pagetable.h>
+
+struct pt_alloc
+{
+    ptr_t base;
+    int index;
+    int total;
+};
+
+struct ptw_state
+{
+    struct pt_alloc* alloc;
+    pte_t* root;
+    pte_t* lntp;
+    int tab_index;
+    int level;
+};
+
+/**
+ * Allocate a page table from the page-table pool
+ */
+ptr_t 
+kpt_alloc_table(struct pt_alloc* alloc);
+
+/**
+ * Set contiguous number of ptes starting from `addr`
+ * Using flattened apporach (i.e., unfold recursive)
+ */
+unsigned int 
+kpt_set_ptes_flatten(struct ptw_state* state, ptr_t addr, 
+                pte_t pte, unsigned long lsize, unsigned int nr);
+
+/**
+ * Remap the kernel to high-memory
+ */
+void 
+kpt_migrate_highmem(struct ptw_state* state);
+
+static inline void must_inline
+init_pt_alloc(struct pt_alloc* alloc, ptr_t pool, unsigned int size)
+{
+    *alloc = (struct pt_alloc) {
+        .base = pool,
+        .index = 0,
+        .total = size / PAGE_SIZE
+    };
+}
+
+static inline void must_inline
+init_ptw_state(struct ptw_state* state, struct pt_alloc* alloc, ptr_t root)
+{
+    *state = (struct ptw_state) {
+        .alloc = alloc,
+        .root  = (pte_t*) root,
+        .level = 0
+    };
+}
+
+/**
+ * set_ptes that is ensured to success
+ */
+static inline void must_inline
+kpt_set_ptes(struct ptw_state* state, ptr_t addr, 
+                pte_t pte, unsigned long lsize, unsigned int nr)
+{
+    if (kpt_set_ptes_flatten(state, addr, pte, lsize, nr) != nr) {
+        spin();
+    }
+}
+
+/**
+ *  prepare a editable page table covering va range [addr, addr + lsize)
+ */
+static inline void must_inline
+kpt_mktable_at(struct ptw_state* state, ptr_t addr, unsigned long lsize)
+{
+    kpt_set_ptes(state, addr, null_pte, lsize >> _PAGE_BASE_SHIFT, 1);
+}
+
+#endif /* __LUNAIX_ARCH_GENERIC_INIT_PAGETABLE_H */