summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorAlexis211 <alexis211@gmail.com>2009-09-06 12:35:07 +0200
committerAlexis211 <alexis211@gmail.com>2009-09-06 12:35:07 +0200
commit6e83d6c7b9fc36f7e7826451899c564a34a2c761 (patch)
treebdb59ac4e422d69c9b60e1645eb2139f9a8453a3 /Source
parent7f6511e97e378d5853ec6b2edc6e330fb09e5132 (diff)
downloadMelon-6e83d6c7b9fc36f7e7826451899c564a34a2c761.tar.gz
Melon-6e83d6c7b9fc36f7e7826451899c564a34a2c761.zip
Ok, exception handling happens in Thread::.
Diffstat (limited to 'Source')
-rwxr-xr-xSource/Kernel/Melon.kebin107783 -> 111884 bytes
-rw-r--r--Source/Kernel/SyscallManager/IDT.ns.cpp48
-rw-r--r--Source/Kernel/SyscallManager/IDT.ns.h1
-rw-r--r--Source/Kernel/TaskManager/Process.class.cpp1
-rw-r--r--Source/Kernel/TaskManager/Thread.class.cpp39
-rw-r--r--Source/Kernel/TaskManager/Thread.class.h2
6 files changed, 47 insertions, 44 deletions
diff --git a/Source/Kernel/Melon.ke b/Source/Kernel/Melon.ke
index 6a1adae..a244f2c 100755
--- a/Source/Kernel/Melon.ke
+++ b/Source/Kernel/Melon.ke
Binary files differ
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();