diff options
author | Alexis211 <alexis211@gmail.com> | 2009-09-06 12:35:07 +0200 |
---|---|---|
committer | Alexis211 <alexis211@gmail.com> | 2009-09-06 12:35:07 +0200 |
commit | 6e83d6c7b9fc36f7e7826451899c564a34a2c761 (patch) | |
tree | bdb59ac4e422d69c9b60e1645eb2139f9a8453a3 /Source | |
parent | 7f6511e97e378d5853ec6b2edc6e330fb09e5132 (diff) | |
download | Melon-6e83d6c7b9fc36f7e7826451899c564a34a2c761.tar.gz Melon-6e83d6c7b9fc36f7e7826451899c564a34a2c761.zip |
Ok, exception handling happens in Thread::.
Diffstat (limited to 'Source')
-rwxr-xr-x | Source/Kernel/Melon.ke | bin | 107783 -> 111884 bytes | |||
-rw-r--r-- | Source/Kernel/SyscallManager/IDT.ns.cpp | 48 | ||||
-rw-r--r-- | Source/Kernel/SyscallManager/IDT.ns.h | 1 | ||||
-rw-r--r-- | Source/Kernel/TaskManager/Process.class.cpp | 1 | ||||
-rw-r--r-- | Source/Kernel/TaskManager/Thread.class.cpp | 39 | ||||
-rw-r--r-- | Source/Kernel/TaskManager/Thread.class.h | 2 |
6 files changed, 47 insertions, 44 deletions
diff --git a/Source/Kernel/Melon.ke b/Source/Kernel/Melon.ke Binary files differindex 6a1adae..a244f2c 100755 --- a/Source/Kernel/Melon.ke +++ b/Source/Kernel/Melon.ke diff --git a/Source/Kernel/SyscallManager/IDT.ns.cpp b/Source/Kernel/SyscallManager/IDT.ns.cpp index 96b2e2a..f31c789 100644 --- a/Source/Kernel/SyscallManager/IDT.ns.cpp +++ b/Source/Kernel/SyscallManager/IDT.ns.cpp @@ -55,15 +55,17 @@ extern "C" void irq13(); extern "C" void irq14(); extern "C" void irq15(); -extern "C" void int65(); //IRQ to request a task switch -extern "C" void int66(); //IRQ to signal that thread ended +extern "C" void int65(); //Syscall to request a task switch +extern "C" void int66(); //Syscall to signal that thread ended extern "C" void idt_flush(u32int); extern "C" void interrupt_handler(registers_t regs) { bool doSwitch = (regs.int_no == 32 or regs.int_no >= 65); //SYSCALLS >= 65 are task-managing-related if (regs.int_no < 32) { - IDT::handleException(regs, regs.int_no); + if ((u32int)Task::currentThread == 0xFFFFFFFF or Task::currentThread == 0) + PANIC("Exception cannot be handled."); + Task::currentThread->handleException(regs, regs.int_no); } else if (regs.int_no < 48) { if (regs.int_no >= 40) outb(0xA0, 0x20); @@ -165,44 +167,4 @@ void init() { idt_flush((u32int)&idt_ptr); } -void handleException(registers_t regs, int no) { //TODO :: make exception handling work with task managment - asm volatile("cli;"); - char* exceptions[] = { - "Division by zero", "Debug exception", "Non maskable interrupt", - "Breakpoint exception", "'Into detected overflow'", "Out of bounds exception", - "Invalid opcode exception", "No coprocessor exception", "Double fault", - "Coprocessor segment overrun", "Bad TSS", "Segment not present", - "Stack fault", "General protection fault", "Page fault", - "Unknown", "Coprocessor fault", "Alignement check exception", - "Machine check exception", "", "", - "", "", "", - "", "", "", - "", "", "", - "", ""}; - - VirtualTerminal *vt = new VirtualTerminal(5, 50, 0, 15); - vt->map(); - - *vt << "\n Unhandled exception " << (s32int)no << " at "; - vt->writeHex(regs.cs); *vt <<":"; vt->writeHex(regs.eip); - *vt << "\n :: " << exceptions[no]; - - if (no == 14) { //Page fault - int present = !(regs.err_code & 0x1); - int rw = regs.err_code & 0x2; - int us = regs.err_code & 0x4; - int rsvd = regs.err_code & 0x8; - u32int faddr; - asm volatile("mov %%cr2, %0" : "=r"(faddr)); - *vt << "\n "; - if (present) *vt << "Present "; - if (rw) *vt << "R/W "; - if (us) *vt << "User "; - if (rsvd) *vt << "Rsvd "; - *vt << "At:" << (u32int)faddr; - } - - asm volatile("hlt"); -} - } diff --git a/Source/Kernel/SyscallManager/IDT.ns.h b/Source/Kernel/SyscallManager/IDT.ns.h index cf8e9f2..52f1ed5 100644 --- a/Source/Kernel/SyscallManager/IDT.ns.h +++ b/Source/Kernel/SyscallManager/IDT.ns.h @@ -25,7 +25,6 @@ namespace IDT { }__attribute__((packed)); void init(); - void handleException(registers_t regs, int no); } #endif diff --git a/Source/Kernel/TaskManager/Process.class.cpp b/Source/Kernel/TaskManager/Process.class.cpp index 13af4b9..f94e652 100644 --- a/Source/Kernel/TaskManager/Process.class.cpp +++ b/Source/Kernel/TaskManager/Process.class.cpp @@ -14,6 +14,7 @@ Process* Process::createKernel(String cmdline, VirtualTerminal *vt) { p->m_pagedir = kernelPageDirectory; p->m_uid = 0; p->m_stacksstart = 0; + p->m_vt = vt; Thread* t = new Thread(); t->m_process = p; diff --git a/Source/Kernel/TaskManager/Thread.class.cpp b/Source/Kernel/TaskManager/Thread.class.cpp index ae399f4..2d167df 100644 --- a/Source/Kernel/TaskManager/Thread.class.cpp +++ b/Source/Kernel/TaskManager/Thread.class.cpp @@ -71,6 +71,45 @@ void Thread::finish(u32int errcode) { m_process->threadFinishes(this, errcode); } +void Thread::handleException(registers_t regs, int no) { + char* exceptions[] = { + "Division by zero", "Debug exception", "Non maskable interrupt", + "Breakpoint exception", "'Into detected overflow'", "Out of bounds exception", + "Invalid opcode exception", "No coprocessor exception", "Double fault", + "Coprocessor segment overrun", "Bad TSS", "Segment not present", + "Stack fault", "General protection fault", "Page fault", + "Unknown", "Coprocessor fault", "Alignement check exception", + "Machine check exception", "", "", + "", "", "", + "", "", "", + "", "", "", + "", ""}; + + *(m_process->m_vt) << "\nUnhandled exception " << (s32int)no << " at " << (u32int)regs.cs << ":" << + (u32int)regs.eip << "\n:: " << exceptions[no]; + + if (no == 14) { //Page fault + int present = !(regs.err_code & 0x1); + int rw = regs.err_code & 0x2; + int us = regs.err_code & 0x4; + int rsvd = regs.err_code & 0x8; + u32int faddr; + asm volatile("mov %%cr2, %0" : "=r"(faddr)); + *(m_process->m_vt) << "\n "; + if (present) *(m_process->m_vt) << "Present "; + if (rw) *(m_process->m_vt) << "R/W "; + if (us) *(m_process->m_vt) << "User "; + if (rsvd) *(m_process->m_vt) << "Rsvd "; + *(m_process->m_vt) << "At:" << (u32int)faddr; + + *(m_process->m_vt) << "\nThread finishing.\n"; + finish(E_PAGEFAULT); + return; + } + *(m_process->m_vt) << "\nThread finishing.\n"; + finish(E_UNHANDLED_EXCEPTION); +} + void Thread::setState(u32int esp, u32int ebp, u32int eip) { m_esp = esp; m_ebp = ebp; diff --git a/Source/Kernel/TaskManager/Thread.class.h b/Source/Kernel/TaskManager/Thread.class.h index f8ab3ff..7d7917b 100644 --- a/Source/Kernel/TaskManager/Thread.class.h +++ b/Source/Kernel/TaskManager/Thread.class.h @@ -2,6 +2,7 @@ #define DEF_THREAD_CLASS_H #include <TaskManager/Process.class.h> +#include <SyscallManager/IDT.ns.h> #define T_ZOMBIE 0 #define T_RUNNING 1 @@ -33,6 +34,7 @@ class Thread { Thread(Process* process, u32int (*entry_point)()); ~Thread(); void finish(u32int errcode); //Called by run() when thread returns, and by exception handler. Can also be called by the thread itself + void handleException(registers_t regs, int no); void setState(u32int esp, u32int ebp, u32int eip); u32int getEsp(); |