diff options
author | Alexis211 <alexis211@gmail.com> | 2009-10-18 17:17:36 +0200 |
---|---|---|
committer | Alexis211 <alexis211@gmail.com> | 2009-10-18 17:17:36 +0200 |
commit | e589a45295a871f38d4a1d1f23b370b612f99be5 (patch) | |
tree | b59f1190633368d78b23d78e011c99fa8fa3cc90 /Source/Kernel/SyscallManager | |
parent | 323e12f1f9ab33df15dcfed210e807561d98fa8c (diff) | |
download | Melon-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.cpp | 19 | ||||
-rw-r--r-- | Source/Kernel/SyscallManager/Res.ns.cpp | 55 | ||||
-rw-r--r-- | Source/Kernel/SyscallManager/Res.ns.h | 15 | ||||
-rw-r--r-- | Source/Kernel/SyscallManager/Ressource.class.cpp | 65 | ||||
-rw-r--r-- | Source/Kernel/SyscallManager/Ressource.class.h | 54 |
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 |