Untitled

 avatar
unknown
c_cpp
a year ago
2.2 kB
13
Indexable
int map_page(uintptr_t vaddr, uintptr_t paddr, PageAttributes attrs) {
    vaddr = _align_down(vaddr);
    paddr = _align_down(paddr);
    if (vaddr == 0) return -1;

    uint32_t indices[2] = {_pd_index(vaddr), _pt_index(vaddr)};
    PTE* tables[2] = {RECURSIVE_PD, NULL};

    for (int i = 0; i < 2; i++) { // walk page table levels
        switch (i) {
            case 0:
                goto _pd;
            case 1:
                goto _pt;
        }

    _pd:
        if (!tables[0][indices[0]].present) {
            PTE* new_pt = (PTE*)pmm_alloc_page();
            if (!new_pt) return -1;
            _zero_pt((PTE*)((uintptr_t)new_pt));

            PageAttributes new_attrs = {
                .present = 1,
                .rw = 1,
                .user = attrs.user,
                .frame_addr = ((uintptr_t)new_pt) >> 12
            };
            SET_PF((PTE*)&tables[0][indices[0]], new_attrs);
        }
        tables[1] = RECURSIVE_PT(indices[0]);
        continue;

    _pt:
        if (tables[1][indices[1]].present) {
            pmm_free_page((void*)(tables[1][indices[1]].frame_addr << 12));
        }
        attrs.frame_addr = paddr >> 12;
        SET_PF(&tables[1][indices[1]], attrs);
        break;
    }

    asm volatile ("invlpg (%0)" : : "a" (vaddr));
    return 0;
}

int unmap_page(uintptr_t vaddr) {
    vaddr = _align_down(vaddr);
    uint32_t pd_idx = _pd_index(vaddr);
    uint32_t pt_idx = _pt_index(vaddr);

    if (!RECURSIVE_PD[pd_idx].present) return -1;
    PTE* pt = RECURSIVE_PT(pd_idx);

    if (!pt[pt_idx].present) return -1;
    pmm_free_page((void*)(pt[pt_idx].frame_addr << 12));
    PageAttributes zero = {0};
    SET_PF(&pt[pt_idx], zero);
    bool pt_empty = true;
    for (int i = 0; i < PAGE_TABLE_SIZE; i++) {
        if (pt[i].present) {
            pt_empty = false;
            break;
        }
    }
    if (pt_empty) {
        pmm_free_page((void*)(RECURSIVE_PD[pd_idx].table_addr << 12));
        PageAttributes zero_pd = {0};
        SET_PF((PTE*)&RECURSIVE_PD[pd_idx], zero_pd);
    }

    asm volatile ("invlpg (%0)" : : "a" (vaddr));
    return 0;
}
Editor is loading...
Leave a Comment