diff options
20 files changed, 338 insertions, 26 deletions
diff --git a/Source/Applications/SampleApps/Makefile b/Source/Applications/SampleApps/Makefile index 6d12f3f..d45011e 100644 --- a/Source/Applications/SampleApps/Makefile +++ b/Source/Applications/SampleApps/Makefile @@ -4,7 +4,7 @@ ASM = nasm ASMFLAGS = -f elf CXX = g++ -CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I ../../Library/Common -I ../../Library/Userland -D THIS_IS_MELON_USERLAND +CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I ../../Library/Common -I ../../Library/Interface -I ../../Library/Userland -D THIS_IS_MELON_USERLAND LD = ld LDFLAGS = --entry=start -Ttext=40000000 diff --git a/Source/Applications/SampleApps/cxxdemo.cpp b/Source/Applications/SampleApps/cxxdemo.cpp index 5d95d28..af16599 100644 --- a/Source/Applications/SampleApps/cxxdemo.cpp +++ b/Source/Applications/SampleApps/cxxdemo.cpp @@ -1,10 +1,14 @@ #include <Syscall/Syscall.wtf.h> #include <WChar.class.h> +#include <VirtualTerminal.class.h> int main() { + VirtualTerminal x = VirtualTerminal::get(); for (char c = ' '; c <= 'z'; c++) { - syscall(0xFFFFFF02, (unsigned int)c); - putch(c); + sleep((u32int)c / 4); + x.put(c); } - putch('\n'); + x.put("\n"); + x.writeHex(0xDEADBEEF); + x.put("\n"); } diff --git a/Source/Kernel/Makefile b/Source/Kernel/Makefile index 257c53d..a090ac6 100644 --- a/Source/Kernel/Makefile +++ b/Source/Kernel/Makefile @@ -5,7 +5,7 @@ CXX = g++ LD = ld LDFLAGS = -T Link.ld -Map Map.txt --oformat=elf32-i386 CFLAGS = -nostdlib -nostartfiles -nodefaultlibs -fno-builtin -fno-stack-protector -Wall -Wextra -Werror -I . -CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I . -I ../Library/Common -Wall -Werror -Wno-write-strings -funsigned-char -D THIS_IS_MELON_KERNEL -D RANDOM_SEED=1`date +%N`LL -g +CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I . -I ../Library/Common -I ../Library/Interface -Wall -Werror -Wno-write-strings -funsigned-char -D THIS_IS_MELON_KERNEL -D RANDOM_SEED=1`date +%N`LL -g ASM = nasm ASMFLAGS = -f elf @@ -38,6 +38,7 @@ Objects = Core/loader.wtf.o \ VTManager/PipeVT.class.o \ VTManager/FileVT.class.o \ VTManager/VirtualTerminal-kbd.proto.o \ + VTManager/VirtualTerminal-sc.proto.o \ VTManager/VT.ns.o \ Shell/KernelShell.class.o \ Shell/KernelShell-fs.class.o \ @@ -59,6 +60,8 @@ Objects = Core/loader.wtf.o \ VFS/DirectoryNode.class.o \ FileSystems/RamFS/RamFS.class.o \ SyscallManager/IDT.ns.o \ + SyscallManager/Ressource.class.o \ + SyscallManager/Res.ns.o \ SyscallManager/IDT.wtf.o \ Devices/Display/VGATextOutput.class.o \ Devices/Keyboard/PS2Keyboard.class.o \ 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 diff --git a/Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp b/Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp new file mode 100644 index 0000000..8948657 --- /dev/null +++ b/Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp @@ -0,0 +1,11 @@ +#include "VirtualTerminal.proto.h" + +u32int VirtualTerminal::writeHexSC(u32int number) { + writeHex(number); + return 0; +} + +u32int VirtualTerminal::putSC(u32int code) { + put(WChar(code)); + return 0; +} diff --git a/Source/Kernel/VTManager/VirtualTerminal.proto.cpp b/Source/Kernel/VTManager/VirtualTerminal.proto.cpp index 0612f1d..b7c7340 100644 --- a/Source/Kernel/VTManager/VirtualTerminal.proto.cpp +++ b/Source/Kernel/VTManager/VirtualTerminal.proto.cpp @@ -2,7 +2,12 @@ #include <DeviceManager/Disp.ns.h> #include <VTManager/VT.ns.h> -VirtualTerminal::VirtualTerminal() : m_kbdMutex(false), m_kbdbuffMutex(false), m_kbdbuff() { +#include <VirtualTerminal.iface.h> + +VirtualTerminal::VirtualTerminal() : + Ressource(VT_IFACE_OBJTYPE), m_kbdMutex(false), m_kbdbuffMutex(false), m_kbdbuff() { + addCall1(VT_IFACE_WRITEHEX, (call1)&VirtualTerminal::writeHexSC); + addCall1(VT_IFACE_PUT, (call1)&VirtualTerminal::putSC); } VirtualTerminal::~VirtualTerminal() { diff --git a/Source/Kernel/VTManager/VirtualTerminal.proto.h b/Source/Kernel/VTManager/VirtualTerminal.proto.h index 9d0afa0..487233d 100644 --- a/Source/Kernel/VTManager/VirtualTerminal.proto.h +++ b/Source/Kernel/VTManager/VirtualTerminal.proto.h @@ -7,16 +7,22 @@ #include <DeviceManager/Kbd.ns.h> #include <Vector.class.h> +#include <SyscallManager/Ressource.class.h> + struct vtchr { u8int color; WChar c; }; -class VirtualTerminal { +class VirtualTerminal : public Ressource { protected: Mutex m_kbdMutex, m_kbdbuffMutex; Vector<Kbd::keypress_t> m_kbdbuff; //Key press events buffer + //SYSCALLS : + u32int writeHexSC(u32int); + u32int putSC(u32int); + public: VirtualTerminal(); virtual ~VirtualTerminal(); diff --git a/Source/Library/Common/SimpleList.class.h b/Source/Library/Common/SimpleList.class.h index 64e37aa..3e0f968 100644 --- a/Source/Library/Common/SimpleList.class.h +++ b/Source/Library/Common/SimpleList.class.h @@ -1,6 +1,8 @@ #ifndef DEF_SIMPLELIST_CLASS_H #define DEF_SIMPLELIST_CLASS_H +#include <common.h> + /* This class implements a singly linked list. It is also used to represent one of its elements. */ template <typename T> diff --git a/Source/Library/Interface/VirtualTerminal.iface.h b/Source/Library/Interface/VirtualTerminal.iface.h new file mode 100644 index 0000000..661162f --- /dev/null +++ b/Source/Library/Interface/VirtualTerminal.iface.h @@ -0,0 +1,8 @@ +#ifndef DEF_VITRUALTERMINAL_IFACE_H +#define DEF_VITRUALTERMINAL_IFACE_H + +#define VT_IFACE_OBJTYPE 0x10 +#define VT_IFACE_PUT 0x01 +#define VT_IFACE_WRITEHEX 0x02 + +#endif diff --git a/Source/Library/Makefile b/Source/Library/Makefile index f7d337b..b9be0a0 100644 --- a/Source/Library/Makefile +++ b/Source/Library/Makefile @@ -9,7 +9,9 @@ LD = ld Library = Melon.o Objects = Common/WChar.class.uo \ Common/CMem.ns.uo \ - Userland/Syscall/Syscall.wtf.uo + Userland/Syscall/Syscall.wtf.uo \ + Userland/Syscall/RessourceCaller.class.uo \ + Userland/Start.uo all: $(Library) echo "* Done with library" diff --git a/Source/Library/Userland/Start.cpp b/Source/Library/Userland/Start.cpp new file mode 100644 index 0000000..02eb951 --- /dev/null +++ b/Source/Library/Userland/Start.cpp @@ -0,0 +1,8 @@ +#include <types.h> + +int main(); + +extern "C" void start() { + u32int r = main(); + asm volatile("int $66" : : "a"(r)); +} diff --git a/Source/Library/Userland/Syscall/RessourceCaller.class.cpp b/Source/Library/Userland/Syscall/RessourceCaller.class.cpp new file mode 100644 index 0000000..2d7b6ba --- /dev/null +++ b/Source/Library/Userland/Syscall/RessourceCaller.class.cpp @@ -0,0 +1,18 @@ +#include "RessourceCaller.class.h" + +RessourceCaller::RessourceCaller(u32int id, u32int type) { + m_id = id; + m_type = 1; + m_type = doCall(0); + if (m_type != type) m_type = 0; +} + +u32int RessourceCaller::getObjId(u32int type) { + return syscall(0xFFFFFE00, type); +} + +u32int RessourceCaller::doCall(u8int call, u32int a, u32int b, u32int c, u32int d, u32int e) { + if (m_type == 0) return (u32int) - 1; //Type 0 = invalid object + u32int x = ((m_id << 8) | call); + return syscall(x, a, b, c, d, e); +} diff --git a/Source/Library/Userland/Syscall/RessourceCaller.class.h b/Source/Library/Userland/Syscall/RessourceCaller.class.h new file mode 100644 index 0000000..3ad8900 --- /dev/null +++ b/Source/Library/Userland/Syscall/RessourceCaller.class.h @@ -0,0 +1,22 @@ +#ifndef DEF_RESSOURCECALLER_CLASS_H +#define DEF_RESSOURCECALLER_CLASS_H + +#include <Syscall/Syscall.wtf.h> + +class RessourceCaller { + private: + u32int m_id; + u32int m_type; + + protected: + RessourceCaller(u32int id, u32int type); + static u32int getObjId(u32int type); + u32int doCall(u8int call, u32int a = 0, u32int b = 0, u32int c = 0, u32int d = 0, u32int e = 0); + + public: + u32int resId() { return m_id; } + u32int resType() { return m_type; } + bool valid() { return m_type != 0; } +}; + +#endif diff --git a/Source/Library/Userland/Syscall/Syscall.wtf.cpp b/Source/Library/Userland/Syscall/Syscall.wtf.cpp index 2c03b20..a28c202 100644 --- a/Source/Library/Userland/Syscall/Syscall.wtf.cpp +++ b/Source/Library/Userland/Syscall/Syscall.wtf.cpp @@ -1,20 +1,21 @@ #include "Syscall.wtf.h" -int main(); - -unsigned int syscall(unsigned int n, unsigned int a, unsigned int b, unsigned int c) { - unsigned int r; +u32int syscall(u32int n, u32int a, u32int b, u32int c, u32int d, u32int e) { + u32int r; asm volatile ("int $64;" - : "=a"(r) : "a"(n), "b"(a), "c"(b), "d"(c)); + : "=a"(r) : "a"(n), "b"(a), "c"(b), "d"(c), "D"(d), "S"(e)); return r; } -extern "C" void start() { - unsigned int r = main(); - asm volatile("int $66" : : "a"(r)); -} - void putch(char c) { - unsigned int x = c; + u32int x = c; syscall(0xFFFFFF01, x); } + +void sleep(u32int t) { + syscall(0xFFFFFF02, t); +} + +void write_hex(u32int n) { + syscall(0XFFFFFF03, n); +} diff --git a/Source/Library/Userland/Syscall/Syscall.wtf.h b/Source/Library/Userland/Syscall/Syscall.wtf.h index b220d14..0401a89 100644 --- a/Source/Library/Userland/Syscall/Syscall.wtf.h +++ b/Source/Library/Userland/Syscall/Syscall.wtf.h @@ -3,7 +3,11 @@ #include <types.h> +//Three basic syscalls, just for testing void putch(char); -unsigned int syscall(unsigned int n, unsigned int a, unsigned int b = 0, unsigned int c = 0); +void sleep(u32int); +void write_hex(u32int); + +u32int syscall(u32int n, u32int a, u32int b = 0, u32int c = 0, u32int d = 0, u32int e = 0); #endif diff --git a/Source/Library/Userland/VirtualTerminal.class.h b/Source/Library/Userland/VirtualTerminal.class.h new file mode 100644 index 0000000..a7bb4c2 --- /dev/null +++ b/Source/Library/Userland/VirtualTerminal.class.h @@ -0,0 +1,22 @@ +#include <Syscall/RessourceCaller.class.h> + +#include <VirtualTerminal.iface.h> + +#include <WChar.class.h> + +class VirtualTerminal : public RessourceCaller { + public: + static VirtualTerminal get() { + u32int id = RessourceCaller::getObjId(VT_IFACE_OBJTYPE); + return VirtualTerminal(id); + } + VirtualTerminal(u32int id) : RessourceCaller(id, VT_IFACE_OBJTYPE) {} + + void writeHex(u32int number) { + doCall(VT_IFACE_WRITEHEX, number); + } + + void put(WChar c) { + doCall(VT_IFACE_PUT, c); + } +}; |