diff --git a/Makefile.build b/Makefile.build index 823d5af3f240461c01f294d8907cfee38a496ac4..0810c23211f18d2e5061f89b0ae00b483078f7bd 100644 --- a/Makefile.build +++ b/Makefile.build @@ -62,6 +62,10 @@ userprog_SRC += userprog/exception.c # User exception handler. userprog_SRC += userprog/syscall.c # System call handler. userprog_SRC += userprog/gdt.c # GDT initialization. userprog_SRC += userprog/tss.c # TSS management. +userprog_SRC += userprog/syscall_exec.c +userprog_SRC += userprog/syscall_exit.c +userprog_SRC += userprog/syscall_halt.c +userprog_SRC += userprog/syscall_wait.c # No virtual memory code yet. #vm_SRC = vm/file.c # Some file. diff --git a/userprog/syscall.c b/userprog/syscall.c index 04635159d30520fa11296dc922e622f2ad2553d5..210d7a8f536d405afada6e553ce469d5647a2a0e 100644 --- a/userprog/syscall.c +++ b/userprog/syscall.c @@ -1,9 +1,40 @@ #include "userprog/syscall.h" #include <stdio.h> #include <syscall-nr.h> +#include "system_calls.h" #include "threads/interrupt.h" #include "threads/thread.h" + +/* System call numbers. */ +typedef enum syscall_t { + /* Projects 2 and later. */ + SYSCALL_HALT, /* Halt the operating system. */ + SYSCALL_EXIT, /* Terminate this process. */ + SYSCALL_EXEC, /* Start another process. */ + SYSCALL_WAIT, /* Wait for a child process to die. */ + SYSCALL_CREATE, /* Create a file. */ + SYSCALL_REMOVE, /* Delete a file. */ + SYSCALL_OPEN, /* Open a file. */ + SYSCALL_FILESIZE, /* Obtain a file's size. */ + SYSCALL_READ, /* Read from a file. */ + SYSCALL_WRITE, /* Write to a file. */ + SYSCALL_SEEK, /* Change position in a file. */ + SYSCALL_TELL, /* Report current position in a file. */ + SYSCALL_CLOSE, /* Close a file. */ + + /* Project 3 and optionally project 4. */ + SYSCALL_MMAP, /* Map a file into memory. */ + SYSCALL_MUNMAP, /* Remove a memory mapping. */ + + /* Project 4 only. */ + SYSCALL_CHDIR, /* Change the current directory. */ + SYSCALL_MKDIR, /* Create a directory. */ + SYSCALL_READDIR, /* Reads a directory entry. */ + SYSCALL_ISDIR, /* Tests if a fd represents a directory. */ + SYSCALL_INUMBER /* Returns the inode number for a fd. */ +} syscall_t; + static void syscall_handler (struct intr_frame *); void @@ -16,6 +47,29 @@ syscall_init (void) static void syscall_handler (struct intr_frame *f UNUSED) { - printf ("system call!\n"); + /* + * the syscall number is addressed by f->esp (pointer to void) + * here we cast it to a pointer to int and then dereference that + * to get the system call number + * --Joshua Saxby + */ + int syscall_number = *((int*)f->esp); + switch (syscall_number) { + case SYSCALL_HALT: + syscall_halt(f); + break; + case SYSCALL_EXIT: + syscall_exit(f); + break; + case SYSCALL_EXEC: + syscall_exec(f); + break; + case SYSCALL_WAIT: + syscall_exec(f); + break; + default: + printf ("WARNING: Invalid Syscall (%d)\n", syscall_number); + } + // TODO: remove this call to exit as we don't want all syscalls to make the thread exit thread_exit (); } diff --git a/userprog/syscall_exec.c b/userprog/syscall_exec.c new file mode 100644 index 0000000000000000000000000000000000000000..94a060b3f85b35ac063246e0d76f040517bb0f4f --- /dev/null +++ b/userprog/syscall_exec.c @@ -0,0 +1,6 @@ +#include "system_calls.h" +#include "threads/interrupt.h" + +void syscall_exec(struct intr_frame *f) { + (void*)0; +} \ No newline at end of file diff --git a/userprog/syscall_exit.c b/userprog/syscall_exit.c new file mode 100644 index 0000000000000000000000000000000000000000..07d917f5c66b91671f7c834b42a4be96aec40bd2 --- /dev/null +++ b/userprog/syscall_exit.c @@ -0,0 +1,6 @@ +#include "system_calls.h" +#include "threads/interrupt.h" + +void syscall_exit(struct intr_frame *f) { + (void*)0; +} diff --git a/userprog/syscall_halt.c b/userprog/syscall_halt.c new file mode 100644 index 0000000000000000000000000000000000000000..1c3607681df736f94eb15186f651d1123ec31b69 --- /dev/null +++ b/userprog/syscall_halt.c @@ -0,0 +1,6 @@ +#include "system_calls.h" +#include "threads/interrupt.h" + +void syscall_halt(struct intr_frame *f) { + (void*)0; +} \ No newline at end of file diff --git a/userprog/syscall_wait.c b/userprog/syscall_wait.c new file mode 100644 index 0000000000000000000000000000000000000000..6ef4d52385c5be4ccd7352d681e289ad8acdc9e7 --- /dev/null +++ b/userprog/syscall_wait.c @@ -0,0 +1,6 @@ +#include "system_calls.h" +#include "threads/interrupt.h" + +void syscall_wait(struct intr_frame *f) { + (void*)0; +} \ No newline at end of file diff --git a/userprog/system_calls.h b/userprog/system_calls.h new file mode 100644 index 0000000000000000000000000000000000000000..5d0727352769f8cdeec4775eef41c6d893f16045 --- /dev/null +++ b/userprog/system_calls.h @@ -0,0 +1,35 @@ +#include "threads/interrupt.h" + +/* + * Terminates Pintos by calling shutdown_power_off() + * (declared in threads/init.h). + */ +void syscall_halt(struct intr_frame *f); + +/* + * Terminates the current user program, returning status to the kernel. If the + * process's parent waits for it (see below), this is the status that will be + * returned. Conventionally, a status of 0 indicates success and nonzero + * values indicate errors. + */ +void syscall_exit(struct intr_frame *f); + +/* + * Runs the executable whose name is given in cmd_line, passing any given + * arguments, and returns the new process's program id (pid). Must return pid + * -1, which otherwise should not be a valid pid, if the program cannot load or + * run for any reason. Thus, the parent process cannot return from the exec + * until it knows whether the child process successfully loaded its executable. + * You must use appropriate synchronization to ensure this. + */ +void syscall_exec(struct intr_frame *f); + +/* + * Waits for a child process pid and retrieves the child's exit status. + */ +void syscall_wait(struct intr_frame *f); + +/* + * NOTE: There are more system calls implemented by Pintos but we are not + * implementing them because the assignment brief does not ask of it. + */ \ No newline at end of file