88 lines
No EOL
1.8 KiB
C
Executable file
88 lines
No EOL
1.8 KiB
C
Executable file
#include "userprog/syscall.h"
|
|
#include <stdio.h>
|
|
#include <syscall-nr.h>
|
|
#include "threads/interrupt.h"
|
|
#include "threads/thread.h"
|
|
#include <string.h>
|
|
#include "userprog/process.h"
|
|
#include "threads/vaddr.h"
|
|
#include "userprog/pagedir.h"
|
|
|
|
typedef int (*handler) (uint32_t, uint32_t, uint32_t);
|
|
static handler syscall_vec[128];
|
|
|
|
static int sys_write (int fd, const void *buffer, unsigned length);
|
|
static int sys_exit (int status);
|
|
static int sys_wait (tid_t tid);
|
|
static tid_t sys_exec (const char* file_name);
|
|
static void syscall_nop(void);
|
|
|
|
static void syscall_handler (struct intr_frame *);
|
|
|
|
void
|
|
syscall_init (void)
|
|
{
|
|
intr_register_int (0x30, 3, INTR_ON, syscall_handler, "syscall");
|
|
printf("syscall\n");
|
|
memset(syscall_vec, (int)&syscall_nop, 128);
|
|
syscall_vec[SYS_EXIT] = (handler)sys_exit;
|
|
syscall_vec[SYS_WAIT] = (handler)sys_wait;
|
|
syscall_vec[SYS_EXEC] = (handler)sys_exec;
|
|
syscall_vec[SYS_WRITE] = (handler)sys_write;
|
|
}
|
|
|
|
static void
|
|
syscall_nop(void) {
|
|
printf("Syscall not implemented");
|
|
}
|
|
|
|
static void
|
|
syscall_handler (struct intr_frame *f)
|
|
{
|
|
handler h;
|
|
int *p;
|
|
int ret;
|
|
|
|
p = f->esp;
|
|
h = syscall_vec[*p];
|
|
ret = h (*(p + 1), *(p + 2), *(p + 3));
|
|
|
|
f->eax = ret;
|
|
}
|
|
|
|
static int
|
|
sys_write (int fd, const void *buffer, unsigned length) {
|
|
if (fd == 1) { // if stdout
|
|
putbuf (buffer, length);
|
|
return length;
|
|
} else {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
int
|
|
sys_exit (int status)
|
|
{
|
|
struct thread* t = thread_current();
|
|
printf("%s: exit(%d)\n", t->name, status);
|
|
t->exit_status = status;
|
|
thread_exit ();
|
|
return -1;
|
|
}
|
|
|
|
int
|
|
sys_wait (tid_t tid)
|
|
{
|
|
printf("system call wait\n");
|
|
return process_wait(tid);
|
|
}
|
|
|
|
tid_t
|
|
sys_exec (const char* file_name) {
|
|
if (file_name == NULL || is_kernel_vaddr(file_name) ||
|
|
pagedir_get_page(thread_current()->pagedir, file_name) == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
return process_execute(file_name);
|
|
} |