- x86_page_table* dir = (x86_page_table*)pmm_alloc_page(KERNEL_PID, PP_FGPERSIST);
- for (size_t i = 0; i < PG_MAX_ENTRIES; i++) {
- dir->entry[i] = PTE_NULL;
- }
-
- // 递归映射,方便我们在软件层面进行查表地址转换
- dir->entry[PG_MAX_ENTRIES - 1] = NEW_L1_ENTRY(T_SELF_REF_PERM, dir);
-
- return dir;
-}
-
-int
-__vmm_map_internal(pid_t pid,
- uint32_t l1_inx,
- uint32_t l2_inx,
- uintptr_t pa,
- pt_attr attr,
- int forced)
-{
- x86_page_table* l1pt = (x86_page_table*)L1_BASE_VADDR;
- x86_page_table* l2pt = (x86_page_table*)L2_VADDR(l1_inx);
-
- // See if attr make sense
- assert(attr <= 128);
-
- if (!l1pt->entry[l1_inx]) {
- x86_page_table* new_l1pt_pa = pmm_alloc_page(pid, PP_FGPERSIST);
-
- // 物理内存已满!
- if (!new_l1pt_pa) {
- return 0;
- }
-
- // This must be writable
- l1pt->entry[l1_inx] = NEW_L1_ENTRY(attr | PG_WRITE, new_l1pt_pa);
- memset((void*)L2_VADDR(l1_inx), 0, PG_SIZE);
- }
-
- x86_pte_t l2pte = l2pt->entry[l2_inx];
- if (l2pte) {
- if (!forced) {
- return 0;
- }
- }
-
- if ((HAS_FLAGS(attr, PG_PRESENT))) {
- // add one on reference count, regardless of existence.
- pmm_ref_page(pid, pa);
- }
-
- l2pt->entry[l2_inx] = NEW_L2_ENTRY(attr, pa);
-
- return 1;
+ ptr_t va = ptep_va(ptep, lvl_size);
+ pte_t* _ptep = mkl0tep(ptep);
+ pte_t pte;
+
+ if (pte_isnull(pte = *_ptep) || _ptep == ptep)
+ return pte;
+
+#if LnT_ENABLED(1)
+ _ptep = getl1tep(_ptep, va);
+ if (_ptep == ptep || pte_isnull(pte = *_ptep))
+ return pte;
+#endif
+#if LnT_ENABLED(2)
+ _ptep = getl2tep(_ptep, va);
+ if (_ptep == ptep || pte_isnull(pte = *_ptep))
+ return pte;
+#endif
+#if LnT_ENABLED(3)
+ _ptep = getl3tep(_ptep, va);
+ if (_ptep == ptep || pte_isnull(pte = *_ptep))
+ return pte;
+#endif
+ _ptep = getlftep(_ptep, va);
+ return *_ptep;