diff options
author | Alexis211 <alexis211@gmail.com> | 2009-08-29 13:39:06 +0200 |
---|---|---|
committer | Alexis211 <alexis211@gmail.com> | 2009-08-29 13:39:06 +0200 |
commit | c92beeedda51487696ce476ee30604f22e7b2270 (patch) | |
tree | 29b89d31b0b35792e1ed2bc5861be0439e7e40d9 /Source/Kernel/SyscallManager | |
parent | 5deab22107fc38bd2bea19f07889b14c376754e0 (diff) | |
download | Melon-c92beeedda51487696ce476ee30604f22e7b2270.tar.gz Melon-c92beeedda51487696ce476ee30604f22e7b2270.zip |
The Melon kernel now has support for simple multitasking
Diffstat (limited to 'Source/Kernel/SyscallManager')
-rw-r--r-- | Source/Kernel/SyscallManager/IDT.ns.cpp | 23 | ||||
-rw-r--r-- | Source/Kernel/SyscallManager/IDT.wtf.asm | 13 |
2 files changed, 35 insertions, 1 deletions
diff --git a/Source/Kernel/SyscallManager/IDT.ns.cpp b/Source/Kernel/SyscallManager/IDT.ns.cpp index 4635f5f..caa3b36 100644 --- a/Source/Kernel/SyscallManager/IDT.ns.cpp +++ b/Source/Kernel/SyscallManager/IDT.ns.cpp @@ -1,6 +1,7 @@ #include "IDT.ns.h" #include <VTManager/VirtualTerminal.class.h> #include <DeviceManager/Dev.ns.h> +#include <TaskManager/Task.ns.h> using namespace Sys; //For outb @@ -54,9 +55,12 @@ extern "C" void irq13(); extern "C" void irq14(); extern "C" void irq15(); +extern "C" void int64(); + extern "C" void idt_flush(u32int); extern "C" void interrupt_handler(registers_t regs) { + bool doSwitch = (regs.int_no == 32 or regs.int_no == 64); if (regs.int_no < 32) { IDT::handleException(regs, regs.int_no); } else if (regs.int_no < 48) { @@ -64,7 +68,9 @@ extern "C" void interrupt_handler(registers_t regs) { outb(0xA0, 0x20); outb(0x20, 0x20); Dev::handleIRQ(regs, (regs.int_no - 32)); + doSwitch = doSwitch or Task::IRQwakeup(regs.int_no - 32); } + if (doSwitch) Task::doSwitch(); } namespace IDT { @@ -148,6 +154,8 @@ void init() { setGate(45, (u32int)irq13, 0x08, 0x8E); setGate(46, (u32int)irq14, 0x08, 0x8E); setGate(47, (u32int)irq15, 0x08, 0x8E); + + setGate(64, (u32int)int64, 0x08, 0x8E); idt_flush((u32int)&idt_ptr); } @@ -173,6 +181,21 @@ void handleException(registers_t regs, int no) { *vt << "\n Unhandled 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)); + *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.wtf.asm b/Source/Kernel/SyscallManager/IDT.wtf.asm index b76d912..7980d13 100644 --- a/Source/Kernel/SyscallManager/IDT.wtf.asm +++ b/Source/Kernel/SyscallManager/IDT.wtf.asm @@ -28,7 +28,7 @@ idt_flush: %endmacro %macro IRQ 2 - global irq%1 + [GLOBAL irq%1] irq%1: cli push byte 0 @@ -36,6 +36,15 @@ idt_flush: jmp interrupt_common_stub %endmacro +%macro SYSCALL 1 + [GLOBAL int%1] + int%1: + cli + push byte 0 + push byte %1 + jmp interrupt_common_stub +%endmacro + ; ******************************************************************** ISR_NOERRCODE 0 @@ -88,6 +97,8 @@ IRQ 13, 45 IRQ 14, 46 IRQ 15, 47 +SYSCALL 64 ; this syscall requests a task switch + ; ****************************************************************** interrupt_common_stub: |