summaryrefslogtreecommitdiff
path: root/Source/Kernel/SyscallManager
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Kernel/SyscallManager')
-rw-r--r--Source/Kernel/SyscallManager/IDT.ns.cpp23
-rw-r--r--Source/Kernel/SyscallManager/IDT.wtf.asm13
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: