From 68940415ee0932a68e2c3fb4fe0dc8b711e67d7c Mon Sep 17 00:00:00 2001 From: Alex AUVOLAT Date: Fri, 4 May 2012 21:02:43 +0200 Subject: Preparations. --- doc/syscalls.txt | 34 +++++++++++++++++----------------- src/common/include/sched.h | 15 ++++++++++++--- src/common/include/tce/syscalls.h | 19 +++++++++++++++++++ src/kernel/task/idt.cpp | 8 -------- src/kernel/task/sched.cpp | 2 +- src/kernel/task/syscall.cpp | 34 ++++++++++++++++++++++++---------- src/user/lib/include/tce/syscall.h | 1 + src/user/lib/tce/syscall.c | 22 +++++++++++----------- 8 files changed, 85 insertions(+), 50 deletions(-) create mode 100644 src/common/include/tce/syscalls.h diff --git a/doc/syscalls.txt b/doc/syscalls.txt index c94db19..5df2cf6 100644 --- a/doc/syscalls.txt +++ b/doc/syscalls.txt @@ -1,25 +1,25 @@ -Syscalls pass by int64. The identifier of the called function is in eax, parameters -are in ebx, ecx, edx, esi, edi. +Syscalls pass by int64. The identifier of the called function is in ebx, with +eax = 0, parameters are in ecx, edx, esi, edi. Syscall list : -id=eax Name Parameters Description - 0 thread_exit none Signal kernel that current thread has finished - 1 schedule none Switch to next thread (might be the current one) - 2 thread_sleep ebx: time (int) msecs Tell kernel to put current thread to sleep - 3 process_exit ebx: return value (int) Tell kernel to end current process, cleaning up everything - 4 printk ebx: addr of a string Print a message to screen - 5 thread_new ebx: entry point Creates a new thread - ecx: data pointer - edx: stack pointer - 6 irq_wait ebx: irq number Waits for an IRQ (requires privilege PL_DRIVER) - 7 proc_priv none Returns current process privilege level +id=ebx Name Parameters Description + 1 thread_exit none Signal kernel that current thread has finished + 2 schedule none Switch to next thread (might be the current one) + 3 thread_sleep ecx: time (int) msecs Tell kernel to put current thread to sleep + 4 process_exit ecx: return value (int) Tell kernel to end current process, cleaning up everything + 5 printk ecx: addr of a string Print a message to screen + 6 thread_new ecx: entry point Creates a new thread + edx: data pointer + esi: stack pointer + 7 irq_wait ecx: irq number Waits for an IRQ (requires privilege PL_DRIVER) + 8 proc_priv none Returns current process privilege level - 8 sbrk ebx: size Allocates some memory - 9 brk ebx: new_end Allocates/frees some memory + 9 sbrk ecx: size Allocates some memory + 10 brk ecx: new_end Allocates/frees some memory - 10 mmap (see linux specs) - 11 munmap (see linux specs) + 11 mmap (see linux specs) + 12 munmap (see linux specs) If a processes wishes to exit with an error code, it HAS to use process_exit. thread_exit will do nothing. diff --git a/src/common/include/sched.h b/src/common/include/sched.h index 0f8f8f4..1fe148d 100644 --- a/src/common/include/sched.h +++ b/src/common/include/sched.h @@ -7,9 +7,18 @@ #define MUTEX_UNLOCKED 0 //A mutex is just an uint32_t +typedef uint32_t mutex_t; -int mutex_lock(uint32_t* mutex); //wait for mutex to be free -int mutex_lockE(uint32_t* mutex); //lock mutex only if free, returns !0 if locked, 0 if was busy -void mutex_unlock(uint32_t* mutex); +#ifdef __cplusplus +extern "C" { +#endif + +int mutex_lock(mutex_t* mutex); //wait for mutex to be free +int mutex_lockE(mutex_t* mutex); //lock mutex only if free, returns !0 if locked, 0 if was busy +void mutex_unlock(mutex_t* mutex); + +#ifdef __cplusplus +} +#endif #endif diff --git a/src/common/include/tce/syscalls.h b/src/common/include/tce/syscalls.h new file mode 100644 index 0000000..3b5b68f --- /dev/null +++ b/src/common/include/tce/syscalls.h @@ -0,0 +1,19 @@ +#ifndef DEF_TCE_SYSCALLS_H +#define DEF_TCE_SYSCALLS_H + +#define SC_THREAD_EXIT 1 +#define SC_SCHEDULE 2 +#define SC_THREAD_SLEEP 3 +#define SC_PROCESS_EXIT 4 +#define SC_PRINTK 5 +#define SC_THREAD_NEW 6 +#define SC_IRQ_WAIT 7 +#define SC_PROC_PRIV 8 +#define SC_SBRK 9 +#define SC_BRK 10 + +// NOT YET IMPLEMENTED +#define SC_MMAP 11 +#define SC_MUNMAP 12 + +#endif diff --git a/src/kernel/task/idt.cpp b/src/kernel/task/idt.cpp index 9008083..c09034e 100644 --- a/src/kernel/task/idt.cpp +++ b/src/kernel/task/idt.cpp @@ -109,14 +109,6 @@ extern "C" void idt_irqHandler(registers regs) { if (doSwitch) schedule(); } -/* Called in idt_.asm on a system call (interrupt 64). - Calls the correct syscall handler (if any). */ -extern "C" void idt_syscallHandler(registers regs) { - if (regs.eax < NUMBER_OF_SYSCALLS && syscalls[regs.eax] != 0) { - syscalls[regs.eax](®s); - } -} - /* For internal use only. Sets up an entry of the IDT with given parameters. */ static void idt_setGate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) { idt_entries[num].base_lo = base & 0xFFFF; diff --git a/src/kernel/task/sched.cpp b/src/kernel/task/sched.cpp index e773e97..2629a33 100644 --- a/src/kernel/task/sched.cpp +++ b/src/kernel/task/sched.cpp @@ -3,7 +3,7 @@ #include // Lower priority numbers have high priority. Priorities must start at 0. -#define PRIORITIES 3 // we have 4 priority levels +#define PRIORITIES 3 // we have 3 priority levels #define PRIORITY(t) (t->process->privilege) //get priority for a thread extern thread *idle_thread; diff --git a/src/kernel/task/syscall.cpp b/src/kernel/task/syscall.cpp index 7a83c25..7938e76 100644 --- a/src/kernel/task/syscall.cpp +++ b/src/kernel/task/syscall.cpp @@ -6,16 +6,16 @@ #define CALL0(name, scname) static void scname(registers* r) { r->eax = name(); } #define CALL1(name, scname) static void scname(registers* r) { \ - r->eax = name(r->ebx); } + r->eax = name(r->ecx); } #define CALL2(name, scname) static void scname(registers* r) { \ - r->eax = name(r->ebx, r->ecx); } + r->eax = name(r->ecx, r->edx); } #define CALL3(name, scname) static void scname(registers* r) { \ - r->eax = name(r->ebx, r->ecx, r->edx); } + r->eax = name(r->ecx, r->edx, r->esi); } #define CALL0V(name, scname) static void scname(registers* r) { name(); } -#define CALL1V(name, scname) static void scname(registers* r) { name(r->ebx); } -#define CALL2V(name, scname) static void scname(registers* r) { name(r->ebx, r->ecx); } -#define CALL3V(name, scname) static void scname(registers* r) { name(r->ebx, r->ecx, r->edx); } -#define CALL4V(name, scname) static void scname(registers* r) { name(r->ebx, r->ecx, r->edx, r->esi); } +#define CALL1V(name, scname) static void scname(registers* r) { name(r->ecx); } +#define CALL2V(name, scname) static void scname(registers* r) { name(r->ecx, r->edx); } +#define CALL3V(name, scname) static void scname(registers* r) { name(r->ecx, r->edx, r->esi); } +#define CALL4V(name, scname) static void scname(registers* r) { name(r->ecx, r->edx, r->esi, r->edi); } CALL0V(thread_exit, thread_exit_sc); CALL0V(schedule, schedule_sc); @@ -27,16 +27,17 @@ CALL1(process_sbrk, proc_sbrk_sc); CALL1V(process_brk, proc_brk_sc); static void printk_sc(registers *r) { - monitor_write((char*)r->ebx); + monitor_write((char*)r->ecx); } static void thread_new_sc(registers* r) { cli(); - new thread(current_thread->process, (thread_entry)r->ebx, (void*)r->ecx, (void*)r->edx); + new thread(current_thread->process, (thread_entry)r->ecx, (void*)r->edx, (void*)r->esi); sti(); } -int_callback syscalls[NUMBER_OF_SYSCALLS] = { +int_callback syscalls[NUMBER_OF_SYSCALLS] = { // This must correspond to common/include/tce/syscalls.h + 0, thread_exit_sc, //0 schedule_sc, thread_sleep_sc, @@ -48,3 +49,16 @@ int_callback syscalls[NUMBER_OF_SYSCALLS] = { proc_sbrk_sc, proc_brk_sc, 0 }; + + +/* Called in idt_.asm on a system call (interrupt 64). + Calls the correct syscall handler (if any). */ +extern "C" void idt_syscallHandler(registers regs) { + if (regs.eax == 0) { + if (regs.ebx < NUMBER_OF_SYSCALLS && syscalls[regs.ebx] != 0) { + syscalls[regs.ebx](®s); + } + } else { + monitor_write("Hello. Object calls not implemented.\n"); + } +} diff --git a/src/user/lib/include/tce/syscall.h b/src/user/lib/include/tce/syscall.h index 7cb4381..7bcdd2b 100644 --- a/src/user/lib/include/tce/syscall.h +++ b/src/user/lib/include/tce/syscall.h @@ -2,6 +2,7 @@ #define DEF_SYSCALL_H #include +#include #define NEW_STACK_SIZE 0x8000 diff --git a/src/user/lib/tce/syscall.c b/src/user/lib/tce/syscall.c index f9243b0..d606491 100644 --- a/src/user/lib/tce/syscall.c +++ b/src/user/lib/tce/syscall.c @@ -9,23 +9,23 @@ static size_t call(size_t a, size_t b, size_t c, size_t d, size_t e, size_t f) { } void thread_exit() { - call(0, 0, 0, 0, 0, 0); + call(0, SC_THREAD_EXIT, 0, 0, 0, 0); } void schedule() { - call(1, 0, 0,0, 0, 0); + call(0, SC_SCHEDULE, 0, 0,0, 0); } void thread_sleep(int time) { - call(2, time, 0, 0, 0, 0); + call(0, SC_THREAD_SLEEP, time, 0, 0, 0); } void process_exit(int retval) { - call(3, retval, 0, 0, 0, 0); + call(0, SC_PROCESS_EXIT, retval, 0, 0, 0); } void printk(char* str) { - call(4, (unsigned)str, 0, 0, 0, 0); + call(0, SC_PRINTK, (unsigned)str, 0, 0, 0); } //THREAD CREATION @@ -44,28 +44,28 @@ void thread_start(void *data) { if (_stack_to_free != 0) free(_stack_to_free); _stack_to_free = tsd->stack; asm volatile("movl %0, (_stack_freeing_mutex); int $64;" :: - "a"(0), "r"(MUTEX_UNLOCKED)); + "a"(0), "b"(SC_THREAD_EXIT), "r"(MUTEX_UNLOCKED)); } void thread_new(void (*entry)(void*), void *data) { struct thread_start_data *tsd = malloc(sizeof(struct thread_start_data)); tsd->entry = entry; tsd->data = data; tsd->stack = malloc(NEW_STACK_SIZE); - call(5, (unsigned)thread_start, (unsigned)tsd, (unsigned)(tsd->stack + NEW_STACK_SIZE), 0, 0); + call(0, SC_THREAD_NEW, (unsigned)thread_start, (unsigned)tsd, (unsigned)(tsd->stack + NEW_STACK_SIZE), 0); } void irq_wait(int number) { - call(6, number, 0, 0, 0, 0); + call(0, SC_IRQ_WAIT, number, 0, 0, 0); } int proc_priv() { - return call(7, 0, 0, 0, 0, 0); + return call(0, SC_PROC_PRIV, 0, 0, 0, 0); } void* sbrk(size_t s) { - return (void*)call(8, s, 0, 0, 0, 0); + return (void*)call(0, SC_SBRK, s, 0, 0, 0); } void brk(void* ptr) { - return call (9, ptr, 0, 0, 0, 0); + return call (0, SC_BRK, ptr, 0, 0, 0); } -- cgit v1.2.3