diff options
Diffstat (limited to 'Source/Kernel/SyscallManager')
-rw-r--r-- | Source/Kernel/SyscallManager/IDT.ns.cpp | 22 | ||||
-rw-r--r-- | Source/Kernel/SyscallManager/IDT.ns.h | 2 | ||||
-rw-r--r-- | Source/Kernel/SyscallManager/Res.ns.cpp | 75 | ||||
-rw-r--r-- | Source/Kernel/SyscallManager/Res.ns.h | 15 | ||||
-rw-r--r-- | Source/Kernel/SyscallManager/Ressource.class.cpp | 41 | ||||
-rw-r--r-- | Source/Kernel/SyscallManager/Ressource.class.h | 56 |
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 |