summaryrefslogtreecommitdiffstats
path: root/src/lib/user/syscall.c
diff options
context:
space:
mode:
authorFelipe Boeira <felipe.boeira@liu.se>2019-01-08 18:39:03 +0100
committerFelipe Boeira <felipe.boeira@liu.se>2019-01-08 18:39:03 +0100
commitd4522b8e9854178473adcea0fbb84f23f6e744bd (patch)
treefbcf620617c5023154eba3f965b3a982daa64a47 /src/lib/user/syscall.c
downloadpintos-d4522b8e9854178473adcea0fbb84f23f6e744bd.tar.gz
Initial commit
Diffstat (limited to 'src/lib/user/syscall.c')
-rw-r--r--src/lib/user/syscall.c184
1 files changed, 184 insertions, 0 deletions
diff --git a/src/lib/user/syscall.c b/src/lib/user/syscall.c
new file mode 100644
index 0000000..a9c5bc8
--- /dev/null
+++ b/src/lib/user/syscall.c
@@ -0,0 +1,184 @@
+#include <syscall.h>
+#include "../syscall-nr.h"
+
+/* Invokes syscall NUMBER, passing no arguments, and returns the
+ return value as an `int'. */
+#define syscall0(NUMBER) \
+ ({ \
+ int retval; \
+ asm volatile \
+ ("pushl %[number]; int $0x30; addl $4, %%esp" \
+ : "=a" (retval) \
+ : [number] "i" (NUMBER) \
+ : "memory"); \
+ retval; \
+ })
+
+/* Invokes syscall NUMBER, passing argument ARG0, and returns the
+ return value as an `int'. */
+#define syscall1(NUMBER, ARG0) \
+ ({ \
+ int retval; \
+ asm volatile \
+ ("pushl %[arg0]; pushl %[number]; int $0x30; addl $8, %%esp" \
+ : "=a" (retval) \
+ : [number] "i" (NUMBER), \
+ [arg0] "g" (ARG0) \
+ : "memory"); \
+ retval; \
+ })
+
+/* Invokes syscall NUMBER, passing arguments ARG0 and ARG1, and
+ returns the return value as an `int'. */
+#define syscall2(NUMBER, ARG0, ARG1) \
+ ({ \
+ int retval; \
+ asm volatile \
+ ("pushl %[arg1]; pushl %[arg0]; " \
+ "pushl %[number]; int $0x30; addl $12, %%esp" \
+ : "=a" (retval) \
+ : [number] "i" (NUMBER), \
+ [arg0] "g" (ARG0), \
+ [arg1] "g" (ARG1) \
+ : "memory"); \
+ retval; \
+ })
+
+/* Invokes syscall NUMBER, passing arguments ARG0, ARG1, and
+ ARG2, and returns the return value as an `int'. */
+#define syscall3(NUMBER, ARG0, ARG1, ARG2) \
+ ({ \
+ int retval; \
+ asm volatile \
+ ("pushl %[arg2]; pushl %[arg1]; pushl %[arg0]; " \
+ "pushl %[number]; int $0x30; addl $16, %%esp" \
+ : "=a" (retval) \
+ : [number] "i" (NUMBER), \
+ [arg0] "g" (ARG0), \
+ [arg1] "g" (ARG1), \
+ [arg2] "g" (ARG2) \
+ : "memory"); \
+ retval; \
+ })
+
+void
+halt (void)
+{
+ syscall0 (SYS_HALT);
+ NOT_REACHED ();
+}
+
+void
+exit (int status)
+{
+ syscall1 (SYS_EXIT, status);
+ NOT_REACHED ();
+}
+
+pid_t
+exec (const char *file)
+{
+ return (pid_t) syscall1 (SYS_EXEC, file);
+}
+
+int
+wait (pid_t pid)
+{
+ return syscall1 (SYS_WAIT, pid);
+}
+
+bool
+create (const char *file, unsigned initial_size)
+{
+ return syscall2 (SYS_CREATE, file, initial_size);
+}
+
+bool
+remove (const char *file)
+{
+ return syscall1 (SYS_REMOVE, file);
+}
+
+int
+open (const char *file)
+{
+ return syscall1 (SYS_OPEN, file);
+}
+
+int
+filesize (int fd)
+{
+ return syscall1 (SYS_FILESIZE, fd);
+}
+
+int
+read (int fd, void *buffer, unsigned size)
+{
+ return syscall3 (SYS_READ, fd, buffer, size);
+}
+
+int
+write (int fd, const void *buffer, unsigned size)
+{
+ return syscall3 (SYS_WRITE, fd, buffer, size);
+}
+
+void
+seek (int fd, unsigned position)
+{
+ syscall2 (SYS_SEEK, fd, position);
+}
+
+unsigned
+tell (int fd)
+{
+ return syscall1 (SYS_TELL, fd);
+}
+
+void
+close (int fd)
+{
+ syscall1 (SYS_CLOSE, fd);
+}
+
+mapid_t
+mmap (int fd, void *addr)
+{
+ return syscall2 (SYS_MMAP, fd, addr);
+}
+
+void
+munmap (mapid_t mapid)
+{
+ syscall1 (SYS_MUNMAP, mapid);
+}
+
+bool
+chdir (const char *dir)
+{
+ return syscall1 (SYS_CHDIR, dir);
+}
+
+bool
+mkdir (const char *dir)
+{
+ return syscall1 (SYS_MKDIR, dir);
+}
+
+bool
+readdir (int fd, char name[READDIR_MAX_LEN + 1])
+{
+ return syscall2 (SYS_READDIR, fd, name);
+}
+
+bool
+isdir (int fd)
+{
+ return syscall1 (SYS_ISDIR, fd);
+}
+
+int
+inumber (int fd)
+{
+ return syscall1 (SYS_INUMBER, fd);
+}