- assert((ptr_t)va % PG_SIZE == 0);
-
- ptr_t l1_inx = L1_INDEX(va);
- ptr_t l2_inx = L2_INDEX(va);
- x86_page_table* l1pt = (x86_page_table*)(mnt | (1023 << 12));
- x86_page_table* l2pt = (x86_page_table*)(mnt | (l1_inx << 12));
-
- // See if attr make sense
- assert(attr <= 128);
-
- if (!l1pt->entry[l1_inx]) {
- x86_page_table* new_l1pt_pa =
- (x86_page_table*)pmm_alloc_page(KERNEL_PID, PP_FGPERSIST);
-
- // 物理内存已满!
- if (!new_l1pt_pa) {
- return 0;
- }
-
- // This must be writable
- l1pt->entry[l1_inx] =
- NEW_L1_ENTRY(attr | PG_WRITE | PG_PRESENT, new_l1pt_pa);
-
- // make sure our new l2 table is visible to CPU
- cpu_flush_page((ptr_t)l2pt);
-
- memset((void*)l2pt, 0, PG_SIZE);
- } else {
- x86_pte_t pte = l2pt->entry[l2_inx];
- if (pte && (options & VMAP_IGNORE)) {
- return 1;
- }
- }