/* * uint8_t* user_vidmap() * Description: Maps video memory for a user process * Inputs: none * Return Value: A pointer to the newly mapped virtual memory */ uint8_t* user_vidmap() { // Set up PTE if necessary uint32_t PT_index = get_PTE_offset(USER_VID); if(PT[1][PT_index].present == 0) { PTE_t PTE_video; PTE_video = PTE_default; PTE_video.user_super = 1; PTE_video.read_write = 1; SET_PTE(PTE_video, VIDEO_MEM); PT[1][PT_index] = PTE_video; } // Set up PDE if necessary uint32_t PD_index = get_PDE_offset(USER_VID); if(cur_PD[PD_index].present == 0) { PDE_t PDE_video; PDE_video = PDE_default; PDE_video.user_super = 1; PDE_video.read_write = 1; SET_PDE_4KB_PT(PDE_video, PT[1]); cur_PD[PD_index] = PDE_video; } INVLPG(USER_VID); return (uint8_t*)USER_VID; }
/* * void init_VIDEO_PT() * Description: Sets up video memory mapping for kernel * Inputs: none * Return Value: none */ void init_VIDEO_PT() { // Fill the video page table with blank entries PTE_default.present = 0; PTE_default.read_write = 0; PTE_default.user_super = 0; PTE_default.write_through = 0; PTE_default.cache_disabled = 0; PTE_default.accessed = 0; PTE_default.dirty = 0; PTE_default.page_table_attribute = 0; PTE_default.global = 0; PTE_default.avail = 0; PTE_default.page_base = 0; int i, j; for(i = 0; i < NUM_PT; i++) { for(j = 0; j < NUM_PTE; j++) { PT[i][j] = PTE_default; } } // Set up the kernel video PTE int offset = get_PTE_offset(VIDEO_MEM); PTE_t PTE_video; PTE_video = PTE_default; PTE_video.global = 1; PTE_video.read_write = 1; SET_PTE(PTE_video, VIDEO_MEM); PT[0][offset] = PTE_video; }
void map_page(void *vaddr, unsigned long pfn, unsigned long flags) { // Allocate page table if not already done if ((GET_PDE(vaddr) & PT_PRESENT) == 0) { unsigned long pdfn; pdfn = alloc_pageframe('PTAB'); if (USERSPACE(vaddr)) { SET_PDE(vaddr, PTOB(pdfn) | PT_PRESENT | PT_WRITABLE | PT_USER); } else { SET_PDE(vaddr, PTOB(pdfn) | PT_PRESENT | PT_WRITABLE); } memset(ptab + PDEIDX(vaddr) * PTES_PER_PAGE, 0, PAGESIZE); register_page_table(pdfn); } // Map page frame into address space SET_PTE(vaddr, PTOB(pfn) | flags); }
void clear_dirty(void *vaddr) { SET_PTE(vaddr, GET_PTE(vaddr) & ~PT_DIRTY); invlpage(vaddr); }
void unguard_page(void *vaddr) { SET_PTE(vaddr, (GET_PTE(vaddr) & ~PT_GUARD) | PT_USER); invlpage(vaddr); }
void set_page_flags(void *vaddr, unsigned long flags) { SET_PTE(vaddr, (GET_PTE(vaddr) & PT_PFNMASK) | flags); invlpage(vaddr); }
void unmap_page(void *vaddr) { SET_PTE(vaddr, 0); invlpage(vaddr); }
void init_pdir() { unsigned long i; // Clear identity mapping of the first 4 MB made by the os loader for (i = 0; i < PTES_PER_PAGE; i++) SET_PTE(PTOB(i), 0); }