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.cpp22
-rw-r--r--Source/Kernel/SyscallManager/IDT.ns.h2
-rw-r--r--Source/Kernel/SyscallManager/Res.ns.cpp75
-rw-r--r--Source/Kernel/SyscallManager/Res.ns.h15
-rw-r--r--Source/Kernel/SyscallManager/Ressource.class.cpp41
-rw-r--r--Source/Kernel/SyscallManager/Ressource.class.h56
6 files changed, 209 insertions, 2 deletions
diff --git a/Source/Kernel/SyscallManager/IDT.ns.cpp b/Source/Kernel/SyscallManager/IDT.ns.cpp
index fcab741..63b340a 100644
--- a/Source/Kernel/SyscallManager/IDT.ns.cpp
+++ b/Source/Kernel/SyscallManager/IDT.ns.cpp
@@ -2,6 +2,7 @@
#include <VTManager/SimpleVT.class.h>
#include <DeviceManager/Dev.ns.h>
#include <TaskManager/Task.ns.h>
+#include <SyscallManager/Res.ns.h>
using namespace Sys; //For outb
@@ -55,6 +56,7 @@ extern "C" void irq13();
extern "C" void irq14();
extern "C" void irq15();
+extern "C" void int64(); //Main syscall
extern "C" void int65(); //Syscall to request a task switch
extern "C" void int66(); //Syscall to signal that thread ended
@@ -73,6 +75,23 @@ extern "C" void interrupt_handler(registers_t regs) {
Dev::handleIRQ(regs, (regs.int_no - 32));
doSwitch = doSwitch or Task::IRQwakeup(regs.int_no - 32);
}
+ if (regs.int_no == 64) {
+ u32int res = (regs.eax >> 8);
+ u8int wat = (regs.eax & 0xFF);
+ if (res == 0xFFFFFF) {
+ if (regs.eax == 0xFFFFFF01) {
+ Task::currProcess()->getVirtualTerminal()->put(WChar(regs.ebx));
+ } else if (regs.eax == 0xFFFFFF02) {
+ Task::currThread()->sleep(regs.ebx);
+ } else if (regs.eax == 0xFFFFFF03) {
+ Task::currProcess()->getVirtualTerminal()->writeHex(regs.ebx);
+ }
+ } else {
+ regs.eax = Res::call(res, wat, regs.ebx, regs.ecx, regs.edx, regs.edi, regs.esi);
+ }
+ //Some syscalls have maybee modified current page directory, set it back to one for current process
+ Task::currProcess()->getPagedir()->switchTo();
+ }
if (regs.int_no == 66) { //This syscall signals to kernel that thread ended.
Task::currentThreadExits(regs.eax); //DO NOT COUNT ON COMMING BACK FROM HERE
}
@@ -89,7 +108,7 @@ void setGate(u8int num, u32int base, u16int sel, u8int flags) {
idt_entries[num].base_hi = (base >> 16) & 0xFFFF;
idt_entries[num].sel = sel;
- idt_entries[num].flags = flags;
+ idt_entries[num].flags = flags | 0x60;
idt_entries[num].always0 = 0;
}
@@ -161,6 +180,7 @@ void init() {
setGate(46, (u32int)irq14, 0x08, 0x8E);
setGate(47, (u32int)irq15, 0x08, 0x8E);
+ setGate(64, (u32int)int64, 0x08, 0x8E);
setGate(65, (u32int)int65, 0x08, 0x8E);
setGate(66, (u32int)int66, 0x08, 0x8E);
diff --git a/Source/Kernel/SyscallManager/IDT.ns.h b/Source/Kernel/SyscallManager/IDT.ns.h
index 52f1ed5..e73a885 100644
--- a/Source/Kernel/SyscallManager/IDT.ns.h
+++ b/Source/Kernel/SyscallManager/IDT.ns.h
@@ -1,7 +1,7 @@
#ifndef DEF_IDT_NS_H
#define DEF_IDT_NS_H
-#include <Core/common.wtf.h>
+#include <common.h>
struct registers_t {
u32int ds; // Data segment selector
diff --git a/Source/Kernel/SyscallManager/Res.ns.cpp b/Source/Kernel/SyscallManager/Res.ns.cpp
new file mode 100644
index 0000000..048d17a
--- /dev/null
+++ b/Source/Kernel/SyscallManager/Res.ns.cpp
@@ -0,0 +1,75 @@
+#include "Res.ns.h"
+
+#include <VirtualTerminal.iface.h>
+#include <Process.iface.h>
+#include <Thread.iface.h>
+#include <FSNode.iface.h>
+#include <TaskManager/Task.ns.h>
+
+namespace Res {
+
+typedef u32int (*staticcall)(u8int, u32int, u32int, u32int, u32int);
+
+struct static_call_t {
+ u32int id;
+ staticcall call;
+};
+
+static_call_t staticCalls[] = {
+ {VTIF_OBJTYPE, VirtualTerminal::scall},
+ {PRIF_OBJTYPE, Process::scall},
+ {THIF_OBJTYPE, Thread::scall},
+ {FNIF_OBJTYPE, FSNode::scall},
+ {0, 0}
+};
+
+Ressource** ressources = 0;
+u32int size = 0;
+
+void expand() { //Expands size of ressources array of 20 entries
+ size += 20;
+ Ressource** tmp = (Ressource**)Mem::alloc(size * sizeof(Ressource*));
+ for (u32int i = 0; i < size; i++) {
+ if (i < size - 20) tmp[i] = ressources[i];
+ else tmp[i] = 0;
+ }
+ Mem::free(ressources);
+ ressources = tmp;
+}
+
+u32int registerRes(Ressource* r) {
+ if (ressources == 0 or size == 0) {
+ ressources = (Ressource**)Mem::alloc(20 * sizeof(Ressource*));
+ size = 20;
+ for (u32int i = 0; i < 20; i++) ressources[i] = 0;
+ }
+ for (u32int i = 0; i < size; i++) {
+ if (ressources[i] == 0) {
+ ressources[i] = r;
+ return i;
+ }
+ }
+ expand();
+ return registerRes(r);
+}
+
+void unregisterRes(u32int id) {
+ ressources[id] = 0;
+}
+
+u32int call(u32int ressource, u8int wat, u32int a, u32int b, u32int c, u32int d, u32int e) {
+ if (ressource == 0xFFFFFE) { //TODO : return ressource id for some stuff for current process
+ for (u32int i = 0; staticCalls[i].id != 0; i++) {
+ if (staticCalls[i].id == a) return staticCalls[i].call(wat, b, c, d, e);
+ }
+ return 0;
+ } else {
+ if (ressource > size or ressources[ressource] == 0) {
+ return (u32int) - 1;
+ } else {
+ return ressources[ressource]->doCall(wat, a, b, c, d, e);
+ }
+ }
+}
+
+}
diff --git a/Source/Kernel/SyscallManager/Res.ns.h b/Source/Kernel/SyscallManager/Res.ns.h
new file mode 100644
index 0000000..e454693
--- /dev/null
+++ b/Source/Kernel/SyscallManager/Res.ns.h
@@ -0,0 +1,15 @@
+#ifndef DEF_RES_NS_H
+#define DEF_RES_NS_H
+
+#include <SyscallManager/Ressource.class.h>
+
+namespace Res {
+
+u32int registerRes(Ressource* r);
+void unregisterRes(u32int id);
+
+u32int call(u32int ressource, u8int wat, u32int a, u32int b, u32int c, u32int d, u32int e);
+
+}
+
+#endif
diff --git a/Source/Kernel/SyscallManager/Ressource.class.cpp b/Source/Kernel/SyscallManager/Ressource.class.cpp
new file mode 100644
index 0000000..f2aaccb
--- /dev/null
+++ b/Source/Kernel/SyscallManager/Ressource.class.cpp
@@ -0,0 +1,41 @@
+#include "Ressource.class.h"
+#include <SyscallManager/Res.ns.h>
+
+Ressource::Ressource(u8int type, call_t* callTable) {
+ m_id = Res::registerRes(this);
+ m_type = type;
+ m_callTables = 0;
+
+ addCallTable(callTable);
+}
+
+Ressource::~Ressource() {
+ Res::unregisterRes(m_id);
+ delete m_callTables;
+}
+
+void Ressource::addCallTable(call_t* callTable) {
+ if (callTable != 0) m_callTables = m_callTables->cons(callTable);
+}
+
+u32int Ressource::doCall(u8int id, u32int a, u32int b, u32int c, u32int d, u32int e) {
+ if (id == 0) return m_type;
+
+ for (SimpleList<call_t*> *iter = m_callTables; iter != 0; iter = iter->next()) {
+ call_t* ct = iter->v();
+ u32int i = 0;
+ while (ct[i].id != 0) {
+ call_t &ce = ct[i];
+ if (ce.id == id) {
+ if (ce.params == 0) return (this->*(ce.c0))();
+ if (ce.params == 1) return (this->*(ce.c1))(a);
+ if (ce.params == 2) return (this->*(ce.c2))(a, b);
+ if (ce.params == 3) return (this->*(ce.c3))(a, b, c);
+ if (ce.params == 4) return (this->*(ce.c4))(a, b, c, d);
+ if (ce.params == 5) return (this->*(ce.c5))(a, b, c, d, e);
+ }
+ i++;
+ }
+ }
+ return (u32int) - 1;
+}
diff --git a/Source/Kernel/SyscallManager/Ressource.class.h b/Source/Kernel/SyscallManager/Ressource.class.h
new file mode 100644
index 0000000..f58276b
--- /dev/null
+++ b/Source/Kernel/SyscallManager/Ressource.class.h
@@ -0,0 +1,56 @@
+#ifndef DEF_RESSOURCE_CLASS_H
+#define DEF_RESSOURCE_CLASS_H
+
+#include <SimpleList.class.h>
+
+class Ressource;
+
+typedef u32int (Ressource::*call0)();
+typedef u32int (Ressource::*call1)(u32int);
+typedef u32int (Ressource::*call2)(u32int, u32int);
+typedef u32int (Ressource::*call3)(u32int, u32int, u32int);
+typedef u32int (Ressource::*call4)(u32int, u32int, u32int, u32int);
+typedef u32int (Ressource::*call5)(u32int, u32int, u32int, u32int, u32int);
+
+#define CALL0(id, ptr) {0, id, {(call0)ptr}}
+#define CALL1(id, ptr) {1, id, {c1: (call1)ptr}}
+#define CALL2(id, ptr) {2, id, {c2: (call2)ptr}}
+#define CALL3(id, ptr) {3, id, {c3: (call3)ptr}}
+#define CALL4(id, ptr) {4, id, {c4: (call4)ptr}}
+#define CALL5(id, ptr) {5, id, {c5: (call5)ptr}}
+
+struct call_t {
+ u8int params;
+ u8int id;
+ union {
+ call0 c0;
+ call1 c1;
+ call2 c2;
+ call3 c3;
+ call4 c4;
+ call5 c5;
+ };
+};
+
+class Ressource {
+ private:
+ Ressource(const Ressource&);
+ Ressource& operator=(const Ressource&);
+
+ u32int m_id;
+ u32int m_type;
+ SimpleList<call_t*> *m_callTables;
+
+ protected:
+ Ressource(u8int type, call_t* callTable = 0);
+ ~Ressource();
+
+ void addCallTable(call_t* callTable);
+
+ public:
+ u32int doCall(u8int id, u32int a, u32int b, u32int c, u32int d, u32int e);
+ u32int resId() { return m_id; }
+ u32int resType() { return m_type; }
+};
+
+#endif