void *MMU::palloc(size_t numberOfPages) { size_t contiguousFoundPages = 0; size_t retpde = 0, retpte = 0; void *retval = nullptr; for (size_t pde = 0; pde < 1024 && contiguousFoundPages != numberOfPages; ++pde) { PageTable table = getOrCreateTable(pde); // look through page table for (size_t pte = 0; pte < 1024; ++pte) { PageEntry entry = table.entryAtIndex(pte); if (!entry.getFlag(kPresentBit)) { // found a page that isn't present (is available) if (contiguousFoundPages == 0) { // this is the first available page, set our return pointer to it retpde = pde; retpte = pte; } ++contiguousFoundPages; if (contiguousFoundPages == numberOfPages) { // done retval = (void *) ((retpde << 22) | (retpte << 12)); break; } } else if (contiguousFoundPages) { // current page is used, reset our contiguous page count retval = nullptr; contiguousFoundPages = 0; } } } if (retval) { // if we succeeded in finding space allocatePages(retval, numberOfPages); } return retval; }
void *MMU::palloc(void *virtualAddress, size_t numberOfPages) { uintptr_t address = reinterpret_cast<uintptr_t>(virtualAddress); if (address & 0xFFF) { return nullptr; // address is not page aligned } for (size_t i = 0; i < numberOfPages; ++i) { auto page = pageForAddress(reinterpret_cast<void*>(address)); if (page.getFlag(kPresentBit)) { virtualAddress = nullptr; // can't allocate, not enough space break; } address += 0x1000; // increment to next page } if (virtualAddress) { allocatePages(virtualAddress, numberOfPages); } return virtualAddress; }
void isr_handler(struct regs r) { if(r.int_number == 0) { printf("Exception : Divide by Zero\n"); printf("Faulting instruction: %x\n",readcr2()); KillisCalled(pcb_head, current_pcb->processID); // exit(0); } else if(r.int_number == 13) { printf("Exception : General Protection fault\n"); printf("Faulting instruction: %x\n",readcr2()); printf("Error code: %x\n",r.err_code); KillisCalled(pcb_head, current_pcb->processID); } else if(r.int_number == 14) { // printf("Page fault\t"); // printf("Fault addr: %x\t",readcr2()); // printf("Error code: %x\n",r.err_code); //while(1);//test 20th apr // New page fault handler uint64_t errorCode = r.err_code; uint64_t faultAddr = (uint64_t)readcr2(); struct vma *vmas = current_pcb->first_vma; if(!(errorCode & 0x4))//Page fault in kernel mode { /* //allocate to heap if malloc ed if(faultAddr>=UHEAPSTART && faultAddr<=UHEAPLIMIT-PAGE_SIZE) { page_insert(current_pcb->pml4,alignDown((void *)faultAddr), page_alloc(), BIT_USER | BIT_RW | BIT_PRESENT); printf("Inserted page for heap mem in kernel space\n"); } else { */ printf("Page fault in kernel mode.\n"); //} } //AADY: 26th APR if(errorCode & 0x1) //Page present but page protection violation, check for COW { if(errorCode & 0x2)//If page fault on write { copy_on_write_handler(faultAddr); } return; } //Find VMA corresponding to faulting address vmas = findVMA(faultAddr, errorCode); if(!vmas)//Illegal access { printf("Segmentation fault.\n"); //KILL PROCESS KillisCalled(pcb_head, current_pcb->processID); } else { allocatePages(vmas);//Allocate pages as per vma size copyELF(vmas); //Copy binary contents } }else if(r.int_number == 128){ // handled directly } else { printf("Common : %d\n",r.int_number); while(1); } //return }