static void virtual_init(struct proc *target, struct proc *source) { /* Create pml4 */ target->cr3 = page_phys_addr(get_zeroed_page(ZONE_1GB)); /* For now, only map the kernel 512 Gbyte segment */ *((struct pml4e *)VIRT(target->cr3) + pml4_index(KERN_PAGE_OFFSET)) = *((struct pml4e *)VIRT(source->cr3) + pml4_index(KERN_PAGE_OFFSET)); }
/** * Called when a pagefault occurs, is in charge of fixing the fault and swapping * if necessary. */ void cPageFault(isrVal_t registers) { addr_t page = getCR2(); addr_t page_addr = page & ~(0xFFF); #ifdef PAGEDBG printf("PG!\n"); printf("Fault addr: %X\nPage index: %X\n", page, page_addr); printf("Fault type: %X\n", registers.errCode); printf("EIP: %X\nESP: %X\nESP: %X\n", registers.eip, registers.procesp, registers.esp); printf("eax: %X\tebx: %X\necx: %X\tedx: %X\n", registers.eax, registers.ebx, registers.ecx, registers.edx); #endif if (registers.cs != 0x8 && registers.cs != 0x18) panic("Incorrect frame!"); if (USER(registers.errCode)) panic("Userspace isn't implemented yet!"); if (RESERVED(registers.errCode)) panic("A reserved bit has been set!\n"); if (PRESENT(registers.errCode)) panic("Illegal operation!"); addr_t pd = getPageDir(); /** * The data bit only works if a specific bit is set. See intel docs volume 3 * for more information. */ if (DATA(registers.errCode)) { #ifdef PAGEDBG printf("Trying to access unimplemented data!\n"); #endif if (WRITE(registers.errCode)) { #ifdef PAGEDBG printf("Faulted a write attempt!\n"); printf("Adding page!\n"); #endif if (USER(registers.errCode)) { //Add a user page! } else { #ifdef PAGEDBG printf("Adding a kernel page!\n"); #endif if (idx_kernel_space == MAP_NOMAP) panic("Kernel page map not correctly initialised!"); int ret = page_alloc_page (idx_kernel_space, page_addr, (void*)pd, FALSE); if (ret != -E_SUCCESS) { printf("ERRCODE: %X\n", -ret); panic("Couldn't alloc page!"); } #ifdef PAGEDBG printf("Phys of %X = %X\n", page, page_phys_addr(page, (void*)pd)); #endif } } else { #ifdef PAGEDBG printf("Faulted a read attempt!\n"); #endif // Assume the page may be read! if (idx_kernel_space == MAP_NOMAP) panic("Kernel page map not correctly initialised!"); int ret = page_alloc_page(idx_kernel_space, page_addr, (void*)pd, FALSE); if (ret != -E_SUCCESS) { printf("ERRCODE: %X\n", -ret); panic("Couldn't alloc page!"); } #ifdef PAGEDBG printf("Phys of %X = %X\n", page, page_phys_addr(page, (void*)pd)); #endif } } else { #ifdef PAGEDBG panic("Trying to run unimplemented code!\n"); #endif } #ifdef UNDEFINED printf("Page faults currently under construction!\n"); #endif }