extern "C" void pageFaultHandler(uint32 address, uint32 error) { PageFaultHandler::enterPageFault(address, error & FLAG_PF_USER, error & FLAG_PF_PRESENT, error & FLAG_PF_RDWR, error & FLAG_PF_INSTR_FETCH); if (currentThread->switch_to_userspace_) arch_contextSwitch(); else asm volatile ("movl %%cr3, %%eax; movl %%eax, %%cr3;" ::: "%eax"); }
extern "C" void irqHandler_0() { ArchCommon::drawHeartBeat(); Scheduler::instance()->incTicks(); Scheduler::instance()->schedule(); // kprintfd("irq0: Going to leave irq Handler 0\n"); ArchInterrupts::EndOfInterrupt(0); arch_contextSwitch(); }
extern "C" void errorHandler(size_t num, size_t rip, size_t cs, size_t spurious) { if (spurious) { assert(num < 128 && "there are only 128 interrupts"); debug(CPU_ERROR, "Spurious Interrupt %zu (%zx)\n", num, num); } else { assert(num < 32 && "there are only 32 CPU errors"); debug(CPU_ERROR, "\033[1;31m%s\033[0;39m\n", errors[num]); } const bool userspace = (cs & 0x3); debug(CPU_ERROR, "Instruction Pointer: %zx, Userspace: %d - currentThread: %p %zd" ":%s, switch_to_userspace_: %d\n", rip, userspace, currentThread, currentThread ? currentThread->getTID() : -1, currentThread ? currentThread->getName() : 0, currentThread ? currentThread->switch_to_userspace_ : -1); const Stabs2DebugInfo* deb = kernel_debug_info; assert(currentThread && "there should be no fault before there is a current thread"); assert(currentThread->kernel_registers_ && "every thread needs kernel registers"); ArchThreadRegisters* registers_ = currentThread->kernel_registers_; if (userspace) { assert(currentThread->loader_ && "User Threads need to have a Loader"); assert(currentThread->user_registers_ && (currentThread->user_registers_->cr3 == currentThread->kernel_registers_->cr3 && "User and Kernel CR3 register values differ, this most likely is a bug!")); deb = currentThread->loader_->getDebugInfos(); registers_ = currentThread->user_registers_; } if(deb && registers_->eip) { debug(CPU_ERROR, "This Fault was probably caused by:"); deb->printCallInformation(registers_->eip); } ArchThreads::printThreadRegisters(currentThread, false); currentThread->printBacktrace(true); if (spurious) { if (currentThread->switch_to_userspace_) arch_contextSwitch(); } else { currentThread->switch_to_userspace_ = false; currentThreadRegisters = currentThread->kernel_registers_; ArchInterrupts::enableInterrupts(); debug(CPU_ERROR, "Terminating process...\n"); currentThread->kill(); } }
extern "C" void dummyHandler() { uint32 saved_switch_to_userspace = currentThread->switch_to_userspace_; currentThread->switch_to_userspace_ = 0; currentThreadRegisters = currentThread->kernel_registers_; ArchInterrupts::enableInterrupts(); kprintfd("DUMMY_HANDLER: Spurious INT\n"); ArchInterrupts::disableInterrupts(); currentThread->switch_to_userspace_ = saved_switch_to_userspace; if (currentThread->switch_to_userspace_) { currentThreadRegisters = currentThread->user_registers_; arch_contextSwitch(); } }
extern "C" void pageFaultHandler(uint32 address, uint32 error) { printPageFaultInfo(address, error); //save previous state on stack of currentThread uint32 saved_switch_to_userspace = currentThread->switch_to_userspace_; currentThread->switch_to_userspace_ = 0; currentThreadRegisters = currentThread->kernel_registers_; ArchInterrupts::enableInterrupts(); const bool page_present = (error & FLAG_PF_PRESENT); const bool user_pagefault = (error & FLAG_PF_USER); //lets hope this Exeption wasn't thrown during a TaskSwitch if (!page_present && address < USER_BREAK && currentThread->loader_) { if (!user_pagefault && address < PAGE_SIZE) currentThread->printBacktrace(true); currentThread->loader_->loadPage(address); } else { debug(PAGEFAULT, "ERROR: The virtual page of address %x (%s-address) is present," "the pagefault was triggered by thread %s(%p), which is a %s""thread.\n", address, address >= USER_BREAK ? "kernel" : "user", currentThread->getName(), currentThread, currentThread->user_registers_ ? "user" : "kernel"); currentThread->printBacktrace(true); if (currentThread->loader_) Syscall::exit(9999); else currentThread->kill(); } ArchInterrupts::disableInterrupts(); asm volatile ("movl %%cr3, %%eax; movl %%eax, %%cr3;" ::: "%eax"); currentThread->switch_to_userspace_ = saved_switch_to_userspace; if (currentThread->switch_to_userspace_) { currentThreadRegisters = currentThread->user_registers_; arch_contextSwitch(); } }
extern "C" void syscallHandler() { currentThread->switch_to_userspace_ = 0; currentThreadRegisters = currentThread->kernel_registers_; ArchInterrupts::enableInterrupts(); currentThread->user_registers_->eax = Syscall::syscallException(currentThread->user_registers_->eax, currentThread->user_registers_->ebx, currentThread->user_registers_->ecx, currentThread->user_registers_->edx, currentThread->user_registers_->esi, currentThread->user_registers_->edi); ArchInterrupts::disableInterrupts(); currentThread->switch_to_userspace_ = 1; currentThreadRegisters = currentThread->user_registers_; //ArchThreads::printThreadRegisters(currentThread,false); arch_contextSwitch(); }
extern "C" void irqHandler_65() { Scheduler::instance()->schedule(); // kprintfd("irq65: Going to leave int Handler 65 to user\n"); arch_contextSwitch(); }