int TLBhandlePageFault(struct proc* p, void* va){ // cprintf("%d | [%s] page fault for process: %d with virtual address: 0x%x \n",proc->pid, __FUNCTION__, p->pid, va); //Getting the pte from the process page directory pte_t* desiredPageTableEntry = walkpgdir(p->pgdir, (const void*)va, 0); if(desiredPageTableEntry == 0 || ( (*desiredPageTableEntry & PTE_P)==0) ){ //todo : should panic? //cprintf("%d | [%s] error finding page table entry \n",proc->pid, __FUNCTION__); return - 1; } // cprintf("%d | [%s] found page table entry. loading into TLB \n",proc->pid, __FUNCTION__); //Making space for the pte in the tlb pte_t* emptySpaceInTLB = walkpgdir(cpu->kpgdir, (const void*)va, 1); if(emptySpaceInTLB == 0){ //todo : should panic? cprintf("%d | [%s] error - no free space in TLB! \n",proc->pid, __FUNCTION__); return -1; } //Copying the pte to the TLB *emptySpaceInTLB = *desiredPageTableEntry; //register in the TLB structure tlb_insert(va); return 0; }
hwaddr_t page_translate(lnaddr_t addr, size_t len) { hwaddr_t hwaddr = -1; hwaddr_t __hwaddr = -1; if ( tlb_read(addr, &hwaddr) ) { test(hwaddr != -1, "tlb hit and wrong: return %x", hwaddr); return hwaddr; } test(hwaddr == -1, "tlb miss and wrong"); Lnaddr lnaddr; PDE dir_entry; PTE page_entry; lnaddr.val = addr; hwaddr_t dir_addr = cpu.cr3.page_directory_base << 12; dir_entry.val = hwaddr_read(dir_addr + 4 * lnaddr.dir, 4); if (!dir_entry.present) { Test(0, "dir fault: eip %#x, vaddr %#x, dir %#x, page %#x, offset %#x", cpu.eip, addr, lnaddr.dir, lnaddr.page, lnaddr.offset); assert(0); } page_entry.val = hwaddr_read((dir_entry.page_frame << 12) + 4 * lnaddr.page, 4); if (!page_entry.present) { Test(0, "page fault: eip %#x, vaddr %#x, dir %#x, page %#x, offset %#x", cpu.eip, addr, lnaddr.dir, lnaddr.page, lnaddr.offset); assert(0); } __hwaddr = (page_entry.page_frame << 12) + lnaddr.offset; tlb_insert(addr, page_entry); return __hwaddr; }