fix dependency check logic cause config always disabled
[lunaix-os.git] / lunaix-os / includes / lunaix / mm / pagetable.h
index 4c2fce52c5b904b5c08bedfc94f8d6e27c773825..7093d669ec0a6dc5d5a19a165c36f378b7072930 100644 (file)
@@ -99,25 +99,34 @@ struct __pte;
 typedef struct __pte pte_t;
 
 
-#include <sys/mm/pagetable.h>
-#include <sys/cpu.h>
-
-#define _LnTEP_AT(vm_mnt, sz)   ( ((vm_mnt) | L0T_MASK) & ~(sz) )
-#define _L0TEP_AT(vm_mnt)       ( ((vm_mnt) | L0T_MASK) & ~LFT_MASK )
-#define _L1TEP_AT(vm_mnt)       ( ((vm_mnt) | L0T_MASK) & ~L3T_MASK )
-#define _L2TEP_AT(vm_mnt)       ( ((vm_mnt) | L0T_MASK) & ~L2T_MASK )
-#define _L3TEP_AT(vm_mnt)       ( ((vm_mnt) | L0T_MASK) & ~L1T_MASK )
-#define _LFTEP_AT(vm_mnt)       ( ((vm_mnt) | L0T_MASK) & ~L0T_MASK )
+#include <asm/mempart.h>
+#include <asm/pagetable.h>
+#include <asm/cpu.h>
+
+#define VMS_SELF                VMS_SELF_MOUNT
+#define VMS_SELF_L0TI           (__index(VMS_SELF_MOUNT) / L0T_SIZE)
+
+#define _LnT_LEVEL_SIZE(n)      ( L##n##T_SIZE / PAGE_SIZE )
+#define _LFTEP_SELF             ( __index(VMS_SELF) )
+#define _L3TEP_SELF             ( _LFTEP_SELF | (_LFTEP_SELF / _LnT_LEVEL_SIZE(3)) )
+#define _L2TEP_SELF             ( _L3TEP_SELF | (_LFTEP_SELF / _LnT_LEVEL_SIZE(2)) )
+#define _L1TEP_SELF             ( _L2TEP_SELF | (_LFTEP_SELF / _LnT_LEVEL_SIZE(1)) )
+#define _L0TEP_SELF             ( _L1TEP_SELF | (_LFTEP_SELF / _LnT_LEVEL_SIZE(0)) )
+
+#define _L0TEP_AT(vm_mnt)       ( ((vm_mnt) | (_L0TEP_SELF & L0T_MASK)) )
+#define _L1TEP_AT(vm_mnt)       ( ((vm_mnt) | (_L1TEP_SELF & L0T_MASK)) )
+#define _L2TEP_AT(vm_mnt)       ( ((vm_mnt) | (_L2TEP_SELF & L0T_MASK)) )
+#define _L3TEP_AT(vm_mnt)       ( ((vm_mnt) | (_L3TEP_SELF & L0T_MASK)) )
+#define _LFTEP_AT(vm_mnt)       ( ((vm_mnt) | (_LFTEP_SELF & L0T_MASK)) )
 
 #define _VM_OF(ptep)            ( (ptr_t)(ptep) & ~L0T_MASK )
 #define _VM_PFN_OF(ptep)        ( ((ptr_t)(ptep) & L0T_MASK) / sizeof(pte_t) )
-#define VMS_SELF                ( ~L0T_MASK & VMS_MASK )
 
 #define __LnTI_OF(ptep, n)\
-    (_VM_PFN_OF(ptep) * LFT_SIZE / L##n##T_SIZE)
+    ( __index(_VM_PFN_OF(ptep) * LFT_SIZE / L##n##T_SIZE) )
 
 #define __LnTEP(ptep, va, n)\
-    ( (pte_t*)_L##n##TEP_AT(_VM_OF(ptep)) + (((va) & VMS_MASK) / L##n##T_SIZE) )
+    ( (pte_t*)_L##n##TEP_AT(_VM_OF(ptep)) + (__index(va) / L##n##T_SIZE) )
 
 #define __LnTEP_OF(ptep, n)\
     ( (pte_t*)_L##n##TEP_AT(_VM_OF(ptep)) + __LnTI_OF(ptep, n))
@@ -128,14 +137,8 @@ typedef struct __pte pte_t;
 #define _has_LnT(n) (L##n##T_SIZE != LFT_SIZE)
 #define LnT_ENABLED(n) _has_LnT(n)
 
-#define ptep_with_level(ptep, lvl_size)                 \
-    ({                                                  \
-        ptr_t __p = _LnTEP_AT(_VM_OF(ptep), lvl_size);  \
-        ((ptr_t)(ptep) & __p) == __p;                   \
-    })
-
-pte_t 
-vmm_alloc_page(pte_t* ptep, pte_t pte);
+extern pte_t 
+alloc_kpage_at(pte_t* ptep, pte_t pte, int order);
 
 /**
  * @brief Try page walk to the pte pointed by ptep and 
@@ -155,7 +158,7 @@ __alloc_level(pte_t* ptep, pte_t pte, pte_attr_t prot)
     }
 
     pte = pte_setprot(pte, prot);
-    return !pte_isnull(vmm_alloc_page(ptep, pte));
+    return !pte_isnull(alloc_kpage_at(ptep, pte, 0));
 }
 
 /**
@@ -185,13 +188,13 @@ ptep_vfn(pte_t* ptep)
 static inline ptr_t
 ptep_va(pte_t* ptep, size_t lvl_size)
 {
-    return ((ptr_t)ptep) / sizeof(pte_t) * lvl_size;
+    return __vaddr(ptep_pfn(ptep) * lvl_size);
 }
 
 static inline ptr_t
 ptep_vm_mnt(pte_t* ptep)
 {
-    return _VM_OF(ptep);
+    return __vaddr(_VM_OF(ptep));
 }
 
 /**
@@ -408,7 +411,7 @@ l3te_index(pte_t* ptep) {
 
 static inline pfn_t
 pfn(ptr_t addr) {
-    return (addr / PAGE_SIZE) & VMS_MASK;
+    return __index(addr) / PAGE_SIZE;
 }
 
 static inline size_t
@@ -428,19 +431,29 @@ va_offset(ptr_t addr) {
 
 static inline ptr_t
 page_addr(ptr_t pfn) {
-    return pfn * PAGE_SIZE;
+    return __vaddr(pfn * PAGE_SIZE);
 }
 
 static inline ptr_t
-va_align(ptr_t va) {
+page_aligned(ptr_t va) {
     return va & ~PAGE_MASK;
 }
 
 static inline ptr_t
-va_alignup(ptr_t va) {
+page_upaligned(ptr_t va) {
     return (va + PAGE_MASK) & ~PAGE_MASK;
 }
 
+static inline ptr_t
+napot_aligned(ptr_t va, size_t napot_sz) {
+    return va & ~(napot_sz - 1);
+}
+
+static inline ptr_t
+napot_upaligned(ptr_t va, size_t napot_sz) {
+    return (va + napot_sz - 1) & ~(napot_sz - 1);
+}
+
 static inline pte_t*
 mkptep_va(ptr_t vm_mnt, ptr_t vaddr)
 {
@@ -455,7 +468,7 @@ mkptep_pn(ptr_t vm_mnt, ptr_t pn)
 
 static inline pfn_t
 pfn_at(ptr_t va, size_t lvl_size) {
-    return va / lvl_size;
+    return __index(va) / lvl_size;
 }
 
 
@@ -498,10 +511,145 @@ mkl0tep_va(ptr_t mnt, ptr_t va)
     return mkl0tep(mkptep_va(mnt, va));
 }
 
+static inline pte_t*
+mkl1tep_va(ptr_t mnt, ptr_t va)
+{
+    return mkl1tep(mkptep_va(mnt, va));
+}
+
+static inline pte_t*
+mkl2tep_va(ptr_t mnt, ptr_t va)
+{
+    return mkl2tep(mkptep_va(mnt, va));
+}
+
+static inline pte_t*
+mkl3tep_va(ptr_t mnt, ptr_t va)
+{
+    return mkl3tep(mkptep_va(mnt, va));
+}
+
+static inline pte_t*
+mklntep_va(int level, ptr_t mnt, ptr_t va)
+{
+    if (level == 0)
+        return mkl0tep_va(mnt, va);
+    
+#if LnT_ENABLED(1)
+    if (level == 1)
+        return mkl1tep_va(mnt, va);
+#endif
+
+#if LnT_ENABLED(2)
+    if (level == 2)
+        return mkl2tep_va(mnt, va);
+#endif
+
+#if LnT_ENABLED(3)
+    if (level == 3)
+        return mkl3tep_va(mnt, va);
+#endif
+    
+    return mkptep_va(mnt, va);
+}
+
+static inline unsigned long
+lnt_page_size(int level)
+{
+    if (level == 0)
+        return L0T_SIZE;
+    if (level == 1)
+        return L1T_SIZE;
+    if (level == 2)
+        return L2T_SIZE;
+    if (level == 3)
+        return L3T_SIZE;
+    
+    return LFT_SIZE;
+}
+
 static inline bool
 pt_last_level(int level)
 {
     return level == _PTW_LEVEL - 1;
 }
 
+static inline ptr_t
+va_mntpoint(ptr_t va)
+{
+    return __vaddr(_VM_OF(va));
+}
+
+static inline unsigned int
+va_level_index(ptr_t va, size_t lvl_size)
+{
+    return (va / lvl_size) & _PAGE_LEVEL_MASK;
+}
+
+static inline bool
+lntep_implie(pte_t* ptep, ptr_t addr, size_t lvl_size)
+{
+    return ptep_va(ptep, lvl_size) == __vaddr(addr);
+}
+
+static inline bool
+is_ptep(ptr_t addr)
+{
+    ptr_t mnt = va_mntpoint(addr);
+    return mnt == VMS_MOUNT_1 || mnt == VMS_SELF;
+}
+
+static inline bool
+vmnt_packed(pte_t* ptep)
+{
+    return is_ptep(__ptr(ptep));
+}
+
+static inline bool
+active_vms(ptr_t vmnt)
+{
+    return vmnt == VMS_SELF;
+}
+
+static inline bool
+lntep_implie_vmnts(pte_t* ptep, size_t lvl_size)
+{
+    return lntep_implie(ptep, VMS_SELF, lvl_size) ||
+           lntep_implie(ptep, VMS_MOUNT_1, lvl_size);
+}
+
+
+static inline int
+ptep_count_level(pte_t* ptep)
+{
+    int i = 0;
+    ptr_t addr = (ptr_t)ptep;
+
+    if (!is_ptep(addr << (LEVEL_SHIFT * i++)))
+        return MAX_LEVEL - i;
+
+#if LnT_ENABLED(1)
+    if (!is_ptep(addr << (LEVEL_SHIFT * i++)))
+        return MAX_LEVEL - i;
+#endif
+
+#if LnT_ENABLED(2)
+    if (!is_ptep(addr << (LEVEL_SHIFT * i++)))
+        return MAX_LEVEL - i;
+#endif
+
+#if LnT_ENABLED(3)
+    if (!is_ptep(addr << (LEVEL_SHIFT * i++)))
+        return MAX_LEVEL - i;
+#endif
+    
+    return 0;
+}
+
+static inline pte_t must_inline
+pte_advance(pte_t pte, unsigned long lvl_size)
+{
+    return pte_setpaddr(pte, pte_paddr(pte) + lvl_size);
+}
+
 #endif /* __LUNAIX_PAGETABLE_H */