From 89c3f3c8f908957a0a878e60535772880ba81d91 Mon Sep 17 00:00:00 2001
From: Joshua Saxby <Joshua2.Saxby@live.uwe.ac.uk>
Date: Mon, 2 Dec 2019 17:51:39 +0000
Subject: [PATCH] Add skeleton of syscall handling implementation

---
 Makefile.build          |  4 +++
 userprog/syscall.c      | 56 ++++++++++++++++++++++++++++++++++++++++-
 userprog/syscall_exec.c |  6 +++++
 userprog/syscall_exit.c |  6 +++++
 userprog/syscall_halt.c |  6 +++++
 userprog/syscall_wait.c |  6 +++++
 userprog/system_calls.h | 35 ++++++++++++++++++++++++++
 7 files changed, 118 insertions(+), 1 deletion(-)
 create mode 100644 userprog/syscall_exec.c
 create mode 100644 userprog/syscall_exit.c
 create mode 100644 userprog/syscall_halt.c
 create mode 100644 userprog/syscall_wait.c
 create mode 100644 userprog/system_calls.h

diff --git a/Makefile.build b/Makefile.build
index 823d5af..0810c23 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 0463515..210d7a8 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 0000000..94a060b
--- /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 0000000..07d917f
--- /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 0000000..1c36076
--- /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 0000000..6ef4d52
--- /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 0000000..5d07273
--- /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
-- 
GitLab