POK(kernelpart)
/home/jaouen/pok_official/pok/trunk/kernel/arch/x86/syscalls.c
Go to the documentation of this file.
00001 /*
00002  *                               POK header
00003  * 
00004  * The following file is a part of the POK project. Any modification should
00005  * made according to the POK licence. You CANNOT use this file or a part of
00006  * this file is this part of a file for your own project
00007  *
00008  * For more information on the POK licence, please see our LICENCE FILE
00009  *
00010  * Please follow the coding guidelines described in doc/CODING_GUIDELINES
00011  *
00012  *                                      Copyright (c) 2007-2009 POK team 
00013  *
00014  * Created by julien on Thu Jan 15 23:34:13 2009 
00015  */
00016 
00025 #include <errno.h>
00026 #include <core/debug.h>
00027 #include <core/partition.h>
00028 #include <core/syscall.h>
00029 
00030 #include "gdt.h"
00031 #include "event.h"
00032 
00033 #define PARTITION_ID(cs) (((cs >> 3) - 4) / 2)
00034 
00035 INTERRUPT_HANDLER_syscall(syscall_gate)
00036 {
00037    pok_syscall_info_t   syscall_info;
00038    pok_ret_t            syscall_ret;
00039    pok_syscall_args_t*  syscall_args;
00040    pok_syscall_id_t     syscall_id;
00041 
00042    /*
00043     * Give informations about syscalls: which partition, thread
00044     * initiates the syscall, the base addr of the partition and so on.
00045     */
00046    syscall_info.partition = PARTITION_ID (frame->cs);
00047    syscall_info.base_addr = pok_partitions[syscall_info.partition].base_addr;
00048    syscall_info.thread    = POK_SCHED_CURRENT_THREAD;
00049 
00050    syscall_args = (pok_syscall_args_t*) (frame->ebx + syscall_info.base_addr);
00051 
00052    /*
00053     * Get the syscall id in the eax register
00054     */
00055    syscall_id = (pok_syscall_id_t) frame->eax;
00056 
00057    /*
00058     * Check that pointer is inside the adress space
00059     */
00060    if (POK_CHECK_PTR_IN_PARTITION(syscall_info.partition, syscall_args) == 0)
00061    {
00062          syscall_ret = POK_ERRNO_EINVAL;
00063    }
00064    else
00065    {
00066       /*
00067        * Perform the syscall baby !
00068        */
00069       syscall_ret = pok_core_syscall (syscall_id, syscall_args, &syscall_info);
00070    }
00071 
00072    /*
00073     * And finally, put the return value in eax register
00074     */
00075    asm ("movl %0, %%eax  \n"
00076         :
00077         : "m" (syscall_ret));
00078 }
00079 
00083 pok_ret_t pok_syscall_init ()
00084 {
00085    pok_idt_set_gate (POK_SYSCALL_INT_NUMBER,
00086                      GDT_CORE_CODE_SEGMENT << 3,
00087                      (uint32_t) syscall_gate,
00088                      IDTE_INTERRUPT,
00089                      3);
00090 
00091    return (POK_ERRNO_OK);
00092 }
00093