cynix

x86 UNIX-like OS
git clone git://git.2f30.org/cynix
Log | Files | Refs | README | LICENSE

syscall.c (7316B)


      1 /*
      2  *  core/syscall.c
      3  *
      4  *  Copyright (C) 2009 stateless
      5  */
      6 
      7 #include <syscall.h>
      8 #include <string.h>
      9 #include <x86.h>
     10 #include <common.h>
     11 #include <tss.h>
     12 #include <serial.h>
     13 #include <rtc.h>
     14 #include <mm.h>
     15 #include <tty.h>
     16 #include <errno.h>
     17 #include <pipe.h>
     18 
     19 extern int f_kdb;
     20 
     21 static void __sys_write(struct trapframe_t *regs);
     22 static void __sys_read(struct trapframe_t *regs);
     23 static void __sys_exit(struct trapframe_t *regs);
     24 static void __sys_fork(struct trapframe_t *regs);
     25 static void __sys_waitpid(struct trapframe_t *regs);
     26 static void __sys_reschedule(struct trapframe_t *regs);
     27 static void __sys_open(struct trapframe_t *regs);
     28 static void __sys_close(struct trapframe_t *regs);
     29 static void __sys_creat(struct trapframe_t *regs);
     30 static void __sys_execve(struct trapframe_t *regs);
     31 static void __sys_isatty(struct trapframe_t *regs);
     32 static void __sys_getpid(struct trapframe_t *regs);
     33 static void __sys_getppid(struct trapframe_t *regs);
     34 static void __sys_readdir(struct trapframe_t *regs);
     35 static void __sys_dup(struct trapframe_t *regs);
     36 static void __sys_dup2(struct trapframe_t *regs);
     37 static void __sys_stat(struct trapframe_t *regs);
     38 static void __sys_fstat(struct trapframe_t *regs);
     39 static void __sys_seeder(struct trapframe_t *regs);
     40 static void __sys_sbrk(struct trapframe_t *regs);
     41 static void __sys_getuid(struct trapframe_t *regs);
     42 static void __sys_setuid(struct trapframe_t *regs);
     43 static void __sys_getgid(struct trapframe_t *regs);
     44 static void __sys_setgid(struct trapframe_t *regs);
     45 static void __sys_suspend_task(struct trapframe_t *regs);
     46 static void __sys_resume_task(struct trapframe_t *regs);
     47 static void __sys_pipe(struct trapframe_t *regs);
     48 
     49 static void *syscall_table[SYSCALL_NR] = {
     50 	[__NR_exit] = &__sys_exit,
     51 	[__NR_fork] = &__sys_fork,
     52 	[__NR_read] = &__sys_read,
     53 	[__NR_write] = &__sys_write,
     54 	[__NR_waitpid] = &__sys_waitpid,
     55 	[__NR_reschedule] = &__sys_reschedule,
     56 	[__NR_open] = &__sys_open,
     57 	[__NR_close] = &__sys_close,
     58 	[__NR_creat] = &__sys_creat,
     59 	[__NR_execve] = &__sys_execve,
     60 	[__NR_isatty] = &__sys_isatty,
     61 	[__NR_getpid] = &__sys_getpid,
     62 	[__NR_getppid] = &__sys_getppid,
     63 	[__NR_readdir] = &__sys_readdir,
     64 	[__NR_dup] = &__sys_dup,
     65 	[__NR_dup2] = &__sys_dup2,
     66 	[__NR_stat] = &__sys_stat,
     67 	[__NR_fstat] = &__sys_fstat,
     68 	[__NR_seeder] = &__sys_seeder,
     69 	[__NR_sbrk] = &__sys_sbrk,
     70 	[__NR_getuid] = &__sys_getuid,
     71 	[__NR_setuid] = &__sys_setuid,
     72 	[__NR_getgid] = &__sys_getgid,
     73 	[__NR_setgid] = &__sys_setgid,
     74 	[__NR_suspend_task] = &__sys_suspend_task,
     75 	[__NR_resume_task] = &__sys_resume_task,
     76 	[__NR_pipe] = &__sys_pipe
     77 };
     78 
     79 #ifdef BSYSCALL_TRACE
     80 static const char *syscall_names[SYSCALL_NR] = {
     81 	[__NR_exit] = "sys_exit",
     82 	[__NR_fork] = "sys_fork",
     83 	[__NR_read] = "sys_read",
     84 	[__NR_write] = "sys_write",
     85 	[__NR_waitpid] = "sys_waitpid",
     86 	[__NR_reschedule] = "sys_reschedule",
     87 	[__NR_open] = "sys_open",
     88 	[__NR_close] = "sys_close",
     89 	[__NR_creat] = "sys_creat",
     90 	[__NR_execve] = "sys_execve",
     91 	[__NR_isatty] = "sys_isatty",
     92 	[__NR_getpid] = "sys_getpid",
     93 	[__NR_getppid] = "sys_getppid",
     94 	[__NR_readdir] = "sys_readdir",
     95 	[__NR_dup] = "sys_dup",
     96 	[__NR_dup2] = "sys_dup2",
     97 	[__NR_stat] = "sys_stat",
     98 	[__NR_fstat] = "sys_fstat",
     99 	[__NR_seeder] = "sys_seeder",
    100 	[__NR_sbrk] = "sys_sbrk",
    101 	[__NR_getuid] = "sys_getuid",
    102 	[__NR_setuid] = "sys_setuid",
    103 	[__NR_getgid] = "sys_getgid",
    104 	[__NR_setgid] = "sys_setgid",
    105 	[__NR_suspend_task] = "sys_suspend_task",
    106 	[__NR_resume_task] = "sys_resume_task",
    107 	[__NR_pipe] = "sys_pipe"
    108 };
    109 #endif
    110 
    111 static void
    112 __sys_write(struct trapframe_t *regs)
    113 {
    114 	regs->eax = (uint32_t)write((int)regs->ebx, (const void *)regs->ecx, (size_t)regs->edx);
    115 }
    116 
    117 static void
    118 __sys_read(struct trapframe_t *regs)
    119 {
    120 	regs->eax = (uint32_t)read((int)regs->ebx, (void *)regs->ecx, (size_t)regs->edx);
    121 }
    122 
    123 static void
    124 __sys_exit(struct trapframe_t *regs)
    125 {
    126 	if (!strcmp(curr_proc->name, "kdb")) {
    127 		unfreeze_tasks();
    128 		f_kdb = 0;
    129 	}
    130 	curr_proc->state = TASK_ZOMBIE;
    131 	curr_proc->status = (int)regs->ebx;
    132 	attach_tty(curr_proc->parent);
    133 	tty_resume();
    134 	closefds();
    135 	remove_proc_mappings();
    136 	schedule();
    137 }
    138 
    139 static void
    140 __sys_fork(struct trapframe_t *regs)
    141 {
    142 	regs->eax = (uint32_t)fork();
    143 }
    144 
    145 static void
    146 __sys_waitpid(struct trapframe_t *regs)
    147 {
    148 	regs->eax = (uint32_t)waitpid((pid_t)regs->ebx, (int *)regs->ecx, (int)regs->edx);
    149 }
    150 
    151 static void
    152 __sys_reschedule(__attribute__ ((unused)) struct trapframe_t *regs)
    153 {
    154 	schedule();
    155 }
    156 
    157 static void
    158 __sys_open(struct trapframe_t *regs)
    159 {
    160 	regs->eax = (uint32_t)open((const char *)regs->ebx, (int)regs->ecx, (mode_t)regs->edx);
    161 }
    162 
    163 static void
    164 __sys_close(struct trapframe_t *regs)
    165 {
    166 	regs->eax = (uint32_t)close((int)regs->ebx);
    167 }
    168 
    169 static void
    170 __sys_creat(struct trapframe_t *regs)
    171 {
    172 	regs->eax = (int)creat((const char *)regs->ebx, (mode_t)regs->ecx);
    173 }
    174 
    175 static void
    176 __sys_execve(__attribute__ ((unused)) struct trapframe_t *regs)
    177 {
    178 	regs->eax = execve((const char *)regs->ebx, 0, 0); /* FIXME */
    179 }
    180 
    181 static void
    182 __sys_isatty(struct trapframe_t *regs)
    183 {
    184 	regs->eax = 1;
    185 }
    186 
    187 static void
    188 __sys_getpid(struct trapframe_t *regs)
    189 {
    190 	regs->eax = (uint32_t)curr_proc->pid;
    191 }
    192 
    193 static void
    194 __sys_getppid(struct trapframe_t *regs)
    195 {
    196 	regs->eax = (!curr_proc->parent) ? 0 : (uint32_t)curr_proc->parent->pid;
    197 }
    198 
    199 static void
    200 __sys_readdir(struct trapframe_t *regs)
    201 {
    202 	/* I will probably need to change the prototype of readdir to not depend on DIR */
    203 	regs->eax = (uint32_t)readdir((DIR *)regs->ebx);
    204 }
    205 
    206 static void
    207 __sys_dup(struct trapframe_t *regs)
    208 {
    209 	regs->eax = (uint32_t)dup((int)regs->ebx);
    210 }
    211 
    212 static void
    213 __sys_dup2(struct trapframe_t *regs)
    214 {
    215 	regs->eax = (uint32_t)dup2((int)regs->ebx, (int)regs->ecx);
    216 }
    217 
    218 static void
    219 __sys_stat(struct trapframe_t *regs)
    220 {
    221 	regs->eax = (uint32_t)stat((const char *)regs->ebx, (struct stat *)regs->ecx);
    222 }
    223 
    224 static void
    225 __sys_fstat(struct trapframe_t *regs)
    226 {
    227 	regs->eax = (uint32_t)fstat((int)regs->ebx, (struct stat *)regs->ecx);
    228 }
    229 
    230 static void
    231 __sys_seeder(struct trapframe_t *regs)
    232 {
    233 	regs->eax = systimer ^ (uint32_t)curr_proc;
    234 }
    235 
    236 static void
    237 __sys_sbrk(struct trapframe_t *regs)
    238 {
    239 	regs->eax = (uint32_t)sbrk((intptr_t)regs->ebx);
    240 }
    241 
    242 static void
    243 __sys_getuid(struct trapframe_t *regs)
    244 {
    245 	regs->eax = (uint32_t)getuid();
    246 }
    247 
    248 static void
    249 __sys_setuid(struct trapframe_t *regs)
    250 {
    251 	regs->eax = (uint32_t)setuid((uid_t)regs->ebx);
    252 }
    253 
    254 static void
    255 __sys_getgid(struct trapframe_t *regs)
    256 {
    257 	regs->eax = (uint32_t)getgid();
    258 }
    259 
    260 static void
    261 __sys_setgid(struct trapframe_t *regs)
    262 {
    263 	regs->eax = (uint32_t)setgid((uid_t)regs->ebx);
    264 }
    265 
    266 static void
    267 __sys_suspend_task(struct trapframe_t *regs)
    268 {
    269 	suspend_task((void *)regs->ebx);
    270 }
    271 
    272 static void
    273 __sys_resume_task(struct trapframe_t *regs)
    274 {
    275 	regs->eax = (uint32_t)resume_task((void *)regs->ebx);
    276 }
    277 
    278 static void
    279 __sys_pipe(struct trapframe_t *regs)
    280 {
    281 	regs->eax = (uint32_t)pipe((int *)regs->ebx);
    282 }
    283 
    284 void
    285 syscall_dispatcher(struct trapframe_t *regs)
    286 {
    287 	if (regs->eax > 0 && regs->eax < SYSCALL_NR && syscall_table[regs->eax]) {
    288 		if (curr_proc) {
    289 			TRACE_SYSCALL(serial_dump("tracing[%s with pid %d]: %s [eax = %08lx, ebx = %08lx, ecx = %08lx, edx = %08lx]\n",
    290 						  curr_proc->name, curr_proc->pid, syscall_names[regs->eax],
    291 						  regs->eax, regs->ebx, regs->ecx, regs->edx);)
    292 		}
    293 		void (*fp)(struct trapframe_t * regs) = (void (*)(struct trapframe_t *))syscall_table[regs->eax];
    294 		fp(regs);
    295 	} else {
    296 		regs->eax = -ENOSYS;
    297 	}
    298 }
    299