summaryrefslogtreecommitdiff
path: root/Source/Kernel/SyscallManager
diff options
context:
space:
mode:
authorAlexis211 <alexis211@gmail.com>2009-10-18 17:17:36 +0200
committerAlexis211 <alexis211@gmail.com>2009-10-18 17:17:36 +0200
commite589a45295a871f38d4a1d1f23b370b612f99be5 (patch)
treeb59f1190633368d78b23d78e011c99fa8fa3cc90 /Source/Kernel/SyscallManager
parent323e12f1f9ab33df15dcfed210e807561d98fa8c (diff)
downloadMelon-e589a45295a871f38d4a1d1f23b370b612f99be5.tar.gz
Melon-e589a45295a871f38d4a1d1f23b370b612f99be5.zip
Syscall interface starts being implemented !
Diffstat (limited to 'Source/Kernel/SyscallManager')
-rw-r--r--Source/Kernel/SyscallManager/IDT.ns.cpp19
-rw-r--r--Source/Kernel/SyscallManager/Res.ns.cpp55
-rw-r--r--Source/Kernel/SyscallManager/Res.ns.h15
-rw-r--r--Source/Kernel/SyscallManager/Ressource.class.cpp65
-rw-r--r--Source/Kernel/SyscallManager/Ressource.class.h54
5 files changed, 202 insertions, 6 deletions
diff --git a/Source/Kernel/SyscallManager/IDT.ns.cpp b/Source/Kernel/SyscallManager/IDT.ns.cpp
index 46e6ee2..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
@@ -75,12 +76,18 @@ extern "C" void interrupt_handler(registers_t regs) {
doSwitch = doSwitch or Task::IRQwakeup(regs.int_no - 32);
}
if (regs.int_no == 64) {
- 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);
+ 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();
diff --git a/Source/Kernel/SyscallManager/Res.ns.cpp b/Source/Kernel/SyscallManager/Res.ns.cpp
new file mode 100644
index 0000000..aceadf7
--- /dev/null
+++ b/Source/Kernel/SyscallManager/Res.ns.cpp
@@ -0,0 +1,55 @@
+#include "Res.ns.h"
+
+#include <VirtualTerminal.iface.h>
+#include <TaskManager/Task.ns.h>
+
+namespace Res {
+
+Ressource** ressources = 0;
+u32int size = 0;
+
+void expand() { //Expands size of ressources array of 20 entries
+ size += 20;
+ Ressource** tmp = (Ressource**)Mem::kalloc(size * sizeof(Ressource*));
+ for (u32int i = 0; i < size; i++) {
+ if (i < size - 20) tmp[i] = ressources[i];
+ else tmp[i] = 0;
+ }
+ Mem::kfree(ressources);
+ ressources = tmp;
+}
+
+u32int registerRes(Ressource* r) {
+ if (ressources == 0 or size == 0) {
+ ressources = (Ressource**)Mem::kalloc(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
+ if (a == VT_IFACE_OBJTYPE) return Task::currProcess()->getVirtualTerminal()->resId();
+ 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..4e62d79
--- /dev/null
+++ b/Source/Kernel/SyscallManager/Ressource.class.cpp
@@ -0,0 +1,65 @@
+#include "Ressource.class.h"
+#include <SyscallManager/Res.ns.h>
+
+Ressource::Ressource(u8int type) {
+ m_id = Res::registerRes(this);
+ m_type = type;
+ m_calls = 0;
+
+ addCall0(0, (call0)&Ressource::resType);
+}
+
+Ressource::~Ressource() {
+ Res::unregisterRes(m_id);
+ delete m_calls;
+}
+
+void Ressource::addCall0(u8int id, call0 c) {
+ call_t e = {0, id, {c}};
+ m_calls = m_calls->cons(e);
+}
+
+void Ressource::addCall1(u8int id, call1 c) {
+ call_t e = {1, id, {0}};
+ e.c1 = c;
+ m_calls = m_calls->cons(e);
+}
+
+void Ressource::addCall2(u8int id, call2 c) {
+ call_t e = {2, id, {0}};
+ e.c2 = c;
+ m_calls = m_calls->cons(e);
+}
+
+void Ressource::addCall3(u8int id, call3 c) {
+ call_t e = {3, id, {0}};
+ e.c3 = c;
+ m_calls = m_calls->cons(e);
+}
+
+void Ressource::addCall4(u8int id, call4 c) {
+ call_t e = {4, id, {0}};
+ e.c4 = c;
+ m_calls = m_calls->cons(e);
+}
+
+void Ressource::addCall5(u8int id, call5 c) {
+ call_t e = {5, id, {0}};
+ e.c5 = c;
+ m_calls = m_calls->cons(e);
+}
+
+u32int Ressource::doCall(u8int id, u32int a, u32int b, u32int c, u32int d, u32int e) {
+ for (SimpleList<call_t> *iter = m_calls; iter != 0; iter = iter->next()) {
+ call_t &ce = iter->v();
+ 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);
+ }
+ }
+ 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..5f4e6bf
--- /dev/null
+++ b/Source/Kernel/SyscallManager/Ressource.class.h
@@ -0,0 +1,54 @@
+#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);
+
+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_calls;
+
+ protected:
+ Ressource(u8int type);
+ ~Ressource();
+
+ void addCall0(u8int id, call0 c);
+ void addCall1(u8int id, call1 c);
+ void addCall2(u8int id, call2 c);
+ void addCall3(u8int id, call3 c);
+ void addCall4(u8int id, call4 c);
+ void addCall5(u8int id, call5 c);
+
+ 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