263 lines
6.5 KiB
C
263 lines
6.5 KiB
C
#include "schedule.h"
|
|
#include "syscalls.h"
|
|
#include "interrupts.h"
|
|
#include "vfs.h"
|
|
#include "gui.h"
|
|
#include "rtc.h"
|
|
#include "execve.h"
|
|
#include "memory.h"
|
|
#include "ether.h"
|
|
#include "socket.h"
|
|
|
|
extern struct task_t *current_task;
|
|
|
|
struct window_req_t {
|
|
int x;
|
|
int y;
|
|
char name[128];
|
|
int width;
|
|
int height;
|
|
unsigned int flags;
|
|
char *icon;
|
|
};
|
|
|
|
struct window_blit_req_t {
|
|
int wh;
|
|
int x;
|
|
int y;
|
|
int w;
|
|
int h;
|
|
char *bmp;
|
|
};
|
|
|
|
struct socket_rcv_t {
|
|
char *buffer;
|
|
int len;
|
|
unsigned int *addr;
|
|
};
|
|
|
|
void sys_exit(struct regs *r) {
|
|
unsigned int *status;
|
|
unsigned int *wait_return;
|
|
unsigned int *u;
|
|
int i;
|
|
|
|
current_task->timetorun = 0;
|
|
current_task->state = TASK_ZOMBIE;
|
|
current_task->exit_status = r->ebx;
|
|
current_task->zombie_ttl = 5;
|
|
|
|
if (current_task->parent_task != (void *)0) {
|
|
if (current_task->parent_task->state == TASK_WAITING) {
|
|
|
|
wait_return = (unsigned int *)(current_task->parent_task->esp + 44);
|
|
status = (unsigned int *)(current_task->parent_task->esp + 32);
|
|
|
|
*wait_return = current_task->pid;
|
|
*status = current_task->exit_status;
|
|
current_task->parent_task->state = TASK_RUNNING;
|
|
current_task->state = TASK_FINISHED;
|
|
}
|
|
}
|
|
schedule(r);
|
|
}
|
|
|
|
int sys_fork(struct regs *r) {
|
|
struct task_t *new_task = sched_new_task();
|
|
|
|
unsigned int *stack_setup = (unsigned int *)new_task->esp;
|
|
|
|
*--stack_setup = r->ss;
|
|
*--stack_setup = r->useresp;
|
|
*--stack_setup = r->eflags;
|
|
*--stack_setup = r->cs;
|
|
*--stack_setup = r->eip;
|
|
|
|
*--stack_setup = 0;
|
|
*--stack_setup = 0;
|
|
|
|
*--stack_setup = 0; //EAX
|
|
*--stack_setup = r->ecx; //ECX
|
|
*--stack_setup = r->edx; //EDX
|
|
*--stack_setup = r->ebx; //EBX
|
|
*--stack_setup = 0; //Just an offset, no value
|
|
*--stack_setup = r->ebp; //EBP
|
|
*--stack_setup = r->esi; //ESI
|
|
*--stack_setup = r->edi; //EDI
|
|
|
|
*--stack_setup = r->ds; //DS
|
|
*--stack_setup = r->es; //ES
|
|
*--stack_setup = r->fs; //FS
|
|
*--stack_setup = r->gs; //GS
|
|
|
|
new_task->esp = (unsigned int)stack_setup;
|
|
|
|
new_task->state = TASK_RUNNING;
|
|
|
|
return new_task->pid;
|
|
}
|
|
|
|
void syscall_isr(struct regs *r) {
|
|
|
|
switch (r->eax) {
|
|
case SYS_EXIT:
|
|
sys_exit(r);
|
|
break;
|
|
case SYS_FORK:
|
|
r->eax = sys_fork(r);
|
|
break;
|
|
case SYS_CLOSE:
|
|
vfs_close_file(r->ebx);
|
|
break;
|
|
case SYS_GETPID:
|
|
r->eax = current_task->pid;
|
|
break;
|
|
case SYS_READ:
|
|
r->eax = vfs_read_file((int)r->ebx, (char *)r->ecx, (int) r->edx);
|
|
break;
|
|
case SYS_OPEN:
|
|
r->eax = vfs_open_file((char *)r->ebx, (int)r->ecx, (int)r->edx);
|
|
break;
|
|
case SYS_WRITE:
|
|
r->eax = vfs_write_file((int)r->ebx, (char *)r->ecx, r->edx);
|
|
break;
|
|
case SYS_ISATTY:
|
|
if (current_task->filehandles[(int)r->ebx].device != (void *)0) {
|
|
r->eax = (current_task->filehandles[(int)r->ebx].device->device == 0 ? 1 : 0);
|
|
} else {
|
|
r->eax = 0;
|
|
}
|
|
break;
|
|
case SYS_SBRK:
|
|
r->eax = mem_usr_sbrk((int)r->ebx);
|
|
break;
|
|
case SYS_LSEEK:
|
|
r->eax = vfs_lseek((int)r->ebx, (unsigned long long)r->ecx, (int)r->edx);
|
|
break;
|
|
case SYS_EXECVE:
|
|
r->eax = execve(r, (char *)r->ebx, (char **)r->ecx, (char **)r->edx);
|
|
break;
|
|
case SYS_SELECTDEV:
|
|
r->eax = vfs_select_device((char *)r->ebx);
|
|
break;
|
|
case SYS_GETDENTS:
|
|
r->eax = vfs_getdents((int)r->ebx, (char *)r->ecx, (int)r->edx);
|
|
break;
|
|
case SYS_STAT:
|
|
r->eax = vfs_stat((char *)r->ebx, (struct stat*)r->ecx);
|
|
break;
|
|
case SYS_FSTAT:
|
|
r->eax = vfs_fstat((int)r->ebx, (struct stat *)r->ecx);
|
|
break;
|
|
case SYS_UNLINK:
|
|
r->eax = vfs_unlink((char *)r->ebx);
|
|
break;
|
|
case SYS_WAIT:
|
|
wait(r);
|
|
break;
|
|
case SYS_GETTIME:
|
|
r->eax = rtc_get_time();
|
|
break;
|
|
case SYS_MKDIR:
|
|
r->eax = vfs_mkdir((char *)r->ebx);
|
|
break;
|
|
case SYS_CHDIR:
|
|
r->eax = vfs_change_directory((char *)r->ebx);
|
|
break;
|
|
case SYS_WINDOW_REQ:
|
|
{
|
|
struct window_req_t *req = (struct window_req_t *)r->ebx;
|
|
r->eax = gui_add_window((void *)0, req->name, req->x, req->y, req->width, req->height, req->icon, req->flags, (void *)0);
|
|
}
|
|
break;
|
|
case SYS_WINDOW_BLIT:
|
|
{
|
|
struct window_blit_req_t *req = (struct window_blit_req_t *)r->ebx;
|
|
r->eax = gui_blit(req->wh, req->x, req->y, req->w, req->h, req->bmp);
|
|
}
|
|
break;
|
|
case SYS_WINDOW_INPUT:
|
|
{
|
|
struct window_update_req *req = (struct window_update_req *)r->ecx;
|
|
r->eax = gui_req_input((int)r->ebx, req);
|
|
}
|
|
break;
|
|
case SYS_WINDOW_WALLPAPER:
|
|
{
|
|
r->eax = gui_set_wallpaper((char *)r->ecx, (int)r->ebx);
|
|
}
|
|
break;
|
|
case SYS_WINDOW_DESTROY:
|
|
gui_destroy_window((int)r->ebx, current_task);
|
|
break;
|
|
case SYS_YIELD:
|
|
yield(r);
|
|
break;
|
|
case SYS_SEM_NEW:
|
|
sched_sem_new((unsigned char)r->ebx);
|
|
break;
|
|
case SYS_SEM_FREE:
|
|
sched_sem_free((unsigned int)r->ebx);
|
|
break;
|
|
case SYS_SEM_SIG:
|
|
sched_sem_signal((unsigned int)r->ebx, (unsigned char)r->ecx);
|
|
break;
|
|
case SYS_SEM_WAIT:
|
|
sched_sem_wait(r, (unsigned int)r->ebx, (int)r->ecx);
|
|
break;
|
|
case SYS_ETHER_UP:
|
|
r->eax = ether_enable((int)r->ebx, (unsigned int)r->ecx, (unsigned int)r->edx);
|
|
break;
|
|
case SYS_ETHER_DFGW:
|
|
r->eax = ether_add_default_gw((int)r->ebx, (unsigned int)r->ecx);
|
|
break;
|
|
case SYS_SOCK_OPEN:
|
|
r->eax = (unsigned int)socket_open((unsigned char)r->ebx);
|
|
break;
|
|
case SYS_SOCK_CONNECT:
|
|
r->eax = (unsigned int)socket_connect((struct socket_t *)r->ebx, (unsigned int)r->ecx, (unsigned short)r->edx);
|
|
break;
|
|
case SYS_SOCK_STATUS:
|
|
r->eax = socket_status((struct socket_t *)r->ebx);
|
|
break;
|
|
case SYS_SOCK_CLOSE:
|
|
socket_close((struct socket_t *)r->ebx);
|
|
break;
|
|
case SYS_SOCK_READ:
|
|
r->eax = socket_read((struct socket_t *)r->ebx, (char *)r->ecx, r->edx);
|
|
break;
|
|
case SYS_SOCK_WRITE:
|
|
r->eax = socket_write((struct socket_t*)r->ebx, (unsigned char*)r->ecx, r->edx);
|
|
break;
|
|
case SYS_SOCK_LISTEN:
|
|
r->eax = socket_listen((struct socket_t *)r->ebx, (unsigned int)r->ecx, (unsigned short)r->edx);
|
|
break;
|
|
case SYS_SOCK_ACCEPT:
|
|
r->eax = (unsigned int)socket_accept((struct socket_t *)r->ebx, (struct inet_addr *)r->ecx);
|
|
break;
|
|
case SYS_MEM_INFO:
|
|
r->eax = mem_get_info((struct mem_info *)r->ebx);
|
|
break;
|
|
case SYS_PIPE:
|
|
r->eax = vfs_pipe((int *)r->ebx);
|
|
break;
|
|
case SYS_DUP:
|
|
r->eax = vfs_dup((int)r->ebx);
|
|
break;
|
|
case SYS_SOCK_BIND:
|
|
r->eax = (unsigned int)socket_bind((struct socket_t *)r->ebx, (unsigned int)r->ecx, (unsigned short)r->edx);
|
|
break;
|
|
case SYS_SOCK_RECV_FROM:
|
|
{
|
|
struct socket_rcv_t *srecv = (struct socket_recv_t *)r->ecx;
|
|
r->eax = (unsigned int)socket_recv_from((struct socket_t *)r->ebx, srecv->buffer, srecv->len, srecv->addr);
|
|
}
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
void init_syscalls() {
|
|
irq_install_handler(0x10, syscall_isr, 0);
|
|
}
|